first commit

This commit is contained in:
2025-01-06 20:47:25 +01:00
commit 3bdbd78c2f
25591 changed files with 3586440 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
.idea/*
/vendor/
composer.lock
/build/

View File

@@ -0,0 +1,22 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
matrix:
allow_failures:
- php: hhvm
before_script:
- composer require satooshi/php-coveralls:1.0.1 squizlabs/php_codesniffer
- composer install
script:
- vendor/bin/phpcs src/ -p --standard=PSR2 --report=summary
- mkdir -p build/logs
- vendor/bin/phpunit --configuration phpunit.xml --coverage-text
after_success:
- sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php vendor/bin/coveralls -v; fi;'

View File

@@ -0,0 +1,33 @@
[![Build Status](https://travis-ci.org/smartsupp/chat-code-generator.svg)](https://travis-ci.org/smartsupp/chat-code-generator)
[![Coverage Status](https://coveralls.io/repos/smartsupp/chat-code-generator/badge.svg?branch=master&service=github)](https://coveralls.io/github/smartsupp/chat-code-generator?branch=master)
# Smartsupp chat code generator
This is simple PHP class for Smartsupp chat API which helps you to generate chat JavaScript code.
* https://www.smartsupp.com/
* [More info about Smartsupp CHAT API](https://developers.smartsupp.com/chat/configuration) This is "Get started" doc for chat API.
* [More info about Smartsupp CHAT API - Overview](https://developers.smartsupp.com/chat/overview) This is full documentation for chat API. Note, that not all properties are possible to be set using this class.
## Get Started
Here is an example on how to use it:
```php
$chat = new Smartsupp\ChatGenerator;
$chat->setKey('XYZ123456');
$chat->disableSendEmailTranscript();
$chat->enableRating('advanced', true);
$chat->setBoxPosition('left', 'side', 20, 120);
$chat->setName('Johny Depp');
$chat->setEmail('johny@depp.com');
$chat->setVariable('orderTotal', 'Total orders', 150);
$chat->setVariable('lastOrder', 'Last ordered', '2015-07-09');
$chat->setGoogleAnalytics('UA-123456');
$data = $chat->render();
```
## Copyright
Copyright (c) 2016 Smartsupp.com, s.r.o.

View File

@@ -0,0 +1,34 @@
{
"name": "smartsupp/chat-code-generator",
"description": "This simple PHP class allows you to easily generate Smartsupp.com JS chat code.",
"type": "library",
"keywords": [
"chat"
],
"homepage": "https://www.smartsupp.com/",
"authors": [
{
"name": "Marek Gach",
"role": "lead"
}
],
"support": {
"issues": "https://github.com/smartsupp/chat-code-generator/issues",
"wiki": "https://github.com/smartsupp/chat-code-generator/wiki",
"source": "https://github.com/smartsupp/chat-code-generator"
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-0": {"Smartsupp": "src/"}
},
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "4.7.*"
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php" colors="true">
<testsuites>
<testsuite name="Smartsupp JS code generator">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>
</phpunit>

View File

@@ -0,0 +1,495 @@
<?php
namespace Smartsupp;
/**
* Generates widget chat code for Smartsupp.com
*
* PHP version >=5.3
*
* @package Smartsupp
* @author Marek Gach <gach@kurzor.net>
* @copyright since 2015 SmartSupp.com
* @version Git: $Id$
* @link https://github.com/smartsupp/chat-code-generator
* @since File available since Release 0.1
*/
class ChatGenerator
{
/**
* @var array Values which are allowed for ratingType param.
*/
protected $allowed_rating_types = array('advanced', 'simple');
/**
* @var array Values which are allowed for alignX param.
*/
protected $allowed_align_x = array('right', 'left');
/**
* @var array Values which are allowed for alignY param.
*/
protected $allowed_align_y = array('side', 'bottom');
/**
* @var array Values which are allowed for widget param.
*/
protected $allowed_widget = array('button', 'widget');
/**
* @var null|string Your unique chat code. Can be obtained after registration.
*/
protected $key = null;
/**
* @var null|string By default chat conversation is terminated when visitor opens a sub-domain on your website.
*/
protected $cookie_domain = null;
/**
* @var string Chat language.
*/
protected $language = 'en';
/**
* @var string Chat charset defaults to utf-8.
*/
protected $charset = 'utf-8';
/**
* @var null|string Email (basic information).
*/
protected $email = null;
/**
* @var null|string Customer name (basic information).
*/
protected $name = null;
/**
* @var null|array contain additional user information.
*/
protected $variables = null;
/**
* @var bool When the visitor ends the conversation a confirmation window is displayed. This flag defaults to true
* and can be changed.
*/
protected $send_email_transcript = true;
/**
* @var bool Indicate if rating is enabled.
*/
protected $rating_enabled = false;
/**
* @var string Rating type.
*/
protected $rating_type = 'simple';
/**
* @var bool Set if rating comment is enambled.
*/
protected $rating_comment = false;
/**
* @var string Chat X align.
*/
protected $align_x = null;
/**
* @var string Chat Y align.
*/
protected $align_y = null;
/**
* @var int Chat X offset.
*/
protected $offset_x = null;
/**
* @var int Chat Y offset.
*/
protected $offset_y = null;
/**
* @var string Widget type.
*/
protected $widget = null;
/**
* @var null|string Google analytics key value.
*/
protected $ga_key = null;
/**
* @var null|array Google analytics additional options.
*/
protected $ga_options = null;
/**
* @var bool
*/
protected $hide_widget = false;
/**
* @var null|string plugin platform
*/
protected $platform = null;
public function __construct($key = null)
{
$this->key = $key;
}
/**
* Set platform - serves as internal information for Smartsupp to identify which CMS and version is used.
*
* @param string $platform
*/
public function setPlatform($platform)
{
$this->platform = $platform;
}
/**
* Set chat language. Also is checking if language is one of allowed values.
*
* @param string $language
* @throws \Exception when parameter value is incorrect
*/
public function setLanguage($language)
{
$this->language = $language;
}
/**
* Set the charset. Check also if charset is allowed and valid value.
*
* @param string $charset
*/
public function setCharset($charset)
{
$this->charset = $charset;
}
/**
* Allows to set Smartsupp code.
*
* @param string $key Smartsupp chat key.
*/
public function setKey($key)
{
$this->key = $key;
}
/**
* Smartsupp visitor is identified by unique key stored in cookies. By default chat conversation is terminated when
* visitor opens a sub-domain on your website. You should set main domain as cookie domain if you want chat
* conversations uninterrupted across your sub-domains. Insert the cookieDomain parameter in your chat code on main
* domain and all sub-domains where you want the chat conversation uninterrupted.
*
* Example: Use value '.your-domain.com' to let chat work also on all sub-domains and main domain.
*
* @param string $cookie_domain
*/
public function setCookieDomain($cookie_domain)
{
$this->cookie_domain = $cookie_domain;
}
/**
* When the visitor ends the conversation a confirmation window is displayed. In this window there is by default a
* button to send a transcript of the chat conversation to email. You can choose not to show this button.
*/
public function disableSendEmailTranscript()
{
$this->send_email_transcript = false;
}
/**
* After visitors ends a chat conversation, he is prompted to rate the conversation. Rating is disabled by default.
* Together with enabling it you can set additional parameters.
*
* @param string $rating_type
* @param boolean|false $rating_comment
* @throws \Exception when parameter value is incorrect
*/
public function enableRating($rating_type = 'simple', $rating_comment = false)
{
if (!in_array($rating_type, $this->allowed_rating_types)) {
throw new \Exception("Rating type $rating_type is not allowed value. You can use only one of values: " .
implode(', ', $this->allowed_rating_types) . ".");
}
$rating_comment = (bool) $rating_comment;
$this->rating_enabled = true;
$this->rating_type = $rating_type;
$this->rating_comment = $rating_comment;
}
/**
* You can send visitor name. So your visitors won't be anonymous and your chat agents will see info about every
* visitor, enabling agents to better focus on VIP visitors and provide customized answers.
*
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* You can send visitor email. So your visitors won't be anonymous and your chat agents will see info about every
* visitor, enabling agents to better focus on VIP visitors and provide customized answers.
*
* @param string $name
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* Will add additional parameter into Extra user info variables list.
*
* @param $id Parameter ID.
* @param $label Parameter label.
* @param $value Parameter value.
*/
public function setVariable($id, $label, $value)
{
$variable = array('id' => $id, 'label' => $label, 'value' => $value);
$this->variables[] = $variable;
}
/**
* By default the chat box is displayed in bottom right corner of the website. You can change the default position
* along the bottom line or place the chat on right or left side of the website.
*
* @param string $align_x Align to right or left.
* @param string $align_y Align to bottom or side.
* @param int $offset_x Offset from left or right.
* @param int $offset_y Offset from top.
* @throws \Exception When params are not correct.
*/
public function setAlign($align_x = 'right', $align_y = 'bottom', $offset_x = 10, $offset_y = 100)
{
if (!in_array($align_x, $this->allowed_align_x)) {
throw new \Exception("AllignX value $align_x is not allowed value. You can use only one of values: " .
implode(', ', $this->allowed_align_x) . ".");
}
if (!in_array($align_y, $this->allowed_align_y)) {
throw new \Exception("AllignY value $align_y is not allowed value. You can use only one of values: " .
implode(', ', $this->allowed_align_y) . ".");
}
$this->align_x = $align_x;
$this->align_y = $align_y;
$this->offset_x = $offset_x;
$this->offset_y = $offset_y;
}
/**
* We supports two chat-box layouts, widget and button. By default is activated layout widget.
*
* @param string $widget Parameter value.
* @throws \Exception when parameter value is incorrect
*/
public function setWidget($widget = 'widget')
{
if (!in_array($widget, $this->allowed_widget)) {
throw new \Exception("Widget value $widget is not allowed value. You can use only one of values: " .
implode(', ', $this->allowed_widget) . ".");
}
$this->widget = $widget;
}
/**
* Smartsupp is linked with your Google Analytics (GA) automatically. Smartsupp automatically checks your site's
* code for GA property ID and sends data to that account. If you are using Google Tag Manager (GTM) or you don't
* have GA code directly inserted in your site's code for some reason, you have to link your GA account as described
* here.
* If you have sub-domains on your website and you are tracking all sub-domains in one GA account, use the gaOptions
* parameter. You can find more info about gaOptions in Google Analytics documentation
* (@see https://developers.google.com/analytics/devguides/collection/analyticsjs/advanced#customizeTracker).
*
* @param $ga_key Google analytics key.
* @param array|null $ga_options Additional gaOptions.
*/
public function setGoogleAnalytics($ga_key, array $ga_options = null)
{
$this->ga_key = $ga_key;
$this->ga_options = $ga_options;
}
/**
* You can hide chat box on certain pages by setting this variable.
*/
public function hideWidget()
{
$this->hide_widget = true;
}
/**
* Function for javascript variable value escaping.
*
* @param $str string String to encode.
* @return string Encoded string.
*/
public function javascriptEscape($str)
{
$new_str = '';
for ($i = 0; $i < mb_strlen($str); $i++) {
// obtain single character
$char = mb_substr($str, $i, 1);
// if is alphanumeric put directly into string
if (!in_array($char, array("'"))) {
$new_str .= $char;
} else { // else encode as hex
$new_str .= '\\x' . bin2hex($char);
}
}
return $new_str;
}
/**
* Will assemble chat JS code. Class property with name key need to be set before rendering.
*
* @param bool|false $print_out Force to echo JS chat code instead of returning it.
* @return string
* @throws \Exception Will reach exception when key param is not set.
*/
public function render($print_out = false)
{
if (empty($this->key)) {
throw new \Exception("At least KEY param must be set!");
}
$params = array();
$params2 = array();
// set cookie domain if not blank
if ($this->cookie_domain) {
$params[] = "_smartsupp.cookieDomain = '%cookie_domain%';";
}
// If is set to false, turn off. Default value is true.
if (!$this->send_email_transcript) {
$params[] = "_smartsupp.sendEmailTanscript = false;";
}
if ($this->rating_enabled) {
$params[] = "_smartsupp.ratingEnabled = true; // by default false";
$params[] = "_smartsupp.ratingType = '" . $this->rating_type . "'; // by default 'simple'";
$params[] = "_smartsupp.ratingComment = " . ($this->rating_comment? 'true':'false') . "; // default false";
}
if ($this->align_x && $this->align_y && $this->widget) {
$params[] = "_smartsupp.alignX = '" . $this->align_x . "'; // or 'left'";
$params[] = "_smartsupp.alignY = '" . $this->align_y . "'; // by default 'bottom'";
$params[] = "_smartsupp.widget = '" . $this->widget . "'; // by default 'widget'";
}
if ($this->offset_x && $this->offset_y) {
$params[] = "_smartsupp.offsetX = " . (int)$this->offset_x . "; // offset from left / right, default 10";
$params[] = "_smartsupp.offsetY = " . (int)$this->offset_y . "; // offset from top, default 100";
}
if ($this->platform) {
$params[] = "_smartsupp.sitePlatform = '" . self::javascriptEscape($this->platform) . "';";
}
// set detailed visitor's info
// basic info
if ($this->email) {
$params2[] = "smartsupp('email', '" . self::javascriptEscape($this->email) . "');";
}
if ($this->name) {
$params2[] = "smartsupp('name', '" . self::javascriptEscape($this->name) . "');";
}
// extra info
if ($this->variables) {
$options = array();
foreach ($this->variables as $key => $value) {
$options[] = self::javascriptEscape($value['id']) .": {label: '" .
self::javascriptEscape($value['label']) . "', value: '" . self::javascriptEscape($value['value']) .
"'}";
}
$params2[] = "smartsupp('variables', {" .
implode(", ", $options) .
"});";
}
// set GA key and additional GA params
if ($this->ga_key) {
$params[] = "_smartsupp.gaKey = '%ga_key%';";
if (!empty($this->ga_options)) {
$options = array();
foreach ($this->ga_options as $key => $value) {
$options[] = "'" . self::javascriptEscape($key) . "': '" . self::javascriptEscape($value) . "'";
}
$params[] = "_smartsupp.gaOptions = {" . implode(", ", $options) . "};";
}
}
// hide widget if needed
if ($this->hide_widget) {
$params[] = "_smartsupp.hideWidget = true;";
}
// create basic code and append params
$code = "<script type=\"text/javascript\">
var _smartsupp = _smartsupp || {};
_smartsupp.key = '%key%';\n" .
implode("\n", $params) . "\n" .
"document.addEventListener('scroll', smartsupplaunch);
document.addEventListener('mousedown', smartsupplaunch);
document.addEventListener('mousemove', smartsupplaunch);
document.addEventListener('touchstart', smartsupplaunch);
document.addEventListener('keydown', smartsupplaunch);
function smartsupplaunch () {
window.smartsupp||(function(d) {
var s,c,o=smartsupp=function(){ o._.push(arguments)};o._=[];
s=d.getElementsByTagName('script')[0];c=d.createElement('script');
c.type='text/javascript';c.charset='utf-8';c.async=true;
c.src='//www.smartsuppchat.com/loader.js';s.parentNode.insertBefore(c,s);
})(document);
document.removeEventListener('scroll', smartsupplaunch);
document.removeEventListener('mousedown', smartsupplaunch);
document.removeEventListener('mousemove', smartsupplaunch);
document.removeEventListener('touchstart', smartsupplaunch);
document.removeEventListener('keydown', smartsupplaunch);
}
"
. implode("\n", $params2) . "
</script>";
$code = str_replace('%key%', self::javascriptEscape($this->key), $code);
$code = str_replace('%cookie_domain%', self::javascriptEscape($this->cookie_domain), $code);
$code = str_replace('%ga_key%', self::javascriptEscape($this->ga_key), $code);
if ($print_out) {
echo $code;
} else {
return $code;
}
}
}

View File

@@ -0,0 +1,481 @@
<?php
namespace Smartsupp;
/**
* Generates widget chat code for Smartsupp.com
*
* PHP version >=5.3
*
* @package Smartsupp
* @author Marek Gach <gach@kurzor.net>
* @copyright since 2015 SmartSupp.com
* @version Git: $Id$
* @link https://github.com/smartsupp/chat-code-generator
* @since File available since Release 0.1
*/
class ChatGenerator
{
/**
* @var array Values which are allowed for ratingType param.
*/
protected $allowed_rating_types = array('advanced', 'simple');
/**
* @var array Values which are allowed for alignX param.
*/
protected $allowed_align_x = array('right', 'left');
/**
* @var array Values which are allowed for alignY param.
*/
protected $allowed_align_y = array('side', 'bottom');
/**
* @var array Values which are allowed for widget param.
*/
protected $allowed_widget = array('button', 'widget');
/**
* @var null|string Your unique chat code. Can be obtained after registration.
*/
protected $key = null;
/**
* @var null|string By default chat conversation is terminated when visitor opens a sub-domain on your website.
*/
protected $cookie_domain = null;
/**
* @var string Chat language.
*/
protected $language = 'en';
/**
* @var string Chat charset defaults to utf-8.
*/
protected $charset = 'utf-8';
/**
* @var null|string Email (basic information).
*/
protected $email = null;
/**
* @var null|string Customer name (basic information).
*/
protected $name = null;
/**
* @var null|array contain additional user information.
*/
protected $variables = null;
/**
* @var bool When the visitor ends the conversation a confirmation window is displayed. This flag defaults to true
* and can be changed.
*/
protected $send_email_transcript = true;
/**
* @var bool Indicate if rating is enabled.
*/
protected $rating_enabled = false;
/**
* @var string Rating type.
*/
protected $rating_type = 'simple';
/**
* @var bool Set if rating comment is enambled.
*/
protected $rating_comment = false;
/**
* @var string Chat X align.
*/
protected $align_x = null;
/**
* @var string Chat Y align.
*/
protected $align_y = null;
/**
* @var int Chat X offset.
*/
protected $offset_x = null;
/**
* @var int Chat Y offset.
*/
protected $offset_y = null;
/**
* @var string Widget type.
*/
protected $widget = null;
/**
* @var null|string Google analytics key value.
*/
protected $ga_key = null;
/**
* @var null|array Google analytics additional options.
*/
protected $ga_options = null;
/**
* @var bool
*/
protected $hide_widget = false;
/**
* @var null|string plugin platform
*/
protected $platform = null;
public function __construct($key = null)
{
$this->key = $key;
}
/**
* Set platform - serves as internal information for Smartsupp to identify which CMS and version is used.
*
* @param string $platform
*/
public function setPlatform($platform)
{
$this->platform = $platform;
}
/**
* Set chat language. Also is checking if language is one of allowed values.
*
* @param string $language
* @throws \Exception when parameter value is incorrect
*/
public function setLanguage($language)
{
$this->language = $language;
}
/**
* Set the charset. Check also if charset is allowed and valid value.
*
* @param string $charset
*/
public function setCharset($charset)
{
$this->charset = $charset;
}
/**
* Allows to set Smartsupp code.
*
* @param string $key Smartsupp chat key.
*/
public function setKey($key)
{
$this->key = $key;
}
/**
* Smartsupp visitor is identified by unique key stored in cookies. By default chat conversation is terminated when
* visitor opens a sub-domain on your website. You should set main domain as cookie domain if you want chat
* conversations uninterrupted across your sub-domains. Insert the cookieDomain parameter in your chat code on main
* domain and all sub-domains where you want the chat conversation uninterrupted.
*
* Example: Use value '.your-domain.com' to let chat work also on all sub-domains and main domain.
*
* @param string $cookie_domain
*/
public function setCookieDomain($cookie_domain)
{
$this->cookie_domain = $cookie_domain;
}
/**
* When the visitor ends the conversation a confirmation window is displayed. In this window there is by default a
* button to send a transcript of the chat conversation to email. You can choose not to show this button.
*/
public function disableSendEmailTranscript()
{
$this->send_email_transcript = false;
}
/**
* After visitors ends a chat conversation, he is prompted to rate the conversation. Rating is disabled by default.
* Together with enabling it you can set additional parameters.
*
* @param string $rating_type
* @param boolean|false $rating_comment
* @throws \Exception when parameter value is incorrect
*/
public function enableRating($rating_type = 'simple', $rating_comment = false)
{
if (!in_array($rating_type, $this->allowed_rating_types)) {
throw new \Exception("Rating type $rating_type is not allowed value. You can use only one of values: " .
implode(', ', $this->allowed_rating_types) . ".");
}
$rating_comment = (bool) $rating_comment;
$this->rating_enabled = true;
$this->rating_type = $rating_type;
$this->rating_comment = $rating_comment;
}
/**
* You can send visitor name. So your visitors won't be anonymous and your chat agents will see info about every
* visitor, enabling agents to better focus on VIP visitors and provide customized answers.
*
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* You can send visitor email. So your visitors won't be anonymous and your chat agents will see info about every
* visitor, enabling agents to better focus on VIP visitors and provide customized answers.
*
* @param string $name
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* Will add additional parameter into Extra user info variables list.
*
* @param $id Parameter ID.
* @param $label Parameter label.
* @param $value Parameter value.
*/
public function setVariable($id, $label, $value)
{
$variable = array('id' => $id, 'label' => $label, 'value' => $value);
$this->variables[] = $variable;
}
/**
* By default the chat box is displayed in bottom right corner of the website. You can change the default position
* along the bottom line or place the chat on right or left side of the website.
*
* @param string $align_x Align to right or left.
* @param string $align_y Align to bottom or side.
* @param int $offset_x Offset from left or right.
* @param int $offset_y Offset from top.
* @throws \Exception When params are not correct.
*/
public function setAlign($align_x = 'right', $align_y = 'bottom', $offset_x = 10, $offset_y = 100)
{
if (!in_array($align_x, $this->allowed_align_x)) {
throw new \Exception("AllignX value $align_x is not allowed value. You can use only one of values: " .
implode(', ', $this->allowed_align_x) . ".");
}
if (!in_array($align_y, $this->allowed_align_y)) {
throw new \Exception("AllignY value $align_y is not allowed value. You can use only one of values: " .
implode(', ', $this->allowed_align_y) . ".");
}
$this->align_x = $align_x;
$this->align_y = $align_y;
$this->offset_x = $offset_x;
$this->offset_y = $offset_y;
}
/**
* We supports two chat-box layouts, widget and button. By default is activated layout widget.
*
* @param string $widget Parameter value.
* @throws \Exception when parameter value is incorrect
*/
public function setWidget($widget = 'widget')
{
if (!in_array($widget, $this->allowed_widget)) {
throw new \Exception("Widget value $widget is not allowed value. You can use only one of values: " .
implode(', ', $this->allowed_widget) . ".");
}
$this->widget = $widget;
}
/**
* Smartsupp is linked with your Google Analytics (GA) automatically. Smartsupp automatically checks your site's
* code for GA property ID and sends data to that account. If you are using Google Tag Manager (GTM) or you don't
* have GA code directly inserted in your site's code for some reason, you have to link your GA account as described
* here.
* If you have sub-domains on your website and you are tracking all sub-domains in one GA account, use the gaOptions
* parameter. You can find more info about gaOptions in Google Analytics documentation
* (@see https://developers.google.com/analytics/devguides/collection/analyticsjs/advanced#customizeTracker).
*
* @param $ga_key Google analytics key.
* @param array|null $ga_options Additional gaOptions.
*/
public function setGoogleAnalytics($ga_key, array $ga_options = null)
{
$this->ga_key = $ga_key;
$this->ga_options = $ga_options;
}
/**
* You can hide chat box on certain pages by setting this variable.
*/
public function hideWidget()
{
$this->hide_widget = true;
}
/**
* Function for javascript variable value escaping.
*
* @param $str string String to encode.
* @return string Encoded string.
*/
public function javascriptEscape($str)
{
$new_str = '';
for ($i = 0; $i < mb_strlen($str); $i++) {
// obtain single character
$char = mb_substr($str, $i, 1);
// if is alphanumeric put directly into string
if (!in_array($char, array("'"))) {
$new_str .= $char;
} else { // else encode as hex
$new_str .= '\\x' . bin2hex($char);
}
}
return $new_str;
}
/**
* Will assemble chat JS code. Class property with name key need to be set before rendering.
*
* @param bool|false $print_out Force to echo JS chat code instead of returning it.
* @return string
* @throws \Exception Will reach exception when key param is not set.
*/
public function render($print_out = false)
{
if (empty($this->key)) {
throw new \Exception("At least KEY param must be set!");
}
$params = array();
$params2 = array();
// set cookie domain if not blank
if ($this->cookie_domain) {
$params[] = "_smartsupp.cookieDomain = '%cookie_domain%';";
}
// If is set to false, turn off. Default value is true.
if (!$this->send_email_transcript) {
$params[] = "_smartsupp.sendEmailTanscript = false;";
}
if ($this->rating_enabled) {
$params[] = "_smartsupp.ratingEnabled = true; // by default false";
$params[] = "_smartsupp.ratingType = '" . $this->rating_type . "'; // by default 'simple'";
$params[] = "_smartsupp.ratingComment = " . ($this->rating_comment? 'true':'false') . "; // default false";
}
if ($this->align_x && $this->align_y && $this->widget) {
$params[] = "_smartsupp.alignX = '" . $this->align_x . "'; // or 'left'";
$params[] = "_smartsupp.alignY = '" . $this->align_y . "'; // by default 'bottom'";
$params[] = "_smartsupp.widget = '" . $this->widget . "'; // by default 'widget'";
}
if ($this->offset_x && $this->offset_y) {
$params[] = "_smartsupp.offsetX = " . (int)$this->offset_x . "; // offset from left / right, default 10";
$params[] = "_smartsupp.offsetY = " . (int)$this->offset_y . "; // offset from top, default 100";
}
if ($this->platform) {
$params[] = "_smartsupp.sitePlatform = '" . self::javascriptEscape($this->platform) . "';";
}
// set detailed visitor's info
// basic info
if ($this->email) {
$params2[] = "smartsupp('email', '" . self::javascriptEscape($this->email) . "');";
}
if ($this->name) {
$params2[] = "smartsupp('name', '" . self::javascriptEscape($this->name) . "');";
}
// extra info
if ($this->variables) {
$options = array();
foreach ($this->variables as $key => $value) {
$options[] = self::javascriptEscape($value['id']) .": {label: '" .
self::javascriptEscape($value['label']) . "', value: '" . self::javascriptEscape($value['value']) .
"'}";
}
$params2[] = "smartsupp('variables', {" .
implode(", ", $options) .
"});";
}
// set GA key and additional GA params
if ($this->ga_key) {
$params[] = "_smartsupp.gaKey = '%ga_key%';";
if (!empty($this->ga_options)) {
$options = array();
foreach ($this->ga_options as $key => $value) {
$options[] = "'" . self::javascriptEscape($key) . "': '" . self::javascriptEscape($value) . "'";
}
$params[] = "_smartsupp.gaOptions = {" . implode(", ", $options) . "};";
}
}
// hide widget if needed
if ($this->hide_widget) {
$params[] = "_smartsupp.hideWidget = true;";
}
// create basic code and append params
$code = "<script type=\"text/javascript\">
var _smartsupp = _smartsupp || {};
_smartsupp.key = '%key%';\n" .
implode("\n", $params) . "\n" .
"window.smartsupp||(function(d) {
var s,c,o=smartsupp=function(){ o._.push(arguments)};o._=[];
s=d.getElementsByTagName('script')[0];c=d.createElement('script');
c.type='text/javascript';c.charset='utf-8';c.async=true;
c.src='//www.smartsuppchat.com/loader.js';s.parentNode.insertBefore(c,s);
})(document);"
. implode("\n", $params2) . "
</script>";
$code = str_replace('%key%', self::javascriptEscape($this->key), $code);
$code = str_replace('%cookie_domain%', self::javascriptEscape($this->cookie_domain), $code);
$code = str_replace('%ga_key%', self::javascriptEscape($this->ga_key), $code);
if ($print_out) {
echo $code;
} else {
return $code;
}
}
}

View File

@@ -0,0 +1,257 @@
<?php
namespace Smartsupp;
class ChatGeneratorTest extends \PHPUnit_Framework_TestCase
{
/**
* @var ChatGenerator
*/
protected $chat;
protected function setUp()
{
parent::setUp();
$this->chat = new ChatGenerator();
}
public function test_javascriptEscape()
{
$ret = $this->chat->javascriptEscape('abc123');
$this->assertEquals('abc123', $ret);
}
public function test_javascriptEscape_someScript()
{
$ret = $this->chat->javascriptEscape("<script>alert('xss')</script>");
$this->assertEquals('<script>alert(\x27xss\x27)</script>', $ret);
}
public function test_javascriptEscape_someSpecialChars()
{
$ret = $this->chat->javascriptEscape("\"'*!@#$%^&*()_+}{:?><.,/`~");
$this->assertEquals('"\x27*!@#$%^&*()_+}{:?><.,/`~', $ret);
}
public function test_hideWidget()
{
$this->chat->hideWidget();
$this->assertTrue(self::getPrivateField($this->chat, 'hide_widget'));
}
public function test_setGoogleAnalytics()
{
$this->chat->setGoogleAnalytics('UA-123456789');
$this->assertEquals('UA-123456789', self::getPrivateField($this->chat, 'ga_key'));
}
public function test_setGoogleAnalytics_withOptions()
{
$options = array('cookieDomain' => 'foo.example.com');
$this->chat->setGoogleAnalytics('UA-123456789', $options);
$this->assertEquals('UA-123456789', self::getPrivateField($this->chat, 'ga_key'));
$this->assertEquals($options, self::getPrivateField($this->chat, 'ga_options'));
}
public function test_widget()
{
$this->chat->setWidget('button');
$this->assertEquals('button', self::getPrivateField($this->chat, 'widget'));
}
/**
* @expectedException \Exception
* @expectedExceptionMessage Widget value foo is not allowed value. You can use only one of values: button, widget.
*/
public function test_widget_badParam()
{
$this->chat->setWidget('foo');
}
public function test_setBoxPosition()
{
$this->chat->setAlign('left', 'side', 20, 120);
$this->assertEquals('left', self::getPrivateField($this->chat, 'align_x'));
$this->assertEquals('side', self::getPrivateField($this->chat, 'align_y'));
$this->assertEquals('20', self::getPrivateField($this->chat, 'offset_x'));
$this->assertEquals('120', self::getPrivateField($this->chat, 'offset_y'));
}
/**
* @expectedException \Exception
* @expectedExceptionMessage AllignX value foo is not allowed value. You can use only one of values: right, left.
*/
public function test_setBoxPosition_badParam()
{
$this->chat->setAlign('foo', 'side', 20, 120);
}
/**
* @expectedException \Exception
* @expectedExceptionMessage AllignY value foo is not allowed value. You can use only one of values: side, bottom.
*/
public function test_setBoxPosition_badParam2()
{
$this->chat->setAlign('left', 'foo', 20, 120);
}
public function test_setVariable()
{
$this->chat->setVariable('userId', 'User ID', 123);
$this->chat->setVariable('orderedPrice', 'Ordered Price in Eshop', '128 000');
$this->assertEquals(
array(
array('id' => 'userId', 'label' => 'User ID', 'value' => 123),
array('id' => 'orderedPrice', 'label' => 'Ordered Price in Eshop', 'value' => '128 000')
),
self::getPrivateField($this->chat, 'variables')
);
}
public function test_setUserBasicInformation()
{
$this->chat->setName('Johny Depp');
$this->chat->setEmail('johny@depp.com');
$this->assertEquals('Johny Depp', self::getPrivateField($this->chat, 'name'));
$this->assertEquals('johny@depp.com', self::getPrivateField($this->chat, 'email'));
}
public function test_enableRating()
{
$this->chat->enableRating('advanced', true);
$this->assertTrue(self::getPrivateField($this->chat, 'rating_enabled'));
$this->assertEquals('advanced', self::getPrivateField($this->chat, 'rating_type'));
$this->assertTrue(self::getPrivateField($this->chat, 'rating_comment'));
}
/**
* @expectedException \Exception
* @expectedExceptionMessage Rating type foo is not allowed value. You can use only one of values: advanced, simple.
*/
public function test_enableRating_badParam()
{
$this->chat->enableRating('foo');
}
public function test_disableSendEmailTranscript()
{
$this->assertTrue(self::getPrivateField($this->chat, 'send_email_transcript'));
$this->chat->disableSendEmailTranscript();
$this->assertFalse(self::getPrivateField($this->chat, 'send_email_transcript'));
}
public function test_setCookieDomain()
{
$this->assertNull(self::getPrivateField($this->chat, 'cookie_domain'));
$this->chat->setCookieDomain('.foo.bar');
$this->assertEquals('.foo.bar', self::getPrivateField($this->chat, 'cookie_domain'));
}
public function test_setKey()
{
$this->assertNull(self::getPrivateField($this->chat, 'key'));
$this->chat->setKey('123456');
$this->assertEquals('123456', self::getPrivateField($this->chat, 'key'));
}
public function test_setCharset()
{
$this->assertEquals('utf-8', self::getPrivateField($this->chat, 'charset'));
$this->chat->setCharset('utf-32');
$this->assertEquals('utf-32', self::getPrivateField($this->chat, 'charset'));
}
public function test_setLanguage()
{
$this->assertEquals('en', self::getPrivateField($this->chat, 'language'));
$this->chat->setLanguage('cs');
$this->assertEquals('cs', self::getPrivateField($this->chat, 'language'));
}
/**
* @expectedException \Exception
* @expectedExceptionMessage At least KEY param must be set!
*/
public function test_render_keyNotSet()
{
$this->chat->render();
}
public function test_render_simple()
{
$this->chat->setKey('XYZ123456');
$ret = $this->chat->render();
$expected = "<script type=\"text/javascript\">
var _smartsupp = _smartsupp || {};
_smartsupp.key = 'XYZ123456';
window.smartsupp||(function(d) {
var s,c,o=smartsupp=function(){ o._.push(arguments)};o._=[];
s=d.getElementsByTagName('script')[0];c=d.createElement('script');
c.type='text/javascript';c.charset='utf-8';c.async=true;
c.src='//www.smartsuppchat.com/loader.js';s.parentNode.insertBefore(c,s);
})(document);
</script>";
$this->assertEquals($expected, $ret);
}
public function test_render_simpleOutput()
{
$this->chat->setKey('XYZ123456');
$ret = $this->chat->render(true);
$this->assertNull($ret);
$this->expectOutputRegex('/.*window.smartsupp.*/');
}
public function test_render_allParams()
{
$this->chat->setKey('XYZ123456');
$this->chat->setCookieDomain('.foo.bar');
$this->chat->disableSendEmailTranscript();
$this->chat->enableRating('advanced', true);
$this->chat->setAlign('left', 'side', 20, 120);
$this->chat->setWidget('button');
$this->chat->setName('Johny Depp');
$this->chat->setEmail('johny@depp.com');
$this->chat->setVariable('orderTotal', 'Total orders', 150);
$this->chat->setVariable('lastOrder', 'Last ordered', '2015-07-09');
$this->chat->setGoogleAnalytics('UA-123456', array('cookieDomain' => '.foo.bar'));
$this->chat->hideWidget();
$ret = $this->chat->render();
$this->assertEquals(file_get_contents(dirname(__FILE__) . '/chat_code.txt'), $ret);
}
/**
* Get private / protected field value using \ReflectionProperty object.
*
* @static
* @param mixed $object object to be used
* @param string $fieldName object property name
* @return mixed given property value
*/
public static function getPrivateField($object, $fieldName)
{
$refId = new \ReflectionProperty($object, $fieldName);
$refId->setAccessible(true);
$value = $refId->getValue($object);
$refId->setAccessible(false);
return $value;
}
}

View File

@@ -0,0 +1,6 @@
<?php
error_reporting(E_ALL | E_STRICT);
require __DIR__ . '/../vendor/autoload.php';
// set multibyte encoding to utf-8 to be sure. Some php configs have not utf-8 by default
mb_internal_encoding('UTF-8');

View File

@@ -0,0 +1,25 @@
<script type="text/javascript">
var _smartsupp = _smartsupp || {};
_smartsupp.key = 'XYZ123456';
_smartsupp.cookieDomain = '.foo.bar';
_smartsupp.sendEmailTanscript = false;
_smartsupp.ratingEnabled = true; // by default false
_smartsupp.ratingType = 'advanced'; // by default 'simple'
_smartsupp.ratingComment = true; // default false
_smartsupp.alignX = 'left'; // or 'left'
_smartsupp.alignY = 'side'; // by default 'bottom'
_smartsupp.widget = 'button'; // by default 'widget'
_smartsupp.offsetX = 20; // offset from left / right, default 10
_smartsupp.offsetY = 120; // offset from top, default 100
_smartsupp.gaKey = 'UA-123456';
_smartsupp.gaOptions = {'cookieDomain': '.foo.bar'};
_smartsupp.hideWidget = true;
window.smartsupp||(function(d) {
var s,c,o=smartsupp=function(){ o._.push(arguments)};o._=[];
s=d.getElementsByTagName('script')[0];c=d.createElement('script');
c.type='text/javascript';c.charset='utf-8';c.async=true;
c.src='//www.smartsuppchat.com/loader.js';s.parentNode.insertBefore(c,s);
})(document);smartsupp('email', 'johny@depp.com');
smartsupp('name', 'Johny Depp');
smartsupp('variables', {orderTotal: {label: 'Total orders', value: '150'}, lastOrder: {label: 'Last ordered', value: '2015-07-09'}});
</script>

View File

@@ -0,0 +1,5 @@
.idea/*
/vendor/
composer.lock
/build/
test.php

View File

@@ -0,0 +1,27 @@
language: php
php:
- 5.6
- 7.0
- 7.1
- 7.2
- 7.3
matrix:
include:
- php: 5.3
dist: precise
- php: 5.4
dist: trusty
- php: 5.5
dist: trusty
before_script:
- composer require satooshi/php-coveralls:1.0.1 squizlabs/php_codesniffer
- composer install
script:
- vendor/bin/phpcs src/ -p --standard=PSR2 --report=summary
- mkdir -p build/logs
- vendor/bin/phpunit --configuration phpunit.xml --coverage-text
after_success:
- sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php vendor/bin/coveralls -v; fi;'

View File

@@ -0,0 +1,92 @@
[![Build Status](https://travis-ci.org/smartsupp/php-auth-client.svg)](https://travis-ci.org/smartsupp/php-auth-client)
[![Coverage Status](https://coveralls.io/repos/github/smartsupp/php-auth-client/badge.svg?branch=master)](https://coveralls.io/github/smartsupp/php-auth-client?branch=master)
# Smartsupp Authentication API PHP client
* https://www.smartsupp.com/
## Get started
- Response is successfull if not contains `error` property in `$response` array.
- The `error` is machine-readable name of error, and `message` is human-readable description of error.
## create
```php
$api = new Smartsupp\Auth\Api();
$response = $api->create(array(
'email' => 'LOGIN_EMAIL', // required
'password' => 'YOUR_PASSWORD', // optional, min length 6 characters
'name' => 'John Doe', // optional
'lang' => 'en', // optional, lowercase; 2 characters
'partnerKey' => 'PARTNER_API_KEY' // optional
));
// print_r($response); // success response
array(
'account' => array(
'key' => 'CHAT_KEY',
'lang' => 'en'
),
'user' => array(
'email' => 'LOGIN_EMAIL',
'name' => 'John Doe',
'password' => 'YOUR_PASSWORD'
)
);
// print_r($response); // failure response
array(
'error' => 'EmailExists',
'message' => 'Email already exists',
'hint' => 'email'
);
```
### Errors
- `AuthError` - invalid PARTNER_KEY.
- `InvalidParam` - missing or invalid parameter (e.g.: email).
- `EmailExists` - email is already taken.
## login
```php
$api = new Smartsupp\Auth\Api();
$response = $api->login(array(
'email' => 'LOGIN_EMAIL',
'password' => 'YOUR_PASSWORD'
));
// print_r($response); // success response
array(
'account' => array(
'key' => 'CHAT_KEY',
'lang' => 'en'
)
);
// print_r($response); // failure response
array(
'error' => 'InvalidCredential',
'message' => 'Invalid password'
);
```
### Errors
- `AuthError` - invalid PARTNER_KEY.
- `InvalidParam` - missing or invalid parameter (e.g.: email is not valid, password is too short).
- `IdentityNotFound` - account with this email not exists.
- `InvalidCredential` - email exists, bad password is incorrect.
- `LoginFailure` - something is bad with login.
## Requirements
For backward compatibility with multiple plugins library supports PHP starting from version 5.3. It is highly possibly the constraint will change to 5.6+ in near future.
## Copyright
Copyright (c) 2016 Smartsupp.com, s.r.o.

View File

@@ -0,0 +1,29 @@
{
"name": "smartsupp/php-partner-client",
"description": "API client allows to register and login (obtain API key) from Smartsupp partner API.",
"type": "library",
"keywords": [
"chat"
],
"homepage": "https://www.smartsupp.com/",
"authors": [
{
"name": "Marek Gach",
"role": "lead"
}
],
"support": {
"issues": "https://github.com/smartsupp/php-partner-client/issues",
"wiki": "https://github.com/smartsupp/php-partner-client/wiki",
"source": "https://github.com/smartsupp/php-partner-client"
},
"autoload": {
"psr-0": {"Smartsupp": "src/"}
},
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "4.8.*"
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php" colors="true">
<testsuites>
<testsuite name="Smartsupp partner API client">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>
</phpunit>

View File

@@ -0,0 +1,169 @@
<?php
namespace Smartsupp\Auth;
use Exception;
use Smartsupp\Auth\Request\CurlRequest;
use Smartsupp\Auth\Request\HttpRequest;
/**
* Class to communicate with Smartsupp partner API.
*
* PHP version >=5.3
*
* @package Smartsupp
* @author Marek Gach <gach@kurzor.net>
* @copyright since 2016 SmartSupp.com
* @version Git: $Id$
* @link https://github.com/smartsupp/php-partner-client
*/
class Api
{
/** API call base URL */
const API_BASE_URL = 'https://www.smartsupp.com/';
/** URL paths for all used resources endpoints methods */
const URL_LOGIN = 'account/login',
URL_CREATE = 'account/create';
/**
* @var null|CurlRequest
*/
private $handle = null;
/**
* Api constructor.
*
* @param null|HttpRequest $handle inject custom request handle to better unit test
* @throws Exception
*/
public function __construct(HttpRequest $handle = null)
{
// @codeCoverageIgnoreStart
if (!function_exists('curl_init')) {
throw new Exception('Smartsupp API client needs the CURL PHP extension.');
}
if (!function_exists('json_decode')) {
throw new Exception('Smartsupp API client needs the JSON PHP extension.');
}
// @codeCoverageIgnoreEnd
$this->handle = $handle ?: new CurlRequest();
}
/**
* Allows to create user.
*
* @param array $data
* @return array
*/
public function create($data)
{
return $this->post(self::URL_CREATE, $data);
}
/**
* Allows to log in account and obtain user key.
*
* @param array $data
* @return array
*/
public function login($data)
{
return $this->post(self::URL_LOGIN, $data);
}
/**
* Helper function to execute POST request.
*
* @param string $path request path
* @param array $data optional POST data array
* @return array|string array data or json encoded string of result
* @throws Exception
*/
private function post($path, $data)
{
return $this->run($path, 'post', $data);
}
/**
* Execute request against URL path with given method, optional data array. Also allows
* to specify if json data will be decoded before function return.
*
* @param $path request path
* @param $method request method
* @param null|array $data optional request data
* @param bool $json_decode specify if returned json data will be decoded
* @return string|array JSON data or array containing decoded JSON data
* @throws Exception
*/
private function run($path, $method, $data = null, $json_decode = true)
{
$this->handle->setOption(CURLOPT_URL, self::API_BASE_URL . $path);
$this->handle->setOption(CURLOPT_RETURNTRANSFER, true);
$this->handle->setOption(CURLOPT_FAILONERROR, false);
$this->handle->setOption(CURLOPT_SSL_VERIFYPEER, true);
$this->handle->setOption(CURLOPT_SSL_VERIFYHOST, 2);
$this->handle->setOption(CURLOPT_USERAGENT, 'cURL:php-partner-client');
// forward headers from request
$headers = array(
'X-Forwarded-For: ' . $this->getUserIpAddr(),
'Accept-Language: ' . $this->getAcceptLanguage(),
);
$this->handle->setOption(CURLOPT_HTTPHEADER, $headers);
switch ($method) {
case 'post':
$this->handle->setOption(CURLOPT_POST, true);
$this->handle->setOption(CURLOPT_POSTFIELDS, $data);
break;
}
$response = $this->handle->execute();
if ($response === false) {
throw new Exception($this->handle->getLastErrorMessage());
}
$this->handle->close();
if ($json_decode) {
$response = json_decode($response, true);
if (json_last_error() != JSON_ERROR_NONE) {
throw new Exception('Cannot parse API response JSON. Error: ' . json_last_error_msg());
}
}
return $response;
}
/**
* Return user IP address.
*
* @return string|null
*/
private function getUserIpAddr()
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
// ip from share internet
return $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// ip pass from proxy
return $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
// in case is not set - may be in CLI
return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null;
}
}
/**
* Get Accept-Language header.
*
* @return string|null
*/
private function getAcceptLanguage()
{
return isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : null;
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace Smartsupp\Auth\Request;
/**
* Class CurlRequest implements basic functionality to handle cURL requests.
* It is used to better mock this communication in PHPUnit tests.
*
* @package Smartsupp\Request
*/
class CurlRequest implements HttpRequest
{
/**
* Curl handler resource.
*
* @var null|resource
*/
private $handle = null;
/**
* CurlRequest constructor.
*
* @param string|null $url URL address to make call for
*/
public function __construct($url = null)
{
$this->init($url);
}
/**
* Init cURL connection object.
*
* @param string|null $url
* @throws Exception
*/
public function init($url = null)
{
$this->handle = curl_init($url);
}
/**
* Set cURL option with given value.
*
* @param string $name option name
* @param string|array $value option value
*/
public function setOption($name, $value)
{
curl_setopt($this->handle, $name, $value);
}
/**
* Execute cURL request.
*
* @return boolean
*/
public function execute()
{
return curl_exec($this->handle);
}
/**
* Get array of information about last request.
*
* @param int $opt options
* @return array info array
*/
public function getInfo($opt = 0)
{
return curl_getinfo($this->handle, $opt);
}
/**
* Close cURL handler connection.
*/
public function close()
{
curl_close($this->handle);
}
/**
* Return last error message as string.
*
* @return string formatted error message
*/
public function getLastErrorMessage()
{
$message = sprintf("cURL failed with error #%d: %s", curl_errno($this->handle), curl_error($this->handle));
return $message;
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Smartsupp\Auth\Request;
/**
* Interface HttpRequest serves as base interface for concrete Request implementations.
*
* @package Smartsupp\Request
*/
interface HttpRequest
{
/**
* Allows to set request options.
*
* @param string $name option name
* @param string|array $value option value
*/
public function setOption($name, $value);
/**
* Execute request call.
*
* @return boolean execution status
*/
public function execute();
/**
* Get request status info.
*
* @param int $opt options
* @return array status info array
*/
public function getInfo($opt = 0);
/**
* Close request connection.
*
* @return boolean close status
*/
public function close();
/**
* Get last error message as formated string.
*
* @return string formated error message
*/
public function getLastErrorMessage();
}

View File

@@ -0,0 +1,94 @@
<?php
namespace Smartsupp\Auth;
use Exception;
class ApiTest extends \PHPUnit_Framework_TestCase
{
public function test_constructor()
{
$api = new Api();
$this->assertNotNull($api);
}
public function test_login()
{
$data = array(
'email' => 'test5@kurzor.net',
'password' => 'xxx'
);
$response = array(
'account' => array(
'key' => 'CHAT_KEY',
'lang' => 'en'
)
);
$http = $this->getMock('Smartsupp\Auth\Request\HttpRequest');
$http->expects($this->any())
->method('execute')
->will($this->returnValue(json_encode($response)));
// create class under test using $http instead of a real CurlRequest
$api = new Api($http);
$this->assertEquals($response, $api->login($data));
}
/**
* @expectedException Exception
* @expectedExceptionMessage Foo is at bar!
*/
public function test_response_error()
{
$data = array(
'email' => 'test5@kurzor.net',
'password' => 'xxx'
);
$http = $this->getMock('Smartsupp\Auth\Request\HttpRequest');
$http->expects($this->any())
->method('execute')
->will($this->returnValue(false));
$http->expects($this->any())
->method('getLastErrorMessage')
->will($this->returnValue('Foo is at bar!'));
// create class under test using $http instead of a real CurlRequest
$api = new Api($http);
$api->login($data);
}
public function test_create()
{
$data = array(
'email' => 'LOGIN_EMAIL', // required
'password' => 'YOUR_PASSWORD', // optional, min length 6 characters
'name' => 'John Doe', // optional
'lang' => 'en', // optional, lowercase; 2 characters
'partnerKey' => 'PARTNER_API_KEY' // optional
);
$response = array(
'account' => array(
'key' => 'CHAT_KEY',
'lang' => 'en'
),
'user' => array(
'email' => 'LOGIN_EMAIL',
'name' => 'John Doe',
'password' => 'YOUR_PASSWORD'
)
);
$http = $this->getMock('Smartsupp\Auth\Request\HttpRequest');
$http->expects($this->any())
->method('execute')
->will($this->returnValue(json_encode($response)));
// create class under test using $http instead of a real CurlRequest
$api = new Api($http);
$this->assertEquals($response, $api->create($data));
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace Smartsupp\Auth\Request;
class CurlRequestTest extends \PHPUnit_Framework_TestCase
{
/**
* @var CurlRequest
*/
protected $curl;
protected function setUp()
{
parent::setUp();
$this->curl = new CurlRequest('https://www.smartsupp.com/cs/product');
}
public function test_constructorVoid()
{
$this->curl = new CurlRequest();
$this->assertInstanceOf('Smartsupp\Auth\Request\CurlRequest', $this->curl);
}
public function test_constructorUrl()
{
$this->curl = new CurlRequest('https://smartsupp.com');
$this->assertInstanceOf('Smartsupp\Auth\Request\CurlRequest', $this->curl);
}
public function test_initError()
{
$this->curl->init('https://smartsupp.com');
}
public function test_setOption()
{
$this->curl->setOption(CURLOPT_HEADER, 0);
}
/**
* @expectedExceptionMessage curl_setopt() expects parameter 1 to be resource, null given
*/
public function test_setOption_notInitialized()
{
$this->curl->setOption(CURLOPT_HEADER, 0);
}
public function test_close()
{
$this->curl->close();
}
public function test_execute()
{
$this->curl->setOption(CURLOPT_RETURNTRANSFER, TRUE);
$this->assertNotEmpty($this->curl->execute());
}
public function test_getInfo()
{
$this->curl->setOption(CURLOPT_RETURNTRANSFER, TRUE);
$this->curl->execute();
$this->assertEquals($this->curl->getInfo(CURLINFO_HTTP_CODE), 200);
}
public function test_getLastErrorMessage()
{
$this->curl->setOption(CURLOPT_URL, 'foo://bar');
$this->curl->setOption(CURLOPT_RETURNTRANSFER, TRUE);
$this->curl->execute();
$this->assertNotEmpty($this->curl->getLastErrorMessage());
}
}

View File

@@ -0,0 +1,6 @@
<?php
error_reporting(E_ALL | E_STRICT);
require __DIR__ . '/../vendor/autoload.php';
// set multibyte encoding to utf-8 to be sure. Some php configs have not utf-8 by default
mb_internal_encoding('UTF-8');