Merge branch 'develop'
diff --git a/.gitignore b/.gitignore
index 2a3cfbd..ec6b6b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
build
composer.phar
+composer.lock
docs
vendor
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..68b4dfe
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,10 @@
+language: php
+php:
+ - 5.5
+ - 5.4
+ - 5.3
+before_script:
+ - pear channel-discover pear.phing.info
+ - pear install phing/phing
+ - phpenv rehash
+ - phing
diff --git a/README.md b/README.md
index 673980d..6e2aa05 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,43 @@
PredictionIO PHP SDK
====================
+[![Build Status](https://travis-ci.org/PredictionIO/PredictionIO-PHP-SDK.png?branch=develop)](https://travis-ci.org/PredictionIO/PredictionIO-PHP-SDK)
+[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/PredictionIO/PredictionIO-PHP-SDK/badges/quality-score.png?s=bba570e3add382f4f56fcba65ec0b4f0b8622091)](https://scrutinizer-ci.com/g/PredictionIO/PredictionIO-PHP-SDK/)
+[![Code Coverage](https://scrutinizer-ci.com/g/PredictionIO/PredictionIO-PHP-SDK/badges/coverage.png?s=db1de9fde081fedd79346b4aba562ab56853ed45)](https://scrutinizer-ci.com/g/PredictionIO/PredictionIO-PHP-SDK/)
+
Prerequisites
--------------
+=============
* PHP 5.3+ (http://php.net/)
* PHP: cURL (http://php.net/manual/en/book.curl.php)
* Phing (http://www.phing.info/)
* ApiGen (http://apigen.org/)
-Getting Started
----------------
-### By Composer
+Support
+=======
+
+
+Forum
+-----
+
+https://groups.google.com/group/predictionio-user
+
+
+Issue Tracker
+-------------
+
+https://predictionio.atlassian.net
+
+If you are unsure whether a behavior is an issue, bringing it up in the forum is highly encouraged.
+
+
+Getting Started
+===============
+
+
+By Composer
+-----------
The easiest way to install PredictionIO PHP client is to use [Composer](http://getcomposer.org/).
@@ -20,7 +45,7 @@
{
"require": {
- "predictionio/predictionio": "*"
+ "predictionio/predictionio": "~0.6.0"
}
}
@@ -37,7 +62,8 @@
require_once("vendor/autoload.php");
-### By Building Phar
+By Building Phar
+----------------
1. Assuming you are cloning to your home directory:
@@ -52,16 +78,18 @@
3. Once the build finishes you will get a Phar in `build/artifacts`, and a set of API documentation.
Assuming you have copied the Phar to your current working directory, to use the client, simply
- require_once("predictionio.phar");
+ require_once("predictionio.phar");
Supported Commands
-------------------
+==================
-For a list of supported commands, please refer to the API documentation.
+For a list of supported commands, please refer to the
+[API documentation](http://docs.prediction.io/php/api/).
+
Usage
------
+=====
This package is a web service client based on Guzzle.
A few quick examples are shown below.
@@ -72,50 +100,74 @@
Many REST request commands support optional arguments.
They can be supplied to these commands by the `set` method.
-### Instantiate PredictionIO API Client
- use PredictionIO\PredictionIOClient;
- $client = PredictionIOClient::factory(array("appkey" => "<your app key>"));
+Instantiate PredictionIO API Client
+-----------------------------------
-### Import a User Record from Your App
+```PHP
+use PredictionIO\PredictionIOClient;
+$client = PredictionIOClient::factory(array("appkey" => "<your app key>"));
+```
- // assume you have a user with user ID 5
- $command = $client->getCommand('create_user', array('pio_uid' => 5));
- $response = $client->execute($command);
-### Import an Item Record from Your App
+Import a User Record from Your App
+----------------------------------
- // assume you have a book with ID 'bookId1' and we assign 1 as the type ID for book
- $command = $client->getCommand('create_item', array('pio_iid' => 'bookId1', 'pio_itypes' => 1));
- $response = $client->execute($command);
+```PHP
+// assume you have a user with user ID 5
+$command = $client->getCommand('create_user', array('pio_uid' => 5));
+$response = $client->execute($command);
+```
-### Import a User Action (View) form Your App
- // assume this user has viewed this book item
+Import an Item Record from Your App
+-----------------------------------
+
+```PHP
+// assume you have a book with ID 'bookId1' and we assign 1 as the type ID for book
+$command = $client->getCommand('create_item', array('pio_iid' => 'bookId1', 'pio_itypes' => 1));
+$response = $client->execute($command);
+```
+
+
+Import a User Action (View) form Your App
+-----------------------------------------
+
+```PHP
+// assume this user has viewed this book item
+$client->identify('5');
+$client->execute($client->getCommand('record_action_on_item', array('pio_action' => 'view', 'pio_iid' => 'bookId1')));
+```
+
+
+Retrieving Top N Recommendations for a User
+-------------------------------------------
+
+```PHP
+try {
+ // assume you have created an itemrec engine named 'engine1'
+ // we try to get top 10 recommendations for a user (user ID 5)
$client->identify('5');
- $client->execute($client->getCommand('record_action_on_item', array('pio_action' => 'view', 'pio_iid' => 'bookId1')));
+ $command = $client->getCommand('itemrec_get_top_n', array('pio_engine' => 'engine1', 'pio_n' => 10));
+ $rec = $client->execute($command);
+ print_r($rec);
+} catch (Exception $e) {
+ echo 'Caught exception: ', $e->getMessage(), "\n";
+}
+```
-### Retrieving Top N Recommendations for a User
- try {
- // assume you have created an itemrec engine named 'engine1'
- // we try to get top 10 recommendations for a user (user ID 5)
- $client->identify('5');
- $command = $client->getCommand('itemrec_get_top_n', array('pio_engine' => 'engine1', 'pio_n' => 10));
- $rec = $client->execute($command);
- print_r($rec);
- } catch (Exception $e) {
- echo 'Caught exception: ', $e->getMessage(), "\n";
- }
+Retrieving Top N Similar Items for an Item
+------------------------------------------
-### Retrieving Top N Similar Items for an Item
-
- try {
- // assume you have created an itemsim engine named 'engine2'
- // we try to get top 10 similar items for an item (item ID 6)
- $command = $client->getCommand('itemsim_get_top_n', array('pio_iid' => '6', 'pio_engine' => 'engine1', 'pio_n' => 10));
- $rec = $client->execute($command);
- print_r($rec);
- } catch (Exception $e) {
- echo 'Caught exception: ', $e->getMessage(), "\n";
- }
+```PHP
+try {
+ // assume you have created an itemsim engine named 'engine2'
+ // we try to get top 10 similar items for an item (item ID 6)
+ $command = $client->getCommand('itemsim_get_top_n', array('pio_iid' => '6', 'pio_engine' => 'engine1', 'pio_n' => 10));
+ $rec = $client->execute($command);
+ print_r($rec);
+} catch (Exception $e) {
+ echo 'Caught exception: ', $e->getMessage(), "\n";
+}
+```
diff --git a/composer.lock b/composer.lock
deleted file mode 100644
index 8a36ad4..0000000
--- a/composer.lock
+++ /dev/null
@@ -1,221 +0,0 @@
-{
- "_readme": [
- "This file locks the dependencies of your project to a known state",
- "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
- ],
- "hash": "c96d97d6408cbc90125b23bdf6fd9fc0",
- "packages": [
- {
- "name": "guzzle/guzzle",
- "version": "v3.3.1",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/guzzle.git",
- "reference": "v3.3.1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/v3.3.1",
- "reference": "v3.3.1",
- "shasum": ""
- },
- "require": {
- "ext-curl": "*",
- "php": ">=5.3.2",
- "symfony/event-dispatcher": ">=2.1"
- },
- "replace": {
- "guzzle/batch": "self.version",
- "guzzle/cache": "self.version",
- "guzzle/common": "self.version",
- "guzzle/http": "self.version",
- "guzzle/inflection": "self.version",
- "guzzle/iterator": "self.version",
- "guzzle/log": "self.version",
- "guzzle/parser": "self.version",
- "guzzle/plugin": "self.version",
- "guzzle/plugin-async": "self.version",
- "guzzle/plugin-backoff": "self.version",
- "guzzle/plugin-cache": "self.version",
- "guzzle/plugin-cookie": "self.version",
- "guzzle/plugin-curlauth": "self.version",
- "guzzle/plugin-error-response": "self.version",
- "guzzle/plugin-history": "self.version",
- "guzzle/plugin-log": "self.version",
- "guzzle/plugin-md5": "self.version",
- "guzzle/plugin-mock": "self.version",
- "guzzle/plugin-oauth": "self.version",
- "guzzle/service": "self.version",
- "guzzle/stream": "self.version"
- },
- "require-dev": {
- "doctrine/cache": "*",
- "monolog/monolog": "1.*",
- "phpunit/phpunit": "3.7.*",
- "symfony/class-loader": "*",
- "zend/zend-cache1": "1.12",
- "zend/zend-log1": "1.12",
- "zendframework/zend-cache": "2.0.*",
- "zendframework/zend-log": "2.0.*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.3-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Guzzle\\Tests": "tests/",
- "Guzzle": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "Guzzle Community",
- "homepage": "https://github.com/guzzle/guzzle/contributors"
- }
- ],
- "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
- "homepage": "http://guzzlephp.org/",
- "keywords": [
- "client",
- "curl",
- "framework",
- "http",
- "http client",
- "rest",
- "web service"
- ],
- "time": "2013-03-10 23:05:38"
- },
- {
- "name": "symfony/event-dispatcher",
- "version": "v2.2.1",
- "target-dir": "Symfony/Component/EventDispatcher",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/EventDispatcher.git",
- "reference": "v2.2.1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.1",
- "reference": "v2.2.1",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "symfony/dependency-injection": ">=2.0,<3.0"
- },
- "suggest": {
- "symfony/dependency-injection": "2.2.*",
- "symfony/http-kernel": "2.2.*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.2-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Symfony\\Component\\EventDispatcher\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- }
- ],
- "description": "Symfony EventDispatcher Component",
- "homepage": "http://symfony.com",
- "time": "2013-02-11 11:26:43"
- }
- ],
- "packages-dev": [
- {
- "name": "symfony/class-loader",
- "version": "v2.2.1",
- "target-dir": "Symfony/Component/ClassLoader",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/ClassLoader.git",
- "reference": "v2.2.1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/ClassLoader/zipball/v2.2.1",
- "reference": "v2.2.1",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "symfony/finder": ">=2.0,<3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.2-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Symfony\\Component\\ClassLoader\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- }
- ],
- "description": "Symfony ClassLoader Component",
- "homepage": "http://symfony.com",
- "time": "2013-03-19 08:32:26"
- }
- ],
- "aliases": [
-
- ],
- "minimum-stability": "stable",
- "stability-flags": [
-
- ],
- "platform": {
- "php": ">=5.3.2"
- },
- "platform-dev": [
-
- ]
-}
diff --git a/examples/SampleImport.php b/examples/SampleImport.php
index dc1e48f..83c9adf 100644
--- a/examples/SampleImport.php
+++ b/examples/SampleImport.php
@@ -12,9 +12,6 @@
$appkey = $argv[1];
$input = $argv[2];
-// Instantiate a client
-$client = PredictionIOClient::factory(array("appkey" => $appkey));
-
if (!file_exists($input)) {
print "$input not found!\n";
exit(1);
@@ -25,6 +22,9 @@
exit(1);
}
+// Instantiate a client
+$client = PredictionIOClient::factory(array("appkey" => $appkey));
+
// Scan sample data file and import ratings
$handle = fopen($input, "r");
while (!feof($handle)) {
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..d313305
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit colors="true"
+ verbose="false"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="false"
+ convertWarningsToExceptions="false"
+ bootstrap="vendor/autoload.php"
+ >
+ <testsuites>
+ <testsuite name="PredictionIO Unit Test Suite">
+ <directory>./tests/Unit</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/src/PredictionIO/Command/CreateItem.php b/src/PredictionIO/Command/CreateItem.php
index c3928b8..ab02c35 100644
--- a/src/PredictionIO/Command/CreateItem.php
+++ b/src/PredictionIO/Command/CreateItem.php
@@ -10,7 +10,8 @@
*
* Create or re-create an information record for a item. Re-creation will remove all data of the current record.
*
- * To supply custom item information, simply pass it in during command creation, or use the "set" method inherited from Guzzle\Common\Collection.
+ * To supply custom item information, simply pass it in during command creation,
+ * or use the "set" method inherited from Guzzle\Common\Collection.
* <code>
* $command = $client->getCommand('create_item', array('pio_iid' => 'foobar', 'custom1' => 'baz'));
* $command->set('custom2', '0xdeadbeef');
@@ -27,117 +28,120 @@
*/
class CreateItem extends AbstractCommand
{
- /**
- * Set the "iid" parameter for the current command
- *
- * @param string $iid Item ID
- *
- * @return CreateItem
- */
- public function setIid($iid)
- {
- return $this->set("pio_iid", $iid);
- }
-
- /**
- * Set the "itypes" parameter for the current command
- *
- * $itypes can be supplied as an array of strings, or a "," delimited list of strings.
- *
- * @param array|string $itypes Item types
- *
- * @return CreateItem
- */
- public function setItypes($itypes)
- {
- if (is_array($itypes)) {
- return $this->set("pio_itypes", implode(",", $itypes));
- } else {
- return $this->set("pio_itypes", $itypes);
+ /**
+ * Set the "iid" parameter for the current command
+ *
+ * @param string $iid Item ID
+ *
+ * @return CreateItem
+ */
+ public function setIid($iid)
+ {
+ return $this->set("pio_iid", $iid);
}
- }
- /**
- * Set the "startT" parameter for the current command
- *
- * @param string $startT Start time
- *
- * @return CreateItem
- */
- public function setStartT($startT)
- {
- return $this->set("pio_startT", $startT);
- }
+ /**
+ * Set the "itypes" parameter for the current command
+ *
+ * $itypes can be supplied as an array of strings, or a "," delimited list of strings.
+ *
+ * @param array|string $itypes Item types
+ *
+ * @return CreateItem
+ */
+ public function setItypes($itypes)
+ {
+ if (is_array($itypes)) {
+ return $this->set("pio_itypes", implode(",", $itypes));
+ }
- /**
- * Set the "endT" parameter for the current command
- *
- * @param string $endT End time
- *
- * @return CreateItem
- */
- public function setEndT($endT)
- {
- return $this->set("pio_endT", $endT);
- }
+ return $this->set("pio_itypes", $itypes);
+ }
- /**
- * Set the "price" parameter for the current command
- *
- * @param float $price Price
- *
- * @return CreateItem
- */
- public function setPrice($price)
- {
- return $this->set("pio_price", $price);
- }
+ /**
+ * Set the "startT" parameter for the current command
+ *
+ * @param string $startT Start time
+ *
+ * @return CreateItem
+ */
+ public function setStartT($startT)
+ {
+ return $this->set("pio_startT", $startT);
+ }
- /**
- * Set the "profit" parameter for the current command
- *
- * @param float $profit Profit
- *
- * @return CreateItem
- */
- public function setProfit($profit)
- {
- return $this->set("pio_profit", $profit);
- }
+ /**
+ * Set the "endT" parameter for the current command
+ *
+ * @param string $endT End time
+ *
+ * @return CreateItem
+ */
+ public function setEndT($endT)
+ {
+ return $this->set("pio_endT", $endT);
+ }
- /**
- * Set the "latlng" parameter for the current command
- *
- * In "latitude,longitude" format, e.g. "20.17,114.08"
- *
- * @param string $latlng Latitude and longitude
- *
- * @return CreateItem
- */
- public function setLatlng($latlng)
- {
- return $this->set("pio_latlng", $latlng);
- }
+ /**
+ * Set the "price" parameter for the current command
+ *
+ * @param float $price Price
+ *
+ * @return CreateItem
+ */
+ public function setPrice($price)
+ {
+ return $this->set("pio_price", $price);
+ }
- /**
- * Set the "inactive" parameter for the current command
- *
- * @param string $inactive Inactive flag (use "true" or "false" string)
- *
- * @return CreateItem
- */
- public function setInactive($inactive)
- {
- return $this->set("inactive", $inactive);
- }
+ /**
+ * Set the "profit" parameter for the current command
+ *
+ * @param float $profit Profit
+ *
+ * @return CreateItem
+ */
+ public function setProfit($profit)
+ {
+ return $this->set("pio_profit", $profit);
+ }
- /**
- * Create the request object that will carry out the command. Used internally by Guzzle.
- */
- protected function build()
- {
- $this->request = $this->client->createRequest(RequestInterface::POST, 'items', null, $this->getAll());
- }
+ /**
+ * Set the "latlng" parameter for the current command
+ *
+ * In "latitude,longitude" format, e.g. "20.17,114.08"
+ *
+ * @param string $lat Latitude
+ * @param string $lng Longitude
+ *
+ * @return CreateItem
+ */
+ public function setLatlng($lat, $lng = null)
+ {
+ if (null === $lng) {
+ return $this->set("pio_latlng", $lat);
+ }
+
+ return $this->set("pio_latlng", sprintf("%s,%s", $lat, $lng));
+ }
+
+ /**
+ * Set the "inactive" parameter for the current command
+ *
+ * @param string $inactive Inactive flag (use "true" or "false" string)
+ *
+ * @return CreateItem
+ */
+ public function setInactive($inactive)
+ {
+ return $this->set("pio_inactive", $inactive);
+ }
+
+ /**
+ * Create the request object that will carry out the command. Used internally by Guzzle.
+ */
+ protected function build()
+ {
+ $this->request = $this->client->createRequest(RequestInterface::POST, 'items', null, $this->getAll());
+ }
}
-
-?>
\ No newline at end of file
diff --git a/src/PredictionIO/Command/CreateUser.php b/src/PredictionIO/Command/CreateUser.php
index 11e7979..0a3c380 100644
--- a/src/PredictionIO/Command/CreateUser.php
+++ b/src/PredictionIO/Command/CreateUser.php
@@ -10,7 +10,8 @@
*
* Create or re-create an information record for a user. Re-creation will remove all data of the current record.
*
- * To supply custom user information, simply pass it in during command creation, or use the "set" method inherited from Guzzle\Common\Collection.
+ * To supply custom user information, simply pass it in during command creation,
+ * or use the "set" method inherited from Guzzle\Common\Collection.
* <code>
* $command = $client->getCommand('create_user', array('pio_uid' => 'foobar', 'custom1' => 'baz'));
* $command->set('custom2', '0xdeadbeef');
@@ -22,51 +23,54 @@
*/
class CreateUser extends AbstractCommand
{
- /**
- * Set the "uid" parameter for the current command
- *
- * @param string $uid User ID
- *
- * @return CreateUser
- */
- public function setUid($uid)
- {
- return $this->set("pio_uid", $uid);
- }
+ /**
+ * Set the "uid" parameter for the current command
+ *
+ * @param string $uid User ID
+ *
+ * @return CreateUser
+ */
+ public function setUid($uid)
+ {
+ return $this->set("pio_uid", $uid);
+ }
- /**
- * Set the "latlng" parameter for the current command
- *
- * In "latitude,longitude" format, e.g. "20.17,114.08"
- *
- * @param string $latlng Latitude and longitude
- *
- * @return CreateUser
- */
- public function setLatlng($latlng)
- {
- return $this->set("pio_latlng", $latlng);
- }
+ /**
+ * Set the "latlng" parameter for the current command
+ *
+ * In "latitude,longitude" format, e.g. "20.17,114.08"
+ *
+ * @param string $lat Latitude
+ * @param string $lng Longitude
+ *
+ * @return CreateUser
+ */
+ public function setLatlng($lat, $lng = null)
+ {
+ if (null === $lng) {
+ return $this->set("pio_latlng", $lat);
+ }
- /**
- * Set the "inactive" parameter for the current command
- *
- * @param bool $inactive Inactive flag (use "true" or "false" string)
- *
- * @return CreateUser
- */
- public function setInactive($inactive)
- {
- return $this->set("pio_inactive", $inactive);
- }
+ return $this->set("pio_latlng", sprintf("%s,%s", $lat, $lng));
+ }
- /**
- * Create the request object that will carry out the command. Used internally by Guzzle.
- */
- protected function build()
- {
- $this->request = $this->client->createRequest(RequestInterface::POST, 'users', null, $this->getAll());
- }
+ /**
+ * Set the "inactive" parameter for the current command
+ *
+ * @param bool $inactive Inactive flag (use "true" or "false" string)
+ *
+ * @return CreateUser
+ */
+ public function setInactive($inactive)
+ {
+ return $this->set("pio_inactive", $inactive);
+ }
+
+ /**
+ * Create the request object that will carry out the command. Used internally by Guzzle.
+ */
+ protected function build()
+ {
+ $this->request = $this->client->createRequest(RequestInterface::POST, 'users', null, $this->getAll());
+ }
}
-
-?>
\ No newline at end of file
diff --git a/src/PredictionIO/Command/DeleteItem.php b/src/PredictionIO/Command/DeleteItem.php
index 7f6f42b..c8df188 100644
--- a/src/PredictionIO/Command/DeleteItem.php
+++ b/src/PredictionIO/Command/DeleteItem.php
@@ -14,25 +14,23 @@
*/
class DeleteItem extends AbstractCommand
{
- /**
- * Set the "iid" parameter for the current command
- *
- * @param string $iid Item ID
- *
- * @return DeleteItem
- */
- public function setIid($iid)
- {
- return $this->set('pio_iid', $iid);
- }
+ /**
+ * Set the "iid" parameter for the current command
+ *
+ * @param string $iid Item ID
+ *
+ * @return DeleteItem
+ */
+ public function setIid($iid)
+ {
+ return $this->set('pio_iid', $iid);
+ }
- /**
- * Create the request object that will carry out the command. Used internally by Guzzle.
- */
- protected function build()
- {
- $this->request = $this->client->createRequest(RequestInterface::DELETE, 'items/' . $this->get('pio_iid'));
- }
+ /**
+ * Create the request object that will carry out the command. Used internally by Guzzle.
+ */
+ protected function build()
+ {
+ $this->request = $this->client->createRequest(RequestInterface::DELETE, 'items/' . $this->get('pio_iid'));
+ }
}
-
-?>
\ No newline at end of file
diff --git a/src/PredictionIO/Command/DeleteUser.php b/src/PredictionIO/Command/DeleteUser.php
index e7eaee6..4df9c1d 100644
--- a/src/PredictionIO/Command/DeleteUser.php
+++ b/src/PredictionIO/Command/DeleteUser.php
@@ -14,25 +14,23 @@
*/
class DeleteUser extends AbstractCommand
{
- /**
- * Set the "uid" parameter for the current command
- *
- * @param string $uid User ID
- *
- * @return DeleteUser
- */
- public function setUid($uid)
- {
- return $this->set('pio_uid', $uid);
- }
+ /**
+ * Set the "uid" parameter for the current command
+ *
+ * @param string $uid User ID
+ *
+ * @return DeleteUser
+ */
+ public function setUid($uid)
+ {
+ return $this->set('pio_uid', $uid);
+ }
- /**
- * Create the request object that will carry out the command. Used internally by Guzzle.
- */
- protected function build()
- {
- $this->request = $this->client->createRequest(RequestInterface::DELETE, 'users/' . $this->get('pio_uid'));
- }
+ /**
+ * Create the request object that will carry out the command. Used internally by Guzzle.
+ */
+ protected function build()
+ {
+ $this->request = $this->client->createRequest(RequestInterface::DELETE, 'users/' . $this->get('pio_uid'));
+ }
}
-
-?>
\ No newline at end of file
diff --git a/src/PredictionIO/Command/GetItem.php b/src/PredictionIO/Command/GetItem.php
index 4912fb2..368c595 100644
--- a/src/PredictionIO/Command/GetItem.php
+++ b/src/PredictionIO/Command/GetItem.php
@@ -15,25 +15,23 @@
*/
class GetItem extends AbstractCommand
{
- /**
- * Set the "iid" parameter for the current command
- *
- * @param string $iid Item ID
- *
- * @return GetItem
- */
- public function setIid($iid)
- {
- return $this->set('pio_iid', $iid);
- }
+ /**
+ * Set the "iid" parameter for the current command
+ *
+ * @param string $iid Item ID
+ *
+ * @return GetItem
+ */
+ public function setIid($iid)
+ {
+ return $this->set('pio_iid', $iid);
+ }
- /**
- * Create the request object that will carry out the command. Used internally by Guzzle.
- */
- protected function build()
- {
- $this->request = $this->client->createRequest(RequestInterface::GET, 'items/' . $this->get('pio_iid'));
- }
+ /**
+ * Create the request object that will carry out the command. Used internally by Guzzle.
+ */
+ protected function build()
+ {
+ $this->request = $this->client->createRequest(RequestInterface::GET, 'items/' . $this->get('pio_iid'));
+ }
}
-
-?>
\ No newline at end of file
diff --git a/src/PredictionIO/Command/GetUser.php b/src/PredictionIO/Command/GetUser.php
index 988d4fa..0a1a0c4 100644
--- a/src/PredictionIO/Command/GetUser.php
+++ b/src/PredictionIO/Command/GetUser.php
@@ -14,25 +14,23 @@
*/
class GetUser extends AbstractCommand
{
- /**
- * Set the "uid" parameter for the current command
- *
- * @param string $uid User ID
- *
- * @return GetUser
- */
- public function setUid($uid)
- {
- return $this->set('pio_uid', $uid);
- }
+ /**
+ * Set the "uid" parameter for the current command
+ *
+ * @param string $uid User ID
+ *
+ * @return GetUser
+ */
+ public function setUid($uid)
+ {
+ return $this->set('pio_uid', $uid);
+ }
- /**
- * Create the request object that will carry out the command. Used internally by Guzzle.
- */
- protected function build()
- {
- $this->request = $this->client->createRequest(RequestInterface::GET, 'users/' . $this->get('pio_uid'));
- }
+ /**
+ * Create the request object that will carry out the command. Used internally by Guzzle.
+ */
+ protected function build()
+ {
+ $this->request = $this->client->createRequest(RequestInterface::GET, 'users/' . $this->get('pio_uid'));
+ }
}
-
-?>
\ No newline at end of file
diff --git a/src/PredictionIO/Command/ItemrecGetTopN.php b/src/PredictionIO/Command/ItemrecGetTopN.php
index 10cad36..a319483 100644
--- a/src/PredictionIO/Command/ItemrecGetTopN.php
+++ b/src/PredictionIO/Command/ItemrecGetTopN.php
@@ -19,94 +19,102 @@
*/
class ItemrecGetTopN extends AbstractCommand
{
- /**
- * Set the "engine" parameter for the current command
- *
- * @param string $engine Engine Name
- *
- * @return ItemrecGetTopN
- */
- public function setEngine($engine)
- {
- return $this->set('pio_engine', $engine);
- }
-
- /**
- * Set the "n" parameter for the current command
- *
- * @param integer $n N
- *
- * @return ItemrecGetTopN
- */
- public function setN($n)
- {
- return $this->set('pio_n', $n);
- }
-
- /**
- * Set the "itypes" parameter for the current command
- *
- * $itypes can be supplied as an array of integers, or a "," delimited list of integers.
- *
- * @param array|string $itypes Item types
- *
- * @return ItemrecGetTopN
- */
- public function setItypes($itypes)
- {
- if (is_array($itypes)) {
- return $this->set('pio_itypes', implode(',', $itypes));
- } else {
- return $this->set('pio_itypes', $itypes);
+ /**
+ * Set the "engine" parameter for the current command
+ *
+ * @param string $engine Engine Name
+ *
+ * @return ItemrecGetTopN
+ */
+ public function setEngine($engine)
+ {
+ return $this->set('pio_engine', $engine);
}
- }
- /**
- * Set the "latlng" parameter for the current command
- *
- * In "latitude,longitude" format, e.g. "20.17,114.08"
- *
- * @param string $latlng Latitude and longitude
- *
- * @return ItemrecGetTopN
- */
- public function setLatlng($latlng)
- {
- return $this->set('pio_latlng', $latlng);
- }
+ /**
+ * Set the "n" parameter for the current command
+ *
+ * @param integer $n N
+ *
+ * @return ItemrecGetTopN
+ */
+ public function setN($n)
+ {
+ return $this->set('pio_n', $n);
+ }
- /**
- * Set the "within" parameter for the current command
- *
- * @param float $within Radius
- *
- * @return ItemrecGetTopN
- */
- public function setWithin($within)
- {
- return $this->set('pio_within', $within);
- }
+ /**
+ * Set the "itypes" parameter for the current command
+ *
+ * $itypes can be supplied as an array of integers, or a "," delimited list of integers.
+ *
+ * @param array|string $itypes Item types
+ *
+ * @return ItemrecGetTopN
+ */
+ public function setItypes($itypes)
+ {
+ if (is_array($itypes)) {
+ return $this->set('pio_itypes', implode(',', $itypes));
+ } else {
+ return $this->set('pio_itypes', $itypes);
+ }
+ }
- /**
- * Set the "unit" parameter for the current command
- *
- * @param string $unit Unit of radius
- *
- * @return ItemrecGetTopN
- */
- public function setUnit($unit)
- {
- return $this->set('pio_unit', $unit);
- }
+ /**
+ * Set the "latlng" parameter for the current command
+ *
+ * In "latitude,longitude" format, e.g. "20.17,114.08"
+ *
+ * @param string $lat Latitude
+ * @param string $lng Longitude
+ *
+ * @return ItemrecGetTopN
+ */
+ public function setLatlng($lat,$lng=null)
+ {
+ if ($lng === null) {
+ return $this->set("pio_latlng", $lat);
+ } else {
+ return $this->set("pio_latlng", sprintf("%s,%s", $lat, $lng));
+ }
+ }
- /**
- * Create the request object that will carry out the command. Used internally by Guzzle.
- */
- protected function build()
- {
- $this->set('pio_uid', $this->client->getIdentity());
- $this->request = $this->client->createRequest(RequestInterface::GET, 'engines/itemrec/' . $this->get('pio_engine') . '/topn', null, $this->getAll());
- }
+ /**
+ * Set the "within" parameter for the current command
+ *
+ * @param float $within Radius
+ *
+ * @return ItemrecGetTopN
+ */
+ public function setWithin($within)
+ {
+ return $this->set('pio_within', $within);
+ }
+
+ /**
+ * Set the "unit" parameter for the current command
+ *
+ * @param string $unit Unit of radius
+ *
+ * @return ItemrecGetTopN
+ */
+ public function setUnit($unit)
+ {
+ return $this->set('pio_unit', $unit);
+ }
+
+ /**
+ * Create the request object that will carry out the command. Used internally by Guzzle.
+ */
+ protected function build()
+ {
+ $this->set('pio_uid', $this->client->getIdentity());
+ $this->request = $this->client->createRequest(
+ RequestInterface::GET,
+ 'engines/itemrec/' . $this->get('pio_engine') . '/topn',
+ null,
+ $this->getAll()
+ );
+ }
}
-
-?>
\ No newline at end of file
diff --git a/src/PredictionIO/Command/ItemsimGetTopN.php b/src/PredictionIO/Command/ItemsimGetTopN.php
index 5108758..217f810 100644
--- a/src/PredictionIO/Command/ItemsimGetTopN.php
+++ b/src/PredictionIO/Command/ItemsimGetTopN.php
@@ -20,105 +20,113 @@
*/
class ItemsimGetTopN extends AbstractCommand
{
- /**
- * Set the "engine" parameter for the current command
- *
- * @param string $engine Engine Name
- *
- * @return ItemsimGetTopN
- */
- public function setEngine($engine)
- {
- return $this->set('pio_engine', $engine);
- }
-
- /**
- * Set the "iid" parameter for the current command
- *
- * @param string $iid Item ID
- *
- * @return ItemsimGetTopN
- */
- public function setIid($iid)
- {
- return $this->set('pio_iid', $iid);
- }
-
- /**
- * Set the "n" parameter for the current command
- *
- * @param integer $n N
- *
- * @return ItemsimGetTopN
- */
- public function setN($n)
- {
- return $this->set('pio_n', $n);
- }
-
- /**
- * Set the "itypes" parameter for the current command
- *
- * $itypes can be supplied as an array of integers, or a "," delimited list of integers.
- *
- * @param array|string $itypes Item types
- *
- * @return ItemsimGetTopN
- */
- public function setItypes($itypes)
- {
- if (is_array($itypes)) {
- return $this->set('pio_itypes', implode(',', $itypes));
- } else {
- return $this->set('pio_itypes', $itypes);
+ /**
+ * Set the "engine" parameter for the current command
+ *
+ * @param string $engine Engine Name
+ *
+ * @return ItemsimGetTopN
+ */
+ public function setEngine($engine)
+ {
+ return $this->set('pio_engine', $engine);
}
- }
- /**
- * Set the "latlng" parameter for the current command
- *
- * In "latitude,longitude" format, e.g. "20.17,114.08"
- *
- * @param string $latlng Latitude and longitude
- *
- * @return ItemsimGetTopN
- */
- public function setLatlng($latlng)
- {
- return $this->set('pio_latlng', $latlng);
- }
+ /**
+ * Set the "iid" parameter for the current command
+ *
+ * @param string $iid Item ID
+ *
+ * @return ItemsimGetTopN
+ */
+ public function setIid($iid)
+ {
+ return $this->set('pio_iid', $iid);
+ }
- /**
- * Set the "within" parameter for the current command
- *
- * @param float $within Radius
- *
- * @return ItemsimGetTopN
- */
- public function setWithin($within)
- {
- return $this->set('pio_within', $within);
- }
+ /**
+ * Set the "n" parameter for the current command
+ *
+ * @param integer $n N
+ *
+ * @return ItemsimGetTopN
+ */
+ public function setN($n)
+ {
+ return $this->set('pio_n', $n);
+ }
- /**
- * Set the "unit" parameter for the current command
- *
- * @param string $unit Unit of radius
- *
- * @return ItemsimGetTopN
- */
- public function setUnit($unit)
- {
- return $this->set('pio_unit', $unit);
- }
+ /**
+ * Set the "itypes" parameter for the current command
+ *
+ * $itypes can be supplied as an array of integers, or a "," delimited list of integers.
+ *
+ * @param array|string $itypes Item types
+ *
+ * @return ItemsimGetTopN
+ */
+ public function setItypes($itypes)
+ {
+ if (is_array($itypes)) {
+ return $this->set('pio_itypes', implode(',', $itypes));
+ }
- /**
- * Create the request object that will carry out the command. Used internally by Guzzle.
- */
- protected function build()
- {
- $this->request = $this->client->createRequest(RequestInterface::GET, 'engines/itemsim/' . $this->get('pio_engine') . '/topn', null, $this->getAll());
- }
+ return $this->set('pio_itypes', $itypes);
+ }
+
+ /**
+ * Set the "latlng" parameter for the current command
+ *
+ * In "latitude,longitude" format, e.g. "20.17,114.08"
+ *
+ * @param string $lat Latitude
+ * @param string $lng Longitude
+ *
+ * @return ItemsimGetTopN
+ */
+ public function setLatlng($lat,$lng=null)
+ {
+ if ($lng === null) {
+ return $this->set("pio_latlng", $lat);
+ } else {
+ return $this->set("pio_latlng", sprintf("%s,%s", $lat, $lng));
+ }
+ }
+
+ /**
+ * Set the "within" parameter for the current command
+ *
+ * @param float $within Radius
+ *
+ * @return ItemsimGetTopN
+ */
+ public function setWithin($within)
+ {
+ return $this->set('pio_within', $within);
+ }
+
+ /**
+ * Set the "unit" parameter for the current command
+ *
+ * @param string $unit Unit of radius
+ *
+ * @return ItemsimGetTopN
+ */
+ public function setUnit($unit)
+ {
+ return $this->set('pio_unit', $unit);
+ }
+
+ /**
+ * Create the request object that will carry out the command. Used internally by Guzzle.
+ */
+ protected function build()
+ {
+ $this->request = $this->client->createRequest(
+ RequestInterface::GET,
+ 'engines/itemsim/' . $this->get('pio_engine') . '/topn',
+ null,
+ $this->getAll()
+ );
+ }
}
-
-?>
\ No newline at end of file
diff --git a/src/PredictionIO/Command/RecordActionOnItem.php b/src/PredictionIO/Command/RecordActionOnItem.php
index 382db3f..09e3d57 100644
--- a/src/PredictionIO/Command/RecordActionOnItem.php
+++ b/src/PredictionIO/Command/RecordActionOnItem.php
@@ -16,64 +16,67 @@
*/
class RecordActionOnItem extends AbstractCommand
{
- /**
- * Set the "action" parameter for the current command
- *
- * @param string $action Action name
- *
- * @return RecordActionOnItem
- */
- public function setAction($action)
- {
- return $this->set('pio_action', $action);
- }
+ /**
+ * Set the "action" parameter for the current command
+ *
+ * @param string $action Action name
+ *
+ * @return RecordActionOnItem
+ */
+ public function setAction($action)
+ {
+ return $this->set('pio_action', $action);
+ }
- /**
- * Set the "iid" parameter for the current command
- *
- * @param string $iid Item ID
- *
- * @return RecordActionOnItem
- */
- public function setIid($iid)
- {
- return $this->set('pio_iid', $iid);
- }
+ /**
+ * Set the "iid" parameter for the current command
+ *
+ * @param string $iid Item ID
+ *
+ * @return RecordActionOnItem
+ */
+ public function setIid($iid)
+ {
+ return $this->set('pio_iid', $iid);
+ }
- /**
- * Set the "t" parameter for the current command
- *
- * @param string $t Time
- *
- * @return RecordActionOnItem
- */
- public function setT($t)
- {
- return $this->set('pio_t', $t*1000);
- }
+ /**
+ * Set the "t" parameter for the current command
+ *
+ * @param string $t Time
+ *
+ * @return RecordActionOnItem
+ */
+ public function setT($t)
+ {
+ return $this->set('pio_t', $t * 1000);
+ }
- /**
- * Set the "latlng" parameter for the current command
- *
- * In "latitude,longitude" format, e.g. "20.17,114.08"
- *
- * @param string $latlng Latitude and longitude
- *
- * @return RecordActionOnItem
- */
- public function setLatlng($latlng)
- {
- return $this->set('pio_latlng', $latlng);
- }
+ /**
+ * Set the "latlng" parameter for the current command
+ *
+ * In "latitude,longitude" format, e.g. "20.17,114.08"
+ *
+ * @param string $lat Latitude
+ * @param string $lng Longitude
+ *
+ * @return RecordActionOnItem
+ */
+ public function setLatlng($lat, $lng = null)
+ {
+ if (null === $lng) {
+ return $this->set("pio_latlng", $lat);
+ }
- /**
- * Create the request object that will carry out the command. Used internally by Guzzle.
- */
- protected function build()
- {
- $this->set('pio_uid', $this->client->getIdentity());
- $this->request = $this->client->createRequest(RequestInterface::POST, 'actions/u2i', null, $this->getAll());
- }
+ return $this->set("pio_latlng", sprintf("%s,%s", $lat, $lng));
+ }
+
+ /**
+ * Create the request object that will carry out the command. Used internally by Guzzle.
+ */
+ protected function build()
+ {
+ $this->set('pio_uid', $this->client->getIdentity());
+ $this->request = $this->client->createRequest(RequestInterface::POST, 'actions/u2i', null, $this->getAll());
+ }
}
-
-?>
\ No newline at end of file
diff --git a/src/PredictionIO/PredictionIOClient.php b/src/PredictionIO/PredictionIOClient.php
index 4717bb0..3a5f3e2 100644
--- a/src/PredictionIO/PredictionIOClient.php
+++ b/src/PredictionIO/PredictionIOClient.php
@@ -3,6 +3,7 @@
namespace PredictionIO;
use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Http\EntityBodyInterface;
use Guzzle\Common\Collection;
use Guzzle\Service\Client;
use Guzzle\Service\Command\AbstractCommand;
@@ -13,7 +14,8 @@
* This package is a web service client based on Guzzle.
* A few quick examples are shown below.
* For a full user guide on how to take advantage of all Guzzle features, please refer to http://guzzlephp.org.
- * Specifically, http://guzzlephp.org/tour/using_services.html#using-client-objects describes how to use a web service client.
+ * Specifically, http://guzzlephp.org/tour/using_services.html#using-client-objects describes
+ * how to use a web service client.
*
* Many REST request commands support optional arguments. They can be supplied to these commands using the set method.
*
@@ -52,93 +54,92 @@
*/
class PredictionIOClient extends Client
{
- private $apiuid = "";
+ private $apiuid = NULL;
- /**
- * Factory method to create a new PredictionIOClient
- *
- * Configuration data is an array with these keys:
- * * appkey - App key of your PredictionIO app (required)
- * * apiurl - URL of API endpoint (optional)
- *
- * @param array|Collection $config Configuration data.
- *
- * @return PredictionIOClient
- */
- public static function factory($config = array())
- {
- $default = array('apiurl' => 'http://localhost:8000');
- $required = array('appkey');
- $config = Collection::fromConfig($config, $default, $required);
+ /**
+ * Factory method to create a new PredictionIOClient
+ *
+ * Configuration data is an array with these keys:
+ * * appkey - App key of your PredictionIO app (required)
+ * * apiurl - URL of API endpoint (optional)
+ *
+ * @param array|Collection $config Configuration data.
+ *
+ * @return PredictionIOClient
+ */
+ public static function factory($config = array())
+ {
+ $default = array('apiurl' => 'http://localhost:8000');
+ $required = array('appkey');
+ $config = Collection::fromConfig($config, $default, $required);
- $client = new self($config->get('apiurl'), $config);
+ $client = new self($config->get('apiurl'), $config);
- return $client;
- }
-
- /**
- * Identify the user ID that will be used by all subsequent recording of actions on items, and recommendations retrieval.
- *
- * @param string $uid User ID.
- */
- public function identify($uid)
- {
- $this->apiuid = $uid;
- }
-
- /**
- * Returns the identity (user ID) that will be used by all subsequent recording of actions on items, and recommendations retrieval.
- *
- * @returns string
- */
- public function getIdentity()
- {
- if (empty($this->apiuid)) {
- throw new UnidentifiedUserException("Must call identify() before performing any user-related commands.");
- }
- return $this->apiuid;
- }
-
- /**
- * Create and return a new Guzzle\Http\Message\RequestInterface configured for the client.
- *
- * Used internally by the library. Do not use directly.
- *
- * @param string $method HTTP method. Default to GET.
- * @param string|array $uri Resource URI
- * @param array|Guzzle\Common\Collection $headers HTTP headers
- * @param string|resource|array|Guzzle\Http\EntityBodyInterface $body Entity body of request (POST/PUT) or response (GET)
- *
- * @returns Guzzle\Http\Message\RequestInterface
- */
- public function createRequest($method = Guzzle\Http\Message\RequestInterface::GET, $uri = null, $headers = null, $body = null)
- {
- if (is_array($body)) {
- $body['pio_appkey'] = $this->getConfig()->get("appkey");
- } else {
- $body = array('pio_appkey' => $this->getConfig()->get("appkey"));
+ return $client;
}
- // Remove Guzzle internals to prevent them from going to the API
- unset($body[AbstractCommand::HEADERS_OPTION]);
- unset($body[AbstractCommand::ON_COMPLETE]);
- unset($body[AbstractCommand::DISABLE_VALIDATION]);
- unset($body[AbstractCommand::RESPONSE_PROCESSING]);
- unset($body[AbstractCommand::RESPONSE_BODY]);
-
- if ($method == RequestInterface::GET ||
- $method == RequestInterface::DELETE) {
- $request = parent::createRequest($method, $uri, $headers, null);
- $request->getQuery()->replace($body);
- } else {
- $request = parent::createRequest($method, $uri, $headers, $body);
+ /**
+ * Identify the user ID that will be used by all subsequent
+ * recording of actions on items, and recommendations retrieval.
+ *
+ * @param string $uid User ID.
+ */
+ public function identify($uid)
+ {
+ $this->apiuid = $uid;
}
- $request->setPath($request->getPath() . ".json");
- return $request;
- }
-}
-/**
- * Thrown when user-related commands are called before identify() is called.
- */
-class UnidentifiedUserException extends \Exception { }
+ /**
+ * Returns the identity (user ID) that will be used by all subsequent
+ * recording of actions on items, and recommendations retrieval.
+ *
+ * @return string
+ * @throws UnidentifiedUserException
+ */
+ public function getIdentity()
+ {
+ if (!isset($this->apiuid)) {
+ throw new UnidentifiedUserException("Must call identify() before performing any user-related commands.");
+ }
+
+ return $this->apiuid;
+ }
+
+ /**
+ * Create and return a new RequestInterface configured for the client.
+ *
+ * Used internally by the library. Do not use directly.
+ *
+ * @param string $method HTTP method. Default to GET.
+ * @param string|array $uri Resource URI
+ * @param array|Collection $headers HTTP headers
+ * @param string|resource|array|EntityBodyInterface $body Entity body of request (POST/PUT) or response (GET)
+ *
+ * @return RequestInterface
+ */
+ public function createRequest($method = RequestInterface::GET, $uri = null, $headers = null, $body = null)
+ {
+ if (is_array($body)) {
+ $body['pio_appkey'] = $this->getConfig()->get("appkey");
+ } else {
+ $body = array('pio_appkey' => $this->getConfig()->get("appkey"));
+ }
+
+ // Remove Guzzle internals to prevent them from going to the API
+ unset($body[AbstractCommand::HEADERS_OPTION]);
+ unset($body[AbstractCommand::ON_COMPLETE]);
+ unset($body[AbstractCommand::DISABLE_VALIDATION]);
+ unset($body[AbstractCommand::RESPONSE_PROCESSING]);
+ unset($body[AbstractCommand::RESPONSE_BODY]);
+
+ if ($method == RequestInterface::GET || $method == RequestInterface::DELETE) {
+ $request = parent::createRequest($method, $uri, $headers, null);
+ $request->getQuery()->replace($body);
+ } else {
+ $request = parent::createRequest($method, $uri, $headers, $body);
+ }
+ $request->setPath($request->getPath() . ".json");
+
+ return $request;
+ }
+}
\ No newline at end of file
diff --git a/src/PredictionIO/UnidentifiedUserException.php b/src/PredictionIO/UnidentifiedUserException.php
new file mode 100644
index 0000000..637fda1
--- /dev/null
+++ b/src/PredictionIO/UnidentifiedUserException.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace PredictionIO;
+
+/**
+ * Thrown when user-related commands are called before identify() is called.
+ */
+class UnidentifiedUserException extends \Exception
+{
+
+}
diff --git a/tests/Unit/Command/CreateItemTest.php b/tests/Unit/Command/CreateItemTest.php
new file mode 100644
index 0000000..09d9a67
--- /dev/null
+++ b/tests/Unit/Command/CreateItemTest.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace PredictionIO\Tests\Unit\Command;
+
+use PredictionIO\Command\CreateItem;
+
+/**
+ * Class CreateItemTest
+ *
+ * @package PredictionIO\Tests\Unit\Command
+ */
+class CreateItemTest extends \PHPUnit_Framework_TestCase
+{
+ public function testCreateItemSetIid()
+ {
+ $mockIid = '1234';
+ $createItemCommand = new CreateItem();
+ $createItemCommand->setIid($mockIid);
+
+ $this->assertSame($mockIid, $createItemCommand->get('pio_iid'));
+ }
+
+ public function testCreateItemSetItypesImplodesAnArrayToCommaDelimitedString()
+ {
+ $mockTypes = array(
+ 'happy',
+ 'mocked',
+ 'types',
+ );
+ $createItemCommand = new CreateItem();
+ $createItemCommand->setItypes($mockTypes);
+
+ $this->assertSame(implode(',', $mockTypes), $createItemCommand->get('pio_itypes'));
+ }
+
+ public function testCreateItemSetItypesFromString()
+ {
+ $mockType = 'happy.mocked.type';
+ $createItemCommand = new CreateItem();
+ $createItemCommand->setItypes($mockType);
+
+ $this->assertSame($mockType, $createItemCommand->get('pio_itypes'));
+ }
+
+ public function testCreateItemSetStartTSuccess()
+ {
+ $mockStartT = 'mock.startT';
+ $createItemCommand = new CreateItem();
+ $createItemCommand->setStartT($mockStartT);
+
+ $this->assertSame($mockStartT, $createItemCommand->get('pio_startT'));
+ }
+
+ public function testCreateItemSetEndTSuccess()
+ {
+ $mockEndT = 'mock.endT';
+ $createItemCommand = new CreateItem();
+ $createItemCommand->setEndT($mockEndT);
+
+ $this->assertSame($mockEndT, $createItemCommand->get('pio_endT'));
+ }
+
+ public function testCreateItemSetPriceSuccess()
+ {
+ $mockPrice = '1234.56';
+ $createItemCommand = new CreateItem();
+ $createItemCommand->setPrice($mockPrice);
+
+ $this->assertSame($mockPrice, $createItemCommand->get('pio_price'));
+ }
+
+ public function testCreateItemSetProfitSuccess()
+ {
+ $mockProfit = '9876.54';
+ $createItemCommand = new CreateItem();
+ $createItemCommand->setProfit($mockProfit);
+
+ $this->assertSame($mockProfit, $createItemCommand->get('pio_profit'));
+ }
+
+ public function testCreateItemSetLatlngSuccess()
+ {
+ $mockLatlng = '20.17,114.08';
+ $createItemCommand = new CreateItem();
+ $createItemCommand->setLatlng($mockLatlng);
+
+ $this->assertSame($mockLatlng, $createItemCommand->get('pio_latlng'));
+ }
+
+ public function testCreateItemSetInactiveSuccess()
+ {
+ $mockInactive = 'true';
+ $createItemCommand = new CreateItem();
+ $createItemCommand->setInactive($mockInactive);
+
+ $this->assertSame($mockInactive, $createItemCommand->get('pio_inactive'));
+ }
+}
diff --git a/tests/Unit/Command/CreateUserTest.php b/tests/Unit/Command/CreateUserTest.php
new file mode 100644
index 0000000..15ff7ba
--- /dev/null
+++ b/tests/Unit/Command/CreateUserTest.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace PredictionIO\Tests\Unit\Command;
+
+use PredictionIO\Command\CreateUser;
+
+/**
+ * Class CreateUserTest
+ *
+ * @package PredictionIO\Tests\Unit\Command
+ */
+class CreateUserTest extends \PHPUnit_Framework_TestCase
+{
+ public function testCreateUserSetIid()
+ {
+ $mockUid = '1234';
+ $createUserCommand = new CreateUser();
+ $createUserCommand->setUid($mockUid);
+
+ $this->assertSame($mockUid, $createUserCommand->get('pio_uid'));
+ }
+
+ public function testCreateUserSetLatlngSuccess()
+ {
+ $mockLatlng = '20.17,114.08';
+ $createUserCommand = new CreateUser();
+ $createUserCommand->setLatlng($mockLatlng);
+
+ $this->assertSame($mockLatlng, $createUserCommand->get('pio_latlng'));
+ }
+
+ public function testCreateUserSetInactiveSuccess()
+ {
+ $mockInactive = 'true';
+ $createUserCommand = new CreateUser();
+ $createUserCommand->setInactive($mockInactive);
+
+ $this->assertSame($mockInactive, $createUserCommand->get('pio_inactive'));
+ }
+}
diff --git a/tests/Unit/Command/DeleteItemTest.php b/tests/Unit/Command/DeleteItemTest.php
new file mode 100644
index 0000000..5ab8cad
--- /dev/null
+++ b/tests/Unit/Command/DeleteItemTest.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace PredictionIO\Tests\Unit\Command;
+
+use PredictionIO\Command\DeleteItem;
+
+/**
+ * Class DeleteItemTest
+ *
+ * @package PredictionIO\Tests\Unit\Command
+ */
+class DeleteItemTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDeleteItemSetIid()
+ {
+ $mockIid = '1234';
+ $deleteItemCommand = new DeleteItem();
+ $deleteItemCommand->setIid($mockIid);
+
+ $this->assertSame($mockIid, $deleteItemCommand->get('pio_iid'));
+ }
+}
diff --git a/tests/Unit/Command/DeleteUserTest.php b/tests/Unit/Command/DeleteUserTest.php
new file mode 100644
index 0000000..4b92e02
--- /dev/null
+++ b/tests/Unit/Command/DeleteUserTest.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace PredictionIO\Tests\Unit\Command;
+
+use PredictionIO\Command\DeleteUser;
+
+/**
+ * Class DeleteUserTest
+ *
+ * @package PredictionIO\Tests\Unit\Command
+ */
+class DeleteUserTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDeleteUserSetIid()
+ {
+ $mockUid = '1234';
+ $deleteUserCommand = new DeleteUser();
+ $deleteUserCommand->setUid($mockUid);
+
+ $this->assertSame($mockUid, $deleteUserCommand->get('pio_uid'));
+ }
+}
diff --git a/tests/Unit/Command/GetItemTest.php b/tests/Unit/Command/GetItemTest.php
new file mode 100644
index 0000000..3609abd
--- /dev/null
+++ b/tests/Unit/Command/GetItemTest.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace PredictionIO\Tests\Unit\Command;
+
+use PredictionIO\Command\GetItem;
+
+/**
+ * Class GetItemTest
+ *
+ * @package PredictionIO\Tests\Unit\Command
+ */
+class GetItemTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetItemSetIid()
+ {
+ $mockIid = '1234';
+ $getItemCommand = new GetItem();
+ $getItemCommand->setIid($mockIid);
+
+ $this->assertSame($mockIid, $getItemCommand->get('pio_iid'));
+ }
+}
diff --git a/tests/Unit/Command/GetUserTest.php b/tests/Unit/Command/GetUserTest.php
new file mode 100644
index 0000000..0c6f8eb
--- /dev/null
+++ b/tests/Unit/Command/GetUserTest.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace PredictionIO\Tests\Unit\Command;
+
+use PredictionIO\Command\GetUser;
+
+/**
+ * Class GetUserTest
+ *
+ * @package PredictionIO\Tests\Unit\Command
+ */
+class GetUserTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetUserSetIid()
+ {
+ $mockUid = '1234';
+ $getUserCommand = new GetUser();
+ $getUserCommand->setUid($mockUid);
+
+ $this->assertSame($mockUid, $getUserCommand->get('pio_uid'));
+ }
+}
diff --git a/tests/Unit/PredictionIOClientTest.php b/tests/Unit/PredictionIOClientTest.php
new file mode 100644
index 0000000..2333eee
--- /dev/null
+++ b/tests/Unit/PredictionIOClientTest.php
@@ -0,0 +1,146 @@
+<?php
+
+namespace PredictionIO\Tests\Unit;
+
+use Guzzle\Common\Collection;
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Command\AbstractCommand;
+use PredictionIO\PredictionIOClient;
+
+/**
+ * Class PredictionIOClientTest
+ *
+ * @package PredictionIO\Tests
+ */
+class PredictionIOClientTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Guzzle\Common\Exception\InvalidArgumentException
+ * @expectedMessage Config must contain a 'appkey' key
+ */
+ public function testFactoryThrowsExceptionWithNoAppKey()
+ {
+ $config = array();
+ PredictionIOClient::factory($config);
+ }
+
+ public function testFactoryReturnsNewClient()
+ {
+ $config = array(
+ 'appkey' => 'mock.appkey',
+ );
+ $client = PredictionIOClient::factory($config);
+
+ $this->assertInstanceOf('\PredictionIO\PredictionIOClient', $client);
+ $this->assertSame($config['appkey'], $client->getConfig('appkey'));
+ }
+
+ public function testFactoryWithDefaultApiUrlSuccess()
+ {
+ $defaultApiUrl = 'http://localhost:8000';
+ $config = array(
+ 'appkey' => 'mock.appkey',
+ );
+ $client = PredictionIOClient::factory($config);
+
+ $this->assertSame($defaultApiUrl, $client->getConfig('apiurl'));
+ }
+
+ public function testFactoryWithDefinedApiUrlSuccess()
+ {
+ $config = array(
+ 'appkey' => 'mock.appkey',
+ 'apiurl' => 'http://mock.api:1234',
+ );
+ $client = PredictionIOClient::factory($config);
+
+ $this->assertSame($client->getConfig('apiurl'), $client->getConfig('apiurl'));
+ }
+
+ public function testFactoryWithCustomConfigSuccess()
+ {
+ $config = array(
+ 'appkey' => 'mock.appkey',
+ 'customconfig' => 'mock.option',
+ );
+ $client = PredictionIOClient::factory($config);
+
+ $this->assertSame($client->getConfig('customconfig'), $client->getConfig('customconfig'));
+ }
+
+ /**
+ * @expectedException \PredictionIO\UnidentifiedUserException
+ * @expectedExceptionMessage Must call identify() before performing any user-related commands.
+ */
+ public function testGetIdentityThrowsExceptionWhenNotSet()
+ {
+ $client = new PredictionIOClient();
+ $client->getIdentity();
+ }
+
+ public function testSetGetIdentitySuccess()
+ {
+ $mockId = "0";
+ $client = new PredictionIOClient();
+ $client->identify($mockId);
+
+ $this->assertSame($mockId, $client->getIdentity());
+ }
+
+ public function testCreateRequestReturnsRequestObject()
+ {
+ $client = new PredictionIOClient();
+ $request = $client->createRequest();
+
+ $this->assertInstanceOf('\Guzzle\Http\Message\Request', $request);
+ }
+
+ public function testCreateRequestSetMethodSuccess()
+ {
+ $mockMethod = RequestInterface::POST;
+ $client = new PredictionIOClient();
+ $request = $client->createRequest($mockMethod);
+
+ $this->assertSame($mockMethod, $request->getMethod());
+ }
+
+ public function testCreateRequestSetUriSuccess()
+ {
+ $mockUri = 'http://mock.uri/method';
+ $expectedUri = $mockUri.'.json?pio_appkey=';
+ $client = new PredictionIOClient();
+ $request = $client->createRequest(RequestInterface::GET, $mockUri);
+
+ $this->assertSame($expectedUri, $request->getUrl());
+ }
+
+ public function testCreateRequestSetHeadersSuccess()
+ {
+ $headers = array(
+ 'mock.header' => 'mock.value',
+ );
+ $client = new PredictionIOClient();
+ $request = $client->createRequest(RequestInterface::GET, null, $headers);
+
+ $this->assertTrue($request->getHeader('mock.header')->hasValue($headers['mock.header']));
+ }
+
+ public function testCreateRequestUnsetsGuzzleInternals()
+ {
+ $body = array(
+ AbstractCommand::HEADERS_OPTION => 'mock.HEADERS_OPTION',
+ AbstractCommand::ON_COMPLETE => 'mock.ON_COMPLETE',
+ AbstractCommand::DISABLE_VALIDATION => 'mock.DISABLE_VALIDATION',
+ AbstractCommand::RESPONSE_PROCESSING => 'mock.RESPONSE_PROCESSING',
+ AbstractCommand::RESPONSE_BODY => 'mock.RESPONSE_BODY',
+ );
+ $client = new PredictionIOClient();
+ $request = $client->createRequest(RequestInterface::GET, null, null, $body);
+
+ $this->assertNull($request->getQuery()->get(AbstractCommand::HEADERS_OPTION));
+ $this->assertNull($request->getQuery()->get(AbstractCommand::ON_COMPLETE));
+ $this->assertNull($request->getQuery()->get(AbstractCommand::DISABLE_VALIDATION));
+ $this->assertNull($request->getQuery()->get(AbstractCommand::RESPONSE_PROCESSING));
+ $this->assertNull($request->getQuery()->get(AbstractCommand::RESPONSE_BODY));
+ }
+}