Version Description
- New integration flow based on OAuth
Download this release
Release Info
Developer | kkopaczyktidio |
Plugin | Tidio Live Chat |
Version | 5.0.0 |
Comparing to | |
See all releases |
Code changes from version 4.5.1 to 5.0.0
- TidioDotEnv.php +5 -6
- config.php +1 -1
- languages/js/.gitkeep +0 -0
- languages/js/tidio-live-chat-es_ES-tidio-chat-admin.json +0 -45
- languages/js/tidio-live-chat-es_MX-tidio-chat-admin.json +0 -45
- languages/js/tidio-live-chat-fr_BE-tidio-chat-admin.json +0 -45
- languages/js/tidio-live-chat-fr_CA-tidio-chat-admin.json +0 -45
- languages/js/tidio-live-chat-fr_FR-tidio-chat-admin.json +0 -45
- languages/js/tidio-live-chat-pl_PL-tidio-chat-admin.json +0 -45
- languages/js/tidio-live-chat-ru_RU-tidio-chat-admin.json +0 -45
- languages/tidio-live-chat-es_ES.mo +0 -0
- languages/tidio-live-chat-es_MX.mo +0 -0
- languages/tidio-live-chat-fr_BE.mo +0 -0
- languages/tidio-live-chat-fr_CA.mo +0 -0
- languages/tidio-live-chat-fr_FR.mo +0 -0
- languages/tidio-live-chat-pl_PL.mo +0 -0
- languages/tidio-live-chat-ru_RU.mo +0 -0
- media/css/options.css +0 -393
- media/img/16.svg +0 -3
- media/img/27.svg +0 -3
- media/img/28.svg +0 -3
- media/img/29.svg +0 -3
- media/img/34.svg +0 -3
- media/img/4.svg +0 -3
- media/img/8.svg +0 -3
- media/img/a-center.png +0 -0
- media/img/ajax-loader.gif +0 -0
- media/img/chevron.svg +0 -4
- media/img/plus.svg +0 -3
- media/img/tidio-logo.svg +0 -8
- media/img/wp-logo.svg +0 -7
- media/js/options.js +0 -341
- options.php +0 -61
- readme.txt +24 -7
- src/Admin/TidioAdminActionLink.php +84 -0
- src/Admin/TidioAdminController.php +104 -0
- src/Admin/TidioAdminDashboard.php +51 -0
- src/Admin/TidioAdminNotice.php +30 -0
- src/Admin/TidioAdminRouting.php +55 -0
- src/Admin/TidioIframeSetup.php +99 -0
- src/Sdk/Api/Client/CurlTidioApiClient.php +108 -0
- src/Sdk/Api/Client/FileGetContentsTidioApiClient.php +137 -0
- src/Sdk/Api/Client/TidioApiClientFactory.php +30 -0
- src/Sdk/Api/Exception/TidioApiException.php +32 -0
- src/Sdk/Api/TidioApiClient.php +19 -0
- src/Sdk/Encryption/Exception/TidioDecryptionFailedException.php +14 -0
- src/Sdk/Encryption/Service/OpenSslTidioEncryptionService.php +54 -0
- src/Sdk/Encryption/Service/PlainTextTidioEncryptionService.php +20 -0
- src/Sdk/Encryption/Service/TidioEncryptionServiceFactory.php +26 -0
- src/Sdk/Encryption/TidioEncryptionService.php +17 -0
- src/Sdk/TidioIntegrationFacade.php +43 -0
- src/TidioIntegrationState.php +92 -0
- src/TidioLiveChat.php +30 -0
- src/TidioLiveChatConfig.php +45 -0
- src/Translation/TidioErrorTranslator.php +15 -0
- src/Translation/TidioTranslationLoader.php +28 -0
- src/Translation/i18n.php +20 -0
- src/Utils/QueryParameters.php +26 -0
- src/Widget/TidioWidgetLoader.php +70 -0
- tidio-elements.php +38 -462
- views/ajax-tidio-chat-redirect.php +0 -55
- views/iframe.php +6 -0
TidioDotEnv.php
CHANGED
@@ -9,6 +9,9 @@ class TidioDotEnv
|
|
9 |
*/
|
10 |
private $envDirectoryPath;
|
11 |
|
|
|
|
|
|
|
12 |
public function __construct($envDirectoryPath)
|
13 |
{
|
14 |
if (!is_dir($envDirectoryPath)) {
|
@@ -18,9 +21,6 @@ class TidioDotEnv
|
|
18 |
$this->envDirectoryPath = $envDirectoryPath;
|
19 |
}
|
20 |
|
21 |
-
/**
|
22 |
-
* @return void
|
23 |
-
*/
|
24 |
public function load()
|
25 |
{
|
26 |
$file = sprintf('%s/%s', $this->envDirectoryPath, self::ENV_FILENAME);
|
@@ -38,7 +38,7 @@ class TidioDotEnv
|
|
38 |
|
39 |
/**
|
40 |
* @param string $file
|
41 |
-
* @return array
|
42 |
*/
|
43 |
private function parseEnvFile($file)
|
44 |
{
|
@@ -57,8 +57,7 @@ class TidioDotEnv
|
|
57 |
}
|
58 |
|
59 |
/**
|
60 |
-
* @param array $envs
|
61 |
-
* @return void
|
62 |
*/
|
63 |
private function setEnvs($envs)
|
64 |
{
|
9 |
*/
|
10 |
private $envDirectoryPath;
|
11 |
|
12 |
+
/**
|
13 |
+
* @param string $envDirectoryPath
|
14 |
+
*/
|
15 |
public function __construct($envDirectoryPath)
|
16 |
{
|
17 |
if (!is_dir($envDirectoryPath)) {
|
21 |
$this->envDirectoryPath = $envDirectoryPath;
|
22 |
}
|
23 |
|
|
|
|
|
|
|
24 |
public function load()
|
25 |
{
|
26 |
$file = sprintf('%s/%s', $this->envDirectoryPath, self::ENV_FILENAME);
|
38 |
|
39 |
/**
|
40 |
* @param string $file
|
41 |
+
* @return array<string, string>
|
42 |
*/
|
43 |
private function parseEnvFile($file)
|
44 |
{
|
57 |
}
|
58 |
|
59 |
/**
|
60 |
+
* @param array<string, string> $envs
|
|
|
61 |
*/
|
62 |
private function setEnvs($envs)
|
63 |
{
|
config.php
CHANGED
@@ -6,6 +6,6 @@ require_once __DIR__ . '/TidioDotEnv.php';
|
|
6 |
|
7 |
return [
|
8 |
'tidio_api_url' => getenv('TIDIO_API_URL') ?: 'https://api-v2.tidio.co',
|
9 |
-
'tidio_panel_url' => getenv('TIDIO_PANEL_URL') ?: 'https://www.tidio.com',
|
10 |
'tidio_widget_url' => getenv('TIDIO_WIDGET_URL') ?: '//code.tidio.co',
|
11 |
];
|
6 |
|
7 |
return [
|
8 |
'tidio_api_url' => getenv('TIDIO_API_URL') ?: 'https://api-v2.tidio.co',
|
9 |
+
'tidio_panel_url' => getenv('TIDIO_PANEL_URL') ?: 'https://www.tidio.com/panel',
|
10 |
'tidio_widget_url' => getenv('TIDIO_WIDGET_URL') ?: '//code.tidio.co',
|
11 |
];
|
languages/js/.gitkeep
DELETED
File without changes
|
languages/js/tidio-live-chat-es_ES-tidio-chat-admin.json
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"domain": "tidio-live-chat",
|
3 |
-
"locale_data": {
|
4 |
-
"tidio-live-chat": {
|
5 |
-
"": {
|
6 |
-
"domain": "tidio-live-chat",
|
7 |
-
"plural_forms": "nplurals=2; plural=(n != 1);",
|
8 |
-
"lang": "es"
|
9 |
-
},
|
10 |
-
"Loading...": [
|
11 |
-
"Cargando..."
|
12 |
-
],
|
13 |
-
"Can’t be empty!": [
|
14 |
-
"¡No puede dejarse en blanco!"
|
15 |
-
],
|
16 |
-
"Email can’t be empty!": [
|
17 |
-
"¡El email no puede dejarse en blanco!"
|
18 |
-
],
|
19 |
-
"Email is invalid!": [
|
20 |
-
"¡El email no es válido!"
|
21 |
-
],
|
22 |
-
"Start using Tidio": [
|
23 |
-
"Comienza a usar Tidio"
|
24 |
-
],
|
25 |
-
"Something went wrong.": [
|
26 |
-
"Algo ha salido mal."
|
27 |
-
],
|
28 |
-
"You have been blocked for too many attempts. Please try again in an hour.": [
|
29 |
-
"Como ha habido demasiados intentos, se te ha bloqueado. Vuelve a intentarlo en una hora."
|
30 |
-
],
|
31 |
-
"Password can’t be empty!": [
|
32 |
-
"¡La contraseña no puede dejarse en blanco!"
|
33 |
-
],
|
34 |
-
"Wrong email or password": [
|
35 |
-
"Email o contraseña no válidos"
|
36 |
-
],
|
37 |
-
"Go to Tidio panel": [
|
38 |
-
"Ir al panel de Tidio"
|
39 |
-
],
|
40 |
-
"Error occured while creating, please try again!": [
|
41 |
-
"Se ha producido un error durante la creación, ¡vuelve a intentarlo!"
|
42 |
-
]
|
43 |
-
}
|
44 |
-
}
|
45 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
languages/js/tidio-live-chat-es_MX-tidio-chat-admin.json
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"domain": "tidio-live-chat",
|
3 |
-
"locale_data": {
|
4 |
-
"tidio-live-chat": {
|
5 |
-
"": {
|
6 |
-
"domain": "tidio-live-chat",
|
7 |
-
"plural_forms": "nplurals=2; plural=(n != 1);",
|
8 |
-
"lang": "es_MX"
|
9 |
-
},
|
10 |
-
"Loading...": [
|
11 |
-
"Cargando..."
|
12 |
-
],
|
13 |
-
"Can’t be empty!": [
|
14 |
-
"No puede quedar en blanco."
|
15 |
-
],
|
16 |
-
"Email can’t be empty!": [
|
17 |
-
"El email no puede quedar en blanco."
|
18 |
-
],
|
19 |
-
"Email is invalid!": [
|
20 |
-
"El email no es válido."
|
21 |
-
],
|
22 |
-
"Start using Tidio": [
|
23 |
-
"Comienza a usar Tidio"
|
24 |
-
],
|
25 |
-
"Something went wrong.": [
|
26 |
-
"Algo salió mal."
|
27 |
-
],
|
28 |
-
"You have been blocked for too many attempts. Please try again in an hour.": [
|
29 |
-
"Como hubo demasiados intentos, fuiste bloqueado. Vuelve a intentar en una hora."
|
30 |
-
],
|
31 |
-
"Password can’t be empty!": [
|
32 |
-
"La contraseña no puede quedar en blanco."
|
33 |
-
],
|
34 |
-
"Wrong email or password": [
|
35 |
-
"Email o contraseña no válidos"
|
36 |
-
],
|
37 |
-
"Go to Tidio panel": [
|
38 |
-
"Ir al panel de Tidio"
|
39 |
-
],
|
40 |
-
"Error occured while creating, please try again!": [
|
41 |
-
"Ocurrió un error durante la creación, ¡vuelve a intentarlo!"
|
42 |
-
]
|
43 |
-
}
|
44 |
-
}
|
45 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
languages/js/tidio-live-chat-fr_BE-tidio-chat-admin.json
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"domain": "tidio-live-chat",
|
3 |
-
"locale_data": {
|
4 |
-
"tidio-live-chat": {
|
5 |
-
"": {
|
6 |
-
"domain": "tidio-live-chat",
|
7 |
-
"plural_forms": "nplurals=2; plural=(n > 1);",
|
8 |
-
"lang": "fr"
|
9 |
-
},
|
10 |
-
"Loading...": [
|
11 |
-
"Chargement..."
|
12 |
-
],
|
13 |
-
"Can’t be empty!": [
|
14 |
-
"Ce champ ne peut pas être vide !"
|
15 |
-
],
|
16 |
-
"Email can’t be empty!": [
|
17 |
-
"L'e-mail ne peut pas être vide !"
|
18 |
-
],
|
19 |
-
"Email is invalid!": [
|
20 |
-
"L'adresse e-mail est invalide !"
|
21 |
-
],
|
22 |
-
"Start using Tidio": [
|
23 |
-
"Commencez à utiliser Tidio"
|
24 |
-
],
|
25 |
-
"Something went wrong.": [
|
26 |
-
"Une erreur s'est produite."
|
27 |
-
],
|
28 |
-
"You have been blocked for too many attempts. Please try again in an hour.": [
|
29 |
-
"Vous avez été bloqué en raison d'un nombre trop élevé de tentatives. Veuillez réessayer dans une heure"
|
30 |
-
],
|
31 |
-
"Password can’t be empty!": [
|
32 |
-
"Le mot de passe ne peut pas être vide !"
|
33 |
-
],
|
34 |
-
"Wrong email or password": [
|
35 |
-
"Adresse e-mail ou mot de passe erroné"
|
36 |
-
],
|
37 |
-
"Go to Tidio panel": [
|
38 |
-
"Accéder au panneau Tidio"
|
39 |
-
],
|
40 |
-
"Error occured while creating, please try again!": [
|
41 |
-
"Une erreur s'est produite lors de la création, veuillez réessayer !"
|
42 |
-
]
|
43 |
-
}
|
44 |
-
}
|
45 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
languages/js/tidio-live-chat-fr_CA-tidio-chat-admin.json
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"domain": "tidio-live-chat",
|
3 |
-
"locale_data": {
|
4 |
-
"tidio-live-chat": {
|
5 |
-
"": {
|
6 |
-
"domain": "tidio-live-chat",
|
7 |
-
"plural_forms": "nplurals=2; plural=(n > 1);",
|
8 |
-
"lang": "fr"
|
9 |
-
},
|
10 |
-
"Loading...": [
|
11 |
-
"Chargement..."
|
12 |
-
],
|
13 |
-
"Can’t be empty!": [
|
14 |
-
"Ce champ ne peut pas être vide !"
|
15 |
-
],
|
16 |
-
"Email can’t be empty!": [
|
17 |
-
"L'e-mail ne peut pas être vide !"
|
18 |
-
],
|
19 |
-
"Email is invalid!": [
|
20 |
-
"L'adresse e-mail est invalide !"
|
21 |
-
],
|
22 |
-
"Start using Tidio": [
|
23 |
-
"Commencez à utiliser Tidio"
|
24 |
-
],
|
25 |
-
"Something went wrong.": [
|
26 |
-
"Une erreur s'est produite."
|
27 |
-
],
|
28 |
-
"You have been blocked for too many attempts. Please try again in an hour.": [
|
29 |
-
"Vous avez été bloqué en raison d'un nombre trop élevé de tentatives. Veuillez réessayer dans une heure."
|
30 |
-
],
|
31 |
-
"Password can’t be empty!": [
|
32 |
-
"Le mot de passe ne peut pas être vide !"
|
33 |
-
],
|
34 |
-
"Wrong email or password": [
|
35 |
-
"Adresse e-mail ou mot de passe erroné"
|
36 |
-
],
|
37 |
-
"Go to Tidio panel": [
|
38 |
-
"Accéder au panneau Tidio"
|
39 |
-
],
|
40 |
-
"Error occured while creating, please try again!": [
|
41 |
-
"Une erreur s'est produite lors de la création, veuillez réessayer !"
|
42 |
-
]
|
43 |
-
}
|
44 |
-
}
|
45 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
languages/js/tidio-live-chat-fr_FR-tidio-chat-admin.json
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"domain": "tidio-live-chat",
|
3 |
-
"locale_data": {
|
4 |
-
"tidio-live-chat": {
|
5 |
-
"": {
|
6 |
-
"domain": "tidio-live-chat",
|
7 |
-
"plural_forms": "nplurals=2; plural=(n > 1);",
|
8 |
-
"lang": "fr"
|
9 |
-
},
|
10 |
-
"Loading...": [
|
11 |
-
"Chargement..."
|
12 |
-
],
|
13 |
-
"Can’t be empty!": [
|
14 |
-
"Ce champ ne peut pas être vide !"
|
15 |
-
],
|
16 |
-
"Email can’t be empty!": [
|
17 |
-
"L'e-mail ne peut pas être vide !"
|
18 |
-
],
|
19 |
-
"Email is invalid!": [
|
20 |
-
"L'adresse e-mail est invalide !"
|
21 |
-
],
|
22 |
-
"Start using Tidio": [
|
23 |
-
"Commencez à utiliser Tidio"
|
24 |
-
],
|
25 |
-
"Something went wrong.": [
|
26 |
-
"Une erreur s'est produite."
|
27 |
-
],
|
28 |
-
"You have been blocked for too many attempts. Please try again in an hour.": [
|
29 |
-
"Vous avez été bloqué en raison d'un nombre trop élevé de tentatives. Veuillez réessayer dans une heure."
|
30 |
-
],
|
31 |
-
"Password can’t be empty!": [
|
32 |
-
"Le mot de passe ne peut pas être vide !"
|
33 |
-
],
|
34 |
-
"Wrong email or password": [
|
35 |
-
"Adresse e-mail ou mot de passe erroné"
|
36 |
-
],
|
37 |
-
"Go to Tidio panel": [
|
38 |
-
"Accéder au panneau Tidio"
|
39 |
-
],
|
40 |
-
"Error occured while creating, please try again!": [
|
41 |
-
"Une erreur s'est produite lors de la création, veuillez réessayer !"
|
42 |
-
]
|
43 |
-
}
|
44 |
-
}
|
45 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
languages/js/tidio-live-chat-pl_PL-tidio-chat-admin.json
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"domain": "tidio-live-chat",
|
3 |
-
"locale_data": {
|
4 |
-
"tidio-live-chat": {
|
5 |
-
"": {
|
6 |
-
"domain": "tidio-live-chat",
|
7 |
-
"plural_forms": "nplurals=2; plural=(n != 1);",
|
8 |
-
"lang": "es_MX"
|
9 |
-
},
|
10 |
-
"Loading...": [
|
11 |
-
"Ładowanie..."
|
12 |
-
],
|
13 |
-
"Can’t be empty!": [
|
14 |
-
"Nie może być puste."
|
15 |
-
],
|
16 |
-
"Email can’t be empty!": [
|
17 |
-
"E-mail musi zostać podany."
|
18 |
-
],
|
19 |
-
"Email is invalid!": [
|
20 |
-
"Podany e-mail jest nieprawidłowy."
|
21 |
-
],
|
22 |
-
"Start using Tidio": [
|
23 |
-
"Rozpocznij korzystanie z Tidio"
|
24 |
-
],
|
25 |
-
"Something went wrong.": [
|
26 |
-
"Coś poszło nie tak."
|
27 |
-
],
|
28 |
-
"You have been blocked for too many attempts. Please try again in an hour.": [
|
29 |
-
"Zostałeś zablokowany z powodu zbyt wielu prób. Spróbuj ponownie za 1 godzinę."
|
30 |
-
],
|
31 |
-
"Password can’t be empty!": [
|
32 |
-
"Hasło nie może być puste!"
|
33 |
-
],
|
34 |
-
"Wrong email or password": [
|
35 |
-
"Nieprawidłowy email lub hasło"
|
36 |
-
],
|
37 |
-
"Go to Tidio panel": [
|
38 |
-
"Przejdź do panelu Tidio"
|
39 |
-
],
|
40 |
-
"Error occured while creating, please try again!": [
|
41 |
-
"Wystąpił błąd podczas tworzenia, proszę spróbować ponownie!"
|
42 |
-
]
|
43 |
-
}
|
44 |
-
}
|
45 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
languages/js/tidio-live-chat-ru_RU-tidio-chat-admin.json
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"domain": "tidio-live-chat",
|
3 |
-
"locale_data": {
|
4 |
-
"tidio-live-chat": {
|
5 |
-
"": {
|
6 |
-
"domain": "tidio-live-chat",
|
7 |
-
"plural_forms": "nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));",
|
8 |
-
"lang": "ru"
|
9 |
-
},
|
10 |
-
"Loading...": [
|
11 |
-
"Загрузка..."
|
12 |
-
],
|
13 |
-
"Can’t be empty!": [
|
14 |
-
"Не может оставаться пустым!"
|
15 |
-
],
|
16 |
-
"Email can’t be empty!": [
|
17 |
-
"Содержимое эл. письма не может быть пустым!"
|
18 |
-
],
|
19 |
-
"Email is invalid!": [
|
20 |
-
"Недействительный адрес эл. почты!"
|
21 |
-
],
|
22 |
-
"Start using Tidio": [
|
23 |
-
"Начать использовать Tidio"
|
24 |
-
],
|
25 |
-
"Something went wrong.": [
|
26 |
-
"Что-то пошло не так."
|
27 |
-
],
|
28 |
-
"You have been blocked for too many attempts. Please try again in an hour.": [
|
29 |
-
"Ваш аккаунт заблокирован из-за слишком большого количества попыток. Пожалуйста, повторите попытку через час."
|
30 |
-
],
|
31 |
-
"Password can’t be empty!": [
|
32 |
-
"Поле Пароль не может оставаться пустым!"
|
33 |
-
],
|
34 |
-
"Wrong email or password": [
|
35 |
-
"Неверный адрес эл. почты или пароль"
|
36 |
-
],
|
37 |
-
"Go to Tidio panel": [
|
38 |
-
"Перейти на панель Tidio"
|
39 |
-
],
|
40 |
-
"Error occured while creating, please try again!": [
|
41 |
-
"При создании произошла ошибка, пожалуйста, повторите попытку!"
|
42 |
-
]
|
43 |
-
}
|
44 |
-
}
|
45 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
languages/tidio-live-chat-es_ES.mo
CHANGED
Binary file
|
languages/tidio-live-chat-es_MX.mo
CHANGED
Binary file
|
languages/tidio-live-chat-fr_BE.mo
CHANGED
Binary file
|
languages/tidio-live-chat-fr_CA.mo
CHANGED
Binary file
|
languages/tidio-live-chat-fr_FR.mo
CHANGED
Binary file
|
languages/tidio-live-chat-pl_PL.mo
CHANGED
Binary file
|
languages/tidio-live-chat-ru_RU.mo
CHANGED
Binary file
|
media/css/options.css
DELETED
@@ -1,393 +0,0 @@
|
|
1 |
-
@import url(https://fonts.googleapis.com/css?family=Muli:300,400,700&subset=latin);
|
2 |
-
|
3 |
-
#tidio-wrapper,
|
4 |
-
#tidio-wrapper *,
|
5 |
-
#tidio-wrapper *:before,
|
6 |
-
#tidio-wrapper *:after {
|
7 |
-
-webkit-box-sizing: border-box;
|
8 |
-
-moz-box-sizing: border-box;
|
9 |
-
box-sizing: border-box;
|
10 |
-
}
|
11 |
-
|
12 |
-
#tidio-wrapper {
|
13 |
-
background: #f1f1f1;
|
14 |
-
color: #080f1a;
|
15 |
-
font-family: 'Muli', sans-serif;
|
16 |
-
height: 100%;
|
17 |
-
font-size: 16px;
|
18 |
-
max-width: 1234px;
|
19 |
-
z-index: 1;
|
20 |
-
position: relative;
|
21 |
-
padding: 66px 24px 0 0;
|
22 |
-
}
|
23 |
-
|
24 |
-
.tidio-box-wrapper {
|
25 |
-
display: flex;
|
26 |
-
flex-direction: column;
|
27 |
-
align-items: stretch;
|
28 |
-
justify-content: center;
|
29 |
-
margin: -12px
|
30 |
-
}
|
31 |
-
|
32 |
-
.tidio-box {
|
33 |
-
background-color: #fff;
|
34 |
-
flex-grow: 0;
|
35 |
-
flex-shrink: 1;
|
36 |
-
margin: 12px;
|
37 |
-
padding: 40px 24px;
|
38 |
-
display: flex;
|
39 |
-
flex-direction: column;
|
40 |
-
align-items: center;
|
41 |
-
}
|
42 |
-
|
43 |
-
.tidio-box-actions {
|
44 |
-
display: flex;
|
45 |
-
flex-direction: row;
|
46 |
-
align-items: flex-start;
|
47 |
-
justify-content: center;
|
48 |
-
position: relative;
|
49 |
-
}
|
50 |
-
|
51 |
-
.tidio-box-actions form {
|
52 |
-
display: none;
|
53 |
-
flex-direction: column;
|
54 |
-
align-items: center;
|
55 |
-
width: 100%;
|
56 |
-
max-width: 360px;
|
57 |
-
}
|
58 |
-
|
59 |
-
.tidio-box-george {
|
60 |
-
text-align: center;
|
61 |
-
position: relative;
|
62 |
-
padding-bottom: 324px;
|
63 |
-
|
64 |
-
background: url(../img/a-center.png) bottom center,
|
65 |
-
url(../img/4.svg) calc(50% + 223px) calc(100% - 82px),
|
66 |
-
url(../img/8.svg) calc(50% - 109px) calc(100% - 149px),
|
67 |
-
url(../img/16.svg) calc(50% + 234px) calc(100% - 183px),
|
68 |
-
url(../img/27.svg) calc(50% + 143px) calc(100% - 248px),
|
69 |
-
url(../img/28.svg) calc(50% - 214px) calc(100% - 55px),
|
70 |
-
url(../img/29.svg) calc(50% - 223px) calc(100% - 148px),
|
71 |
-
url(../img/34.svg) calc(50% - 159px) calc(100% - 226px),
|
72 |
-
#fff;
|
73 |
-
background-size: 314px 293px, 21px 15px, 23px 15px, 18px 19px, 16px 16px, 14px 22px, 43px 21px, 22px 20px;
|
74 |
-
background-repeat: no-repeat;
|
75 |
-
}
|
76 |
-
|
77 |
-
.tidio-box-george h2, .tidio-box-actions h1 {
|
78 |
-
font-size: 24px;
|
79 |
-
line-height: 34px;
|
80 |
-
font-weight: bold;
|
81 |
-
max-width: 400px;
|
82 |
-
margin-top: 0;
|
83 |
-
margin-bottom: 16px;
|
84 |
-
}
|
85 |
-
|
86 |
-
.tidio-box-actions h1 {
|
87 |
-
margin: 32px 0;
|
88 |
-
padding-top: 48px;
|
89 |
-
}
|
90 |
-
|
91 |
-
.tidio-box p {
|
92 |
-
font-size: 16px;
|
93 |
-
line-height: 25px;
|
94 |
-
font-weight: 300;
|
95 |
-
max-width: 350px;
|
96 |
-
margin: 0;
|
97 |
-
}
|
98 |
-
|
99 |
-
.tidio-box-george-image {
|
100 |
-
position: absolute;
|
101 |
-
left: 0;
|
102 |
-
right: 0;
|
103 |
-
bottom: 0;
|
104 |
-
height: 300px;
|
105 |
-
background-repeat: no-repeat;
|
106 |
-
|
107 |
-
background-position: bottom left;
|
108 |
-
}
|
109 |
-
|
110 |
-
.tidio-box-actions form label,
|
111 |
-
.tidio-box-actions form input,
|
112 |
-
.tidio-box-actions form select,
|
113 |
-
.tidio-box-actions form button,
|
114 |
-
.tidio-box-actions form .button {
|
115 |
-
width: 100%;
|
116 |
-
}
|
117 |
-
|
118 |
-
.tidio-box-actions form label {
|
119 |
-
font-size: 14px;
|
120 |
-
}
|
121 |
-
|
122 |
-
.tidio-box-actions form label + label {
|
123 |
-
margin-top: 16px;
|
124 |
-
}
|
125 |
-
|
126 |
-
.tidio-box-actions form input,
|
127 |
-
.tidio-box-actions .select-selected {
|
128 |
-
margin-top: 8px;
|
129 |
-
height: 48px;
|
130 |
-
padding: 12px 16px 11px;
|
131 |
-
border-radius: 3px;
|
132 |
-
font-size: 16px;
|
133 |
-
line-height: 24px;
|
134 |
-
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
135 |
-
border: solid 1px #bcc5d7;
|
136 |
-
display: flex;
|
137 |
-
align-items: center;
|
138 |
-
justify-content: flex-start;
|
139 |
-
color: #080f1a;
|
140 |
-
}
|
141 |
-
|
142 |
-
.tidio-box-actions form input:focus,
|
143 |
-
.tidio-box-actions form select:focus {
|
144 |
-
border-color: #0566ff;
|
145 |
-
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
146 |
-
outline: none;
|
147 |
-
}
|
148 |
-
|
149 |
-
.tidio-box-actions input::placeholder {
|
150 |
-
font-style: normal;
|
151 |
-
color: #8894ab;
|
152 |
-
}
|
153 |
-
|
154 |
-
.tidio-box-actions form button,
|
155 |
-
.tidio-box-actions form .button {
|
156 |
-
font-size: 16px;
|
157 |
-
color: #fff;
|
158 |
-
background-color: #0566ff;
|
159 |
-
border-color: #0566ff;
|
160 |
-
border-radius: 3px;
|
161 |
-
height: 48px;
|
162 |
-
display: flex;
|
163 |
-
align-items: center;
|
164 |
-
justify-content: center;
|
165 |
-
font-weight: 300;
|
166 |
-
cursor: pointer;
|
167 |
-
transition: all .3s;
|
168 |
-
}
|
169 |
-
|
170 |
-
.tidio-box-actions form * + button,
|
171 |
-
.tidio-box-actions form * + .button {
|
172 |
-
margin-top: 24px;
|
173 |
-
}
|
174 |
-
|
175 |
-
.tidio-box-actions form button:hover,
|
176 |
-
.tidio-box-actions form button:focus,
|
177 |
-
.tidio-box-actions form .button:hover,
|
178 |
-
.tidio-box-actions form .button:focus {
|
179 |
-
color: #fff;
|
180 |
-
background-color: #0b5bda;
|
181 |
-
border-color: #0b5bda;
|
182 |
-
}
|
183 |
-
|
184 |
-
.tidio-box-actions form .btn-link {
|
185 |
-
background-color: transparent;
|
186 |
-
border-color: transparent;
|
187 |
-
color: #0566ff;
|
188 |
-
margin-top: 8px;
|
189 |
-
box-shadow: none;
|
190 |
-
}
|
191 |
-
|
192 |
-
.tidio-box-actions form .btn-link:hover,
|
193 |
-
.tidio-box-actions form .btn-link:active,
|
194 |
-
.tidio-box-actions form .btn-link:focus {
|
195 |
-
text-decoration: underline;
|
196 |
-
outline: none;
|
197 |
-
background-color: transparent;
|
198 |
-
border-color: transparent;
|
199 |
-
color: #0566ff;
|
200 |
-
box-shadow: none;
|
201 |
-
}
|
202 |
-
|
203 |
-
@media only screen and (min-width: 480px) {
|
204 |
-
.tidio-box-actions {
|
205 |
-
padding-top: 64px;
|
206 |
-
}
|
207 |
-
|
208 |
-
.tidio-box-actions h1 {
|
209 |
-
margin-top: 44px;
|
210 |
-
}
|
211 |
-
|
212 |
-
.tidio-box-george h2 {
|
213 |
-
margin-top: 24px;
|
214 |
-
}
|
215 |
-
}
|
216 |
-
|
217 |
-
@media only screen and (min-width: 1280px) {
|
218 |
-
.tidio-box-wrapper {
|
219 |
-
flex-direction: row;
|
220 |
-
}
|
221 |
-
|
222 |
-
.tidio-box-actions {
|
223 |
-
flex-basis: 530px;
|
224 |
-
align-items: flex-start;
|
225 |
-
}
|
226 |
-
|
227 |
-
.tidio-box-actions h1 {
|
228 |
-
background-position: top left;
|
229 |
-
}
|
230 |
-
|
231 |
-
.tidio-box-george h2 {
|
232 |
-
margin-top: 32px;
|
233 |
-
}
|
234 |
-
|
235 |
-
.tidio-box-actions form {
|
236 |
-
align-items: flex-start;
|
237 |
-
}
|
238 |
-
|
239 |
-
.tidio-box-george {
|
240 |
-
flex-basis: 680px;
|
241 |
-
}
|
242 |
-
}
|
243 |
-
|
244 |
-
#after-install-text {
|
245 |
-
display: none;
|
246 |
-
}
|
247 |
-
|
248 |
-
.tidio-button {
|
249 |
-
font-family: 'Muli', sans-serif;
|
250 |
-
margin-top: 20px !important;
|
251 |
-
height: 40px !important;
|
252 |
-
line-height: 38px !important;
|
253 |
-
text-align: center;
|
254 |
-
width: 170px;
|
255 |
-
}
|
256 |
-
|
257 |
-
/* error */
|
258 |
-
#tidio-wrapper .error {
|
259 |
-
display: none;
|
260 |
-
margin: 12px 0 -12px;
|
261 |
-
padding: 0;
|
262 |
-
border: none;
|
263 |
-
box-shadow: none;
|
264 |
-
color: #e81332;
|
265 |
-
font-size: 14px;
|
266 |
-
line-height: 20px;
|
267 |
-
}
|
268 |
-
|
269 |
-
#tidio-wrapper .error:before {
|
270 |
-
content: '!';
|
271 |
-
display: inline-flex;
|
272 |
-
align-items: center;
|
273 |
-
justify-content: center;
|
274 |
-
width: 16px;
|
275 |
-
height: 16px;
|
276 |
-
background-color: #e81332;
|
277 |
-
color: #fff;
|
278 |
-
font-size: 13px;
|
279 |
-
border-radius: 10px;
|
280 |
-
margin-right: 8px;
|
281 |
-
}
|
282 |
-
|
283 |
-
.custom-select {
|
284 |
-
position: relative;
|
285 |
-
font-family: 'Muli', sans-serif;
|
286 |
-
}
|
287 |
-
|
288 |
-
.custom-select select {
|
289 |
-
display: none; /*hide original SELECT element: */
|
290 |
-
}
|
291 |
-
|
292 |
-
.select-selected {
|
293 |
-
background-color: #fff;
|
294 |
-
}
|
295 |
-
|
296 |
-
.select-selected.disabled {
|
297 |
-
color: #8894ab;
|
298 |
-
}
|
299 |
-
|
300 |
-
/* Style the arrow inside the select element: */
|
301 |
-
.select-selected:after {
|
302 |
-
position: absolute;
|
303 |
-
content: "";
|
304 |
-
top: 14px;
|
305 |
-
right: 14px;
|
306 |
-
width: 20px;
|
307 |
-
height: 20px;
|
308 |
-
background: url(../img/chevron.svg) center center;
|
309 |
-
}
|
310 |
-
|
311 |
-
/* Point the arrow upwards when the select box is open (active): */
|
312 |
-
.select-selected.select-arrow-active {
|
313 |
-
border-color: #0566ff;
|
314 |
-
}
|
315 |
-
|
316 |
-
.select-selected.select-arrow-active:after {
|
317 |
-
transform: rotate(180deg);
|
318 |
-
}
|
319 |
-
|
320 |
-
/* style the items (options), including the selected item: */
|
321 |
-
.select-items div, .select-selected {
|
322 |
-
color: #080f1a;
|
323 |
-
padding: 8px 15px;
|
324 |
-
line-height: 24px;
|
325 |
-
border: none;
|
326 |
-
cursor: pointer;
|
327 |
-
}
|
328 |
-
|
329 |
-
/* Style items (options): */
|
330 |
-
.select-items {
|
331 |
-
position: absolute;
|
332 |
-
background-color: #fff;
|
333 |
-
top: calc(100% + 8px);
|
334 |
-
left: 0;
|
335 |
-
right: 0;
|
336 |
-
z-index: 99;
|
337 |
-
max-height: 212px;
|
338 |
-
overflow-y: auto;
|
339 |
-
border: 1px solid #bcc5d7;
|
340 |
-
border-radius: 3px;
|
341 |
-
padding-top: 4px;
|
342 |
-
padding-bottom: 4px;
|
343 |
-
font-size: 16px;
|
344 |
-
line-height: 24px;
|
345 |
-
}
|
346 |
-
|
347 |
-
/* Hide the items when the select box is closed: */
|
348 |
-
.select-hide {
|
349 |
-
display: none;
|
350 |
-
}
|
351 |
-
|
352 |
-
.select-items div:hover, .same-as-selected {
|
353 |
-
background-color: rgba(5, 102, 255, 0.08);
|
354 |
-
color: #0566ff;
|
355 |
-
}
|
356 |
-
|
357 |
-
.logos {
|
358 |
-
position: absolute;
|
359 |
-
width: 100%;
|
360 |
-
max-width: 128px;
|
361 |
-
display: inline-flex;
|
362 |
-
background: url(../img/plus.svg) no-repeat;
|
363 |
-
background-position: 68px 18px;
|
364 |
-
}
|
365 |
-
|
366 |
-
@media only screen and (min-width: 480px) {
|
367 |
-
.logos {
|
368 |
-
max-width: 360px;
|
369 |
-
}
|
370 |
-
}
|
371 |
-
|
372 |
-
.logo {
|
373 |
-
position: relative;
|
374 |
-
display: inline-flex;
|
375 |
-
width: 48px;
|
376 |
-
height: 48px;
|
377 |
-
border-radius: 20px;
|
378 |
-
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.08);
|
379 |
-
}
|
380 |
-
|
381 |
-
.logo + .logo {
|
382 |
-
margin-left: 53px;
|
383 |
-
}
|
384 |
-
|
385 |
-
.tidio-logo {
|
386 |
-
background: url(../img/tidio-logo.svg) no-repeat center center;
|
387 |
-
background-color: #fff;
|
388 |
-
}
|
389 |
-
|
390 |
-
.wp-logo {
|
391 |
-
background: url(../img/wp-logo.svg) no-repeat center center;
|
392 |
-
background-color: #fff;
|
393 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
media/img/16.svg
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="19" viewBox="0 0 18 19">
|
2 |
-
<path fill="#D6D9E3" fill-rule="evenodd" d="M8.575 0C3.94.226.229 4.163.01 9.085c-.219 4.922 3.126 9.212 7.72 9.902.317.05.64-.046.883-.267.243-.22.385-.543.387-.883v-.062c-.009-.59-.426-1.081-.976-1.152-3.45-.533-5.948-3.77-5.762-7.466.185-3.696 2.992-6.633 6.475-6.773m.42.123c3.318-.15 6.2 2.612 6.684 6.407.065.614.513 1.078 1.048 1.086h.057c.308-.002.6-.16.8-.43.2-.27.288-.628.242-.98C17.354 3.48 13.462-.234 9 .012"/>
|
3 |
-
</svg>
|
|
|
|
|
|
media/img/27.svg
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
2 |
-
<path fill="#F54586" fill-rule="evenodd" d="M4 1.474c.002.841.686 1.521 1.53 1.521L10.823 3l-5.63 5.633a1.503 1.503 0 0 0 .02 2.112c.584.58 1.526.588 2.12.017L13 5.188v5.296c0 .403.162.789.448 1.073.286.284.673.444 1.077.443a1.487 1.487 0 0 0 1.056-.45c.277-.285.427-.669.418-1.066V1.542a1.442 1.442 0 0 0-.467-1.046l.016-.017a1.465 1.465 0 0 0-1.055-.466L5.526.001A1.475 1.475 0 0 0 4 1.475zM.393 15.608a1.34 1.34 0 0 1 0-1.898l1.316-1.316a1.34 1.34 0 0 1 1.897-.001c.525.524.525 1.374.002 1.899l-1.316 1.316a1.343 1.343 0 0 1-1.899-.002v.002z"/>
|
3 |
-
</svg>
|
|
|
|
|
|
media/img/28.svg
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="22" viewBox="0 0 14 22">
|
2 |
-
<path fill="#D6D9E3" fill-rule="evenodd" d="M12.698 2.673L5.814 9.634h4.607c.365-.027.724.107.985.366a1.308 1.308 0 0 1 0 1.84l-9.098 9.196a1.277 1.277 0 0 1-1.243.337c-.444-.12-.79-.471-.91-.92a1.31 1.31 0 0 1 .334-1.256l6.887-6.962H2.769a1.26 1.26 0 0 1-.985-.366 1.308 1.308 0 0 1 0-1.84L10.882.834c.32-.35.804-.493 1.261-.376.457.118.814.48.93.941a1.31 1.31 0 0 1-.375 1.275z"/>
|
3 |
-
</svg>
|
|
|
|
|
|
media/img/29.svg
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="43" height="21" viewBox="0 0 43 21">
|
2 |
-
<path fill="#303CA5" fill-rule="evenodd" d="M42.671 19.304c-.144.498-.53.89-1.027 1.044a1.552 1.552 0 0 1-1.44-.281c-1.472-1.166-2.08-2.957-2.599-4.477-.675-1.985-1.122-3.125-2.46-3.482-1.337-.357-2.296.406-3.879 1.79-1.652 1.445-3.71 3.244-6.72 2.44-3.012-.803-3.889-3.385-4.595-5.46-.674-1.985-1.12-3.125-2.456-3.481-1.336-.357-2.295.406-3.877 1.79-1.652 1.446-3.709 3.245-6.72 2.441-3.01-.803-3.887-3.386-4.593-5.46C1.8 4.678 1.421 3.663.698 3.099A1.497 1.497 0 0 1 .16 1.53 1.552 1.552 0 0 1 2.63.767C4.1 1.933 4.71 3.724 5.224 5.243c.675 1.984 1.122 3.124 2.458 3.48 1.336.358 2.295-.405 3.876-1.79 1.653-1.445 3.71-3.244 6.72-2.44 3.01.803 3.888 3.385 4.593 5.46.674 1.985 1.121 3.124 2.457 3.481 1.337.357 2.298-.405 3.88-1.79 1.652-1.446 3.709-3.244 6.72-2.44 3.012.804 3.89 3.386 4.596 5.46.508 1.492.886 2.507 1.61 3.07.48.369.691.987.537 1.57z"/>
|
3 |
-
</svg>
|
|
|
|
|
|
media/img/34.svg
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="20" viewBox="0 0 22 20">
|
2 |
-
<path fill="#D6D9E3" fill-rule="evenodd" d="M20.374 11.944l-2.57 1.457-1.94 5.075c-.155.361-.506.603-.905.624a1.048 1.048 0 0 1-.968-.527l-1.33-2.26-5.141 2.914a1.523 1.523 0 0 1-1.138.136 1.494 1.494 0 0 1-.903-.692L.32 9.904A1.445 1.445 0 0 1 .159 8.79c.1-.378.348-.702.69-.9L13.705.608c.72-.4 1.633-.151 2.04.555l5.159 8.766c.203.336.26.737.162 1.115-.1.378-.348.702-.69.9z"/>
|
3 |
-
</svg>
|
|
|
|
|
|
media/img/4.svg
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="15" viewBox="0 0 21 15">
|
2 |
-
<path fill="#F8AA09" fill-rule="evenodd" d="M18.769 6.63l-3.68-3.562-3.582 3.463c-.026.03-.037.068-.065.097a1.385 1.385 0 0 1-1.882 0 1.05 1.05 0 0 1-.066-.097L5.911 3.068 2.21 6.648a1.34 1.34 0 0 1-1.827-.022A1.235 1.235 0 0 1 .36 4.86L4.904.466c.026-.03.036-.067.065-.096A1.33 1.33 0 0 1 5.893 0c.347 0 .68.133.925.37l3.68 3.56L14.08.466c.026-.03.037-.067.066-.096a1.385 1.385 0 0 1 1.882 0c.029.029.04.064.065.096l4.523 4.374c.33.32.46.785.34 1.221-.12.437-.473.778-.924.896a1.338 1.338 0 0 1-1.263-.326zM4.92 8.466c.026-.03.037-.068.066-.096A1.33 1.33 0 0 1 5.91 8c.346 0 .678.133.923.37l3.677 3.552 3.578-3.457c.026-.03.037-.068.066-.096a1.385 1.385 0 0 1 1.88 0c.03.029.04.064.065.096l4.519 4.365c.33.319.458.783.337 1.218-.12.436-.472.776-.923.892a1.337 1.337 0 0 1-1.261-.326l-3.676-3.555-3.577 3.456c-.026.03-.037.067-.066.096a1.384 1.384 0 0 1-1.88 0 1.053 1.053 0 0 1-.065-.096l-3.58-3.456L2.23 14.63a1.339 1.339 0 0 1-1.847 0 1.232 1.232 0 0 1 0-1.784L4.92 8.465z"/>
|
3 |
-
</svg>
|
|
|
|
|
|
media/img/8.svg
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="23" height="15" viewBox="0 0 23 15">
|
2 |
-
<path fill="#D6D9E3" fill-rule="evenodd" d="M18.099 8.113c-.201 1.937-1.297 3.692-2.995 4.795a7.331 7.331 0 0 1-6.831.579c-3.852 1.26-7.01 1.282-7.91-.196-.902-1.477.69-4.046 3.762-6.57.218-2.116 1.503-4.003 3.452-5.069a7.35 7.35 0 0 1 6.373-.304c3.854-1.262 7.01-1.283 7.911.195.901 1.478-.69 4.047-3.762 6.57zM2.771 11.965c.332.542 1.564.527 3.287.062a6.584 6.584 0 0 1-1.7-2.78c-1.289 1.178-1.919 2.175-1.587 2.718zM19.453 2.87c-.332-.543-1.564-.527-3.287-.063a6.583 6.583 0 0 1 1.699 2.78c1.29-1.177 1.92-2.174 1.588-2.717z"/>
|
3 |
-
</svg>
|
|
|
|
|
|
media/img/a-center.png
DELETED
Binary file
|
media/img/ajax-loader.gif
DELETED
Binary file
|
media/img/chevron.svg
DELETED
@@ -1,4 +0,0 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
2 |
-
<path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" fill="#bcc5d7"/>
|
3 |
-
<path d="M0 0h24v24H0z" fill="none"/>
|
4 |
-
</svg>
|
|
|
|
|
|
|
|
media/img/plus.svg
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="12" viewBox="0 0 13 12">
|
2 |
-
<path fill="#D6D9E3" fill-rule="evenodd" d="M8 0v4.5h4.5v3H8V12H5V7.499L.5 7.5v-3L5 4.499V0h3z"/>
|
3 |
-
</svg>
|
|
|
|
|
|
media/img/tidio-logo.svg
DELETED
@@ -1,8 +0,0 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
2 |
-
<g fill="none" fill-rule="nonzero">
|
3 |
-
<path fill="#135EEB" d="M15.2.554c-4.062 0-7.508 2.892-8.246 6.892.492-.061.984-.123 1.477-.123-.493 0-.985.062-1.477.123-4 .739-6.892 4.185-6.892 8.246V24H8.43c4 0 7.446-2.83 8.184-6.77H14.77 23.57V8.924c-.062-4.615-3.755-8.37-8.37-8.37zm-8.37 8.37z"/>
|
4 |
-
<path fill="#0A60EA" d="M8.43 7.323c-.492 0-.984.062-1.476.123-.062.492-.123.985-.123 1.477 0 4.615 3.754 8.37 8.369 8.308h1.415c.123-.493.123-1.046.123-1.6.062-4.554-3.692-8.246-8.307-8.308z"/>
|
5 |
-
<path fill="#15C2FF" d="M15.2 17.292c-4.615 0-8.37-3.692-8.37-8.307 0-.493.062-.985.124-1.477a8.266 8.266 0 0 0-6.892 8.184V24H8.43c4 0 7.446-2.83 8.184-6.77H15.2v.062z"/>
|
6 |
-
<path fill="#2C82FF" d="M15.2.554c-4.062 0-7.508 2.892-8.246 6.892.492-.061.984-.123 1.477-.123 4.615 0 8.369 3.692 8.369 8.308 0 .554-.062 1.046-.123 1.6h6.892V8.923C23.508 4.308 19.815.553 15.2.553z"/>
|
7 |
-
</g>
|
8 |
-
</svg>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
media/img/wp-logo.svg
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28px" height="28px" viewBox="0 0 28 28" version="1.1">
|
3 |
-
<g id="surface1">
|
4 |
-
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(19.607843%,21.568627%,23.529412%);fill-opacity:1;" d="M 14.035156 0.078125 C 6.324219 0.078125 0.078125 6.324219 0.078125 14.035156 C 0.078125 21.742188 6.324219 27.992188 14.035156 27.992188 C 21.742188 27.992188 27.992188 21.742188 27.992188 14.035156 C 27.992188 6.324219 21.742188 0.078125 14.035156 0.078125 M 14.035156 0.914062 C 16.648438 0.90625 19.203125 1.6875 21.367188 3.152344 C 22.765625 4.097656 23.96875 5.300781 24.914062 6.699219 C 26.378906 8.863281 27.160156 11.417969 27.152344 14.03125 C 27.160156 16.648438 26.378906 19.203125 24.914062 21.367188 C 23.96875 22.765625 22.765625 23.96875 21.367188 24.914062 C 19.203125 26.378906 16.648438 27.160156 14.035156 27.152344 C 11.417969 27.160156 8.863281 26.378906 6.699219 24.914062 C 5.300781 23.96875 4.097656 22.765625 3.152344 21.367188 C 1.6875 19.203125 0.90625 16.648438 0.914062 14.035156 C 0.90625 11.417969 1.6875 8.863281 3.152344 6.699219 C 4.097656 5.300781 5.300781 4.097656 6.699219 3.152344 C 8.863281 1.6875 11.417969 0.90625 14.03125 0.914062 "/>
|
5 |
-
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(19.607843%,21.568627%,23.529412%);fill-opacity:1;" d="M 24.242188 8.453125 C 24.292969 8.824219 24.320312 9.222656 24.320312 9.648438 C 24.320312 10.828125 24.097656 12.15625 23.433594 13.816406 L 19.882812 24.085938 C 23.464844 22.003906 25.667969 18.175781 25.664062 14.03125 C 25.667969 12.082031 25.179688 10.164062 24.242188 8.453125 Z M 14.238281 15.050781 L 10.75 25.191406 C 13.089844 25.882812 15.59375 25.816406 17.898438 25.007812 C 17.863281 24.957031 17.835938 24.902344 17.8125 24.847656 Z M 21.886719 13.449219 C 21.886719 12.007812 21.371094 11.015625 20.925781 10.238281 C 20.339844 9.28125 19.785156 8.46875 19.785156 7.511719 C 19.785156 6.441406 20.59375 5.445312 21.738281 5.445312 C 21.789062 5.445312 21.839844 5.453125 21.886719 5.457031 C 19.746094 3.488281 16.941406 2.398438 14.035156 2.402344 C 10.117188 2.398438 6.464844 4.371094 4.316406 7.644531 C 4.589844 7.652344 4.84375 7.65625 5.0625 7.65625 C 6.28125 7.65625 8.164062 7.511719 8.164062 7.511719 C 8.789062 7.476562 8.863281 8.394531 8.238281 8.46875 C 8.238281 8.46875 7.609375 8.542969 6.90625 8.578125 L 11.144531 21.179688 L 13.6875 13.546875 L 11.878906 8.578125 C 11.46875 8.554688 11.0625 8.515625 10.65625 8.46875 C 10.027344 8.429688 10.101562 7.472656 10.730469 7.507812 C 10.730469 7.507812 12.652344 7.65625 13.792969 7.65625 C 15.011719 7.65625 16.894531 7.507812 16.894531 7.507812 C 17.523438 7.472656 17.59375 8.394531 16.96875 8.46875 C 16.96875 8.46875 16.335938 8.542969 15.636719 8.578125 L 19.839844 21.082031 L 21.039062 17.28125 C 21.574219 15.617188 21.886719 14.441406 21.886719 13.445312 Z M 2.402344 14.03125 C 2.402344 18.492188 4.945312 22.554688 8.957031 24.5 L 3.410156 9.300781 C 2.742188 10.789062 2.402344 12.402344 2.402344 14.035156 Z M 2.402344 14.03125 "/>
|
6 |
-
</g>
|
7 |
-
</svg>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
media/js/options.js
DELETED
@@ -1,341 +0,0 @@
|
|
1 |
-
/* global jQuery */
|
2 |
-
jQuery(function ($) {
|
3 |
-
const { __ } = wp.i18n;
|
4 |
-
|
5 |
-
var TidioChatWP = {
|
6 |
-
nonce: tidioConfig.nonce,
|
7 |
-
apiUrl: tidioConfig.apiUrl,
|
8 |
-
panelUrl: tidioConfig.panelUrl,
|
9 |
-
token: null,
|
10 |
-
email: '',
|
11 |
-
translate: message => __(message, 'tidio-live-chat'),
|
12 |
-
init: function () {
|
13 |
-
this.error = $('.error');
|
14 |
-
this.form = $('#tidio-start');
|
15 |
-
this.form.show();
|
16 |
-
var emailField = this.form.find('#email');
|
17 |
-
emailField.val('');
|
18 |
-
this.form.off().submit(this.onStartSubmit.bind(this));
|
19 |
-
},
|
20 |
-
onStartSubmit: function () {
|
21 |
-
var emailField = this.form.find('#email');
|
22 |
-
var submitButton = this.form.find('button');
|
23 |
-
if (emailField.val() === '') {
|
24 |
-
this.showError(this.translate('Can’t be empty!'));
|
25 |
-
return false;
|
26 |
-
}
|
27 |
-
if (emailField.is(':invalid')) {
|
28 |
-
this.showError(this.translate('Email is invalid!'));
|
29 |
-
return false;
|
30 |
-
}
|
31 |
-
this.hideError();
|
32 |
-
this.email = emailField.val();
|
33 |
-
submitButton.prop('disabled', true).text(this.translate('Loading...'));
|
34 |
-
|
35 |
-
$.get(TidioChatWP.apiUrl + '/access/checkIfEmailIsRegistered', {
|
36 |
-
email: emailField.val(),
|
37 |
-
}).done(function (data) {
|
38 |
-
if (data.status === true && data.value &&
|
39 |
-
data.value.registered === true) {
|
40 |
-
this.form.hide();
|
41 |
-
submitButton.prop('disabled', false).text(this.translate('Start using Tidio'));
|
42 |
-
this.showLoginForm(emailField.val());
|
43 |
-
} else {
|
44 |
-
this.redirectToPanel();
|
45 |
-
}
|
46 |
-
}.bind(this)).fail((function(error) {
|
47 |
-
submitButton.prop('disabled', false).text(this.translate('Start using Tidio'));
|
48 |
-
if (error && error.status === 429) {
|
49 |
-
this.showError(this.translate('You have been blocked for too many attempts. Please try again in an hour.'));
|
50 |
-
} else {
|
51 |
-
this.showError(this.translate('Something went wrong.'));
|
52 |
-
}
|
53 |
-
|
54 |
-
}).bind(this));
|
55 |
-
return false;
|
56 |
-
},
|
57 |
-
showError: function (message) {
|
58 |
-
this.error.text(message).fadeIn();
|
59 |
-
},
|
60 |
-
hideError: function () {
|
61 |
-
this.error.hide();
|
62 |
-
},
|
63 |
-
showLoginForm: function (emailValue) {
|
64 |
-
this.form = $('#tidio-login');
|
65 |
-
this.form.css('display', 'flex');
|
66 |
-
var emailField = this.form.find('#email');
|
67 |
-
emailField.val(emailValue);
|
68 |
-
var passwordField = this.form.find('#password');
|
69 |
-
passwordField.val('');
|
70 |
-
|
71 |
-
this.form.off().submit(this.onLoginSubmit.bind(this));
|
72 |
-
},
|
73 |
-
onLoginSubmit: function () {
|
74 |
-
var emailField = this.form.find('#email');
|
75 |
-
var passwordField = this.form.find('#password');
|
76 |
-
var submitButton = this.form.find('button');
|
77 |
-
if (emailField.val() === '') {
|
78 |
-
this.showError(this.translate('Email can’t be empty!'));
|
79 |
-
return false;
|
80 |
-
}
|
81 |
-
if (emailField.is(':invalid')) {
|
82 |
-
this.showError(this.translate('Email is invalid!'));
|
83 |
-
return false;
|
84 |
-
}
|
85 |
-
if (passwordField.val() === '') {
|
86 |
-
this.showError(this.translate('Password can’t be empty!'));
|
87 |
-
return false;
|
88 |
-
}
|
89 |
-
this.hideError();
|
90 |
-
submitButton.prop('disabled', true).text(this.translate('Loading...'));
|
91 |
-
|
92 |
-
var email = emailField.val();
|
93 |
-
var password = document.querySelector(
|
94 |
-
'#tidio-login #password').value;
|
95 |
-
|
96 |
-
$.get(TidioChatWP.apiUrl + '/access/getUserToken', {
|
97 |
-
email: email,
|
98 |
-
password: password,
|
99 |
-
})
|
100 |
-
.done(function (data) {
|
101 |
-
TidioChatWP.token = data.value;
|
102 |
-
this.getProjects(TidioChatWP.token);
|
103 |
-
}.bind(this))
|
104 |
-
.fail(function (error) {
|
105 |
-
const statusCode = error?.status;
|
106 |
-
if (statusCode === 401) {
|
107 |
-
this.showError(this.translate('Wrong email or password'));
|
108 |
-
} else if (statusCode === 429) {
|
109 |
-
this.showError(this.translate('You have been blocked for too many attempts. Please try again in an hour.'));
|
110 |
-
} else {
|
111 |
-
this.showError(this.translate('Something went wrong.'));
|
112 |
-
}
|
113 |
-
}.bind(this))
|
114 |
-
.always(function() {
|
115 |
-
submitButton.prop('disabled', false).text(this.translate('Go to Tidio panel'));
|
116 |
-
}.bind(this));
|
117 |
-
|
118 |
-
return false;
|
119 |
-
},
|
120 |
-
addEmailToRedirectLink: function(url) {
|
121 |
-
return url + '&tour_default_email=' + encodeURIComponent(this.email);
|
122 |
-
},
|
123 |
-
redirectToPanel: function () {
|
124 |
-
var redirect = function (response) {
|
125 |
-
var url = this.addEmailToRedirectLink(response);
|
126 |
-
window.open(url, '_blank');
|
127 |
-
TidioChatWP.setRedirectLink(url);
|
128 |
-
this.form.fadeOut('fast', function () {
|
129 |
-
$('#after-install-text').fadeIn('fast');
|
130 |
-
});
|
131 |
-
}.bind(this);
|
132 |
-
|
133 |
-
$.post(ajaxurl, {
|
134 |
-
'action': 'get_private_key',
|
135 |
-
'_wpnonce': TidioChatWP.nonce,
|
136 |
-
},
|
137 |
-
function (response) {
|
138 |
-
if (response === 'error') {
|
139 |
-
// load through ajax url
|
140 |
-
TidioChatWP.accessThroughXHR(redirect);
|
141 |
-
return false;
|
142 |
-
}
|
143 |
-
redirect(response);
|
144 |
-
});
|
145 |
-
},
|
146 |
-
setRedirectLink: function (url) {
|
147 |
-
$('a[href="admin.php?page=tidio-chat"]').
|
148 |
-
attr('href', url).
|
149 |
-
attr('target', '_blank');
|
150 |
-
$('#open-panel-link').attr('href', url);
|
151 |
-
},
|
152 |
-
renderProjects: function (data) {
|
153 |
-
var select_project = $('#select-tidio-project');
|
154 |
-
var defaultOption = select_project.children()[0];
|
155 |
-
select_project.children().remove();
|
156 |
-
select_project.append(defaultOption);
|
157 |
-
var selected = false;
|
158 |
-
if (data.value.length === 1) {
|
159 |
-
selected = true;
|
160 |
-
}
|
161 |
-
for (var i in data.value) {
|
162 |
-
var project = data.value[i];
|
163 |
-
var value = {
|
164 |
-
project_id: project.id,
|
165 |
-
private_key: project.private_key,
|
166 |
-
public_key: project.public_key,
|
167 |
-
};
|
168 |
-
|
169 |
-
var option = $(
|
170 |
-
'<option value="' + project.id + '" ' + (selected ? 'selected="selected"' : '') + '>' + project.name +
|
171 |
-
'</option>');
|
172 |
-
option.data('value', value);
|
173 |
-
select_project.append(option);
|
174 |
-
}
|
175 |
-
this.renderCustomSelect();
|
176 |
-
|
177 |
-
},
|
178 |
-
getProjects: function (token) {
|
179 |
-
$.get(TidioChatWP.apiUrl + '/project', {
|
180 |
-
api_token: token,
|
181 |
-
}, (function (response) {
|
182 |
-
if (response.value.length === 1) {
|
183 |
-
this.renderProjects(response);
|
184 |
-
this.onProjectSubmit();
|
185 |
-
} else {
|
186 |
-
this.form.hide();
|
187 |
-
this.form = $('#tidio-project');
|
188 |
-
this.form.show();
|
189 |
-
this.renderProjects(response);
|
190 |
-
this.form.off().submit(this.onProjectSubmit.bind(this));
|
191 |
-
var startOver = $('#start-over');
|
192 |
-
startOver.click(this.startOver.bind(this));
|
193 |
-
}
|
194 |
-
}).bind(this), 'json');
|
195 |
-
},
|
196 |
-
onProjectSubmit: function () {
|
197 |
-
var details = $('#select-tidio-project option:selected').data('value');
|
198 |
-
$.extend(details, {
|
199 |
-
'action': 'set_project_keys',
|
200 |
-
'api_token': TidioChatWP.token,
|
201 |
-
'_wpnonce': TidioChatWP.nonce,
|
202 |
-
});
|
203 |
-
|
204 |
-
$.post(ajaxurl, details, (function (response) {
|
205 |
-
var url = this.addEmailToRedirectLink(response);
|
206 |
-
window.open(url, '_blank');
|
207 |
-
TidioChatWP.setRedirectLink(url);
|
208 |
-
this.form.fadeOut('fast', function () {
|
209 |
-
$('#after-install-text').fadeIn('fast');
|
210 |
-
});
|
211 |
-
}).bind(this));
|
212 |
-
return false;
|
213 |
-
},
|
214 |
-
startOver: function () {
|
215 |
-
this.deleteCustomSelect();
|
216 |
-
this.form.hide();
|
217 |
-
this.init();
|
218 |
-
},
|
219 |
-
deleteCustomSelect: function() {
|
220 |
-
var selectSelected = this.form.find('.custom-select .select-selected');
|
221 |
-
if (selectSelected.length) {
|
222 |
-
selectSelected.off().remove();
|
223 |
-
}
|
224 |
-
var selectItems = this.form.find('.custom-select .select-items');
|
225 |
-
if (selectItems.length) {
|
226 |
-
selectItems.off().remove();
|
227 |
-
}
|
228 |
-
},
|
229 |
-
renderCustomSelect: function () {
|
230 |
-
|
231 |
-
var customSelect, i, j, select, selectedItem, options, option;
|
232 |
-
/* Look for any elements with the class "custom-select": */
|
233 |
-
customSelect = document.getElementsByClassName('custom-select');
|
234 |
-
for (i = 0; i < customSelect.length; i++) {
|
235 |
-
select = customSelect[i].getElementsByTagName('select')[0];
|
236 |
-
/* For each element, create a new DIV that will act as the selected item: */
|
237 |
-
selectedItem = document.createElement('DIV');
|
238 |
-
selectedItem.setAttribute('class', 'select-selected disabled');
|
239 |
-
selectedItem.innerHTML = select.options[select.selectedIndex].innerHTML;
|
240 |
-
customSelect[i].appendChild(selectedItem);
|
241 |
-
/* For each element, create a new DIV that will contain the option list: */
|
242 |
-
options = document.createElement('DIV');
|
243 |
-
options.setAttribute('class', 'select-items select-hide');
|
244 |
-
for (j = 1; j < select.length; j++) {
|
245 |
-
/* For each option in the original select element,
|
246 |
-
create a new DIV that will act as an option item: */
|
247 |
-
option = document.createElement('DIV');
|
248 |
-
option.innerHTML = select.options[j].innerHTML;
|
249 |
-
option.addEventListener('click', function () {
|
250 |
-
/* When an item is clicked, update the original select box,
|
251 |
-
and the selected item: */
|
252 |
-
var y, i, k, s, h;
|
253 |
-
s = this.parentNode.parentNode.getElementsByTagName(
|
254 |
-
'select')[0];
|
255 |
-
h = this.parentNode.previousSibling;
|
256 |
-
for (i = 0; i < s.length; i++) {
|
257 |
-
if (s.options[i].innerHTML === this.innerHTML) {
|
258 |
-
s.selectedIndex = i;
|
259 |
-
h.innerHTML = this.innerHTML;
|
260 |
-
y = this.parentNode.getElementsByClassName(
|
261 |
-
'same-as-selected');
|
262 |
-
for (k = 0; k < y.length; k++) {
|
263 |
-
y[k].removeAttribute('class');
|
264 |
-
}
|
265 |
-
this.setAttribute('class', 'same-as-selected');
|
266 |
-
break;
|
267 |
-
}
|
268 |
-
}
|
269 |
-
h.click();
|
270 |
-
});
|
271 |
-
options.appendChild(option);
|
272 |
-
}
|
273 |
-
customSelect[i].appendChild(options);
|
274 |
-
selectedItem.addEventListener('click', function (event) {
|
275 |
-
/* When the select box is clicked, close any other select boxes,
|
276 |
-
and open/close the current select box: */
|
277 |
-
event.stopPropagation();
|
278 |
-
event.preventDefault();
|
279 |
-
closeAllSelect(this);
|
280 |
-
this.nextSibling.classList.toggle('select-hide');
|
281 |
-
this.classList.toggle('select-arrow-active');
|
282 |
-
if (!this.classList.contains('select-arrow-active')) {
|
283 |
-
this.classList.remove('disabled');
|
284 |
-
}
|
285 |
-
});
|
286 |
-
}
|
287 |
-
|
288 |
-
function closeAllSelect(element) {
|
289 |
-
/* A function that will close all select boxes in the document,
|
290 |
-
except the current select box: */
|
291 |
-
var items, selected, i, arrNo = [];
|
292 |
-
items = document.getElementsByClassName('select-items');
|
293 |
-
selected = document.getElementsByClassName('select-selected');
|
294 |
-
for (i = 0; i < selected.length; i++) {
|
295 |
-
if (element == selected[i]) {
|
296 |
-
arrNo.push(i);
|
297 |
-
} else {
|
298 |
-
selected[i].classList.remove('select-arrow-active');
|
299 |
-
}
|
300 |
-
}
|
301 |
-
for (i = 0; i < items.length; i++) {
|
302 |
-
if (arrNo.indexOf(i)) {
|
303 |
-
items[i].classList.add('select-hide');
|
304 |
-
}
|
305 |
-
}
|
306 |
-
}
|
307 |
-
|
308 |
-
/* If the user clicks anywhere outside the select box,
|
309 |
-
then close all select boxes: */
|
310 |
-
document.addEventListener('click', closeAllSelect);
|
311 |
-
},
|
312 |
-
accessThroughXHR: function (_func) {
|
313 |
-
|
314 |
-
var xhr_url = TidioChatWP.apiUrl + '/access/external/create?url=' +
|
315 |
-
location.protocol + '//' + location.host +
|
316 |
-
'&platform=wordpress';
|
317 |
-
$.getJSON(xhr_url, {}, function (r) {
|
318 |
-
if (!r || !r.value) {
|
319 |
-
alert(this.translate('Error occured while creating, please try again!'));
|
320 |
-
return false;
|
321 |
-
}
|
322 |
-
_func(TidioChatWP.panelUrl + '/access?privateKey=' +
|
323 |
-
r.value.private_key +
|
324 |
-
'&app=chat&utm_source=platform&utm_medium=wordpress');
|
325 |
-
|
326 |
-
// save this in wordpress database
|
327 |
-
$.post(ajaxurl, {
|
328 |
-
'action': 'tidio_chat_save_keys',
|
329 |
-
'public_key': r.value.public_key,
|
330 |
-
'private_key': r.value.private_key,
|
331 |
-
'_wpnonce': TidioChatWP.nonce,
|
332 |
-
});
|
333 |
-
}).fail(function () {
|
334 |
-
alert(this.translate('Error occured while creating, please try again!'));
|
335 |
-
});
|
336 |
-
|
337 |
-
},
|
338 |
-
};
|
339 |
-
|
340 |
-
TidioChatWP.init();
|
341 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
options.php
DELETED
@@ -1,61 +0,0 @@
|
|
1 |
-
<div id="tidio-wrapper">
|
2 |
-
<div class="tidio-box-wrapper">
|
3 |
-
<div class="tidio-box tidio-box-actions">
|
4 |
-
<div class="logos">
|
5 |
-
<div class="logo tidio-logo"></div>
|
6 |
-
<div class="logo wp-logo"></div>
|
7 |
-
</div>
|
8 |
-
<form novalidate id="tidio-start">
|
9 |
-
<h1><?php i18n::_e('Start using Tidio');?></h1>
|
10 |
-
<label>
|
11 |
-
<?php i18n::_e('Email Address');?>
|
12 |
-
<input type="email" id="email" placeholder="e.g. tidius@tidio.com" required/>
|
13 |
-
</label>
|
14 |
-
|
15 |
-
<div class="error"></div>
|
16 |
-
<button><?php i18n::_e('Let’s go');?></button>
|
17 |
-
</form>
|
18 |
-
<form novalidate id="tidio-login">
|
19 |
-
<h1><?php i18n::_e('Log into your account');?></h1>
|
20 |
-
<label>
|
21 |
-
<?php i18n::_e('Email Address');?>
|
22 |
-
<input type="email" id="email" placeholder="e.g. tidius@tidio.com" required/>
|
23 |
-
</label>
|
24 |
-
|
25 |
-
<label>
|
26 |
-
<?php i18n::_e('Password');?>
|
27 |
-
<input type="password" id="password" placeholder="<?php i18n::_e('Type your password');?>…" required/>
|
28 |
-
</label>
|
29 |
-
|
30 |
-
<div class="error"></div>
|
31 |
-
<button><?php i18n::_e('Go to Tidio panel');?></button>
|
32 |
-
<a class="button btn-link" href="https://www.tidio.com/panel/forgot-password" target="_blank"><?php i18n::_e('Forgot password?');?></a>
|
33 |
-
</form>
|
34 |
-
<form novalidate id="tidio-project">
|
35 |
-
<h1><?php i18n::_e('Choose your project');?></h1>
|
36 |
-
<label>
|
37 |
-
<?php i18n::_e('Choose your project');?>
|
38 |
-
<div class="custom-select">
|
39 |
-
<select name="select-tidio-project" id="select-tidio-project">
|
40 |
-
<option selected="selected" disabled><?php i18n::_e('Pick one from the list');?>…</option>
|
41 |
-
</select>
|
42 |
-
</div>
|
43 |
-
</label>
|
44 |
-
|
45 |
-
<div class="error"></div>
|
46 |
-
<button><?php i18n::_e('Go to Tidio panel');?></button>
|
47 |
-
<button type="button" id="start-over" class="btn-link"><?php i18n::_e('Start all over again');?></button>
|
48 |
-
</form>
|
49 |
-
<form id="after-install-text">
|
50 |
-
<h1><?php i18n::_e('Your site is already integrated with Tidio Chat');?></h1>
|
51 |
-
<p><?php i18n::_e('All you need to do now is select the “Tidio Chat” tab on the left - that will take you to your Tidio panel. You can also open the panel by using the link below.');?></p>
|
52 |
-
<a href="#" id="open-panel-link" class="button" target="_blank"><?php i18n::_e('Go to Panel');?></a>
|
53 |
-
</form>
|
54 |
-
</div>
|
55 |
-
<div class="tidio-box tidio-box-george">
|
56 |
-
<h2><?php i18n::_e('Join 300 000+ websites using Tidio - Live Chat boosted with Bots');?></h2>
|
57 |
-
<p><?php i18n::_e('Increase sales by skyrocketing communication with customers.');?></p>
|
58 |
-
<div class="tidio-box-george-image"></div>
|
59 |
-
</div>
|
60 |
-
</div>
|
61 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
readme.txt
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
=== Tidio – Live Chat, Chatbots & Email Integration ===
|
2 |
-
Contributors: tytus-tytus, lucastidio, marcingwizdala, kkopaczyktidio
|
3 |
Tags: free live chat, live chat, chat, chatbot, livechat, tidio, widget, zendesk, mailchimp, messenger
|
4 |
-
Requires at least:
|
5 |
-
Tested up to:
|
6 |
-
|
|
|
7 |
License: GPLv2
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -13,7 +14,7 @@ Add Tidio Live Chat to your WordPress for free to answer customers’ questions,
|
|
13 |
|
14 |
Looking for an easy-to-use live chat plugin for your WordPress website? **Tidio offers this and plenty more.**
|
15 |
|
16 |
-
It’s a multifunctional customer service platform that enables you to offer world-class customer support and actively generate more leads and sales. Tidio offers [live chat](https://www.tidio.com/live-chat/) and [chatbots](https://www.tidio.com/chatbots/) as well as [
|
17 |
|
18 |
But don't take our word for it—experience it yourself! Our plugin is completely free, and the installation takes under 5 minutes.
|
19 |
|
@@ -55,6 +56,12 @@ See how live chat can boost your sales
|
|
55 |
Never used chatbots before? Check our video guide
|
56 |
[youtube https://www.youtube.com/watch?v=-LUChIx9UW8]
|
57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
## Selected Tidio features:
|
59 |
|
60 |
- A lightweight and customizable widget that will work great with your branding and is 100% mobile-friendly
|
@@ -74,6 +81,12 @@ Never used chatbots before? Check our video guide
|
|
74 |
- Tidio Live Chat and Chatbot is the **highest rated plugin of this type for WordPress**
|
75 |
- The solution is actively used by **275,000 users … and growing**
|
76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
Hard to believe it? Read the testimonials, because our users say it best:
|
78 |
|
79 |
## TESTIMONIALS
|
@@ -137,7 +150,7 @@ After activating the plugin, create your account and start the product tour. Fol
|
|
137 |
|
138 |
== Frequently Asked Questions ==
|
139 |
= How much does Tidio Live Chat cost? =
|
140 |
-
Tidio is free and we don’t need your card details. Later on, you can unlock additional premium features for a small price starting from
|
141 |
= I’ve installed the WordPress chat plugin—what happens next? =
|
142 |
Click on the new Tidio live chat icon that appeared on your WP-admin menu on the left. You'll be able to create your Tidio account connected to the plugin. Finish the initial configuration and you can start using the best live chat plugin for WordPress.
|
143 |
= Do I need a Tidio account to use this WordPress live chat plugin? =
|
@@ -160,7 +173,7 @@ Yes. Apart from the tips available inside the tool itself, you can learn more ab
|
|
160 |
- [Case Studies](https://www.tidio.com/case-studies/)
|
161 |
|
162 |
= Can several support agents use the free chat at the same time? =
|
163 |
-
Yes. You can also transfer conversations between operators. The free plan has
|
164 |
= Can visitors start chatting without providing their email address? =
|
165 |
Yes, but you need to switch off the pre-chat survey. By default, Tidio shows a survey that visitors have to fill in before joining a live chat conversation.
|
166 |
= Can I check if I missed any messages from my visitors? =
|
@@ -185,6 +198,10 @@ Currently, Tidio is available in English and French. Other languages are in deve
|
|
185 |
|
186 |
== Changelog ==
|
187 |
|
|
|
|
|
|
|
|
|
188 |
= 4.5.1 =
|
189 |
|
190 |
- Add missing "tidioApiUrl" value in options.js file
|
1 |
=== Tidio – Live Chat, Chatbots & Email Integration ===
|
2 |
+
Contributors: tytus-tytus, lucastidio, marcingwizdala, kkopaczyktidio, ksladek, adrianmtidio
|
3 |
Tags: free live chat, live chat, chat, chatbot, livechat, tidio, widget, zendesk, mailchimp, messenger
|
4 |
+
Requires at least: 4.7
|
5 |
+
Tested up to: 6.0
|
6 |
+
Requires PHP: 5.6
|
7 |
+
Stable tag: 5.0.0
|
8 |
License: GPLv2
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
14 |
|
15 |
Looking for an easy-to-use live chat plugin for your WordPress website? **Tidio offers this and plenty more.**
|
16 |
|
17 |
+
It’s a multifunctional customer service platform that enables you to offer world-class customer support and actively generate more leads and sales. Tidio offers [live chat](https://www.tidio.com/live-chat/) and [chatbots](https://www.tidio.com/chatbots/) as well as [Messenger](https://help.tidio.com/docs/messenger-integration-with-tidio), [Instagram](https://help.tidio.com/docs/integration-with-instagram) and [email](https://help.tidio.com/docs/external-mailbox-integration) integration so **you can manage all these channels in one panel**.
|
18 |
|
19 |
But don't take our word for it—experience it yourself! Our plugin is completely free, and the installation takes under 5 minutes.
|
20 |
|
56 |
Never used chatbots before? Check our video guide
|
57 |
[youtube https://www.youtube.com/watch?v=-LUChIx9UW8]
|
58 |
|
59 |
+
## Automated customer support - for even better experience.
|
60 |
+
Built-in chatbots can automatically answer most common customer questions about order status, product availability and delivery time. This kind of virtual assistant will not only support your customers 24/7, but save your time!
|
61 |
+
|
62 |
+
## Smart Pop ups that improve conversion without irritating your customers
|
63 |
+
We all know that pop ups can boost sales, but they can also be frustrating for visitors. Ready-made Tidio chatbot scenarios can turn the live chat widget into smart pop ups. They can be triggered by defined action and fully customized. You can edit all the conditions, text and images using our drag&drop chatbot editor.
|
64 |
+
|
65 |
## Selected Tidio features:
|
66 |
|
67 |
- A lightweight and customizable widget that will work great with your branding and is 100% mobile-friendly
|
81 |
- Tidio Live Chat and Chatbot is the **highest rated plugin of this type for WordPress**
|
82 |
- The solution is actively used by **275,000 users … and growing**
|
83 |
|
84 |
+
|
85 |
+
## To run Tidio plugin for WordPress we recommend your host supports:
|
86 |
+
|
87 |
+
- **OpenSSL** (to increase security by encrypting your access tokens)
|
88 |
+
- **cURL**
|
89 |
+
|
90 |
Hard to believe it? Read the testimonials, because our users say it best:
|
91 |
|
92 |
## TESTIMONIALS
|
150 |
|
151 |
== Frequently Asked Questions ==
|
152 |
= How much does Tidio Live Chat cost? =
|
153 |
+
Tidio is free and we don’t need your card details. Later on, you can unlock additional premium features for a small price starting from $33 per month.
|
154 |
= I’ve installed the WordPress chat plugin—what happens next? =
|
155 |
Click on the new Tidio live chat icon that appeared on your WP-admin menu on the left. You'll be able to create your Tidio account connected to the plugin. Finish the initial configuration and you can start using the best live chat plugin for WordPress.
|
156 |
= Do I need a Tidio account to use this WordPress live chat plugin? =
|
173 |
- [Case Studies](https://www.tidio.com/case-studies/)
|
174 |
|
175 |
= Can several support agents use the free chat at the same time? =
|
176 |
+
Yes. You can also transfer conversations between operators. The free plan has 2 operator seats. It means that 2 operators (and an unlimited number of customers) can use the live chat at once for free. You can also buy extra seats if your support team grows.
|
177 |
= Can visitors start chatting without providing their email address? =
|
178 |
Yes, but you need to switch off the pre-chat survey. By default, Tidio shows a survey that visitors have to fill in before joining a live chat conversation.
|
179 |
= Can I check if I missed any messages from my visitors? =
|
198 |
|
199 |
== Changelog ==
|
200 |
|
201 |
+
= 5.0.0 =
|
202 |
+
|
203 |
+
- New integration flow based on OAuth
|
204 |
+
|
205 |
= 4.5.1 =
|
206 |
|
207 |
- Add missing "tidioApiUrl" value in options.js file
|
src/Admin/TidioAdminActionLink.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioAdminActionLink
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var TidioIntegrationState
|
7 |
+
*/
|
8 |
+
private $integrationState;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param TidioIntegrationState $integrationsState
|
12 |
+
*/
|
13 |
+
public function __construct($integrationsState)
|
14 |
+
{
|
15 |
+
$this->integrationState = $integrationsState;
|
16 |
+
|
17 |
+
add_filter('plugin_action_links', [$this, 'addPluginActionLinks'], 10, 2);
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @param string[] $links
|
22 |
+
* @param string $file
|
23 |
+
* @return string[]
|
24 |
+
*/
|
25 |
+
public function addPluginActionLinks($links, $file)
|
26 |
+
{
|
27 |
+
if (!$this->isPluginConfigurationFile($file) ||
|
28 |
+
!$this->integrationState->isPluginIntegrated()
|
29 |
+
) {
|
30 |
+
return $links;
|
31 |
+
}
|
32 |
+
|
33 |
+
$links[] = $this->prepareClearAccountDataActionLink();
|
34 |
+
$links[] = $this->prepareToggleAsyncLoadingActionLink();
|
35 |
+
|
36 |
+
return $links;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @param string $file
|
41 |
+
* @return bool
|
42 |
+
*/
|
43 |
+
private function isPluginConfigurationFile($file)
|
44 |
+
{
|
45 |
+
return strpos($file, TidioLiveChat::TIDIO_PLUGIN_NAME) !== false;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @return string
|
50 |
+
*/
|
51 |
+
private function prepareClearAccountDataActionLink()
|
52 |
+
{
|
53 |
+
return sprintf(
|
54 |
+
'<a href="%s">%s</a>',
|
55 |
+
TidioAdminRouting::getEndpointForClearAccountDataAction(),
|
56 |
+
esc_html(i18n::_t('Clear Account Data'))
|
57 |
+
);
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @return string
|
62 |
+
*/
|
63 |
+
private function prepareToggleAsyncLoadingActionLink()
|
64 |
+
{
|
65 |
+
$toggleAsyncLabel = '✘';
|
66 |
+
$onclickPart = '';
|
67 |
+
if ($this->integrationState->isAsyncLoadingTurnedOn()) {
|
68 |
+
$toggleAsyncLabel = '✓';
|
69 |
+
$onclickPart = sprintf(
|
70 |
+
'onclick="return confirm(\'%s\');"',
|
71 |
+
i18n::_t('Disabling asynchronous loading of the chat widget may affect the page loading time of your website. Are you sure you want to disable the asynchronous loading?')
|
72 |
+
);
|
73 |
+
}
|
74 |
+
|
75 |
+
return sprintf(
|
76 |
+
'<a href="%s" %s>%s</a>',
|
77 |
+
TidioAdminRouting::getEndpointForToggleAsyncLoadingAction(),
|
78 |
+
$onclickPart,
|
79 |
+
esc_html(
|
80 |
+
sprintf('%s %s', $toggleAsyncLabel, i18n::_t('Asynchronous loading'))
|
81 |
+
)
|
82 |
+
);
|
83 |
+
}
|
84 |
+
}
|
src/Admin/TidioAdminController.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioAdminController
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var TidioIntegrationFacade
|
7 |
+
*/
|
8 |
+
private $integrationFacade;
|
9 |
+
/**
|
10 |
+
* @var TidioIntegrationState
|
11 |
+
*/
|
12 |
+
private $integrationState;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param TidioIntegrationFacade $integrationFacade
|
16 |
+
* @param TidioIntegrationState $integrationState
|
17 |
+
*/
|
18 |
+
public function __construct($integrationFacade, $integrationState)
|
19 |
+
{
|
20 |
+
$this->integrationFacade = $integrationFacade;
|
21 |
+
$this->integrationState = $integrationState;
|
22 |
+
}
|
23 |
+
|
24 |
+
public function handleIntegrateProjectAction()
|
25 |
+
{
|
26 |
+
if (!$this->isRequestNonceValid(TidioAdminRouting::INTEGRATE_PROJECT_ACTION)) {
|
27 |
+
wp_die('', 403);
|
28 |
+
}
|
29 |
+
|
30 |
+
$refreshToken = QueryParameters::get('refreshToken');
|
31 |
+
try {
|
32 |
+
$data = $this->integrationFacade->integrateProject($refreshToken);
|
33 |
+
} catch (TidioApiException $exception) {
|
34 |
+
$errorCode = $exception->getMessage();
|
35 |
+
$this->redirectToPluginAdminDashboardWithError($errorCode);
|
36 |
+
}
|
37 |
+
|
38 |
+
$this->integrationState->integrate(
|
39 |
+
$data['projectPublicKey'],
|
40 |
+
$data['accessToken'],
|
41 |
+
$data['refreshToken']
|
42 |
+
);
|
43 |
+
|
44 |
+
$this->redirectToPluginAdminDashboard();
|
45 |
+
}
|
46 |
+
|
47 |
+
public function handleToggleAsyncLoadingAction()
|
48 |
+
{
|
49 |
+
if (!$this->isRequestNonceValid(TidioAdminRouting::TOGGLE_ASYNC_LOADING_ACTION)) {
|
50 |
+
wp_die('', 403);
|
51 |
+
}
|
52 |
+
|
53 |
+
$this->integrationState->toggleAsyncLoading();
|
54 |
+
|
55 |
+
$this->redirectToPluginsListDashboard();
|
56 |
+
}
|
57 |
+
|
58 |
+
public function handleClearAccountDataAction()
|
59 |
+
{
|
60 |
+
if (!$this->isRequestNonceValid(TidioAdminRouting::CLEAR_ACCOUNT_DATA_ACTION)) {
|
61 |
+
wp_die('', 403);
|
62 |
+
}
|
63 |
+
|
64 |
+
$this->integrationState->removeIntegration();
|
65 |
+
|
66 |
+
$this->redirectToPluginsListDashboard();
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* @param string $nonce
|
71 |
+
* @return bool
|
72 |
+
*/
|
73 |
+
private function isRequestNonceValid($nonce)
|
74 |
+
{
|
75 |
+
if (!QueryParameters::has('_wpnonce')) {
|
76 |
+
return false;
|
77 |
+
}
|
78 |
+
|
79 |
+
return (bool) wp_verify_nonce(QueryParameters::get('_wpnonce'), $nonce);
|
80 |
+
}
|
81 |
+
|
82 |
+
private function redirectToPluginsListDashboard()
|
83 |
+
{
|
84 |
+
wp_redirect(admin_url('plugins.php'));
|
85 |
+
die();
|
86 |
+
}
|
87 |
+
|
88 |
+
private function redirectToPluginAdminDashboard()
|
89 |
+
{
|
90 |
+
$url = 'admin.php?page=' . TidioLiveChat::TIDIO_PLUGIN_NAME;
|
91 |
+
wp_redirect(admin_url($url));
|
92 |
+
die();
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @param string $errorCode
|
97 |
+
*/
|
98 |
+
private function redirectToPluginAdminDashboardWithError($errorCode)
|
99 |
+
{
|
100 |
+
$url = sprintf('admin.php?page=%s&error=%s', TidioLiveChat::TIDIO_PLUGIN_NAME, $errorCode);
|
101 |
+
wp_redirect(admin_url($url));
|
102 |
+
die();
|
103 |
+
}
|
104 |
+
}
|
src/Admin/TidioAdminDashboard.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioAdminDashboard
|
4 |
+
{
|
5 |
+
const TIDIO_ICON_BASE64 = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIzLjEuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IldhcnN0d2FfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiCgkgdmlld0JveD0iMCAwIDIwIDIwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMCAyMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiNBMEE1QUE7fQo8L3N0eWxlPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMiwxOHYtNS45YzAtMi43LDEuNy01LDQuMy01LjdDNy4xLDMuNyw5LjQsMiwxMi4xLDJDMTUuNCwyLDE4LDQuNiwxOCw3Ljl2NS45aC00LjVsMCwwLjEKCWMtMC44LDIuNS0zLDQuMS01LjYsNC4xSDJ6IE02LjEsOC4xTDYuMSw4LjFjLTEuNiwwLjctMi42LDIuMy0yLjYsNC4xdjQuNGg0LjRjMS44LDAsMy4zLTEsNC4xLTIuNmwwLTAuMWwtMC4xLDAKCWMtMy4xLTAuMi01LjYtMi43LTUuNy01LjZsMC0wLjFMNi4xLDguMXogTTEyLjEsMy41Yy0xLjgsMC0zLjMsMS00LjEsMi42bDAsMC4xbDAuMSwwYzMuMiwwLjEsNS43LDIuNyw1LjcsNS45djAuMWwwLjEsMC4xaDIuN1Y3LjkKCUMxNi41LDUuNSwxNC41LDMuNSwxMi4xLDMuNXogTTcuNiw3LjhMNy42LDcuOGMwLDIuNSwyLDQuNSw0LjQsNC41aDAuMWwwLjEtMC4xYzAtMi41LTItNC41LTQuNC00LjVINy43TDcuNiw3Ljh6Ii8+Cjwvc3ZnPgo=';
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @var TidioIntegrationState
|
9 |
+
*/
|
10 |
+
private $integrationState;
|
11 |
+
/**
|
12 |
+
* @var TidioIframeSetup
|
13 |
+
*/
|
14 |
+
private $iframeSetup;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param TidioIntegrationState $integrationState
|
18 |
+
* @param TidioIframeSetup $iframeSetup
|
19 |
+
*/
|
20 |
+
public function __construct($integrationState, $iframeSetup)
|
21 |
+
{
|
22 |
+
$this->integrationState = $integrationState;
|
23 |
+
$this->iframeSetup = $iframeSetup;
|
24 |
+
|
25 |
+
add_action('admin_menu', [$this, 'addAdminMenuLink']);
|
26 |
+
}
|
27 |
+
|
28 |
+
public function addAdminMenuLink()
|
29 |
+
{
|
30 |
+
add_menu_page(
|
31 |
+
'Tidio Chat',
|
32 |
+
'Tidio Chat',
|
33 |
+
'manage_options',
|
34 |
+
TidioLiveChat::TIDIO_PLUGIN_NAME,
|
35 |
+
[$this, 'addAdminPage'],
|
36 |
+
'data:image/svg+xml;base64,' . self::TIDIO_ICON_BASE64
|
37 |
+
);
|
38 |
+
}
|
39 |
+
|
40 |
+
public function addAdminPage()
|
41 |
+
{
|
42 |
+
$dir = plugin_dir_path(__FILE__);
|
43 |
+
if ($this->integrationState->isPluginIntegrated()) {
|
44 |
+
$iframeUrl = $this->iframeSetup->prepareIntegrationSuccessIframeUrl();
|
45 |
+
} else {
|
46 |
+
$iframeUrl = $this->iframeSetup->prepareAuthenticationIframeUrl();
|
47 |
+
}
|
48 |
+
|
49 |
+
include $dir . '../../views/iframe.php';
|
50 |
+
}
|
51 |
+
}
|
src/Admin/TidioAdminNotice.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioAdminNotice
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var TidioErrorTranslator
|
7 |
+
*/
|
8 |
+
private $errorTranslator;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param TidioErrorTranslator $errorTranslator
|
12 |
+
*/
|
13 |
+
public function __construct($errorTranslator)
|
14 |
+
{
|
15 |
+
$this->errorTranslator = $errorTranslator;
|
16 |
+
|
17 |
+
add_action('admin_notices', [$this, 'addAdminErrorNotice']);
|
18 |
+
}
|
19 |
+
|
20 |
+
public function addAdminErrorNotice()
|
21 |
+
{
|
22 |
+
if (!QueryParameters::has('error')) {
|
23 |
+
return;
|
24 |
+
}
|
25 |
+
|
26 |
+
$errorCode = QueryParameters::get('error');
|
27 |
+
$errorMessage = $this->errorTranslator->translate($errorCode);
|
28 |
+
echo sprintf('<div class="notice notice-error is-dismissible"><p>%s</p></div>', $errorMessage);
|
29 |
+
}
|
30 |
+
}
|
src/Admin/TidioAdminRouting.php
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioAdminRouting
|
4 |
+
{
|
5 |
+
const CLEAR_ACCOUNT_DATA_ACTION = 'tidio-live-chat-clear-account-data';
|
6 |
+
const INTEGRATE_PROJECT_ACTION = 'tidio-live-chat-integrate-project';
|
7 |
+
const TOGGLE_ASYNC_LOADING_ACTION = 'tidio-live-chat-toggle-async-loading';
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @param TidioAdminController $adminController
|
11 |
+
*/
|
12 |
+
public function __construct($adminController)
|
13 |
+
{
|
14 |
+
add_action('admin_post_' . self::INTEGRATE_PROJECT_ACTION, [$adminController, 'handleIntegrateProjectAction']);
|
15 |
+
add_action('admin_post_' . self::TOGGLE_ASYNC_LOADING_ACTION, [$adminController, 'handleToggleAsyncLoadingAction']);
|
16 |
+
add_action('admin_post_' . self::CLEAR_ACCOUNT_DATA_ACTION, [$adminController, 'handleClearAccountDataAction']);
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @return string
|
21 |
+
*/
|
22 |
+
public static function getEndpointForIntegrateProjectAction()
|
23 |
+
{
|
24 |
+
return self::getEndpointForAction(self::INTEGRATE_PROJECT_ACTION);
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @return string
|
29 |
+
*/
|
30 |
+
public static function getEndpointForToggleAsyncLoadingAction()
|
31 |
+
{
|
32 |
+
return self::getEndpointForAction(self::TOGGLE_ASYNC_LOADING_ACTION);
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @return string
|
37 |
+
*/
|
38 |
+
public static function getEndpointForClearAccountDataAction()
|
39 |
+
{
|
40 |
+
return self::getEndpointForAction(self::CLEAR_ACCOUNT_DATA_ACTION);
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param string $action
|
45 |
+
* @return string
|
46 |
+
*/
|
47 |
+
private static function getEndpointForAction($action)
|
48 |
+
{
|
49 |
+
$queryString = http_build_query([
|
50 |
+
'action' => $action,
|
51 |
+
'_wpnonce' => wp_create_nonce($action),
|
52 |
+
]);
|
53 |
+
return admin_url('admin-post.php?' . $queryString);
|
54 |
+
}
|
55 |
+
}
|
src/Admin/TidioIframeSetup.php
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioIframeSetup
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var TidioIntegrationState
|
7 |
+
*/
|
8 |
+
private $integrationState;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param TidioIntegrationState $integrationState
|
12 |
+
*/
|
13 |
+
public function __construct($integrationState)
|
14 |
+
{
|
15 |
+
$this->integrationState = $integrationState;
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return string
|
20 |
+
*/
|
21 |
+
public function prepareAuthenticationIframeUrl()
|
22 |
+
{
|
23 |
+
$userId = get_current_user_id();
|
24 |
+
$userName = get_user_meta($userId, 'first_name', true);
|
25 |
+
|
26 |
+
$queryParams = array_merge(
|
27 |
+
[
|
28 |
+
'pluginUrl' => TidioAdminRouting::getEndpointForIntegrateProjectAction(),
|
29 |
+
'name' => $userName,
|
30 |
+
'refId' => $this->readRefIdFromFile()
|
31 |
+
],
|
32 |
+
$this->getDefaultIframeQueryParams()
|
33 |
+
);
|
34 |
+
|
35 |
+
$iframeBaseUrl = TidioLiveChatConfig::getPanelUrl() . '/register-platforms';
|
36 |
+
return sprintf('%s?%s', $iframeBaseUrl, http_build_query($queryParams));
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @return string
|
41 |
+
*/
|
42 |
+
public function prepareIntegrationSuccessIframeUrl()
|
43 |
+
{
|
44 |
+
$queryParams = array_merge(
|
45 |
+
[
|
46 |
+
'panelUrl' => $this->getPanelRedirectUrl()
|
47 |
+
],
|
48 |
+
$this->getDefaultIframeQueryParams()
|
49 |
+
);
|
50 |
+
|
51 |
+
$iframeBaseUrl = TidioLiveChatConfig::getPanelUrl() . '/integration-success';
|
52 |
+
return sprintf('%s?%s', $iframeBaseUrl, http_build_query($queryParams));
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @return array<string, string>
|
57 |
+
*/
|
58 |
+
private function getDefaultIframeQueryParams()
|
59 |
+
{
|
60 |
+
$userId = get_current_user_id();
|
61 |
+
$localeCode = get_user_locale($userId);
|
62 |
+
|
63 |
+
return [
|
64 |
+
'siteUrl' => get_home_url(),
|
65 |
+
'localeCode' => $localeCode,
|
66 |
+
'utm_source' => 'platform',
|
67 |
+
'utm_medium' => 'wordpress',
|
68 |
+
];
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @return string|null
|
73 |
+
*/
|
74 |
+
private function readRefIdFromFile() {
|
75 |
+
try {
|
76 |
+
$loadedRefIdFromFile = @file_get_contents(AFFILIATE_CONFIG_FILE_PATH);
|
77 |
+
return trim($loadedRefIdFromFile);
|
78 |
+
} catch (Exception $e) {
|
79 |
+
return null;
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @return string
|
85 |
+
*/
|
86 |
+
private function getPanelRedirectUrl()
|
87 |
+
{
|
88 |
+
$queryParams = [
|
89 |
+
'utm_source' => 'platform',
|
90 |
+
'utm_medium' => 'wordpress'
|
91 |
+
];
|
92 |
+
if ($this->integrationState->hasProjectPrivateKey()) {
|
93 |
+
$queryParams['privateKey'] = $this->integrationState->getProjectPrivateKey();
|
94 |
+
return sprintf('%s/external-access?%s', TidioLiveChatConfig::getPanelUrl(), http_build_query($queryParams));
|
95 |
+
}
|
96 |
+
|
97 |
+
return sprintf('%s?%s', TidioLiveChatConfig::getPanelUrl(), http_build_query($queryParams));
|
98 |
+
}
|
99 |
+
}
|
src/Sdk/Api/Client/CurlTidioApiClient.php
ADDED
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class CurlTidioApiClient implements TidioApiClient
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var string[]
|
7 |
+
*/
|
8 |
+
private $headers;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param string[] $additionalHeaders
|
12 |
+
*/
|
13 |
+
public function __construct($additionalHeaders = [])
|
14 |
+
{
|
15 |
+
$this->headers = array_merge(
|
16 |
+
[
|
17 |
+
'Content-Type: application/json',
|
18 |
+
'Accept: application/json'
|
19 |
+
],
|
20 |
+
$additionalHeaders
|
21 |
+
);
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @inerhitDoc
|
26 |
+
*/
|
27 |
+
public function sendPostRequest($path, $data = [])
|
28 |
+
{
|
29 |
+
$url = TidioLiveChatConfig::getApiUrl() . $path;
|
30 |
+
$ch = curl_init();
|
31 |
+
|
32 |
+
curl_setopt($ch, CURLOPT_HEADER, 1);
|
33 |
+
curl_setopt($ch, CURLOPT_POST, 1);
|
34 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
35 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
|
36 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
37 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
38 |
+
|
39 |
+
$response = curl_exec($ch);
|
40 |
+
$responseInfo = curl_getinfo($ch);
|
41 |
+
curl_close($ch);
|
42 |
+
|
43 |
+
$responseData = $this->parseResponseData($response, $responseInfo);
|
44 |
+
$this->validateResponse($responseData, $responseInfo);
|
45 |
+
|
46 |
+
return $responseData;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @inerhitDoc
|
51 |
+
*/
|
52 |
+
public function sendGetRequest($path)
|
53 |
+
{
|
54 |
+
$url = TidioLiveChatConfig::getApiUrl() . $path;
|
55 |
+
$ch = curl_init();
|
56 |
+
|
57 |
+
curl_setopt($ch, CURLOPT_HEADER, 1);
|
58 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
|
59 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
60 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
61 |
+
|
62 |
+
$response = curl_exec($ch);
|
63 |
+
$responseInfo = curl_getinfo($ch);
|
64 |
+
curl_close($ch);
|
65 |
+
|
66 |
+
$responseData = $this->parseResponseData($response, $responseInfo);
|
67 |
+
$this->validateResponse($responseData, $responseInfo);
|
68 |
+
|
69 |
+
return $responseData;
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @param string|false $response
|
74 |
+
* @param array<string, mixed> $responseInfo
|
75 |
+
* @return array<string, mixed>
|
76 |
+
*/
|
77 |
+
private function parseResponseData($response, $responseInfo)
|
78 |
+
{
|
79 |
+
$headerSize = $responseInfo['header_size'];
|
80 |
+
$responseBody = substr($response, $headerSize);
|
81 |
+
$responseData = json_decode($responseBody, true);
|
82 |
+
|
83 |
+
if (false === $responseData) {
|
84 |
+
return [];
|
85 |
+
}
|
86 |
+
|
87 |
+
return $responseData;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* @param array<string, mixed> $responseData
|
92 |
+
* @param array<string, mixed> $responseInfo
|
93 |
+
* @throws TidioApiException
|
94 |
+
*/
|
95 |
+
private function validateResponse($responseData, $responseInfo)
|
96 |
+
{
|
97 |
+
$statusCode = $responseInfo['http_code'];
|
98 |
+
if ($statusCode === 401) {
|
99 |
+
throw TidioApiException::withUnauthorizedErrorCode();
|
100 |
+
} elseif ($statusCode < 200 || $statusCode >= 300) {
|
101 |
+
if (isset($responseData['error'])) {
|
102 |
+
throw TidioApiException::withErrorCode($responseData['error']);
|
103 |
+
}
|
104 |
+
|
105 |
+
throw TidioApiException::withUnknownErrorCode();
|
106 |
+
}
|
107 |
+
}
|
108 |
+
}
|
src/Sdk/Api/Client/FileGetContentsTidioApiClient.php
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class FileGetContentsTidioApiClient implements TidioApiClient
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var string[]
|
7 |
+
*/
|
8 |
+
private $headers;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param string[] $additionalHeaders
|
12 |
+
*/
|
13 |
+
public function __construct($additionalHeaders = [])
|
14 |
+
{
|
15 |
+
$this->headers = array_merge(
|
16 |
+
['Accept: application/json'],
|
17 |
+
$additionalHeaders
|
18 |
+
);
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @inerhitDoc
|
23 |
+
*/
|
24 |
+
public function sendPostRequest($path, $data = [])
|
25 |
+
{
|
26 |
+
$url = TidioLiveChatConfig::getApiUrl() . $path;
|
27 |
+
$content = http_build_query($data);
|
28 |
+
$headers = array_merge([
|
29 |
+
'Content-Type: application/x-www-form-urlencoded',
|
30 |
+
'Content-Length: ' . strlen($content)
|
31 |
+
], $this->headers);
|
32 |
+
$options = [
|
33 |
+
'http' => [
|
34 |
+
'method' => 'POST',
|
35 |
+
'header' => $this->prepareRequestHeaders($headers),
|
36 |
+
'content' => http_build_query($data),
|
37 |
+
'ignore_errors' => true
|
38 |
+
]
|
39 |
+
];
|
40 |
+
|
41 |
+
$context = stream_context_create($options);
|
42 |
+
$response = @file_get_contents($url, false, $context);
|
43 |
+
|
44 |
+
$responseData = $this->parseResponseData($response);
|
45 |
+
$this->validateResponse($responseData, $http_response_header);
|
46 |
+
|
47 |
+
return $responseData;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @inerhitDoc
|
52 |
+
*/
|
53 |
+
public function sendGetRequest($path)
|
54 |
+
{
|
55 |
+
$url = TidioLiveChatConfig::getApiUrl() . $path;
|
56 |
+
$options = [
|
57 |
+
'http' => [
|
58 |
+
'method' => 'GET',
|
59 |
+
'header' => $this->prepareRequestHeaders($this->headers),
|
60 |
+
'ignore_errors' => true
|
61 |
+
]
|
62 |
+
];
|
63 |
+
|
64 |
+
$context = stream_context_create($options);
|
65 |
+
$response = @file_get_contents($url, false, $context);
|
66 |
+
|
67 |
+
$responseData = $this->parseResponseData($response);
|
68 |
+
$this->validateResponse($responseData, $http_response_header);
|
69 |
+
|
70 |
+
return $responseData;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @param string[] $headers
|
75 |
+
* @return string
|
76 |
+
*/
|
77 |
+
private function prepareRequestHeaders($headers)
|
78 |
+
{
|
79 |
+
$headerString = '';
|
80 |
+
foreach ($headers as $header) {
|
81 |
+
$headerString .= $header . "\r\n";
|
82 |
+
}
|
83 |
+
|
84 |
+
return $headerString;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @param string|false $response
|
89 |
+
* @return array<string, mixed>
|
90 |
+
*/
|
91 |
+
private function parseResponseData($response)
|
92 |
+
{
|
93 |
+
if (false === $response) {
|
94 |
+
return [];
|
95 |
+
}
|
96 |
+
|
97 |
+
return json_decode($response, true);
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* @param array<string, mixed> $responseData
|
102 |
+
* @param string[] $responseHeaders
|
103 |
+
* @throws TidioApiException
|
104 |
+
*/
|
105 |
+
private function validateResponse($responseData, $responseHeaders)
|
106 |
+
{
|
107 |
+
$statusCode = $this->parseStatusCodeFromHeaders($responseHeaders);
|
108 |
+
if ($statusCode === 401) {
|
109 |
+
throw TidioApiException::withUnauthorizedErrorCode();
|
110 |
+
} elseif ($statusCode < 200 || $statusCode >= 300) {
|
111 |
+
if (isset($responseData['error'])) {
|
112 |
+
throw TidioApiException::withErrorCode($responseData['error']);
|
113 |
+
}
|
114 |
+
|
115 |
+
throw TidioApiException::withUnknownErrorCode();
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* @param string[] $responseHeaders
|
121 |
+
* @return int
|
122 |
+
*/
|
123 |
+
private function parseStatusCodeFromHeaders($responseHeaders)
|
124 |
+
{
|
125 |
+
$statusCodeFallback = 500;
|
126 |
+
if (!isset($responseHeaders[0])) {
|
127 |
+
// cannot retrieve status code from headers, return 500 as fallback
|
128 |
+
return $statusCodeFallback;
|
129 |
+
}
|
130 |
+
|
131 |
+
$responseStatusHeader = $responseHeaders[0];
|
132 |
+
preg_match('/^HTTP\/\S*\s(\d{3})\s.+$/', $responseStatusHeader, $statusCodeResult);
|
133 |
+
|
134 |
+
$statusCode = end($statusCodeResult);
|
135 |
+
return $statusCode ? (int) $statusCode : $statusCodeFallback;
|
136 |
+
}
|
137 |
+
}
|
src/Sdk/Api/Client/TidioApiClientFactory.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioApiClientFactory
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @return TidioApiClient
|
7 |
+
*/
|
8 |
+
public function create()
|
9 |
+
{
|
10 |
+
if (function_exists('curl_version')) {
|
11 |
+
return new CurlTidioApiClient();
|
12 |
+
}
|
13 |
+
|
14 |
+
return new FileGetContentsTidioApiClient();
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @param string $token
|
19 |
+
* @return TidioApiClient
|
20 |
+
*/
|
21 |
+
public function createAuthenticated($token)
|
22 |
+
{
|
23 |
+
$authorizationHeader = ['Authorization: Bearer ' . $token];
|
24 |
+
if (function_exists('curl_version')) {
|
25 |
+
return new CurlTidioApiClient($authorizationHeader);
|
26 |
+
}
|
27 |
+
|
28 |
+
return new FileGetContentsTidioApiClient($authorizationHeader);
|
29 |
+
}
|
30 |
+
}
|
src/Sdk/Api/Exception/TidioApiException.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioApiException extends \Exception
|
4 |
+
{
|
5 |
+
const UNAUTHORIZED_ERROR_CODE = 'unauthorized';
|
6 |
+
const UNKNOWN_ERROR_CODE = 'unknown_error';
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @param string $errorCode
|
10 |
+
* @return TidioApiException
|
11 |
+
*/
|
12 |
+
public static function withErrorCode($errorCode)
|
13 |
+
{
|
14 |
+
return new self($errorCode);
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @return TidioApiException
|
19 |
+
*/
|
20 |
+
public static function withUnauthorizedErrorCode()
|
21 |
+
{
|
22 |
+
return new self(self::UNAUTHORIZED_ERROR_CODE);
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @return TidioApiException
|
27 |
+
*/
|
28 |
+
public static function withUnknownErrorCode()
|
29 |
+
{
|
30 |
+
return new self(self::UNKNOWN_ERROR_CODE);
|
31 |
+
}
|
32 |
+
}
|
src/Sdk/Api/TidioApiClient.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface TidioApiClient
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @param string $path
|
7 |
+
* @param array<string, mixed> $data
|
8 |
+
* @return array<string, mixed>
|
9 |
+
* @throws TidioApiException
|
10 |
+
*/
|
11 |
+
public function sendPostRequest($path, $data = []);
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @param string $path
|
15 |
+
* @return array<string, mixed>
|
16 |
+
* @throws TidioApiException
|
17 |
+
*/
|
18 |
+
public function sendGetRequest($path);
|
19 |
+
}
|
src/Sdk/Encryption/Exception/TidioDecryptionFailedException.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioDecryptionFailedException extends \Exception
|
4 |
+
{
|
5 |
+
const INVALID_HASH_ERROR_CODE = 'invalid_hash';
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @return TidioDecryptionFailedException
|
9 |
+
*/
|
10 |
+
public static function withInvalidHashErrorCode()
|
11 |
+
{
|
12 |
+
return new self(self::INVALID_HASH_ERROR_CODE);
|
13 |
+
}
|
14 |
+
}
|
src/Sdk/Encryption/Service/OpenSslTidioEncryptionService.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class OpenSslTidioEncryptionService implements TidioEncryptionService
|
4 |
+
{
|
5 |
+
const CIPHER_ALGORITHM = 'aes-256-ctr';
|
6 |
+
const HASH_ALGORITHM = 'sha256';
|
7 |
+
const HASH_LENGTH = 32;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var string
|
11 |
+
*/
|
12 |
+
private $encryptionKey;
|
13 |
+
/**
|
14 |
+
* @var int
|
15 |
+
*/
|
16 |
+
private $ivLength;
|
17 |
+
|
18 |
+
public function __construct($encryptionKey)
|
19 |
+
{
|
20 |
+
$this->encryptionKey = $encryptionKey;
|
21 |
+
$this->ivLength = openssl_cipher_iv_length(self::CIPHER_ALGORITHM);
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @inerhitDoc
|
26 |
+
*/
|
27 |
+
public function encrypt($value)
|
28 |
+
{
|
29 |
+
$iv = openssl_random_pseudo_bytes($this->ivLength);
|
30 |
+
$encryptedValue = openssl_encrypt($value, self::CIPHER_ALGORITHM, $this->encryptionKey, 0, $iv);
|
31 |
+
$hmac = hash_hmac(self::HASH_ALGORITHM, $encryptedValue, $this->encryptionKey, true);
|
32 |
+
|
33 |
+
return base64_encode($iv . $hmac . $encryptedValue);
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @inerhitDoc
|
38 |
+
*/
|
39 |
+
public function decrypt($encryptedString)
|
40 |
+
{
|
41 |
+
$encryptedString = base64_decode($encryptedString, true);
|
42 |
+
|
43 |
+
$iv = substr($encryptedString, 0, $this->ivLength);
|
44 |
+
$hmac = substr($encryptedString, $this->ivLength, self::HASH_LENGTH);
|
45 |
+
$encryptedValue = substr($encryptedString, $this->ivLength + self::HASH_LENGTH);
|
46 |
+
|
47 |
+
$hashToCompare = hash_hmac(self::HASH_ALGORITHM, $encryptedValue, $this->encryptionKey, true);
|
48 |
+
if (!hash_equals($hmac, $hashToCompare)) {
|
49 |
+
throw TidioDecryptionFailedException::withInvalidHashErrorCode();
|
50 |
+
}
|
51 |
+
|
52 |
+
return openssl_decrypt($encryptedValue, self::CIPHER_ALGORITHM, $this->encryptionKey, 0, $iv);
|
53 |
+
}
|
54 |
+
}
|
src/Sdk/Encryption/Service/PlainTextTidioEncryptionService.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class PlainTextTidioEncryptionService implements TidioEncryptionService
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @inerhitDoc
|
7 |
+
*/
|
8 |
+
public function encrypt($value)
|
9 |
+
{
|
10 |
+
return $value;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inerhitDoc
|
15 |
+
*/
|
16 |
+
public function decrypt($encryptedString)
|
17 |
+
{
|
18 |
+
return $encryptedString;
|
19 |
+
}
|
20 |
+
}
|
src/Sdk/Encryption/Service/TidioEncryptionServiceFactory.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioEncryptionServiceFactory
|
4 |
+
{
|
5 |
+
public function create()
|
6 |
+
{
|
7 |
+
$encryptionKey = $this->getEncryptionKey();
|
8 |
+
if (empty($encryptionKey) || !extension_loaded('openssl')) {
|
9 |
+
return new PlainTextTidioEncryptionService();
|
10 |
+
}
|
11 |
+
|
12 |
+
return new OpenSslTidioEncryptionService($encryptionKey);
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @return string|null
|
17 |
+
*/
|
18 |
+
private function getEncryptionKey()
|
19 |
+
{
|
20 |
+
if (!defined('LOGGED_IN_KEY')) {
|
21 |
+
return null;
|
22 |
+
}
|
23 |
+
|
24 |
+
return LOGGED_IN_KEY;
|
25 |
+
}
|
26 |
+
}
|
src/Sdk/Encryption/TidioEncryptionService.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface TidioEncryptionService
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @param string $value
|
7 |
+
* @return string
|
8 |
+
*/
|
9 |
+
public function encrypt($value);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param string $encryptedString
|
13 |
+
* @return string
|
14 |
+
* @throws TidioDecryptionFailedException
|
15 |
+
*/
|
16 |
+
public function decrypt($encryptedString);
|
17 |
+
}
|
src/Sdk/TidioIntegrationFacade.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioIntegrationFacade
|
4 |
+
{
|
5 |
+
const TIDIO_WORDPRESS_OAUTH_CLIENT_ID = '8ea883be-28c3-4bfd-9fe2-4091eb38fe08';
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @var TidioApiClientFactory
|
9 |
+
*/
|
10 |
+
private $apiClientFactory;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @param TidioApiClientFactory $apiClientFactory
|
14 |
+
*/
|
15 |
+
public function __construct($apiClientFactory)
|
16 |
+
{
|
17 |
+
$this->apiClientFactory = $apiClientFactory;
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @param string $refreshToken
|
22 |
+
* @return array<string, mixed>
|
23 |
+
* @throws TidioApiException
|
24 |
+
*/
|
25 |
+
public function integrateProject($refreshToken)
|
26 |
+
{
|
27 |
+
$apiClient = $this->apiClientFactory->create();
|
28 |
+
$tokens = $apiClient->sendPostRequest('/platforms/oauth/access_token', [
|
29 |
+
'grant_type' => 'refresh_token',
|
30 |
+
'client_id' => self::TIDIO_WORDPRESS_OAUTH_CLIENT_ID,
|
31 |
+
'refresh_token' => $refreshToken
|
32 |
+
]);
|
33 |
+
|
34 |
+
$apiClient = $this->apiClientFactory->createAuthenticated($tokens['access_token']);
|
35 |
+
$data = $apiClient->sendPostRequest('/platforms/wordpress/integrate');
|
36 |
+
|
37 |
+
return [
|
38 |
+
'projectPublicKey' => $data['projectPublicKey'],
|
39 |
+
'accessToken' => $tokens['access_token'],
|
40 |
+
'refreshToken' => $tokens['refresh_token']
|
41 |
+
];
|
42 |
+
}
|
43 |
+
}
|
src/TidioIntegrationState.php
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioIntegrationState
|
4 |
+
{
|
5 |
+
const PUBLIC_KEY_OPTION = 'tidio-one-public-key';
|
6 |
+
const PRIVATE_KEY_OPTION = 'tidio-one-private-key';
|
7 |
+
const ASYNC_LOAD_OPTION = 'tidio-async-load';
|
8 |
+
const TIDIO_OAUTH_ACCESS_TOKEN_KEY = 'tidio-access-token';
|
9 |
+
const TIDIO_OAUTH_REFRESH_TOKEN_KEY = 'tidio-refresh-token';
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var OpenSslTidioEncryptionService
|
13 |
+
*/
|
14 |
+
private $encryptionService;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param OpenSslTidioEncryptionService $encryptionService
|
18 |
+
*/
|
19 |
+
public function __construct($encryptionService)
|
20 |
+
{
|
21 |
+
$this->encryptionService = $encryptionService;
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @return string|null
|
26 |
+
*/
|
27 |
+
public function getProjectPublicKey()
|
28 |
+
{
|
29 |
+
return get_option(self::PUBLIC_KEY_OPTION, null);
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @return string|null
|
34 |
+
*/
|
35 |
+
public function getProjectPrivateKey()
|
36 |
+
{
|
37 |
+
return get_option(self::PRIVATE_KEY_OPTION, null);
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return bool
|
42 |
+
*/
|
43 |
+
public function hasProjectPrivateKey()
|
44 |
+
{
|
45 |
+
return !empty(get_option(self::PRIVATE_KEY_OPTION));
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @return bool
|
50 |
+
*/
|
51 |
+
public function isPluginIntegrated()
|
52 |
+
{
|
53 |
+
return !empty(get_option(self::PUBLIC_KEY_OPTION));
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @return bool
|
58 |
+
*/
|
59 |
+
public function isAsyncLoadingTurnedOn()
|
60 |
+
{
|
61 |
+
return (bool) get_option(self::ASYNC_LOAD_OPTION);
|
62 |
+
}
|
63 |
+
|
64 |
+
public function integrate($projectPublicKey, $accessToken, $refreshToken)
|
65 |
+
{
|
66 |
+
$encryptedRefreshToken = $this->encryptionService->encrypt($refreshToken);
|
67 |
+
|
68 |
+
update_option(self::PUBLIC_KEY_OPTION, $projectPublicKey);
|
69 |
+
update_option(self::TIDIO_OAUTH_ACCESS_TOKEN_KEY, $accessToken);
|
70 |
+
update_option(self::TIDIO_OAUTH_REFRESH_TOKEN_KEY, $encryptedRefreshToken);
|
71 |
+
update_option(self::ASYNC_LOAD_OPTION, true);
|
72 |
+
}
|
73 |
+
|
74 |
+
public function removeIntegration()
|
75 |
+
{
|
76 |
+
delete_option(self::PUBLIC_KEY_OPTION);
|
77 |
+
delete_option(self::TIDIO_OAUTH_ACCESS_TOKEN_KEY);
|
78 |
+
delete_option(self::TIDIO_OAUTH_REFRESH_TOKEN_KEY);
|
79 |
+
delete_option(self::ASYNC_LOAD_OPTION);
|
80 |
+
delete_option(self::PRIVATE_KEY_OPTION);
|
81 |
+
}
|
82 |
+
|
83 |
+
public function turnOnAsyncLoading()
|
84 |
+
{
|
85 |
+
update_option(self::ASYNC_LOAD_OPTION, true);
|
86 |
+
}
|
87 |
+
|
88 |
+
public function toggleAsyncLoading()
|
89 |
+
{
|
90 |
+
update_option(self::ASYNC_LOAD_OPTION, !$this->isAsyncLoadingTurnedOn());
|
91 |
+
}
|
92 |
+
}
|
src/TidioLiveChat.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioLiveChat
|
4 |
+
{
|
5 |
+
const TIDIO_PLUGIN_NAME = 'tidio-live-chat';
|
6 |
+
|
7 |
+
public static function load()
|
8 |
+
{
|
9 |
+
$encryptionService = (new TidioEncryptionServiceFactory())->create();
|
10 |
+
$integrationState = new TidioIntegrationState($encryptionService);
|
11 |
+
if (!is_admin()) {
|
12 |
+
new TidioWidgetLoader($integrationState);
|
13 |
+
return;
|
14 |
+
}
|
15 |
+
|
16 |
+
if (current_user_can('activate_plugins')) {
|
17 |
+
new TidioTranslationLoader();
|
18 |
+
$apiClientFactory = new TidioApiClientFactory();
|
19 |
+
$integrationFacade = new TidioIntegrationFacade($apiClientFactory);
|
20 |
+
$adminController = new TidioAdminController($integrationFacade, $integrationState);
|
21 |
+
$iframeSetup = new TidioIframeSetup($integrationState);
|
22 |
+
$errorTranslator = new TidioErrorTranslator();
|
23 |
+
|
24 |
+
new TidioAdminRouting($adminController);
|
25 |
+
new TidioAdminActionLink($integrationState);
|
26 |
+
new TidioAdminDashboard($integrationState, $iframeSetup);
|
27 |
+
new TidioAdminNotice($errorTranslator);
|
28 |
+
}
|
29 |
+
}
|
30 |
+
}
|
src/TidioLiveChatConfig.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
final class TidioLiveChatConfig
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var array|null
|
7 |
+
*/
|
8 |
+
private static $config = null;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @return string
|
12 |
+
*/
|
13 |
+
public static function getApiUrl()
|
14 |
+
{
|
15 |
+
return self::getConfig()['tidio_api_url'];
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return string
|
20 |
+
*/
|
21 |
+
public static function getPanelUrl()
|
22 |
+
{
|
23 |
+
return self::getConfig()['tidio_panel_url'];
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @return string
|
28 |
+
*/
|
29 |
+
public static function getWidgetUrl()
|
30 |
+
{
|
31 |
+
return self::getConfig()['tidio_widget_url'];
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @return array<string, string>
|
36 |
+
*/
|
37 |
+
private static function getConfig()
|
38 |
+
{
|
39 |
+
if (self::$config === null) {
|
40 |
+
self::$config = require __DIR__ . '/../config.php';
|
41 |
+
}
|
42 |
+
|
43 |
+
return self::$config;
|
44 |
+
}
|
45 |
+
}
|
src/Translation/TidioErrorTranslator.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioErrorTranslator
|
4 |
+
{
|
5 |
+
const ERROR_CODE_FALLBACK_MESSAGE = 'The integration process has been interrupted. An error has occurred (%s). Please try again later or contact our support team.';
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @param string $errorCode
|
9 |
+
* @return string
|
10 |
+
*/
|
11 |
+
public function translate($errorCode)
|
12 |
+
{
|
13 |
+
return sprintf(i18n::_t(self::ERROR_CODE_FALLBACK_MESSAGE), $errorCode);
|
14 |
+
}
|
15 |
+
}
|
src/Translation/TidioTranslationLoader.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioTranslationLoader
|
4 |
+
{
|
5 |
+
public function __construct()
|
6 |
+
{
|
7 |
+
add_filter('load_textdomain_mofile', [$this, 'loadTextDomain'], 10, 2);
|
8 |
+
load_plugin_textdomain(TidioLiveChat::TIDIO_PLUGIN_NAME);
|
9 |
+
}
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param string $mofile
|
13 |
+
* @param string $domain
|
14 |
+
* @return string
|
15 |
+
*/
|
16 |
+
public function loadTextDomain($mofile, $domain)
|
17 |
+
{
|
18 |
+
if (TidioLiveChat::TIDIO_PLUGIN_NAME === $domain && false !== strpos($mofile, WP_LANG_DIR . '/plugins/')) {
|
19 |
+
$userId = get_current_user_id();
|
20 |
+
$userLocaleCode = get_user_locale($userId);
|
21 |
+
|
22 |
+
$locale = apply_filters('plugin_locale', $userLocaleCode, $domain);
|
23 |
+
$mofile = sprintf('%s/%s/../../languages/%s-%s.mo', WP_PLUGIN_DIR, dirname(plugin_basename(__FILE__)), $domain, $locale);
|
24 |
+
}
|
25 |
+
|
26 |
+
return $mofile;
|
27 |
+
}
|
28 |
+
}
|
src/Translation/i18n.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class i18n
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* echo translation
|
7 |
+
*/
|
8 |
+
public static function _e($message)
|
9 |
+
{
|
10 |
+
_e($message, TidioLiveChat::TIDIO_PLUGIN_NAME);
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* returns translation
|
15 |
+
*/
|
16 |
+
public static function _t($message)
|
17 |
+
{
|
18 |
+
return __($message, TidioLiveChat::TIDIO_PLUGIN_NAME);
|
19 |
+
}
|
20 |
+
}
|
src/Utils/QueryParameters.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class QueryParameters
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @param string $key
|
7 |
+
* @return bool
|
8 |
+
*/
|
9 |
+
public static function has($key)
|
10 |
+
{
|
11 |
+
return isset($_GET[$key]);
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param string $key
|
16 |
+
* @return string|null
|
17 |
+
*/
|
18 |
+
public static function get($key)
|
19 |
+
{
|
20 |
+
if (!self::has($key)) {
|
21 |
+
return null;
|
22 |
+
}
|
23 |
+
|
24 |
+
return sanitize_text_field($_GET[$key]);
|
25 |
+
}
|
26 |
+
}
|
src/Widget/TidioWidgetLoader.php
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TidioWidgetLoader
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var TidioIntegrationState
|
7 |
+
*/
|
8 |
+
private $integrationState;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param TidioIntegrationState $integrationState
|
12 |
+
*/
|
13 |
+
public function __construct($integrationState)
|
14 |
+
{
|
15 |
+
$this->integrationState = $integrationState;
|
16 |
+
|
17 |
+
if (!$this->integrationState->isPluginIntegrated()) {
|
18 |
+
return;
|
19 |
+
}
|
20 |
+
|
21 |
+
add_action('wp_head', [$this,'addPreconnectLink']);
|
22 |
+
if ($this->integrationState->isAsyncLoadingTurnedOn()) {
|
23 |
+
add_action('wp_footer', [$this, 'enqueueScriptsAsync'], PHP_INT_MAX);
|
24 |
+
return;
|
25 |
+
}
|
26 |
+
|
27 |
+
add_action('wp_enqueue_scripts', [$this, 'enqueueScriptsSync'], 1000);
|
28 |
+
}
|
29 |
+
|
30 |
+
public function addPreconnectLink() {
|
31 |
+
echo '<link rel="preconnect" href="//code.tidio.co">';
|
32 |
+
}
|
33 |
+
|
34 |
+
public function enqueueScriptsAsync()
|
35 |
+
{
|
36 |
+
$publicKey = $this->integrationState->getProjectPublicKey();
|
37 |
+
$widgetUrl = sprintf('%s/%s.js', TidioLiveChatConfig::getWidgetUrl(), $publicKey);
|
38 |
+
$asyncScript = <<<SRC
|
39 |
+
<script type='text/javascript'>
|
40 |
+
document.tidioChatCode = "$publicKey";
|
41 |
+
(function() {
|
42 |
+
function asyncLoad() {
|
43 |
+
var tidioScript = document.createElement("script");
|
44 |
+
tidioScript.type = "text/javascript";
|
45 |
+
tidioScript.async = true;
|
46 |
+
tidioScript.src = "{$widgetUrl}";
|
47 |
+
document.body.appendChild(tidioScript);
|
48 |
+
}
|
49 |
+
if (window.attachEvent) {
|
50 |
+
window.attachEvent("onload", asyncLoad);
|
51 |
+
} else {
|
52 |
+
window.addEventListener("load", asyncLoad, false);
|
53 |
+
}
|
54 |
+
})();
|
55 |
+
</script>
|
56 |
+
SRC;
|
57 |
+
echo $asyncScript;
|
58 |
+
}
|
59 |
+
|
60 |
+
public function enqueueScriptsSync()
|
61 |
+
{
|
62 |
+
$projectPublicKey = $this->integrationState->getProjectPublicKey();
|
63 |
+
|
64 |
+
$widgetUrl = sprintf('%s/%s.js', TidioLiveChatConfig::getWidgetUrl(), $projectPublicKey);
|
65 |
+
wp_enqueue_script(TidioLiveChat::TIDIO_PLUGIN_NAME, $widgetUrl, [], TIDIOCHAT_VERSION, true);
|
66 |
+
|
67 |
+
$inlineScriptWithProjectPublicKeyVariable = sprintf('document.tidioChatCode = "%s";', $projectPublicKey);
|
68 |
+
wp_add_inline_script(TidioLiveChat::TIDIO_PLUGIN_NAME, $inlineScriptWithProjectPublicKeyVariable, 'before');
|
69 |
+
}
|
70 |
+
}
|
tidio-elements.php
CHANGED
@@ -4,478 +4,54 @@
|
|
4 |
* Plugin Name: Tidio Chat
|
5 |
* Plugin URI: http://www.tidio.com
|
6 |
* Description: Tidio Live Chat - live chat boosted with chatbots for your online business. Integrates with your website in less than 20 seconds.
|
7 |
-
* Version:
|
8 |
* Author: Tidio Ltd.
|
9 |
* Author URI: http://www.tidio.com
|
10 |
* Text Domain: tidio-live-chat
|
11 |
* Domain Path: /languages/
|
12 |
* License: GPL2
|
13 |
*/
|
14 |
-
define('TIDIOCHAT_VERSION', '
|
15 |
-
define('AFFILIATE_CONFIG_FILE_PATH', get_template_directory().'/tidio_affiliate_ref_id.txt');
|
16 |
-
|
17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
{
|
19 |
-
|
20 |
-
|
21 |
-
const ASYNC_LOAD_OPTION = 'tidio-async-load';
|
22 |
-
const CLEAR_ACCOUNT_DATA_ACTION = 'tidio-chat-reset';
|
23 |
-
const TIDIO_PLUGIN_NAME = 'tidio-live-chat';
|
24 |
-
const TOGGLE_ASYNC_ACTION = 'tidio-chat-toggle-async';
|
25 |
-
const TIDIO_ICON_BASE64 = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIzLjEuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IldhcnN0d2FfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiCgkgdmlld0JveD0iMCAwIDIwIDIwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMCAyMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiNBMEE1QUE7fQo8L3N0eWxlPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMiwxOHYtNS45YzAtMi43LDEuNy01LDQuMy01LjdDNy4xLDMuNyw5LjQsMiwxMi4xLDJDMTUuNCwyLDE4LDQuNiwxOCw3Ljl2NS45aC00LjVsMCwwLjEKCWMtMC44LDIuNS0zLDQuMS01LjYsNC4xSDJ6IE02LjEsOC4xTDYuMSw4LjFjLTEuNiwwLjctMi42LDIuMy0yLjYsNC4xdjQuNGg0LjRjMS44LDAsMy4zLTEsNC4xLTIuNmwwLTAuMWwtMC4xLDAKCWMtMy4xLTAuMi01LjYtMi43LTUuNy01LjZsMC0wLjFMNi4xLDguMXogTTEyLjEsMy41Yy0xLjgsMC0zLjMsMS00LjEsMi42bDAsMC4xbDAuMSwwYzMuMiwwLjEsNS43LDIuNyw1LjcsNS45djAuMWwwLjEsMC4xaDIuN1Y3LjkKCUMxNi41LDUuNSwxNC41LDMuNSwxMi4xLDMuNXogTTcuNiw3LjhMNy42LDcuOGMwLDIuNSwyLDQuNSw0LjQsNC41aDAuMWwwLjEtMC4xYzAtMi41LTItNC41LTQuNC00LjVINy43TDcuNiw3Ljh6Ii8+Cjwvc3ZnPgo=';
|
26 |
-
const TIDIO_XHR_NONCE_NAME = 'tidio-xhr-nonce';
|
27 |
-
|
28 |
-
public function __construct()
|
29 |
-
{
|
30 |
-
if (!empty($_GET['tidio_chat_version'])) {
|
31 |
-
echo TIDIOCHAT_VERSION;
|
32 |
-
exit;
|
33 |
-
}
|
34 |
-
|
35 |
-
/* load plugin translations*/
|
36 |
-
add_filter('load_textdomain_mofile', [$this, 'loadTextDomain'], 10, 2);
|
37 |
-
load_plugin_textdomain(self::TIDIO_PLUGIN_NAME);
|
38 |
-
|
39 |
-
/* Before add link to menu - check is user trying to unninstal */
|
40 |
-
if (is_admin() && current_user_can('activate_plugins') && !empty($_GET['tidio_one_clear_cache'])) {
|
41 |
-
delete_option(TidioLiveChat::PUBLIC_KEY_OPTION);
|
42 |
-
delete_option(TidioLiveChat::PRIVATE_KEY_OPTION);
|
43 |
-
}
|
44 |
-
|
45 |
-
if (get_option(TidioLiveChat::PUBLIC_KEY_OPTION)) {
|
46 |
-
add_action('admin_footer', array($this, 'adminJS'));
|
47 |
-
}
|
48 |
-
|
49 |
-
if (!is_admin()) {
|
50 |
-
add_action('wp_head', array($this,'addPreconnectLink'));
|
51 |
-
if (get_option(TidioLiveChat::ASYNC_LOAD_OPTION)) {
|
52 |
-
add_action('wp_footer', array($this, 'enqueueScriptsAsync'), PHP_INT_MAX);
|
53 |
-
} else {
|
54 |
-
add_action('wp_enqueue_scripts', array($this, 'enqueueScriptsSync'), 1000);
|
55 |
-
}
|
56 |
-
} else if (current_user_can('activate_plugins')) {
|
57 |
-
add_action('admin_menu', array($this, 'addAdminMenuLink'));
|
58 |
-
add_action('admin_enqueue_scripts', array($this, 'enqueueAdminScripts'));
|
59 |
-
add_action('admin_enqueue_scripts', [$this, 'enqueueAdminScriptTranslation']);
|
60 |
-
|
61 |
-
add_action('wp_ajax_tidio_chat_save_keys', array($this, 'ajaxTidioChatSaveKeys'));
|
62 |
-
add_action('wp_ajax_set_project_keys', array($this, 'ajaxSetProjectKeys'));
|
63 |
-
add_action('wp_ajax_get_private_key', array($this, 'ajaxGetPrivateKey'));
|
64 |
-
|
65 |
-
add_action('admin_post_' . TidioLiveChat::CLEAR_ACCOUNT_DATA_ACTION . '', array($this, 'uninstall'));
|
66 |
-
add_action('admin_post_' . TidioLiveChat::TOGGLE_ASYNC_ACTION . '', array($this, 'toggleAsync'));
|
67 |
-
|
68 |
-
add_filter('plugin_action_links', array($this, 'pluginActionLinks'), 10, 2);
|
69 |
-
}
|
70 |
-
}
|
71 |
-
|
72 |
-
public function loadTextDomain($mofile, $domain)
|
73 |
-
{
|
74 |
-
if ('tidio-live-chat' === $domain && false !== strpos($mofile, WP_LANG_DIR . '/plugins/')) {
|
75 |
-
$locale = apply_filters('plugin_locale', determine_locale(), $domain);
|
76 |
-
$mofile = WP_PLUGIN_DIR . '/' . dirname(plugin_basename(__FILE__)) . '/languages/' . $domain . '-' . $locale . '.mo';
|
77 |
-
}
|
78 |
-
|
79 |
-
return $mofile;
|
80 |
-
}
|
81 |
-
|
82 |
-
public static function activate()
|
83 |
-
{
|
84 |
-
update_option(TidioLiveChat::ASYNC_LOAD_OPTION, true);
|
85 |
-
}
|
86 |
-
|
87 |
-
public static function ajaxGetPrivateKey()
|
88 |
-
{
|
89 |
-
check_ajax_referer(TidioLiveChat::TIDIO_XHR_NONCE_NAME);
|
90 |
-
|
91 |
-
$privateKey = TidioLiveChat::getPrivateKey();
|
92 |
-
if (!$privateKey || $privateKey == 'false') {
|
93 |
-
echo 'error';
|
94 |
-
exit();
|
95 |
-
}
|
96 |
-
echo TidioLiveChat::getRedirectUrl($privateKey);
|
97 |
-
exit();
|
98 |
-
}
|
99 |
-
|
100 |
-
public static function getPrivateKey()
|
101 |
-
{
|
102 |
-
TidioLiveChat::syncPrivateKey();
|
103 |
-
|
104 |
-
$privateKey = get_option(TidioLiveChat::PRIVATE_KEY_OPTION);
|
105 |
-
|
106 |
-
if ($privateKey) {
|
107 |
-
return $privateKey;
|
108 |
-
}
|
109 |
-
|
110 |
-
try {
|
111 |
-
$data = TidioLiveChat::getContent(TidioLiveChat::getAccessUrl());
|
112 |
-
} catch (Exception $e) {
|
113 |
-
$data = null;
|
114 |
-
}
|
115 |
-
//
|
116 |
-
if (!$data) {
|
117 |
-
update_option(TidioLiveChat::PRIVATE_KEY_OPTION, 'false');
|
118 |
-
return false;
|
119 |
-
}
|
120 |
-
|
121 |
-
@$data = json_decode($data, true);
|
122 |
-
if (!$data || !$data['status']) {
|
123 |
-
update_option(TidioLiveChat::PRIVATE_KEY_OPTION, 'false');
|
124 |
-
return false;
|
125 |
-
}
|
126 |
-
|
127 |
-
update_option(TidioLiveChat::PRIVATE_KEY_OPTION, $data['value']['private_key']);
|
128 |
-
update_option(TidioLiveChat::PUBLIC_KEY_OPTION, $data['value']['public_key']);
|
129 |
-
update_option(TidioLiveChat::ASYNC_LOAD_OPTION, true);
|
130 |
-
|
131 |
-
return $data['value']['private_key'];
|
132 |
-
}
|
133 |
-
|
134 |
-
public static function syncPrivateKey()
|
135 |
-
{
|
136 |
-
if (get_option(TidioLiveChat::PUBLIC_KEY_OPTION)) {
|
137 |
-
return false;
|
138 |
-
}
|
139 |
-
|
140 |
-
$publicKey = get_option('tidio-chat-external-public-key');
|
141 |
-
$privateKey = get_option('tidio-chat-external-private-key');
|
142 |
-
|
143 |
-
if (!$publicKey || !$privateKey) {
|
144 |
-
return false;
|
145 |
-
}
|
146 |
-
|
147 |
-
// sync old variables with new one
|
148 |
-
|
149 |
-
update_option(TidioLiveChat::PUBLIC_KEY_OPTION, $publicKey);
|
150 |
-
update_option(TidioLiveChat::PRIVATE_KEY_OPTION, $privateKey);
|
151 |
-
|
152 |
-
return true;
|
153 |
-
}
|
154 |
-
|
155 |
-
public static function getContent($url)
|
156 |
-
{
|
157 |
-
|
158 |
-
if (function_exists('curl_version')) { // load through curl
|
159 |
-
$ch = curl_init();
|
160 |
-
|
161 |
-
curl_setopt($ch, CURLOPT_HEADER, 0);
|
162 |
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
163 |
-
curl_setopt($ch, CURLOPT_URL, $url);
|
164 |
-
|
165 |
-
$data = curl_exec($ch);
|
166 |
-
curl_close($ch);
|
167 |
-
|
168 |
-
return $data;
|
169 |
-
} else { // load through file get contents
|
170 |
-
return file_get_contents($url);
|
171 |
-
}
|
172 |
-
}
|
173 |
-
|
174 |
-
public static function readRefIDFromFile() {
|
175 |
-
try {
|
176 |
-
$loadedRefIdFromFile = @file_get_contents(AFFILIATE_CONFIG_FILE_PATH);
|
177 |
-
return trim($loadedRefIdFromFile);
|
178 |
-
} catch (Exception $e){}
|
179 |
-
return null;
|
180 |
-
}
|
181 |
-
|
182 |
-
public static function getAccessUrl()
|
183 |
-
{
|
184 |
-
$parameters = array(
|
185 |
-
'url' => site_url(),
|
186 |
-
'platform' => 'wordpress',
|
187 |
-
'email' => get_option('admin_email'),
|
188 |
-
'_ip' => $_SERVER['REMOTE_ADDR'],
|
189 |
-
);
|
190 |
-
$refIdFromFile = TidioLiveChat::readRefIDFromFile();
|
191 |
-
if (isset($refIdFromFile)) {
|
192 |
-
$parameters['ref_id'] = $refIdFromFile;
|
193 |
-
}
|
194 |
-
$accessUrlParameters = http_build_query($parameters);
|
195 |
-
return TidioLiveChatConfig::getApiUrl() . '/access/external/create?'.$accessUrlParameters;
|
196 |
-
}
|
197 |
-
|
198 |
-
public static function getRedirectUrl($privateKey)
|
199 |
-
{
|
200 |
-
return TidioLiveChatConfig::getPanelUrl() . '/panel/external-access?' . http_build_query(
|
201 |
-
array(
|
202 |
-
'privateKey' => $privateKey,
|
203 |
-
'utm_source' => 'platform',
|
204 |
-
'utm_medium' => 'wordpress'
|
205 |
-
)
|
206 |
-
);
|
207 |
-
}
|
208 |
-
|
209 |
-
public function pluginActionLinks($links, $file)
|
210 |
-
{
|
211 |
-
if (strpos($file, basename(__FILE__)) !== false) {
|
212 |
-
if (get_option(TidioLiveChat::PRIVATE_KEY_OPTION)) {
|
213 |
-
$queryString = http_build_query(
|
214 |
-
array(
|
215 |
-
'action' => TidioLiveChat::CLEAR_ACCOUNT_DATA_ACTION,
|
216 |
-
'_wpnonce' => wp_create_nonce(TidioLiveChat::CLEAR_ACCOUNT_DATA_ACTION),
|
217 |
-
)
|
218 |
-
);
|
219 |
-
$links[] = '<a href="' . admin_url('admin-post.php') . '?' . $queryString . '">' . esc_html(i18n::_t('Clear Account Data')) . '</a>';
|
220 |
-
|
221 |
-
if (get_option(TidioLiveChat::ASYNC_LOAD_OPTION)) {
|
222 |
-
$toggleAsyncLabel = '✓';
|
223 |
-
$onclickPart = 'onclick="return confirm(\''.i18n::_t('Disabling asynchronous loading of the chat widget may affect the page loading time of your website. Are you sure you want to disable the asynchronous loading?').'\');"';
|
224 |
-
} else {
|
225 |
-
$toggleAsyncLabel = '✘';
|
226 |
-
$onclickPart = '';
|
227 |
-
}
|
228 |
-
$queryString = http_build_query(
|
229 |
-
array(
|
230 |
-
'action' => TidioLiveChat::TOGGLE_ASYNC_ACTION,
|
231 |
-
'_wpnonce' => wp_create_nonce(TidioLiveChat::TOGGLE_ASYNC_ACTION),
|
232 |
-
)
|
233 |
-
);
|
234 |
-
$links[] = '<a href="' . admin_url('admin-post.php') . '?' . $queryString . '" ' . $onclickPart . '>' . esc_html($toggleAsyncLabel . ' ' . i18n::_t('Asynchronous loading')) . '</a>';
|
235 |
-
}
|
236 |
-
}
|
237 |
-
|
238 |
-
return $links;
|
239 |
-
}
|
240 |
-
|
241 |
-
public function toggleAsync()
|
242 |
-
{
|
243 |
-
if (wp_verify_nonce($_GET['_wpnonce'], TidioLiveChat::TOGGLE_ASYNC_ACTION) === false) {
|
244 |
-
wp_die('', 403);
|
245 |
-
}
|
246 |
-
|
247 |
-
update_option(TidioLiveChat::ASYNC_LOAD_OPTION, !get_option(TidioLiveChat::ASYNC_LOAD_OPTION));
|
248 |
-
wp_redirect(admin_url('plugins.php'));
|
249 |
-
die();
|
250 |
-
}
|
251 |
-
|
252 |
-
public function ajaxSetProjectKeys()
|
253 |
-
{
|
254 |
-
check_ajax_referer(TidioLiveChat::TIDIO_XHR_NONCE_NAME);
|
255 |
-
|
256 |
-
update_option(TidioLiveChat::PUBLIC_KEY_OPTION, $_POST['public_key']);
|
257 |
-
update_option(TidioLiveChat::PRIVATE_KEY_OPTION, $_POST['private_key']);
|
258 |
-
|
259 |
-
$query = http_build_query(array(
|
260 |
-
'api_token' => $_POST['api_token'],
|
261 |
-
'project_public_key' => $_POST['public_key']
|
262 |
-
));
|
263 |
-
|
264 |
-
$options = array('http' => array('method' => 'POST'));
|
265 |
-
|
266 |
-
$context = stream_context_create($options);
|
267 |
-
@file_get_contents(TidioLiveChatConfig::getApiUrl() . '/access/connectWordpress?' . $query, false, $context);
|
268 |
-
|
269 |
-
echo TidioLiveChat::getRedirectUrl($_POST['private_key']);
|
270 |
-
exit();
|
271 |
-
}
|
272 |
-
|
273 |
-
public function ajaxTidioChatSaveKeys()
|
274 |
-
{
|
275 |
-
if (!is_admin()) {
|
276 |
-
exit;
|
277 |
-
}
|
278 |
-
|
279 |
-
check_ajax_referer(TidioLiveChat::TIDIO_XHR_NONCE_NAME);
|
280 |
-
|
281 |
-
if (empty($_POST['private_key']) || empty($_POST['public_key'])) {
|
282 |
-
exit;
|
283 |
-
}
|
284 |
-
|
285 |
-
update_option(TidioLiveChat::PUBLIC_KEY_OPTION, $_POST['public_key']);
|
286 |
-
update_option(TidioLiveChat::PRIVATE_KEY_OPTION, $_POST['private_key']);
|
287 |
-
|
288 |
-
echo '1';
|
289 |
exit;
|
290 |
}
|
291 |
|
292 |
-
|
293 |
-
echo '<link rel="preconnect" href="//code.tidio.co">';
|
294 |
-
}
|
295 |
-
|
296 |
-
public function enqueueScriptsAsync()
|
297 |
-
{
|
298 |
-
$publicKey = TidioLiveChat::getPublicKey();
|
299 |
-
$widgetUrl = TidioLiveChatConfig::getWidgetUrl() . '/' . $publicKey . '.js';
|
300 |
-
$asyncScript = <<<SRC
|
301 |
-
<script type='text/javascript'>
|
302 |
-
document.tidioChatCode = "$publicKey";
|
303 |
-
(function() {
|
304 |
-
function asyncLoad() {
|
305 |
-
var tidioScript = document.createElement("script");
|
306 |
-
tidioScript.type = "text/javascript";
|
307 |
-
tidioScript.async = true;
|
308 |
-
tidioScript.src = "{$widgetUrl}";
|
309 |
-
document.body.appendChild(tidioScript);
|
310 |
-
}
|
311 |
-
if (window.attachEvent) {
|
312 |
-
window.attachEvent("onload", asyncLoad);
|
313 |
-
} else {
|
314 |
-
window.addEventListener("load", asyncLoad, false);
|
315 |
-
}
|
316 |
-
})();
|
317 |
-
</script>
|
318 |
-
SRC;
|
319 |
-
echo $asyncScript;
|
320 |
-
}
|
321 |
-
|
322 |
-
public static function getPublicKey()
|
323 |
-
{
|
324 |
-
$publicKey = get_option(TidioLiveChat::PUBLIC_KEY_OPTION);
|
325 |
-
|
326 |
-
if ($publicKey) {
|
327 |
-
return $publicKey;
|
328 |
-
}
|
329 |
-
|
330 |
-
TidioLiveChat::getPrivateKey();
|
331 |
-
|
332 |
-
return get_option(TidioLiveChat::PUBLIC_KEY_OPTION);
|
333 |
-
}
|
334 |
-
|
335 |
-
public function enqueueScriptsSync()
|
336 |
-
{
|
337 |
-
wp_enqueue_script('tidio-chat', TidioLiveChatConfig::getWidgetUrl() . '/' . TidioLiveChat::getPublicKey() . '.js', array(),
|
338 |
-
TIDIOCHAT_VERSION,
|
339 |
-
true);
|
340 |
-
wp_add_inline_script('tidio-chat', 'document.tidioChatCode = "' . TidioLiveChat::getPublicKey() . '";',
|
341 |
-
'before');
|
342 |
-
}
|
343 |
-
|
344 |
-
public function enqueueAdminScriptTranslation()
|
345 |
-
{
|
346 |
-
$langDir = plugin_dir_path(__FILE__) . 'languages/js/';
|
347 |
-
|
348 |
-
wp_set_script_translations('tidio-chat-admin', 'tidio-live-chat', $langDir);
|
349 |
-
}
|
350 |
-
|
351 |
-
public function enqueueAdminScripts()
|
352 |
-
{
|
353 |
-
$tidioConfig = [
|
354 |
-
'nonce' => wp_create_nonce(self::TIDIO_XHR_NONCE_NAME),
|
355 |
-
'apiUrl' => TidioLiveChatConfig::getApiUrl(),
|
356 |
-
'panelUrl' => TidioLiveChatConfig::getPanelUrl()
|
357 |
-
];
|
358 |
-
|
359 |
-
wp_enqueue_script('tidio-chat-admin', plugins_url('media/js/options.js', __FILE__), ['wp-i18n'], TIDIOCHAT_VERSION, true);
|
360 |
-
wp_add_inline_script('tidio-chat-admin', sprintf('const tidioConfig = %s', json_encode($tidioConfig)), 'before');
|
361 |
-
wp_enqueue_style('tidio-chat-admin-style', plugins_url('media/css/options.css', __FILE__), array(), TIDIOCHAT_VERSION);
|
362 |
-
}
|
363 |
-
|
364 |
-
public function adminJS()
|
365 |
-
{
|
366 |
-
$privateKey = TidioLiveChat::getPrivateKey();
|
367 |
-
$redirectUrl = '';
|
368 |
-
|
369 |
-
if ($privateKey && $privateKey != 'false') {
|
370 |
-
$redirectUrl = TidioLiveChat::getRedirectUrl($privateKey);
|
371 |
-
} else {
|
372 |
-
$redirectUrl = admin_url('admin-ajax.php?action=tidio_chat_redirect');
|
373 |
-
}
|
374 |
-
|
375 |
-
echo "<script>jQuery('a[href=\"admin.php?page=tidio-chat\"]').attr('href', '" . $redirectUrl . "').attr('target', '_blank') </script>";
|
376 |
-
}
|
377 |
-
|
378 |
-
public function addAdminMenuLink()
|
379 |
-
{
|
380 |
-
add_menu_page(
|
381 |
-
'Tidio Chat',
|
382 |
-
'Tidio Chat',
|
383 |
-
'manage_options',
|
384 |
-
'tidio-chat',
|
385 |
-
array($this, 'addAdminPage'),
|
386 |
-
'data:image/svg+xml;base64,' . self::TIDIO_ICON_BASE64
|
387 |
-
);
|
388 |
-
}
|
389 |
-
|
390 |
-
public function addAdminPage()
|
391 |
-
{
|
392 |
-
// Set class property
|
393 |
-
$dir = plugin_dir_path(__FILE__);
|
394 |
-
include $dir . 'options.php';
|
395 |
-
}
|
396 |
-
|
397 |
-
public function uninstall()
|
398 |
-
{
|
399 |
-
if (wp_verify_nonce($_GET['_wpnonce'], TidioLiveChat::CLEAR_ACCOUNT_DATA_ACTION) === false) {
|
400 |
-
wp_die('', 403);
|
401 |
-
}
|
402 |
-
|
403 |
-
delete_option(TidioLiveChat::PUBLIC_KEY_OPTION);
|
404 |
-
delete_option(TidioLiveChat::PRIVATE_KEY_OPTION);
|
405 |
-
delete_option(TidioLiveChat::ASYNC_LOAD_OPTION);
|
406 |
-
wp_redirect(admin_url('plugins.php'));
|
407 |
-
die();
|
408 |
-
}
|
409 |
}
|
410 |
|
411 |
-
|
412 |
-
{
|
413 |
-
/**
|
414 |
-
* @var array|null
|
415 |
-
*/
|
416 |
-
private static $config = null;
|
417 |
-
|
418 |
-
/**
|
419 |
-
* @return string
|
420 |
-
*/
|
421 |
-
public static function getApiUrl()
|
422 |
-
{
|
423 |
-
return self::getConfig()['tidio_api_url'];
|
424 |
-
}
|
425 |
-
|
426 |
-
/**
|
427 |
-
* @return string
|
428 |
-
*/
|
429 |
-
public static function getPanelUrl()
|
430 |
-
{
|
431 |
-
return self::getConfig()['tidio_panel_url'];
|
432 |
-
}
|
433 |
-
|
434 |
-
/**
|
435 |
-
* @return string
|
436 |
-
*/
|
437 |
-
public static function getWidgetUrl()
|
438 |
-
{
|
439 |
-
return self::getConfig()['tidio_widget_url'];
|
440 |
-
}
|
441 |
-
|
442 |
-
/**
|
443 |
-
* @return array
|
444 |
-
*/
|
445 |
-
private static function getConfig()
|
446 |
-
{
|
447 |
-
if (self::$config === null) {
|
448 |
-
self::$config = require __DIR__ . '/config.php';
|
449 |
-
}
|
450 |
|
451 |
-
|
452 |
-
|
453 |
-
}
|
454 |
-
|
455 |
-
add_action('init', 'initialize_tidio');
|
456 |
-
|
457 |
-
function initialize_tidio()
|
458 |
-
{
|
459 |
-
$tidioLiveChat = new TidioLiveChat();
|
460 |
-
}
|
461 |
-
|
462 |
-
register_activation_hook(__FILE__, array('TidioLiveChat', 'activate'));
|
463 |
-
|
464 |
-
class i18n
|
465 |
-
{
|
466 |
-
/**
|
467 |
-
* echo translation
|
468 |
-
*/
|
469 |
-
public static function _e($message)
|
470 |
-
{
|
471 |
-
_e($message, TidioLiveChat::TIDIO_PLUGIN_NAME);
|
472 |
-
}
|
473 |
-
|
474 |
-
/**
|
475 |
-
* returns translation
|
476 |
-
*/
|
477 |
-
public static function _t($message)
|
478 |
-
{
|
479 |
-
return __($message, TidioLiveChat::TIDIO_PLUGIN_NAME);
|
480 |
-
}
|
481 |
-
}
|
4 |
* Plugin Name: Tidio Chat
|
5 |
* Plugin URI: http://www.tidio.com
|
6 |
* Description: Tidio Live Chat - live chat boosted with chatbots for your online business. Integrates with your website in less than 20 seconds.
|
7 |
+
* Version: 5.0.0
|
8 |
* Author: Tidio Ltd.
|
9 |
* Author URI: http://www.tidio.com
|
10 |
* Text Domain: tidio-live-chat
|
11 |
* Domain Path: /languages/
|
12 |
* License: GPL2
|
13 |
*/
|
14 |
+
define('TIDIOCHAT_VERSION', '5.0.0');
|
15 |
+
define('AFFILIATE_CONFIG_FILE_PATH', get_template_directory() . '/tidio_affiliate_ref_id.txt');
|
16 |
+
|
17 |
+
require_once __DIR__ . '/src/TidioLiveChatConfig.php';
|
18 |
+
require_once __DIR__ . '/src/Translation/TidioTranslationLoader.php';
|
19 |
+
require_once __DIR__ . '/src/Translation/TidioErrorTranslator.php';
|
20 |
+
require_once __DIR__ . '/src/Translation/i18n.php';
|
21 |
+
require_once __DIR__ . '/src/Widget/TidioWidgetLoader.php';
|
22 |
+
require_once __DIR__ . '/src/Admin/TidioAdminActionLink.php';
|
23 |
+
require_once __DIR__ . '/src/Admin/TidioAdminController.php';
|
24 |
+
require_once __DIR__ . '/src/Admin/TidioIframeSetup.php';
|
25 |
+
require_once __DIR__ . '/src/Admin/TidioAdminDashboard.php';
|
26 |
+
require_once __DIR__ . '/src/Admin/TidioAdminRouting.php';
|
27 |
+
require_once __DIR__ . '/src/Admin/TidioAdminNotice.php';
|
28 |
+
require_once __DIR__ . '/src/Admin/TidioIframeSetup.php';
|
29 |
+
require_once __DIR__ . '/src/Sdk/TidioIntegrationFacade.php';
|
30 |
+
require_once __DIR__ . '/src/Sdk/Encryption/TidioEncryptionService.php';
|
31 |
+
require_once __DIR__ . '/src/Sdk/Encryption/Exception/TidioDecryptionFailedException.php';
|
32 |
+
require_once __DIR__ . '/src/Sdk/Encryption/Service/PlainTextTidioEncryptionService.php';
|
33 |
+
require_once __DIR__ . '/src/Sdk/Encryption/Service/OpenSslTidioEncryptionService.php';
|
34 |
+
require_once __DIR__ . '/src/Sdk/Encryption/Service/TidioEncryptionServiceFactory.php';
|
35 |
+
require_once __DIR__ . '/src/Sdk/Api/TidioApiClient.php';
|
36 |
+
require_once __DIR__ . '/src/Sdk/Api/Client/TidioApiClientFactory.php';
|
37 |
+
require_once __DIR__ . '/src/Sdk/Api/Client/CurlTidioApiClient.php';
|
38 |
+
require_once __DIR__ . '/src/Sdk/Api/Client/FileGetContentsTidioApiClient.php';
|
39 |
+
require_once __DIR__ . '/src/Sdk/Api/Exception/TidioApiException.php';
|
40 |
+
require_once __DIR__ . '/src/Utils/QueryParameters.php';
|
41 |
+
require_once __DIR__ . '/src/TidioIntegrationState.php';
|
42 |
+
require_once __DIR__ . '/src/TidioLiveChat.php';
|
43 |
+
|
44 |
+
function initializeTidioLiveChat()
|
45 |
{
|
46 |
+
if (!empty($_GET['tidio_chat_version'])) {
|
47 |
+
echo TIDIOCHAT_VERSION;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
exit;
|
49 |
}
|
50 |
|
51 |
+
TidioLiveChat::load();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
}
|
53 |
|
54 |
+
add_action('init', 'initializeTidioLiveChat');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
+
$encryptionService = (new TidioEncryptionServiceFactory())->create();
|
57 |
+
register_activation_hook(__FILE__, [new TidioIntegrationState($encryptionService), 'turnOnAsyncLoading']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
views/ajax-tidio-chat-redirect.php
DELETED
@@ -1,55 +0,0 @@
|
|
1 |
-
<!doctype html>
|
2 |
-
<html>
|
3 |
-
<head>
|
4 |
-
<meta charset="utf-8">
|
5 |
-
<title>Redirect to Tidio Chat...</title>
|
6 |
-
</head>
|
7 |
-
|
8 |
-
<body>
|
9 |
-
|
10 |
-
<script>
|
11 |
-
|
12 |
-
var path = {
|
13 |
-
admin_url: '<?php echo admin_url() ?>'
|
14 |
-
};
|
15 |
-
|
16 |
-
</script>
|
17 |
-
|
18 |
-
<?php /* ACCESS REDIRECT */ ?>
|
19 |
-
|
20 |
-
<?php if($view['mode']=='redirect'){ ?>
|
21 |
-
|
22 |
-
<script> location.href = '<?php echo $view['redirect_url'] ?>'; </script>
|
23 |
-
|
24 |
-
<?php } ?>
|
25 |
-
|
26 |
-
<?php /* ACCESS REQUEST */ ?>
|
27 |
-
|
28 |
-
<?php if($view['mode']=='access_request'){ ?>
|
29 |
-
|
30 |
-
<img src="<?php echo admin_url() ?>../wp-content/plugins/tidio-live-chat/media/img/ajax-loader.gif" />
|
31 |
-
|
32 |
-
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
|
33 |
-
<script>
|
34 |
-
|
35 |
-
$.getJSON('<?php echo $view['access_url'] ?>&remote=1', function(data){
|
36 |
-
|
37 |
-
if(!data || !data['status']){
|
38 |
-
alert('Error occurred, please refresh page and try again!');
|
39 |
-
return false;
|
40 |
-
}
|
41 |
-
|
42 |
-
data = data['value'];
|
43 |
-
|
44 |
-
location.href = path.admin_url + 'admin-ajax.php?action=tidio_chat_redirect&access_status=success&private_key=' + data.private_key + '&public_key=' + data.public_key;
|
45 |
-
|
46 |
-
});
|
47 |
-
|
48 |
-
</script>
|
49 |
-
|
50 |
-
<?php } ?>
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
</body>
|
55 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
views/iframe.php
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<iframe
|
2 |
+
id="tidio-panel-iframe"
|
3 |
+
style="overflow:hidden; height:calc(100vh - 32px); min-height: 620px; width:100%"
|
4 |
+
width="100%"
|
5 |
+
src="<?php echo isset($iframeUrl) ? $iframeUrl : ''; ?>">
|
6 |
+
</iframe>
|