3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * This class generates form components to allow an Event to be cancelled or transferred from an email link
22 class CRM_Event_Form_SelfSvcUpdate
extends CRM_Core_Form
{
29 protected $_participant_id;
36 protected $_contact_id;
38 * name of the particpant
43 protected $_contact_name;
45 * email of participant
49 protected $_contact_email;
51 * event to be cancelled/transferred
61 protected $_event_title;
67 protected $_event_start_date;
79 protected $_participant = [];
85 protected $_part_values;
87 * details of event registration values
91 protected $_details = [];
97 protected $isBackoffice = FALSE;
100 * Set variables up before form is built based on participant ID from URL
104 * @throws \CRM_Core_Exception
106 public function preProcess() {
107 $config = CRM_Core_Config
::singleton();
108 $session = CRM_Core_Session
::singleton();
109 $this->_userContext
= $session->readUserContext();
110 $participant = $values = [];
111 $this->_participant_id
= CRM_Utils_Request
::retrieve('pid', 'Positive', $this, FALSE, NULL, 'REQUEST');
112 $this->_userChecksum
= CRM_Utils_Request
::retrieve('cs', 'String', $this, FALSE, NULL, 'REQUEST');
113 $this->isBackoffice
= CRM_Utils_Request
::retrieve('is_backoffice', 'String', $this, FALSE, NULL, 'REQUEST');
114 $params = ['id' => $this->_participant_id
];
115 $this->_participant
= CRM_Event_BAO_Participant
::getValues($params, $values, $participant);
116 $this->_part_values
= $values[$this->_participant_id
];
117 $this->set('values', $this->_part_values
);
118 //fetch Event by event_id, verify that this event can still be xferred/cancelled
119 $this->_event_id
= $this->_part_values
['event_id'];
120 $url = CRM_Utils_System
::url('civicrm/event/info', "reset=1&id={$this->_event_id}");
121 $this->_contact_id
= $this->_part_values
['participant_contact_id'];
122 $validUser = CRM_Contact_BAO_Contact_Utils
::validChecksum($this->_contact_id
, $this->_userChecksum
);
123 if (!$validUser && !CRM_Core_Permission
::check('edit all events')) {
124 CRM_Core_Error
::statusBounce(ts('You do not have sufficient permission to transfer/cancel this participant.'), $url);
126 $this->assign('action', $this->_action
);
127 if ($this->_participant_id
) {
128 $this->assign('participantId', $this->_participant_id
);
132 $this->_event_title
= CRM_Event_BAO_Event
::getFieldValue('CRM_Event_DAO_Event', $this->_event_id
, $daoName);
133 $daoName = 'start_date';
134 $this->_event_start_date
= CRM_Event_BAO_Event
::getFieldValue('CRM_Event_DAO_Event', $this->_event_id
, $daoName);
135 list($displayName, $email) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($this->_contact_id
);
136 $this->_contact_name
= $displayName;
137 $this->_contact_email
= $email;
139 $details = CRM_Event_BAO_Participant
::participantDetails($this->_participant_id
);
140 $contributionId = CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_participant_id
, 'contribution_id', 'participant_id');
141 $this->assign('contributionId', $contributionId);
142 $selfServiceDetails = CRM_Event_BAO_Participant
::getSelfServiceEligibility($this->_participant_id
, $url, $this->isBackoffice
);
143 $details = array_merge($details, $selfServiceDetails);
144 $this->assign('details', $details);
145 $this->selfsvcupdateUrl
= CRM_Utils_System
::url('civicrm/event/selfsvcupdate', "reset=1&id={$this->_participant_id}&id=0");
146 $this->selfsvcupdateText
= ts('Update');
147 $this->selfsvcupdateButtonText
= ts('Update');
148 // Based on those ids retrieve event and verify it is eligible
149 // for self update (event.start_date > today, event can be 'self_updated'
150 // retrieve contact name and email, and let user verify his/her identity
154 * buildQuickForm -populate input variables for source Event
155 * to cancel or transfer to another person
159 public function buildQuickForm() {
160 $this->add('select', 'action', ts('Transfer or Cancel Registration'), [ts('-select-'), ts('Transfer'), ts('Cancel')], TRUE);
164 'name' => ts('Submit'),
167 $this->addFormRule(['CRM_Event_Form_SelfSvcUpdate', 'formRule'], $this);
168 parent
::buildQuickForm();
172 * Set default values for contact
176 public function setDefaultValues() {
177 $this->_defaults
= [];
178 $this->_defaults
['details'] = $this->_details
;
179 return $this->_defaults
;
183 * Validate action input
184 * @param array $fields
185 * Posted fields of the form.
190 * list of errors to be posted back to the form
192 public static function formRule($fields, $files, $self) {
194 if (empty($fields['action'])) {
195 $errors['action'] = ts("Please select Transfer OR Cancel action.");
197 return empty($errors) ?
TRUE : $errors;
201 * Process submit form - based on user selection of action
202 * transfer or cancel the event
206 public function postProcess() {
207 //if selection is cancel, cancel this participant' registration, process refund
208 //if transfer, process form to allow selection of transferree
209 $params = $this->controller
->exportValues($this->_name
);
210 $action = $params['action'];
211 if ($action == "1") {
212 $this->transferParticipant($params);
214 elseif ($action == "2") {
215 $this->cancelParticipant($params);
220 * Transfer to a new form, allowing selection of a new contact
221 * based on email and name. The Event will be transferred to this new participant
225 public function transferParticipant($params) {
226 CRM_Utils_System
::redirect(CRM_Utils_System
::url(
227 'civicrm/event/selfsvctransfer',
231 'pid' => $this->_participant_id
,
232 'cs' => $this->_userChecksum
,
233 'is_backoffice' => $this->isBackoffice
,
239 * Cancel this participant and finish, send cancellation email. At this point no
240 * auto-cancellation of payment is handled, so payment needs to be manually cancelled
244 * @throws \CRM_Core_Exception
246 public function cancelParticipant($params) {
247 //set participant record status to Cancelled, refund payment if possible
248 // send email to participant and admin, and log Activity
250 $value['id'] = $this->_participant_id
;
251 $cancelledId = array_search('Cancelled',
252 CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Negative'"));
253 $value['status_id'] = $cancelledId;
254 CRM_Event_BAO_Participant
::create($value);
256 $domain = CRM_Core_BAO_Domain
::getDomain();
265 'contact' => CRM_Core_SelectValues
::contactTokens(),
267 foreach ($tokens['domain'] as $token) {
268 $domainValues[$token] = CRM_Utils_Token
::getDomainTokenReplacement($token, $domain);
271 $participantRoles = CRM_Event_PseudoConstant
::participantRole();
272 $participantDetails = [];
273 $query = "SELECT * FROM civicrm_participant WHERE id = {$this->_participant_id}";
274 $dao = CRM_Core_DAO
::executeQuery($query);
275 while ($dao->fetch()) {
276 $participantDetails[$dao->id
] = [
278 'role' => $participantRoles[$dao->role_id
],
279 'is_test' => $dao->is_test
,
280 'event_id' => $dao->event_id
,
281 'status_id' => $dao->status_id
,
282 'fee_amount' => $dao->fee_amount
,
283 'contact_id' => $dao->contact_id
,
284 'register_date' => $dao->register_date
,
285 'registered_by_id' => $dao->registered_by_id
,
289 $eventParams = ['id' => $this->_event_id
];
290 CRM_Event_BAO_Event
::retrieve($eventParams, $eventDetails[$this->_event_id
]);
291 //get default participant role.
292 $eventDetails[$this->_event_id
]['participant_role'] = $participantRoles[$eventDetails[$this->_event_id
]['default_role_id']] ??
NULL;
293 //get the location info
294 $locParams = ['entity_id' => $this->_event_id
, 'entity_table' => 'civicrm_event'];
295 $eventDetails[$this->_event_id
]['location'] = CRM_Core_BAO_Location
::getValues($locParams, TRUE);
296 //get contact details
297 $contactIds[$this->_contact_id
] = $this->_contact_id
;
298 list($currentContactDetails) = CRM_Utils_Token
::getTokenDetails($contactIds, NULL,
299 FALSE, FALSE, NULL, [],
300 'CRM_Event_BAO_Participant'
302 foreach ($currentContactDetails as $contactId => $contactValues) {
303 $contactDetails[$this->_contact_id
] = $contactValues;
305 //send a 'cancelled' email to user, and cc the event's cc_confirm email
306 $mail = CRM_Event_BAO_Participant
::sendTransitionParticipantMail($this->_participant_id
,
307 $participantDetails[$this->_participant_id
],
308 $eventDetails[$this->_event_id
],
309 $contactDetails[$this->_contact_id
],
314 $statusMsg = ts('Event registration information for %1 has been updated.', [1 => $this->_contact_name
]);
315 $statusMsg .= ' ' . ts('A cancellation email has been sent to %1.', [1 => $this->_contact_email
]);
316 CRM_Core_Session
::setStatus($statusMsg, ts('Thanks'), 'success');
317 if (!empty($this->isBackoffice
)) {
320 $url = CRM_Utils_System
::url('civicrm/event/info', "reset=1&id={$this->_event_id}&noFullMsg=true");
321 CRM_Utils_System
::redirect($url);