⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.50
Server IP:
41.128.143.86
Server:
Linux host.raqmix.cloud 6.8.0-1025-azure #30~22.04.1-Ubuntu SMP Wed Mar 12 15:28:20 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.3.23
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
psa-horde
/
kronolith
/
lib
/
Edit File: FreeBusy.php
<?php /** * Free/Busy functionality. * * @author Chuck Hagenbuch <chuck@horde.org> * @package Kronolith */ class Kronolith_FreeBusy { /** * Generates the free/busy text for $calendars. Cache it for at least an * hour, as well. * * @param string|array $calendars The calendar to view free/busy slots for. * @param integer $startstamp The start of the time period to retrieve. * @param integer $endstamp The end of the time period to retrieve. * @param boolean $returnObj Default false. Return a vFreebusy object * instead of text. * @param string $user Set organizer to this user. * * @return string The free/busy text. * @throws Horde_Exception */ public static function generate($calendars, $startstamp = null, $endstamp = null, $returnObj = false, $user = null) { if (!is_array($calendars)) { $calendars = array($calendars); } if (!$user) { $kronolith_shares = $GLOBALS['injector']->getInstance('Kronolith_Shares'); /* Find a share and retrieve owner. */ foreach ($calendars as $calendar) { if (strpos($calendar, 'internal_') !== 0) { continue; } $calendar = substr($calendar, 9); try { $share = $kronolith_shares->getShare($calendar); $user = $share->get('owner'); break; } catch (Horde_Exception $e) { } } } /* Default the start date to today. */ if (is_null($startstamp)) { $startstamp = mktime(0, 0, 0); } /* Default the end date to the start date + freebusy_days. */ if (is_null($endstamp) || $endstamp < $startstamp) { $enddate = new Horde_Date($startstamp); $enddate->mday += $GLOBALS['prefs']->getValue('freebusy_days'); $endstamp = $enddate->timestamp(); } else { $enddate = new Horde_Date($endstamp); } /* Get the Identity for the owner of the share. */ $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($user); $email = $identity->getValue('from_addr'); $cn = $identity->getValue('fullname'); if (empty($email) && empty($cn)) { $cn = $user; } /* Fetch events. */ $busy = array(); foreach ($calendars as $calendar) { if (strpos($calendar, '_')) { @list($type, $calendar) = explode('_', $calendar, 2); } else { $type = 'internal'; } try { $driver = Kronolith::getDriver($type, $calendar); $events = $driver->listEvents( new Horde_Date($startstamp), $enddate, array('show_recurrence' => true)); Kronolith::mergeEvents($busy, $events); } catch (Exception $e) { } } /* Create the new iCalendar. */ $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//The Horde Project//Kronolith ' . $GLOBALS['registry']->getVersion() . '//EN'); $vCal->setAttribute('METHOD', 'PUBLISH'); /* Create new vFreebusy. */ $vFb = Horde_Icalendar::newComponent('vfreebusy', $vCal); $params = array(); if (!empty($cn)) { $params['CN'] = $cn; } if (!empty($email)) { $vFb->setAttribute('ORGANIZER', 'mailto:' . $email, $params); } else { $vFb->setAttribute('ORGANIZER', '', $params); } $vFb->setAttribute('DTSTAMP', $_SERVER['REQUEST_TIME']); $vFb->setAttribute('DTSTART', $startstamp); $vFb->setAttribute('DTEND', $endstamp); $vFb->setAttribute('URL', Horde::url('fb.php?u=' . $user, true, -1)); /* Add all the busy periods. */ foreach ($busy as $events) { foreach ($events as $event) { if ($event->status == Kronolith::STATUS_FREE) { continue; } if ($event->status == Kronolith::STATUS_CANCELLED) { continue; } /* Horde_Icalendar_Vfreebusy only supports timestamps at the * moment. */ $vFb->addBusyPeriod('BUSY', $event->start->timestamp(), null, $event->end->timestamp() - $event->start->timestamp()); } } /* Remove the overlaps. */ $vFb->simplify(); $vCal->addComponent($vFb); /* Return the vFreebusy object if requested. */ if ($returnObj) { return $vFb; } /* Generate the vCal file. */ return $vCal->exportvCalendar(); } /** * Retrieves the free/busy information for a given email address, if any * information is available. * * @param string $email The email address to look for. * @param boolean $json Whether to return the free/busy data as a simple * object suitable to be transferred as json. * * @return Horde_Icalendar_Vfreebusy Free/busy component. * @throws Kronolith_Exception */ public static function get($email, $json = false) { $default_domain = empty($GLOBALS['conf']['storage']['default_domain']) ? null : $GLOBALS['conf']['storage']['default_domain']; $rfc822 = new Horde_Mail_Rfc822(); try { $res = $rfc822->parseAddressList($email, array( 'default_domain' => $default_domain )); } catch (Horde_Mail_Exception $e) { throw new Kronolith_Exception($e); } if (!($tmp = $res[0])) { throw new Kronolith_Exception(_("No valid email address found")); } $email = $tmp->bare_address; /* Check if we can retrieve a VFB from the Free/Busy URL, if one is * set. */ $url = self::getUrl($email); if ($url) { $url = trim($url); $http = $GLOBALS['injector'] ->getInstance('Horde_Core_Factory_HttpClient') ->create(array('request.verifyPeer' => false)); try { $response = $http->get($url); } catch (Horde_Http_Exception $e) { throw new Kronolith_Exception(sprintf(_("The free/busy url for %s cannot be retrieved."), $email)); } if ($response->code == 200 && $data = $response->getBody()) { // Detect the charset of the iCalendar data. $contentType = $response->getHeader('Content-Type'); if ($contentType && strpos($contentType, ';') !== false) { list(,$charset,) = explode(';', $contentType); $data = Horde_String::convertCharset($data, trim(str_replace('charset=', '', $charset)), 'UTF-8'); } $vCal = new Horde_Icalendar(); $vCal->parsevCalendar($data, 'VCALENDAR'); $components = $vCal->getComponents(); $vCal = new Horde_Icalendar(); $vFb = Horde_Icalendar::newComponent('vfreebusy', $vCal); $vFb->setAttribute('ORGANIZER', $email); $found = false; foreach ($components as $component) { if ($component instanceof Horde_Icalendar_Vfreebusy) { $found = true; $vFb->merge($component); } } if ($found) { // @todo: actually store the results in the storage, so // that they can be retrieved later. We should store the // plain iCalendar data though, to avoid versioning // problems with serialize iCalendar objects. return $json ? self::toJson($vFb) : $vFb; } } } /* Check storage driver. */ $storage = $GLOBALS['injector']->getInstance('Kronolith_Factory_Storage')->create(); try { $fb = $storage->search($email); return $json ? self::toJson($fb) : $fb; } catch (Horde_Exception_NotFound $e) { if ($url) { throw new Kronolith_Exception(sprintf(_("No free/busy information found at the free/busy url of %s."), $email)); } throw new Kronolith_Exception(sprintf(_("No free/busy url found for %s."), $email)); } } /** * Searches address books for the freebusy URL for a given email address. * * @param string $email The email address to look for. * * @return mixed The url on success or false on failure. */ public static function getUrl($email) { $sources = json_decode($GLOBALS['prefs']->getValue('search_sources')); if (empty($sources)) { $sources = array(); } try { $result = $GLOBALS['registry']->call('contacts/getField', array($email, 'freebusyUrl', $sources, true, true)); } catch (Horde_Exception $e) { return false; } if (is_array($result)) { return array_shift($result); } return $result; } /** * Converts free/busy data to a simple object suitable to be transferred * as json. * * @param Horde_Icalendar_Vfreebusy $fb A Free/busy component. * * @return object A simple object representation. */ public static function toJson(Horde_Icalendar_Vfreebusy $fb) { $json = new stdClass; $start = $fb->getStart(); if ($start) { $start = new Horde_Date($start); $json->s = $start->dateString(); } $end = $fb->getEnd(); if ($end) { $end = new Horde_Date($end); $json->e = $end->dateString(); } $b = $fb->getBusyPeriods(); if (empty($b)) { $b = new StdClass(); } $new = new StdClass(); foreach ($b as $from => $to) { $from = new Horde_Date($from); $to = new Horde_Date($to); $new->{$from->toJson()} = $to->toJson(); } $json->b = $new; return $json; } }
Simpan