Merge pull request #4375 from totten/master-mysqli-compat
[civicrm-core.git] / CRM / Contribute / Page / ContributionPage.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
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 * Create a page for displaying Contribute Pages
38 * Contribute Pages are pages that are used to display
39 * contributions of different types. Pages consist
40 * of many customizable sections which can be
41 * accessed.
42 *
43 * This page provides a top level browse view
44 * of all the contribution pages in the system.
45 *
46 */
47 class CRM_Contribute_Page_ContributionPage extends CRM_Core_Page {
48
49 /**
50 * The action links that we need to display for the browse screen
51 *
52 * @var array
53 */
54 private static $_actionLinks;
55 private static $_contributionLinks;
56 private static $_configureActionLinks;
57 private static $_onlineContributionLinks;
58
59 private static $_links = NULL;
60
61 protected $_pager = NULL;
62
63 protected $_sortByCharacter;
64
65 /**
66 * Get the action links for this page.
67 *
68 * @return array $_actionLinks
69 *
70 */ function &actionLinks() {
71 // check if variable _actionsLinks is populated
72 if (!isset(self::$_actionLinks)) {
73 // helper variable for nicer formatting
74 $deleteExtra = ts('Are you sure you want to delete this Contribution page?');
75 $copyExtra = ts('Are you sure you want to make a copy of this Contribution page?');
76
77 self::$_actionLinks = array(
78 CRM_Core_Action::COPY => array(
79 'name' => ts('Make a Copy'),
80 'url' => CRM_Utils_System::currentPath(),
81 'qs' => 'action=copy&gid=%%id%%',
82 'title' => ts('Make a Copy of CiviCRM Contribution Page'),
83 'extra' => 'onclick = "return confirm(\'' . $copyExtra . '\');"',
84 ),
85 CRM_Core_Action::DISABLE => array(
86 'name' => ts('Disable'),
87 'title' => ts('Disable'),
88 'ref' => 'crm-enable-disable',
89 ),
90 CRM_Core_Action::ENABLE => array(
91 'name' => ts('Enable'),
92 'ref' => 'crm-enable-disable',
93 'title' => ts('Enable'),
94 ),
95 CRM_Core_Action::DELETE => array(
96 'name' => ts('Delete'),
97 'url' => CRM_Utils_System::currentPath(),
98 'qs' => 'action=delete&reset=1&id=%%id%%',
99 'title' => ts('Delete Custom Field'),
100 'extra' => 'onclick = "return confirm(\'' . $deleteExtra . '\');"',
101 ),
102 );
103 }
104 return self::$_actionLinks;
105 }
106
107 /**
108 * Get the configure action links for this page.
109 *
110 * @return array $_configureActionLinks
111 *
112 */
113 function &configureActionLinks() {
114 // check if variable _actionsLinks is populated
115 if (!isset(self::$_configureActionLinks)) {
116 $urlString = 'civicrm/admin/contribute/';
117 $urlParams = 'reset=1&action=update&id=%%id%%';
118
119 self::$_configureActionLinks = array(
120 CRM_Core_Action::ADD => array(
121 'name' => ts('Title and Settings'),
122 'title' => ts('Title and Settings'),
123 'url' => $urlString . 'settings',
124 'qs' => $urlParams,
125 'uniqueName' => 'settings',
126 ),
127 CRM_Core_Action::UPDATE => array(
128 'name' => ts('Contribution Amounts'),
129 'title' => ts('Contribution Amounts'),
130 'url' => $urlString . 'amount',
131 'qs' => $urlParams,
132 'uniqueName' => 'amount',
133 ),
134 CRM_Core_Action::VIEW => array(
135 'name' => ts('Membership Settings'),
136 'title' => ts('Membership Settings'),
137 'url' => $urlString . 'membership',
138 'qs' => $urlParams,
139 'uniqueName' => 'membership',
140 ),
141 CRM_Core_Action::EXPORT => array(
142 'name' => ts('Thank-you and Receipting'),
143 'title' => ts('Thank-you and Receipting'),
144 'url' => $urlString . 'thankyou',
145 'qs' => $urlParams,
146 'uniqueName' => 'thankyou',
147 ),
148 CRM_Core_Action::BASIC => array(
149 'name' => ts('Tell a Friend'),
150 'title' => ts('Tell a Friend'),
151 'url' => $urlString . 'friend',
152 'qs' => $urlParams,
153 'uniqueName' => 'friend',
154 ),
155 CRM_Core_Action::PROFILE => array(
156 'name' => ts('Include Profiles'),
157 'title' => ts('Include Profiles'),
158 'url' => $urlString . 'custom',
159 'qs' => $urlParams,
160 'uniqueName' => 'custom',
161 ),
162 CRM_Core_Action::MAP => array(
163 'name' => ts('Contribution Widget'),
164 'title' => ts('Contribution Widget'),
165 'url' => $urlString . 'widget',
166 'qs' => $urlParams,
167 'uniqueName' => 'widget',
168 ),
169 CRM_Core_Action::FOLLOWUP => array(
170 'name' => ts('Premiums'),
171 'title' => ts('Premiums'),
172 'url' => $urlString . 'premium',
173 'qs' => $urlParams,
174 'uniqueName' => 'premium',
175 ),
176 CRM_Core_Action::ADVANCED => array(
177 'name' => ts('Personal Campaign Pages'),
178 'title' => ts('Personal Campaign Pages'),
179 'url' => $urlString . 'pcp',
180 'qs' => $urlParams,
181 'uniqueName' => 'pcp',
182 ),
183 );
184 }
185
186 return self::$_configureActionLinks;
187 }
188
189 /**
190 * Get the online contribution links.
191 *
192 * @return array $_onlineContributionLinks.
193 *
194 */
195 function &onlineContributionLinks() {
196 if (!isset(self::$_onlineContributionLinks)) {
197 $urlString = 'civicrm/contribute/transact';
198 $urlParams = 'reset=1&id=%%id%%';
199 self::$_onlineContributionLinks = array(
200 CRM_Core_Action::RENEW => array(
201 'name' => ts('Live Page'),
202 'title' => ts('Live Page'),
203 'url' => $urlString,
204 'qs' => $urlParams,
205 'fe' => TRUE,
206 'uniqueName' => 'live_page',
207 ),
208 CRM_Core_Action::PREVIEW => array(
209 'name' => ts('Test-drive'),
210 'title' => ts('Test-drive'),
211 'url' => $urlString,
212 'qs' => $urlParams . '&action=preview',
213 'uniqueName' => 'test_drive',
214 ),
215 );
216 }
217
218 return self::$_onlineContributionLinks;
219 }
220
221 /**
222 * Get the contributions links.
223 *
224 * @return array $_contributionLinks
225 *
226 */
227 function &contributionLinks() {
228 if (!isset(self::$_contributionLinks)) {
229 //get contribution dates.
230 $dates = CRM_Contribute_BAO_Contribution::getContributionDates();
231 $now = $dates['now'];
232 $yearDate = $dates['yearDate'];
233 $monthDate = $dates['monthDate'];
234 $yearNow = $yearDate + 10000;
235
236 $urlString = 'civicrm/contribute/search';
237 $urlParams = 'reset=1&pid=%%id%%&force=1&test=0';
238
239 self::$_contributionLinks = array(
240 CRM_Core_Action::DETACH => array(
241 'name' => ts('Current Month-To-Date'),
242 'title' => ts('Current Month-To-Date'),
243 'url' => $urlString,
244 'qs' => "{$urlParams}&start={$monthDate}&end={$now}",
245 'uniqueName' => 'current_month_to_date',
246 ),
247 CRM_Core_Action::REVERT => array(
248 'name' => ts('Fiscal Year-To-Date'),
249 'title' => ts('Fiscal Year-To-Date'),
250 'url' => $urlString,
251 'qs' => "{$urlParams}&start={$yearDate}&end={$yearNow}",
252 'uniqueName' => 'fiscal_year_to_date',
253 ),
254 CRM_Core_Action::BROWSE => array(
255 'name' => ts('Cumulative'),
256 'title' => ts('Cumulative'),
257 'url' => $urlString,
258 'qs' => "{$urlParams}&start=&end=$now",
259 'uniqueName' => 'cumulative',
260 ),
261 );
262 }
263
264 return self::$_contributionLinks;
265 }
266
267 /**
268 * Run the page.
269 *
270 * This method is called after the page is created. It checks for the
271 * type of action and executes that action.
272 * Finally it calls the parent's run method.
273 *
274 * @return void
275 * @access public
276 *
277 */
278 function run() {
279 // get the requested action
280 $action = CRM_Utils_Request::retrieve('action', 'String',
281 // default to 'browse'
282 $this, FALSE, 'browse'
283 );
284
285 // assign vars to templates
286 $this->assign('action', $action);
287 $id = CRM_Utils_Request::retrieve('id', 'Positive',
288 $this, FALSE, 0
289 );
290
291 // set breadcrumb to append to 2nd layer pages
292 $breadCrumb = array(array('title' => ts('Manage Contribution Pages'),
293 'url' => CRM_Utils_System::url(CRM_Utils_System::currentPath(),
294 'reset=1'
295 ),
296 ));
297
298 // what action to take ?
299 if ($action & CRM_Core_Action::ADD) {
300 $session = CRM_Core_Session::singleton();
301 $session->pushUserContext(CRM_Utils_System::url(CRM_Utils_System::currentPath(),
302 'action=browse&reset=1'
303 ));
304
305 $controller = new CRM_Contribute_Controller_ContributionPage(NULL, $action);
306 CRM_Utils_System::setTitle(ts('Manage Contribution Page'));
307 CRM_Utils_System::appendBreadCrumb($breadCrumb);
308 return $controller->run();
309 }
310 elseif ($action & CRM_Core_Action::UPDATE) {
311 $config = CRM_Core_Config::singleton();
312
313 // assign vars to templates
314 $this->assign('id', $id);
315 $this->assign('title', CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionPage', $id, 'title'));
316 $this->assign('is_active', CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionPage', $id, 'is_active'));
317 if (in_array('CiviMember', $config->enableComponents)) {
318 $this->assign('CiviMember', TRUE);
319 }
320 }
321 elseif ($action & CRM_Core_Action::COPY) {
322 $session = CRM_Core_Session::singleton();
323 CRM_Core_Session::setStatus(ts('A copy of the contribution page has been created'), ts('Successfully Copied'), 'success');
324 $this->copy();
325 }
326 elseif ($action & CRM_Core_Action::DELETE) {
327 CRM_Utils_System::appendBreadCrumb($breadCrumb);
328
329 $session = CRM_Core_Session::singleton();
330 $session->pushUserContext(CRM_Utils_System::url(CRM_Utils_System::currentPath(),
331 'reset=1&action=browse'
332 ));
333
334 $id = CRM_Utils_Request::retrieve('id', 'Positive',
335 $this, FALSE, 0
336 );
337 $query = "
338 SELECT ccp.title
339 FROM civicrm_contribution_page ccp
340 JOIN civicrm_pcp cp ON ccp.id = cp.page_id
341 WHERE cp.page_id = {$id}
342 AND cp.page_type = 'contribute'
343 ";
344
345 if ($pageTitle = CRM_Core_DAO::singleValueQuery($query)) {
346 CRM_Core_Session::setStatus(ts('The \'%1\' cannot be deleted! You must Delete all Personal Campaign Page(s) related with this contribution page prior to deleting the page.', array(1 => $pageTitle)), ts('Deletion Error'), 'error');
347
348 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/contribute', 'reset=1'));
349 }
350
351 $controller = new CRM_Core_Controller_Simple('CRM_Contribute_Form_ContributionPage_Delete',
352 'Delete Contribution Page',
353 CRM_Core_Action::DELETE
354 );
355 $controller->set('id', $id);
356 $controller->process();
357 return $controller->run();
358 }
359 else {
360 // finally browse the contribution pages
361 $this->browse();
362
363 CRM_Utils_System::setTitle(ts('Manage Contribution Pages'));
364 }
365
366 return parent::run();
367 }
368
369 /**
370 * This function is to make a copy of a contribution page, including
371 * all the fields in the page
372 *
373 * @return void
374 * @access public
375 */
376 function copy() {
377 $gid = CRM_Utils_Request::retrieve('gid', 'Positive',
378 $this, TRUE, 0, 'GET'
379 );
380
381 CRM_Contribute_BAO_ContributionPage::copy($gid);
382
383 CRM_Utils_System::redirect(CRM_Utils_System::url(CRM_Utils_System::currentPath(), 'reset=1'));
384 }
385
386 /**
387 * Browse all contribution pages
388 *
389 * @param null $action
390 *
391 * @return void
392 * @access public
393 * @static
394 */
395 function browse($action = NULL) {
396 $this->_sortByCharacter = CRM_Utils_Request::retrieve('sortByCharacter',
397 'String',
398 $this
399 );
400 $createdId = CRM_Utils_Request::retrieve('cid', 'Positive',
401 $this, FALSE, 0
402 );
403
404 if ($this->_sortByCharacter == 1 ||
405 !empty($_POST)
406 ) {
407 $this->_sortByCharacter = '';
408 $this->set('sortByCharacter', '');
409 }
410
411 $this->search();
412
413 $params = array();
414
415 $whereClause = $this->whereClause($params, FALSE);
416 $this->pagerAToZ($whereClause, $params);
417
418 $params = array();
419 $whereClause = $this->whereClause($params, TRUE);
420 $this->pager($whereClause, $params);
421
422 list($offset, $rowCount) = $this->_pager->getOffsetAndRowCount();
423
424 //check for delete CRM-4418
425 $allowToDelete = CRM_Core_Permission::check('delete in CiviContribute');
426
427 $query = "
428 SELECT id
429 FROM civicrm_contribution_page
430 WHERE $whereClause
431 LIMIT $offset, $rowCount";
432 $contribPage = CRM_Core_DAO::executeQuery($query, $params, TRUE, 'CRM_Contribute_DAO_ContributionPage');
433 $contribPageIds = array();
434 while ($contribPage->fetch()) {
435 $contribPageIds[$contribPage->id] = $contribPage->id;
436 }
437 //get all section info.
438 $contriPageSectionInfo = CRM_Contribute_BAO_ContributionPage::getSectionInfo($contribPageIds);
439
440 $query = "
441 SELECT *
442 FROM civicrm_contribution_page
443 WHERE $whereClause
444 ORDER BY title asc
445 LIMIT $offset, $rowCount";
446
447 $dao = CRM_Core_DAO::executeQuery($query, $params, TRUE, 'CRM_Contribute_DAO_ContributionPage');
448
449 //get all campaigns.
450 $allCampaigns = CRM_Campaign_BAO_Campaign::getCampaigns(NULL, NULL, FALSE, FALSE, FALSE, TRUE);
451
452 //get configure actions links.
453 $configureActionLinks = self::configureActionLinks();
454
455 while ($dao->fetch()) {
456 $contribution[$dao->id] = array();
457 CRM_Core_DAO::storeValues($dao, $contribution[$dao->id]);
458
459 // form all action links
460 $action = array_sum(array_keys($this->actionLinks()));
461
462 //add configure actions links.
463 $action += array_sum(array_keys($configureActionLinks));
464
465 //add online contribution links.
466 $action += array_sum(array_keys(self::onlineContributionLinks()));
467
468 //add contribution search links.
469 $action += array_sum(array_keys(self::contributionLinks()));
470
471 if ($dao->is_active) {
472 $action -= CRM_Core_Action::ENABLE;
473 }
474 else {
475 $action -= CRM_Core_Action::DISABLE;
476 }
477
478 //CRM-4418
479 if (!$allowToDelete) {
480 $action -= CRM_Core_Action::DELETE;
481 }
482
483 //build the configure links.
484 $sectionsInfo = CRM_Utils_Array::value($dao->id, $contriPageSectionInfo, array());
485 $contribution[$dao->id]['configureActionLinks'] = CRM_Core_Action::formLink(self::formatConfigureLinks($sectionsInfo),
486 $action,
487 array('id' => $dao->id),
488 ts('Configure'),
489 TRUE,
490 'contributionpage.configure.actions',
491 'ContributionPage',
492 $dao->id
493 );
494
495 //build the contributions links.
496 $contribution[$dao->id]['contributionLinks'] = CRM_Core_Action::formLink(self::contributionLinks(),
497 $action,
498 array('id' => $dao->id),
499 ts('Contributions'),
500 TRUE,
501 'contributionpage.contributions.search',
502 'ContributionPage',
503 $dao->id
504 );
505
506 //build the online contribution links.
507 $contribution[$dao->id]['onlineContributionLinks'] = CRM_Core_Action::formLink(self::onlineContributionLinks(),
508 $action,
509 array('id' => $dao->id),
510 ts('Links'),
511 TRUE,
512 'contributionpage.online.links',
513 'ContributionPage',
514 $dao->id
515 );
516
517 //build the normal action links.
518 $contribution[$dao->id]['action'] = CRM_Core_Action::formLink(self::actionLinks(),
519 $action,
520 array('id' => $dao->id),
521 ts('more'),
522 TRUE,
523 'contributionpage.action.links',
524 'ContributionPage',
525 $dao->id
526 );
527
528 //show campaigns on selector.
529 $contribution[$dao->id]['campaign'] = CRM_Utils_Array::value($dao->campaign_id, $allCampaigns);
530 }
531
532 if (isset($contribution)) {
533 $this->assign('rows', $contribution);
534 }
535 }
536
537 function search() {
538 if (isset($this->_action) &
539 (CRM_Core_Action::ADD |
540 CRM_Core_Action::UPDATE |
541 CRM_Core_Action::DELETE
542 )
543 ) {
544 return;
545 }
546
547 $form = new CRM_Core_Controller_Simple('CRM_Contribute_Form_SearchContribution',
548 ts('Search Contribution'),
549 CRM_Core_Action::ADD
550 );
551 $form->setEmbedded(TRUE);
552 $form->setParent($this);
553 $form->process();
554 $form->run();
555 }
556
557 /**
558 * @param array $params
559 * @param bool $sortBy
560 *
561 * @return int|string
562 */
563 function whereClause(&$params, $sortBy = TRUE) {
564 $values = $clauses = array();
565 $title = $this->get('title');
566 $createdId = $this->get('cid');
567
568 if ($createdId) {
569 $clauses[] = "(created_id = {$createdId})";
570 }
571
572 if ($title) {
573 $clauses[] = "title LIKE %1";
574 if (strpos($title, '%') !== FALSE) {
575 $params[1] = array(trim($title), 'String', FALSE);
576 }
577 else {
578 $params[1] = array(trim($title), 'String', TRUE);
579 }
580 }
581
582 $value = $this->get( 'financial_type_id' );
583 $val = array();
584 if ($value) {
585 if (is_array($value)) {
586 foreach ($value as $k => $v) {
587 if ($v) {
588 $val[$k] = $k;
589 }
590 }
591 $type = implode(',', $val);
592 }
593
594 $clauses[] = "financial_type_id IN ({$type})";
595 }
596
597 if ($sortBy &&
598 $this->_sortByCharacter !== NULL
599 ) {
600 $clauses[] = "title LIKE '" . strtolower(CRM_Core_DAO::escapeWildCardString($this->_sortByCharacter)) . "%'";
601 }
602
603 $campainIds = $this->get('campaign_id');
604 if (!CRM_Utils_System::isNull($campainIds)) {
605 if (!is_array($campainIds)) {
606 $campaignIds = array($campaignIds);
607 }
608 $clauses[] = '( campaign_id IN ( ' . implode(' , ', array_values($campainIds)) . ' ) )';
609 }
610
611 if (empty($clauses)) {
612 // Let template know if user has run a search or not
613 $this->assign('isSearch', 0);
614 return 1;
615 }
616 else {
617 $this->assign('isSearch', 1);
618 }
619
620 return implode(' AND ', $clauses);
621 }
622
623 /**
624 * @param $whereClause
625 * @param array $whereParams
626 */
627 function pager($whereClause, $whereParams) {
628
629 $params['status'] = ts('Contribution %%StatusMessage%%');
630 $params['csvString'] = NULL;
631 $params['buttonTop'] = 'PagerTopButton';
632 $params['buttonBottom'] = 'PagerBottomButton';
633 $params['rowCount'] = $this->get(CRM_Utils_Pager::PAGE_ROWCOUNT);
634 if (!$params['rowCount']) {
635 $params['rowCount'] = CRM_Utils_Pager::ROWCOUNT;
636 }
637
638 $query = "
639 SELECT count(id)
640 FROM civicrm_contribution_page
641 WHERE $whereClause";
642
643 $params['total'] = CRM_Core_DAO::singleValueQuery($query, $whereParams);
644
645 $this->_pager = new CRM_Utils_Pager($params);
646 $this->assign_by_ref('pager', $this->_pager);
647 }
648
649 /**
650 * @param $whereClause
651 * @param array $whereParams
652 */
653 function pagerAtoZ($whereClause, $whereParams) {
654
655 $query = "
656 SELECT DISTINCT UPPER(LEFT(title, 1)) as sort_name
657 FROM civicrm_contribution_page
658 WHERE $whereClause
659 ORDER BY LEFT(title, 1)
660 ";
661 $dao = CRM_Core_DAO::executeQuery($query, $whereParams);
662
663 $aToZBar = CRM_Utils_PagerAToZ::getAToZBar($dao, $this->_sortByCharacter, TRUE);
664 $this->assign('aToZ', $aToZBar);
665 }
666
667 /**
668 * @param $sectionsInfo
669 *
670 * @return array
671 */
672 function formatConfigureLinks($sectionsInfo) {
673 //build the formatted configure links.
674 $formattedConfLinks = self::configureActionLinks();
675 foreach ($formattedConfLinks as $act => & $link) {
676 $sectionName = CRM_Utils_Array::value('uniqueName', $link);
677 if (!$sectionName) {
678 continue;
679 }
680
681 $classes = array();
682 if (isset($link['class'])) {
683 $classes = $link['class'];
684 }
685
686 if (empty($sectionsInfo[$sectionName])) {
687 $classes = array();
688 if (isset($link['class'])) {
689 $classes = $link['class'];
690 }
691 $link['class'] = array_merge($classes, array('disabled'));
692 }
693 }
694
695 return $formattedConfLinks;
696 }
697 }
698