package.xml0000664000175000017500000000777612337143470011324 0ustar janjan Horde_OpenXchange pear.horde.org Open-Xchange Connector Library to interact with Open-Xchange servers. Jan Schneider jan jan@horde.org yes 2014-05-21 1.0.0 1.0.0 stable stable LGPL-2.1 * [jan] First stable release. 5.3.0 6.0.0alpha1 6.0.0alpha1 1.7.0 Horde_Date pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 Horde_Http pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 Horde_Perms pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 Horde_Url pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 1.0.0alpha1 1.0.0alpha1 alpha alpha 2014-05-05 LGPL-2.1 * Initial release. 1.0.0 1.0.0 stable stable 2014-05-21 LGPL-2.1 * [jan] First stable release. Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Base.php0000664000175000017500000002514212337143470020535 0ustar janjan * @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); } } } Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Contacts.php0000664000175000017500000001162712337143470021444 0ustar janjan * @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; } } Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Events.php0000664000175000017500000000521712337143470021130 0ustar janjan * @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); } } Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/EventsAndTasks.php0000664000175000017500000000663312337143470022564 0ustar janjan * @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']; } } Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Exception.php0000664000175000017500000000123612337143470021617 0ustar janjan * @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 { } Horde_OpenXchange-1.0.0/lib/Horde/OpenXchange/Tasks.php0000664000175000017500000000573712337143470020760 0ustar janjan * @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); } }