3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * Create a page for displaying Contribute Pages
20 * Contribute Pages are pages that are used to display
21 * contributions of different types. Pages consist
22 * of many customizable sections which can be
25 * This page provides a top level browse view
26 * of all the contribution pages in the system.
29 class CRM_Contribute_Page_ContributionPage
extends CRM_Core_Page
{
32 * The action links that we need to display for the browse screen.
36 private static $_actionLinks;
37 private static $_contributionLinks;
38 private static $_configureActionLinks;
39 private static $_onlineContributionLinks;
42 * @var CRM_Utils_Pager
44 protected $_pager = NULL;
49 protected $_sortByCharacter;
52 * Get the action links for this page.
56 public static function &actionLinks() {
57 // check if variable _actionsLinks is populated
58 if (!isset(self
::$_actionLinks)) {
59 // helper variable for nicer formatting
60 $deleteExtra = ts('Are you sure you want to delete this Contribution page?');
61 $copyExtra = ts('Are you sure you want to make a copy of this Contribution page?');
63 self
::$_actionLinks = array(
64 CRM_Core_Action
::COPY
=> array(
65 'name' => ts('Make a Copy'),
66 'url' => CRM_Utils_System
::currentPath(),
67 'qs' => 'action=copy&gid=%%id%%',
68 'title' => ts('Make a Copy of CiviCRM Contribution Page'),
69 'extra' => 'onclick = "return confirm(\'' . $copyExtra . '\');"',
71 CRM_Core_Action
::DISABLE
=> array(
72 'name' => ts('Disable'),
73 'title' => ts('Disable'),
74 'ref' => 'crm-enable-disable',
76 CRM_Core_Action
::ENABLE
=> array(
77 'name' => ts('Enable'),
78 'ref' => 'crm-enable-disable',
79 'title' => ts('Enable'),
81 CRM_Core_Action
::DELETE
=> array(
82 'name' => ts('Delete'),
83 'url' => CRM_Utils_System
::currentPath(),
84 'qs' => 'action=delete&reset=1&id=%%id%%',
85 'title' => ts('Delete Custom Field'),
86 'extra' => 'onclick = "return confirm(\'' . $deleteExtra . '\');"',
90 return self
::$_actionLinks;
94 * Get the configure action links for this page.
98 public function &configureActionLinks() {
99 // check if variable _actionsLinks is populated
100 if (!isset(self
::$_configureActionLinks)) {
101 $urlString = 'civicrm/admin/contribute/';
102 $urlParams = 'reset=1&action=update&id=%%id%%';
104 self
::$_configureActionLinks = array(
105 CRM_Core_Action
::ADD
=> array(
106 'name' => ts('Title and Settings'),
107 'title' => ts('Title and Settings'),
108 'url' => $urlString . 'settings',
110 'uniqueName' => 'settings',
112 CRM_Core_Action
::UPDATE
=> array(
113 'name' => ts('Contribution Amounts'),
114 'title' => ts('Contribution Amounts'),
115 'url' => $urlString . 'amount',
117 'uniqueName' => 'amount',
119 CRM_Core_Action
::VIEW
=> array(
120 'name' => ts('Membership Settings'),
121 'title' => ts('Membership Settings'),
122 'url' => $urlString . 'membership',
124 'uniqueName' => 'membership',
126 CRM_Core_Action
::EXPORT
=> array(
127 'name' => ts('Thank-you and Receipting'),
128 'title' => ts('Thank-you and Receipting'),
129 'url' => $urlString . 'thankyou',
131 'uniqueName' => 'thankyou',
133 CRM_Core_Action
::BASIC
=> array(
134 'name' => ts('Tell a Friend'),
135 'title' => ts('Tell a Friend'),
136 'url' => $urlString . 'friend',
138 'uniqueName' => 'friend',
140 CRM_Core_Action
::PROFILE
=> array(
141 'name' => ts('Include Profiles'),
142 'title' => ts('Include Profiles'),
143 'url' => $urlString . 'custom',
145 'uniqueName' => 'custom',
147 CRM_Core_Action
::MAP
=> array(
148 'name' => ts('Contribution Widget'),
149 'title' => ts('Contribution Widget'),
150 'url' => $urlString . 'widget',
152 'uniqueName' => 'widget',
154 CRM_Core_Action
::FOLLOWUP
=> array(
155 'name' => ts('Premiums'),
156 'title' => ts('Premiums'),
157 'url' => $urlString . 'premium',
159 'uniqueName' => 'premium',
161 CRM_Core_Action
::ADVANCED
=> array(
162 'name' => ts('Personal Campaign Pages'),
163 'title' => ts('Personal Campaign Pages'),
164 'url' => $urlString . 'pcp',
166 'uniqueName' => 'pcp',
170 'urlString' => $urlString,
171 'urlParams' => $urlParams,
173 CRM_Utils_Hook
::tabset('civicrm/admin/contribute', self
::$_configureActionLinks, $context);
176 return self
::$_configureActionLinks;
180 * Get the online contribution links.
184 public function &onlineContributionLinks() {
185 if (!isset(self
::$_onlineContributionLinks)) {
186 $urlString = 'civicrm/contribute/transact';
187 $urlParams = 'reset=1&id=%%id%%';
188 self
::$_onlineContributionLinks = array(
189 CRM_Core_Action
::RENEW
=> array(
190 'name' => ts('Live Page'),
191 'title' => ts('Live Page'),
195 'uniqueName' => 'live_page',
197 CRM_Core_Action
::PREVIEW
=> array(
198 'name' => ts('Test-drive'),
199 'title' => ts('Test-drive'),
201 'qs' => $urlParams . '&action=preview',
202 // Addresses https://lab.civicrm.org/dev/core/issues/658
204 'uniqueName' => 'test_drive',
209 return self
::$_onlineContributionLinks;
213 * Get the contributions links.
217 public function &contributionLinks() {
218 if (!isset(self
::$_contributionLinks)) {
219 //get contribution dates.
220 $dates = CRM_Contribute_BAO_Contribution
::getContributionDates();
221 $now = $dates['now'];
222 $yearDate = $dates['yearDate'];
223 $monthDate = $dates['monthDate'];
224 $yearNow = $yearDate +
10000;
226 $urlString = 'civicrm/contribute/search';
227 $urlParams = 'reset=1&contribution_page_id=%%id%%&force=1&test=0';
229 self
::$_contributionLinks = array(
230 CRM_Core_Action
::DETACH
=> array(
231 'name' => ts('Current Month-To-Date'),
232 'title' => ts('Current Month-To-Date'),
234 'qs' => "{$urlParams}&receive_date_low={$monthDate}&receive_date_high={$now}",
235 'uniqueName' => 'current_month_to_date',
237 CRM_Core_Action
::REVERT
=> array(
238 'name' => ts('Fiscal Year-To-Date'),
239 'title' => ts('Fiscal Year-To-Date'),
241 'qs' => "{$urlParams}&receive_date_low={$yearDate}&receive_date_high={$yearNow}",
242 'uniqueName' => 'fiscal_year_to_date',
244 CRM_Core_Action
::BROWSE
=> array(
245 'name' => ts('Cumulative'),
246 'title' => ts('Cumulative'),
248 'qs' => "{$urlParams}&receive_date_low=&receive_date_high=$now",
249 'uniqueName' => 'cumulative',
254 return self
::$_contributionLinks;
260 * This method is called after the page is created. It checks for the
261 * type of action and executes that action.
262 * Finally it calls the parent's run method.
266 public function run() {
267 // get the requested action
268 $action = CRM_Utils_Request
::retrieve('action', 'String',
269 // default to 'browse'
270 $this, FALSE, 'browse'
273 // assign vars to templates
274 $this->assign('action', $action);
275 $id = CRM_Utils_Request
::retrieve('id', 'Positive',
279 // set breadcrumb to append to 2nd layer pages
282 'title' => ts('Manage Contribution Pages'),
283 'url' => CRM_Utils_System
::url(CRM_Utils_System
::currentPath(),
289 // what action to take ?
290 if ($action & CRM_Core_Action
::ADD
) {
291 $session = CRM_Core_Session
::singleton();
292 $session->pushUserContext(CRM_Utils_System
::url(CRM_Utils_System
::currentPath(),
293 'action=browse&reset=1'
296 $controller = new CRM_Contribute_Controller_ContributionPage(NULL, $action);
297 CRM_Utils_System
::setTitle(ts('Manage Contribution Page'));
298 CRM_Utils_System
::appendBreadCrumb($breadCrumb);
299 return $controller->run();
301 elseif ($action & CRM_Core_Action
::UPDATE
) {
302 $config = CRM_Core_Config
::singleton();
304 // assign vars to templates
305 $this->assign('id', $id);
306 $this->assign('title', CRM_Core_DAO
::getFieldValue('CRM_Contribute_DAO_ContributionPage', $id, 'title'));
307 $this->assign('is_active', CRM_Core_DAO
::getFieldValue('CRM_Contribute_DAO_ContributionPage', $id, 'is_active'));
308 if (in_array('CiviMember', $config->enableComponents
)) {
309 $this->assign('CiviMember', TRUE);
312 elseif ($action & CRM_Core_Action
::COPY
) {
313 // @todo Unused local variable can be safely removed.
314 // But are there any side effects of CRM_Core_Session::singleton() that we
316 $session = CRM_Core_Session
::singleton();
317 CRM_Core_Session
::setStatus(ts('A copy of the contribution page has been created'), ts('Successfully Copied'), 'success');
320 elseif ($action & CRM_Core_Action
::DELETE
) {
321 CRM_Utils_System
::appendBreadCrumb($breadCrumb);
323 $session = CRM_Core_Session
::singleton();
324 $session->pushUserContext(CRM_Utils_System
::url(CRM_Utils_System
::currentPath(),
325 'reset=1&action=browse'
328 $id = CRM_Utils_Request
::retrieve('id', 'Positive',
333 FROM civicrm_contribution_page ccp
334 JOIN civicrm_pcp cp ON ccp.id = cp.page_id
335 WHERE cp.page_id = {$id}
336 AND cp.page_type = 'contribute'
339 if ($pageTitle = CRM_Core_DAO
::singleValueQuery($query)) {
340 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');
342 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/admin/contribute', 'reset=1'));
345 $controller = new CRM_Core_Controller_Simple('CRM_Contribute_Form_ContributionPage_Delete',
346 'Delete Contribution Page',
347 CRM_Core_Action
::DELETE
349 $controller->set('id', $id);
350 $controller->process();
351 return $controller->run();
354 // finally browse the contribution pages
357 CRM_Utils_System
::setTitle(ts('Manage Contribution Pages'));
360 return parent
::run();
364 * Make a copy of a contribution page, including all the fields in the page.
366 public function copy() {
367 $gid = CRM_Utils_Request
::retrieve('gid', 'Positive',
368 $this, TRUE, 0, 'GET'
371 $copy = CRM_Contribute_BAO_ContributionPage
::copy($gid);
373 $urlString = CRM_Utils_System
::currentPath();
374 $urlParams = 'reset=1';
376 // Redirect to copied contribution page
378 $urlString = 'civicrm/admin/contribute/settings';
379 $urlParams .= '&action=update&id=' . $copy->id
;
382 CRM_Utils_System
::redirect(CRM_Utils_System
::url($urlString, $urlParams));
386 * Browse all contribution pages.
388 * @param mixed $action
391 public function browse($action = NULL) {
392 Civi
::resources()->addStyleFile('civicrm', 'css/searchForm.css', 1, 'html-header');
394 $this->_sortByCharacter
= CRM_Utils_Request
::retrieve('sortByCharacter',
398 // @todo Unused local variable can be safely removed.
399 // But are there any side effects of CRM_Utils_Request::retrieve() that we
401 $createdId = CRM_Utils_Request
::retrieve('cid', 'Positive',
405 if ($this->_sortByCharacter
== 'all' ||
408 $this->_sortByCharacter
= '';
409 $this->set('sortByCharacter', '');
416 $whereClause = $this->whereClause($params, FALSE);
417 $config = CRM_Core_Config
::singleton();
418 if ($config->includeAlphabeticalPager
) {
419 $this->pagerAToZ($whereClause, $params);
422 $whereClause = $this->whereClause($params, TRUE);
423 $this->pager($whereClause, $params);
425 list($offset, $rowCount) = $this->_pager
->getOffsetAndRowCount();
427 //check for delete CRM-4418
428 $allowToDelete = CRM_Core_Permission
::check('delete in CiviContribute');
432 FROM civicrm_contribution_page
434 ORDER BY is_active desc, title asc
435 LIMIT $offset, $rowCount";
436 $contribPage = CRM_Core_DAO
::executeQuery($query, $params, TRUE, 'CRM_Contribute_DAO_ContributionPage');
437 $contribPageIds = array();
438 while ($contribPage->fetch()) {
439 $contribPageIds[$contribPage->id
] = $contribPage->id
;
441 //get all section info.
442 $contriPageSectionInfo = CRM_Contribute_BAO_ContributionPage
::getSectionInfo($contribPageIds);
446 FROM civicrm_contribution_page
448 ORDER BY is_active desc, title asc
449 LIMIT $offset, $rowCount";
451 $dao = CRM_Core_DAO
::executeQuery($query, $params, TRUE, 'CRM_Contribute_DAO_ContributionPage');
454 $allCampaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(NULL, NULL, FALSE, FALSE, FALSE, TRUE);
456 //get configure actions links.
457 $configureActionLinks = self
::configureActionLinks();
459 while ($dao->fetch()) {
460 $contribution[$dao->id
] = array();
461 CRM_Core_DAO
::storeValues($dao, $contribution[$dao->id
]);
463 // form all action links
464 $action = array_sum(array_keys(self
::actionLinks()));
466 //add configure actions links.
467 $action +
= array_sum(array_keys($configureActionLinks));
469 //add online contribution links.
470 $action +
= array_sum(array_keys(self
::onlineContributionLinks()));
472 //add contribution search links.
473 $action +
= array_sum(array_keys(self
::contributionLinks()));
475 if ($dao->is_active
) {
476 $action -= (int) CRM_Core_Action
::ENABLE
;
479 $action -= (int) CRM_Core_Action
::DISABLE
;
483 if (!$allowToDelete) {
484 $action -= (int) CRM_Core_Action
::DELETE
;
487 //build the configure links.
488 $sectionsInfo = CRM_Utils_Array
::value($dao->id
, $contriPageSectionInfo, array());
489 $contribution[$dao->id
]['configureActionLinks'] = CRM_Core_Action
::formLink(self
::formatConfigureLinks($sectionsInfo),
491 array('id' => $dao->id
),
494 'contributionpage.configure.actions',
499 //build the contributions links.
500 $contribution[$dao->id
]['contributionLinks'] = CRM_Core_Action
::formLink(self
::contributionLinks(),
502 array('id' => $dao->id
),
505 'contributionpage.contributions.search',
510 //build the online contribution links.
511 $contribution[$dao->id
]['onlineContributionLinks'] = CRM_Core_Action
::formLink(self
::onlineContributionLinks(),
513 array('id' => $dao->id
),
516 'contributionpage.online.links',
521 //build the normal action links.
522 $contribution[$dao->id
]['action'] = CRM_Core_Action
::formLink(self
::actionLinks(),
524 array('id' => $dao->id
),
527 'contributionpage.action.links',
532 //show campaigns on selector.
533 $contribution[$dao->id
]['campaign'] = $allCampaigns[$dao->campaign_id
] ??
NULL;
536 if (isset($contribution)) {
537 $this->assign('rows', $contribution);
541 public function search() {
542 if (isset($this->_action
) & (CRM_Core_Action
::ADD |
543 CRM_Core_Action
::UPDATE |
544 CRM_Core_Action
::DELETE
550 $form = new CRM_Core_Controller_Simple('CRM_Contribute_Form_SearchContribution',
551 ts('Search Contribution'),
554 $form->setEmbedded(TRUE);
555 $form->setParent($this);
561 * @param array $params
562 * @param bool $sortBy
566 public function whereClause(&$params, $sortBy = TRUE) {
567 // @todo Unused local variable can be safely removed.
568 $values = $clauses = array();
569 $title = $this->get('title');
570 $createdId = $this->get('cid');
573 $clauses[] = "(created_id = {$createdId})";
577 $clauses[] = "title LIKE %1";
578 if (strpos($title, '%') !== FALSE) {
579 $params[1] = array(trim($title), 'String', FALSE);
582 $params[1] = array(trim($title), 'String', TRUE);
586 $value = $this->get('financial_type_id');
589 if (is_array($value)) {
590 foreach ($value as $k => $v) {
595 $type = implode(',', $val);
597 // @todo Variable 'type' might not have been defined.
598 $clauses[] = "financial_type_id IN ({$type})";
601 if ($sortBy && $this->_sortByCharacter
!== NULL) {
602 $clauses[] = "title LIKE '" . strtolower(CRM_Core_DAO
::escapeWildCardString($this->_sortByCharacter
)) . "%'";
605 $campaignIds = $this->getCampaignIds();
606 if (count($campaignIds) >= 1) {
607 $clauses[] = '( campaign_id IN ( ' . implode(' , ', $campaignIds) . ' ) )';
610 if (empty($clauses)) {
611 // Let template know if user has run a search or not
612 $this->assign('isSearch', 0);
616 $this->assign('isSearch', 1);
619 return implode(' AND ', $clauses);
623 * Gets the campaign ids from the session.
627 public function getCampaignIds() {
628 // The unfiltered value from the session cannot be trusted, it needs to be
629 // processed to get a clean array of positive integers.
631 foreach ((array) $this->get('campaign_id') as $id) {
632 if ((string) (int) $id === (string) $id && $id > 0) {
640 * @param $whereClause
641 * @param array $whereParams
643 public function pager($whereClause, $whereParams) {
645 $params['status'] = ts('Contribution %%StatusMessage%%');
646 $params['csvString'] = NULL;
647 $params['buttonTop'] = 'PagerTopButton';
648 $params['buttonBottom'] = 'PagerBottomButton';
649 $params['rowCount'] = $this->get(CRM_Utils_Pager
::PAGE_ROWCOUNT
);
650 if (!$params['rowCount']) {
651 $params['rowCount'] = CRM_Utils_Pager
::ROWCOUNT
;
656 FROM civicrm_contribution_page
659 $params['total'] = CRM_Core_DAO
::singleValueQuery($query, $whereParams);
661 $this->_pager
= new CRM_Utils_Pager($params);
662 $this->assign_by_ref('pager', $this->_pager
);
666 * @param $whereClause
667 * @param array $whereParams
669 public function pagerAtoZ($whereClause, $whereParams) {
672 SELECT DISTINCT UPPER(LEFT(title, 1)) as sort_name
673 FROM civicrm_contribution_page
675 ORDER BY UPPER(LEFT(title, 1))
677 $dao = CRM_Core_DAO
::executeQuery($query, $whereParams);
679 $aToZBar = CRM_Utils_PagerAToZ
::getAToZBar($dao, $this->_sortByCharacter
, TRUE);
680 $this->assign('aToZ', $aToZBar);
684 * @param array $sectionsInfo
688 public function formatConfigureLinks($sectionsInfo) {
689 // build the formatted configure links.
690 $formattedConfLinks = self
::configureActionLinks();
691 foreach ($formattedConfLinks as $act => & $link) {
692 $sectionName = $link['uniqueName'] ??
NULL;
697 if (empty($sectionsInfo[$sectionName])) {
699 if (isset($link['class'])) {
700 $classes = $link['class'];
702 $link['class'] = array_merge($classes, array('disabled'));
706 return $formattedConfLinks;