diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..252a1c6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +License: +======== +The MIT License (MIT) +http://opensource.org/licenses/MIT + +Copyright (c) 2014 - 2016 APIMATIC Limited + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Trade Mark: +========== +APIMATIC is a trade mark for APIMATIC Limited \ No newline at end of file diff --git a/README.md b/README.md new file mode 100755 index 0000000..8fe1018 --- /dev/null +++ b/README.md @@ -0,0 +1,359 @@ +# Getting started + +Taplytics decisions is an API to quickly use Taplytics features and functionality at edge. + +## How to Build + +The generated code has dependencies over external libraries like UniRest. These dependencies are defined in the ```composer.json``` file that comes with the SDK. +To resolve these dependencies, we use the Composer package manager which requires PHP greater than 5.3.2 installed in your system. +Visit [https://getcomposer.org/download/](https://getcomposer.org/download/) to download the installer file for Composer and run it in your system. +Open command prompt and type ```composer --version```. This should display the current version of the Composer installed if the installation was successful. + +* Using command line, navigate to the directory containing the generated files (including ```composer.json```) for the SDK. +* Run the command ```composer install```. This should install all the required dependencies and create the ```vendor``` directory in your project directory. + +![Building SDK - Step 1](https://apidocs.io/illustration/php?step=installDependencies&workspaceFolder=Taplytics-PHP) + +### [For Windows Users Only] Configuring CURL Certificate Path in php.ini + +CURL used to include a list of accepted CAs, but no longer bundles ANY CA certs. So by default it will reject all SSL certificates as unverifiable. You will have to get your CA's cert and point curl at it. The steps are as follows: + +1. Download the certificate bundle (.pem file) from [https://curl.haxx.se/docs/caextract.html](https://curl.haxx.se/docs/caextract.html) on to your system. +2. Add curl.cainfo = "PATH_TO/cacert.pem" to your php.ini file located in your php installation. “PATH_TO” must be an absolute path containing the .pem file. + +```ini +[curl] +; A default value for the CURLOPT_CAINFO option. This is required to be an +; absolute path. +;curl.cainfo = +``` + +## How to Use + +The following section explains how to use the Taplytics library in a new project. + +### 1. Open Project in an IDE + +Open an IDE for PHP like PhpStorm. The basic workflow presented here is also applicable if you prefer using a different editor or IDE. + +![Open project in PHPStorm - Step 1](https://apidocs.io/illustration/php?step=openIDE&workspaceFolder=Taplytics-PHP) + +Click on ```Open``` in PhpStorm to browse to your generated SDK directory and then click ```OK```. + +![Open project in PHPStorm - Step 2](https://apidocs.io/illustration/php?step=openProject0&workspaceFolder=Taplytics-PHP) + +### 2. Add a new Test Project + +Create a new directory by right clicking on the solution name as shown below: + +![Add a new project in PHPStorm - Step 1](https://apidocs.io/illustration/php?step=createDirectory&workspaceFolder=Taplytics-PHP) + +Name the directory as "test" + +![Add a new project in PHPStorm - Step 2](https://apidocs.io/illustration/php?step=nameDirectory&workspaceFolder=Taplytics-PHP) + +Add a PHP file to this project + +![Add a new project in PHPStorm - Step 3](https://apidocs.io/illustration/php?step=createFile&workspaceFolder=Taplytics-PHP) + +Name it "testSDK" + +![Add a new project in PHPStorm - Step 4](https://apidocs.io/illustration/php?step=nameFile&workspaceFolder=Taplytics-PHP) + +Depending on your project setup, you might need to include composer's autoloader in your PHP code to enable auto loading of classes. + +```PHP +require_once "../vendor/autoload.php"; +``` + +It is important that the path inside require_once correctly points to the file ```autoload.php``` inside the vendor directory created during dependency installations. + +![Add a new project in PHPStorm - Step 4](https://apidocs.io/illustration/php?step=projectFiles&workspaceFolder=Taplytics-PHP) + +After this you can add code to initialize the client library and acquire the instance of a Controller class. Sample code to initialize the client library and using controller methods is given in the subsequent sections. + +### 3. Run the Test Project + +To run your project you must set the Interpreter for your project. Interpreter is the PHP engine installed on your computer. + +Open ```Settings``` from ```File``` menu. + +![Run Test Project - Step 1](https://apidocs.io/illustration/php?step=openSettings&workspaceFolder=Taplytics-PHP) + +Select ```PHP``` from within ```Languages & Frameworks``` + +![Run Test Project - Step 2](https://apidocs.io/illustration/php?step=setInterpreter0&workspaceFolder=Taplytics-PHP) + +Browse for Interpreters near the ```Interpreter``` option and choose your interpreter. + +![Run Test Project - Step 3](https://apidocs.io/illustration/php?step=setInterpreter1&workspaceFolder=Taplytics-PHP) + +Once the interpreter is selected, click ```OK``` + +![Run Test Project - Step 4](https://apidocs.io/illustration/php?step=setInterpreter2&workspaceFolder=Taplytics-PHP) + +To run your project, right click on your PHP file inside your Test project and click on ```Run``` + +![Run Test Project - Step 5](https://apidocs.io/illustration/php?step=runProject&workspaceFolder=Taplytics-PHP) + +## How to Test + +Unit tests in this SDK can be run using PHPUnit. + +1. First install the dependencies using composer including the `require-dev` dependencies. +2. Run `vendor\bin\phpunit --verbose` from commandline to execute tests. If you have + installed PHPUnit globally, run tests using `phpunit --verbose` instead. + +You can change the PHPUnit test configuration in the `phpunit.xml` file. + +## Initialization + +### + +API client can be initialized as following. + +```php + +$client = new TaplyticsLib\TaplyticsClient(); +``` + + +# Class Reference + +## List of Controllers + +* [APIController](#api_controller) + +## ![Class: ](https://apidocs.io/img/class.png ".APIController") APIController + +### Get singleton instance + +The singleton instance of the ``` APIController ``` class can be accessed from the API Client. + +```php +$client = $client->getClient(); +``` + +### ![Method: ](https://apidocs.io/img/method.png ".APIController.createGetVariables") createGetVariables + +> All variables and their values for the given user + + +```php +function createGetVariables( + $token, + $userId, + $body = null) +``` + +#### Parameters + +| Parameter | Tags | Description | +|-----------|------|-------------| +| token | ``` Required ``` | SDK token for the project | +| userId | ``` Required ``` | ID for given user | +| body | ``` Optional ``` | All relevant attributes associated with the user | + + + +#### Example Usage + +```php +$token = 'token'; +$userId = 'user_id'; +$body = new Body(); + +$result = $client->createGetVariables($token, $userId, $body); + +``` + + +### ![Method: ](https://apidocs.io/img/method.png ".APIController.createGetVariationForExperiment") createGetVariationForExperiment + +> *Tags:* ``` Skips Authentication ``` + +> For a given experiment, determine whether or not a user is in the experiment, and in which variation + + +```php +function createGetVariationForExperiment( + $token, + $userId, + $experimentName, + $body = null) +``` + +#### Parameters + +| Parameter | Tags | Description | +|-----------|------|-------------| +| token | ``` Required ``` | SDK token for the project | +| userId | ``` Required ``` | ID for given user | +| experimentName | ``` Required ``` | Name of an Experiment | +| body | ``` Optional ``` | All relevant attributes associated with the user | + + + +#### Example Usage + +```php +$token = 'token'; +$userId = 'user_id'; +$experimentName = 'experimentName'; +$body = new Body(); + +$result = $client->createGetVariationForExperiment($token, $userId, $experimentName, $body); + +``` + + +### ![Method: ](https://apidocs.io/img/method.png ".APIController.createGetVariableValue") createGetVariableValue + +> *Tags:* ``` Skips Authentication ``` + +> Value for given Taplytics Dynamic Variable. If a user is not in an experiment containing the variable, the response be the provided default value in the query params. + + +```php +function createGetVariableValue( + $token, + $userId, + $varName, + $defaultValue, + $body = null) +``` + +#### Parameters + +| Parameter | Tags | Description | +|-----------|------|-------------| +| token | ``` Required ``` | SDK token for the project | +| userId | ``` Required ``` | ID for given user | +| varName | ``` Required ``` | name of variable | +| defaultValue | ``` Required ``` | default value to be used if user does not have variable available. | +| body | ``` Optional ``` | All relevant attributes associated with the user | + + + +#### Example Usage + +```php +$token = 'token'; +$userId = 'user_id'; +$varName = 'varName'; +$defaultValue = 'defaultValue'; +$body = new Body(); + +$result = $client->createGetVariableValue($token, $userId, $varName, $defaultValue, $body); + +``` + + +### ![Method: ](https://apidocs.io/img/method.png ".APIController.createGetBucketing") createGetBucketing + +> Returns a key/value pairing of all experiments that the user has been segmented into, as well as the variation the users are assigned. + + +```php +function createGetBucketing( + $token, + $userId, + $body = null) +``` + +#### Parameters + +| Parameter | Tags | Description | +|-----------|------|-------------| +| token | ``` Required ``` | SDK token for the project | +| userId | ``` Required ``` | ID for current user | +| body | ``` Optional ``` | Provide all relevant attributes associated with the user | + + + +#### Example Usage + +```php +$token = 'token'; +$userId = 'user_id'; +$body = new Body(); + +$result = $client->createGetBucketing($token, $userId, $body); + +``` + + +### ![Method: ](https://apidocs.io/img/method.png ".APIController.postEvent") postEvent + +> *Tags:* ``` Skips Authentication ``` + +> Send an event to Taplytics. These events are then used to compare against an experiment's goals to determine the success of an A/B test. + + +```php +function postEvent( + $token, + $userId, + $body = null) +``` + +#### Parameters + +| Parameter | Tags | Description | +|-----------|------|-------------| +| token | ``` Required ``` | SDK token for the project | +| userId | ``` Required ``` | ID for given user | +| body | ``` Optional ``` | Provide an array of events, as well as all additional relevant user attributes. | + + + +#### Example Usage + +```php +$token = 'token'; +$userId = 'user_id'; +$body = new EventsBody(); + +$result = $client->postEvent($token, $userId, $body); + +``` + + +### ![Method: ](https://apidocs.io/img/method.png ".APIController.createGetConfig") createGetConfig + +> Returns the entire configuration for the project. This is the document that informs the experiment information such as segmentation. Extremely verbose and should be used for debugging. + + +```php +function createGetConfig( + $token, + $userId, + $body = null) +``` + +#### Parameters + +| Parameter | Tags | Description | +|-----------|------|-------------| +| token | ``` Required ``` | SDK token for the project | +| userId | ``` Required ``` | ID for given user | +| body | ``` Optional ``` | All relevant attributes associated with the user | + + + +#### Example Usage + +```php +$token = 'token'; +$userId = 'user_id'; +$body = new Body(); + +$result = $client->createGetConfig($token, $userId, $body); + +``` + + +[Back to List of Controllers](#list_of_controllers) + + + diff --git a/composer.json b/composer.json new file mode 100755 index 0000000..18e3f05 --- /dev/null +++ b/composer.json @@ -0,0 +1,32 @@ +{ + "name": "taplytics/decisions", + "type": "library", + "description": "Taplytics decisions is an API to quickly use Taplytics features and functionality at edge.", + "keywords": ["Taplytics Decisions API","API","SDK"], + "homepage": "https://apimatic.io", + "license": "MIT", + "authors": [ + { + "name": "APIMatic SDK Generator", + "email": "support@apimatic.io", + "homepage": "https://apimatic.io", + "role": "API Tool" + } + ], + "require": { + "php": ">=5.4.0", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "mashape/unirest-php": "~3.0.1", + "apimatic/jsonmapper": "~1.3.0" + }, + "require-dev": { + "squizlabs/php_codesniffer": "^2.7" + }, + "autoload": { + "psr-4": { + "TaplyticsLib\\": "src/" + } + } +} \ No newline at end of file diff --git a/src/APIException.php b/src/APIException.php new file mode 100755 index 0000000..c64821a --- /dev/null +++ b/src/APIException.php @@ -0,0 +1,88 @@ +getResponse()->getStatusCode()); + $this->context = $context; + $this->errorMessage = $reason; + + if (get_class() != 'APIException') { + $this->unbox(); + } + } + + /** + * Unbox response into this exception class + */ + public function unbox() + { + } + + /** + * The HTTP context from the API request + * @return Http\HttpContext + */ + public function getContext() + { + return $this->context; + } + + /** + * The HTTP response code from the API request + * @return int + */ + public function getResponseCode() + { + return $this->context->getResponse()->getStatusCode(); + } + + /** + * The HTTP response body from the API request + * @return mixed + */ + public function getResponseBody() + { + return $this->context->getResponse()->getRawBody(); + } + + /** + * The reason for raising an exception + * @return string + */ + public function getReason() + { + return $this->message; + } +} diff --git a/src/APIHelper.php b/src/APIHelper.php new file mode 100755 index 0000000..efc2408 --- /dev/null +++ b/src/APIHelper.php @@ -0,0 +1,170 @@ + $value) { + $replaceValue = ''; + + //load parameter value + if (is_null($value)) { + $replaceValue = ''; + } elseif (is_array($value)) { + $replaceValue = implode("/", array_map("urlencode", $value)); + } else { + $replaceValue = urlencode(strval($value)); + } + + //find the template parameter and replace it with its value + $url = str_replace('{' . strval($key) . '}', $replaceValue, $url); + } + + return $url; + } + + /** + * Appends the given set of parameters to the given query string + * @param string $queryBuilder The query url string to append the parameters + * @param array $parameters The parameters to append + * @return void + */ + public static function appendUrlWithQueryParameters(&$queryBuilder, $parameters) + { + //perform parameter validation + if (is_null($queryBuilder) || !is_string($queryBuilder)) { + throw new InvalidArgumentException('Given value for parameter "queryBuilder" is invalid.'); + } + if (is_null($parameters)) { + return; + } + //does the query string already has parameters + $hasParams = (strrpos($queryBuilder, '?') > 0); + + //if already has parameters, use the & to append new parameters + $queryBuilder = $queryBuilder . (($hasParams) ? '&' : '?'); + + //append parameters + $queryBuilder = $queryBuilder . http_build_query($parameters); + } + + /** + * Validates and processes the given Url + * @param string $url The given Url to process + * @return string Pre-processed Url as string */ + public static function cleanUrl($url) + { + //perform parameter validation + if (is_null($url) || !is_string($url)) { + throw new InvalidArgumentException('Invalid Url.'); + } + //ensure that the urls are absolute + $matchCount = preg_match("#^(https?://[^/]+)#", $url, $matches); + if ($matchCount == 0) { + throw new InvalidArgumentException('Invalid Url format.'); + } + //get the http protocol match + $protocol = $matches[1]; + + //remove redundant forward slashes + $query = substr($url, strlen($protocol)); + $query = preg_replace("#//+#", "/", $query); + + //return process url + return $protocol.$query; + } + + /** + * Deserialize a Json string + * @param string $json A valid Json string + * @param mixed $instance Instance of an object to map the json into + * @param boolean $isArray Is the Json an object array? + * @return mixed Decoded Json + */ + public static function deserialize($json, $instance = null, $isArray = false) + { + if ($instance == null) { + return json_decode($json, true); + } else { + $mapper = new \apimatic\jsonmapper\JsonMapper(); + if ($isArray) { + return $mapper->mapArray(json_decode($json), array(), $instance); + } else { + return $mapper->map(json_decode($json), $instance); + } + } + } + + /** + * Check if an array isAssociative (has string keys) + * @param array $array A valid array + * @return boolean True if the array is Associative, false if it is Indexed + */ + private static function isAssociative($arr) + { + foreach ($arr as $key => $value) { + if (is_string($key)) { + return true; + } + } + + return false; + } + + /** + * Prepare a model for form encoding + * @param JsonSerializable $model A valid instance of JsonSerializable + * @return array The model as a map of key value pairs + */ + public static function prepareFormFields($model) + { + if (!$model instanceof JsonSerializable) { + return $model; + } + + $arr = $model->jsonSerialize(); + + foreach ($model as $key => $value) { + if ($value instanceof JsonSerializable) { + $arr[$key] = static::prepareFormFields($model->$key); + } elseif (is_array($value) && !empty($value) && !static::isAssociative($value) && + $value[0] instanceof JsonSerializable) { + $temp = array(); + foreach ($value as $k => $v) { + $temp[$k] = static::prepareFormFields($v); + } + $arr[$key] = $temp; + } + } + return $arr; + } +} diff --git a/src/Configuration.php b/src/Configuration.php new file mode 100755 index 0000000..7086045 --- /dev/null +++ b/src/Configuration.php @@ -0,0 +1,21 @@ + $token, + 'user_id' => $userId, + )); + + //validate and preprocess url + $_queryUrl = APIHelper::cleanUrl($_queryBuilder); + + //prepare headers + $_headers = array ( + 'user-agent' => 'taplytics', + 'Accept' => 'application/json', + 'content-type' => 'application/json; charset=utf-8' + ); + + //call on-before Http callback + $_httpRequest = new HttpRequest(HttpMethod::POST, $_headers, $_queryUrl); + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnBeforeRequest($_httpRequest); + } + + //and invoke the API call request to fetch the response + $response = Request::post($_queryUrl, $_headers, Request\Body::Json($body)); + + $_httpResponse = new HttpResponse($response->code, $response->headers, $response->raw_body); + $_httpContext = new HttpContext($_httpRequest, $_httpResponse); + + //call on-after Http callback + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnAfterRequest($_httpContext); + } + + //handle errors defined at the API level + $this->validateResponse($_httpResponse, $_httpContext); + + $mapper = $this->getJsonMapper(); + + return $mapper->mapClassArray($response->body, 'TaplyticsLib\\Models\\Variable'); + } + + /** + * For a given experiment, determine whether or not a user is in the experiment, and in which + * variation + * + * @param string $token SDK token for the project + * @param string $userId ID for given user + * @param string $experimentName Name of an Experiment + * @param Models\Body $body (optional) All relevant attributes associated with the user + * @return string response from the API call + * @throws APIException Thrown if API call fails + */ + public function createGetVariationForExperiment( + $token, + $userId, + $experimentName, + $body = null + ) { + + //the base uri for api requests + $_queryBuilder = Configuration::$BASEURI; + + //prepare query string for API call + $_queryBuilder = $_queryBuilder.'/variation'; + + //process optional query parameters + APIHelper::appendUrlWithQueryParameters($_queryBuilder, array ( + 'token' => $token, + 'user_id' => $userId, + 'experimentName' => $experimentName, + )); + + //validate and preprocess url + $_queryUrl = APIHelper::cleanUrl($_queryBuilder); + + //prepare headers + $_headers = array ( + 'user-agent' => 'taplytics', + 'content-type' => 'application/json; charset=utf-8' + ); + + //call on-before Http callback + $_httpRequest = new HttpRequest(HttpMethod::POST, $_headers, $_queryUrl); + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnBeforeRequest($_httpRequest); + } + + //and invoke the API call request to fetch the response + $response = Request::post($_queryUrl, $_headers, Request\Body::Json($body)); + + $_httpResponse = new HttpResponse($response->code, $response->headers, $response->raw_body); + $_httpContext = new HttpContext($_httpRequest, $_httpResponse); + + //call on-after Http callback + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnAfterRequest($_httpContext); + } + + //handle errors defined at the API level + $this->validateResponse($_httpResponse, $_httpContext); + + return $response->body; + } + + /** + * Value for given Taplytics Dynamic Variable. If a user is not in an experiment containing the + * variable, the response be the provided default value in the query params. + * + * @param string $token SDK token for the project + * @param string $userId ID for given user + * @param string $varName name of variable + * @param string $defaultValue default value to be used if user does not have variable available. + * @param Models\Body $body (optional) All relevant attributes associated with the user + * @return mixed response from the API call + * @throws APIException Thrown if API call fails + */ + public function createGetVariableValue( + $token, + $userId, + $varName, + $defaultValue, + $body = null + ) { + + //the base uri for api requests + $_queryBuilder = Configuration::$BASEURI; + + //prepare query string for API call + $_queryBuilder = $_queryBuilder.'/variablevalue'; + + //process optional query parameters + APIHelper::appendUrlWithQueryParameters($_queryBuilder, array ( + 'token' => $token, + 'user_id' => $userId, + 'varName' => $varName, + 'defaultValue' => $defaultValue, + )); + + //validate and preprocess url + $_queryUrl = APIHelper::cleanUrl($_queryBuilder); + + //prepare headers + $_headers = array ( + 'user-agent' => 'taplytics', + 'Accept' => 'application/json', + 'content-type' => 'application/json; charset=utf-8' + ); + + //call on-before Http callback + $_httpRequest = new HttpRequest(HttpMethod::POST, $_headers, $_queryUrl); + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnBeforeRequest($_httpRequest); + } + + //and invoke the API call request to fetch the response + $response = Request::post($_queryUrl, $_headers, Request\Body::Json($body)); + + $_httpResponse = new HttpResponse($response->code, $response->headers, $response->raw_body); + $_httpContext = new HttpContext($_httpRequest, $_httpResponse); + + //call on-after Http callback + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnAfterRequest($_httpContext); + } + + //handle errors defined at the API level + $this->validateResponse($_httpResponse, $_httpContext); + + return $response->body; + } + + /** + * Returns a key/value pairing of all experiments that the user has been segmented into, as well as the + * variation the users are assigned. + * + * @param string $token SDK token for the project + * @param string $userId ID for current user + * @param Models\Body $body (optional) Provide all relevant attributes associated with the user + * @return mixed response from the API call + * @throws APIException Thrown if API call fails + */ + public function createGetBucketing( + $token, + $userId, + $body = null + ) { + + //the base uri for api requests + $_queryBuilder = Configuration::$BASEURI; + + //prepare query string for API call + $_queryBuilder = $_queryBuilder.'/bucketing'; + + //process optional query parameters + APIHelper::appendUrlWithQueryParameters($_queryBuilder, array ( + 'token' => $token, + 'user_id' => $userId, + )); + + //validate and preprocess url + $_queryUrl = APIHelper::cleanUrl($_queryBuilder); + + //prepare headers + $_headers = array ( + 'user-agent' => 'taplytics', + 'Accept' => 'application/json', + 'content-type' => 'application/json; charset=utf-8' + ); + + //call on-before Http callback + $_httpRequest = new HttpRequest(HttpMethod::POST, $_headers, $_queryUrl); + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnBeforeRequest($_httpRequest); + } + + //and invoke the API call request to fetch the response + $response = Request::post($_queryUrl, $_headers, Request\Body::Json($body)); + + $_httpResponse = new HttpResponse($response->code, $response->headers, $response->raw_body); + $_httpContext = new HttpContext($_httpRequest, $_httpResponse); + + //call on-after Http callback + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnAfterRequest($_httpContext); + } + + //handle errors defined at the API level + $this->validateResponse($_httpResponse, $_httpContext); + + return $response->body; + } + + /** + * Send an event to Taplytics. These events are then used to compare against an experiment's goals to + * determine the success of an A/B test. + * + * @param string $token SDK token for the project + * @param string $userId ID for given user + * @param Models\EventsBody $body (optional) Provide an array of events, as well as all additional relevant user + * attributes. + * @return mixed response from the API call + * @throws APIException Thrown if API call fails + */ + public function postEvent( + $token, + $userId, + $body = null + ) { + + //the base uri for api requests + $_queryBuilder = Configuration::$BASEURI; + + //prepare query string for API call + $_queryBuilder = $_queryBuilder.'/events'; + + //process optional query parameters + APIHelper::appendUrlWithQueryParameters($_queryBuilder, array ( + 'token' => $token, + 'user_id' => $userId, + )); + + //validate and preprocess url + $_queryUrl = APIHelper::cleanUrl($_queryBuilder); + + //prepare headers + $_headers = array ( + 'user-agent' => 'taplytics', + 'Accept' => 'application/json', + 'content-type' => 'application/json; charset=utf-8' + ); + + //call on-before Http callback + $_httpRequest = new HttpRequest(HttpMethod::POST, $_headers, $_queryUrl); + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnBeforeRequest($_httpRequest); + } + + //and invoke the API call request to fetch the response + $response = Request::post($_queryUrl, $_headers, Request\Body::Json($body)); + + $_httpResponse = new HttpResponse($response->code, $response->headers, $response->raw_body); + $_httpContext = new HttpContext($_httpRequest, $_httpResponse); + + //call on-after Http callback + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnAfterRequest($_httpContext); + } + + //handle errors defined at the API level + $this->validateResponse($_httpResponse, $_httpContext); + + return $response->body; + } + + /** + * Returns the entire configuration for the project. This is the document that informs the experiment + * information such as segmentation. Extremely verbose and should be used for debugging. + * + * @param string $token SDK token for the project + * @param string $userId ID for given user + * @param Models\Body $body (optional) All relevant attributes associated with the user + * @return mixed response from the API call + * @throws APIException Thrown if API call fails + */ + public function createGetConfig( + $token, + $userId, + $body = null + ) { + + //the base uri for api requests + $_queryBuilder = Configuration::$BASEURI; + + //prepare query string for API call + $_queryBuilder = $_queryBuilder.'/config'; + + //process optional query parameters + APIHelper::appendUrlWithQueryParameters($_queryBuilder, array ( + 'token' => $token, + 'user_id' => $userId, + )); + + //validate and preprocess url + $_queryUrl = APIHelper::cleanUrl($_queryBuilder); + + //prepare headers + $_headers = array ( + 'user-agent' => 'taplytics', + 'Accept' => 'application/json', + 'content-type' => 'application/json; charset=utf-8' + ); + + //call on-before Http callback + $_httpRequest = new HttpRequest(HttpMethod::POST, $_headers, $_queryUrl); + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnBeforeRequest($_httpRequest); + } + + //and invoke the API call request to fetch the response + $response = Request::post($_queryUrl, $_headers, Request\Body::Json($body)); + + $_httpResponse = new HttpResponse($response->code, $response->headers, $response->raw_body); + $_httpContext = new HttpContext($_httpRequest, $_httpResponse); + + //call on-after Http callback + if ($this->getHttpCallBack() != null) { + $this->getHttpCallBack()->callOnAfterRequest($_httpContext); + } + + //handle errors defined at the API level + $this->validateResponse($_httpResponse, $_httpContext); + + return $response->body; + } +} diff --git a/src/Controllers/BaseController.php b/src/Controllers/BaseController.php new file mode 100755 index 0000000..91fb861 --- /dev/null +++ b/src/Controllers/BaseController.php @@ -0,0 +1,67 @@ +httpCallBack = $httpCallBack; + } + + /** + * Get HttpCallBack for this controller + * @return HttpCallBack The HttpCallBack object set for this controller + */ + public function getHttpCallBack() + { + return $this->httpCallBack; + } + + /** + * Get a new JsonMapper instance for mapping objects + * @return \apimatic\jsonmapper\JsonMapper JsonMapper instance + */ + protected function getJsonMapper() + { + $mapper = new JsonMapper(); + return $mapper; + } + + protected function validateResponse(HttpResponse $response, HttpContext $_httpContext) + { + if (($response->getStatusCode() < 200) || ($response->getStatusCode() > 208)) { //[200,208] = HTTP OK + throw new APIException('HTTP Response Not OK', $_httpContext); + } + } +} diff --git a/src/Http/HttpCallBack.php b/src/Http/HttpCallBack.php new file mode 100755 index 0000000..93ab582 --- /dev/null +++ b/src/Http/HttpCallBack.php @@ -0,0 +1,95 @@ +onBeforeRequest = $onBeforeRequest; + $this->onAfterRequest = $onAfterRequest; + } + + /** + * Set on-before event callback + * @param callable $func On-before event callable + */ + public function setOnBeforeRequest(callable $func) + { + $this->onBeforeRequest = $func; + } + + /** + * Get On-before API call event callable + * @return callable Callable + */ + public function getOnBeforeRequest() + { + return $this->onBeforeRequest; + } + + /** + * Set On-after API call event callable + * @param callable $func On-after event callable + */ + public function setOnAfterRequest(callable $func) + { + $this->onAfterRequest = $func; + } + + /** + * Get On-After API call event callable + * @return callable On-after event callable + */ + public function getOnAfterRequest() + { + return $this->onAfterRequest; + } + + /** + * Call on-before event callable + * @param HttpRequest $httpRequest HttpRequest for this call + */ + public function callOnBeforeRequest(HttpRequest $httpRequest) + { + if ($this->onBeforeRequest != null) { + call_user_func($this->onBeforeRequest, $httpRequest); + } + } + + /** + * Call on-after event callable + * @param HttpRequest $httpRequest HttpRequest for this call + */ + public function callOnAfterRequest(HttpContext $httpContext) + { + if ($this->onAfterRequest != null) { + call_user_func($this->onAfterRequest, $httpContext); + } + } +} diff --git a/src/Http/HttpContext.php b/src/Http/HttpContext.php new file mode 100755 index 0000000..7e87d3e --- /dev/null +++ b/src/Http/HttpContext.php @@ -0,0 +1,55 @@ +request = $request; + $this->response = $response; + } + + /** + * Getter for the Http Request + * @return HttpRequest request + */ + public function getRequest() + { + return $this->request; + } + + /** + * Getter for the Http Response + * @return HttpResponse response + */ + public function getResponse() + { + return $this->response; + } +} diff --git a/src/Http/HttpMethod.php b/src/Http/HttpMethod.php new file mode 100755 index 0000000..2070140 --- /dev/null +++ b/src/Http/HttpMethod.php @@ -0,0 +1,21 @@ +httpMethod = $httpMethod; + $this->headers = $headers; + $this->queryUrl = $queryUrl; + $this->parameters = $parameters; + } + + /** + * Get http method + * @return string + */ + public function getHttpMethod() + { + return $this->httpMethod; + } + + /** + * Set http method + * @param string $httpMethod Http Method as defined in HttpMethod class + */ + public function setHttpMethod($httpMethod) + { + $this->httpMethod = $httpMethod; + } + + /** + * Get headers + * @return array Map of headers + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Set headers + * @param array $headers Headers as map + */ + public function setHeaders(array $headers) + { + $this->headers = $headers; + } + + /** + * Get query url + * @return string Query url + */ + public function getQueryUrl() + { + return $this->queryUrl; + } + + /** + * Set query url + * @param string $queryUrl Query url + */ + public function setQueryUrl($queryUrl) + { + $this->queryUrl = $queryUrl; + } + + /** + * Get parameters + * @return array Map of input parameters + */ + public function getParameters() + { + return $this->parameters; + } + + /** + * Set parameters + * @param array $parameters Map of input parameters + */ + public function setParameters($parameters) + { + $this->parameters = $parameters; + } +} diff --git a/src/Http/HttpResponse.php b/src/Http/HttpResponse.php new file mode 100755 index 0000000..a5f41b5 --- /dev/null +++ b/src/Http/HttpResponse.php @@ -0,0 +1,72 @@ +statusCode = $statusCode; + $this->headers = $headers; + $this->rawBody = $rawBody; + } + + /** + * Get status code + * @return int Status code + */ + public function getStatusCode() + { + return $this->statusCode; + } + + /** + * Get headers + * @return array Map of headers + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Get raw response body + * @return string Raw body + */ + public function getRawBody() + { + return $this->rawBody; + } +} diff --git a/src/Models/Attributes.php b/src/Models/Attributes.php new file mode 100755 index 0000000..4300dce --- /dev/null +++ b/src/Models/Attributes.php @@ -0,0 +1,90 @@ +email + * @param string $firstName Initialization value for $this->firstName + * @param string $lastName Initialization value for $this->lastName + * @param string $name Initialization value for $this->name + * @param double $age Initialization value for $this->age + * @param object $customData Initialization value for $this->customData + */ + public function __construct() + { + if (6 == func_num_args()) { + $this->email = func_get_arg(0); + $this->firstName = func_get_arg(1); + $this->lastName = func_get_arg(2); + $this->name = func_get_arg(3); + $this->age = func_get_arg(4); + $this->customData = func_get_arg(5); + } + } + + + /** + * Encode this object to JSON + */ + public function jsonSerialize() + { + $json = array(); + $json['email'] = $this->email; + $json['firstName'] = $this->firstName; + $json['lastName'] = $this->lastName; + $json['name'] = $this->name; + $json['age'] = $this->age; + $json['customData'] = $this->customData; + + return $json; + } +} diff --git a/src/Models/Body.php b/src/Models/Body.php new file mode 100755 index 0000000..0fb7643 --- /dev/null +++ b/src/Models/Body.php @@ -0,0 +1,45 @@ +attributes + */ + public function __construct() + { + if (1 == func_num_args()) { + $this->attributes = func_get_arg(0); + } + } + + + /** + * Encode this object to JSON + */ + public function jsonSerialize() + { + $json = array(); + $json['attributes'] = $this->attributes; + + return $json; + } +} diff --git a/src/Models/Event.php b/src/Models/Event.php new file mode 100755 index 0000000..1db8849 --- /dev/null +++ b/src/Models/Event.php @@ -0,0 +1,64 @@ +eventName + * @param double $eventValue Initialization value for $this->eventValue + * @param object $metaData Initialization value for $this->metaData + */ + public function __construct() + { + if (3 == func_num_args()) { + $this->eventName = func_get_arg(0); + $this->eventValue = func_get_arg(1); + $this->metaData = func_get_arg(2); + } + } + + + /** + * Encode this object to JSON + */ + public function jsonSerialize() + { + $json = array(); + $json['eventName'] = $this->eventName; + $json['eventValue'] = $this->eventValue; + $json['metaData'] = $this->metaData; + + return $json; + } +} diff --git a/src/Models/EventsBody.php b/src/Models/EventsBody.php new file mode 100755 index 0000000..94eac99 --- /dev/null +++ b/src/Models/EventsBody.php @@ -0,0 +1,55 @@ +events + * @param Attributes $attributes Initialization value for $this->attributes + */ + public function __construct() + { + if (2 == func_num_args()) { + $this->events = func_get_arg(0); + $this->attributes = func_get_arg(1); + } + } + + + /** + * Encode this object to JSON + */ + public function jsonSerialize() + { + $json = array(); + $json['events'] = $this->events; + $json['attributes'] = $this->attributes; + + return $json; + } +} diff --git a/src/Models/Variable.php b/src/Models/Variable.php new file mode 100755 index 0000000..97b862b --- /dev/null +++ b/src/Models/Variable.php @@ -0,0 +1,54 @@ +name + * @param object $value Initialization value for $this->value + */ + public function __construct() + { + if (2 == func_num_args()) { + $this->name = func_get_arg(0); + $this->value = func_get_arg(1); + } + } + + + /** + * Encode this object to JSON + */ + public function jsonSerialize() + { + $json = array(); + $json['name'] = $this->name; + $json['value'] = $this->value; + + return $json; + } +} diff --git a/src/TaplyticsClient.php b/src/TaplyticsClient.php new file mode 100755 index 0000000..40620c2 --- /dev/null +++ b/src/TaplyticsClient.php @@ -0,0 +1,25 @@ +