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