ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilObjSession.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 include_once('./Modules/Session/classes/class.ilSessionAppointment.php');
6 include_once './Services/Membership/classes/class.ilMembershipRegistrationSettings.php';
7 
16 class ilObjSession extends ilObject
17 {
18  const MAIL_ALLOWED_ALL = 1;
19  const MAIL_ALLOWED_ADMIN = 2;
20 
21  const LOCAL_ROLE_PARTICIPANT_PREFIX = 'il_sess_participant';
22 
23  const CAL_REG_START = 1;
24 
25  protected $db;
26 
27  protected $location;
28  protected $name;
29  protected $phone;
30  protected $email;
31  protected $details;
32  protected $registration;
33  protected $event_id;
34 
36  protected $reg_limited = 0;
37  protected $reg_min_users = 0;
38  protected $reg_limited_users = 0;
39  protected $reg_waiting_list = 0;
40  protected $reg_waiting_list_autofill; // [bool]
41 
45  protected $show_members = false;
46 
50  protected $mail_members = self::MAIL_ALLOWED_ADMIN;
51 
52  protected $appointments;
53  protected $files = array();
54 
58  protected $session_logger = null;
59 
63  protected $members_obj;
64 
65 
66 
73  public function __construct($a_id = 0, $a_call_by_reference = true)
74  {
75  global $DIC;
76 
77  $ilDB = $DIC['ilDB'];
78 
79  $this->session_logger = $GLOBALS['DIC']->logger()->sess();
80 
81  $this->db = $ilDB;
82  $this->type = "sess";
83  parent::__construct($a_id, $a_call_by_reference);
84  }
85 
94  public static function _lookupRegistrationEnabled($a_obj_id)
95  {
96  global $DIC;
97 
98  $ilDB = $DIC['ilDB'];
99 
100  $query = "SELECT reg_type FROM event " .
101  "WHERE obj_id = " . $ilDB->quote($a_obj_id, 'integer') . " ";
102  $res = $ilDB->query($query);
103  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
104  return (bool) $row->reg_type != ilMembershipRegistrationSettings::TYPE_NONE;
105  }
106  return false;
107  }
108 
114  public static function lookupSession($a_obj_id)
115  {
116  global $DIC;
117 
118  $ilDB = $DIC['ilDB'];
119 
120  $query = "SELECT * FROM event " .
121  "WHERE obj_id = " . $ilDB->quote($a_obj_id);
122  $res = $ilDB->query($query);
123  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
124  $data['location'] = $row->location ? $row->location : '';
125  $data['details'] = $row->details ? $row->details : '';
126  $data['name'] = $row->tutor_name ? $row->tutor_name : '';
127  $data['email'] = $row->tutor_email ? $row->tutor_email : '';
128  $data['phone'] = $row->tutor_phone ? $row->tutor_phone : '';
129  }
130  return (array) $data;
131  }
132 
140  public function getPresentationTitle()
141  {
142  $date = new ilDate($this->getFirstAppointment()->getStart()->getUnixTime(), IL_CAL_UNIX);
143  if ($this->getTitle()) {
144  return ilDatePresentation::formatDate($this->getFirstAppointment()->getStart()) . ': ' . $this->getTitle();
145  } else {
146  return ilDatePresentation::formatDate($date);
147  }
148  }
149 
154  {
155  $title = '';
156  if ($this->getTitle()) {
157  $title = ': ' . $this->getTitle();
158  }
160  $this->getFirstAppointment()->getStart(),
161  $this->getFirstAppointment()->getEnd()
162  ) . $title;
163  }
164 
168  public function initDefaultRoles()
169  {
170  include_once './Services/AccessControl/classes/class.ilObjRole.php';
172  self::LOCAL_ROLE_PARTICIPANT_PREFIX . '_' . $this->getRefId(),
173  'Participant of session obj_no.' . $this->getId(),
174  self::LOCAL_ROLE_PARTICIPANT_PREFIX,
175  $this->getRefId()
176  );
177 
178  if (!$role instanceof ilObjRole) {
179  $this->session_logger->warning('Could not create default session role.');
180  $this->session_logger->logStack(ilLogLevel::WARNING);
181  }
182  return array();
183  }
184 
191  public function getEventId()
192  {
193  return $this->event_id;
194  }
195 
202  public function setLocation($a_location)
203  {
204  $this->location = $a_location;
205  }
206 
213  public function getLocation()
214  {
215  return $this->location;
216  }
217 
224  public function setName($a_name)
225  {
226  $this->name = $a_name;
227  }
228 
235  public function getName()
236  {
237  return $this->name;
238  }
239 
246  public function setPhone($a_phone)
247  {
248  $this->phone = $a_phone;
249  }
250 
257  public function getPhone()
258  {
259  return $this->phone;
260  }
261 
269  public function setEmail($a_email)
270  {
271  $this->email = $a_email;
272  }
273 
280  public function getEmail()
281  {
282  return $this->email;
283  }
284 
290  public function hasTutorSettings()
291  {
292  return strlen($this->getName()) or
293  strlen($this->getEmail()) or
294  strlen($this->getPhone());
295  }
296 
297 
304  public function setDetails($a_details)
305  {
306  $this->details = $a_details;
307  }
308 
315  public function getDetails()
316  {
317  return $this->details;
318  }
319 
320  public function setRegistrationType($a_type)
321  {
322  $this->reg_type = $a_type;
323  }
324 
325  public function getRegistrationType()
326  {
327  return $this->reg_type;
328  }
329 
331  {
332  return $this->reg_limited;
333  }
334 
335  public function enableRegistrationUserLimit($a_limit)
336  {
337  $this->reg_limited = $a_limit;
338  }
339 
340  public function getRegistrationMinUsers()
341  {
342  return $this->reg_min_users;
343  }
344 
345  public function setRegistrationMinUsers($a_users)
346  {
347  $this->reg_min_users = $a_users;
348  }
349 
350  public function getRegistrationMaxUsers()
351  {
353  }
354 
355  public function setRegistrationMaxUsers($a_users)
356  {
357  $this->reg_limited_users = $a_users;
358  }
359 
361  {
363  }
364 
365  public function enableRegistrationWaitingList($a_stat)
366  {
367  $this->reg_waiting_list = $a_stat;
368  }
369 
370  public function setWaitingListAutoFill($a_value)
371  {
372  $this->reg_waiting_list_autofill = (bool) $a_value;
373  }
374 
375  public function hasWaitingListAutoFill()
376  {
377  return (bool) $this->reg_waiting_list_autofill;
378  }
379 
384  public function setShowMembers($a_status)
385  {
386  $this->show_members = (bool) $a_status;
387  }
388 
393  public function getShowMembers()
394  {
395  return (bool) $this->show_members;
396  }
397 
404  public function enabledRegistration()
405  {
406  return $this->reg_type != ilMembershipRegistrationSettings::TYPE_NONE;
407  }
408 
415  public function getAppointments()
416  {
417  return $this->appointments ? $this->appointments : array();
418  }
419 
427  public function addAppointment($appointment)
428  {
429  $this->appointments[] = $appointment;
430  }
431 
440  {
441  $this->appointments = $appointments;
442  }
443 
450  public function getFirstAppointment()
451  {
452  return is_object($this->appointments[0]) ? $this->appointments[0] : ($this->appointments[0] = new ilSessionAppointment());
453  }
454 
462  public function getFiles()
463  {
464  return $this->files ? $this->files : array();
465  }
466 
467 
472  public function setMailToMembersType($a_type)
473  {
474  $this->mail_members = $a_type;
475  }
476 
481  public function getMailToMembersType()
482  {
483  return $this->mail_members;
484  }
485 
486 
494  public function validate()
495  {
496  global $DIC;
497 
498  $ilErr = $DIC['ilErr'];
499 
500  // #17114
501  if ($this->isRegistrationUserLimitEnabled() &&
502  !$this->getRegistrationMaxUsers()) {
503  $ilErr->appendMessage($this->lng->txt("sess_max_members_needed"));
504  return false;
505  }
506 
507  return true;
508  }
509 
518  public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
519  {
523  $new_obj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
524 
526  $new_obj->applyDidacticTemplate($dtpl);
527 
528  $this->read();
529 
530  $this->cloneSettings($new_obj);
531  $this->cloneMetaData($new_obj);
532 
533 
534  // Clone appointment
535  $new_app = $this->getFirstAppointment()->cloneObject($new_obj->getId());
536  $new_obj->setAppointments(array($new_app));
537  $new_obj->update(true);
538 
539  // Clone session files
540  foreach ($this->files as $file) {
541  $file->cloneFiles($new_obj->getEventId());
542  }
543 
544  // Raise update forn new appointments
545 
546 
547 
548  // Copy learning progress settings
549  include_once('Services/Tracking/classes/class.ilLPObjSettings.php');
550  $obj_settings = new ilLPObjSettings($this->getId());
551  $obj_settings->cloneSettings($new_obj->getId());
552  unset($obj_settings);
553 
554  return $new_obj;
555  }
556 
564  public function cloneSettings(ilObjSession $new_obj)
565  {
567  $new_obj->getId(),
570  $this->getId(),
572  )
573  );
574 
575  // @var
576  $new_obj->setLocation($this->getLocation());
577  $new_obj->setName($this->getName());
578  $new_obj->setPhone($this->getPhone());
579  $new_obj->setEmail($this->getEmail());
580  $new_obj->setDetails($this->getDetails());
581 
582  $new_obj->setRegistrationType($this->getRegistrationType());
588  $new_obj->setShowMembers($this->getShowMembers());
589  $new_obj->setMailToMembersType($this->getMailToMembersType());
590 
591  $new_obj->update(true);
592 
593  return true;
594  }
595 
603  public function cloneDependencies($a_target_id, $a_copy_id)
604  {
605  global $DIC;
606 
607  $ilObjDataCache = $DIC['ilObjDataCache'];
608 
609  parent::cloneDependencies($a_target_id, $a_copy_id);
610 
611  $target_obj_id = $ilObjDataCache->lookupObjId($a_target_id);
612 
613  include_once('./Modules/Session/classes/class.ilEventItems.php');
614  $session_materials = new ilEventItems($target_obj_id);
615  $session_materials->cloneItems($this->getId(), $a_copy_id);
616 
617  return true;
618  }
619 
620 
621 
627  public function create($a_skip_meta_data = false)
628  {
629  global $DIC;
630 
631  $ilDB = $DIC['ilDB'];
632  global $DIC;
633 
634  $ilAppEventHandler = $DIC['ilAppEventHandler'];
635 
636  parent::create();
637 
638  if (!$a_skip_meta_data) {
639  $this->createMetaData();
640  }
641 
642  $next_id = $ilDB->nextId('event');
643  $query = "INSERT INTO event (event_id,obj_id,location,tutor_name,tutor_phone,tutor_email,details,registration, " .
644  'reg_type, reg_limit_users, reg_limited, reg_waiting_list, reg_min_users, reg_auto_wait,show_members,mail_members) ' .
645  "VALUES( " .
646  $ilDB->quote($next_id, 'integer') . ", " .
647  $this->db->quote($this->getId(), 'integer') . ", " .
648  $this->db->quote($this->getLocation(), 'text') . "," .
649  $this->db->quote($this->getName(), 'text') . ", " .
650  $this->db->quote($this->getPhone(), 'text') . ", " .
651  $this->db->quote($this->getEmail(), 'text') . ", " .
652  $this->db->quote($this->getDetails(), 'text') . "," .
653  $this->db->quote($this->enabledRegistration(), 'integer') . ", " .
654  $this->db->quote($this->getRegistrationType(), 'integer') . ', ' .
655  $this->db->quote($this->getRegistrationMaxUsers(), 'integer') . ', ' .
656  $this->db->quote($this->isRegistrationUserLimitEnabled(), 'integer') . ', ' .
657  $this->db->quote($this->isRegistrationWaitingListEnabled(), 'integer') . ', ' .
658  $this->db->quote($this->getRegistrationMinUsers(), 'integer') . ', ' .
659  $this->db->quote($this->hasWaitingListAutoFill(), 'integer') . ', ' .
660  $this->db->quote($this->getShowMembers(), 'integer') . ', ' .
661  $this->db->quote($this->getMailToMembersType(), 'integer') . ' ' .
662  ")";
663  $res = $ilDB->manipulate($query);
664  $this->event_id = $next_id;
665 
666  $ilAppEventHandler->raise(
667  'Modules/Session',
668  'create',
669  array('object' => $this,
670  'obj_id' => $this->getId(),
671  'appointments' => $this->prepareCalendarAppointments('create'))
672  );
673 
674  return $this->getId();
675  }
676 
684  public function update($a_skip_meta_update = false)
685  {
686  global $DIC;
687 
688  $ilDB = $DIC['ilDB'];
689  global $DIC;
690 
691  $ilAppEventHandler = $DIC['ilAppEventHandler'];
692 
693  if (!parent::update()) {
694  return false;
695  }
696  if (!$a_skip_meta_update) {
697  $this->updateMetaData();
698  }
699 
700  $query = "UPDATE event SET " .
701  "location = " . $this->db->quote($this->getLocation(), 'text') . "," .
702  "tutor_name = " . $this->db->quote($this->getName(), 'text') . ", " .
703  "tutor_phone = " . $this->db->quote($this->getPhone(), 'text') . ", " .
704  "tutor_email = " . $this->db->quote($this->getEmail(), 'text') . ", " .
705  "details = " . $this->db->quote($this->getDetails(), 'text') . ", " .
706  "registration = " . $this->db->quote($this->enabledRegistration(), 'integer') . ", " .
707  "reg_type = " . $this->db->quote($this->getRegistrationType(), 'integer') . ", " .
708  "reg_limited = " . $this->db->quote($this->isRegistrationUserLimitEnabled(), 'integer') . ", " .
709  "reg_limit_users = " . $this->db->quote($this->getRegistrationMaxUsers(), 'integer') . ", " .
710  "reg_min_users = " . $this->db->quote($this->getRegistrationMinUsers(), 'integer') . ", " .
711  "reg_waiting_list = " . $this->db->quote($this->isRegistrationWaitingListEnabled(), 'integer') . ", " .
712  "reg_auto_wait = " . $this->db->quote($this->hasWaitingListAutoFill(), 'integer') . ", " .
713  'show_members = ' . $this->db->quote($this->getShowMembers(), 'integer') . ', ' .
714  'mail_members = ' . $this->db->quote($this->getMailToMembersType(), 'integer') . ' ' .
715  "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer') . " ";
716  $res = $ilDB->manipulate($query);
717 
718  $ilAppEventHandler->raise(
719  'Modules/Session',
720  'update',
721  array('object' => $this,
722  'obj_id' => $this->getId(),
723  'appointments' => $this->prepareCalendarAppointments('update'))
724  );
725  return true;
726  }
727 
734  public function delete()
735  {
736  global $DIC;
737 
738  $ilDB = $DIC['ilDB'];
739  global $DIC;
740 
741  $ilAppEventHandler = $DIC['ilAppEventHandler'];
742 
743  if (!parent::delete()) {
744  return false;
745  }
746 
747  // delete meta data
748  $this->deleteMetaData();
749 
750  $query = "DELETE FROM event " .
751  "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer') . " ";
752  $res = $ilDB->manipulate($query);
753 
754  include_once('./Modules/Session/classes/class.ilSessionAppointment.php');
756 
757  include_once('./Modules/Session/classes/class.ilEventItems.php');
758  ilEventItems::_delete($this->getId());
759 
760  include_once('./Modules/Session/classes/class.ilEventParticipants.php');
762 
763  foreach ($this->getFiles() as $file) {
764  $file->delete();
765  }
766 
767  $ilAppEventHandler->raise(
768  'Modules/Session',
769  'delete',
770  array('object' => $this,
771  'obj_id' => $this->getId(),
772  'appointments' => $this->prepareCalendarAppointments('delete'))
773  );
774 
775 
776  return true;
777  }
778 
786  public function read()
787  {
788  parent::read();
789 
790  $query = "SELECT * FROM event WHERE " .
791  "obj_id = " . $this->db->quote($this->getId(), 'integer') . " ";
792  $res = $this->db->query($query);
793 
794  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
795  $this->setLocation($row->location);
796  $this->setName($row->tutor_name);
797  $this->setPhone($row->tutor_phone);
798  $this->setEmail($row->tutor_email);
799  $this->setDetails($row->details);
800  $this->setRegistrationType($row->reg_type);
801  $this->enableRegistrationUserLimit($row->reg_limited);
802  $this->enableRegistrationWaitingList($row->reg_waiting_list);
803  $this->setWaitingListAutoFill($row->reg_auto_wait);
804  $this->setRegistrationMaxUsers($row->reg_limit_users);
805  $this->setRegistrationMinUsers($row->reg_min_users);
806  $this->setShowMembers((bool) $row->show_members);
807  $this->setMailToMembersType((int) $row->mail_members);
808  $this->event_id = $row->event_id;
809  }
810 
811  $this->initAppointments();
812  $this->initFiles();
813  }
814 
822  protected function initAppointments()
823  {
824  // get assigned appointments
825  include_once('./Modules/Session/classes/class.ilSessionAppointment.php');
826  $this->appointments = ilSessionAppointment::_readAppointmentsBySession($this->getId());
827  }
828 
836  public function initFiles()
837  {
838  include_once('./Modules/Session/classes/class.ilSessionFile.php');
840  }
841 
842 
850  public function prepareCalendarAppointments($a_mode = 'create')
851  {
852  include_once('./Services/Calendar/classes/class.ilCalendarAppointmentTemplate.php');
853 
854  switch ($a_mode) {
855  case 'create':
856  case 'update':
857 
858  $app = new ilCalendarAppointmentTemplate(self::CAL_REG_START);
859  $app->setTranslationType(IL_CAL_TRANSLATION_NONE);
860  $app->setTitle($this->getTitle() ? $this->getTitle() : $this->lng->txt('obj_sess'));
861  $app->setDescription($this->getLongDescription());
862  $app->setLocation($this->getLocation());
863 
864  $sess_app = $this->getFirstAppointment();
865  $app->setFullday($sess_app->isFullday());
866  $app->setStart($sess_app->getStart());
867  $app->setEnd($sess_app->getEnd());
868  $apps[] = $app;
869 
870  return $apps;
871 
872  case 'delete':
873  // Nothing to do: The category and all assigned appointments will be deleted.
874  return array();
875  }
876  }
877 
881  public function handleAutoFill()
882  {
883  if (
885  !$this->hasWaitingListAutoFill()
886  ) {
887  $this->session_logger->debug('Waiting list or auto fill is disabled.');
888  return true;
889  }
890 
892  $current = $parts->getCountParticipants();
893  $max = $this->getRegistrationMaxUsers();
894 
895  if ($max <= $current) {
896  $this->session_logger->debug('Maximum number of participants not reached.');
897  $this->session_logger->debug('Maximum number of members: ' . $max);
898  $this->session_logger->debug('Current number of members: ' . $current);
899  return true;
900  }
901 
902  $session_waiting_list = new ilSessionWaitingList($this->getId());
903  foreach ($session_waiting_list->getUserIds() as $user_id) {
905  if (!$user instanceof ilObjUser) {
906  $this->session_logger->warning('Found invalid user id on waiting list: ' . $user_id);
907  continue;
908  }
909  if (in_array($user_id, $parts->getParticipants())) {
910  $this->session_logger->notice('User on waiting list already session member: ' . $user_id);
911  continue;
912  }
913 
914  if ($this->enabledRegistration()) {
915  $this->session_logger->debug('Registration enabled: register user');
916  $parts->register($user_id);
917  $parts->sendNotification(
919  $user_id
920  );
921  } else {
922  $this->session_logger->debug('Registration disabled: set user status to participated.');
923  $parts->getEventParticipants()->updateParticipation($user_id, true);
924  $parts->sendNotification(
926  $user_id
927  );
928  }
929 
930  $session_waiting_list->removeFromList($user_id);
931 
932  $current++;
933  if ($current >= $max) {
934  break;
935  }
936  }
937  }
938 
939 
947  protected function initParticipants()
948  {
949  $this->members_obj = ilSessionParticipants::_getInstanceByObjId($this->getId());
950  }
951 
957  public function getMembersObject()
958  {
959  if (!$this->members_obj instanceof ilSessionParticipants) {
960  $this->initParticipants();
961  }
962  return $this->members_obj;
963  }
964 
969  public function getEnableMap()
970  {
971  return false;
972  }
973 }
create($a_skip_meta_data=false)
create new session
static lookupTemplateId($a_ref_id)
Lookup template id ilDB $ilDB.
getPresentationTitle()
get title (overwritten from base class)
Class ilObjRole.
enabledRegistration()
is registration enabled
enableRegistrationUserLimit($a_limit)
getMembersObject()
Get members objects.
initFiles()
init files
Session participation handling.
getEnableMap()
ALways disabled.
addAppointment($appointment)
add appointment
getEmail()
get email
const IL_CAL_TRANSLATION_NONE
getEventId()
sget event id
global $DIC
Definition: saml.php:7
getLocation()
get location
setLocation($a_location)
set location
cloneSettings(ilObjSession $new_obj)
clone settings
__construct($a_id=0, $a_call_by_reference=true)
Constructor public.
updateMetaData()
update meta data entry
read()
read session data
setPhone($a_phone)
set phone
const LOCAL_ROLE_PARTICIPANT_PREFIX
initAppointments()
init appointments
createMetaData()
create meta data entry
setWaitingListAutoFill($a_value)
setName($a_name)
set name
setEmail($a_email)
set email
Apointment templates are used for automatic generated apointments.
const IL_CAL_UNIX
setMailToMembersType($a_type)
Set mail to members type.
static _getInstanceByObjId($a_obj_id)
Get instance.
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date public.
getAppointments()
get appointments
$ilErr
Definition: raiseError.php:18
static createDefaultRole($a_title, $a_description, $a_tpl_name, $a_ref_id)
static lookupSession($a_obj_id)
Get session data.
$a_type
Definition: workflow.php:92
static _deleteBySession($a_event_id)
cloneDependencies($a_target_id, $a_copy_id)
Clone dependencies.
setRegistrationMinUsers($a_users)
Class for single dates.
foreach($_POST as $key=> $value) $res
getId()
get object id public
handleAutoFill()
Handle auto fill for session members.
static _lookupRegistrationEnabled($a_obj_id)
lookup registration enabled
setRegistrationType($a_type)
hasTutorSettings()
check if there any tutor settings
prepareCalendarAppointments($a_mode='create')
Prepare calendar appointments.
getTitle()
get object title public
cloneMetaData($target_obj)
Copy meta data.
getFiles()
get files
getPhone()
get phone
$query
getMailToMembersType()
Get mail to members type.
getShowMembers()
Member gallery enabled.
static _deleteByEvent($a_event_id)
$user
Definition: migrateto20.php:57
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
initDefaultRoles()
Create local session participant role.
$row
update($pash, $contents, Config $config)
static formatPeriod(ilDateTime $start, ilDateTime $end, $a_skip_starting_day=false)
Format a period of two date Shows: 14.
setAppointments($appointments)
set appointments
setDetails($a_details)
set details
getDetails()
get details
global $ilDB
getLongDescription()
get object long description (stored in object_description)
getRefId()
get reference id public
static _readAppointmentsBySession($a_event_id)
setShowMembers($a_status)
Show members gallery.
static _writeContainerSetting($a_id, $a_keyword, $a_value)
setRegistrationMaxUsers($a_users)
deleteMetaData()
delete meta data entry
initParticipants()
init participants object
static _readFilesByEvent($a_event_id)
enableRegistrationWaitingList($a_stat)
update($a_skip_meta_update=false)
update object
getPresentationTitleAppointmentPeriod()
$GLOBALS['JPEG_Segment_Names']
Global Variable: XMP_tag_captions.
static _lookupContainerSetting($a_id, $a_keyword, $a_default_value=null)
Lookup a container setting.
class ilEvent
class ilSessionAppointment
$data
Definition: bench.php:6
static _delete($a_event_id)
getFirstAppointment()
get first appointment