diff --git a/composer.lock b/composer.lock index 22193fd..0d291bf 100644 --- a/composer.lock +++ b/composer.lock @@ -1,57 +1,93 @@ { "_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": "eccad7521596b5fe0d81af51ab2f16a1", - "packages": [ - + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" ], + "content-hash": "d6810a171a6fbbf05f7f1156b79fdd3d", + "packages": [], "packages-dev": [ { "name": "simpletest/simpletest", - "version": "1.1.3", + "version": "v1.1.7", "source": { "type": "git", - "url": "https://github.com/simpletest/simpletest", - "reference": "1.1.3" + "url": "https://github.com/simpletest/simpletest.git", + "reference": "2f8c466c114bdb9c11028a0c3e6d1380ae6a18dc" }, "dist": { "type": "zip", - "url": "https://github.com/simpletest/simpletest/zipball/1.1.3", - "reference": "1.1.3", + "url": "https://api.github.com/repos/simpletest/simpletest/zipball/2f8c466c114bdb9c11028a0c3e6d1380ae6a18dc", + "reference": "2f8c466c114bdb9c11028a0c3e6d1380ae6a18dc", "shasum": "" }, "require": { "php": ">=5.0.5" }, + "replace": { + "lastcraft/simpletest": "self.version", + "vierbergenlars/simpletest": "self.version" + }, "type": "library", + "autoload": { + "classmap": [ + "." + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.0+" ], "authors": [ + { + "name": "Lars Vierbergen", + "email": "vierbergenlars@gmail.com" + }, + { + "name": "Lachlan Donald", + "email": "lachlan@ljd.cc" + }, { "name": "Marcus Baker", - "email": "marcus@lastcraft.com" + "email": "marcus@lastcraft.com", + "role": "Original project lead" + }, + { + "name": "Jason Sweat", + "role": "Original developer" + }, + { + "name": "Travis Swicegood", + "role": "Original developer" + }, + { + "name": "Perrick Penet", + "role": "Original developer" + }, + { + "name": "Edward Z. Yang", + "role": "Original developer" } ], "description": "Unit testing, mock objects and web testing framework for PHP built around test cases.", "homepage": "http://simpletest.org/", - "time": "2012-06-11 22:22:54" + "keywords": [ + "SimpleTest", + "code-coverage", + "selenium", + "testing", + "unit-test" + ], + "time": "2015-09-21T18:19:52+00:00" } ], - "aliases": [ - - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": [ - - ], + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, "platform": { "php": ">=5.3.0" }, - "platform-dev": [ - - ] + "platform-dev": [] } diff --git a/csrest_events.php b/csrest_events.php index cb1e8d6..4eb8f95 100644 --- a/csrest_events.php +++ b/csrest_events.php @@ -16,6 +16,47 @@ class CS_REST_Events extends CS_REST_Wrapper_Base { */ var $_events_base_route; + /** + * The type of event supports 'shopify', 'identify' and 'custom' + * @var string + * @access private + */ + private $_event_type; + + /** + * Client ID + * @var string + * @access private + */ + private $_client_id; + + /** + * Anonymous ID + * @var string + * @access private + */ + private $_anonymous_id; + + /** + * User ID + * @var string + * @access private + */ + private $_user_id; + + /** + * Email address + * @var string + * @access private + */ + private $_email; + + /** + * Indicates invalid Event + * @var bool + * @access private + */ + private $_invalid_event = false; /** * Constructor. @@ -30,6 +71,7 @@ class CS_REST_Events extends CS_REST_Wrapper_Base { * Or if using an API key: * array('api_key' => 'your api key') * @param $client_id string The client id to send event to + * @param $event_type string The event type we support - `custom`, `identify` and `shopify` * @param $protocol string The protocol to use for requests (http|https) * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE * @param $host string The host to send API requests to. There is no need to change this @@ -41,6 +83,7 @@ class CS_REST_Events extends CS_REST_Wrapper_Base { function __construct ( $auth_details, $client_id, + $event_type, $protocol = 'https', $debug_level = CS_REST_LOG_NONE, $host = 'api.createsend.com', @@ -49,9 +92,12 @@ function __construct ( $transport = NULL) { parent::__construct($auth_details, $protocol, $debug_level, $host, $log, $serialiser, $transport); $this->set_client_id($client_id); + if (!isset($event_type)) { + trigger_error('$event_type should be one of \'custom\', \'identify\' or \'shopify\''); + } + $this->setEventType($event_type); } - /** * Change the client id used for calls after construction * @param $client_id @@ -62,6 +108,56 @@ function set_client_id($client_id) { trigger_error('$client_id needs to be set'); } $this->_events_base_route = $this->_base_route.'events/'.$client_id.'/'; + $this->_client_id = $client_id; + } + + /** + * Set the type of event that we support: 'custom', 'identify' and 'shopify' + * @param $event_type string Event that we support: 'custom', 'identify' and 'shopify' + * @access private + */ + private function setEventType($event_type) { + if (!isset($event_type)) { + trigger_error('$event_type needs to be set'); + return new CS_REST_Wrapper_Result(null, 400); + } + + if (strcmp($event_type, "custom") !== 0 && + strcmp($event_type,"identify") !== 0 && + strcmp($event_type,"shopify") !== 0) { + trigger_error('$event_type needs to be one of \'custom\', \'identify\' or \'shopify\''); + $this->_invalid_event = true; + return new CS_REST_Wrapper_Result(null, 400); + } + $this->_event_type = $event_type; + } + + + /* + * Validate email address + * @param $email string email address + * @access private + */ + private function validateEmail($email) { + if (!isset($email)) { + trigger_error('$email needs to be set'); + return new CS_REST_Wrapper_Result(null, 400); + } + + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + trigger_error('$email needs to be a valid email address'); + return new CS_REST_Wrapper_Result(null, 400); + } + + return $email; + } + + /** + * Get the event type name + * @access public + */ + function getEventType() { + return $this->_event_type; } /** @@ -80,7 +176,8 @@ function set_client_id($client_id) { * 'RandomFieldURL' => 'Example', * 'RandomArray' => array(1,3,5,6,7), * ) - * + * @param $anonymous_id string Anonymous ID to use for identify events + * @param $user_id string User ID to use for identify events * @access public * @return CS_REST_Wrapper_Result A successful response will include an Event ID. * array( @@ -89,31 +186,146 @@ function set_client_id($client_id) { * ) * ) */ - function track($email, $event_name, $data = NULL) { + function track($email, $event_name, $anonymous_id = NULL, $user_id = NULL, $data = NULL) + { + // Basic validation + if (!isset($event_name)) { + trigger_error('$event_name needs to be set'); + return new CS_REST_Wrapper_Result(null, 400); + } + if (strlen($event_name) > 1000) { + trigger_error('$event_name needs to be shorter, max length is 1000 bytes'); + return new CS_REST_Wrapper_Result(null, 400); + } + if (isset($data)) { + if (!is_array($data)) { + trigger_error('$data needs to be a valid array'); + return new CS_REST_Wrapper_Result(null, 400); + } + } + if (empty($data)) { + $data = NULL; + } + + if (strcmp($this->_event_type, "identify") === 0) { + return $this->sendIdentifyTrack($email, $event_name, $anonymous_id, $user_id, $data); + } elseif (strcmp($this->_event_type, "custom") === 0 || strcmp($this->_event_type, "shopify") === 0) { + return $this->sendNonIdentifyTrack($email, $event_name, $anonymous_id, $user_id, $data); + } + + trigger_error('event type is invalid. Supported - custom, identify or shopify'); + return new CS_REST_Wrapper_Result(null, 400); + } + + /* + * Send identify track event + * @param $email string email address + * @param $event_name string event name + * @param $anonymousId string anonymous id + * @param $userId string user id + * @param $data array event data + * @access private + */ + private function sendIdentifyTrack($email, $event_name, $anonymousId, $userId, $data) { if (!isset($email)) { - trigger_error('$email needs to be set'); + trigger_error('email needs to be a set for identify event'); return new CS_REST_Wrapper_Result(null, 400); } - if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { - trigger_error('$email needs to be a valid email address'); + $minRequiredParam = 1; // anonymous id / user id + $paramPresent = 0; + if (isset($anonymousId)) { + $paramPresent += 1; + } + if (isset($userId)) { + $paramPresent += 1; + } + + if ($paramPresent < $minRequiredParam) { + trigger_error('at least one of: anonymous id, user id needs to be set and be a valid string for identify event'); return new CS_REST_Wrapper_Result(null, 400); } - if (!isset($event_name)) { - trigger_error('$event_name needs to be set'); + + $this->_anonymous_id = $anonymousId; + $this->_email = $this->validateEmail($email); + $this->_user_id = $userId; + + $payload = array( + 'ContactID' => + array( + 'Email' => $this->_email, + 'AnonymousID' => $this->_anonymous_id, + 'UserID' => $this->_user_id, + ), + 'EventName' => $event_name, + 'Data' => $data + ); + return $this->sendTrack($payload); + } + + /* + * Send non-identify track event (custom or shopify) + * @param $email string email + * @param $event_name string event name + * @param $data array event data + */ + private function sendNonIdentifyTrack($email, $event_name, $anonymousId, $userId, $data) { + $paramPresent = 0; + if (isset($email)) { + $this->_email = $this->validateEmail($email); + $paramPresent += 1; + } else { + $this->_email = NULL; + } + $minRequiredParam = 1; // anonymous id / user id / email + if (isset($anonymousId)) { + $paramPresent += 1; + } + if (isset($userId)) { + $paramPresent += 1; + } + + if ($paramPresent < $minRequiredParam) { + trigger_error('at least one of: anonymous id, user id, email needs to be set and be a valid string for identify event'); return new CS_REST_Wrapper_Result(null, 400); } - if (strlen($event_name) > 1000 ) { - trigger_error('$event_name needs to be shorter, max length is 1000 character'); + + $this->_anonymous_id = $anonymousId; + $this->_user_id = $userId; + + $payload = array( + 'ContactID' => + array( + 'Email' => $this->_email, + 'AnonymousID' => $this->_anonymous_id, + 'UserID' => $this->_user_id + ), + 'EventName' => $event_name, + 'Data' => $data + ); + return $this->sendTrack($payload); + } + + /* + * Send track event payload + * @param $payload array Payload to send to track endpoint + * @access private + */ + private function sendTrack($payload) { + if ($this->_invalid_event) { + trigger_error('$event_type must be one of \'identify\', \'custom\' or \'shopify\''); return new CS_REST_Wrapper_Result(null, 400); - } - if (isset($data)) { - if (!is_array($data)){ - trigger_error('$data needs to be a valid array'); + } + // Basic validation before finally POST'ing + if (!isset($this->_base_route) || !isset($this->_event_type) || !isset($this->_client_id)) { + trigger_error('one of: $_base_route, $_event_type, $_client_id is missing during URL construction'); return new CS_REST_Wrapper_Result(null, 400); - } } - $payload = array('ContactID' => array('Email' => $email), 'EventName' => $event_name, 'Data' => $data); - return $this->post_request($this->_events_base_route. 'track', $payload); + if (isset($payload) && is_array($payload)) { + $event_url = $this->_base_route . 'events/' . $this->_event_type . '/' . $this->_client_id . '/track'; + return $this->post_request($event_url, $payload); + } + trigger_error('$payload needs to be a valid array'); + return new CS_REST_Wrapper_Result(null, 400); } } } diff --git a/samples/events/event_track.php b/samples/events/event_track.php index 37014af..6f5a383 100644 --- a/samples/events/event_track.php +++ b/samples/events/event_track.php @@ -1,34 +1,42 @@ "Your API Key"); -$client_id = "Your Client ID"; -$wrap = new CS_REST_Events($auth, $client_id); +$auth = array("api_key" => "sample api key"); +$client_id = "sample client id"; +$api_event_type = "identify"; +$wrap = new CS_REST_Events($auth, $client_id, $api_event_type); -echo "\nSending a simple event...\n"; +echo "\nSending a $api_event_type event...\n"; $contact = "joe@example.org"; -$event_type = "checkout"; +$event_type = "checkout"; $event_data = array( - "Page" => "/cart/checkout", - "Items" => array( - array( - "Description" => "Rubber Widget", - "Quantity" => 1, - "Price" => 300, - ), - array( - "Description" => "Paint 1L", - "Quantity" => 10, - "Price" => 1, - ), - ), - "User" => "joe@example.org", - "CardType" => "VISA", + "Page" => "/cart/checkout", + "Items" => array( + array( + "Description" => "Rubber Widget", + "Quantity" => 1, + "Price" => 300, + ), + array( + "Description" => "Paint 1L", + "Quantity" => 10, + "Price" => 1, + ), + ), + "User" => "joe@example.org", + "CardType" => "VISA", ); -$result = $wrap->track($contact, $event_type, $event_data); +if (strcmp($wrap->getEventType(), "identify") === 0) { + // `Identify` event + $anon_id = "anonymousid-0"; + $user_id = "userid-0"; + $result = $wrap->track($contact, $event_type, $anon_id, $user_id, $event_data); +} else { + // `Non-identify` event (custom, shopify) + $result = $wrap->track($contact, $event_type, NULL, NULL, $event_data); +} echo "\nEvent Sent! Here's the response:\n"; var_dump($result); - diff --git a/tests/all_tests.php b/tests/all_tests.php index 4a7e1e9..b71c9d9 100644 --- a/tests/all_tests.php +++ b/tests/all_tests.php @@ -4,8 +4,8 @@ require_once __DIR__.'/../vendor/simpletest/simpletest/mock_objects.php'; class AllTests extends TestSuite { - function AllTests() { - $this->TestSuite('All Tests'); + function __construct() { + parent::__construct('All Tests'); $this->addFile('class_tests/transport_test.php'); $this->addFile('class_tests/response_tests.php'); $this->addFile('csrest_test.php'); diff --git a/tests/csrest_events_test.php b/tests/csrest_events_test.php index fb52727..199f45f 100644 --- a/tests/csrest_events_test.php +++ b/tests/csrest_events_test.php @@ -20,11 +20,13 @@ class CS_REST_OAuthTestEvents extends CS_REST_TestEvents { abstract class CS_REST_TestEvents extends CS_REST_TestBase { var $client_id = 'fakeclientid'; var $events_base_route; + var $event_type = "identify"; function set_up_inner() { $this->events_base_route = $this->base_route.'events/'.$this->client_id.'/'; - $this->wrapper = new CS_REST_Events($this->auth, $this->client_id, $this->protocol, $this->log_level, - $this->api_host, $this->mock_log, $this->mock_serialiser, $this->mock_transport); + $this->wrapper = new CS_REST_Events($this->auth, $this->client_id, $this->event_type, $this->protocol, + $this->log_level, $this->api_host, $this->mock_log, + $this->mock_serialiser, $this->mock_transport); } function testtrack() { @@ -33,13 +35,16 @@ function testtrack() { $email = 'test@email.com'; $event_name = 'Widget Man!'; $data = array('ExampleField'=> 'Me'); + $anon_id = 'anonid-0'; + $user_id = 'userid-0'; $response_code = 202; - $call_options = $this->get_call_options($this->base_route.'events/'.$client_id.'/track', 'POST'); + $call_options = $this->get_call_options($this->base_route.'events/'.$this->event_type.'/'.$this->client_id.'/track', 'POST'); + // `Non-identify` event (custom, shopify) $event_info = array ( 'ContactID' => array( - 'Email' => 'test@email.com' + 'Email' => 'test@email.com', ), 'EventName' => $event_name, 'Data' => array( @@ -47,6 +52,12 @@ function testtrack() { ) ); + if (strcmp($this->event_type, "identify") === 0) { + // `Identify` event + $event_info['ContactID']['AnonymousID'] = $anon_id; + $event_info['ContactID']['UserID'] = $user_id; + } + $transport_result = array ( 'code' => $response_code, 'response' => $raw_result @@ -59,7 +70,11 @@ function testtrack() { $this->setup_transport_and_serialisation($transport_result, $call_options, $raw_result, $raw_result, 'event info was serialised to this', $event_info, $response_code); - $result = $this->wrapper->track($email, $event_name, $data); + if (strcmp($this->event_type, "identify") == 0) { + $result = $this->wrapper->track($email, $event_name, $anon_id, $user_id, $data); + } else { + $result = $this->wrapper->track($email, $event_name, NULL, NULL, $data); + } $this->assertIdentical($expected_result, $result); diff --git a/tests/csrest_test.php b/tests/csrest_test.php index b1c124f..e0509a1 100644 --- a/tests/csrest_test.php +++ b/tests/csrest_test.php @@ -38,7 +38,8 @@ function setUp() { function set_up_inner() { $this->wrapper = new CS_REST_General($this->auth, $this->protocol, $this->log_level, - $this->api_host, $this->mock_log, $this->mock_serialiser, $this->mock_transport); + $this->api_host, $this->mock_log, $this->mock_serialiser, + $this->mock_transport); } function get_call_options($route, $method = 'GET') {