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