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