(NFC) (dev/core#878) Simplify copyright header (templates/*)
[civicrm-core.git] / CRM / PCP / BAO / PCP.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
f299f7db 6 | Copyright CiviCRM LLC (c) 2004-2020 |
6a488035
TO
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
ca5cec67 31 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
32 */
33class CRM_PCP_BAO_PCP extends CRM_PCP_DAO_PCP {
34
35 /**
eceb18cc 36 * The action links that we need to display for the browse screen.
6a488035
TO
37 *
38 * @var array
6a488035 39 */
c86d4e7c 40 public static $_pcpLinks = NULL;
9d9922e7 41
e0ef6999 42 /**
ad37ac8e 43 * Class constructor.
e0ef6999 44 */
00be9182 45 public function __construct() {
6a488035
TO
46 parent::__construct();
47 }
48
49 /**
eceb18cc 50 * Add or update either a Personal Campaign Page OR a PCP Block.
6a488035 51 *
db95eff6 52 * @param array $params
f6bc51fd 53 * Values to create the pcp.
d75f2f47 54 *
6a488035
TO
55 * @return object
56 */
f6bc51fd 57 public static function create($params) {
6a488035
TO
58
59 $dao = new CRM_PCP_DAO_PCP();
60 $dao->copyValues($params);
61
62 // ensure we set status_id since it is a not null field
63 // we should change the schema and allow this to be null
64 if (!$dao->id && !isset($dao->status_id)) {
65 $dao->status_id = 0;
66 }
67
68 // set currency for CRM-1496
69 if (!isset($dao->currency)) {
f6bc51fd 70 $dao->currency = CRM_Core_Config::singleton()->defaultCurrency;
6a488035
TO
71 }
72
73 $dao->save();
74 return $dao;
75 }
76
77 /**
eceb18cc 78 * Get the Display name of a contact for a PCP.
6a488035 79 *
db95eff6
TO
80 * @param int $id
81 * Id for the PCP.
6a488035 82 *
72b3a70c
CW
83 * @return null|string
84 * Dispaly name of the contact if found
6a488035 85 */
00be9182 86 public static function displayName($id) {
6a488035
TO
87 $id = CRM_Utils_Type::escape($id, 'Integer');
88
89 $query = "
90SELECT civicrm_contact.display_name
91FROM civicrm_pcp, civicrm_contact
92WHERE civicrm_pcp.contact_id = civicrm_contact.id
93 AND civicrm_pcp.id = {$id}
94";
9d2678f4 95 return CRM_Core_DAO::singleValueQuery($query);
6a488035
TO
96 }
97
98 /**
eceb18cc 99 * Return PCP Block info for dashboard.
6a488035 100 *
100fef9d 101 * @param int $contactId
dd244018 102 *
a6c01b45
CW
103 * @return array
104 * array of Pcp if found
6a488035 105 */
00be9182 106 public static function getPcpDashboardInfo($contactId) {
6a488035
TO
107 $links = self::pcpLinks();
108
109 $query = "
743f5cb2 110SELECT pcp.*, block.is_tellfriend_enabled FROM civicrm_pcp pcp
6da0be4d 111LEFT JOIN civicrm_pcp_block block ON block.id = pcp.pcp_block_id
6a488035
TO
112WHERE pcp.is_active = 1
113 AND pcp.contact_id = %1
114ORDER BY page_type, page_id";
115
be2fb01f 116 $params = [1 => [$contactId, 'Integer']];
6a488035 117
9d9922e7 118 $pcpInfoDao = CRM_Core_DAO::executeQuery($query, $params);
be2fb01f 119 $pcpInfo = [];
9d9922e7 120 $hide = $mask = array_sum(array_keys($links['all']));
be2fb01f 121 $contactPCPPages = [];
6a488035 122
9d9922e7 123 $event = CRM_Event_PseudoConstant::event(NULL, FALSE, "( is_template IS NULL OR is_template != 1 )");
6a488035 124 $contribute = CRM_Contribute_PseudoConstant::contributionPage();
9d9922e7 125 $pcpStatus = CRM_Contribute_PseudoConstant::pcpStatus();
126 $approved = CRM_Utils_Array::key('Approved', $pcpStatus);
6a488035
TO
127
128 while ($pcpInfoDao->fetch()) {
129 $mask = $hide;
130 if ($links) {
be2fb01f 131 $replace = [
6a488035
TO
132 'pcpId' => $pcpInfoDao->id,
133 'pcpBlock' => $pcpInfoDao->pcp_block_id,
134 'pageComponent' => $pcpInfoDao->page_type,
be2fb01f 135 ];
6a488035
TO
136 }
137
138 $pcpLink = $links['all'];
139 $class = '';
140
141 if ($pcpInfoDao->status_id != $approved || $pcpInfoDao->is_active != 1) {
142 $class = 'disabled';
6da0be4d 143 if (!$pcpInfoDao->is_tellfriend_enabled) {
6a488035
TO
144 $mask -= CRM_Core_Action::DETACH;
145 }
146 }
147
148 if ($pcpInfoDao->is_active == 1) {
149 $mask -= CRM_Core_Action::ENABLE;
150 }
151 else {
152 $mask -= CRM_Core_Action::DISABLE;
153 }
87dab4a4
AH
154 $action = CRM_Core_Action::formLink($pcpLink, $mask, $replace, ts('more'),
155 FALSE, 'pcp.dashboard.active', 'PCP', $pcpInfoDao->id);
6a488035
TO
156 $component = $pcpInfoDao->page_type;
157 $pageTitle = CRM_Utils_Array::value($pcpInfoDao->page_id, $$component);
158
be2fb01f 159 $pcpInfo[] = [
6a488035
TO
160 'pageTitle' => $pageTitle,
161 'pcpId' => $pcpInfoDao->id,
162 'pcpTitle' => $pcpInfoDao->title,
163 'pcpStatus' => $pcpStatus[$pcpInfoDao->status_id],
164 'action' => $action,
165 'class' => $class,
be2fb01f 166 ];
6a488035
TO
167 $contactPCPPages[$pcpInfoDao->page_type][] = $pcpInfoDao->page_id;
168 }
169
170 $excludePageClause = $clause = NULL;
171 if (!empty($contactPCPPages)) {
172 foreach ($contactPCPPages as $component => $entityIds) {
173 $excludePageClause[] = "
174( target_entity_type = '{$component}'
175AND target_entity_id NOT IN ( " . implode(',', $entityIds) . ") )";
176 }
177
178 $clause = ' AND ' . implode(' OR ', $excludePageClause);
179 }
180
181 $query = "
3636b520 182SELECT *
6a488035
TO
183FROM civicrm_pcp_block block
184LEFT JOIN civicrm_pcp pcp ON pcp.pcp_block_id = block.id
185WHERE block.is_active = 1
186{$clause}
3636b520 187GROUP BY block.id, pcp.id
6a488035
TO
188ORDER BY target_entity_type, target_entity_id
189";
190 $pcpBlockDao = CRM_Core_DAO::executeQuery($query);
be2fb01f 191 $pcpBlock = [];
9d9922e7 192 $mask = 0;
6a488035
TO
193
194 while ($pcpBlockDao->fetch()) {
195 if ($links) {
be2fb01f 196 $replace = [
6a488035
TO
197 'pageId' => $pcpBlockDao->target_entity_id,
198 'pageComponent' => $pcpBlockDao->target_entity_type,
be2fb01f 199 ];
6a488035 200 }
9d9922e7 201 $pcpLink = $links['add'];
87dab4a4
AH
202 $action = CRM_Core_Action::formLink($pcpLink, $mask, $replace, ts('more'),
203 FALSE, 'pcp.dashboard.other', "{$pcpBlockDao->target_entity_type}_PCP", $pcpBlockDao->target_entity_id);
9d9922e7 204 $component = $pcpBlockDao->target_entity_type;
6167c3d3 205 if ($pageTitle = CRM_Utils_Array::value($pcpBlockDao->target_entity_id, $$component)) {
be2fb01f 206 $pcpBlock[] = [
6167c3d3
BS
207 'pageId' => $pcpBlockDao->target_entity_id,
208 'pageTitle' => $pageTitle,
209 'action' => $action,
be2fb01f 210 ];
6167c3d3 211 }
6a488035
TO
212 }
213
be2fb01f 214 return [$pcpBlock, $pcpInfo];
6a488035
TO
215 }
216
217 /**
eceb18cc 218 * Show the total amount for Personal Campaign Page on thermometer.
6a488035 219 *
db95eff6
TO
220 * @param array $pcpId
221 * Contains the pcp ID.
6a488035 222 *
ad37ac8e 223 * @return float
224 * Total amount
6a488035 225 */
00be9182 226 public static function thermoMeter($pcpId) {
0e362aad
PN
227 $completedStatusId = CRM_Core_PseudoConstant::getKey(
228 'CRM_Contribute_BAO_Contribution',
229 'contribution_status_id',
230 'Completed'
231 );
6a488035
TO
232 $query = "
233SELECT SUM(cc.total_amount) as total
234FROM civicrm_pcp pcp
235LEFT JOIN civicrm_contribution_soft cs ON ( pcp.id = cs.pcp_id )
236LEFT JOIN civicrm_contribution cc ON ( cs.contribution_id = cc.id)
0e362aad 237WHERE pcp.id = %1 AND cc.contribution_status_id = %2 AND cc.is_test = 0";
6a488035 238
0e362aad
PN
239 $params = [
240 1 => [$pcpId, 'Integer'],
241 2 => [$completedStatusId, 'Integer'],
242 ];
6a488035
TO
243 return CRM_Core_DAO::singleValueQuery($query, $params);
244 }
245
246 /**
ad37ac8e 247 * Show the amount, nickname on honor roll.
6a488035 248 *
db95eff6
TO
249 * @param array $pcpId
250 * Contains the pcp ID.
6a488035 251 *
a6c01b45 252 * @return array
6a488035 253 */
00be9182 254 public static function honorRoll($pcpId) {
821ee787
PN
255 $completedStatusId = CRM_Core_PseudoConstant::getKey(
256 'CRM_Contribute_BAO_Contribution',
257 'contribution_status_id',
258 'Completed'
259 );
6a488035
TO
260 $query = "
261 SELECT cc.id, cs.pcp_roll_nickname, cs.pcp_personal_note,
262 cc.total_amount, cc.currency
263 FROM civicrm_contribution cc
264 LEFT JOIN civicrm_contribution_soft cs ON cc.id = cs.contribution_id
821ee787 265 WHERE cs.pcp_id = %1
6a488035 266 AND cs.pcp_display_in_roll = 1
821ee787 267 AND contribution_status_id = %2
6a488035 268 AND is_test = 0";
821ee787
PN
269 $params = [
270 1 => [$pcpId, 'Integer'],
271 2 => [$completedStatusId, 'Integer'],
272 ];
273 $dao = CRM_Core_DAO::executeQuery($query, $params);
be2fb01f 274 $honor = [];
6a488035
TO
275 while ($dao->fetch()) {
276 $honor[$dao->id]['nickname'] = ucwords($dao->pcp_roll_nickname);
277 $honor[$dao->id]['total_amount'] = CRM_Utils_Money::format($dao->total_amount, $dao->currency);
278 $honor[$dao->id]['personal_note'] = $dao->pcp_personal_note;
279 }
280 return $honor;
281 }
282
283 /**
eceb18cc 284 * Get action links.
6a488035 285 *
a6c01b45
CW
286 * @return array
287 * (reference) of action links
6a488035 288 */
00be9182 289 public static function &pcpLinks() {
6a488035
TO
290 if (!(self::$_pcpLinks)) {
291 $deleteExtra = ts('Are you sure you want to delete this Personal Campaign Page?') . '\n' . ts('This action cannot be undone.');
292
be2fb01f
CW
293 self::$_pcpLinks['add'] = [
294 CRM_Core_Action::ADD => [
9d9922e7 295 'name' => ts('Create a Personal Campaign Page'),
cbc1fad4 296 'class' => 'no-popup',
6a488035
TO
297 'url' => 'civicrm/contribute/campaign',
298 'qs' => 'action=add&reset=1&pageId=%%pageId%%&component=%%pageComponent%%',
299 'title' => ts('Configure'),
be2fb01f
CW
300 ],
301 ];
6a488035 302
be2fb01f
CW
303 self::$_pcpLinks['all'] = [
304 CRM_Core_Action::UPDATE => [
9d9922e7 305 'name' => ts('Edit Your Page'),
6a488035
TO
306 'url' => 'civicrm/pcp/info',
307 'qs' => 'action=update&reset=1&id=%%pcpId%%&component=%%pageComponent%%',
308 'title' => ts('Configure'),
be2fb01f
CW
309 ],
310 CRM_Core_Action::DETACH => [
9d9922e7 311 'name' => ts('Tell Friends'),
6a488035
TO
312 'url' => 'civicrm/friend',
313 'qs' => 'eid=%%pcpId%%&blockId=%%pcpBlock%%&reset=1&pcomponent=pcp&component=%%pageComponent%%',
314 'title' => ts('Tell Friends'),
be2fb01f
CW
315 ],
316 CRM_Core_Action::VIEW => [
ff06e012
DG
317 'name' => ts('URL for this Page'),
318 'url' => 'civicrm/pcp/info',
319 'qs' => 'reset=1&id=%%pcpId%%&component=%%pageComponent%%',
320 'title' => ts('URL for this Page'),
be2fb01f
CW
321 ],
322 CRM_Core_Action::BROWSE => [
9d9922e7 323 'name' => ts('Update Contact Information'),
6a488035
TO
324 'url' => 'civicrm/pcp/info',
325 'qs' => 'action=browse&reset=1&id=%%pcpId%%&component=%%pageComponent%%',
326 'title' => ts('Update Contact Information'),
be2fb01f
CW
327 ],
328 CRM_Core_Action::ENABLE => [
9d9922e7 329 'name' => ts('Enable'),
6a488035
TO
330 'url' => 'civicrm/pcp',
331 'qs' => 'action=enable&reset=1&id=%%pcpId%%&component=%%pageComponent%%',
332 'title' => ts('Enable'),
be2fb01f
CW
333 ],
334 CRM_Core_Action::DISABLE => [
9d9922e7 335 'name' => ts('Disable'),
6a488035
TO
336 'url' => 'civicrm/pcp',
337 'qs' => 'action=disable&reset=1&id=%%pcpId%%&component=%%pageComponent%%',
338 'title' => ts('Disable'),
be2fb01f
CW
339 ],
340 CRM_Core_Action::DELETE => [
9d9922e7 341 'name' => ts('Delete'),
6a488035
TO
342 'url' => 'civicrm/pcp',
343 'qs' => 'action=delete&reset=1&id=%%pcpId%%&component=%%pageComponent%%',
344 'extra' => 'onclick = "return confirm(\'' . $deleteExtra . '\');"',
345 'title' => ts('Delete'),
be2fb01f
CW
346 ],
347 ];
6a488035
TO
348 }
349 return self::$_pcpLinks;
350 }
351
352 /**
eceb18cc 353 * Delete the campaign page.
6a488035 354 *
ad37ac8e 355 * @param int $id
db95eff6 356 * Campaign page id.
6a488035
TO
357 */
358 public static function deleteById($id) {
359 CRM_Utils_Hook::pre('delete', 'Campaign', $id, CRM_Core_DAO::$_nullArray);
360
361 $transaction = new CRM_Core_Transaction();
362
363 // delete from pcp table
364 $pcp = new CRM_PCP_DAO_PCP();
365 $pcp->id = $id;
366 $pcp->delete();
367
368 $transaction->commit();
369
370 CRM_Utils_Hook::post('delete', 'Campaign', $id, $pcp);
371 }
372
373 /**
eceb18cc 374 * Build the form object.
6a488035 375 *
db95eff6
TO
376 * @param CRM_Core_Form $form
377 * Form object.
6a488035 378 */
cad004cf 379 public static function buildPCPForm($form) {
be2fb01f 380 $form->addElement('checkbox', 'pcp_active', ts('Enable Personal Campaign Pages?'), NULL, ['onclick' => "return showHideByValue('pcp_active',true,'pcpFields','block','radio',false);"]);
6a488035
TO
381
382 $form->addElement('checkbox', 'is_approval_needed', ts('Approval required'));
383
be2fb01f 384 $profile = [];
6a488035 385 $isUserRequired = NULL;
9d9922e7 386 $config = CRM_Core_Config::singleton();
6a488035
TO
387 if ($config->userFramework != 'Standalone') {
388 $isUserRequired = 2;
389 }
be2fb01f 390 CRM_Core_DAO::commonRetrieveAll('CRM_Core_DAO_UFGroup', 'is_cms_user', $isUserRequired, $profiles, [
9d9922e7 391 'title',
21dfd5f5 392 'is_active',
be2fb01f 393 ]);
6a488035
TO
394 if (!empty($profiles)) {
395 foreach ($profiles as $key => $value) {
396 if ($value['is_active']) {
397 $profile[$key] = $value['title'];
398 }
399 }
400 $form->assign('profile', $profile);
401 }
402
be2fb01f 403 $form->add('select', 'supporter_profile_id', ts('Supporter Profile'), ['' => ts('- select -')] + $profile, TRUE);
6a488035 404
12f92dbd
N
405 //CRM-15821 - To add new option for PCP "Owner" notification
406 $ownerNotifications = CRM_Core_OptionGroup::values('pcp_owner_notify');
5798d2ec 407 $form->addRadio('owner_notify_id', ts('Owner Email Notification'), $ownerNotifications, NULL, '<br/>', TRUE);
12f92dbd 408
be2fb01f 409 $form->addElement('checkbox', 'is_tellfriend_enabled', ts("Allow 'Tell a friend' functionality"), NULL, ['onclick' => "return showHideByValue('is_tellfriend_enabled',true,'tflimit','table-row','radio',false);"]);
6a488035 410
d70ada2a 411 $form->add('number',
6a488035
TO
412 'tellfriend_limit',
413 ts("'Tell a friend' maximum recipients limit"),
414 CRM_Core_DAO::getAttribute('CRM_PCP_DAO_PCPBlock', 'tellfriend_limit')
415 );
416 $form->addRule('tellfriend_limit', ts('Please enter a valid limit.'), 'integer');
417
418 $form->add('text',
419 'link_text',
420 ts("'Create Personal Campaign Page' link text"),
421 CRM_Core_DAO::getAttribute('CRM_PCP_DAO_PCPBlock', 'link_text')
422 );
423
424 $form->add('text', 'notify_email', ts('Notify Email'), CRM_Core_DAO::getAttribute('CRM_PCP_DAO_PCPBlock', 'notify_email'));
425 }
426
e0ef6999 427 /**
eceb18cc 428 * Add PCP form elements to a form.
d424ffde 429 *
db95eff6 430 * @param int $pcpId
bddddc63 431 * @param CRM_Core_Form $page
e0ef6999
EM
432 * @param null $elements
433 */
5fe87df6 434 public static function buildPcp($pcpId, &$page, &$elements = NULL) {
6a488035 435
be2fb01f 436 $prms = ['id' => $pcpId];
6a488035 437 CRM_Core_DAO::commonRetrieve('CRM_PCP_DAO_PCP', $prms, $pcpInfo);
6a488035
TO
438 if ($pcpSupporter = CRM_PCP_BAO_PCP::displayName($pcpId)) {
439 if ($pcpInfo['page_type'] == 'event') {
be2fb01f 440 $pcp_supporter_text = ts('This event registration is being made thanks to the efforts of <strong>%1</strong>, who supports our campaign. ', [1 => $pcpSupporter]);
eea141c0 441 $text = CRM_PCP_BAO_PCP::getPcpBlockStatus($pcpInfo['page_id'], 'event');
22e263ad 442 if (!empty($text)) {
eea141c0
DG
443 $pcp_supporter_text .= "You can support it as well - once you complete the registration, you will be able to create your own Personal Campaign Page!";
444 }
6a488035
TO
445 }
446 else {
be2fb01f 447 $pcp_supporter_text = ts('This contribution is being made thanks to the efforts of <strong>%1</strong>, who supports our campaign. ', [1 => $pcpSupporter]);
eea141c0 448 $text = CRM_PCP_BAO_PCP::getPcpBlockStatus($pcpInfo['page_id'], 'contribute');
22e263ad 449 if (!empty($text)) {
eea141c0
DG
450 $pcp_supporter_text .= "You can support it as well - once you complete the donation, you will be able to create your own Personal Campaign Page!";
451 }
6a488035 452 }
77b97be7 453
eea141c0 454 $page->assign('pcpSupporterText', $pcp_supporter_text);
6a488035
TO
455 }
456 $page->assign('pcp', TRUE);
457
458 // build honor roll fields for registration form if supporter has honor roll enabled for their PCP
459 if ($pcpInfo['is_honor_roll']) {
460 $page->assign('is_honor_roll', TRUE);
461 $page->add('checkbox', 'pcp_display_in_roll', ts('Show my support in the public honor roll'), NULL, NULL,
be2fb01f 462 ['onclick' => "showHideByValue('pcp_display_in_roll','','nameID|nickID|personalNoteID','block','radio',false); pcpAnonymous( );"]
6a488035 463 );
be2fb01f
CW
464 $extraOption = ['onclick' => "return pcpAnonymous( );"];
465 $elements = [];
353ffa53
TO
466 $elements[] = &$page->createElement('radio', NULL, '', ts('Include my name and message'), 0, $extraOption);
467 $elements[] = &$page->createElement('radio', NULL, '', ts('List my support anonymously'), 1, $extraOption);
6a488035
TO
468 $page->addGroup($elements, 'pcp_is_anonymous', NULL, '&nbsp;&nbsp;&nbsp;');
469 $page->_defaults['pcp_is_anonymous'] = 0;
470
be2fb01f
CW
471 $page->add('text', 'pcp_roll_nickname', ts('Name'), ['maxlength' => 30]);
472 $page->addField('pcp_personal_note', ['entity' => 'ContributionSoft', 'context' => 'create', 'style' => 'height: 3em; width: 40em;']);
6a488035
TO
473 }
474 else {
475 $page->assign('is_honor_roll', FALSE);
476 }
477 }
478
e0ef6999 479 /**
eceb18cc 480 * Process a PCP contribution.
d424ffde 481 *
100fef9d 482 * @param int $pcpId
ad37ac8e 483 * @param string $component
484 * @param string $entity
e0ef6999
EM
485 *
486 * @return array
487 */
9d9922e7 488 public static function handlePcp($pcpId, $component, $entity) {
6a488035 489
9d9922e7 490 self::getPcpEntityTable($component);
6a488035
TO
491
492 if (!$pcpId) {
493 return FALSE;
494 }
495
676159c9 496 $pcpStatus = CRM_Core_PseudoConstant::get('CRM_PCP_BAO_PCP', 'status_id');
497 $approvedId = array_search('Approved', $pcpStatus);
6a488035 498
be2fb01f 499 $params = ['id' => $pcpId];
6a488035
TO
500 CRM_Core_DAO::commonRetrieve('CRM_PCP_DAO_PCP', $params, $pcpInfo);
501
be2fb01f 502 $params = ['id' => $pcpInfo['pcp_block_id']];
6a488035
TO
503 CRM_Core_DAO::commonRetrieve('CRM_PCP_DAO_PCPBlock', $params, $pcpBlock);
504
be2fb01f 505 $params = ['id' => $pcpInfo['page_id']];
9d9922e7 506 $now = time();
6a488035
TO
507
508 if ($component == 'event') {
509 // figure out where to redirect if an exception occurs below based on target entity
510 $urlBase = 'civicrm/event/register';
511
512 // ignore startDate for events - PCP's can be active long before event start date
513 $startDate = 0;
9d9922e7 514 $endDate = CRM_Utils_Date::unixTime(CRM_Utils_Array::value('end_date', $entity));
6a488035 515 }
6a488035
TO
516 elseif ($component == 'contribute') {
517 $urlBase = 'civicrm/contribute/transact';
518 //start and end date of the contribution page
519 $startDate = CRM_Utils_Date::unixTime(CRM_Utils_Array::value('start_date', $entity));
9d9922e7 520 $endDate = CRM_Utils_Date::unixTime(CRM_Utils_Array::value('end_date', $entity));
6a488035
TO
521 }
522
523 // define redirect url back to contrib page or event if needed
481a74f4 524 $url = CRM_Utils_System::url($urlBase, "reset=1&id={$pcpBlock['entity_id']}", FALSE, NULL, FALSE, TRUE);
ed71bbca 525 $currentPCPStatus = CRM_Core_PseudoConstant::getName('CRM_PCP_BAO_PCP', 'status_id', $pcpInfo['status_id']);
6a488035
TO
526
527 if ($pcpBlock['target_entity_id'] != $entity['id']) {
528 $statusMessage = ts('This page is not related to the Personal Campaign Page you have just visited. However you can still make a contribution here.');
529 CRM_Core_Error::statusBounce($statusMessage, $url);
530 }
ed71bbca 531 elseif ($currentPCPStatus !== 'Approved') {
be2fb01f 532 $statusMessage = ts('The Personal Campaign Page you have just visited is currently %1. However you can still support the campaign here.', [1 => $pcpStatus[$pcpInfo['status_id']]]);
6a488035
TO
533 CRM_Core_Error::statusBounce($statusMessage, $url);
534 }
a7488080 535 elseif (empty($pcpBlock['is_active'])) {
6a488035
TO
536 $statusMessage = ts('Personal Campaign Pages are currently not enabled for this contribution page. However you can still support the campaign here.');
537 CRM_Core_Error::statusBounce($statusMessage, $url);
538 }
a7488080 539 elseif (empty($pcpInfo['is_active'])) {
6a488035
TO
540 $statusMessage = ts('The Personal Campaign Page you have just visited is currently inactive. However you can still support the campaign here.');
541 CRM_Core_Error::statusBounce($statusMessage, $url);
542 }
543 // Check if we're in range for contribution page start and end dates. for events, check if after event end date
544 elseif (($startDate && $startDate > $now) || ($endDate && $endDate < $now)) {
545 $customStartDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('start_date', $entity));
546 $customEndDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('end_date', $entity));
547 if ($startDate && $endDate) {
548 $statusMessage = ts('The Personal Campaign Page you have just visited is only active from %1 to %2. However you can still support the campaign here.',
be2fb01f 549 [1 => $customStartDate, 2 => $customEndDate]
6a488035
TO
550 );
551 CRM_Core_Error::statusBounce($statusMessage, $url);
552 }
553 elseif ($startDate) {
be2fb01f 554 $statusMessage = ts('The Personal Campaign Page you have just visited will be active beginning on %1. However you can still support the campaign here.', [1 => $customStartDate]);
6a488035
TO
555 CRM_Core_Error::statusBounce($statusMessage, $url);
556 }
557 elseif ($endDate) {
558 if ($component == 'event') {
559 // Target_entity is an event and the event is over, redirect to event info instead of event registration page.
560 $url = CRM_Utils_System::url('civicrm/event/info',
561 "reset=1&id={$pcpBlock['entity_id']}",
562 FALSE, NULL, FALSE, TRUE
563 );
be2fb01f 564 $statusMessage = ts('The event linked to the Personal Campaign Page you have just visited is over (as of %1).', [1 => $customEndDate]);
6a488035 565 CRM_Core_Error::statusBounce($statusMessage, $url);
9d9922e7 566 }
567 else {
be2fb01f 568 $statusMessage = ts('The Personal Campaign Page you have just visited is no longer active (as of %1). However you can still support the campaign here.', [1 => $customEndDate]);
6a488035
TO
569 CRM_Core_Error::statusBounce($statusMessage, $url);
570 }
571 }
572 }
573
be2fb01f 574 return [
6a488035
TO
575 'pcpId' => $pcpId,
576 'pcpBlock' => $pcpBlock,
577 'pcpInfo' => $pcpInfo,
be2fb01f 578 ];
6a488035
TO
579 }
580
581 /**
54957108 582 * Approve / Reject the campaign page.
6a488035 583 *
db95eff6
TO
584 * @param int $id
585 * Campaign page id.
6a488035 586 *
ad37ac8e 587 * @param bool $is_active
6a488035 588 */
00be9182 589 public static function setIsActive($id, $is_active) {
6a488035
TO
590 switch ($is_active) {
591 case 0:
592 $is_active = 3;
593 break;
594
595 case 1:
596 $is_active = 2;
597 break;
598 }
599
600 CRM_Core_DAO::setFieldValue('CRM_PCP_DAO_PCP', $id, 'status_id', $is_active);
601
9d9922e7 602 $pcpTitle = CRM_Core_DAO::getFieldValue('CRM_PCP_DAO_PCP', $id, 'title');
603 $pcpPageType = CRM_Core_DAO::getFieldValue('CRM_PCP_DAO_PCP', $id, 'page_type');
6a488035 604
2158332a 605 $pcpStatus = CRM_Core_OptionGroup::values("pcp_status");
6a488035
TO
606 $pcpStatus = $pcpStatus[$is_active];
607
be2fb01f 608 CRM_Core_Session::setStatus(ts("%1 status has been updated to %2.", [
9d9922e7 609 1 => $pcpTitle,
21dfd5f5 610 2 => $pcpStatus,
be2fb01f 611 ]), 'Status Updated', 'success');
6a488035
TO
612
613 // send status change mail
614 $result = self::sendStatusUpdate($id, $is_active, FALSE, $pcpPageType);
615
616 if ($result) {
617 CRM_Core_Session::setStatus(ts("A notification email has been sent to the supporter."), ts('Email Sent'), 'success');
618 }
619 }
620
621 /**
ad37ac8e 622 * Send notification email to supporter.
623 *
6a488035
TO
624 * 1. when their PCP status is changed by site admin.
625 * 2. when supporter initially creates a Personal Campaign Page ($isInitial set to true).
626 *
db95eff6
TO
627 * @param int $pcpId
628 * Campaign page id.
629 * @param int $newStatus
630 * Pcp status id.
2a6da8d7 631 * @param bool|int $isInitial is it the first time, campaign page has been created by the user
6a488035 632 *
2a6da8d7
EM
633 * @param string $component
634 *
635 * @throws Exception
6a488035 636 * @return null
6a488035 637 */
00be9182 638 public static function sendStatusUpdate($pcpId, $newStatus, $isInitial = FALSE, $component = 'contribute') {
aef123f6
C
639 $pcpStatusName = CRM_Core_OptionGroup::values("pcp_status", FALSE, FALSE, FALSE, NULL, 'name');
640 $pcpStatus = CRM_Core_OptionGroup::values("pcp_status");
6a488035
TO
641 $config = CRM_Core_Config::singleton();
642
643 if (!isset($pcpStatus[$newStatus])) {
644 return FALSE;
645 }
646
647 require_once 'Mail/mime.php';
648
649 //set loginUrl
650 $loginURL = $config->userSystem->getLoginURL();
651
652 // used in subject templates
653 $contribPageTitle = self::getPcpPageTitle($pcpId, $component);
654
be2fb01f 655 $tplParams = [
6a488035
TO
656 'loginUrl' => $loginURL,
657 'contribPageTitle' => $contribPageTitle,
658 'pcpId' => $pcpId,
be2fb01f 659 ];
6a488035
TO
660
661 //get the default domain email address.
662 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail();
663
664 if (!$domainEmailAddress || $domainEmailAddress == 'info@EXAMPLE.ORG') {
665 $fixUrl = CRM_Utils_System::url("civicrm/admin/domain", 'action=update&reset=1');
be2fb01f 666 CRM_Core_Error::fatal(ts('The site administrator needs to enter a valid \'FROM Email Address\' in <a href="%1">Administer CiviCRM &raquo; Communications &raquo; FROM Email Addresses</a>. The email address used may need to be a valid mail account with your email service provider.', [1 => $fixUrl]));
6a488035
TO
667 }
668
669 $receiptFrom = '"' . $domainEmailName . '" <' . $domainEmailAddress . '>';
670
671 // get recipient (supporter) name and email
be2fb01f 672 $params = ['id' => $pcpId];
6a488035
TO
673 CRM_Core_DAO::commonRetrieve('CRM_PCP_DAO_PCP', $params, $pcpInfo);
674 list($name, $address) = CRM_Contact_BAO_Contact_Location::getEmailDetails($pcpInfo['contact_id']);
675
676 // get pcp block info
677 list($blockId, $eid) = self::getPcpBlockEntityId($pcpId, $component);
be2fb01f 678 $params = ['id' => $blockId];
6a488035
TO
679 CRM_Core_DAO::commonRetrieve('CRM_PCP_DAO_PCPBlock', $params, $pcpBlockInfo);
680
681 // assign urls required in email template
aef123f6 682 if ($pcpStatusName[$newStatus] == 'Approved') {
6a488035
TO
683 $tplParams['isTellFriendEnabled'] = $pcpBlockInfo['is_tellfriend_enabled'];
684 if ($pcpBlockInfo['is_tellfriend_enabled']) {
685 $pcpTellFriendURL = CRM_Utils_System::url('civicrm/friend',
686 "reset=1&eid=$pcpId&blockId=$blockId&pcomponent=pcp",
687 TRUE, NULL, FALSE, TRUE
688 );
689 $tplParams['pcpTellFriendURL'] = $pcpTellFriendURL;
690 }
691 }
692 $pcpInfoURL = CRM_Utils_System::url('civicrm/pcp/info',
693 "reset=1&id=$pcpId",
694 TRUE, NULL, FALSE, TRUE
695 );
696 $tplParams['pcpInfoURL'] = $pcpInfoURL;
697 $tplParams['contribPageTitle'] = $contribPageTitle;
698 if ($emails = CRM_Utils_Array::value('notify_email', $pcpBlockInfo)) {
699 $emailArray = explode(',', $emails);
700 $tplParams['pcpNotifyEmailAddress'] = $emailArray[0];
701 }
702 // get appropriate message based on status
703 $tplParams['pcpStatus'] = $pcpStatus[$newStatus];
704
705 $tplName = $isInitial ? 'pcp_supporter_notify' : 'pcp_status_change';
706
c6327d7d 707 list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate(
be2fb01f 708 [
6a488035
TO
709 'groupName' => 'msg_tpl_workflow_contribution',
710 'valueName' => $tplName,
711 'contactId' => $pcpInfo['contact_id'],
712 'tplParams' => $tplParams,
713 'from' => $receiptFrom,
714 'toName' => $name,
715 'toEmail' => $address,
be2fb01f 716 ]
6a488035
TO
717 );
718 return $sent;
719 }
720
721 /**
ad37ac8e 722 * Enable / Disable the campaign page.
6a488035 723 *
db95eff6
TO
724 * @param int $id
725 * Campaign page id.
6a488035 726 *
ad37ac8e 727 * @param bool $is_active
8a4fede3 728 *
729 * @return bool
730 * true if we found and updated the object, else false
6a488035 731 */
00be9182 732 public static function setDisable($id, $is_active) {
6a488035
TO
733 return CRM_Core_DAO::setFieldValue('CRM_PCP_DAO_PCP', $id, 'is_active', $is_active);
734 }
735
736 /**
eceb18cc 737 * Get pcp block is active.
6a488035 738 *
c490a46a 739 * @param int $pcpId
2a6da8d7 740 * @param $component
6a488035
TO
741 *
742 * @return int
6a488035 743 */
00be9182 744 public static function getStatus($pcpId, $component) {
6a488035
TO
745 $query = "
746 SELECT pb.is_active
747 FROM civicrm_pcp pcp
748 LEFT JOIN civicrm_pcp_block pb ON ( pcp.page_id = pb.entity_id )
749 WHERE pcp.id = %1
750 AND pb.entity_table = %2";
751
752 $entity_table = self::getPcpEntityTable($component);
753
be2fb01f 754 $params = [1 => [$pcpId, 'Integer'], 2 => [$entity_table, 'String']];
6a488035
TO
755 return CRM_Core_DAO::singleValueQuery($query, $params);
756 }
757
758 /**
eceb18cc 759 * Get pcp block is enabled for component page.
6a488035 760 *
c490a46a 761 * @param int $pageId
2a6da8d7 762 * @param $component
6a488035 763 *
c490a46a 764 * @return string
6a488035 765 */
00be9182 766 public static function getPcpBlockStatus($pageId, $component) {
6a488035
TO
767 $query = "
768 SELECT pb.link_text as linkText
eea141c0
DG
769 FROM civicrm_pcp_block pb
770 WHERE pb.is_active = 1 AND
771 pb.entity_id = %1 AND
772 pb.entity_table = %2";
6a488035
TO
773
774 $entity_table = self::getPcpEntityTable($component);
775
be2fb01f 776 $params = [1 => [$pageId, 'Integer'], 2 => [$entity_table, 'String']];
6a488035
TO
777 return CRM_Core_DAO::singleValueQuery($query, $params);
778 }
779
780 /**
eceb18cc 781 * Find out if the PCP block is in use by one or more PCP page.
6a488035 782 *
db95eff6
TO
783 * @param int $id
784 * Pcp block id.
6a488035 785 *
d5cc0fc2 786 * @return Bool
6a488035 787 */
00be9182 788 public static function getPcpBlockInUse($id) {
6a488035
TO
789 $query = "
790 SELECT count(*)
791 FROM civicrm_pcp pcp
792 WHERE pcp.pcp_block_id = %1";
793
be2fb01f 794 $params = [1 => [$id, 'Integer']];
6a488035
TO
795 $result = CRM_Core_DAO::singleValueQuery($query, $params);
796 return $result > 0;
797 }
798
799 /**
100fef9d 800 * Get email is enabled for supporter's profile
6a488035 801 *
db95eff6
TO
802 * @param int $profileId
803 * Supporter's profile id.
6a488035 804 *
d5cc0fc2 805 * @return bool
6a488035 806 */
00be9182 807 public static function checkEmailProfile($profileId) {
6a488035
TO
808 $query = "
809SELECT field_name
810FROM civicrm_uf_field
811WHERE field_name like 'email%' And is_active = 1 And uf_group_id = %1";
812
be2fb01f 813 $params = [1 => [$profileId, 'Integer']];
6a488035
TO
814 $dao = CRM_Core_DAO::executeQuery($query, $params);
815 if (!$dao->fetch()) {
816 return TRUE;
817 }
818 return FALSE;
819 }
820
821 /**
eceb18cc 822 * Obtain the title of page associated with a pcp.
6a488035 823 *
c490a46a 824 * @param int $pcpId
dd244018
EM
825 * @param $component
826 *
6a488035 827 * @return int
6a488035 828 */
00be9182 829 public static function getPcpPageTitle($pcpId, $component) {
6a488035
TO
830 if ($component == 'contribute') {
831 $query = "
832 SELECT cp.title
833 FROM civicrm_pcp pcp
834 LEFT JOIN civicrm_contribution_page as cp ON ( cp.id = pcp.page_id )
835 WHERE pcp.id = %1";
836 }
837 elseif ($component == 'event') {
838 $query = "
839 SELECT ce.title
840 FROM civicrm_pcp pcp
841 LEFT JOIN civicrm_event as ce ON ( ce.id = pcp.page_id )
842 WHERE pcp.id = %1";
843 }
844
be2fb01f 845 $params = [1 => [$pcpId, 'Integer']];
6a488035
TO
846 return CRM_Core_DAO::singleValueQuery($query, $params);
847 }
848
849 /**
100fef9d 850 * Get pcp block & entity id given pcp id
6a488035 851 *
c490a46a 852 * @param int $pcpId
dd244018
EM
853 * @param $component
854 *
d5cc0fc2 855 * @return string
6a488035 856 */
00be9182 857 public static function getPcpBlockEntityId($pcpId, $component) {
6a488035
TO
858 $entity_table = self::getPcpEntityTable($component);
859
860 $query = "
861SELECT pb.id as pcpBlockId, pb.entity_id
862FROM civicrm_pcp pcp
863LEFT JOIN civicrm_pcp_block pb ON ( pb.entity_id = pcp.page_id AND pb.entity_table = %2 )
864WHERE pcp.id = %1";
865
be2fb01f 866 $params = [1 => [$pcpId, 'Integer'], 2 => [$entity_table, 'String']];
6a488035
TO
867 $dao = CRM_Core_DAO::executeQuery($query, $params);
868 if ($dao->fetch()) {
be2fb01f 869 return [$dao->pcpBlockId, $dao->entity_id];
6a488035
TO
870 }
871
be2fb01f 872 return [];
6a488035
TO
873 }
874
875 /**
100fef9d 876 * Get pcp entity table given a component.
6a488035 877 *
2a6da8d7
EM
878 * @param $component
879 *
d5cc0fc2 880 * @return string
6a488035 881 */
00be9182 882 public static function getPcpEntityTable($component) {
be2fb01f 883 $entity_table_map = [
6a488035
TO
884 'event' => 'civicrm_event',
885 'civicrm_event' => 'civicrm_event',
886 'contribute' => 'civicrm_contribution_page',
887 'civicrm_contribution_page' => 'civicrm_contribution_page',
be2fb01f 888 ];
6a488035
TO
889 return isset($entity_table_map[$component]) ? $entity_table_map[$component] : FALSE;
890 }
891
892 /**
eceb18cc 893 * Get supporter profile id.
6a488035 894 *
c490a46a 895 * @param int $component_id
fd31fa4c
EM
896 * @param string $component
897 *
6a488035 898 * @return int
6a488035 899 */
c1204160 900 public static function getSupporterProfileId($component_id, $component = 'contribute') {
6a488035
TO
901 $entity_table = self::getPcpEntityTable($component);
902
903 $query = "
904SELECT pcp.supporter_profile_id
905FROM civicrm_pcp_block pcp
906INNER JOIN civicrm_uf_group ufgroup
907 ON pcp.supporter_profile_id = ufgroup.id
908 WHERE pcp.entity_id = %1
909 AND pcp.entity_table = %2
910 AND ufgroup.is_active = 1";
911
be2fb01f 912 $params = [1 => [$component_id, 'Integer'], 2 => [$entity_table, 'String']];
6a488035
TO
913 if (!$supporterProfileId = CRM_Core_DAO::singleValueQuery($query, $params)) {
914 CRM_Core_Error::fatal(ts('Supporter profile is not set for this Personal Campaign Page or the profile is disabled. Please contact the site administrator if you need assistance.'));
915 }
916 else {
917 return $supporterProfileId;
918 }
919 }
96025800 920
12f92dbd 921 /**
eceb18cc 922 * Get owner notification id.
12f92dbd 923 *
5fe87df6 924 * @param int $component_id
12f92dbd
N
925 * @param $component
926 *
12f92dbd
N
927 * @return int
928 */
5fe87df6
N
929 public static function getOwnerNotificationId($component_id, $component = 'contribute') {
930 $entity_table = self::getPcpEntityTable($component);
12f92dbd
N
931 $query = "
932 SELECT pb.owner_notify_id
933 FROM civicrm_pcp_block pb
5fe87df6 934 WHERE pb.entity_id = %1 AND pb.entity_table = %2";
be2fb01f 935 $params = [1 => [$component_id, 'Integer'], 2 => [$entity_table, 'String']];
5fe87df6
N
936 if (!$ownerNotificationId = CRM_Core_DAO::singleValueQuery($query, $params)) {
937 CRM_Core_Error::fatal(ts('Owner Notification is not set for this Personal Campaign Page. Please contact the site administrator if you need assistance.'));
938 }
939 else {
940 return $ownerNotificationId;
941 }
12f92dbd 942 }
eceb18cc 943
6a488035 944}