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