first commit
This commit is contained in:
154
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment.php
vendored
Normal file
154
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment.php
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/Segment/Client.php';
|
||||
|
||||
class Segment {
|
||||
private static $client;
|
||||
|
||||
/**
|
||||
* Initializes the default client to use. Uses the libcurl consumer by default.
|
||||
* @param string $secret your project's secret key
|
||||
* @param array $options passed straight to the client
|
||||
*/
|
||||
public static function init($secret, $options = array()) {
|
||||
self::assert($secret, "Segment::init() requires secret");
|
||||
self::$client = new Segment_Client($secret, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a user action
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the track call succeeded
|
||||
*/
|
||||
public static function track(array $message) {
|
||||
self::checkClient();
|
||||
$event = !empty($message["event"]);
|
||||
self::assert($event, "Segment::track() expects an event");
|
||||
self::validate($message, "track");
|
||||
|
||||
return self::$client->track($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags traits about the user.
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the identify call succeeded
|
||||
*/
|
||||
public static function identify(array $message) {
|
||||
self::checkClient();
|
||||
$message["type"] = "identify";
|
||||
self::validate($message, "identify");
|
||||
|
||||
return self::$client->identify($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags traits about the group.
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the group call succeeded
|
||||
*/
|
||||
public static function group(array $message) {
|
||||
self::checkClient();
|
||||
$groupId = !empty($message['groupId']);
|
||||
self::assert($groupId, "Segment::group() expects a groupId");
|
||||
self::validate($message, "group");
|
||||
|
||||
return self::$client->group($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a page view
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the page call succeeded
|
||||
*/
|
||||
public static function page(array $message) {
|
||||
self::checkClient();
|
||||
self::validate($message, "page");
|
||||
|
||||
return self::$client->page($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a screen view
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the screen call succeeded
|
||||
*/
|
||||
public static function screen(array $message) {
|
||||
self::checkClient();
|
||||
self::validate($message, "screen");
|
||||
|
||||
return self::$client->screen($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aliases the user id from a temporary id to a permanent one
|
||||
*
|
||||
* @param array $from user id to alias from
|
||||
* @return boolean whether the alias call succeeded
|
||||
*/
|
||||
public static function alias(array $message) {
|
||||
self::checkClient();
|
||||
$userId = (array_key_exists('userId', $message) && strlen((string) $message['userId']) > 0);
|
||||
$previousId = (array_key_exists('previousId', $message) && strlen((string) $message['previousId']) > 0);
|
||||
self::assert($userId && $previousId, "Segment::alias() requires both userId and previousId");
|
||||
|
||||
return self::$client->alias($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate common properties.
|
||||
*
|
||||
* @param array $message
|
||||
* @param string $type
|
||||
*/
|
||||
public static function validate($message, $type){
|
||||
$userId = (array_key_exists('userId', $message) && strlen((string) $message['userId']) > 0);
|
||||
$anonId = !empty($message['anonymousId']);
|
||||
self::assert($userId || $anonId, "Segment::${type}() requires userId or anonymousId");
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the client
|
||||
*/
|
||||
|
||||
public static function flush(){
|
||||
self::checkClient();
|
||||
|
||||
return self::$client->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the client.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function checkClient(){
|
||||
if (null != self::$client) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception("Segment::init() must be called before any other tracking method.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert `value` or throw.
|
||||
*
|
||||
* @param array $value
|
||||
* @param string $msg
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function assert($value, $msg) {
|
||||
if (!$value) {
|
||||
throw new Exception($msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('json_encode')) {
|
||||
throw new Exception('Segment needs the JSON PHP extension.');
|
||||
}
|
||||
265
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Client.php
vendored
Normal file
265
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Client.php
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
|
||||
require_once(__DIR__ . '/Consumer.php');
|
||||
require_once(__DIR__ . '/QueueConsumer.php');
|
||||
require_once(__DIR__ . '/Consumer/File.php');
|
||||
require_once(__DIR__ . '/Consumer/ForkCurl.php');
|
||||
require_once(__DIR__ . '/Consumer/LibCurl.php');
|
||||
require_once(__DIR__ . '/Consumer/Socket.php');
|
||||
require_once(__DIR__ . '/Version.php');
|
||||
|
||||
class Segment_Client {
|
||||
protected $consumer;
|
||||
|
||||
/**
|
||||
* Create a new analytics object with your app's secret
|
||||
* key
|
||||
*
|
||||
* @param string $secret
|
||||
* @param array $options array of consumer options [optional]
|
||||
* @param string Consumer constructor to use, libcurl by default.
|
||||
*
|
||||
*/
|
||||
public function __construct($secret, $options = array()) {
|
||||
|
||||
$consumers = array(
|
||||
"socket" => "Segment_Consumer_Socket",
|
||||
"file" => "Segment_Consumer_File",
|
||||
"fork_curl" => "Segment_Consumer_ForkCurl",
|
||||
"lib_curl" => "Segment_Consumer_LibCurl"
|
||||
);
|
||||
// Use our socket libcurl by default
|
||||
$consumer_type = isset($options["consumer"]) ? $options["consumer"] :
|
||||
"lib_curl";
|
||||
|
||||
if (!array_key_exists($consumer_type, $consumers) && class_exists($consumer_type)) {
|
||||
if (!is_subclass_of($consumer_type, Segment_Consumer::class)) {
|
||||
throw new Exception('Consumers must extend the Segment_Consumer abstract class');
|
||||
}
|
||||
// Try to resolve it by class name
|
||||
$this->consumer = new $consumer_type($secret, $options);
|
||||
return;
|
||||
}
|
||||
|
||||
$Consumer = $consumers[$consumer_type];
|
||||
|
||||
$this->consumer = new $Consumer($secret, $options);
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->consumer->__destruct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a user action
|
||||
*
|
||||
* @param array $message
|
||||
* @return [boolean] whether the track call succeeded
|
||||
*/
|
||||
public function track(array $message) {
|
||||
$message = $this->message($message, "properties");
|
||||
$message["type"] = "track";
|
||||
|
||||
return $this->consumer->track($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags traits about the user.
|
||||
*
|
||||
* @param [array] $message
|
||||
* @return [boolean] whether the track call succeeded
|
||||
*/
|
||||
public function identify(array $message) {
|
||||
$message = $this->message($message, "traits");
|
||||
$message["type"] = "identify";
|
||||
|
||||
return $this->consumer->identify($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags traits about the group.
|
||||
*
|
||||
* @param [array] $message
|
||||
* @return [boolean] whether the group call succeeded
|
||||
*/
|
||||
public function group(array $message) {
|
||||
$message = $this->message($message, "traits");
|
||||
$message["type"] = "group";
|
||||
|
||||
return $this->consumer->group($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a page view.
|
||||
*
|
||||
* @param [array] $message
|
||||
* @return [boolean] whether the page call succeeded
|
||||
*/
|
||||
public function page(array $message) {
|
||||
$message = $this->message($message, "properties");
|
||||
$message["type"] = "page";
|
||||
|
||||
return $this->consumer->page($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a screen view.
|
||||
*
|
||||
* @param [array] $message
|
||||
* @return [boolean] whether the screen call succeeded
|
||||
*/
|
||||
public function screen(array $message) {
|
||||
$message = $this->message($message, "properties");
|
||||
$message["type"] = "screen";
|
||||
|
||||
return $this->consumer->screen($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aliases from one user id to another
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the alias call succeeded
|
||||
*/
|
||||
public function alias(array $message) {
|
||||
$message = $this->message($message);
|
||||
$message["type"] = "alias";
|
||||
|
||||
return $this->consumer->alias($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush any async consumers
|
||||
* @return boolean true if flushed successfully
|
||||
*/
|
||||
public function flush() {
|
||||
if (method_exists($this->consumer, 'flush')) {
|
||||
return $this->consumer->flush();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Segment_Consumer
|
||||
*/
|
||||
public function getConsumer() {
|
||||
return $this->consumer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formats a timestamp by making sure it is set
|
||||
* and converting it to iso8601.
|
||||
*
|
||||
* The timestamp can be time in seconds `time()` or `microtime(true)`.
|
||||
* any other input is considered an error and the method will return a new date.
|
||||
*
|
||||
* Note: php's date() "u" format (for microseconds) has a bug in it
|
||||
* it always shows `.000` for microseconds since `date()` only accepts
|
||||
* ints, so we have to construct the date ourselves if microtime is passed.
|
||||
*
|
||||
* @param ts $timestamp - time in seconds (time())
|
||||
*/
|
||||
private function formatTime($ts) {
|
||||
// time()
|
||||
if (null == $ts || !$ts) {
|
||||
$ts = time();
|
||||
}
|
||||
if (false !== filter_var($ts, FILTER_VALIDATE_INT)) {
|
||||
return date("c", (int) $ts);
|
||||
}
|
||||
|
||||
// anything else try to strtotime the date.
|
||||
if (false === filter_var($ts, FILTER_VALIDATE_FLOAT)) {
|
||||
if (is_string($ts)) {
|
||||
return date("c", strtotime($ts));
|
||||
}
|
||||
|
||||
return date("c");
|
||||
}
|
||||
|
||||
// fix for floatval casting in send.php
|
||||
$parts = explode(".", (string)$ts);
|
||||
if (!isset($parts[1])) {
|
||||
return date("c", (int)$parts[0]);
|
||||
}
|
||||
|
||||
// microtime(true)
|
||||
$sec = $parts[0];
|
||||
$usec = $parts[1];
|
||||
$fmt = sprintf("Y-m-d\TH:i:s.%sP", $usec);
|
||||
|
||||
return date($fmt, (int)$sec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add common fields to the given `message`
|
||||
*
|
||||
* @param array $msg
|
||||
* @param string $def
|
||||
* @return array
|
||||
*/
|
||||
|
||||
private function message($msg, $def = ""){
|
||||
if ($def && !isset($msg[$def])) {
|
||||
$msg[$def] = array();
|
||||
}
|
||||
if ($def && empty($msg[$def])) {
|
||||
$msg[$def] = (object)$msg[$def];
|
||||
}
|
||||
|
||||
if (!isset($msg["context"])) {
|
||||
$msg["context"] = array();
|
||||
}
|
||||
$msg["context"] = array_merge($this->getDefaultContext(), $msg["context"]);
|
||||
|
||||
if (!isset($msg["timestamp"])) {
|
||||
$msg["timestamp"] = null;
|
||||
}
|
||||
$msg["timestamp"] = $this->formatTime($msg["timestamp"]);
|
||||
|
||||
if (!isset($msg["messageId"])) {
|
||||
$msg["messageId"] = self::messageId();
|
||||
}
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random messageId.
|
||||
*
|
||||
* https://gist.github.com/dahnielson/508447#file-uuid-php-L74
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
||||
private static function messageId(){
|
||||
return sprintf("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
|
||||
mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000,
|
||||
mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the segment.io context to the request
|
||||
* @return array additional context
|
||||
*/
|
||||
private function getDefaultContext() {
|
||||
global $SEGMENT_VERSION;
|
||||
|
||||
return array(
|
||||
"library" => array(
|
||||
"name" => "analytics-php",
|
||||
"version" => $SEGMENT_VERSION,
|
||||
"consumer" => $this->consumer->getConsumer()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
100
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Consumer.php
vendored
Normal file
100
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Consumer.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
abstract class Segment_Consumer {
|
||||
protected $type = "Consumer";
|
||||
|
||||
protected $options;
|
||||
protected $secret;
|
||||
|
||||
/**
|
||||
* Store our secret and options as part of this consumer
|
||||
* @param string $secret
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($secret, $options = array()) {
|
||||
$this->secret = $secret;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a user action
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the track call succeeded
|
||||
*/
|
||||
abstract public function track(array $message);
|
||||
|
||||
/**
|
||||
* Tags traits about the user.
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the identify call succeeded
|
||||
*/
|
||||
abstract public function identify(array $message);
|
||||
|
||||
/**
|
||||
* Tags traits about the group.
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the group call succeeded
|
||||
*/
|
||||
abstract public function group(array $message);
|
||||
|
||||
/**
|
||||
* Tracks a page view.
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the page call succeeded
|
||||
*/
|
||||
abstract public function page(array $message);
|
||||
|
||||
/**
|
||||
* Tracks a screen view.
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the group call succeeded
|
||||
*/
|
||||
abstract public function screen(array $message);
|
||||
|
||||
/**
|
||||
* Aliases from one user id to another
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the alias call succeeded
|
||||
*/
|
||||
abstract public function alias(array $message);
|
||||
|
||||
/**
|
||||
* Check whether debug mode is enabled
|
||||
* @return boolean
|
||||
*/
|
||||
protected function debug() {
|
||||
return isset($this->options["debug"]) ? $this->options["debug"] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether we should connect to the API using SSL. This is enabled by
|
||||
* default with connections which make batching requests. For connections
|
||||
* which can save on round-trip times, you may disable it.
|
||||
* @return boolean
|
||||
*/
|
||||
protected function ssl() {
|
||||
return isset($this->options["ssl"]) ? $this->options["ssl"] : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* On an error, try and call the error handler, if debugging output to
|
||||
* error_log as well.
|
||||
* @param string $code
|
||||
* @param string $msg
|
||||
*/
|
||||
protected function handleError($code, $msg) {
|
||||
if (isset($this->options['error_handler'])) {
|
||||
$handler = $this->options['error_handler'];
|
||||
$handler($code, $msg);
|
||||
}
|
||||
|
||||
if ($this->debug()) {
|
||||
error_log("[Analytics][" . $this->type . "] " . $msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
120
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Consumer/File.php
vendored
Normal file
120
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Consumer/File.php
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
class Segment_Consumer_File extends Segment_Consumer {
|
||||
protected $type = "File";
|
||||
|
||||
private $file_handle;
|
||||
|
||||
/**
|
||||
* The file consumer writes track and identify calls to a file.
|
||||
* @param string $secret
|
||||
* @param array $options
|
||||
* string "filename" - where to log the analytics calls
|
||||
*/
|
||||
public function __construct($secret, $options = array()) {
|
||||
if (!isset($options["filename"])) {
|
||||
$options["filename"] = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "analytics.log";
|
||||
}
|
||||
|
||||
parent::__construct($secret, $options);
|
||||
|
||||
try {
|
||||
$this->file_handle = fopen($options["filename"], "a");
|
||||
if (isset($options["filepermissions"])) {
|
||||
chmod($options["filename"], $options["filepermissions"]);
|
||||
} else {
|
||||
chmod($options["filename"], 0777);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->handleError($e->getCode(), $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
if ($this->file_handle &&
|
||||
"Unknown" != get_resource_type($this->file_handle)) {
|
||||
fclose($this->file_handle);
|
||||
}
|
||||
}
|
||||
|
||||
//define getter method for consumer type
|
||||
public function getConsumer() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a user action
|
||||
*
|
||||
* @param array $message
|
||||
* @return [boolean] whether the track call succeeded
|
||||
*/
|
||||
public function track(array $message) {
|
||||
return $this->write($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags traits about the user.
|
||||
*
|
||||
* @param array $message
|
||||
* @return [boolean] whether the identify call succeeded
|
||||
*/
|
||||
public function identify(array $message) {
|
||||
return $this->write($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags traits about the group.
|
||||
*
|
||||
* @param array $message
|
||||
* @return [boolean] whether the group call succeeded
|
||||
*/
|
||||
public function group(array $message) {
|
||||
return $this->write($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a page view.
|
||||
*
|
||||
* @param array $message
|
||||
* @return [boolean] whether the page call succeeded
|
||||
*/
|
||||
public function page(array $message) {
|
||||
return $this->write($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a screen view.
|
||||
*
|
||||
* @param array $message
|
||||
* @return [boolean] whether the screen call succeeded
|
||||
*/
|
||||
public function screen(array $message) {
|
||||
return $this->write($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aliases from one user id to another
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the alias call succeeded
|
||||
*/
|
||||
public function alias(array $message) {
|
||||
return $this->write($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the API call to a file as line-delimited json
|
||||
* @param [array] $body post body content.
|
||||
* @return [boolean] whether the request succeeded
|
||||
*/
|
||||
private function write($body) {
|
||||
if (!$this->file_handle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$content = json_encode($body);
|
||||
$content.= "\n";
|
||||
|
||||
return fwrite($this->file_handle, $content) == strlen($content);
|
||||
}
|
||||
}
|
||||
100
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Consumer/ForkCurl.php
vendored
Normal file
100
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Consumer/ForkCurl.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
class Segment_Consumer_ForkCurl extends Segment_QueueConsumer {
|
||||
protected $type = "ForkCurl";
|
||||
|
||||
/**
|
||||
* Creates a new queued fork consumer which queues fork and identify
|
||||
* calls before adding them to
|
||||
* @param string $secret
|
||||
* @param array $options
|
||||
* boolean "debug" - whether to use debug output, wait for response.
|
||||
* number "max_queue_size" - the max size of messages to enqueue
|
||||
* number "flush_at" - how many messages to send in a single request
|
||||
*/
|
||||
public function __construct($secret, $options = array()) {
|
||||
parent::__construct($secret, $options);
|
||||
}
|
||||
|
||||
//define getter method for consumer type
|
||||
public function getConsumer() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an async request to our API. Fork a curl process, immediately send
|
||||
* to the API. If debug is enabled, we wait for the response.
|
||||
* @param array $messages array of all the messages to send
|
||||
* @return boolean whether the request succeeded
|
||||
*/
|
||||
public function flushBatch($messages) {
|
||||
$body = $this->payload($messages);
|
||||
$payload = json_encode($body);
|
||||
|
||||
// Escape for shell usage.
|
||||
$payload = escapeshellarg($payload);
|
||||
$secret = escapeshellarg($this->secret);
|
||||
|
||||
$protocol = $this->ssl() ? "https://" : "http://";
|
||||
if ($this->host) {
|
||||
$host = $this->host;
|
||||
} else {
|
||||
$host = "api.segment.io";
|
||||
}
|
||||
$path = "/v1/batch";
|
||||
$url = $protocol . $host . $path;
|
||||
|
||||
$cmd = "curl -u ${secret}: -X POST -H 'Content-Type: application/json'";
|
||||
|
||||
$tmpfname = "";
|
||||
if ($this->compress_request) {
|
||||
// Compress request to file
|
||||
$tmpfname = tempnam("/tmp", "forkcurl_");
|
||||
$cmd2 = "echo " . $payload . " | gzip > " . $tmpfname;
|
||||
exec($cmd2, $output, $exit);
|
||||
|
||||
if (0 != $exit) {
|
||||
$this->handleError($exit, $output);
|
||||
return false;
|
||||
}
|
||||
|
||||
$cmd.= " -H 'Content-Encoding: gzip'";
|
||||
|
||||
$cmd.= " --data-binary '@" . $tmpfname . "'";
|
||||
} else {
|
||||
$cmd.= " -d " . $payload;
|
||||
}
|
||||
|
||||
$cmd.= " '" . $url . "'";
|
||||
|
||||
// Verify message size is below than 32KB
|
||||
if (strlen($payload) >= 32 * 1024) {
|
||||
$msg = "Message size is larger than 32KB";
|
||||
error_log("[Analytics][" . $this->type . "] " . $msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send user agent in the form of {library_name}/{library_version} as per RFC 7231.
|
||||
$library = $messages[0]['context']['library'];
|
||||
$libName = $library['name'];
|
||||
$libVersion = $library['version'];
|
||||
$cmd.= " -H 'User-Agent: ${libName}/${libVersion}'";
|
||||
|
||||
if (!$this->debug()) {
|
||||
$cmd .= " > /dev/null 2>&1 &";
|
||||
}
|
||||
|
||||
exec($cmd, $output, $exit);
|
||||
|
||||
if (0 != $exit) {
|
||||
$this->handleError($exit, $output);
|
||||
}
|
||||
|
||||
if ($tmpfname != "") {
|
||||
unlink($tmpfname);
|
||||
}
|
||||
|
||||
return 0 == $exit;
|
||||
}
|
||||
}
|
||||
114
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Consumer/LibCurl.php
vendored
Normal file
114
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Consumer/LibCurl.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
class Segment_Consumer_LibCurl extends Segment_QueueConsumer {
|
||||
protected $type = "LibCurl";
|
||||
|
||||
/**
|
||||
* Creates a new queued libcurl consumer
|
||||
* @param string $secret
|
||||
* @param array $options
|
||||
* boolean "debug" - whether to use debug output, wait for response.
|
||||
* number "max_queue_size" - the max size of messages to enqueue
|
||||
* number "flush_at" - how many messages to send in a single request
|
||||
*/
|
||||
public function __construct($secret, $options = array()) {
|
||||
parent::__construct($secret, $options);
|
||||
}
|
||||
|
||||
//define getter method for consumer type
|
||||
public function getConsumer() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a sync request to our API. If debug is
|
||||
* enabled, we wait for the response
|
||||
* and retry once to diminish impact on performance.
|
||||
* @param array $messages array of all the messages to send
|
||||
* @return boolean whether the request succeeded
|
||||
*/
|
||||
public function flushBatch($messages) {
|
||||
$body = $this->payload($messages);
|
||||
$payload = json_encode($body);
|
||||
$secret = $this->secret;
|
||||
|
||||
if ($this->compress_request) {
|
||||
$payload = gzencode($payload);
|
||||
}
|
||||
|
||||
$protocol = $this->ssl() ? "https://" : "http://";
|
||||
if ($this->host) {
|
||||
$host = $this->host;
|
||||
} else {
|
||||
$host = "api.segment.io";
|
||||
}
|
||||
$path = "/v1/batch";
|
||||
$url = $protocol . $host . $path;
|
||||
|
||||
$backoff = 100; // Set initial waiting time to 100ms
|
||||
|
||||
while ($backoff < $this->maximum_backoff_duration) {
|
||||
$start_time = microtime(true);
|
||||
|
||||
// open connection
|
||||
$ch = curl_init();
|
||||
|
||||
// set the url, number of POST vars, POST data
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $secret . ':');
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
|
||||
// set variables for headers
|
||||
$header = array();
|
||||
$header[] = 'Content-Type: application/json';
|
||||
|
||||
if ($this->compress_request) {
|
||||
$header[] = 'Content-Encoding: gzip';
|
||||
}
|
||||
|
||||
// Send user agent in the form of {library_name}/{library_version} as per RFC 7231.
|
||||
$library = $messages[0]['context']['library'];
|
||||
$libName = $library['name'];
|
||||
$libVersion = $library['version'];
|
||||
$header[] = "User-Agent: ${libName}/${libVersion}";
|
||||
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
// retry failed requests just once to diminish impact on performance
|
||||
$responseContent = curl_exec($ch);
|
||||
|
||||
$err = curl_error($ch);
|
||||
if ($err) {
|
||||
$this->handleError(curl_errno($ch), $err);
|
||||
return;
|
||||
}
|
||||
|
||||
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
//close connection
|
||||
curl_close($ch);
|
||||
|
||||
$elapsed_time = microtime(true) - $start_time;
|
||||
|
||||
if (200 != $responseCode) {
|
||||
// log error
|
||||
$this->handleError($responseCode, $responseContent);
|
||||
|
||||
if (($responseCode >= 500 && $responseCode <= 600) || 429 == $responseCode) {
|
||||
// If status code is greater than 500 and less than 600, it indicates server error
|
||||
// Error code 429 indicates rate limited.
|
||||
// Retry uploading in these cases.
|
||||
usleep($backoff * 1000);
|
||||
$backoff *= 2;
|
||||
} elseif ($responseCode >= 400) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break; // no error
|
||||
}
|
||||
}
|
||||
|
||||
return $responseCode;
|
||||
}
|
||||
}
|
||||
226
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Consumer/Socket.php
vendored
Normal file
226
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Consumer/Socket.php
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
class Segment_Consumer_Socket extends Segment_QueueConsumer {
|
||||
protected $type = "Socket";
|
||||
private $socket_failed;
|
||||
|
||||
/**
|
||||
* Creates a new socket consumer for dispatching async requests immediately
|
||||
* @param string $secret
|
||||
* @param array $options
|
||||
* number "timeout" - the timeout for connecting
|
||||
* function "error_handler" - function called back on errors.
|
||||
* boolean "debug" - whether to use debug output, wait for response.
|
||||
*/
|
||||
public function __construct($secret, $options = array()) {
|
||||
if (!isset($options["timeout"])) {
|
||||
$options["timeout"] = 5;
|
||||
}
|
||||
|
||||
if (!isset($options["host"])) {
|
||||
$options["host"] = "api.segment.io";
|
||||
}
|
||||
|
||||
parent::__construct($secret, $options);
|
||||
}
|
||||
|
||||
//define getter method for consumer type
|
||||
public function getConsumer() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function flushBatch($batch) {
|
||||
$socket = $this->createSocket();
|
||||
|
||||
if (!$socket) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payload = $this->payload($batch);
|
||||
$payload = json_encode($payload);
|
||||
|
||||
$body = $this->createBody($this->options["host"], $payload);
|
||||
if (false === $body) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->makeRequest($socket, $body);
|
||||
}
|
||||
|
||||
private function createSocket() {
|
||||
if ($this->socket_failed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$protocol = $this->ssl() ? "ssl" : "tcp";
|
||||
$host = $this->options["host"];
|
||||
$port = $this->ssl() ? 443 : 80;
|
||||
$timeout = $this->options["timeout"];
|
||||
|
||||
try {
|
||||
// Open our socket to the API Server.
|
||||
// Since we're try catch'ing prevent PHP logs.
|
||||
$socket = @pfsockopen(
|
||||
$protocol . "://" . $host,
|
||||
$port,
|
||||
$errno,
|
||||
$errstr,
|
||||
$timeout
|
||||
);
|
||||
|
||||
// If we couldn't open the socket, handle the error.
|
||||
if (false === $socket) {
|
||||
$this->handleError($errno, $errstr);
|
||||
$this->socket_failed = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $socket;
|
||||
} catch (Exception $e) {
|
||||
$this->handleError($e->getCode(), $e->getMessage());
|
||||
$this->socket_failed = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to write the request to the socket, wait for response if debug
|
||||
* mode is enabled.
|
||||
* @param stream $socket the handle for the socket
|
||||
* @param string $req request body
|
||||
* @param boolean $retry
|
||||
* @return boolean $success
|
||||
*/
|
||||
private function makeRequest($socket, $req, $retry = true) {
|
||||
$bytes_written = 0;
|
||||
$bytes_total = strlen($req);
|
||||
$closed = false;
|
||||
$success = true;
|
||||
|
||||
// Retries with exponential backoff until success
|
||||
$backoff = 100; // Set initial waiting time to 100ms
|
||||
|
||||
while (true) {
|
||||
// Send request to server
|
||||
while (!$closed && $bytes_written < $bytes_total) {
|
||||
try {
|
||||
// Since we're try catch'ing prevent PHP logs.
|
||||
$written = @fwrite($socket, substr($req, $bytes_written));
|
||||
} catch (Exception $e) {
|
||||
$this->handleError($e->getCode(), $e->getMessage());
|
||||
$closed = true;
|
||||
}
|
||||
if (!isset($written) || !$written) {
|
||||
$closed = true;
|
||||
} else {
|
||||
$bytes_written += $written;
|
||||
}
|
||||
}
|
||||
|
||||
// Get response for request
|
||||
$statusCode = 0;
|
||||
$errorMessage = "";
|
||||
|
||||
if (!$closed) {
|
||||
$res = $this->parseResponse(fread($socket, 2048));
|
||||
$statusCode = (int)$res["status"];
|
||||
$errorMessage = $res["message"];
|
||||
}
|
||||
fclose($socket);
|
||||
|
||||
// If status code is 200, return true
|
||||
if (200 == $statusCode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If status code is greater than 500 and less than 600, it indicates server error
|
||||
// Error code 429 indicates rate limited.
|
||||
// Retry uploading in these cases.
|
||||
if (($statusCode >= 500 && $statusCode <= 600) || 429 == $statusCode || 0 == $statusCode) {
|
||||
if ($backoff >= $this->maximum_backoff_duration) {
|
||||
break;
|
||||
}
|
||||
|
||||
usleep($backoff * 1000);
|
||||
} elseif ($statusCode >= 400) {
|
||||
if ($this->debug()) {
|
||||
$this->handleError($res["status"], $res["message"]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Retry uploading...
|
||||
$backoff *= 2;
|
||||
$socket = $this->createSocket();
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the body to send as the post request.
|
||||
* @param string $host
|
||||
* @param string $content
|
||||
* @return string body
|
||||
*/
|
||||
private function createBody($host, $content) {
|
||||
$req = "";
|
||||
$req.= "POST /v1/batch HTTP/1.1\r\n";
|
||||
$req.= "Host: " . $host . "\r\n";
|
||||
$req.= "Content-Type: application/json\r\n";
|
||||
$req.= "Authorization: Basic " . base64_encode($this->secret . ":") . "\r\n";
|
||||
$req.= "Accept: application/json\r\n";
|
||||
|
||||
// Send user agent in the form of {library_name}/{library_version} as per RFC 7231.
|
||||
$content_json = json_decode($content, true);
|
||||
$library = $content_json['batch'][0]['context']['library'];
|
||||
$libName = $library['name'];
|
||||
$libVersion = $library['version'];
|
||||
$req.= "User-Agent: ${libName}/${libVersion}\r\n";
|
||||
|
||||
// Compress content if compress_request is true
|
||||
if ($this->compress_request) {
|
||||
$content = gzencode($content);
|
||||
|
||||
$req.= "Content-Encoding: gzip\r\n";
|
||||
}
|
||||
|
||||
$req.= "Content-length: " . strlen($content) . "\r\n";
|
||||
$req.= "\r\n";
|
||||
$req.= $content;
|
||||
|
||||
// Verify message size is below than 32KB
|
||||
if (strlen($req) >= 32 * 1024) {
|
||||
$msg = "Message size is larger than 32KB";
|
||||
error_log("[Analytics][" . $this->type . "] " . $msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse our response from the server, check header and body.
|
||||
* @param string $res
|
||||
* @return array
|
||||
* string $status HTTP code, e.g. "200"
|
||||
* string $message JSON response from the api
|
||||
*/
|
||||
private function parseResponse($res) {
|
||||
$contents = explode("\n", $res);
|
||||
|
||||
// Response comes back as HTTP/1.1 200 OK
|
||||
// Final line contains HTTP response.
|
||||
$status = explode(" ", $contents[0], 3);
|
||||
$result = $contents[count($contents) - 1];
|
||||
|
||||
return array(
|
||||
"status" => isset($status[1]) ? $status[1] : null,
|
||||
"message" => $result
|
||||
);
|
||||
}
|
||||
}
|
||||
214
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/QueueConsumer.php
vendored
Normal file
214
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/QueueConsumer.php
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
abstract class Segment_QueueConsumer extends Segment_Consumer {
|
||||
protected $type = "QueueConsumer";
|
||||
|
||||
protected $queue;
|
||||
protected $max_queue_size = 10000;
|
||||
protected $max_queue_size_bytes = 33554432; //32M
|
||||
|
||||
protected $flush_at = 100;
|
||||
protected $max_batch_size_bytes = 512000; //500kb
|
||||
protected $max_item_size_bytes = 32000; // 32kb
|
||||
protected $maximum_backoff_duration = 10000; // Set maximum waiting limit to 10s
|
||||
protected $host = "";
|
||||
protected $compress_request = false;
|
||||
|
||||
protected $flush_interval_in_mills = 10000; //frequency in milliseconds to send data, default 10
|
||||
|
||||
/**
|
||||
* Store our secret and options as part of this consumer
|
||||
* @param string $secret
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($secret, $options = array()) {
|
||||
parent::__construct($secret, $options);
|
||||
|
||||
if (isset($options["max_queue_size"])) {
|
||||
$this->max_queue_size = $options["max_queue_size"];
|
||||
}
|
||||
|
||||
if (isset($options["batch_size"])) {
|
||||
if($options["batch_size"] < 1) {
|
||||
$msg = "Batch Size must not be less than 1";
|
||||
error_log("[Analytics][" . $this->type . "] " . $msg);
|
||||
} else {
|
||||
$msg = "WARNING: batch_size option to be depricated soon, please use new option flush_at";
|
||||
error_log("[Analytics][" . $this->type . "] " . $msg);
|
||||
$this->flush_at = $options["batch_size"];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options["flush_at"])) {
|
||||
if($options["flush_at"] < 1) {
|
||||
$msg = "Flush at Size must not be less than 1";
|
||||
error_log("[Analytics][" . $this->type . "] " . $msg);
|
||||
} else {
|
||||
$this->flush_at = $options["flush_at"];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options["host"])) {
|
||||
$this->host = $options["host"];
|
||||
}
|
||||
|
||||
if (isset($options["compress_request"])) {
|
||||
$this->compress_request = json_decode($options["compress_request"]);
|
||||
}
|
||||
|
||||
if (isset($options["flush_interval"])) {
|
||||
if($options["flush_interval"] < 1000) {
|
||||
$msg = "Flush interval must not be less than 1 second";
|
||||
error_log("[Analytics][" . $this->type . "] " . $msg);
|
||||
} else {
|
||||
$this->flush_interval_in_mills = $options["flush_interval"];
|
||||
}
|
||||
}
|
||||
|
||||
$this->queue = array();
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
// Flush our queue on destruction
|
||||
$this->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a user action
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the track call succeeded
|
||||
*/
|
||||
public function track(array $message) {
|
||||
return $this->enqueue($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags traits about the user.
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the identify call succeeded
|
||||
*/
|
||||
public function identify(array $message) {
|
||||
return $this->enqueue($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags traits about the group.
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the group call succeeded
|
||||
*/
|
||||
public function group(array $message) {
|
||||
return $this->enqueue($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a page view.
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the page call succeeded
|
||||
*/
|
||||
public function page(array $message) {
|
||||
return $this->enqueue($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a screen view.
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the screen call succeeded
|
||||
*/
|
||||
public function screen(array $message) {
|
||||
return $this->enqueue($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aliases from one user id to another
|
||||
*
|
||||
* @param array $message
|
||||
* @return boolean whether the alias call succeeded
|
||||
*/
|
||||
public function alias(array $message) {
|
||||
return $this->enqueue($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes our queue of messages by batching them to the server
|
||||
*/
|
||||
public function flush() {
|
||||
$count = count($this->queue);
|
||||
$success = true;
|
||||
|
||||
while ($count > 0 && $success) {
|
||||
|
||||
$batch = array_splice($this->queue, 0, min($this->flush_at, $count));
|
||||
|
||||
if (mb_strlen(serialize($batch), '8bit') >= $this->max_batch_size_bytes) {
|
||||
$msg = "Batch size is larger than 500KB";
|
||||
error_log("[Analytics][" . $this->type . "] " . $msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$success = $this->flushBatch($batch);
|
||||
|
||||
$count = count($this->queue);
|
||||
|
||||
if($count > 0)
|
||||
usleep($this->flush_interval_in_mills * 1000);
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to our queue.
|
||||
* @param mixed $item
|
||||
* @return boolean whether call has succeeded
|
||||
*/
|
||||
protected function enqueue($item) {
|
||||
$count = count($this->queue);
|
||||
|
||||
if ($count > $this->max_queue_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mb_strlen(serialize((array)$this->queue), '8bit') >= $this->max_queue_size_bytes) {
|
||||
$msg = "Queue size is larger than 32MB";
|
||||
error_log("[Analytics][" . $this->type . "] " . $msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mb_strlen(json_encode($item), '8bit') >= $this->max_item_size_bytes) {
|
||||
$msg = "Item size is larger than 32KB";
|
||||
error_log("[Analytics][" . $this->type . "] " . $msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$count = array_push($this->queue, $item);
|
||||
|
||||
|
||||
if ($count >= $this->flush_at) {
|
||||
return $this->flush(); // return ->flush() result: true on success
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a batch of messages the method returns
|
||||
* a valid payload.
|
||||
*
|
||||
* @param {Array} $batch
|
||||
* @return {Array}
|
||||
*/
|
||||
protected function payload($batch){
|
||||
return array(
|
||||
"batch" => $batch,
|
||||
"sentAt" => date("c"),
|
||||
);
|
||||
}
|
||||
}
|
||||
3
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Version.php
vendored
Normal file
3
modules/ps_facebook/vendor/segmentio/analytics-php/lib/Segment/Version.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
global $SEGMENT_VERSION;
|
||||
$SEGMENT_VERSION = "1.8.0";
|
||||
Reference in New Issue
Block a user