diff -Nru php-horde-openxchange-1.0.0/debian/changelog php-horde-openxchange-1.0.1/debian/changelog --- php-horde-openxchange-1.0.0/debian/changelog 2016-06-08 07:22:41.000000000 +0000 +++ php-horde-openxchange-1.0.1/debian/changelog 2017-09-27 20:35:51.000000000 +0000 @@ -1,3 +1,9 @@ +php-horde-openxchange (1.0.1-1) unstable; urgency=medium + + * New upstream version 1.0.1 + + -- Mathieu Parent Wed, 27 Sep 2017 22:35:51 +0200 + php-horde-openxchange (1.0.0-7) unstable; urgency=medium * Update Standards-Version to 3.9.8, no change diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Base.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Base.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Base.php 2014-05-21 15:33:12.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Base.php 1970-01-01 00:00:00.000000000 +0000 @@ -1,378 +0,0 @@ - - * @category Horde - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ - -/** - * Horde_OpenXchange_Base is the base class for HTTP API requests to an - * Open-Xchange server. - * - * @author Jan Schneider - * @category Horde - * @copyright 2014 Horde LLC - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ -abstract class Horde_OpenXchange_Base -{ - /** - * Return private resources. - * - * @see listResources() - */ - const RESOURCE_PRIVATE = 'private'; - - /** - * Return public resources. - * - * @see listResources() - */ - const RESOURCE_PUBLIC = 'public'; - - /** - * The folder category. - * - * @var string - */ - protected $_folderType; - - /** - * Any parameters. - * - * @var array - */ - protected $_params; - - /** - * HTTP client - * - * @var Horde_Http_Client - */ - protected $_client; - - /** - * Base URI of the API endpoint. - * - * @var string - */ - protected $_uri; - - /** - * All cookies to sent with OX requests. - * - * @var array - */ - protected $_cookies = array(); - - /** - * The current session ID. - * - * @var string - */ - protected $_session; - - /** - * Constructor. - * - * @param array $params List of optional parameters: - * - client: (Horde_Http_Client) An HTTP client. - * - endpoint: (string) The URI of the OX API - * endpoint. - * - user: (string) Authentication user. - * - password: (string) Authentication password. - */ - public function __construct(array $params = array()) - { - if (isset($params['client'])) { - $this->_client = $params['client']; - unset($params['client']); - } else { - $this->_client = new Horde_Http_Client(array('request.timeout' => 10)); - } - $this->_params = array_merge( - array('endpoint' => 'http://localhost/ajax'), - $params - ); - $this->_uri = $this->_params['endpoint']; - } - - /** - * Logs a user in. - * - * @param string $user A user name. - * @param string $password A password. - * - * @throws Horde_OpenXchange_Exception. - */ - public function login($user, $password) - { - $this->_params['user'] = $user; - $this->_params['password'] = $password; - $this->_login(); - } - - /** - * Logs the current user out. - * - * @throws Horde_OpenXchange_Exception. - */ - public function logout() - { - if (!isset($this->_session)) { - return; - } - - $response = $this->_request( - 'GET', - 'login', - array('action' => 'logout'), - array('session' => $this->_session) - ); - - unset($this->_session); - $this->_cookies = array(); - } - - /** - * Returns information about a system user. - * - * @param integer $id A user ID. - * - * @return array User information hash. - * @throws Horde_OpenXchange_Exception. - */ - public function getUser($id) - { - $user = $this->_request( - 'GET', - 'user', - array( - 'action' => 'get', - 'session' => $this->_session, - 'id' => $id, - ) - ); - return $user['data']; - } - - /** - * Returns information about a system group. - * - * @param integer $id A group ID. - * - * @return array Group information hash. - * @throws Horde_OpenXchange_Exception. - */ - public function getGroup($id) - { - $group = $this->_request( - 'GET', - 'group', - array( - 'action' => 'get', - 'session' => $this->_session, - 'id' => $id, - ) - ); - return $group; - } - - /** - * Returns user configuration. - * - * @param string $config A configuration namespace. - * - * @return mixed Configuration contents. - * @throws Horde_OpenXchange_Exception. - */ - public function getConfig($config) - { - $content = $this->_request( - 'GET', - 'config/' . $config, - array('session' => $this->_session) - ); - switch ($content['data']) { - case 'true': - return true; - case 'false': - return false; - case 'null': - return null; - default: - return $content['data']; - } - } - - /** - * Returns a list of visible groupware resources. - * - * @param string $type An resource type, one of the RESOURCE_* constants. - * - * @return array List of resources with resource IDs as keys and - * information hashes as values. - * @throws Horde_OpenXchange_Exception. - */ - public function listResources($type = self::RESOURCE_PRIVATE) - { - $this->_login(); - - $response = $this->_request( - 'PUT', - 'folders', - array( - 'action' => 'allVisible', - 'session' => $this->_session, - 'content_type' => $this->_folderType, - 'columns' => '1,300,306,308' - ) - ); - - $resources = $users = $groups = array(); - foreach ($response['data'][$type] as $resource) { - $info = array( - 'label' => $resource[1], - 'default' => $resource[3], - ); - foreach ($resource[2] as $perm) { - // http://oxpedia.org/wiki/index.php?title=HTTP_API#PermissionFlags - $permission = 0; - if ($perm['bits'] & 127) { - $permission |= Horde_Perms::SHOW; - } - if ((($perm['bits'] >> 7) & 127) > 1) { - $permission |= Horde_Perms::READ; - } - if ((($perm['bits'] >> 14) & 127) > 1) { - $permission |= Horde_Perms::EDIT; - } - if ((($perm['bits'] >> 21) & 127) > 1) { - $permission |= Horde_Perms::DELETE; - } - if ($perm['group']) { - if (!isset($groups[$perm['entity']])) { - $group = $this->getGroup($perm['entity']); - $groups[$perm['entity']] = $group['name']; - } - $info['permission']['group'][$groups[$perm['entity']]] = $perm['bits']; - $info['hordePermission']['group'][$groups[$perm['entity']]] = $permission; - } else { - if (!isset($users[$perm['entity']])) { - $user = $this->getUser($perm['entity']); - $users[$perm['entity']] = $user['login_info']; - } - $info['permission']['user'][$users[$perm['entity']]] = $perm['bits']; - $info['hordePermission']['user'][$users[$perm['entity']]] = $permission; - } - } - $resources[$resource[0]] = $info; - } - - return $resources; - } - - /** - * Logs a user in, if necessary. - * - * @throws Horde_OpenXchange_Exception. - */ - protected function _login() - { - if (isset($this->_session)) { - return; - } - - if (!isset($this->_params['user']) || - !isset($this->_params['password'])) { - throw new LogicException('User name or password missing'); - } - - $response = $this->_request( - 'POST', - 'login', - array('action' => 'login'), - array( - 'name' => $this->_params['user'], - 'password' => $this->_params['password'] - ) - ); - - $this->_session = $response['session']; - } - - /** - * Sends a request and parses the response. - * - * @param string $method A HTTP request method (uppercase). - * @param string $namespace An API namespace. - * @param array $params URL parameters. - * @param array|string $data Request data. - * - * @return array The decoded result data or null if no data has been - * returned but the request was still successful. - * @throws Horde_OpenXchange_Exception. - */ - protected function _request($method, $namespace, $params, $data = array()) - { - $uri = new Horde_Url($this->_uri . '/' . $namespace, true); - try { - $headers = array(); - if (isset($this->_cookies)) { - $headers['Cookie'] = implode('; ', $this->_cookies); - } - if ($method == 'GET') { - $params = array_merge($params, $data); - $data = null; - } - $response = $this->_client->request( - $method, - (string)$uri->add($params), - $data, - $headers - ); - if ($cookies = $response->getHeader('set-cookie')) { - if (!is_array($cookies)) { - $cookies = array($cookies); - } - foreach ($cookies as $cookie) { - $cookie = preg_split('/;\s*/', $cookie); - for ($i = 1, $c = count($cookie); $i < $c; $i++) { - list($key, $value) = explode('=', $cookie[$i]); - if ($key == 'Expires') { - $expire = new Horde_Date($value); - if ($expire->before(time())) { - continue 2; - } - break; - } - } - $this->_cookies[] = $cookie[0]; - } - } - $body = $response->getBody(); - $data = json_decode($body, true); - if (!$data) { - if ($response->code == 200) { - return; - } - throw new Horde_OpenXchange_Exception($body); - } - if (isset($data['error'])) { - $e = new Horde_OpenXchange_Exception($data['error']); - $e->details = $data; - throw $e; - } - return $data; - } catch (Horde_Http_Exception $e) { - throw new Horde_OpenXchange_Exception($e); - } - } -} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Contacts.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Contacts.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Contacts.php 2014-05-21 15:33:12.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Contacts.php 1970-01-01 00:00:00.000000000 +0000 @@ -1,185 +0,0 @@ - - * @category Horde - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ - -/** - * Horde_OpenXchange_Contacts is the interface class for the contacts storage - * of an Open-Xchange server. - * - * @author Jan Schneider - * @category Horde - * @copyright 2014 Horde LLC - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ -class Horde_OpenXchange_Contacts extends Horde_OpenXchange_Base -{ - /** - * The folder category. - * - * @var string - */ - protected $_folderType = 'contacts'; - - /** - * Column IDs mapped to column names. - * - * @var array - */ - protected $_columns = array( - 1 => 'id', - 20 => 'folder_id', - 100 => 'categories', - 223 => 'uid', - 500 => 'name', - 501 => 'firstname', - 502 => 'lastname', - 503 => 'middlenames', - 504 => 'nameSuffix', - 505 => 'namePrefix', - 506 => 'homeStreet', - 507 => 'homePostalCode', - 508 => 'homeCity', - 509 => 'homeProvince', - 510 => 'homeCountry', - 511 => 'birthday', - 512 => 'maritalStatus', - 513 => 'numberChildren', - 514 => 'role', - 515 => 'nickname', - 516 => 'spouse', - 517 => 'anniversary', - 518 => 'notes', - 519 => 'department', - 520 => 'title', - 521 => 'employeeType', - 522 => 'office', - 523 => 'workStreet', - 524 => 'userid', - 525 => 'workPostalCode', - 526 => 'workCity', - 527 => 'workProvince', - 528 => 'workCountry', - 529 => 'numberEmployees', - 530 => 'salesVolume', - 531 => 'taxId', - 532 => 'commercialRegister', - 533 => 'branches', - 534 => 'businessCategory', - 535 => 'info', - 536 => 'manager', - 537 => 'assistant', - 538 => 'otherStreet', - 539 => 'otherCity', - 540 => 'otherPostalCode', - 541 => 'otherCountry', - 542 => 'workPhone', - 543 => 'workPhone2', - 544 => 'workFax', - 545 => 'callbackPhone', - 546 => 'carPhone', - 547 => 'companyPhone', - 548 => 'homePhone', - 549 => 'homePhone2', - 550 => 'homeFax', - 551 => 'cellPhone', - 552 => 'workCellPhone', - 553 => 'phone', - 554 => 'fax', - 555 => 'email', - 556 => 'emailWork', - 557 => 'emailHome', - 558 => 'website', - 559 => 'isdnPhone', - 560 => 'pager', - 561 => 'primaryPhone', - 562 => 'radioPhone', - 563 => 'telexPhone', - 564 => 'ttytddPhone', - 565 => 'imaddress', - 566 => 'imaddress2', - 567 => 'sip', - 568 => 'assistPhone', - 569 => 'company', - 570 => 'photo', - 571 => 'userField01', - 572 => 'userField02', - 573 => 'userField03', - 574 => 'userField04', - 575 => 'userField05', - 576 => 'userField06', - 577 => 'userField07', - 578 => 'userField08', - 579 => 'userField09', - 580 => 'userField10', - 581 => 'userField11', - 582 => 'userField12', - 583 => 'userField13', - 584 => 'userField14', - 585 => 'userField15', - 586 => 'userField16', - 587 => 'userField17', - 588 => 'userField18', - 589 => 'userField19', - 590 => 'userField20', - 592 => 'members', - 601 => 'phototype', - 602 => 'distributionList', - 606 => 'photourl', - 610 => 'yomifirstname', - 611 => 'yomilastname', - 612 => 'yomicompany', - 613 => 'homeAddress', - 614 => 'workAddress', - 615 => 'otherAddress', - ); - - /** - * Returns a list contacts. - * - * @param integer $folder A folder ID. If empty, returns contacts of all - * visible address books. - * - * @return array List of contact hashes. - * @throws Horde_OpenXchange_Exception. - */ - public function listContacts($folder = null) - { - $this->_login(); - - $data = array( - 'session' => $this->_session, - 'columns' => implode(',', array_keys($this->_columns)), - ); - if ($folder) { - $data['folder'] = $folder; - } - - $response = $this->_request( - 'GET', - 'contacts', - array('action' => 'all'), - $data - ); - - $contacts = array(); - foreach ($response['data'] as $contact) { - $map = array(); - foreach (array_values($this->_columns) as $key => $column) { - $map[$column] = $contact[$key]; - } - $contacts[] = $map; - } - - return $contacts; - } -} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/EventsAndTasks.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/EventsAndTasks.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/EventsAndTasks.php 2014-05-21 15:33:12.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/EventsAndTasks.php 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ - - * @category Horde - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ - -/** - * Horde_OpenXchange_EventsAndTasks is the base class for the events and tasks - * storage of an Open-Xchange server. - * - * @author Jan Schneider - * @category Horde - * @copyright 2014 Horde LLC - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ -abstract class Horde_OpenXchange_EventsAndTasks extends Horde_OpenXchange_Base -{ - /** - * Column IDs mapped to column names. - * - * @var array - */ - protected $_columns = array( - 1 => 'id', - 20 => 'folder_id', - 100 => 'categories', - 101 => 'private', - 200 => 'title', - 201 => 'start', - 202 => 'end', - 203 => 'description', - 204 => 'alarm', - 209 => 'recur_type', - 212 => 'recur_days', - 213 => 'recur_day_in_month', - 214 => 'recur_month', - 215 => 'recur_interval', - 216 => 'recur_end', - 220 => 'attendees', - 221 => 'users', - 222 => 'recur_count', - 223 => 'uid', - ); - - /** - * Returns a list of events or tasks. - * - * @param integer $folder A folder ID. If empty, returns objects of all - * visible resources. - * @param Horde_Date $start Start date, defaults to epoch. - * @param Horde_Date $end End date, defaults to maximum date possible. - * - * @return array List of object hashes. - * @throws Horde_OpenXchange_Exception. - */ - protected function _listObjects($folder = null, $start = null, $end = null) - { - $this->_login(); - - $data = array( - 'session' => $this->_session, - 'columns' => implode(',', array_keys($this->_columns)), - 'start' => $start ? $start->timestamp() * 1000 : 0, - 'end' => $end ? $end->timestamp() * 1000 : PHP_INT_MAX, - // Doesn't work for some reason. - 'recurrence_master' => true, - ); - if ($folder) { - $data['folder'] = $folder; - } - - $response = $this->_request( - 'GET', - $this->_folderType, - array('action' => 'all'), - $data - ); - - $events = array(); - foreach ($response['data'] as $event) { - $map = array(); - foreach (array_values($this->_columns) as $key => $column) { - $map[$column] = $event[$key]; - } - $events[] = $map; - } - - return $events; - } - - /** - * Returns an event or task. - * - * @param integer $folder A folder ID. - * @param integer $id An object ID. - * - * @return array The object hash. - * @throws Horde_OpenXchange_Exception. - */ - protected function _getObject($folder, $id) - { - $this->_login(); - - $data = array( - 'session' => $this->_session, - 'id' => $id, - 'folder' => $folder, - ); - - $response = $this->_request( - 'GET', - $this->_folderType, - array('action' => 'get'), - $data - ); - - return $response['data']; - } -} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Events.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Events.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Events.php 2014-05-21 15:33:12.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Events.php 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ - - * @category Horde - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ - -/** - * Horde_OpenXchange_Events is the interface class for the events storage - * of an Open-Xchange server. - * - * @author Jan Schneider - * @category Horde - * @copyright 2014 Horde LLC - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ -class Horde_OpenXchange_Events extends Horde_OpenXchange_EventsAndTasks -{ - /** - * The folder category. - * - * @var string - */ - protected $_folderType = 'calendar'; - - /** - * Constructor. - * - * @param array $params List of optional parameters: - * - client: (Horde_Http_Client) An HTTP client. - * - endpoint: (string) The URI of the OX API - * endpoint. - * - user: (string) Authentication user. - * - password: (string) Authentication password. - */ - public function __construct(array $params = array()) - { - parent::__construct($params); - $this->_columns += array( - 206 => 'recur_id', - 207 => 'recur_position', - 210 => 'recur_change_exceptions', - 211 => 'recur_delete_exceptions', - 224 => 'organizer', - 225 => 'sequence', - 226 => 'confirmations', - 400 => 'location', - 401 => 'allday', - 402 => 'status', - 408 => 'timezone', - ); - } - - /** - * Returns a list events. - * - * @param integer $folder A folder ID. If empty, returns events of all - * visible calendars. - * @param Horde_Date $start Start date, defaults to epoch. - * @param Horde_Date $end End date, defaults to maximum date possible. - * - * @return array List of event hashes. - * @throws Horde_OpenXchange_Exception. - */ - public function listEvents($folder = null, $start = null, $end = null) - { - return $this->_listObjects($folder, $start, $end); - } - - /** - * Returns an event. - * - * @param integer $folder A folder ID. - * @param integer $id An event ID. - * - * @return array The event hash. - * @throws Horde_OpenXchange_Exception. - */ - public function getEvent($folder, $id) - { - return $this->_getObject($folder, $id); - } -} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Exception.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Exception.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Exception.php 2014-05-21 15:33:12.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Exception.php 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ - - * @category Horde - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ - -/** - * Base exception class for Horde_OpenXchange. - * - * @author Jan Schneider - * @category Horde - * @copyright 2014 Horde LLC - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ -class Horde_OpenXchange_Exception extends Horde_Exception_Wrapped -{ -} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Tasks.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Tasks.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Tasks.php 2014-05-21 15:33:12.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Tasks.php 1970-01-01 00:00:00.000000000 +0000 @@ -1,124 +0,0 @@ - - * @category Horde - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ - -/** - * Horde_OpenXchange_Tasks is the interface class for the tasks storage - * of an Open-Xchange server. - * - * @author Jan Schneider - * @category Horde - * @copyright 2014 Horde LLC - * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 - * @package OpenXchange - */ -class Horde_OpenXchange_Tasks extends Horde_OpenXchange_EventsAndTasks -{ - /** - * Status: not started. - */ - const STATUS_NOT_STARTED = 1; - - /** - * Status: in progress. - */ - const STATUS_IN_PROGRESS = 2; - - /** - * Status: done. - */ - const STATUS_DONE = 3; - - /** - * Status: waiting. - */ - const STATUS_WAITING = 4; - - /** - * Status: deferred. - */ - const STATUS_DEFERRED = 5; - - /** - * Priority: high. - */ - const PRIORITY_LOW = 1; - - /** - * Priority: high. - */ - const PRIORITY_MEDIUM = 2; - - /** - * Priority: high. - */ - const PRIORITY_HIGH = 3; - - /** - * The folder category. - * - * @var string - */ - protected $_folderType = 'tasks'; - - /** - * Constructor. - * - * @param array $params List of optional parameters: - * - client: (Horde_Http_Client) An HTTP client. - * - endpoint: (string) The URI of the OX API - * endpoint. - * - user: (string) Authentication user. - * - password: (string) Authentication password. - */ - public function __construct(array $params = array()) - { - parent::__construct($params); - $this->_columns += array( - 300 => 'status', - 301 => 'percent', - 308 => 'duration', - 309 => 'priority', - 315 => 'completed', - ); - } - - /** - * Returns a list tasks. - * - * @param integer $folder A folder ID. If empty, returns tasks of all - * visible task lists. - * @param Horde_Date $start Start date, defaults to epoch. - * @param Horde_Date $end End date, defaults to maximum date possible. - * - * @return array List of task hashes. - * @throws Horde_OpenXchange_Exception. - */ - public function listTasks($folder = null, $start = null, $end = null) - { - return $this->_listObjects($folder, $start, $end); - } - - /** - * Returns an task. - * - * @param integer $folder A folder ID. - * @param integer $id An task ID. - * - * @return array The task hash. - * @throws Horde_OpenXchange_Exception. - */ - public function getTask($folder, $id) - { - return $this->_getObject($folder, $id); - } -} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Base.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Base.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Base.php 1970-01-01 00:00:00.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Base.php 2017-09-19 09:13:49.000000000 +0000 @@ -0,0 +1,379 @@ + + * @category Horde + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ + +/** + * Horde_OpenXchange_Base is the base class for HTTP API requests to an + * Open-Xchange server. + * + * @link http://oxpedia.org/wiki/index.php?title=HTTP_API + * @author Jan Schneider + * @category Horde + * @copyright 2014-2017 Horde LLC + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ +abstract class Horde_OpenXchange_Base +{ + /** + * Return private resources. + * + * @see listResources() + */ + const RESOURCE_PRIVATE = 'private'; + + /** + * Return public resources. + * + * @see listResources() + */ + const RESOURCE_PUBLIC = 'public'; + + /** + * The folder category. + * + * @var string + */ + protected $_folderType; + + /** + * Any parameters. + * + * @var array + */ + protected $_params; + + /** + * HTTP client + * + * @var Horde_Http_Client + */ + protected $_client; + + /** + * Base URI of the API endpoint. + * + * @var string + */ + protected $_uri; + + /** + * All cookies to sent with OX requests. + * + * @var array + */ + protected $_cookies = array(); + + /** + * The current session ID. + * + * @var string + */ + protected $_session; + + /** + * Constructor. + * + * @param array $params List of optional parameters: + * - client: (Horde_Http_Client) An HTTP client. + * - endpoint: (string) The URI of the OX API + * endpoint. + * - user: (string) Authentication user. + * - password: (string) Authentication password. + */ + public function __construct(array $params = array()) + { + if (isset($params['client'])) { + $this->_client = $params['client']; + unset($params['client']); + } else { + $this->_client = new Horde_Http_Client(array('request.timeout' => 10)); + } + $this->_params = array_merge( + array('endpoint' => 'http://localhost/ajax'), + $params + ); + $this->_uri = $this->_params['endpoint']; + } + + /** + * Logs a user in. + * + * @param string $user A user name. + * @param string $password A password. + * + * @throws Horde_OpenXchange_Exception. + */ + public function login($user, $password) + { + $this->_params['user'] = $user; + $this->_params['password'] = $password; + $this->_login(); + } + + /** + * Logs the current user out. + * + * @throws Horde_OpenXchange_Exception. + */ + public function logout() + { + if (!isset($this->_session)) { + return; + } + + $response = $this->_request( + 'GET', + 'login', + array('action' => 'logout'), + array('session' => $this->_session) + ); + + unset($this->_session); + $this->_cookies = array(); + } + + /** + * Returns information about a system user. + * + * @param integer $id A user ID. + * + * @return array User information hash. + * @throws Horde_OpenXchange_Exception. + */ + public function getUser($id) + { + $user = $this->_request( + 'GET', + 'user', + array( + 'action' => 'get', + 'session' => $this->_session, + 'id' => $id, + ) + ); + return $user['data']; + } + + /** + * Returns information about a system group. + * + * @param integer $id A group ID. + * + * @return array Group information hash. + * @throws Horde_OpenXchange_Exception. + */ + public function getGroup($id) + { + $group = $this->_request( + 'GET', + 'group', + array( + 'action' => 'get', + 'session' => $this->_session, + 'id' => $id, + ) + ); + return $group; + } + + /** + * Returns user configuration. + * + * @param string $config A configuration namespace. + * + * @return mixed Configuration contents. + * @throws Horde_OpenXchange_Exception. + */ + public function getConfig($config) + { + $content = $this->_request( + 'GET', + 'config/' . $config, + array('session' => $this->_session) + ); + switch ($content['data']) { + case 'true': + return true; + case 'false': + return false; + case 'null': + return null; + default: + return $content['data']; + } + } + + /** + * Returns a list of visible groupware resources. + * + * @param string $type An resource type, one of the RESOURCE_* constants. + * + * @return array List of resources with resource IDs as keys and + * information hashes as values. + * @throws Horde_OpenXchange_Exception. + */ + public function listResources($type = self::RESOURCE_PRIVATE) + { + $this->_login(); + + $response = $this->_request( + 'PUT', + 'folders', + array( + 'action' => 'allVisible', + 'session' => $this->_session, + 'content_type' => $this->_folderType, + 'columns' => '1,300,306,308' + ) + ); + + $resources = $users = $groups = array(); + foreach ($response['data'][$type] as $resource) { + $info = array( + 'label' => $resource[1], + 'default' => $resource[3], + ); + foreach ($resource[2] as $perm) { + // http://oxpedia.org/wiki/index.php?title=HTTP_API#PermissionFlags + $permission = 0; + if ($perm['bits'] & 127) { + $permission |= Horde_Perms::SHOW; + } + if ((($perm['bits'] >> 7) & 127) > 1) { + $permission |= Horde_Perms::READ; + } + if ((($perm['bits'] >> 14) & 127) > 1) { + $permission |= Horde_Perms::EDIT; + } + if ((($perm['bits'] >> 21) & 127) > 1) { + $permission |= Horde_Perms::DELETE; + } + if ($perm['group']) { + if (!isset($groups[$perm['entity']])) { + $group = $this->getGroup($perm['entity']); + $groups[$perm['entity']] = $group['name']; + } + $info['permission']['group'][$groups[$perm['entity']]] = $perm['bits']; + $info['hordePermission']['group'][$groups[$perm['entity']]] = $permission; + } else { + if (!isset($users[$perm['entity']])) { + $user = $this->getUser($perm['entity']); + $users[$perm['entity']] = $user['login_info']; + } + $info['permission']['user'][$users[$perm['entity']]] = $perm['bits']; + $info['hordePermission']['user'][$users[$perm['entity']]] = $permission; + } + } + $resources[$resource[0]] = $info; + } + + return $resources; + } + + /** + * Logs a user in, if necessary. + * + * @throws Horde_OpenXchange_Exception. + */ + protected function _login() + { + if (isset($this->_session)) { + return; + } + + if (!isset($this->_params['user']) || + !isset($this->_params['password'])) { + throw new LogicException('User name or password missing'); + } + + $response = $this->_request( + 'POST', + 'login', + array('action' => 'login'), + array( + 'name' => $this->_params['user'], + 'password' => $this->_params['password'] + ) + ); + + $this->_session = $response['session']; + } + + /** + * Sends a request and parses the response. + * + * @param string $method A HTTP request method (uppercase). + * @param string $namespace An API namespace. + * @param array $params URL parameters. + * @param array|string $data Request data. + * + * @return array The decoded result data or null if no data has been + * returned but the request was still successful. + * @throws Horde_OpenXchange_Exception. + */ + protected function _request($method, $namespace, $params, $data = array()) + { + $uri = new Horde_Url($this->_uri . '/' . $namespace, true); + try { + $headers = array(); + if (isset($this->_cookies)) { + $headers['Cookie'] = implode('; ', $this->_cookies); + } + if ($method == 'GET') { + $params = array_merge($params, $data); + $data = null; + } + $response = $this->_client->request( + $method, + (string)$uri->add($params), + $data, + $headers + ); + if ($cookies = $response->getHeader('set-cookie')) { + if (!is_array($cookies)) { + $cookies = array($cookies); + } + foreach ($cookies as $cookie) { + $cookie = preg_split('/;\s*/', $cookie); + for ($i = 1, $c = count($cookie); $i < $c; $i++) { + list($key, $value) = explode('=', $cookie[$i]); + if ($key == 'Expires') { + $expire = new Horde_Date($value); + if ($expire->before(time())) { + continue 2; + } + break; + } + } + $this->_cookies[] = $cookie[0]; + } + } + $body = $response->getBody(); + $data = json_decode($body, true); + if (!$data) { + if ($response->code == 200) { + return; + } + throw new Horde_OpenXchange_Exception($body); + } + if (isset($data['error'])) { + $e = new Horde_OpenXchange_Exception($data['error']); + $e->details = $data; + throw $e; + } + return $data; + } catch (Horde_Http_Exception $e) { + throw new Horde_OpenXchange_Exception($e); + } + } +} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Contacts.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Contacts.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Contacts.php 1970-01-01 00:00:00.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Contacts.php 2017-09-19 09:13:49.000000000 +0000 @@ -0,0 +1,185 @@ + + * @category Horde + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ + +/** + * Horde_OpenXchange_Contacts is the interface class for the contacts storage + * of an Open-Xchange server. + * + * @author Jan Schneider + * @category Horde + * @copyright 2014-2017 Horde LLC + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ +class Horde_OpenXchange_Contacts extends Horde_OpenXchange_Base +{ + /** + * The folder category. + * + * @var string + */ + protected $_folderType = 'contacts'; + + /** + * Column IDs mapped to column names. + * + * @var array + */ + protected $_columns = array( + 1 => 'id', + 20 => 'folder_id', + 100 => 'categories', + 223 => 'uid', + 500 => 'name', + 501 => 'firstname', + 502 => 'lastname', + 503 => 'middlenames', + 504 => 'nameSuffix', + 505 => 'namePrefix', + 506 => 'homeStreet', + 507 => 'homePostalCode', + 508 => 'homeCity', + 509 => 'homeProvince', + 510 => 'homeCountry', + 511 => 'birthday', + 512 => 'maritalStatus', + 513 => 'numberChildren', + 514 => 'role', + 515 => 'nickname', + 516 => 'spouse', + 517 => 'anniversary', + 518 => 'notes', + 519 => 'department', + 520 => 'title', + 521 => 'employeeType', + 522 => 'office', + 523 => 'workStreet', + 524 => 'userid', + 525 => 'workPostalCode', + 526 => 'workCity', + 527 => 'workProvince', + 528 => 'workCountry', + 529 => 'numberEmployees', + 530 => 'salesVolume', + 531 => 'taxId', + 532 => 'commercialRegister', + 533 => 'branches', + 534 => 'businessCategory', + 535 => 'info', + 536 => 'manager', + 537 => 'assistant', + 538 => 'otherStreet', + 539 => 'otherCity', + 540 => 'otherPostalCode', + 541 => 'otherCountry', + 542 => 'workPhone', + 543 => 'workPhone2', + 544 => 'workFax', + 545 => 'callbackPhone', + 546 => 'carPhone', + 547 => 'companyPhone', + 548 => 'homePhone', + 549 => 'homePhone2', + 550 => 'homeFax', + 551 => 'cellPhone', + 552 => 'workCellPhone', + 553 => 'phone', + 554 => 'fax', + 555 => 'email', + 556 => 'emailWork', + 557 => 'emailHome', + 558 => 'website', + 559 => 'isdnPhone', + 560 => 'pager', + 561 => 'primaryPhone', + 562 => 'radioPhone', + 563 => 'telexPhone', + 564 => 'ttytddPhone', + 565 => 'imaddress', + 566 => 'imaddress2', + 567 => 'sip', + 568 => 'assistPhone', + 569 => 'company', + 570 => 'photo', + 571 => 'userField01', + 572 => 'userField02', + 573 => 'userField03', + 574 => 'userField04', + 575 => 'userField05', + 576 => 'userField06', + 577 => 'userField07', + 578 => 'userField08', + 579 => 'userField09', + 580 => 'userField10', + 581 => 'userField11', + 582 => 'userField12', + 583 => 'userField13', + 584 => 'userField14', + 585 => 'userField15', + 586 => 'userField16', + 587 => 'userField17', + 588 => 'userField18', + 589 => 'userField19', + 590 => 'userField20', + 592 => 'members', + 601 => 'phototype', + 602 => 'distributionList', + 606 => 'photourl', + 610 => 'yomifirstname', + 611 => 'yomilastname', + 612 => 'yomicompany', + 613 => 'homeAddress', + 614 => 'workAddress', + 615 => 'otherAddress', + ); + + /** + * Returns a list contacts. + * + * @param integer $folder A folder ID. If empty, returns contacts of all + * visible address books. + * + * @return array List of contact hashes. + * @throws Horde_OpenXchange_Exception. + */ + public function listContacts($folder = null) + { + $this->_login(); + + $data = array( + 'session' => $this->_session, + 'columns' => implode(',', array_keys($this->_columns)), + ); + if ($folder) { + $data['folder'] = $folder; + } + + $response = $this->_request( + 'GET', + 'contacts', + array('action' => 'all'), + $data + ); + + $contacts = array(); + foreach ($response['data'] as $contact) { + $map = array(); + foreach (array_values($this->_columns) as $key => $column) { + $map[$column] = $contact[$key]; + } + $contacts[] = $map; + } + + return $contacts; + } +} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/EventsAndTasks.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/EventsAndTasks.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/EventsAndTasks.php 1970-01-01 00:00:00.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/EventsAndTasks.php 2017-09-19 09:13:49.000000000 +0000 @@ -0,0 +1,127 @@ + + * @category Horde + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ + +/** + * Horde_OpenXchange_EventsAndTasks is the base class for the events and tasks + * storage of an Open-Xchange server. + * + * @author Jan Schneider + * @category Horde + * @copyright 2014-2017 Horde LLC + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ +abstract class Horde_OpenXchange_EventsAndTasks extends Horde_OpenXchange_Base +{ + /** + * Column IDs mapped to column names. + * + * @var array + */ + protected $_columns = array( + 1 => 'id', + 20 => 'folder_id', + 100 => 'categories', + 101 => 'private', + 200 => 'title', + 201 => 'start', + 202 => 'end', + 203 => 'description', + 204 => 'alarm', + 209 => 'recur_type', + 212 => 'recur_days', + 213 => 'recur_day_in_month', + 214 => 'recur_month', + 215 => 'recur_interval', + 216 => 'recur_end', + 220 => 'attendees', + 221 => 'users', + 222 => 'recur_count', + 223 => 'uid', + ); + + /** + * Returns a list of events or tasks. + * + * @param integer $folder A folder ID. If empty, returns objects of all + * visible resources. + * @param Horde_Date $start Start date, defaults to epoch. + * @param Horde_Date $end End date, defaults to maximum date possible. + * + * @return array List of object hashes. + * @throws Horde_OpenXchange_Exception. + */ + protected function _listObjects($folder = null, $start = null, $end = null) + { + $this->_login(); + + $data = array( + 'session' => $this->_session, + 'columns' => implode(',', array_keys($this->_columns)), + 'start' => $start ? $start->timestamp() * 1000 : 0, + 'end' => $end ? $end->timestamp() * 1000 : PHP_INT_MAX, + // Doesn't work for some reason. + 'recurrence_master' => true, + ); + if ($folder) { + $data['folder'] = $folder; + } + + $response = $this->_request( + 'GET', + $this->_folderType, + array('action' => 'all'), + $data + ); + + $events = array(); + foreach ($response['data'] as $event) { + $map = array(); + foreach (array_values($this->_columns) as $key => $column) { + $map[$column] = $event[$key]; + } + $events[] = $map; + } + + return $events; + } + + /** + * Returns an event or task. + * + * @param integer $folder A folder ID. + * @param integer $id An object ID. + * + * @return array The object hash. + * @throws Horde_OpenXchange_Exception. + */ + protected function _getObject($folder, $id) + { + $this->_login(); + + $data = array( + 'session' => $this->_session, + 'id' => $id, + 'folder' => $folder, + ); + + $response = $this->_request( + 'GET', + $this->_folderType, + array('action' => 'get'), + $data + ); + + return $response['data']; + } +} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Events.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Events.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Events.php 1970-01-01 00:00:00.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Events.php 2017-09-19 09:13:49.000000000 +0000 @@ -0,0 +1,90 @@ + + * @category Horde + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ + +/** + * Horde_OpenXchange_Events is the interface class for the events storage + * of an Open-Xchange server. + * + * @author Jan Schneider + * @category Horde + * @copyright 2014-2017 Horde LLC + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ +class Horde_OpenXchange_Events extends Horde_OpenXchange_EventsAndTasks +{ + /** + * The folder category. + * + * @var string + */ + protected $_folderType = 'calendar'; + + /** + * Constructor. + * + * @param array $params List of optional parameters: + * - client: (Horde_Http_Client) An HTTP client. + * - endpoint: (string) The URI of the OX API + * endpoint. + * - user: (string) Authentication user. + * - password: (string) Authentication password. + */ + public function __construct(array $params = array()) + { + parent::__construct($params); + $this->_columns += array( + 206 => 'recur_id', + 207 => 'recur_position', + 210 => 'recur_change_exceptions', + 211 => 'recur_delete_exceptions', + 224 => 'organizer', + 225 => 'sequence', + 226 => 'confirmations', + 400 => 'location', + 401 => 'allday', + 402 => 'status', + 408 => 'timezone', + ); + } + + /** + * Returns a list events. + * + * @param integer $folder A folder ID. If empty, returns events of all + * visible calendars. + * @param Horde_Date $start Start date, defaults to epoch. + * @param Horde_Date $end End date, defaults to maximum date possible. + * + * @return array List of event hashes. + * @throws Horde_OpenXchange_Exception. + */ + public function listEvents($folder = null, $start = null, $end = null) + { + return $this->_listObjects($folder, $start, $end); + } + + /** + * Returns an event. + * + * @param integer $folder A folder ID. + * @param integer $id An event ID. + * + * @return array The event hash. + * @throws Horde_OpenXchange_Exception. + */ + public function getEvent($folder, $id) + { + return $this->_getObject($folder, $id); + } +} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Exception.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Exception.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Exception.php 1970-01-01 00:00:00.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Exception.php 2017-09-19 09:13:49.000000000 +0000 @@ -0,0 +1,25 @@ + + * @category Horde + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ + +/** + * Base exception class for Horde_OpenXchange. + * + * @author Jan Schneider + * @category Horde + * @copyright 2014-2017 Horde LLC + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ +class Horde_OpenXchange_Exception extends Horde_Exception_Wrapped +{ +} diff -Nru php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Tasks.php php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Tasks.php --- php-horde-openxchange-1.0.0/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Tasks.php 1970-01-01 00:00:00.000000000 +0000 +++ php-horde-openxchange-1.0.1/Horde_OpenXchange-1.0.1/lib/Horde/OpenXchange/Tasks.php 2017-09-19 09:13:49.000000000 +0000 @@ -0,0 +1,124 @@ + + * @category Horde + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ + +/** + * Horde_OpenXchange_Tasks is the interface class for the tasks storage + * of an Open-Xchange server. + * + * @author Jan Schneider + * @category Horde + * @copyright 2014-2017 Horde LLC + * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 + * @package OpenXchange + */ +class Horde_OpenXchange_Tasks extends Horde_OpenXchange_EventsAndTasks +{ + /** + * Status: not started. + */ + const STATUS_NOT_STARTED = 1; + + /** + * Status: in progress. + */ + const STATUS_IN_PROGRESS = 2; + + /** + * Status: done. + */ + const STATUS_DONE = 3; + + /** + * Status: waiting. + */ + const STATUS_WAITING = 4; + + /** + * Status: deferred. + */ + const STATUS_DEFERRED = 5; + + /** + * Priority: high. + */ + const PRIORITY_LOW = 1; + + /** + * Priority: high. + */ + const PRIORITY_MEDIUM = 2; + + /** + * Priority: high. + */ + const PRIORITY_HIGH = 3; + + /** + * The folder category. + * + * @var string + */ + protected $_folderType = 'tasks'; + + /** + * Constructor. + * + * @param array $params List of optional parameters: + * - client: (Horde_Http_Client) An HTTP client. + * - endpoint: (string) The URI of the OX API + * endpoint. + * - user: (string) Authentication user. + * - password: (string) Authentication password. + */ + public function __construct(array $params = array()) + { + parent::__construct($params); + $this->_columns += array( + 300 => 'status', + 301 => 'percent', + 308 => 'duration', + 309 => 'priority', + 315 => 'completed', + ); + } + + /** + * Returns a list tasks. + * + * @param integer $folder A folder ID. If empty, returns tasks of all + * visible task lists. + * @param Horde_Date $start Start date, defaults to epoch. + * @param Horde_Date $end End date, defaults to maximum date possible. + * + * @return array List of task hashes. + * @throws Horde_OpenXchange_Exception. + */ + public function listTasks($folder = null, $start = null, $end = null) + { + return $this->_listObjects($folder, $start, $end); + } + + /** + * Returns an task. + * + * @param integer $folder A folder ID. + * @param integer $id An task ID. + * + * @return array The task hash. + * @throws Horde_OpenXchange_Exception. + */ + public function getTask($folder, $id) + { + return $this->_getObject($folder, $id); + } +} diff -Nru php-horde-openxchange-1.0.0/package.xml php-horde-openxchange-1.0.1/package.xml --- php-horde-openxchange-1.0.0/package.xml 2014-05-21 15:33:12.000000000 +0000 +++ php-horde-openxchange-1.0.1/package.xml 2017-09-19 09:13:49.000000000 +0000 @@ -1,5 +1,5 @@ - + Horde_OpenXchange pear.horde.org Open-Xchange Connector @@ -10,10 +10,10 @@ jan@horde.org yes - 2014-05-21 - + 2017-09-19 + - 1.0.0 + 1.0.1 1.0.0 @@ -22,24 +22,24 @@ LGPL-2.1 -* [jan] First stable release. +* [jan] Mark PHP 7 as supported. - - - - - - + + + + + + 5.3.0 - 6.0.0alpha1 - 6.0.0alpha1 + 8.0.0alpha1 + 8.0.0alpha1 1.7.0 @@ -115,5 +115,20 @@ * [jan] First stable release. + + + 1.0.1 + 1.0.0 + + + stable + stable + + 2017-09-19 + LGPL-2.1 + +* [jan] Mark PHP 7 as supported. + +