-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
378 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.idea | ||
composer.phar | ||
composer.lock | ||
vendor | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,53 @@ | ||
# php-tracking | ||
# php-tracking | ||
|
||
## Installation | ||
|
||
```bash | ||
composer require affise/php-tracking:^1.0 | ||
``` | ||
|
||
## Documentation | ||
|
||
The links bellow should provide all the documentation needed to make the best | ||
use of the library: | ||
|
||
- [Documentation](https://help-center.affise.com/en/articles/6466563-postback-integration-s2s-admins) | ||
|
||
## Usage | ||
|
||
### Clicks | ||
|
||
```php | ||
<?php | ||
|
||
use Affise\Tracking\Cookie; | ||
use Affise\Tracking\CookieInvalidParamException; | ||
use Affise\Tracking\CookieUnsetException; | ||
|
||
try { | ||
Cookie::set(); | ||
} | ||
catch (CookieInvalidParamException $e) { | ||
echo "Invalid click id param\n"; | ||
} | ||
catch (CookieUnsetException $e) { | ||
echo "Failed to set cookie\n"; | ||
} | ||
``` | ||
|
||
### Conversions | ||
|
||
```php | ||
<?php | ||
|
||
use Affise\Tracking\PostbackSender; | ||
|
||
$sender = new PostbackSender("example.com"); | ||
|
||
try { | ||
$sender->send(['clickID' => '111111111111111111111111']); | ||
} | ||
catch (PostbackInvalidClickIDException $e) { | ||
echo "Invalid click id\n"; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "affise/php-tracking", | ||
"description": "Affise tracking SDK", | ||
"minimum-stability": "stable", | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "vladimirkoptev", | ||
"email": "[email protected]" | ||
} | ||
], | ||
"require": { | ||
"php": ">=7.4", | ||
"guzzlehttp/guzzle": "^7.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"Affise\\Tracking\\": "src" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
namespace Affise\Tracking; | ||
|
||
class Cookie | ||
{ | ||
private const QUERY_PARAM = ["click_id", "clickid", "afclick"]; | ||
private const COOKIE_NAME = "afclick"; | ||
|
||
/** | ||
* @return void | ||
* @throws CookieInvalidParamException | ||
* @throws CookieUnsetException | ||
*/ | ||
public static function set() | ||
{ | ||
$val = ""; | ||
foreach ([$_GET, $_POST] as $src) { | ||
foreach (self::QUERY_PARAM as $key) { | ||
if (isset($src[$key])) { | ||
$val = $src[$key]; | ||
break 2; | ||
} | ||
} | ||
} | ||
|
||
if ($val === "") { | ||
throw new CookieInvalidParamException(); | ||
} | ||
|
||
$r = setcookie(self::COOKIE_NAME, $val, time()+3600*24*365, "/", $_SERVER['HTTP_HOST'], true, false); | ||
if (!$r) { | ||
throw new CookieUnsetException(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace Affise\Tracking; | ||
|
||
class CookieInvalidParamException extends \Exception | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace Affise\Tracking; | ||
|
||
class CookieUnsetException extends \Exception | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
<?php | ||
|
||
namespace Affise\Tracking; | ||
|
||
class Postback | ||
{ | ||
public const CUSTOM_FIELDS_COUNT = 15; | ||
protected string $domain = ""; | ||
protected bool $ssl = true; | ||
protected ?string $clickID = null; | ||
protected ?string $actionID = null; | ||
protected ?string $goal = null; | ||
protected ?float $sum = null; | ||
protected ?string $IP = null; | ||
protected ?PostbackStatus $status = null; | ||
protected ?string $referrer = null; | ||
protected ?string $comment = null; | ||
protected ?string $secure = null; | ||
protected ?string $fbClID = null; | ||
protected ?string $deviceType = null; | ||
protected ?string $userID = null; | ||
/** | ||
* @var array<string> | ||
*/ | ||
protected ?array $customFields = []; | ||
|
||
protected array $propertyMap = [ | ||
"clickID" => "click_id", | ||
"actionID" => "action_id", | ||
"goal" => "goal", | ||
"sum" => "sum", | ||
"IP" => "ip", | ||
"status" => "status", | ||
"referrer" => "referrer", | ||
"comment" => "comment", | ||
"secure" => "secure", | ||
"fbClID" => "fbclid", | ||
"deviceType" => "device_type", | ||
"userID" => "user_id", | ||
"customFields" => "custom_field", | ||
]; | ||
|
||
/** | ||
* @param string $domain | ||
* @param bool $ssl | ||
* @param array $options | ||
* @throws PostbackInvalidDomainException | ||
*/ | ||
public function __construct(string $domain, bool $ssl = true, array $options = []) | ||
{ | ||
if ($domain === "") { | ||
throw new PostbackInvalidDomainException(); | ||
} | ||
|
||
$this->domain = $domain; | ||
$this->ssl = $ssl; | ||
|
||
foreach ($options as $key => $value) { | ||
if (in_array($key, ["domain", "ssl"])) { | ||
continue; | ||
} | ||
|
||
if ($key === "customFields") { | ||
for ($i = 1; $i <= self::CUSTOM_FIELDS_COUNT; $i++) { | ||
if (isset($value[$i])) { | ||
$this->customFields[$i] = $value[$i]; | ||
} | ||
} | ||
} | ||
|
||
if (property_exists($this, $key)) { | ||
$this->$key = $value; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @return string | ||
* @throws PostbackInvalidClickIDException | ||
*/ | ||
public function url(): string | ||
{ | ||
if ($this->clickID === "" || !preg_match('/[0-9a-f]{24}/i', $this->clickID)) { | ||
throw new PostbackInvalidClickIDException(); | ||
} | ||
|
||
$url = "http" . ($this->ssl ? "s" : "") . "://" . $this->domain . "/postback?"; | ||
$query = []; | ||
|
||
foreach ($this->propertyMap as $key => $param) { | ||
$query = array_merge($query, $this->mapProperty($key)); | ||
} | ||
|
||
return $url . http_build_query($query); | ||
} | ||
|
||
protected function mapProperty(string $key): array | ||
{ | ||
$param = $this->propertyMap[$key] ?? $key; | ||
$query = []; | ||
|
||
switch ($key) { | ||
case "status": | ||
$query[$param] = $this->status->value(); | ||
break; | ||
case "customFields": | ||
foreach ($this->customFields as $i => $value) { | ||
$query[$param . $i] = $value; | ||
} | ||
break; | ||
default: | ||
$query[$param] = $this->$key; | ||
break; | ||
} | ||
|
||
return $query; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace Affise\Tracking; | ||
|
||
class PostbackInvalidClickIDException extends \Exception | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace Affise\Tracking; | ||
|
||
class PostbackInvalidDomainException extends \Exception | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
namespace Affise\Tracking; | ||
|
||
use GuzzleHttp\Client; | ||
use GuzzleHttp\Exception\GuzzleException; | ||
|
||
class PostbackSender | ||
{ | ||
private Client $client; | ||
protected string $domain; | ||
protected bool $ssl = true; | ||
|
||
public function __construct(string $domain, bool $ssl = true) | ||
{ | ||
$this->client = new Client(); | ||
$this->domain = $domain; | ||
$this->ssl = $ssl; | ||
} | ||
|
||
/** | ||
* @param array $options | ||
* @return bool | ||
* @throws GuzzleException | ||
* @throws PostbackInvalidClickIDException | ||
* @throws PostbackInvalidDomainException | ||
*/ | ||
public function send(array $options = []): bool | ||
{ | ||
return $this->sendPostback(new Postback($this->domain, $this->ssl, $options)); | ||
} | ||
|
||
/** | ||
* @param Postback $p | ||
* @return bool | ||
* @throws GuzzleException | ||
* @throws PostbackInvalidClickIDException | ||
*/ | ||
public function sendPostback(Postback $p): bool | ||
{ | ||
$url = $p->url(); | ||
$resp = $this->client->get($url); | ||
return $resp->getStatusCode() === 200; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
namespace Affise\Tracking; | ||
|
||
/** | ||
* Enum PostbackStatus | ||
*/ | ||
final class PostbackStatus | ||
{ | ||
public const CONFIRMED = 1; | ||
public const PENDING = 2; | ||
public const DECLINED = 3; | ||
public const HOLD = 5; | ||
|
||
private int $value; | ||
|
||
private static array $values = [ | ||
self::CONFIRMED => null, | ||
self::PENDING => null, | ||
self::DECLINED => null, | ||
self::HOLD => null, | ||
]; | ||
|
||
public static function Confirmed(): PostbackStatus | ||
{ | ||
if (self::$values[self::CONFIRMED] == null) { | ||
self::$values[self::CONFIRMED] = new PostbackStatus(self::CONFIRMED); | ||
} | ||
return self::$values[self::CONFIRMED]; | ||
} | ||
|
||
public static function Pending(): PostbackStatus | ||
{ | ||
if (self::$values[self::PENDING] == null) { | ||
self::$values[self::PENDING] = new PostbackStatus(self::PENDING); | ||
} | ||
return self::$values[self::PENDING]; | ||
} | ||
|
||
public static function Declined(): PostbackStatus | ||
{ | ||
if (self::$values[self::DECLINED] == null) { | ||
self::$values[self::DECLINED] = new PostbackStatus(self::DECLINED); | ||
} | ||
return self::$values[self::DECLINED]; | ||
} | ||
|
||
public static function Hold(): PostbackStatus | ||
{ | ||
if (self::$values[self::HOLD] == null) { | ||
self::$values[self::HOLD] = new PostbackStatus(self::HOLD); | ||
} | ||
return self::$values[self::HOLD]; | ||
} | ||
|
||
/** | ||
* @param int $status | ||
*/ | ||
private function __construct(int $status) | ||
{ | ||
$this->value = $status; | ||
} | ||
|
||
public function value(): int | ||
{ | ||
return $this->value; | ||
} | ||
} |