| #!/usr/bin/env php |
| <?php |
| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @file |
| * Basic class for accessing Usergrid functionality. |
| * |
| * @author Daniel Johnson <djohnson@apigee.com> |
| * @author Rod Simpson <rod@apigee.com> |
| * @since 26-Apr-2013 |
| */ |
| |
| namespace Apache\Usergrid; |
| |
| require_once(dirname(__FILE__) . '/Exceptions.php'); |
| |
| define('AUTH_CLIENT_ID', 'CLIENT_ID'); |
| define('AUTH_APP_USER', 'APP_USER'); |
| define('AUTH_NONE', 'NONE'); |
| |
| class Client { |
| |
| const SDK_VERSION = '0.1'; |
| |
| /** |
| * Usergrid endpoint |
| * @var string |
| */ |
| private $url = 'http://api.usergrid.com'; |
| |
| /** |
| * Organization name. Find your in the Admin Portal |
| * @var string |
| */ |
| private $org_name; |
| |
| /** |
| * App name. Find your in the Admin Portal |
| * @var string |
| */ |
| private $app_name; |
| |
| /** |
| * @var bool |
| */ |
| private $build_curl = FALSE; |
| |
| /** |
| * @var bool |
| */ |
| private $use_exceptions = FALSE; |
| |
| /** |
| * @var Callable |
| */ |
| private $log_callback = NULL; |
| |
| /** |
| * @var int |
| */ |
| private $call_timeout = 30000; |
| |
| /** |
| * @var Callable |
| */ |
| private $call_timeout_callback = NULL; |
| |
| /** |
| * @var Callable |
| */ |
| private $logout_callback = NULL; |
| |
| /** |
| * @var string |
| */ |
| private $oauth_token; |
| |
| /** |
| * @var string |
| */ |
| private $client_id; |
| |
| /** |
| * @var string |
| */ |
| private $client_secret; |
| |
| /** |
| * @var string |
| */ |
| private $auth_type = AUTH_APP_USER; |
| |
| /** |
| * Object constructor |
| * |
| * @param string $org_name |
| * @param string $app_name |
| */ |
| public function __construct($org_name, $app_name) { |
| $this->org_name = $org_name; |
| $this->app_name = $app_name; |
| } |
| |
| /* Accessor functions */ |
| |
| /** |
| * Returns OAuth token if it has been set; else NULL. |
| * |
| * @return string|NULL |
| */ |
| public function get_oauth_token() { |
| return $this->oauth_token; |
| } |
| |
| /** |
| * Sets OAuth token. |
| * |
| * @param string $token |
| */ |
| public function set_oauth_token($token) { |
| $this->oauth_token = $token; |
| } |
| |
| /** |
| * Returns the authorization type in use. |
| * |
| * @return string |
| */ |
| public function get_auth_type() { |
| return $this->auth_type; |
| } |
| |
| /** |
| * Sets (and validates) authorization type in use. If an invalid auth_type is |
| * passed, AUTH_APP_USER is assumed. |
| * |
| * @param $auth_type |
| * @throws UGException |
| */ |
| public function set_auth_type($auth_type) { |
| if ($auth_type == AUTH_APP_USER || $auth_type == AUTH_CLIENT_ID || $auth_type == AUTH_NONE) { |
| $this->auth_type = $auth_type; |
| } |
| else { |
| $this->auth_type = AUTH_APP_USER; |
| if ($this->use_exceptions) { |
| throw new UGException('Auth type is not valid'); |
| } |
| } |
| } |
| |
| /** |
| * Returns client_id. |
| * |
| * @return string |
| */ |
| public function get_client_id() { |
| return $this->client_id; |
| } |
| |
| /** |
| * Sets the client ID. |
| * |
| * @param string $id |
| */ |
| public function set_client_id($id) { |
| $this->client_id = $id; |
| } |
| |
| /** |
| * Gets the client secret. |
| * |
| * @return string |
| */ |
| public function get_client_secret() { |
| return $this->client_secret; |
| } |
| |
| /** |
| * Sets the client secret. You should have received this information when |
| * you registered your UserGrid/Apache account. |
| * |
| * @param $secret |
| */ |
| public function set_client_secret($secret) { |
| $this->client_secret = $secret; |
| } |
| |
| /** |
| * When set to TRUE, a curl command-line string will be generated. This may |
| * be useful when debugging. |
| * |
| * @param bool $bool |
| */ |
| public function enable_build_curl($bool = TRUE) { |
| $this->build_curl = (bool) $bool; |
| } |
| |
| /** |
| * Returns TRUE if curl command-line building is enabled, else FALSE. |
| * |
| * @return bool |
| */ |
| public function is_build_curl_enabled() { |
| return $this->build_curl; |
| } |
| |
| /** |
| * Enables/disables use of exceptions when errors are encountered. |
| * |
| * @param bool $bool |
| */ |
| public function enable_exceptions($bool = TRUE) { |
| $this->use_exceptions = (bool) $bool; |
| } |
| |
| /** |
| * @return bool |
| */ |
| public function are_exceptions_enabled() { |
| return $this->use_exceptions; |
| } |
| |
| /** |
| * Sets the callback for logging functions. |
| * |
| * @param Callable|NULL $callback |
| * @throws UGException |
| * @see write_log() |
| */ |
| public function set_log_callback($callback = NULL) { |
| if (!empty($callback) && !is_callable($callback)) { |
| if ($this->use_exceptions) { |
| throw new UGException('Log Callback is not callable.'); |
| } |
| $this->log_callback = NULL; |
| } |
| else { |
| $this->log_callback = (empty($callback) ? NULL : $callback); |
| } |
| } |
| |
| /** |
| * Sets the timeout for HTTP calls in seconds. Internally this is stored in |
| * milliseconds. |
| * |
| * @param int|float $seconds |
| */ |
| public function set_call_timeout($seconds = 30) { |
| $this->call_timeout = intval($seconds * 1000); |
| } |
| |
| /** |
| * Gets timeout for HTTP calls in seconds. May return fractional parts. |
| * |
| * @return float |
| */ |
| public function get_call_timeout() { |
| return $this->call_timeout / 1000; |
| } |
| |
| /** |
| * Sets the callback to be invoked when an HTTP call timeout occurs. |
| * |
| * @TODO Actually use/invoke this callback. Currently not implemented. |
| * |
| * @param Callable|null $callback |
| * @throws UGException |
| */ |
| public function set_call_timeout_callback($callback = NULL) { |
| if (!empty($callback) && !is_callable($callback)) { |
| if ($this->use_exceptions) { |
| throw new UGException('Call Timeout Callback is not callable.'); |
| } |
| $this->call_timeout_callback = NULL; |
| } |
| else { |
| $this->call_timeout_callback = (empty($callback) ? NULL : $callback); |
| } |
| } |
| |
| /** |
| * Sets the callback to be invoked upon logout. |
| * |
| * @TODO Actually use/invoke this callback. Currently not implemented. |
| * |
| * @param Callable|null $callback |
| * @throws UGException |
| */ |
| public function set_logout_callback($callback = NULL) { |
| if (!empty($callback) && !is_callable($callback)) { |
| if ($this->use_exceptions) { |
| throw new UGException('Logout Callback is not callable.'); |
| } |
| $this->logout_callback = NULL; |
| } |
| else { |
| $this->logout_callback = (empty($callback) ? NULL : $callback); |
| } |
| } |
| |
| /* End accessor functions */ |
| |
| /** |
| * If a log callback has been set, invoke it to write a given message. |
| * |
| * @param $message |
| */ |
| public function write_log($message) { |
| if (isset($this->log_callback)) { |
| call_user_func($this->log_callback, $message); |
| } |
| } |
| |
| /** |
| * Issues a CURL request via HTTP/HTTPS and returns the response. |
| * |
| * @param Request $request |
| * @return Response |
| * @throws UG_404_NotFound |
| * @throws UG_403_Forbidden |
| * @throws UGException |
| * @throws UG_500_ServerError |
| * @throws UG_401_Unauthorized |
| * @throws UG_400_BadRequest |
| */ |
| public function request(Request $request) { |
| |
| $method = $request->get_method(); |
| $endpoint = $request->get_endpoint(); |
| $body = $request->get_body(); |
| $query_string_array = $request->get_query_string_array(); |
| |
| if ($this->get_auth_type() == AUTH_APP_USER) { |
| if ($token = $this->get_oauth_token()) { |
| $query_string_array['access_token'] = $token; |
| } |
| } else { |
| $query_string_array['client_id'] = $this->get_client_id(); |
| $query_string_array['client_secret'] = $this->get_client_secret(); |
| } |
| |
| foreach ($query_string_array as $key => $value) { |
| $query_string_array[$key] = urlencode($value); |
| } |
| $query_string = http_build_query($query_string_array); |
| if ($request->get_management_query()) { |
| $url = $this->url . '/' . $endpoint; |
| } |
| else { |
| $url = $this->url . '/' . $this->org_name . '/' . $this->app_name . '/' . $endpoint; |
| } |
| |
| //append params to the path |
| if ($query_string) { |
| $url .= '?' . $query_string; |
| } |
| $curl = curl_init($url); |
| |
| if ($method == 'POST' || $method == 'PUT' || $method == 'DELETE') { |
| curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); |
| } |
| if ($method == 'POST' || $method == 'PUT') { |
| $body = json_encode($body); |
| curl_setopt($curl, CURLOPT_HTTPHEADER, array( |
| 'Content-Length: ' . strlen($body), |
| 'Content-Type: application/json' |
| )); |
| curl_setopt($curl, CURLOPT_POSTFIELDS, $body); |
| } |
| |
| |
| curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); |
| curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); |
| curl_setopt($curl, CURLOPT_FOLLOWLOCATION, FALSE); |
| curl_setopt($curl, CURLOPT_MAXREDIRS, 10); |
| curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); |
| |
| |
| $response = curl_exec($curl); |
| $meta = curl_getinfo($curl); |
| |
| curl_close($curl); |
| |
| |
| $response_array = @json_decode($response, TRUE); |
| $response_obj = new Response(); |
| $response_obj->set_curl_meta($meta); |
| $response_obj->set_data($response_array); |
| |
| $response_json = $response; |
| $response_obj->set_json($response_json); |
| |
| if ($meta['http_code'] != 200) { |
| //there was an API error |
| $error_code = $response_array['error']; |
| $description = isset($response_array['error_description'])?$response_array['error_description']:''; |
| $description = isset($response_array['exception'])?$response_array['exception']:$description; |
| $this->write_log('Error: '.$meta['http_code'].' error:'.$description); |
| $response_obj->set_error(TRUE); |
| $response_obj->set_error_code($error_code); |
| $response_obj->set_error_message($description); |
| |
| if ($this->use_exceptions) { |
| switch ($meta['http_code']) { |
| case 400: |
| throw new UG_400_BadRequest($description, $meta['http_code']); |
| break; |
| case 401: |
| throw new UG_401_Unauthorized($description, $meta['http_code']); |
| break; |
| case 403: |
| throw new UG_403_Forbidden($description, $meta['http_code']); |
| break; |
| case 404: |
| throw new UG_404_NotFound($description, $meta['http_code']); |
| break; |
| case 500: |
| throw new UG_500_ServerError($description, $meta['http_code']); |
| break; |
| default: |
| throw new UGException($description, $meta['http_code']); |
| break; |
| } |
| } |
| |
| } |
| else { |
| $response_obj->set_error(FALSE); |
| $response_obj->set_error_message(FALSE); |
| } |
| |
| return $response_obj; |
| } |
| |
| /** |
| * Performs an HTTP GET operation |
| * |
| * @param string $endpoint |
| * @param array $query_string_array |
| * @return Response |
| */ |
| public function get($endpoint, $query_string_array) { |
| |
| $request = new Request(); |
| $request->set_method('GET'); |
| $request->set_endpoint($endpoint); |
| $request->set_query_string_array($query_string_array); |
| |
| $response = $this->request($request); |
| |
| return $response; |
| } |
| |
| /** |
| * Performs an HTTP POST operation |
| * |
| * @param string $endpoint |
| * @param array $query_string_array |
| * @param array $body |
| * @return Response |
| */ |
| public function post($endpoint, $query_string_array, $body) { |
| |
| $request = new Request(); |
| $request->set_method('POST'); |
| $request->set_endpoint($endpoint); |
| $request->set_query_string_array($query_string_array); |
| $request->set_body($body); |
| |
| $response = $this->request($request); |
| |
| return $response; |
| } |
| |
| /** |
| * Performs an HTTP PUT operation |
| * |
| * @param string $endpoint |
| * @param array $query_string_array |
| * @param array $body |
| * @return Response |
| */ |
| public function put($endpoint, $query_string_array, $body) { |
| |
| $request = new Request(); |
| $request->set_method('PUT'); |
| $request->set_endpoint($endpoint); |
| $request->set_query_string_array($query_string_array); |
| $request->set_body($body); |
| |
| $response = $this->request($request); |
| |
| return $response; |
| } |
| |
| /** |
| * Performs an HTTP DELETE operation |
| * |
| * @param string $endpoint |
| * @param array $query_string_array |
| * @return Response |
| */ |
| public function delete($endpoint, $query_string_array) { |
| $request = new Request(); |
| $request->set_method('DELETE'); |
| $request->set_endpoint($endpoint); |
| $request->set_query_string_array($query_string_array); |
| |
| $response = $this->request($request); |
| |
| return $response; |
| } |
| |
| /** |
| * Creates an entity. If no error occurred, the entity may be accessed in the |
| * returned object's ->parsed_objects['entity'] member. |
| * |
| * @param array $entity_data |
| * @return \Apache\Usergrid\Entity |
| */ |
| public function create_entity($entity_data) { |
| $entity = new Entity($this, $entity_data); |
| $response = $entity->fetch(); |
| |
| $ok_to_save = ( |
| ($response->get_error() && ('service_resource_not_found' == $response->get_error_code() || 'no_name_specified' == $response->get_error_code() || 'null_pointer' == $response->get_error_code() )) |
| || |
| (!$response->get_error() && array_key_exists('getOnExist', $entity_data) && $entity_data['getOnExist']) |
| ); |
| |
| if ($ok_to_save) { |
| $entity->set($entity_data); |
| $response = $entity->save(); |
| if ($response->get_error()) { |
| $this->write_log('Could not create entity.'); |
| return FALSE; |
| } |
| } |
| elseif ($response->get_error() || array_key_exists('error', $response->get_data())) { |
| return FALSE; |
| } |
| return $entity; |
| } |
| |
| /** |
| * Fetches and returns an entity. |
| * |
| * @param $entity_data |
| * @return \Apache\Usergrid\Entity|bool |
| */ |
| public function get_entity($entity_data) { |
| $entity = new Entity($this, $entity_data); |
| $response = $entity->fetch(); |
| if ($response->get_error()) { |
| $this->write_log($response->get_error_message()); |
| return FALSE; |
| } |
| return $entity; |
| } |
| |
| /** |
| * Fetches and returns a collection. If the collection does not yet exist, |
| * it is created. |
| * |
| * @param string $type |
| * @param array $qs |
| * @return \Apache\Usergrid\Collection |
| */ |
| public function get_collection($type, $qs = array()) { |
| $collection = new Collection($this, $type, $qs); |
| return $collection; |
| } |
| |
| /** |
| * Creates and returns a user-activity entity. Returns FALSE if such an |
| * entity could not be created. |
| * |
| * @param string $user_identifier |
| * @param array $user_data |
| * @return \Apache\Usergrid\Entity|bool |
| */ |
| public function create_user_activity($user_identifier, $user_data) { |
| $user_data['type'] = "users/$user_identifier/activities"; |
| $entity = new Entity($this, $user_data); |
| $response = $entity->save(); |
| return ($response->get_error() ? FALSE : $entity); |
| } |
| |
| /** |
| * Attempts a login. If successful, sets the OAuth token to be used for |
| * subsequent calls, and returns a User entity. If unsuccessful, returns |
| * FALSE. |
| * |
| * @param string $username |
| * @param string $password |
| * @return \Apache\Usergrid\Entity|bool |
| */ |
| public function login($username, $password) { |
| $body = array( |
| 'username' => $username, |
| 'password' => $password, |
| 'grant_type' => 'password' |
| ); |
| $response = $this->POST('token', array(), $body); |
| if ($response->get_error()) { |
| $user = NULL; |
| $error = 'Error trying to log user in.'; |
| $this->write_log($error); |
| if (!$response->get_error()) { |
| $response->set_error(TRUE); |
| $response->set_error_message($error); |
| $response->set_error_code($error); |
| } |
| } |
| else { |
| $response_data = $response->get_data(); |
| $user = new Entity($this, $response_data['user']); |
| $this->set_oauth_token($response_data['access_token']); |
| } |
| return ($user && !$response->get_error() ? $user : FALSE); |
| } |
| |
| /** |
| * Not yet implemented. Logs in via Facebook. |
| * |
| * @param $fb_token |
| */ |
| public function login_facebook($fb_token) { |
| // TODO |
| } |
| |
| /** |
| * A public facing helper method for signing up users |
| * |
| * @params string $username |
| * @params string $password |
| * @params string $email |
| * @params string $name |
| * @return \Apache\Usergrid\Entity |
| */ |
| public function signup($username, $password, $email, $name) { |
| $data = array( |
| 'type' => 'users', |
| 'username' => $username, |
| 'password' => $password, |
| 'email' => $email, |
| 'name' => $name |
| ); |
| return $this->create_entity($data); |
| } |
| |
| /** |
| * Returns current user as an entity. If no user is logged in, |
| * returns FALSE. |
| * |
| * @return Entity|bool |
| */ |
| public function get_logged_in_user() { |
| $data = array('username' => 'me', 'type' => 'users'); |
| return $this->get_entity($data); |
| } |
| |
| /** |
| * Determines if a user is logged in. |
| * |
| * @return bool |
| */ |
| public function is_logged_in() { |
| return !empty($this->oauth_token); |
| } |
| |
| /** |
| * Logs current user out. |
| * @todo: Invoke logout callback. |
| */ |
| public function log_out() { |
| $this->oauth_token = NULL; |
| } |
| |
| /** |
| * Determines if a string is a valid UUID. Note that this function will |
| * return FALSE if the UUID is wrapped in curly-braces, Microsoft-style. |
| * |
| * @param $uuid |
| * @return bool |
| */ |
| public static function is_uuid($uuid) { |
| static $regex = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i'; |
| if (empty($uuid)) { |
| return FALSE; |
| } |
| return (bool) preg_match($regex, $uuid); |
| } |
| |
| // TODO: Document the following methods |
| |
| public function createNewNotifierApple($name, $environment, $p12Certificate_path) { |
| |
| $endpoint = "notifiers"; |
| $data = array( |
| "name" => $name, |
| "environment" => $environment, |
| "p12Certificate" => $p12Certificate_path, |
| "provider" => "apple" |
| ); |
| return $this->post($endpoint, array(), $data); |
| } |
| |
| public function createNewNotifierAndroid($name, $apiKey) { |
| $endpoint = "notifiers"; |
| $data = array( |
| "name" => $name, |
| "apiKey" => $apiKey, |
| "provider" => "google" |
| ); |
| return $this->post($endpoint, array(), $data); |
| } |
| |
| public function createNotification() { |
| return new Notification(); |
| } |
| |
| public function scheduleNotification(Notification $notification) { |
| $notifier_name = $notification->get_notifier_name(); |
| $message = $notification->get_message(); |
| $delivery_time = $notification->get_delivery_time(); |
| $recipients_list = $notification->get_recipients_list(); |
| $recipient_type = $notification->get_recipient_type(); |
| |
| //we are trying to make this (where notifierName is the name of the notifier: |
| // { "payloads": { notifierName: "msg" }, "deliver":timestamp } |
| $body = array('payloads' => array($notifier_name => $message, 'deliver' => $delivery_time)); |
| |
| switch ($recipient_type) { |
| case GROUPS: |
| $type = 'groups/'; |
| break; |
| case USERS: |
| $type = 'users/'; |
| break; |
| case DEVICES: |
| $type = 'devices/'; |
| break; |
| default: |
| $type = 'devices/'; |
| $recipients_list = array(';ql='); |
| } |
| |
| //schedule notification |
| if (count($recipients_list) > 0) { |
| foreach ($recipients_list as $recipient) { |
| $endpoint = $type . $recipient . '/notifications'; |
| $result = $this->post($endpoint, array(), $body); |
| if ($result->get_error()) { |
| $notification->log_error($result->get_error()); |
| } |
| } |
| } |
| return $notification; |
| } |
| |
| /** |
| * Gets URL of Usergrid endpoint |
| * |
| * @return string |
| */ |
| public function getUrl() |
| { |
| return $this->url; |
| } |
| |
| /** |
| * Sets Usergrid endpoint URL |
| * |
| * @param string $url |
| * @return bool |
| * @throws UGException |
| */ |
| public function setUrl($url) |
| { |
| if (filter_var($url, FILTER_VALIDATE_URL) !== false) { |
| $this->url = $url; |
| return true; |
| } |
| else { |
| if ($this->use_exceptions) { |
| throw new UGException('Invalid URL'); |
| } |
| } |
| } |
| |
| } |
| |
| |
| |