Merge pull request #17981 from eileenmcnaughton/merge_form
[civicrm-core.git] / CRM / Event / Form / SelfSvcUpdate.php
CommitLineData
97d8187a 1<?php
97d8187a
DG
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
97d8187a 5 | |
bc77d7c0
TO
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 |
97d8187a
DG
9 +--------------------------------------------------------------------+
10 */
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
97d8187a
DG
16 */
17
18/**
19 * This class generates form components to allow an Event to be cancelled or transferred from an email link
20 *
21 */
22class CRM_Event_Form_SelfSvcUpdate extends CRM_Core_Form {
23 /**
24 * particpant id
25 *
26 * @var string
27 *
28 */
29 protected $_participant_id;
30 /**
31 * contact id
32 *
33 * @var string
34 *
35 */
36 protected $_contact_id;
37 /**
38 * name of the particpant
39 *
40 * @var string
41 *
42 */
43 protected $_contact_name;
44 /**
45 * email of participant
46 *
47 * @var string
48 */
49 protected $_contact_email;
50 /**
51 * event to be cancelled/transferred
52 *
53 * @var string
54 */
55 protected $_event_id;
56 /**
57 * event title
58 *
59 * @var string
60 */
61 protected $_event_title;
62 /**
63 * event title
64 *
65 * @var string
66 */
67 protected $_event_start_date;
68 /**
69 * action
70 *
71 * @var string
72 */
3a936dab 73 public $_action;
97d8187a
DG
74 /**
75 * participant object
76 *
77 * @var string
78 */
be2fb01f 79 protected $_participant = [];
97d8187a
DG
80 /**
81 * particpant values
82 *
83 * @var string
84 */
85 protected $_part_values;
86 /**
87 * details of event registration values
88 *
89 * @var array
90 */
be2fb01f 91 protected $_details = [];
e219d53b 92 /**
93 * Is backoffice form?
94 *
90b461f1 95 * @var bool
e219d53b 96 */
97 protected $isBackoffice = FALSE;
90b461f1 98
97d8187a
DG
99 /**
100 * Set variables up before form is built based on participant ID from URL
101 *
102 * @return void
5db18d97 103 *
104 * @throws \CRM_Core_Exception
97d8187a
DG
105 */
106 public function preProcess() {
107 $config = CRM_Core_Config::singleton();
108 $session = CRM_Core_Session::singleton();
109 $this->_userContext = $session->readUserContext();
be2fb01f 110 $participant = $values = [];
97d8187a 111 $this->_participant_id = CRM_Utils_Request::retrieve('pid', 'Positive', $this, FALSE, NULL, 'REQUEST');
af29aaac 112 $this->_userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this, FALSE, NULL, 'REQUEST');
c0fc0432 113 $this->isBackoffice = CRM_Utils_Request::retrieve('is_backoffice', 'String', $this, FALSE, FALSE, 'REQUEST') ?? FALSE;
be2fb01f 114 $params = ['id' => $this->_participant_id];
97d8187a
DG
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'];
af29aaac 120 $url = CRM_Utils_System::url('civicrm/event/info', "reset=1&id={$this->_event_id}");
97d8187a 121 $this->_contact_id = $this->_part_values['participant_contact_id'];
af29aaac 122 $validUser = CRM_Contact_BAO_Contact_Utils::validChecksum($this->_contact_id, $this->_userChecksum);
e3b510fe 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);
125 }
97d8187a
DG
126 $this->assign('action', $this->_action);
127 if ($this->_participant_id) {
128 $this->assign('participantId', $this->_participant_id);
129 }
5db18d97 130
97d8187a
DG
131 $daoName = 'title';
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;
5db18d97 138
97d8187a 139 $details = CRM_Event_BAO_Participant::participantDetails($this->_participant_id);
4abc4ee1 140 $contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_participant_id, 'contribution_id', 'participant_id');
141 $this->assign('contributionId', $contributionId);
4a3451de 142 $selfServiceDetails = CRM_Event_BAO_Participant::getSelfServiceEligibility($this->_participant_id, $url, $this->isBackoffice);
c0fc0432
JG
143 if (!$selfServiceDetails['eligible']) {
144 CRM_Core_Error::statusBounce($selfServiceDetails['ineligible_message'], $url, ts('Sorry'));
145 }
4a3451de 146 $details = array_merge($details, $selfServiceDetails);
97d8187a
DG
147 $this->assign('details', $details);
148 $this->selfsvcupdateUrl = CRM_Utils_System::url('civicrm/event/selfsvcupdate', "reset=1&id={$this->_participant_id}&id=0");
149 $this->selfsvcupdateText = ts('Update');
150 $this->selfsvcupdateButtonText = ts('Update');
151 // Based on those ids retrieve event and verify it is eligible
152 // for self update (event.start_date > today, event can be 'self_updated'
153 // retrieve contact name and email, and let user verify his/her identity
154 }
90b461f1 155
97d8187a
DG
156 /**
157 * buildQuickForm -populate input variables for source Event
158 * to cancel or transfer to another person
159 *
160 * return @void
161 */
162 public function buildQuickForm() {
be2fb01f
CW
163 $this->add('select', 'action', ts('Transfer or Cancel Registration'), [ts('-select-'), ts('Transfer'), ts('Cancel')], TRUE);
164 $this->addButtons([
165 [
97d8187a
DG
166 'type' => 'submit',
167 'name' => ts('Submit'),
be2fb01f
CW
168 ],
169 ]);
170 $this->addFormRule(['CRM_Event_Form_SelfSvcUpdate', 'formRule'], $this);
97d8187a
DG
171 parent::buildQuickForm();
172 }
974bdb44 173
97d8187a
DG
174 /**
175 * Set default values for contact
176 *
177 * return @void
178 */
179 public function setDefaultValues() {
be2fb01f 180 $this->_defaults = [];
97d8187a
DG
181 $this->_defaults['details'] = $this->_details;
182 return $this->_defaults;
183 }
974bdb44 184
e3b510fe 185 /**
186 * Validate action input
187 * @param array $fields
188 * Posted fields of the form.
189 * @param $files
190 * @param $self
191 *
192 * @return array
193 * list of errors to be posted back to the form
194 */
195 public static function formRule($fields, $files, $self) {
be2fb01f 196 $errors = [];
e3b510fe 197 if (empty($fields['action'])) {
198 $errors['action'] = ts("Please select Transfer OR Cancel action.");
199 }
200 return empty($errors) ? TRUE : $errors;
201 }
202
97d8187a
DG
203 /**
204 * Process submit form - based on user selection of action
205 * transfer or cancel the event
206 *
207 * return @void
208 */
209 public function postProcess() {
210 //if selection is cancel, cancel this participant' registration, process refund
211 //if transfer, process form to allow selection of transferree
212 $params = $this->controller->exportValues($this->_name);
213 $action = $params['action'];
214 if ($action == "1") {
97d8187a
DG
215 $this->transferParticipant($params);
216 }
217 elseif ($action == "2") {
97d8187a
DG
218 $this->cancelParticipant($params);
219 }
220 }
974bdb44 221
97d8187a
DG
222 /**
223 * Transfer to a new form, allowing selection of a new contact
224 * based on email and name. The Event will be transferred to this new participant
225 *
226 * return @void
227 */
228 public function transferParticipant($params) {
e219d53b 229 CRM_Utils_System::redirect(CRM_Utils_System::url(
230 'civicrm/event/selfsvctransfer',
be2fb01f 231 [
e219d53b 232 'reset' => 1,
233 'action' => 'add',
234 'pid' => $this->_participant_id,
235 'cs' => $this->_userChecksum,
cb98c7f9 236 'is_backoffice' => $this->isBackoffice,
be2fb01f 237 ]
e219d53b 238 ));
97d8187a 239 }
974bdb44 240
97d8187a
DG
241 /**
242 * Cancel this participant and finish, send cancellation email. At this point no
243 * auto-cancellation of payment is handled, so payment needs to be manually cancelled
244 *
245 * return @void
5db18d97 246 *
247 * @throws \CRM_Core_Exception
97d8187a
DG
248 */
249 public function cancelParticipant($params) {
250 //set participant record status to Cancelled, refund payment if possible
251 // send email to participant and admin, and log Activity
be2fb01f 252 $value = [];
97d8187a
DG
253 $value['id'] = $this->_participant_id;
254 $cancelledId = array_search('Cancelled',
255 CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Negative'"));
256 $value['status_id'] = $cancelledId;
257 CRM_Event_BAO_Participant::create($value);
be2fb01f 258 $domainValues = [];
97d8187a 259 $domain = CRM_Core_BAO_Domain::getDomain();
be2fb01f 260 $tokens = [
97d8187a 261 'domain' =>
be2fb01f 262 [
97d8187a
DG
263 'name',
264 'phone',
265 'address',
266 'email',
be2fb01f 267 ],
97d8187a 268 'contact' => CRM_Core_SelectValues::contactTokens(),
be2fb01f 269 ];
97d8187a
DG
270 foreach ($tokens['domain'] as $token) {
271 $domainValues[$token] = CRM_Utils_Token::getDomainTokenReplacement($token, $domain);
272 }
5db18d97 273
97d8187a 274 $participantRoles = CRM_Event_PseudoConstant::participantRole();
be2fb01f 275 $participantDetails = [];
97d8187a
DG
276 $query = "SELECT * FROM civicrm_participant WHERE id = {$this->_participant_id}";
277 $dao = CRM_Core_DAO::executeQuery($query);
278 while ($dao->fetch()) {
be2fb01f 279 $participantDetails[$dao->id] = [
97d8187a
DG
280 'id' => $dao->id,
281 'role' => $participantRoles[$dao->role_id],
282 'is_test' => $dao->is_test,
283 'event_id' => $dao->event_id,
284 'status_id' => $dao->status_id,
285 'fee_amount' => $dao->fee_amount,
286 'contact_id' => $dao->contact_id,
287 'register_date' => $dao->register_date,
288 'registered_by_id' => $dao->registered_by_id,
be2fb01f 289 ];
97d8187a 290 }
be2fb01f
CW
291 $eventDetails = [];
292 $eventParams = ['id' => $this->_event_id];
97d8187a
DG
293 CRM_Event_BAO_Event::retrieve($eventParams, $eventDetails[$this->_event_id]);
294 //get default participant role.
9c1bc317 295 $eventDetails[$this->_event_id]['participant_role'] = $participantRoles[$eventDetails[$this->_event_id]['default_role_id']] ?? NULL;
97d8187a 296 //get the location info
be2fb01f 297 $locParams = ['entity_id' => $this->_event_id, 'entity_table' => 'civicrm_event'];
97d8187a
DG
298 $eventDetails[$this->_event_id]['location'] = CRM_Core_BAO_Location::getValues($locParams, TRUE);
299 //get contact details
300 $contactIds[$this->_contact_id] = $this->_contact_id;
301 list($currentContactDetails) = CRM_Utils_Token::getTokenDetails($contactIds, NULL,
be2fb01f 302 FALSE, FALSE, NULL, [],
97d8187a
DG
303 'CRM_Event_BAO_Participant'
304 );
305 foreach ($currentContactDetails as $contactId => $contactValues) {
306 $contactDetails[$this->_contact_id] = $contactValues;
307 }
308 //send a 'cancelled' email to user, and cc the event's cc_confirm email
309 $mail = CRM_Event_BAO_Participant::sendTransitionParticipantMail($this->_participant_id,
310 $participantDetails[$this->_participant_id],
311 $eventDetails[$this->_event_id],
312 $contactDetails[$this->_contact_id],
313 $domainValues,
314 "Cancelled",
315 ""
316 );
be2fb01f
CW
317 $statusMsg = ts('Event registration information for %1 has been updated.', [1 => $this->_contact_name]);
318 $statusMsg .= ' ' . ts('A cancellation email has been sent to %1.', [1 => $this->_contact_email]);
8b9023b8 319 CRM_Core_Session::setStatus($statusMsg, ts('Thanks'), 'success');
e219d53b 320 if (!empty($this->isBackoffice)) {
321 return;
322 }
4abc4ee1 323 $url = CRM_Utils_System::url('civicrm/event/info', "reset=1&id={$this->_event_id}&noFullMsg=true");
324 CRM_Utils_System::redirect($url);
97d8187a
DG
325 }
326
327}