You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2016/10/24 13:06:10 UTC

[25/83] [abbrv] usergrid git commit: Moving older SDKs to a difference location and updating main README to link to new SDK locations.

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/README.md
----------------------------------------------------------------------
diff --git a/sdks/other/php/README.md b/sdks/other/php/README.md
new file mode 100644
index 0000000..ec04cc9
--- /dev/null
+++ b/sdks/other/php/README.md
@@ -0,0 +1,388 @@
+##Quickstart
+Detailed instructions follow but if you just want a quick example of how to get started with this SDK, use this minimal PHP file to show you how to include & initialize the SDK, as well as how to read & write data from Usergrid with it.
+
+The file is located in this repository:
+
+	https://github.com/usergrid/usergrid/blob/master/sdks/php/examples/quick_start/index.php
+	
+
+```html
+<?php
+//include autoloader to make sure all files are included
+include '../autoloader.inc.php';
+
+//initialize the SDK
+$client = new Apache\Usergrid\Client('yourorgname','sandbox');
+
+//reading data
+$books = $client->get_collection('books');
+//do something with the data
+while ($books->has_next_entity()) {
+	$book = $books->get_next_entity();
+	$title = $book->get('title');
+	echo "Next Book's title is: " . $title . "<br>";
+}
+
+//writing data
+$data = array('title' => 'the old man and the sea', 'type' => 'books');
+$book = $books->add_entity($data);
+if ($book == FALSE) {
+	echo 'write failed';
+} else {
+	echo 'write succeeded';
+}
+?>
+```
+
+##Version
+
+Current Version: **0.0.1**
+
+See change log:
+
+<https://github.com/usergrid/usergrid/blob/master/sdks/php/changelog.md>
+
+**About this version:**
+
+This is the initial release of this SDK. It is functionally complete with some test coverage.  I plan to add additional test coverage in the near future as well as more examples.  
+
+This SDK is open source, and we welcome any contributions!  
+
+##Comments / Questions
+Please feel free to send comments or questions to the various
+community communication channels
+<http://usergrid.apache.org/community/>
+
+##Overview
+This open source SDK simplifies writing PHP applications that connect to App Services. The repo is located here:
+
+<https://github.com/usergrid/usergrid/tree/master/sdks/php>
+
+You can download the release artfacts via the Apache Mirroring newtwork.
+
+A wealth of Usergrid documentation can be found on the site
+
+<http://usergrid.apache.org/docs/>
+
+
+##About the samples
+This SDK comes with several samples to get you started.  They are located in this repo here:
+
+<https://github.com/usergrid/usergrid/tree/master/sdks/php/examples>
+
+The quick start shows how to get a basic file constructed.  The tests directory has the test code that is used to create this readme file.  **Note:** Ignore the //@han and //@solo comments - they are delimiters for the code parsing app we use to generate the readme.
+
+#Installing
+Download this repo, then add it to the root of your PHP project.
+
+#Getting started
+Once you have the the PHP SDK included in your directory tree, get started by including the SDK:
+
+	 include '../autoloader.inc.php';
+	 usergrid_autoload('Apache\\Usergrid\\Client');
+
+Then, start the client, which is the main object for connecting to the SDK.
+
+	 $client = new Apache\Usergrid\Client('1hotrod','sandbox');
+
+Once you have a client created, you will be able to use it to create Entities and Collections, the building blocks of the Usergrid API.
+
+##Entities
+This sdk provides an easy way to make new entities. Here is a simple example that shows how to create a new object of type "dogs":
+
+	 $data = array('name' => 'Dino', 'type' => 'dog');
+	 $dog = $client->create_entity($data);
+	 if ($dog) {
+	 	//once you have your entity, use the get() method to retrieve properties
+	 	$name = $dog->get('name');
+	 } else {
+	 	//there was an error creating / retrieving the entity
+	 }
+	
+**Note:** The above method will automatically get the entity if it already exists on the server.  
+
+If you only want to **get** an entity from the server: 
+
+	 $data = array('name' => 'Dino', 'type' => 'dog');
+	 $dog = $client->get_entity($data);
+	 if ($dog) {
+	 	$name = $dog->get('name');
+	 } else {
+	 	//entity doesn't exist on the server
+	 }
+	
+**Note:** The above method will return **false** if the entity does not exist, and will **not** automatically create a new entity.
+
+
+You can also refresh the object from the database if needed (in case the data has been updated by a different client or device), by calling the fetch() method:
+
+	 $dog->fetch();
+
+To set properties on the entity, use the set() method:
+
+	 $dog->set('master', 'Fred');
+	 $dog->set('breed', 'dinosaur');
+	 $dog->set('color', 'purple');
+
+These properties are now set locally, but make sure you call the save() method on the entity to save them back to the database!
+
+	 $result = $dog->save();
+	 if (!$result->get_error()) {
+	 	//all is well
+	 } else {
+	 	//there was a problem!
+	 }
+
+To get a single property from the entity, use the get method:
+
+
+
+To remove the entity from the database:
+
+	 $result = $dog->destroy();
+
+
+##The Collection object
+The Collection object models Collections in the database.  Once you start programming your app, you will likely find that this is the most useful method of interacting with the database.  
+
+**Note:** Collections are automatically created when entities are added.  So you can use the get_collection method even if there are no entities in your collection yet!
+
+Getting a collection will automatically populate the object with entities from the collection. The following example shows how to create a Collection object, then how to use entities once the Collection has been populated with entities from the server:
+
+	 $dogs = $client->get_collection('dogs');
+
+
+You can also add a new entity of the same type to the collection:
+
+	 $data = array('name' => 'Dino', 'type' => 'dogs');
+	 $dino = $dogs->add_entity($data);
+
+**Note:** this will also add the entity to the local collection object as well as creating it on the server
+
+
+##Collection iteration and paging
+The Collection object works in Pages of data.  This means that at any given time, the Collection object will have one page of data loaded.  You can iterate across all the entities in the current page of data by using the following pattern:
+
+	 while ($dogs->has_next_entity()) {
+	 	$dog = $dogs->get_next_entity();
+	 	//do something with dog
+	 	$name = $dog->get('name');
+	 }
+
+To iterate over the collection again, you must reset the entity pointer:
+
+	 $dogs->reset_entity_pointer();
+	 while ($dogs->has_next_entity()) {
+	 	$dog = $dogs->get_next_entity();
+	 	//do something with dog
+	 	$name = $dog->get('name');
+	 }
+	
+To get the next page of data:
+
+	 $dogs->get_next_page();
+	 while ($dogs->has_next_entity()) {
+	 	$dog = $dogs->get_next_entity();
+	 	$name = $dog->get('name');
+	 }
+
+You can use the same pattern to get a previous page of data:
+
+	 $dogs->get_prev_page();
+	 while ($dogs->has_next_entity()) {
+	 	$dog = $dogs->get_next_entity();
+	 	$name = $dog->get('name');
+	 }
+
+To get all the subsequent pages of data from the server and iterate across them, use the following pattern:
+
+	 while ($dogs->get_next_page()) {
+	 	while ($dogs->has_next_entity()) {
+	 		$dog = $dogs->get_next_entity();
+	 		$name = $dog->get('name');
+	 	}
+	 }
+
+
+By default, the database will return 10 entities per page.  You can change that amount by setting a limit:
+
+	 $data = array('ql'=>'select * where created > 0', 'limit'=>'40');
+	 $dogs = $client->get_collection('dogs', $data);
+
+Several other convenience methods exist to make working with pages of data easier:
+
+	* get_first_entity - gets the first entity of a page
+	* get_last_entity - gets the last entity of a page
+	* reset_entity_pointer - sets the internal pointer back to the first element of the page
+	* get_entity_by_uuid - returns the entity if it is in the current page
+
+
+
+##Modeling users with the Entity object
+There is no specific User object in this SDK.  Instead, you simply need to use the Entity object, specifying a type of "users".  Here is an example:
+
+	 $marty =  $client->signup('marty', 'mysecurepassword','marty@timetravel.com', 'Marty McFly');
+	 if ($marty) {
+	 	//user created
+	 } else {
+	 	//there was an error
+	 }
+
+If the user is modified, just call save on the user again:
+
+	 $marty->set('state', 'California');
+	 $marty->set('girlfriend', 'Jennifer');
+	 $result = $marty->save();
+
+To refresh the user's information in the database:
+
+
+
+To change the user's password:
+	
+	 $marty->set('oldpassword', 'mysecurepassword');
+	 $marty->set('newpassword', 'mynewsecurepassword');
+	 $marty->save();
+
+To log a user in:
+
+	 if ($client->login('marty', 'mysecurepassword')) {
+	 	//the login call will return an OAuth token, which is saved
+	 	//in the client. Any calls made now will use the token.
+	 	//once a user has logged in, their user object is stored
+	 	//in the client and you can access it this way:
+	 	$token = $client->get_oauth_token();
+	 } else {
+	 }
+
+To log a user out:
+
+	 $client->log_out();
+	 if ($client->is_logged_in()) {
+	 	//error - user is still logged in
+	 } else {
+	 	//success - user was logged out
+	 }
+
+If you no longer need the object, call the destroy() method and the object will be removed from database:
+
+	 $result = $marty->destroy();
+	 if ($result->get_error()) {
+	 	//there was an error deleting the user
+	 } else {
+	 	//success - user was deleted
+	 }
+	
+
+##Making generic calls
+If you find that you need to make calls to the API that fall outside of the scope of the Entity and Collection objects, you can use the following methods to make any of the REST calls (GET, POST, PUT, DELETE).
+
+GET:
+
+	 $endpoint = 'users/fred';
+	 $query_string = array();
+	 $result = $client->get($endpoint, $query_string);
+	 if ($result->get_error()){
+	 	//error - there was a problem getting the entity
+	 } else {
+	 	//success - entity retrieved
+	 }
+
+POST:
+
+	 $endpoint = 'users';
+	 $query_string = array();
+	 $body = array('username'=>'fred');
+	 $result = $client->post($endpoint, $query_string, $body);
+	 if ($result->get_error()){
+	 	//error - there was a problem creating the entity
+	 } else {
+	 	//success - entity created
+	 }
+	
+PUT:
+
+	 $endpoint = 'users/fred';
+	 $query_string = array();
+	 $body = array('dog'=>'dino');
+	 $result = $client->put($endpoint, $query_string, $body);
+	 if ($result->get_error()){
+	 	//error - there was a problem updating the entity
+	 } else {
+	 	//success - entity updated
+	 }
+	
+DELETE:
+
+	 $endpoint = 'users/idontexist';
+	 $query_string = array();
+	 try {
+	 	$result =  $client->delete($endpoint, $query_string);
+	 } catch (Exception $e) {
+	 	//entity didn't exist on the server, so UG_404_NotFound is thrown
+	 }
+	 
+	 ?>
+	 
+	 ?>
+	 $endpoint = 'users/fred';
+	 $query_string = array();
+	 $result =  $client->delete($endpoint, $query_string);
+	 if ($result->get_error()){
+	 	//error - there was a problem deleting the entity
+	 } else {
+	 	//success - entity deleted
+	 }
+
+
+You can make any call to the API using the format above.  However, in practice using the higher level Entity and Collection objects will make life easier as they take care of much of the heavy lifting.
+
+#Authentication
+By default, every App Services account comes with an app called "Sandbox".  While using the Sandbox app for testing, you will not need to worry about authentication as it has all permissions enabled for unauthenticated users.  However, when you are ready to create your own secured app, there are two authentication methods you will use: app user credentials, where your users sign in to get a token, and system level credentials (a client id / client secret combo).
+
+#App user credentials
+To get an Oauth token, users will sign into their accounts with a username and password.  See the "Modeling users with the Entity object" section above for details on how to use the login method.  Once logged in, the user's Oauth token is stored and used for all subsequent calls.
+
+The SDK uses app level credentials by default.
+
+
+#System level credentials (client id / client secret combo)
+If your app needs an elevated level of permissions, then you can use the client id / client secret combo. This is useful if you need to update permissions, do user manipulation, etc. Since the PHP sdk is running server-side, it is safe for you to use the client id / client secret combo on your API calls.  Keep in mind that if you are making API calls on behalf of your application user, say to get resources only they should have access to, such as a feed, it may be more appropriate to use the app user credentials described above.
+
+To use make calls using system level credentials, simply set the auth type and specify your client id and client secret:
+
+	 $testname = 'Use Client Auth type - ';
+	 $client->set_auth_type(AUTH_CLIENT_ID);
+	 $client->set_client_id('YXA6Us6Rg0b0EeKuRALoGsWhew');
+	 $client->set_client_secret('YXA6OYsTy6ENwwnbvjtvsbLpjw5mF40');
+
+
+## Contributing
+We welcome your enhancements!
+
+1. Fork it
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Added some feature'`)
+4. Push your changes to the upstream branch (`git push origin my-new-feature`)
+5. Create new Pull Request (make sure you describe what you did and why your mod is needed)
+
+##More information
+For more information on Usergrid, visit <http://usergrid.apache.org>.
+
+## Copyright
+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.
+
+

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/changelog.md
----------------------------------------------------------------------
diff --git a/sdks/other/php/changelog.md b/sdks/other/php/changelog.md
new file mode 100755
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/autoloader.inc.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/autoloader.inc.php b/sdks/other/php/examples/autoloader.inc.php
new file mode 100755
index 0000000..39f8bc5
--- /dev/null
+++ b/sdks/other/php/examples/autoloader.inc.php
@@ -0,0 +1,36 @@
+#!/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.
+ */
+
+function usergrid_autoload($class) {
+
+
+  if (strpos($class, '\\') !== FALSE) {
+    $path_parts = explode('\\', $class);
+    if ($path_parts[0] == 'Apache') {
+      $lib_path = realpath(dirname(__FILE__) . '/../lib/vendor');
+      $class_path = $lib_path . '/' . join('/', $path_parts) . '.php';
+      if (file_exists($class_path)) {
+        require_once($class_path);
+      }
+    }
+  }
+}
+
+spl_autoload_register('usergrid_autoload');

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/quick_start/index.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/quick_start/index.php b/sdks/other/php/examples/quick_start/index.php
new file mode 100755
index 0000000..95dd861
--- /dev/null
+++ b/sdks/other/php/examples/quick_start/index.php
@@ -0,0 +1,45 @@
+#!/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.
+ */
+
+//include autoloader to make sure all files are included
+include '../autoloader.inc.php';
+usergrid_autoload('Apache\\Usergrid\\Client');
+
+//initialize the SDK
+$client = new Apache\Usergrid\Client('yourorgname','sandbox');
+
+//reading data
+$books = $client->get_collection('books');
+//do something with the data
+while ($books->has_next_entity()) {
+	$book = $books->get_next_entity();
+	$title = $book->get('title');
+	echo "Next Book's title is: " . $title . "<br>";
+}
+
+//writing data
+$data = array('title' => 'the old man and the sea', 'type' => 'books');
+$book = $books->add_entity($data);
+if ($book == FALSE) {
+	echo 'write failed';
+} else {
+	echo 'write succeeded';
+}
+?>

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/tests/Tester.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/tests/Tester.php b/sdks/other/php/examples/tests/Tester.php
new file mode 100755
index 0000000..13f7e22
--- /dev/null
+++ b/sdks/other/php/examples/tests/Tester.php
@@ -0,0 +1,80 @@
+#!/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
+ * Tester - a simple class for logging during a test run
+ *
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 09-Mar-2013
+ */
+
+class Tester {
+
+  public $error_count = 0;
+	public $success_count = 0;
+
+	//logging
+	public $log_success = true;
+	public $log_error = true;
+	public $log_notice = true;
+
+  public function __construct() {
+
+  }
+
+	//logging functions
+	public function success($message){
+		$this->success_count++;
+		if ($this->log_success) {
+			echo('SUCCESS: ' . $message . '<br>');
+		}
+	}
+
+	public function error($message){
+		$this->error_count++;
+		if ($this->log_error) {
+			echo('ERROR: ' . $message . '<br>');
+		}
+	}
+
+	public function notice($message){
+		if ($this->log_notice) {
+			echo('NOTICE: ' . $message . '<br>');
+		}
+	}
+
+	function printSummary(){
+		echo '<br><br><br>';
+		echo '----------       Summary       ----------- <br>';
+		if ($this->error_count > 0) {
+			echo 'ERROR: BUILD NOT STABLE <br>';
+		} else {
+			echo 'OK: BUILD STABLE <br>';
+		}
+		echo 'Error Count: ' . $this->error_count . ' <br>';
+		echo 'Success Count: ' . $this->success_count . ' <br>';
+		echo '---------- Thanks for playing! ----------- <br>';
+	}
+
+}
+
+
+?>

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/tests/client_auth.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/tests/client_auth.php b/sdks/other/php/examples/tests/client_auth.php
new file mode 100755
index 0000000..17c5b73
--- /dev/null
+++ b/sdks/other/php/examples/tests/client_auth.php
@@ -0,0 +1,101 @@
+#!/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
+ * Client Auth tests
+ *
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 01-Apr-2013
+ */
+
+//--------------------------------------------------------------
+// Client Auth
+//--------------------------------------------------------------
+//@han {client-auth}
+$testname = 'Use Client Auth type - ';
+$client->set_auth_type(AUTH_CLIENT_ID);
+$client->set_client_id('YXA6Us6Rg0b0EeKuRALoGsWhew');
+$client->set_client_secret('YXA6OYsTy6ENwwnbvjtvsbLpjw5mF40');
+//@solo
+
+//--------------------------------------------------------------
+// Generic Client Auth Tests
+//--------------------------------------------------------------
+$testname = 'DELETE users/fred';
+
+$endpoint = 'users/fred';
+$query_string = array();
+$result =  $client->delete($endpoint, $query_string);
+$data = $result->get_data();
+if ($data['action'] != 'delete'){
+  //error - there was a problem deleting the entity
+  $tester->error($testname);
+} else {
+  //success - entity deleted
+  $tester->success($testname);
+}
+
+if (!$result->get_error()) {
+  $tester->success($testname);
+} else {
+  $tester->error($testname);
+}
+
+$testname = 'POST users / fred';
+$endpoint = 'users';
+$query_string = array();
+$body = array('username'=>'fred');
+$result = $client->post($endpoint, $query_string, $body);
+$data = $result->get_data();
+if (isset($data['entities'][0]['username']) && $data['entities'][0]['username'] == 'fred'){
+  $tester->success($testname);
+} else {
+  $tester->error($testname);
+}
+
+
+$testname = 'PUT users/fred';
+$endpoint = 'users/fred';
+$query_string = array();
+$body = array('dog'=>'dino');
+$result = $client->put($endpoint, $query_string, $body);
+$data = $result->get_data();
+if (isset($data['entities'][0]['dog']) && $data['entities'][0]['dog'] == 'dino'){
+  $tester->success($testname);
+} else {
+  $tester->error($testname);
+}
+
+$testname = 'GET users/fred';
+$endpoint = 'users/fred';
+$query_string = array();
+$result = $client->get($endpoint, $query_string);
+$data = $result->get_data();
+if (isset($data['path']) && $data['path'] == '/users'){
+  $tester->success($testname);
+} else {
+  $tester->error($testname);
+}
+
+
+$client->set_auth_type(AUTH_APP_USER);
+$client->set_client_id(null);
+$client->set_client_secret(null);
+?>

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/tests/collection.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/tests/collection.php b/sdks/other/php/examples/tests/collection.php
new file mode 100755
index 0000000..1c49911
--- /dev/null
+++ b/sdks/other/php/examples/tests/collection.php
@@ -0,0 +1,154 @@
+#!/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
+ * Collection tests
+ *
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 09-Mar-2013
+ */
+
+//--------------------------------------------------------------
+// Collection tests
+//--------------------------------------------------------------
+$testname = 'Create test data - ';
+for($i=0;$i<30;$i++) {
+	$testname = 'Create dog_'.$i;
+	$data = array('name' => 'dog_'.$i, 'type' => 'dogs');
+	$entity = $client->create_entity($data);
+	if ($entity->get('name') == 'dog_'.$i && $entity->get('type') == 'dog'){
+	  $tester->success($testname);
+	} else {
+		$tester->error($testname);
+	}
+}
+
+$testname = 'Get dogs collection';
+//@han {get-collection}
+$dogs = $client->get_collection('dogs');
+//@solo
+//echo '<pre>'.$dogs->get_json().'</pre><br>';
+if ($dogs->get_type() == 'dogs') {
+  $tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+//@han {iterate-collection}
+while ($dogs->has_next_entity()) {
+	$dog = $dogs->get_next_entity();
+	//do something with dog
+	$name = $dog->get('name');
+}
+//@solo
+
+//@han {re-iterate-collection}
+$dogs->reset_entity_pointer();
+while ($dogs->has_next_entity()) {
+	$dog = $dogs->get_next_entity();
+	//do something with dog
+	$name = $dog->get('name');
+}
+//@solo
+
+//@han {get-next-page-collection}
+$dogs->get_next_page();
+while ($dogs->has_next_entity()) {
+	$dog = $dogs->get_next_entity();
+	$name = $dog->get('name');
+}
+//@solo
+
+//@han {get-prev-page-collection}
+$dogs->get_prev_page();
+while ($dogs->has_next_entity()) {
+	$dog = $dogs->get_next_entity();
+	$name = $dog->get('name');
+}
+//@solo
+
+
+$testname = 'Get next page of dogs collection';
+$testname2 = 'Verify next page of dogs collection - ';
+//@han {iterate-over-entire-collection}
+while ($dogs->get_next_page()) {
+	$tester->success($testname);
+	while ($dogs->has_next_entity()) {
+		$dog = $dogs->get_next_entity();
+		$name = $dog->get('name');
+		//@solo
+		if ($entity->get('type') == 'dog'){
+			$tester->success($testname2.$name);
+		} else {
+			$tester->error($testname2.$name);
+		}
+		//@han {iterate-over-entire-collection2}
+	}
+}
+//@solo
+
+//@han {get-previous-page-collection}
+while ($dogs->get_prev_page()) {
+	$testname = 'Get next page of dogs collection';
+	$tester->success($testname);
+	$testname = 'Verify next page of dogs collection - ';
+	while ($dogs->has_next_entity()) {
+		$dog = $dogs->get_next_entity();
+		$name = $dog->get('name');
+		if ($entity->get('type') == 'dog'){
+			$tester->success($testname.$name);
+		} else {
+			$tester->error($testname.$name);
+		}
+	}
+}
+
+$testname = 'Add new dog to collection';
+//@han {add-entity-to-collection}
+$data = array('name' => 'Dino', 'type' => 'dogs');
+$dino = $dogs->add_entity($data);
+//@solo
+if ($dino->get('name') == 'Dino') {
+	$tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+//@han {set-limit-collection}
+$data = array('ql'=>'select * where created > 0', 'limit'=>'40');
+$dogs = $client->get_collection('dogs', $data);
+//@solo
+
+$testname = 'Clear dogs sample data - ';
+$dogs->reset_entity_pointer();
+while ($dogs->has_next_entity()) {
+	$dog = $dogs->get_next_entity();
+	$name = $dog->get('name');
+	$result = $dog->destroy();
+	$response_data = $result->get_data();
+	if (isset($response_data['action']) && $response_data['action'] == 'delete') {
+		$tester->success($testname.$name);
+	} else {
+		$tester->error($testname.$name);
+	}
+}
+
+?>

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/tests/entity.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/tests/entity.php b/sdks/other/php/examples/tests/entity.php
new file mode 100755
index 0000000..1f564f2
--- /dev/null
+++ b/sdks/other/php/examples/tests/entity.php
@@ -0,0 +1,114 @@
+#!/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
+ * Entity tests
+ *
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 09-Mar-2013
+ */
+
+//--------------------------------------------------------------
+// Entity tests
+//--------------------------------------------------------------
+$testname = 'Create Entity';
+//@han {create-entity}
+$data = array('name' => 'Dino', 'type' => 'dog');
+$dog = $client->create_entity($data);
+if ($dog) {
+	//once you have your entity, use the get() method to retrieve properties
+	$name = $dog->get('name');
+} else {
+	//there was an error creating / retrieving the entity
+}
+//@solo
+if ($dog->get('name') == 'Dino' && $dog->get('type') == 'dog'){
+  $tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+$testname = 'Get Entity';
+//@han {get-entity}
+$data = array('name' => 'Dino', 'type' => 'dog');
+$dog = $client->get_entity($data);
+if ($dog) {
+	$name = $dog->get('name');
+} else {
+	//entity doesn't exist on the server
+}
+//@solo
+if ($name == 'Dino' && $dog->get('type') == 'dog'){
+  $tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+//@han {refresh-entity}
+$dog->fetch();
+//@solo
+
+
+$testname = 'Set key on entity';
+//@han {set-entity}
+$dog->set('master', 'Fred');
+$dog->set('breed', 'dinosaur');
+$dog->set('color', 'purple');
+//@solo
+if ($dog->get('color') == 'purple') {
+	$tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+$testname = 'Save key on entity';
+//@han {save-entity}
+$result = $dog->save();
+if (!$result->get_error()) {
+	//all is well
+	$tester->success($testname);
+} else {
+	//there was a problem!
+	$tester->error($testname);
+}
+//@solo
+
+$testname = 'Refresh entity and check key';
+$dog->set('color', 'red'); //set the value
+$result = $dog->fetch(); //refresh to overwrite
+if ($dog->get('color') == 'purple') {
+	$tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+$testname = 'Delete entity';
+//@han {destroy-entity}
+$result = $dog->destroy();
+//@solo
+$data = $result->get_data();
+if (isset($data['action']) && $data['action'] == 'delete') {
+	$tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+?>

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/tests/exceptions.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/tests/exceptions.php b/sdks/other/php/examples/tests/exceptions.php
new file mode 100755
index 0000000..45d44c0
--- /dev/null
+++ b/sdks/other/php/examples/tests/exceptions.php
@@ -0,0 +1,45 @@
+#!/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
+ * exceptions tests
+ *
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 09-Mar-2013
+ */
+
+//--------------------------------------------------------------
+// Exception Tests - NOT DONE YET!!!
+//--------------------------------------------------------------
+$testname = 'DELETE users/fred';
+//@han {generic-delete}
+$endpoint = 'users/idontexist';
+$query_string = array();
+try {
+	$result =  $client->delete($endpoint, $query_string);
+} catch (Exception $e) {
+	//entity didn't exist on the server, so UG_404_NotFound is thrown
+	$tester->success($testname);
+}
+
+?>
+
+?>

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/tests/generic.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/tests/generic.php b/sdks/other/php/examples/tests/generic.php
new file mode 100755
index 0000000..11ba083
--- /dev/null
+++ b/sdks/other/php/examples/tests/generic.php
@@ -0,0 +1,122 @@
+#!/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
+ * Generic tests
+ *
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 09-Mar-2013
+ */
+
+//--------------------------------------------------------------
+// Generic Tests
+//--------------------------------------------------------------
+$testname = 'DELETE users/fred';
+//@han {generic-delete}
+$endpoint = 'users/fred';
+$query_string = array();
+$result =  $client->delete($endpoint, $query_string);
+if ($result->get_error()){
+	//error - there was a problem deleting the entity
+} else {
+	//success - entity deleted
+}
+//@solo
+$data = $result->get_data();
+if ($data['action'] != 'delete'){
+	//error - there was a problem deleting the entity
+  $tester->error($testname);
+} else {
+	//success - entity deleted
+	$tester->success($testname);
+}
+
+if (!$result->get_error()) {
+  $tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+$testname = 'POST users / fred';
+//@han {generic-post}
+$endpoint = 'users';
+$query_string = array();
+$body = array('username'=>'fred');
+$result = $client->post($endpoint, $query_string, $body);
+if ($result->get_error()){
+	//error - there was a problem creating the entity
+  $tester->error($testname);
+} else {
+	//success - entity created
+	$tester->success($testname);
+}
+//@solo
+$data = $result->get_data();
+$json = $result->get_json();
+//echo '<pre>'.$json.'</pre><br>';
+if (isset($data['entities'][0]['username']) && $data['entities'][0]['username'] == 'fred'){
+  $tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+
+$testname = 'PUT users/fred';
+//@han {generic-put}
+$endpoint = 'users/fred';
+$query_string = array();
+$body = array('dog'=>'dino');
+$result = $client->put($endpoint, $query_string, $body);
+if ($result->get_error()){
+	//error - there was a problem updating the entity
+  $tester->error($testname);
+} else {
+	//success - entity updated
+	$tester->success($testname);
+}
+//@solo
+$data = $result->get_data();
+if (isset($data['entities'][0]['dog']) && $data['entities'][0]['dog'] == 'dino'){
+  $tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+$testname = 'GET users/fred';
+//@han {generic-get}
+$endpoint = 'users/fred';
+$query_string = array();
+$result = $client->get($endpoint, $query_string);
+if ($result->get_error()){
+	//error - there was a problem getting the entity
+  $tester->error($testname);
+} else {
+	//success - entity retrieved
+	$tester->success($testname);
+}
+//@solo
+$data = $result->get_data();
+if (isset($data['path']) && $data['path'] == '/users'){
+  $tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+?>

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/tests/push.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/tests/push.php b/sdks/other/php/examples/tests/push.php
new file mode 100755
index 0000000..5c7e1e0
--- /dev/null
+++ b/sdks/other/php/examples/tests/push.php
@@ -0,0 +1,71 @@
+#!/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
+ * Push Notification tests
+ *
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 09-Mar-2013
+ */
+
+//--------------------------------------------------------------
+// Push tests
+//--------------------------------------------------------------
+$testname = 'Create apple notifier';
+$apple_name = 'name_'.time();
+$environment = 'development';
+$p12Certificate_path = "@pushtest_dev.p12";
+$result =  $client->createNewNotifierApple($apple_name, $environment, $p12Certificate_path);
+echo '<pre>'.$result->get_json().'</pre><br>';
+if ($result->get_error()){
+  $tester->error($testname);
+} else {
+	$tester->success($testname);
+}
+
+$testname = 'Create google notifier';
+$google_name = 'name_'.time();
+$apiKey = 'AIzaSyCIH_7WC0mOqBGMOXyQnFgrBpOePgHvQJM';
+$result =  $client->createNewNotifierAndroid($google_name, $apiKey);
+echo '<pre>'.$result->get_json().'</pre><br>';
+if ($result->get_error()){
+  $tester->error($testname);
+} else {
+	$tester->success($testname);
+}
+
+$testname = 'Create notification';
+$notification = $client->createNotification();
+$notification->set_notifier_name($apple_name);
+$notification->set_message("Test Message");
+$notification->set_delivery_time(time());
+$notification->set_recipients_list(array(0=>'fred'));
+$notification->set_recipient_type(USERS);
+
+$result = $client->scheduleNotification($notification);
+echo '<pre>'.$result->get_json().'</pre><br>';
+if ($result->get_error()){
+  $tester->error($testname);
+} else {
+	$tester->success($testname);
+}
+
+?>

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/tests/pushtest_dev.p12
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/tests/pushtest_dev.p12 b/sdks/other/php/examples/tests/pushtest_dev.p12
new file mode 100644
index 0000000..b4373a2
Binary files /dev/null and b/sdks/other/php/examples/tests/pushtest_dev.p12 differ

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/tests/test.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/tests/test.php b/sdks/other/php/examples/tests/test.php
new file mode 100755
index 0000000..e0578d2
--- /dev/null
+++ b/sdks/other/php/examples/tests/test.php
@@ -0,0 +1,56 @@
+#!/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
+ * main entry point for running tests
+ *
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 09-Mar-2013
+ */
+
+//@han {include-sdk}
+include '../autoloader.inc.php';
+usergrid_autoload('Apache\\Usergrid\\Client');
+//@solo
+
+//@han {create-new-client}
+$client = new Apache\Usergrid\Client('1hotrod','sandbox');
+//@solo
+
+include 'Tester.php';
+
+$tester = new Tester();
+
+include 'generic.php';
+include 'entity.php';
+include 'collection.php';
+include 'user.php';
+include 'client_auth.php';
+include 'push.php';
+
+
+
+//--------------------------------------------------------------
+// Summary
+//--------------------------------------------------------------
+$tester->printSummary();
+
+?>

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/examples/tests/user.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/examples/tests/user.php b/sdks/other/php/examples/tests/user.php
new file mode 100755
index 0000000..545ba7a
--- /dev/null
+++ b/sdks/other/php/examples/tests/user.php
@@ -0,0 +1,137 @@
+#!/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
+ * User tests
+ *
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 09-Mar-2013
+ */
+
+//--------------------------------------------------------------
+// User tests
+//--------------------------------------------------------------
+$testname = 'DELETE users/marty';
+$endpoint = 'users/marty';
+$query_string = array();
+$result =  $client->delete($endpoint, $query_string);
+$result_data = $result->get_data();
+if (isset($result_data)){
+  $tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+$testname = 'Signup user';
+//@han {create-user}
+$marty =  $client->signup('marty', 'mysecurepassword','marty@timetravel.com', 'Marty McFly');
+if ($marty) {
+	//user created
+} else {
+	//there was an error
+}
+//@solo
+if ($marty->get('username') == 'marty'){
+  $tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+$testname = 'Update user';
+//@han {update-user}
+$marty->set('state', 'California');
+$marty->set('girlfriend', 'Jennifer');
+$result = $marty->save();
+//@solo
+if ($result->get_error()) {
+	$tester->error($testname);
+} else {
+	$tester->success($testname);
+}
+
+$testname = 'Log user in';
+//@han {log-user-in}
+if ($client->login('marty', 'mysecurepassword')) {
+	//the login call will return an OAuth token, which is saved
+	//in the client. Any calls made now will use the token.
+	//once a user has logged in, their user object is stored
+	//in the client and you can access it this way:
+	$token = $client->get_oauth_token();
+	$tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+//@solo
+
+$testname = 'Get logged in user';
+$marty = $client->get_logged_in_user();
+if (isset($marty) && $marty->get('username') == 'marty') {
+	$tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+$testname = 'Update user password';
+//@han {update-user-password}
+$marty->set('oldpassword', 'mysecurepassword');
+$marty->set('newpassword', 'mynewsecurepassword');
+$marty->save();
+//@solo
+$result_data = $result->get_data();
+if (isset($result_data['action']) && $result_data['action'] == 'put') {
+	$tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+$testname = 'Log user out';
+//@han {log-user-out}
+$client->log_out();
+if ($client->is_logged_in()) {
+	//error - user is still logged in
+	$tester->error($testname);
+} else {
+	//success - user was logged out
+	$tester->success($testname);
+}
+//@solo
+
+$testname = 'Log user in with new password';
+if ($client->login('marty', 'mynewsecurepassword')){
+	$tester->success($testname);
+} else {
+	$tester->error($testname);
+}
+
+$testname = 'Delete user';
+//@han {destroy-user}
+$result = $marty->destroy();
+if ($result->get_error()) {
+	//there was an error deleting the user
+	$tester->error($testname);
+} else {
+	//success - user was deleted
+	$tester->success($testname);
+}
+//@solo
+
+
+?>

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/lib/vendor/Apache/Usergrid/Client.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/lib/vendor/Apache/Usergrid/Client.php b/sdks/other/php/lib/vendor/Apache/Usergrid/Client.php
new file mode 100755
index 0000000..cd0120d
--- /dev/null
+++ b/sdks/other/php/lib/vendor/Apache/Usergrid/Client.php
@@ -0,0 +1,813 @@
+#!/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 <dj...@apigee.com>
+ * @author Rod Simpson <ro...@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');
+            }
+        }
+    }
+
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/lib/vendor/Apache/Usergrid/Collection.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/lib/vendor/Apache/Usergrid/Collection.php b/sdks/other/php/lib/vendor/Apache/Usergrid/Collection.php
new file mode 100644
index 0000000..ee8a070
--- /dev/null
+++ b/sdks/other/php/lib/vendor/Apache/Usergrid/Collection.php
@@ -0,0 +1,313 @@
+#!/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
+ * Allows CRUD operations on Usergrid Collections.
+ *
+ * @author Daniel Johnson <dj...@apigee.com>
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 26-Apr-2013
+ */
+
+namespace Apache\Usergrid;
+require_once(dirname(__FILE__) . '/Exceptions.php');
+
+class Collection {
+
+  /**
+   * @var \Apache\Usergrid\Client
+   */
+  private $client;
+  /**
+   * @var string
+   */
+  private $type;
+  /**
+   * @var array
+   */
+  private $qs;
+  /**
+   * @var array
+   */
+  private $list;
+  /**
+   * @var int
+   */
+  private $iterator;
+  /**
+   * @var array
+   */
+  private $previous;
+  /**
+   * @var bool|int
+   */
+  private $next;
+  /**
+   * @var null|int
+   */
+  private $cursor;
+
+  /**
+   * @var string|string
+   */
+  private $json = '';
+
+  /**
+   * Object constructor.
+   *
+   * @param \Apache\Usergrid\Client $client
+   * @param string $type
+   * @param array $qs
+   */
+  public function __construct(Client $client, $type, $qs = array()) {
+    $this->client = $client;
+    $this->type = $type;
+    $this->qs = $qs;
+
+    $this->list = array();
+    $this->iterator = -1;
+
+    $this->previous = array();
+    $this->next = FALSE;
+    $this->cursor = NULL;
+
+    $this->fetch();
+  }
+
+  public function get_json() {
+    return $this->json;
+  }
+
+  public function set_json($json) {
+    $this->json = $json;
+  }
+
+  /**
+   * @return string
+   */
+  public function get_type() {
+    return $this->type;
+  }
+
+  /**
+   * @param string $type
+   */
+  public function set_type($type) {
+    $this->type = $type;
+  }
+
+  /**
+   * @return \Apache\Usergrid\Response
+   */
+  public function fetch() {
+    if ($this->cursor) {
+      $this->qs['cursor'] = $this->cursor;
+    }
+    elseif (array_key_exists('cursor', $this->qs)) {
+      unset($this->qs['cursor']);
+    }
+    $response = $this->client->get($this->type, $this->qs);
+    if ($response->get_error()) {
+      $this->client->write_log('Error getting collection.');
+    }
+    else {
+      $this->set_json($response->get_json());
+      $response_data = $response->get_data();
+      $cursor = (isset($response_data['cursor']) ? $response_data['cursor'] : NULL);
+      $this->save_cursor($cursor);
+      if (!empty($response_data['entities'])) {
+        $this->reset_entity_pointer();
+        $count = count($response_data['entities']);
+        $this->list = array();
+        for ($i = 0; $i < $count; $i++) {
+          $entity_data = $response_data['entities'][$i];
+          if (array_key_exists('uuid', $entity_data)) {
+            $entity = new Entity($this->client, $entity_data);
+            $entity->set('type', $this->type);
+
+            $this->list[] = $entity;
+          }
+        }
+      }
+    }
+    return $response;
+  }
+
+  /**
+   * @param array $entity_data
+   * @return \Apache\Usergrid\Entity
+   */
+  public function add_entity($entity_data) {
+    $entity = $this->client->create_entity($entity_data);
+    if ($entity) {
+      $this->list[] = $entity;
+    }
+    return $entity;
+  }
+
+  /**
+   * @param \Apache\Usergrid\Entity $entity
+   * @return \Apache\Usergrid\Response
+   */
+  public function destroy_entity(Entity $entity) {
+    $response = $entity->destroy();
+    if ($response->get_error()) {
+      $this->client->write_log('Could not destroy entity.');
+    }
+    else {
+      $response = $this->fetch();
+    }
+    return $response;
+  }
+
+  /**
+   * @param string $uuid
+   * @return \Apache\Usergrid\Response|bool
+   * @throws \Apache\Usergrid\UGException
+   */
+  public function get_entity_by_uuid($uuid) {
+    if (!Client::is_uuid($uuid)) {
+      if ($this->client->are_exceptions_enabled()) {
+        throw new UGException("Invalid UUID $uuid");
+      }
+      return FALSE;
+    }
+    $entity = new Entity($this->client, array('type' => $this->type, 'uuid' => $uuid));
+    return $entity->fetch();
+  }
+
+  /**
+   * @return \Apache\Usergrid\Entity|null
+   */
+  public function get_first_entity() {
+    return (count($this->list) > 0 ? $this->list[0] : NULL);
+  }
+
+  /**
+   * @return \Apache\Usergrid\Entity|null
+   */
+  public function get_last_entity() {
+    return (count($this->list) > 0 ? $this->list[count($this->list) - 1] : NULL);
+  }
+
+  /**
+   * @return bool
+   */
+  public function has_next_entity() {
+    $next = $this->iterator + 1;
+    return ($next >= 0 && $next < count($this->list));
+  }
+
+  /**
+   * @return bool
+   */
+  public function has_prev_entity() {
+    $prev = $this->iterator - 1;
+    return ($prev >= 0 && $prev < count($this->list));
+  }
+
+  /**
+   * @return \Apache\Usergrid\Entity|null
+   */
+  public function get_next_entity() {
+    if ($this->has_next_entity()) {
+      $this->iterator++;
+      return $this->list[$this->iterator];
+    }
+    return NULL;
+  }
+
+  /**
+   * @return \Apache\Usergrid\Entity|null
+   */
+  public function get_prev_entity() {
+    if ($this->has_prev_entity()) {
+      $this->iterator--;
+      return $this->list[$this->iterator];
+    }
+    return NULL;
+  }
+
+  public function reset_entity_pointer() {
+    $this->iterator = -1;
+  }
+
+  public function save_cursor($cursor) {
+    $this->next = $cursor;
+  }
+
+  public function reset_paging() {
+    $this->previous = array();
+    $this->next = FALSE;
+    $this->cursor = NULL;
+  }
+
+  public function has_next_page() {
+    return (bool) $this->next;
+  }
+
+  public function has_prev_page() {
+    return (count($this->previous) > 0);
+  }
+
+  /**
+   * @return \Apache\Usergrid\Response|bool
+   */
+  public function get_next_page() {
+    if ($this->has_next_page()) {
+      array_push($this->previous, $this->cursor);
+      $this->cursor = $this->next;
+      $this->list = array();
+      return $this->fetch();
+    }
+    return FALSE;
+  }
+
+  /**
+   * @return \Apache\Usergrid\Response|bool
+   */
+  public function get_prev_page() {
+    if ($this->has_prev_page()) {
+      $this->next = FALSE;
+      $this->cursor = array_pop($this->previous);
+      $this->list = array();
+      return $this->fetch();
+    }
+    return FALSE;
+  }
+  public function serialize(){
+    $data = array();
+    $data->type = $this->type;
+    $data->qs = $this->qs;
+    $data->iterator = $this->iterator;
+    $data->previous = $this->previous;
+    $data->next = $this->next;
+    $data->cursor = $this->cursor;
+    $data->list = array();
+    $this->reset_entity_pointer();
+    while ($this->has_next_entity()) {
+        $entity = $this->get_next_entity();
+        array_push($data->list, $entity->get_json());
+    }
+    return json_encode($data);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/lib/vendor/Apache/Usergrid/Entity.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/lib/vendor/Apache/Usergrid/Entity.php b/sdks/other/php/lib/vendor/Apache/Usergrid/Entity.php
new file mode 100755
index 0000000..ccb9377
--- /dev/null
+++ b/sdks/other/php/lib/vendor/Apache/Usergrid/Entity.php
@@ -0,0 +1,320 @@
+#!/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
+ * Allows CRUD operations on Usergrid Entities, including Users.
+ *
+ * @author Daniel Johnson <dj...@apigee.com>
+ * @author Rod Simpson <ro...@apigee.com>
+ * @since 26-Apr-2013
+ */
+
+namespace Apache\Usergrid;
+
+class Entity {
+
+  private $client;
+  private $data;
+  private $json;
+
+  public function __construct(Client $client, $data = array(), $json_data='') {
+    $this->client = $client;
+    $this->data = $data;
+    $this->json_data = $json_data;
+  }
+
+  public function get_json() {
+    return $this->json;
+  }
+
+  public function set_json($json) {
+    $this->json = $json;
+  }
+
+  public function get($field = NULL) {
+    if (!empty($field)) {
+      return (isset($this->data[$field]) ? $this->data[$field] : NULL);
+    }
+    return $this->data;
+  }
+
+  public function set($key, $value = NULL) {
+    if (is_array($key)) {
+      foreach ($key as $field => $value) {
+        $this->data[$field] = $value;
+      }
+    }
+    elseif (is_string($key)) {
+      if (!isset($value)) {
+        if (isset($this->data[$key])) {
+          unset($this->data[$key]);
+        }
+      }
+      else {
+        $this->data[$key] = $value;
+      }
+    }
+    else {
+      $this->data = array();
+    }
+  }
+
+  public function save() {
+    $type = $this->get('type');
+    $method = 'POST';
+    $uuid = $this->get('uuid');
+    if (isset($uuid) && Client::is_uuid($uuid)) {
+      $method = 'PUT';
+      $type .= "/$uuid";
+    }
+    $data = array();
+    $entity_data = $this->get();
+    foreach ($entity_data as $key => $val) {
+      switch ($key) {
+        case 'metadata':
+        case 'created':
+        case 'modified':
+        case 'type':
+        case 'activated':
+        case 'uuid':
+          continue;
+          break;
+        default:
+          $data[$key] = $val;
+      }
+    }
+
+    if ($method == 'PUT') {
+      $response = $this->client->put($type, array(), $data);
+    }
+    else {
+      $response = $this->client->post($type, array(), $data);
+    }
+
+    $this->set_json($response->get_json());
+
+    if ($response->get_error()) {
+      $this->client->write_log('Could not save entity.');
+    }
+    else {
+      $response_data = $response->get_data();
+      if (!empty($response_data['entities'])) {
+        $this->set($response_data['entities'][0]);
+      }
+      $need_password_change = (
+        ($this->get('type') == 'user' || $this->get('type') == 'users')
+        && !empty($entity_data['oldpassword'])
+        && !empty($entity_data['newpassword'])
+      );
+      if ($need_password_change) {
+        $pw_data = array(
+          'oldpassword' => $entity_data['oldpassword'],
+          'newpassword' => $entity_data['newpassword']
+        );
+        $response = $this->client->PUT("$type/password", array(), $pw_data);
+        if ($response->get_error()) {
+          $this->client->write_log('Could not update user\'s password.');
+        }
+        $this->set('oldpassword', NULL);
+        $this->set('newpassword', NULL);
+      }
+    }
+    return $response;
+  }
+
+  public function fetch() {
+    $response = new Response();
+    $type = $this->get('type');
+    $uuid = $this->get('uuid'); // may be NULL
+    if (!empty($uuid)) {
+      $type .= "/$uuid";
+    }
+    else {
+      if ($type == 'user' || $type == 'users') {
+        $username = $this->get('username');
+        if (!empty($username)) {
+          $type .= "/$username";
+        }
+        else {
+          $error = 'no_name_specified';
+          $this->client->write_log($error);
+          $response->set_error($error);
+          $response->set_error_code($error);
+          return $response;
+        }
+      }
+      else {
+        $name = $this->get('name');
+        if (!empty($name)) {
+          $type .= "/$name";
+        }
+        else {
+          $error = 'no_name_specified';
+          $this->client->write_log($error);
+          $response->set_error($error);
+          $response->set_error_code($error);
+          return $response;
+        }
+      }
+    }
+    $response = $this->client->get($type, array());
+    $this->set_json($response->get_json());
+    if ($response->get_error()) {
+      $this->client->write_log('Could not get entity.');
+    }
+    else {
+      $data = $response->get_data();
+      if (isset($data['user'])) {
+        $this->set($data['user']);
+      }
+      elseif (!empty($data['entities'])) {
+        $this->set($data['entities'][0]);
+      }
+    }
+    return $response;
+  }
+
+  public function destroy() {
+    $response = new Response();
+    $type = $this->get('type');
+    $uuid = $this->get('uuid');
+    if (Client::is_uuid($uuid)) {
+      $type .= "/$uuid";
+    }
+    else {
+      $error = 'Error trying to delete object: No UUID specified.';
+      $this->client->write_log($error);
+      $response->set_error($error);
+      $response->set_error_code($error);
+      return $response;
+    }
+
+    $response = $this->client->delete($type, array());
+    $this->set_json($response->get_json());
+    if ($response->get_error()) {
+      $this->client->write_log('Entity could not be deleted.');
+    }
+    else {
+      $this->set(NULL);
+    }
+    return $response;
+  }
+
+  public function connect($connection, $entity) {
+    $connectee=Entity::get_entity_id($entity);
+    $connecteeType=$entity->get("type");
+    if(!$connectee){
+      return "Error in connect. No UUID specified for connectee";
+    }
+
+    $connector=Entity::get_entity_id($this);
+    $connectorType=$this->get("type");
+    if(!$connector){
+      return "Error in connect. No UUID specified for connector";
+    }
+
+    $endpoint = $connectorType.'/'.$connector.'/'.$connection.'/'.$connecteeType.'/'.$connectee;
+    $result=$this->client->post($endpoint, array(), array());
+    $error=$result->get_error();
+    if($error){
+      return $result->get_error_message();
+    }else{
+      return $result->get_data();
+    }
+  }
+
+  public function disconnect($connection, $entity) {
+    $connectee=Entity::get_entity_id($entity);
+    $connecteeType=$entity->get("type");
+    if(!$connectee){
+      return "Error in disconnect. No UUID specified for connectee";
+    }
+
+    $connector=Entity::get_entity_id($this);
+    $connectorType=$this->get("type");
+    if(!$connector){
+      return "Error in disconnect. No UUID specified for connector";
+    }
+
+    $endpoint = $connectorType.'/'.$connector.'/'.$connection.'/'.$connecteeType.'/'.$connectee;
+
+    $result=$this->client->delete($endpoint, array(), array());
+    $error=$result->get_error();
+    if($error){
+      return $result->get_error_message();
+    }else{
+      return $result->get_data();
+    }
+  }
+
+  public static function get_entity_id($entity) {
+      $id = false;
+      if (Client::is_uuid($entity->get('uuid'))) {
+        $id = $entity->get('uuid');
+      } else {
+        if ($type == 'users') {
+          $id = $entity->get('username');
+        } else if ($entity->get('name')) {
+          $id = $entity->get('name');
+        }
+      }
+      return $id;
+  }
+
+  public function get_connections($connection) {
+    $connectorType = $this->get('type');
+    $connector = Entity::get_entity_id($this);
+    if (!$connector) {
+      return;
+    }
+
+    $endpoint = $connectorType . '/' . $connector . '/' . $connection . '/';
+    $result=$this->client->get($endpoint, array());
+
+    $connected_entities = array();
+
+    $response_data = $result->get_data();
+    $length        = count($response_data['entities']);
+    
+    for ($i = 0; $i < $length; $i++) {
+      $tmp_entity = $response_data['entities'][$i];
+      if ($tmp_entity['type'] == 'user') {
+          $connected_entities[$tmp_entity['username']] = $tmp_entity;
+      } else {
+          $connected_entities[$tmp_entity['name']]     = $tmp_entity;
+      }
+    }
+    $this->set($connection, $connected_entities);
+  }
+
+  public function get_connecting($connection) {
+    $connectorType = $this->get('type');
+    $connector = Entity::get_entity_id($this);
+    if (!$connector) {
+      return;
+    }
+
+    $endpoint = $connectorType. '/' . $connector . '/connecting/' . $connection . '/';
+    $result=$this->client->get($endpoint, array());
+    return $result->get_data();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/php/lib/vendor/Apache/Usergrid/Exceptions.php
----------------------------------------------------------------------
diff --git a/sdks/other/php/lib/vendor/Apache/Usergrid/Exceptions.php b/sdks/other/php/lib/vendor/Apache/Usergrid/Exceptions.php
new file mode 100755
index 0000000..706e9e5
--- /dev/null
+++ b/sdks/other/php/lib/vendor/Apache/Usergrid/Exceptions.php
@@ -0,0 +1,41 @@
+#!/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
+* Request - a data structure to hold all request-related parameters
+*
+* @author Daniel Johnson <dj...@apigee.com>
+* @author Rod Simpson <ro...@apigee.com>
+* @since 26-Apr-2013
+*/
+
+
+namespace Apache\Usergrid;
+
+
+class UGException extends \Exception { }
+class UG_400_BadRequest extends UGException {}
+class UG_401_Unauthorized extends UGException {}
+class UG_403_Forbidden extends UGException {}
+class UG_404_NotFound extends UGException {}
+class UG_500_ServerError extends UGException {}
+
+?>