diff options
| author | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2024-01-27 13:05:41 +0100 |
|---|---|---|
| committer | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2024-01-27 13:05:41 +0100 |
| commit | 907f39db4ab00de43016646660d9d1ca9c73d1f9 (patch) | |
| tree | 49642a7e9ab374c3eab2ae91b12a24fdf4a21f62 /api.php | |
Diffstat (limited to 'api.php')
| -rw-r--r-- | api.php | 443 |
1 files changed, 443 insertions, 0 deletions
@@ -0,0 +1,443 @@ +<?php + +class CommuniApi { + const BASE_URL = 'https://api.communiapp.de/rest/'; + const TIMEZONE = 'Europe/Berlin'; + + private $authtoken = false; + private $logininfo = null; + private $userinfocache = array(); + private $groupinfocache = array(); + + public function __construct($authtoken) { + $this->authtoken = $authtoken; + } + + private function get($sub, $params = null) { + $url = self::BASE_URL . $sub; + if (!empty($params)) { + $url .= '?' . http_build_query($params); + } + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + curl_setopt($ch, CURLOPT_HTTPHEADER, array( + 'User-Agent: WP Communi Events <jonas@kuemmerlin.eu>', + 'X-Authorization: Bearer ' . $this->authtoken + )); + + curl_setopt($ch, CURLOPT_URL, $url); + $result = curl_exec($ch); + + if ($result === false) { + $cn = curl_errno($ch); + $cm = curl_error($ch); + trigger_error("curl error($cn): $cm", E_USER_NOTICE); + curl_close($ch); + return false; + } + + curl_close($ch); + return json_decode($result); + } + + // retval: { id: User-ID, group: Main-Group-ID, ... } + public function login() { + if ($this->logininfo === null) { + $info = $this->get('login'); + if (!empty($info) && !empty($info->id)) { + $this->logininfo = $info; + } else { + $this->logininfo = false; + } + } + return $this->logininfo; + } + + public function userId() { + $i = $this->login(); + if (!empty($i) && !empty($i->id)) { + return $i->id; + } else { + return false; + } + } + + public function user($id = null) { + if (empty($id)) + $id = $this->userId(); + + if (empty($id)) + return false; + + if (!array_key_exists($id, $this->userinfocache)) { + $info = $this->get('user/' . urlencode($id)); + if (!empty($info)) { + $this->userinfocache[$id] = new CommuniUser($this, $id, $info); + } else { + $this->userinfocache[$id] = false; + } + } + + return $this->userinfocache[$id]; + + } + + public function group($id = null) { + if (empty($id)) + $id = $this->mainGroupId(); + + if (empty($id)) + return false; + + if (!array_key_exists($id, $this->groupinfocache)) { + $info = $this->get('group/' . urlencode($id)); + if (!empty($info)) { + $this->groupinfocache[$id] = new CommuniGroup($this, $id, $info); + } else { + $this->groupinfocache[$id] = false; + } + } + + return $this->groupinfocache[$id]; + } + + public function userGroupIds($userid = null) { + if (empty($userid)) + $userid = $this->userId(); + + if (empty($userid)) + return array(); + + if ($userid instanceof CommuniUser) + $userid = $userid->id(); + + $usergroups = $this->get('userGroup', array('user' => $userid)); + if (empty($usergroups)) + return array(); + + $retval = array(); + foreach ($usergroups as $row) { + if (!empty($row->status) && !empty($row->group) && $row->status == 2) { + $retval[] = $row->group; + } + } + + return $retval; + } + + public function userGroups($user = null) { + $ids = $this->userGroupIds($user); + $retval = array(); + + foreach ($ids as $id) { + $g = $this->group($id); + if (!empty($g)) + $retval[] = $g; + } + + return $retval; + } + + public function events($groups = null) { + $groupids = array(); + if ($groups !== null) { + foreach ($groups as $g) { + if ($g instanceof CommuniGroup) { + $groupids[] = $g->id(); + } else { + $groupids[] = $g; + } + } + } else { + $maingroup = $this->mainGroupId(); + if (!empty($maingroup)) + $groupids[] = $maingroup; + } + + if (empty($groupids)) + return array(); + + if (count($groupids) == 1) + $groupids = $groupids[0]; + + $infos = $this->get('event', array('group' => $groupids)); + if (empty($infos)) + return array(); + + $retval = array(); + foreach ($infos as $i) { + if (!empty($i) && !empty($i->id) && empty($i->baseType)) { + $retval[] = new CommuniEvent($this, $i->id, $i); + } + } + + return $retval; + } + + public function mainGroupId() { + $i = $this->login(); + if (!empty($i) && !empty($i->group)) { + return $i->group; + } else { + return false; + } + } + + public function webappUrl() { + $g = $this->group(); + if (!empty($g) && !empty($g->name())) { + return "https://{$g->name()}.communiapp.de/"; + } else { + return false; + } + } + + public static function defaultInstance() { + static $inst = null; + if (empty($inst)) { + $inst = new CommuniApi(get_option('communievents-auth-token')); + } + return $inst; + } +} + +class CommuniUser { + private $api; + private $id_; + private $info; + + public function __construct($api, $id, $info) { + $this->api = $api; + $this->id_ = $id; + $this->info = $info; + } + + public function vorname() { + if (!empty($this->info) && !empty($this->info->vorname)) { + return $this->info->vorname; + } else { + return ''; + } + } + + public function nachname() { + if (!empty($this->info) && !empty($this->info->nachname)) { + return $this->info->nachname; + } else { + return ''; + } + } + + public function id() { + return $this->id_; + } + + public function name() { + return "{$this->vorname()} {$this->nachname()}"; + } + + public function webappUrl() { + $baseurl = $this->api->webappUrl(); + if (!empty($baseurl)) { + return "{$baseurl}page/detail/tab/user-{$this->id()}"; + } else { + return false; + } + } + + public function groupIds() { + return $this->api->userGroupIds($this); + } + + public function groups() { + return $this->api->userGroups($this); + } +} + +class CommuniGroup { + private $api; + private $id_; + private $info; + + public function __construct($api, $id, $info) { + $this->api = $api; + $this->id_ = $id; + $this->info = $info; + } + + public function id() { + return $this->id_; + } + + public function name() { + if (!empty($this->info) && !empty($this->info->name)) { + return $this->info->name; + } else { + return ''; + } + } + + public function title() { + if (!empty($this->info) && !empty($this->info->title)) { + return $this->info->title; + } else { + return ''; + } + } + + public function webappUrl() { + if (!empty($this->info) && !empty($this->info->name)) { + return "https://{$this->info->name}.communiapp.de/"; + } else { + $baseurl = $this->api->webappUrl(); + if (!empty($baseurl)) { + //return "{$baseurl}page/group/tab/content-{$this->id()}"; + return "{$baseurl}page/detail/tab/group-{$this->id()}"; + } else { + return false; + } + } + } + + public function members() { + // TODO implement + return array(); + } +} + +class CommuniEvent { + private $api; + private $id_; + private $info; + private $start_dt; + private $end_dt; + private $allday; + + public function __construct($api, $id, $info) { + $this->api = $api; + $this->id_ = $id; + $this->info = $info; + + // parse start and end date and figure out allday + $tz = new DateTimeZone(CommuniApi::TIMEZONE); + $this->start_dt = new DateTimeImmutable($info->dateTime, $tz); + $this->end_dt = new DateTimeImmutable(!empty($info->endDateTime) ? $info->endDateTime : $info->dateTime, $tz); + $this->allday = self::is_allday_time($this->start_dt) && self::is_allday_time($this->end_dt); + if ($this->allday) { + // set to datetime which contains date only + $this->start_dt = self::make_allday_dt($this->start_dt); + $this->end_dt = self::make_allday_dt($this->end_dt); + } + } + + // If the time is ambiguous (i.e. it is inside the "double hour" of + // a DST transition, get the earliest UTC time that matches + private static function get_earliest_timestamp($dt) { + $ts_utc_php = $dt->getTimestamp(); + $ts_local = $ts_utc_php + $dt->getOffset(); + $tz = $dt->getTimezone(); + + if (empty($tz)) + return $ts_utc_php; + + $t = $tz->getTransitions($ts_local - 259200, $ts_local + 259200); + if (empty($t)) + return $ts_utc_php; + + for ($i = 0; $i < count($t)-1; ++$i) { + $last_local_ts = $t[$i+1]['ts'] + $t[$i]['offset']; + if ($ts_local < $last_local_ts) { + return $ts_local - $t[$i]['offset']; + } + } + + return $ts_local - $t[count($t)-1]['offset']; + } + + private static function is_allday_time($dt) { + $ts = self::get_earliest_timestamp($dt); + return ($ts % 86400) == 1; + } + + private static function make_allday_dt($dt) { + $ts = self::get_earliest_timestamp($dt); + $ts -= $ts % 86400; + return new DateTimeImmutable("@$ts"); + } + + public function id() { + return $this->id_; + } + + public function groupId() { + if (!empty($this->info->group)) { + return $this->info->group; + } else { + return false; + } + } + + public function group() { + $i = $this->groupId(); + if (!empty($i)) { + return $this->api->group($i); + } else { + return false; + } + } + + public function title() { + if (!empty($this->info->titleFormatted)) { + return $this->info->titleFormatted; + } else { + return ''; + } + } + + public function location() { + if (!empty($this->info->locationFormatted)) { + return $this->info->locationFormatted; + } else { + return ''; + } + } + + public function description() { + if (!empty($this->info->descriptionFormatted)) { + return $this->info->descriptionFormatted; + } else { + return ''; + } + } + + public function official() { + if (isset($this->info->isOfficial)) { + return $this->info->isOfficial; + } else { + return false; + } + } + + public function allday() { + return $this->allday; + } + + public function start() { + return $this->start_dt; + } + + public function end() { + return $this->end_dt; + } + + public function webappUrl() { + $baseurl = $this->api->webappUrl(); + if (!empty($baseurl)) { + return "{$baseurl}page/detail/tab/event-{$this->id()}"; + } else { + return false; + } + } +} |
