4 +--------------------------------------------------------------------+
5 | CiviCRM version 4.7 |
6 +--------------------------------------------------------------------+
7 | Copyright CiviCRM LLC (c) 2004-2017 |
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
20 | You should have received a copy of the GNU Affero General Public |
21 | License and the CiviCRM Licensing Exception along |
22 | with this program; if not, contact CiviCRM LLC |
23 | at info[AT]civicrm[DOT]org. If you have questions about the |
24 | GNU Affero General Public License or the licensing of CiviCRM, |
25 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
26 +--------------------------------------------------------------------+
32 * @copyright CiviCRM LLC (c) 2004-2017
38 * This class generates form components to transfer an Event to another participant
41 class CRM_Event_Form_SelfSvcTransfer
extends CRM_Core_Form
{
48 protected $_from_participant_id;
55 protected $_from_contact_id;
57 * last name of the particpant to transfer to
62 protected $_to_contact_last_name;
64 * first name of the particpant to transfer to
69 protected $_to_contact_first_name;
71 * email of participant
76 protected $_to_contact_email;
82 protected $_to_contact_id;
84 * event to be cancelled/transferred
94 protected $_event_title;
100 protected $_event_start_date;
112 protected $_participant = array();
118 protected $_part_values;
124 protected $_details = array();
130 protected $_line_items = array();
136 protected $contact_id;
139 * Get source values for transfer based on participant id in URL. Line items will
140 * be transferred to this participant - at this point no transaction changes processed
144 public function preProcess() {
145 $config = CRM_Core_Config
::singleton();
146 $session = CRM_Core_Session
::singleton();
147 $this->_userContext
= $session->readUserContext();
148 $this->_from_participant_id
= CRM_Utils_Request
::retrieve('pid', 'Positive', $this, FALSE, NULL, 'REQUEST');
149 $this->_userChecksum
= CRM_Utils_Request
::retrieve('cs', 'String', $this, FALSE, NULL, 'REQUEST');
150 $params = array('id' => $this->_from_participant_id
);
151 $participant = $values = array();
152 $this->_participant
= CRM_Event_BAO_Participant
::getValues($params, $values, $participant);
153 $this->_part_values
= $values[$this->_from_participant_id
];
154 $this->set('values', $this->_part_values
);
155 $this->_event_id
= $this->_part_values
['event_id'];
156 $url = CRM_Utils_System
::url('civicrm/event/info', "reset=1&id={$this->_event_id}");
157 $this->_from_contact_id
= $this->_part_values
['participant_contact_id'];
158 $validUser = CRM_Contact_BAO_Contact_Utils
::validChecksum($this->_from_contact_id
, $this->_userChecksum
);
159 if (!$validUser && !CRM_Core_Permission
::check('edit all events')) {
160 CRM_Core_Error
::statusBounce(ts('You do not have sufficient permission to transfer/cancel this participant.'), $url);
162 $this->assign('action', $this->_action
);
163 if ($this->_from_participant_id
) {
164 $this->assign('participantId', $this->_from_participant_id
);
168 $this->_event_title
= CRM_Event_BAO_Event
::getFieldValue('CRM_Event_DAO_Event', $this->_event_id
, $daoName);
169 $daoName = 'start_date';
170 $this->_event_start_date
= CRM_Event_BAO_Event
::getFieldValue('CRM_Event_DAO_Event', $this->_event_id
, $daoName);
171 list($displayName, $email) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($this->_from_contact_id
);
172 $this->_contact_name
= $displayName;
173 $this->_contact_email
= $email;
175 $details = CRM_Event_BAO_Participant
::participantDetails($this->_from_participant_id
);
176 $optionGroupId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_OptionGroup', 'participant_role', 'id', 'name');
178 SELECT cpst.name as status, cov.name as role, cp.fee_level, cp.fee_amount, cp.register_date, civicrm_event.start_date
179 FROM civicrm_participant cp
180 LEFT JOIN civicrm_participant_status_type cpst ON cpst.id = cp.status_id
181 LEFT JOIN civicrm_option_value cov ON cov.value = cp.role_id and cov.option_group_id = {$optionGroupId}
182 LEFT JOIN civicrm_event ON civicrm_event.id = cp.event_id
183 WHERE cp.id = {$this->_from_participant_id}";
184 $dao = CRM_Core_DAO
::executeQuery($query);
185 while ($dao->fetch()) {
186 $details['status'] = $dao->status
;
187 $details['role'] = $dao->role
;
188 $details['fee_level'] = $dao->fee_level
;
189 $details['fee_amount'] = $dao->fee_amount
;
190 $details['register_date'] = $dao->register_date
;
191 $details['event_start_date'] = $dao->start_date
;
193 $this->assign('details', $details);
194 //This participant row will be cancelled. Get line item(s) to cancel
195 $this->selfsvctransferUrl
= CRM_Utils_System
::url('civicrm/event/selfsvcupdate',
196 "reset=1&id={$this->_from_participant_id}&id=0");
197 $this->selfsvctransferText
= ts('Update');
198 $this->selfsvctransferButtonText
= ts('Update');
202 * Build form for input of transferree email, name
206 public function buildQuickForm() {
207 $this->add('text', 'email', ts('To Email'), ts($this->_contact_email
), TRUE);
208 $this->add('text', 'last_name', ts('To Last Name'), ts($this->_to_contact_last_name
), TRUE);
209 $this->add('text', 'first_name', ts('To First Name'), ts($this->_to_contact_first_name
), TRUE);
210 $this->addButtons(array(
213 'name' => ts('Transfer Registration'),),
216 $this->addFormRule(array('CRM_Event_Form_SelfSvcTransfer', 'formRule'), $this);
217 parent
::buildQuickForm();
223 * return @array _defaults
225 public function setDefaultValues() {
226 $this->_defaults
= array();
227 return $this->_defaults
;
231 * Validate email and name input
233 * return array $errors
235 public static function formRule($fields, $files, $self) {
237 //check that either an email or firstname+lastname is included in the form(CRM-9587)
238 $to_contact_id = self
::checkProfileComplete($fields, $errors, $self);
239 //To check if the user is already registered for the event(CRM-2426)
240 if ($to_contact_id) {
241 self
::checkRegistration($fields, $self, $to_contact_id, $errors);
243 //return parent::formrule($fields, $files, $self);
244 return empty($errors) ?
TRUE : $errors;
248 * Check whether profile (name, email) is complete
252 public static function checkProfileComplete($fields, &$errors, $self) {
254 foreach ($fields as $fieldname => $fieldvalue) {
255 if (substr($fieldname, 0, 5) == 'email' && $fieldvalue) {
256 $email = $fieldvalue;
259 if (!$email && !(CRM_Utils_Array
::value('first_name', $fields) &&
260 CRM_Utils_Array
::value('last_name', $fields))) {
261 $defaults = $params = array('id' => $eventId);
262 CRM_Event_BAO_Event
::retrieve($params, $defaults);
263 $message = ts("Mandatory fields (first name and last name, OR email address) are missing from this form.");
264 $errors['_qf_default'] = $message;
266 $contact = CRM_Contact_BAO_Contact
::matchContactOnEmail($email, "");
267 $contact_id = empty($contact->contact_id
) ?
NULL : $contact->contact_id
;
268 if (!CRM_Utils_Rule
::email($fields['email'])) {
269 $errors['email'] = ts('Enter valid email address.');
271 if (empty($errors) && empty($contact_id)) {
273 'email-Primary' => CRM_Utils_Array
::value('email', $fields, NULL),
274 'first_name' => CRM_Utils_Array
::value('first_name', $fields, NULL),
275 'last_name' => CRM_Utils_Array
::value('last_name', $fields, NULL),
276 'is_deleted' => CRM_Utils_Array
::value('is_deleted', $fields, FALSE),);
277 //create new contact for this name/email pair
278 //if new contact, no need to check for contact already registered
279 $contact_id = CRM_Contact_BAO_Contact
::createProfileContact($params, $fields, $contact_id);
285 * Check contact details
289 public static function checkRegistration($fields, $self, $contact_id, &$errors) {
290 // verify whether this contact already registered for this event
291 $contact_details = CRM_Contact_BAO_Contact
::getContactDetails($contact_id);
292 $display_name = $contact_details[0];
293 $query = "select event_id from civicrm_participant where contact_id = " . $contact_id;
294 $dao = CRM_Core_DAO
::executeQuery($query);
295 while ($dao->fetch()) {
296 $to_event_id[] = $dao->event_id
;
298 if (!empty($to_event_id)) {
299 foreach ($to_event_id as $id) {
300 if ($id == $self->_event_id
) {
301 $errors['email'] = $display_name . ts(" is already registered for this event");
308 * Process transfer - first add the new participant to the event, then cancel
309 * source participant - send confirmation email to transferee
311 public function postProcess() {
312 //For transfer, process form to allow selection of transferree
313 $params = $this->controller
->exportValues($this->_name
);
314 //cancel 'from' participant row
315 $query = "select contact_id from civicrm_email where email = '" . $params['email'] . "'";
316 $dao = CRM_Core_DAO
::executeQuery($query);
317 while ($dao->fetch()) {
318 $contact_id = $dao->contact_id
;
320 $from_participant = $params = array();
321 $query = "select role_id, source, fee_level, is_test, is_pay_later, fee_amount, discount_id, fee_currency,campaign_id, discount_amount from civicrm_participant where id = " . $this->_from_participant_id
;
322 $dao = CRM_Core_DAO
::executeQuery($query);
324 while ($dao->fetch()) {
325 $value_to['role_id'] = $dao->role_id
;
326 $value_to['source'] = $dao->source
;
327 $value_to['fee_level'] = $dao->fee_level
;
328 $value_to['is_test'] = $dao->is_test
;
329 $value_to['is_pay_later'] = $dao->is_pay_later
;
330 $value_to['fee_amount'] = $dao->fee_amount
;
332 $value_to['contact_id'] = $contact_id;
333 $value_to['event_id'] = $this->_event_id
;
334 $value_to['status_id'] = 1;
335 $value_to['register_date'] = date("Y-m-d");
336 //first create the new participant row -don't set registered_by yet or email won't be sent
337 $participant = CRM_Event_BAO_Participant
::create($value_to);
338 //send a confirmation email to the new participant
339 $this->participantTransfer($participant);
340 //now update registered_by_id
341 $query = "UPDATE civicrm_participant cp SET cp.registered_by_id = %1 WHERE cp.id = ({$participant->id})";
342 $params = array(1 => array($this->_from_participant_id
, 'Integer'));
343 $dao = CRM_Core_DAO
::executeQuery($query, $params);
344 //copy line items to new participant
345 $line_items = CRM_Price_BAO_LineItem
::getLineItems($this->_from_participant_id
);
346 foreach ($line_items as $item) {
347 $item['entity_id'] = $participant->id
;
349 $item['entity_table'] = "civicrm_participant";
350 $new_item = CRM_Price_BAO_LineItem
::create($item);
352 //now cancel the from participant record, leaving the original line-item(s)
353 $value_from = array();
354 $value_from['id'] = $this->_from_participant_id
;
355 $tansferId = array_search('Transferred', CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Negative'"));
356 $value_from['status_id'] = $tansferId;
357 $value_from['transferred_to_contact_id'] = $contact_id;
358 $contact_details = CRM_Contact_BAO_Contact
::getContactDetails($contact_id);
359 $display_name = current($contact_details);
360 $this->assign('to_participant', $display_name);
361 CRM_Event_BAO_Participant
::create($value_from);
362 $this->sendCancellation();
363 list($displayName, $email) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contact_id);
364 $statusMsg = ts('Event registration information for %1 has been updated.', array(1 => $displayName));
365 $statusMsg .= ' ' . ts('A confirmation email has been sent to %1.', array(1 => $email));
366 CRM_Core_Session
::setStatus($statusMsg, ts('Registration Transferred'), 'success');
367 $url = CRM_Utils_System
::url('civicrm/event/info', "reset=1&id={$this->_event_id}");
368 CRM_Utils_System
::redirect($url);
372 * Based on input, create participant row for transferee and send email
376 public function participantTransfer($participant) {
377 $contactDetails = array();
378 $contactIds[] = $participant->contact_id
;
379 list($currentContactDetails) = CRM_Utils_Token
::getTokenDetails($contactIds, NULL,
380 FALSE, FALSE, NULL, array(), 'CRM_Event_BAO_Participant');
381 foreach ($currentContactDetails as $contactId => $contactValues) {
382 $contactDetails[$contactId] = $contactValues;
384 $participantRoles = CRM_Event_PseudoConstant
::participantRole();
385 $participantDetails = array();
386 $query = "SELECT * FROM civicrm_participant WHERE id = " . $participant->id
;
387 $dao = CRM_Core_DAO
::executeQuery($query);
388 while ($dao->fetch()) {
389 $participantDetails[$dao->id
] = array(
391 'role' => $participantRoles[$dao->role_id
],
392 'is_test' => $dao->is_test
,
393 'event_id' => $dao->event_id
,
394 'status_id' => $dao->status_id
,
395 'fee_amount' => $dao->fee_amount
,
396 'contact_id' => $dao->contact_id
,
397 'register_date' => $dao->register_date
,
398 'registered_by_id' => $dao->registered_by_id
,
401 $domainValues = array();
402 if (empty($domainValues)) {
403 $domain = CRM_Core_BAO_Domain
::getDomain();
412 'contact' => CRM_Core_SelectValues
::contactTokens(),
414 foreach ($tokens['domain'] as $token) {
415 $domainValues[$token] = CRM_Utils_Token
::getDomainTokenReplacement($token, $domain);
418 $eventDetails = array();
419 $eventParams = array('id' => $participant->event_id
);
420 CRM_Event_BAO_Event
::retrieve($eventParams, $eventDetails);
421 //get default participant role.
422 $eventDetails['participant_role'] = CRM_Utils_Array
::value($eventDetails['default_role_id'], $participantRoles);
423 //get the location info
425 'entity_id' => $participant->event_id
,
426 'entity_table' => 'civicrm_event',
428 $eventDetails['location'] = CRM_Core_BAO_Location
::getValues($locParams, TRUE);
429 $toEmail = CRM_Utils_Array
::value('email', $contactDetails[$participant->contact_id
]);
431 //take a receipt from as event else domain.
432 $receiptFrom = $domainValues['name'] . ' <' . $domainValues['email'] . '>';
433 if (!empty($eventDetails['confirm_from_name']) && !empty($eventDetails['confirm_from_email'])) {
434 $receiptFrom = $eventDetails['confirm_from_name'] . ' <' . $eventDetails['confirm_from_email'] . '>';
436 $participantName = $contactDetails[$participant->contact_id
]['display_name'];
438 'event' => $eventDetails,
439 'participant' => $participantDetails[$participant->id
],
440 'participantID' => $participant->id
,
441 'participant_status' => 'Registered',
444 $sendTemplateParams = array(
445 'groupName' => 'msg_tpl_workflow_event',
446 'valueName' => 'event_online_receipt',
447 'contactId' => $participantDetails[$participant->id
]['contact_id'],
448 'tplParams' => $tplParams,
449 'from' => $receiptFrom,
450 'toName' => $participantName,
451 'toEmail' => $toEmail,
452 'cc' => CRM_Utils_Array
::value('cc_confirm', $eventDetails),
453 'bcc' => CRM_Utils_Array
::value('bcc_confirm', $eventDetails),
455 CRM_Core_BAO_MessageTemplate
::sendTemplate($sendTemplateParams);
460 * Send confirmation of cancellation to source participant
464 public function sendCancellation() {
465 $domainValues = array();
466 $domain = CRM_Core_BAO_Domain
::getDomain();
475 'contact' => CRM_Core_SelectValues
::contactTokens(),
477 foreach ($tokens['domain'] as $token) {
478 $domainValues[$token] = CRM_Utils_Token
::getDomainTokenReplacement($token, $domain);
480 $participantRoles = array();
481 $participantRoles = CRM_Event_PseudoConstant
::participantRole();
482 $participantDetails = array();
483 $query = "SELECT * FROM civicrm_participant WHERE id = {$this->_from_participant_id}";
484 $dao = CRM_Core_DAO
::executeQuery($query);
485 while ($dao->fetch()) {
486 $participantDetails[$dao->id
] = array(
488 'role' => $participantRoles[$dao->role_id
],
489 'is_test' => $dao->is_test
,
490 'event_id' => $dao->event_id
,
491 'status_id' => $dao->status_id
,
492 'fee_amount' => $dao->fee_amount
,
493 'contact_id' => $dao->contact_id
,
494 'register_date' => $dao->register_date
,
495 'registered_by_id' => $dao->registered_by_id
,
498 $eventDetails = array();
499 $eventParams = array('id' => $this->_event_id
);
500 CRM_Event_BAO_Event
::retrieve($eventParams, $eventDetails[$this->_event_id
]);
501 //get default participant role.
502 $eventDetails[$this->_event_id
]['participant_role'] = CRM_Utils_Array
::value($eventDetails[$this->_event_id
]['default_role_id'], $participantRoles);
503 //get the location info
504 $locParams = array('entity_id' => $this->_event_id
, 'entity_table' => 'civicrm_event');
505 $eventDetails[$this->_event_id
]['location'] = CRM_Core_BAO_Location
::getValues($locParams, TRUE);
506 //get contact details
507 $contactIds[$this->_from_contact_id
] = $this->_from_contact_id
;
508 list($currentContactDetails) = CRM_Utils_Token
::getTokenDetails($contactIds, NULL,
509 FALSE, FALSE, NULL, array(),
510 'CRM_Event_BAO_Participant'
512 foreach ($currentContactDetails as $contactId => $contactValues) {
513 $contactDetails[$this->_from_contact_id
] = $contactValues;
515 //send a 'cancelled' email to user, and cc the event's cc_confirm email
516 $mail = CRM_Event_BAO_Participant
::sendTransitionParticipantMail($this->_from_participant_id
,
517 $participantDetails[$this->_from_participant_id
],
518 $eventDetails[$this->_event_id
],
519 $contactDetails[$this->_from_contact_id
],
524 $statusMsg = ts('Event registration information for %1 has been updated.', array(1 => $this->_contact_name
));
525 $statusMsg .= ' ' . ts('A cancellation email has been sent to %1.', array(1 => $this->_contact_email
));
526 CRM_Core_Session
::setStatus($statusMsg, ts('Thanks'), 'success');