Update Copywrite year to be 2019
[civicrm-core.git] / CRM / Event / Form / SelfSvcUpdate.php
CommitLineData
97d8187a 1<?php
97d8187a
DG
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
97d8187a 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
97d8187a
DG
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
6b83d5bd 31 * @copyright CiviCRM LLC (c) 2004-2019
97d8187a
DG
32 * $Id$
33 *
34 */
35
36/**
37 * This class generates form components to allow an Event to be cancelled or transferred from an email link
38 *
39 */
40class CRM_Event_Form_SelfSvcUpdate extends CRM_Core_Form {
41 /**
42 * particpant id
43 *
44 * @var string
45 *
46 */
47 protected $_participant_id;
48 /**
49 * contact id
50 *
51 * @var string
52 *
53 */
54 protected $_contact_id;
55 /**
56 * name of the particpant
57 *
58 * @var string
59 *
60 */
61 protected $_contact_name;
62 /**
63 * email of participant
64 *
65 * @var string
66 */
67 protected $_contact_email;
68 /**
69 * event to be cancelled/transferred
70 *
71 * @var string
72 */
73 protected $_event_id;
74 /**
75 * event title
76 *
77 * @var string
78 */
79 protected $_event_title;
80 /**
81 * event title
82 *
83 * @var string
84 */
85 protected $_event_start_date;
86 /**
87 * action
88 *
89 * @var string
90 */
3a936dab 91 public $_action;
97d8187a
DG
92 /**
93 * participant object
94 *
95 * @var string
96 */
97 protected $_participant = array();
98 /**
99 * particpant values
100 *
101 * @var string
102 */
103 protected $_part_values;
104 /**
105 * details of event registration values
106 *
107 * @var array
108 */
109 protected $_details = array();
e219d53b 110 /**
111 * Is backoffice form?
112 *
113 * @array bool
114 */
115 protected $isBackoffice = FALSE;
97d8187a
DG
116 /**
117 * Set variables up before form is built based on participant ID from URL
118 *
119 * @return void
120 */
121 public function preProcess() {
122 $config = CRM_Core_Config::singleton();
123 $session = CRM_Core_Session::singleton();
124 $this->_userContext = $session->readUserContext();
125 $participant = $values = array();
126 $this->_participant_id = CRM_Utils_Request::retrieve('pid', 'Positive', $this, FALSE, NULL, 'REQUEST');
af29aaac 127 $this->_userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this, FALSE, NULL, 'REQUEST');
e219d53b 128 $this->isBackoffice = CRM_Utils_Request::retrieve('is_backoffice', 'String', $this, FALSE, NULL, 'REQUEST');
97d8187a
DG
129 $params = array('id' => $this->_participant_id);
130 $this->_participant = CRM_Event_BAO_Participant::getValues($params, $values, $participant);
131 $this->_part_values = $values[$this->_participant_id];
132 $this->set('values', $this->_part_values);
133 //fetch Event by event_id, verify that this event can still be xferred/cancelled
134 $this->_event_id = $this->_part_values['event_id'];
af29aaac 135 $url = CRM_Utils_System::url('civicrm/event/info', "reset=1&id={$this->_event_id}");
97d8187a 136 $this->_contact_id = $this->_part_values['participant_contact_id'];
af29aaac 137 $validUser = CRM_Contact_BAO_Contact_Utils::validChecksum($this->_contact_id, $this->_userChecksum);
e3b510fe 138 if (!$validUser && !CRM_Core_Permission::check('edit all events')) {
139 CRM_Core_Error::statusBounce(ts('You do not have sufficient permission to transfer/cancel this participant.'), $url);
140 }
97d8187a
DG
141 $this->assign('action', $this->_action);
142 if ($this->_participant_id) {
143 $this->assign('participantId', $this->_participant_id);
144 }
145 $event = array();
146 $daoName = 'title';
147 $this->_event_title = CRM_Event_BAO_Event::getFieldValue('CRM_Event_DAO_Event', $this->_event_id, $daoName);
148 $daoName = 'start_date';
149 $this->_event_start_date = CRM_Event_BAO_Event::getFieldValue('CRM_Event_DAO_Event', $this->_event_id, $daoName);
150 list($displayName, $email) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contact_id);
151 $this->_contact_name = $displayName;
152 $this->_contact_email = $email;
153 $details = array();
154 $details = CRM_Event_BAO_Participant::participantDetails($this->_participant_id);
4abc4ee1 155 $optionGroupId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'participant_role', 'id', 'name');
156 $contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_participant_id, 'contribution_id', 'participant_id');
157 $this->assign('contributionId', $contributionId);
97d8187a 158 $query = "
974bdb44 159 SELECT cpst.name as status, cov.name as role, cp.fee_level, cp.fee_amount, cp.register_date, cp.status_id, civicrm_event.start_date
97d8187a
DG
160 FROM civicrm_participant cp
161 LEFT JOIN civicrm_participant_status_type cpst ON cpst.id = cp.status_id
4abc4ee1 162 LEFT JOIN civicrm_option_value cov ON cov.value = cp.role_id and cov.option_group_id = {$optionGroupId}
974bdb44 163 LEFT JOIN civicrm_event ON civicrm_event.id = cp.event_id
97d8187a 164 WHERE cp.id = {$this->_participant_id}";
33621c4f 165 $dao = CRM_Core_DAO::executeQuery($query);
97d8187a
DG
166 while ($dao->fetch()) {
167 $details['status'] = $dao->status;
168 $details['role'] = $dao->role;
e219d53b 169 $details['fee_level'] = trim($dao->fee_level, CRM_Core_DAO::VALUE_SEPARATOR);
97d8187a
DG
170 $details['fee_amount'] = $dao->fee_amount;
171 $details['register_date'] = $dao->register_date;
0d21c8b1 172 $details['event_start_date'] = $dao->start_date;
97d8187a
DG
173 }
174 //verify participant status is still Registered
175 if ($details['status'] != "Registered") {
8b9023b8
DG
176 $status = "You cannot transfer or cancel your registration for " . $this->_event_title . ' as you are not currently registered for this event.';
177 CRM_Core_Session::setStatus($status, ts('Sorry'), 'alert');
4abc4ee1 178 CRM_Utils_System::redirect($url);
97d8187a
DG
179 }
180 $query = "select start_date as start, selfcancelxfer_time as time from civicrm_event where id = " . $this->_event_id;
33621c4f 181 $dao = CRM_Core_DAO::executeQuery($query);
97d8187a
DG
182 while ($dao->fetch()) {
183 $time_limit = $dao->time;
184 $start_date = $dao->start;
185 }
4abc4ee1 186 $start_time = new Datetime($start_date);
187 $timenow = new Datetime();
e219d53b 188 if (!$this->isBackoffice && !empty($start_time) && $start_time < $timenow) {
8b9023b8
DG
189 $status = ts("Registration for this event cannot be cancelled or transferred once the event has begun. Contact the event organizer if you have questions.");
190 CRM_Core_Error::statusBounce($status, $url, ts('Sorry'));
4abc4ee1 191 }
e219d53b 192 if (!$this->isBackoffice && !empty($time_limit) && $time_limit > 0) {
97d8187a
DG
193 $interval = $timenow->diff($start_time);
194 $days = $interval->format('%d');
195 $hours = $interval->format('%h');
196 if ($hours <= $time_limit && $days < 1) {
8b9023b8
DG
197 $status = ts("Registration for this event cannot be cancelled or transferred less than %1 hours prior to the event's start time. Contact the event organizer if you have questions.", array(1 => $time_limit));
198 CRM_Core_Error::statusBounce($status, $url, ts('Sorry'));
97d8187a
DG
199 }
200 }
201 $this->assign('details', $details);
202 $this->selfsvcupdateUrl = CRM_Utils_System::url('civicrm/event/selfsvcupdate', "reset=1&id={$this->_participant_id}&id=0");
203 $this->selfsvcupdateText = ts('Update');
204 $this->selfsvcupdateButtonText = ts('Update');
205 // Based on those ids retrieve event and verify it is eligible
206 // for self update (event.start_date > today, event can be 'self_updated'
207 // retrieve contact name and email, and let user verify his/her identity
208 }
209 /**
210 * buildQuickForm -populate input variables for source Event
211 * to cancel or transfer to another person
212 *
213 * return @void
214 */
215 public function buildQuickForm() {
974bdb44 216 $this->add('select', 'action', ts('Transfer or Cancel Registration'), array(ts('-select-'), ts('Transfer'), ts('Cancel')), TRUE);
97d8187a
DG
217 $this->addButtons(array(
218 array(
219 'type' => 'submit',
220 'name' => ts('Submit'),
221 ),
97d8187a 222 ));
e3b510fe 223 $this->addFormRule(array('CRM_Event_Form_SelfSvcUpdate', 'formRule'), $this);
97d8187a
DG
224 parent::buildQuickForm();
225 }
974bdb44 226
97d8187a
DG
227 /**
228 * Set default values for contact
229 *
230 * return @void
231 */
232 public function setDefaultValues() {
233 $this->_defaults = array();
97d8187a
DG
234 $this->_defaults['details'] = $this->_details;
235 return $this->_defaults;
236 }
974bdb44 237
e3b510fe 238 /**
239 * Validate action input
240 * @param array $fields
241 * Posted fields of the form.
242 * @param $files
243 * @param $self
244 *
245 * @return array
246 * list of errors to be posted back to the form
247 */
248 public static function formRule($fields, $files, $self) {
249 $errors = array();
250 if (empty($fields['action'])) {
251 $errors['action'] = ts("Please select Transfer OR Cancel action.");
252 }
253 return empty($errors) ? TRUE : $errors;
254 }
255
97d8187a
DG
256 /**
257 * Process submit form - based on user selection of action
258 * transfer or cancel the event
259 *
260 * return @void
261 */
262 public function postProcess() {
263 //if selection is cancel, cancel this participant' registration, process refund
264 //if transfer, process form to allow selection of transferree
265 $params = $this->controller->exportValues($this->_name);
266 $action = $params['action'];
267 if ($action == "1") {
268 $action = "Transfer Event";
269 $this->transferParticipant($params);
270 }
271 elseif ($action == "2") {
272 $action = "Cancel Event";
273 $this->cancelParticipant($params);
274 }
275 }
974bdb44 276
97d8187a
DG
277 /**
278 * Transfer to a new form, allowing selection of a new contact
279 * based on email and name. The Event will be transferred to this new participant
280 *
281 * return @void
282 */
283 public function transferParticipant($params) {
e219d53b 284 $isBackOfficeArg = $this->isBackoffice ? '&is_backoffice=1' : '';
285 CRM_Utils_System::redirect(CRM_Utils_System::url(
286 'civicrm/event/selfsvctransfer',
287 array(
288 'reset' => 1,
289 'action' => 'add',
290 'pid' => $this->_participant_id,
291 'cs' => $this->_userChecksum,
292 )
293 ));
97d8187a 294 }
974bdb44 295
97d8187a
DG
296 /**
297 * Cancel this participant and finish, send cancellation email. At this point no
298 * auto-cancellation of payment is handled, so payment needs to be manually cancelled
299 *
300 * return @void
301 */
302 public function cancelParticipant($params) {
303 //set participant record status to Cancelled, refund payment if possible
304 // send email to participant and admin, and log Activity
305 $value = array();
306 $value['id'] = $this->_participant_id;
307 $cancelledId = array_search('Cancelled',
308 CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Negative'"));
309 $value['status_id'] = $cancelledId;
310 CRM_Event_BAO_Participant::create($value);
311 $domainValues = array();
312 $domain = CRM_Core_BAO_Domain::getDomain();
313 $tokens = array(
314 'domain' =>
315 array(
316 'name',
317 'phone',
318 'address',
319 'email',
320 ),
321 'contact' => CRM_Core_SelectValues::contactTokens(),
322 );
323 foreach ($tokens['domain'] as $token) {
324 $domainValues[$token] = CRM_Utils_Token::getDomainTokenReplacement($token, $domain);
325 }
326 $participantRoles = array();
327 $participantRoles = CRM_Event_PseudoConstant::participantRole();
328 $participantDetails = array();
329 $query = "SELECT * FROM civicrm_participant WHERE id = {$this->_participant_id}";
330 $dao = CRM_Core_DAO::executeQuery($query);
331 while ($dao->fetch()) {
332 $participantDetails[$dao->id] = array(
333 'id' => $dao->id,
334 'role' => $participantRoles[$dao->role_id],
335 'is_test' => $dao->is_test,
336 'event_id' => $dao->event_id,
337 'status_id' => $dao->status_id,
338 'fee_amount' => $dao->fee_amount,
339 'contact_id' => $dao->contact_id,
340 'register_date' => $dao->register_date,
341 'registered_by_id' => $dao->registered_by_id,
342 );
343 }
344 $eventDetails = array();
345 $eventParams = array('id' => $this->_event_id);
346 CRM_Event_BAO_Event::retrieve($eventParams, $eventDetails[$this->_event_id]);
347 //get default participant role.
348 $eventDetails[$this->_event_id]['participant_role'] = CRM_Utils_Array::value($eventDetails[$this->_event_id]['default_role_id'], $participantRoles);
349 //get the location info
350 $locParams = array('entity_id' => $this->_event_id, 'entity_table' => 'civicrm_event');
351 $eventDetails[$this->_event_id]['location'] = CRM_Core_BAO_Location::getValues($locParams, TRUE);
352 //get contact details
353 $contactIds[$this->_contact_id] = $this->_contact_id;
354 list($currentContactDetails) = CRM_Utils_Token::getTokenDetails($contactIds, NULL,
355 FALSE, FALSE, NULL, array(),
356 'CRM_Event_BAO_Participant'
357 );
358 foreach ($currentContactDetails as $contactId => $contactValues) {
359 $contactDetails[$this->_contact_id] = $contactValues;
360 }
361 //send a 'cancelled' email to user, and cc the event's cc_confirm email
362 $mail = CRM_Event_BAO_Participant::sendTransitionParticipantMail($this->_participant_id,
363 $participantDetails[$this->_participant_id],
364 $eventDetails[$this->_event_id],
365 $contactDetails[$this->_contact_id],
366 $domainValues,
367 "Cancelled",
368 ""
369 );
370 $statusMsg = ts('Event registration information for %1 has been updated.', array(1 => $this->_contact_name));
371 $statusMsg .= ' ' . ts('A cancellation email has been sent to %1.', array(1 => $this->_contact_email));
8b9023b8 372 CRM_Core_Session::setStatus($statusMsg, ts('Thanks'), 'success');
e219d53b 373 if (!empty($this->isBackoffice)) {
374 return;
375 }
4abc4ee1 376 $url = CRM_Utils_System::url('civicrm/event/info', "reset=1&id={$this->_event_id}&noFullMsg=true");
377 CRM_Utils_System::redirect($url);
97d8187a
DG
378 }
379
380}