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