summaryrefslogtreecommitdiff
path: root/api.php
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2024-01-27 13:05:41 +0100
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2024-01-27 13:05:41 +0100
commit907f39db4ab00de43016646660d9d1ca9c73d1f9 (patch)
tree49642a7e9ab374c3eab2ae91b12a24fdf4a21f62 /api.php
initial commitHEADmaster
Diffstat (limited to 'api.php')
-rw-r--r--api.php443
1 files changed, 443 insertions, 0 deletions
diff --git a/api.php b/api.php
new file mode 100644
index 0000000..0439bf3
--- /dev/null
+++ b/api.php
@@ -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;
+ }
+ }
+}