Tidio Live Chat - Version 6.0.0

Version Description

  • Add WooCommerce integration
Download this release

Release Info

Developer kkopaczyktidio
Plugin Icon 128x128 Tidio Live Chat
Version 6.0.0
Comparing to
See all releases

Code changes from version 5.4.3 to 6.0.0

Files changed (51) hide show
  1. composer.json +4 -1
  2. composer.lock +5 -2
  3. languages/tidio-live-chat-es_ES.mo +0 -0
  4. languages/tidio-live-chat-es_MX.mo +0 -0
  5. languages/tidio-live-chat-fr_BE.mo +0 -0
  6. languages/tidio-live-chat-fr_CA.mo +0 -0
  7. languages/tidio-live-chat-fr_FR.mo +0 -0
  8. languages/tidio-live-chat-pl_PL.mo +0 -0
  9. readme.txt +6 -2
  10. src/Admin/AdminActionLink.php +4 -1
  11. src/Admin/AdminController.php +57 -20
  12. src/Admin/AdminDashboard.php +8 -5
  13. src/Admin/AdminNotice.php +41 -19
  14. src/Admin/AdminRouting.php +40 -4
  15. src/Admin/IframeSetup.php +9 -2
  16. src/Admin/Notice/DismissibleNoticeService.php +13 -2
  17. src/Admin/Notice/Views/{Php72RequirementNotice.php → NewWoocommerceFeaturesNotice.php} +3 -6
  18. src/Container.php +275 -0
  19. src/{Sdk/Encryption → Encryption}/EncryptionService.php +2 -2
  20. src/{Sdk/Encryption → Encryption}/Exception/DecryptionFailedException.php +1 -1
  21. src/{Sdk/Encryption → Encryption}/Service/EncryptionServiceFactory.php +6 -1
  22. src/{Sdk/Encryption → Encryption}/Service/OpenSslEncryptionService.php +3 -3
  23. src/{Sdk/Encryption → Encryption}/Service/PlainTextEncryptionService.php +2 -2
  24. src/{Sdk/Api/Client/CurlTidioApiClient.php → Http/Client/CurlHttpClient.php} +21 -15
  25. src/{Sdk/Api/Client/FileGetContentsTidioApiClient.php → Http/Client/FileGetContentsHttpClient.php} +21 -15
  26. src/Http/Exception/ErrorResponseException.php +56 -0
  27. src/Http/Exception/HttpClientException.php +11 -0
  28. src/Http/Exception/UnauthorizedResponseException.php +11 -0
  29. src/{Sdk/Api/TidioApiClient.php → Http/HttpClient.php} +8 -5
  30. src/IntegrationState.php +73 -6
  31. src/Sdk/Api/Client/TidioApiClientFactory.php +0 -38
  32. src/Sdk/IntegrationFacade.php +0 -52
  33. src/TidioLiveChat.php +31 -38
  34. src/TidioSdk/Dto/ApiCredentialsDto.php +45 -0
  35. src/TidioSdk/Exception/AccessTokensAreNotSetException.php +11 -0
  36. src/{Sdk/Api/Exception/TidioApiException.php → TidioSdk/Exception/CannotIntegrateWithProjectException.php} +31 -9
  37. src/TidioSdk/Exception/CannotRetrieveAccessTokensException.php +80 -0
  38. src/TidioSdk/TidioApiClientFactory.php +43 -0
  39. src/TidioSdk/TidioIntegrationService.php +123 -0
  40. src/Translation/I18n.php +2 -2
  41. src/Translation/TranslationLoader.php +3 -3
  42. src/Utils/Url.php +24 -0
  43. src/Widget/WidgetLoader.php +7 -3
  44. src/WooCommerceSdk/Dto/WooCommerceIntegrationDto.php +95 -0
  45. src/WooCommerceSdk/WooCommerceApiV3ClientFactory.php +27 -0
  46. src/WooCommerceSdk/WooCommerceIntegrationService.php +172 -0
  47. tidio-elements.php +6 -4
  48. vendor/composer/InstalledVersions.php +2 -2
  49. vendor/composer/autoload_classmap.php +22 -11
  50. vendor/composer/autoload_static.php +22 -11
  51. vendor/composer/installed.php +2 -2
composer.json CHANGED
@@ -1,6 +1,9 @@
1
  {
2
  "require": {
3
- "php": ">=5.6"
 
 
 
4
  },
5
  "autoload": {
6
  "psr-4": {
1
  {
2
  "require": {
3
+ "php": ">=5.6",
4
+ "ext-curl": "*",
5
+ "ext-json": "*",
6
+ "ext-openssl": "*"
7
  },
8
  "autoload": {
9
  "psr-4": {
composer.lock CHANGED
@@ -4,7 +4,7 @@
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
  "This file is @generated automatically"
6
  ],
7
- "content-hash": "160efcb558626824f4f30c49c7249d84",
8
  "packages": [],
9
  "packages-dev": [],
10
  "aliases": [],
@@ -13,7 +13,10 @@
13
  "prefer-stable": false,
14
  "prefer-lowest": false,
15
  "platform": {
16
- "php": ">=5.6"
 
 
 
17
  },
18
  "platform-dev": [],
19
  "plugin-api-version": "2.2.0"
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
  "This file is @generated automatically"
6
  ],
7
+ "content-hash": "b203ac4ce0c318e7778917506fe0d2f7",
8
  "packages": [],
9
  "packages-dev": [],
10
  "aliases": [],
13
  "prefer-stable": false,
14
  "prefer-lowest": false,
15
  "platform": {
16
+ "php": ">=5.6",
17
+ "ext-curl": "*",
18
+ "ext-json": "*",
19
+ "ext-openssl": "*"
20
  },
21
  "platform-dev": [],
22
  "plugin-api-version": "2.2.0"
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
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: tytus-tytus, lucastidio, marcingwizdala, kkopaczyktidio, ksladek,
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.4.3
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -198,6 +198,10 @@ Currently, Tidio is available in English and French. Other languages are in deve
198
 
199
  == Changelog ==
200
 
 
 
 
 
201
  = 5.4.3 =
202
 
203
  - Fix php function compatibility usage in notice
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: 7.2
7
+ Stable tag: 6.0.0
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
198
 
199
  == Changelog ==
200
 
201
+ = 6.0.0 =
202
+
203
+ - Add WooCommerce integration
204
+
205
  = 5.4.3 =
206
 
207
  - Fix php function compatibility usage in notice
src/Admin/AdminActionLink.php CHANGED
@@ -23,7 +23,10 @@ class AdminActionLink
23
  public function __construct($integrationsState)
24
  {
25
  $this->integrationState = $integrationsState;
 
26
 
 
 
27
  add_filter('plugin_action_links', [$this, 'addPluginActionLinks'], 10, 2);
28
  }
29
 
@@ -52,7 +55,7 @@ class AdminActionLink
52
  */
53
  private function isPluginConfigurationFile($file)
54
  {
55
- return strpos($file, TidioLiveChat::TIDIO_PLUGIN_NAME) !== false;
56
  }
57
 
58
  /**
23
  public function __construct($integrationsState)
24
  {
25
  $this->integrationState = $integrationsState;
26
+ }
27
 
28
+ public function load()
29
+ {
30
  add_filter('plugin_action_links', [$this, 'addPluginActionLinks'], 10, 2);
31
  }
32
 
55
  */
56
  private function isPluginConfigurationFile($file)
57
  {
58
+ return strpos($file, TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME) !== false;
59
  }
60
 
61
  /**
src/Admin/AdminController.php CHANGED
@@ -7,22 +7,28 @@ if (!defined('WPINC')) {
7
  }
8
 
9
  use TidioLiveChat\Admin\Notice\DismissibleNoticeService;
10
- use TidioLiveChat\Sdk\Api\Exception\TidioApiException;
11
- use TidioLiveChat\Sdk\IntegrationFacade;
 
12
  use TidioLiveChat\IntegrationState;
13
  use TidioLiveChat\TidioLiveChat;
14
  use TidioLiveChat\Utils\QueryParameters;
 
15
 
16
  class AdminController
17
  {
18
  /**
19
- * @var IntegrationFacade
20
  */
21
  private $integrationFacade;
22
  /**
23
  * @var IntegrationState
24
  */
25
  private $integrationState;
 
 
 
 
26
  /**
27
  * @var NonceValidator
28
  */
@@ -33,15 +39,17 @@ class AdminController
33
  private $dismissibleNoticeService;
34
 
35
  /**
36
- * @param IntegrationFacade $integrationFacade
37
  * @param IntegrationState $integrationState
 
38
  * @param NonceValidator $nonceValidator
39
  * @param DismissibleNoticeService $dismissibleNoticeService
40
  */
41
- public function __construct($integrationFacade, $integrationState, $nonceValidator, $dismissibleNoticeService)
42
  {
43
  $this->integrationFacade = $integrationFacade;
44
  $this->integrationState = $integrationState;
 
45
  $this->nonceValidator = $nonceValidator;
46
  $this->dismissibleNoticeService = $dismissibleNoticeService;
47
  }
@@ -54,17 +62,39 @@ class AdminController
54
 
55
  $refreshToken = QueryParameters::get('refreshToken');
56
  try {
57
- $data = $this->integrationFacade->integrateProject($refreshToken);
58
- } catch (TidioApiException $exception) {
59
- $errorCode = $exception->getMessage();
60
  $this->redirectToPluginAdminDashboardWithError($errorCode);
61
  }
62
 
63
- $this->integrationState->integrate(
64
- $data['projectPublicKey'],
65
- $data['accessToken'],
66
- $data['refreshToken']
67
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  $this->redirectToPluginAdminDashboard();
70
  }
@@ -103,15 +133,13 @@ class AdminController
103
 
104
  private function redirectToPluginsListDashboard()
105
  {
106
- wp_redirect(admin_url('plugins.php'));
107
- die();
108
  }
109
 
110
  private function redirectToPluginAdminDashboard()
111
  {
112
- $url = 'admin.php?page=' . TidioLiveChat::TIDIO_PLUGIN_NAME;
113
- wp_redirect(admin_url($url));
114
- die();
115
  }
116
 
117
  /**
@@ -119,8 +147,17 @@ class AdminController
119
  */
120
  private function redirectToPluginAdminDashboardWithError($errorCode)
121
  {
122
- $url = sprintf('admin.php?page=%s&error=%s', TidioLiveChat::TIDIO_PLUGIN_NAME, $errorCode);
123
- wp_redirect(admin_url($url));
 
 
 
 
 
 
 
 
 
124
  die();
125
  }
126
  }
7
  }
8
 
9
  use TidioLiveChat\Admin\Notice\DismissibleNoticeService;
10
+ use TidioLiveChat\TidioSdk\Exception\CannotIntegrateWithProjectException;
11
+ use TidioLiveChat\TidioSdk\Exception\CannotRetrieveAccessTokensException;
12
+ use TidioLiveChat\TidioSdk\TidioIntegrationService;
13
  use TidioLiveChat\IntegrationState;
14
  use TidioLiveChat\TidioLiveChat;
15
  use TidioLiveChat\Utils\QueryParameters;
16
+ use TidioLiveChat\WooCommerceSdk\WooCommerceIntegrationService;
17
 
18
  class AdminController
19
  {
20
  /**
21
+ * @var TidioIntegrationService
22
  */
23
  private $integrationFacade;
24
  /**
25
  * @var IntegrationState
26
  */
27
  private $integrationState;
28
+ /**
29
+ * @var WooCommerceIntegrationService
30
+ */
31
+ private $wooCommerceIntegrationService;
32
  /**
33
  * @var NonceValidator
34
  */
39
  private $dismissibleNoticeService;
40
 
41
  /**
42
+ * @param TidioIntegrationService $integrationFacade
43
  * @param IntegrationState $integrationState
44
+ * @param WooCommerceIntegrationService $wooCommerceIntegrationService
45
  * @param NonceValidator $nonceValidator
46
  * @param DismissibleNoticeService $dismissibleNoticeService
47
  */
48
+ public function __construct($integrationFacade, $integrationState, $wooCommerceIntegrationService, $nonceValidator, $dismissibleNoticeService)
49
  {
50
  $this->integrationFacade = $integrationFacade;
51
  $this->integrationState = $integrationState;
52
+ $this->wooCommerceIntegrationService = $wooCommerceIntegrationService;
53
  $this->nonceValidator = $nonceValidator;
54
  $this->dismissibleNoticeService = $dismissibleNoticeService;
55
  }
62
 
63
  $refreshToken = QueryParameters::get('refreshToken');
64
  try {
65
+ $this->integrationFacade->integrateProject($refreshToken);
66
+ } catch (CannotIntegrateWithProjectException $exception) {
67
+ $errorCode = $exception->getErrorCode();
68
  $this->redirectToPluginAdminDashboardWithError($errorCode);
69
  }
70
 
71
+ $this->redirectToPluginAdminDashboard();
72
+ }
73
+
74
+ public function handleAuthorizeWooCommerceAction()
75
+ {
76
+ if (!$this->isRequestNonceValid(AdminRouting::AUTHORIZE_WOOCOMMERCE_ACTION)) {
77
+ wp_die('', 403);
78
+ }
79
+
80
+ try {
81
+ $authUrl = $this->wooCommerceIntegrationService->getAuthUrl();
82
+ } catch (CannotRetrieveAccessTokensException $exception) {
83
+ $this->redirectToPluginAdminDashboardWithError($exception->getErrorCode());
84
+ }
85
+
86
+ $this->redirectToUrl($authUrl);
87
+ }
88
+
89
+ public function handleIntegrateWooCommerceAction()
90
+ {
91
+ if (!$this->isRequestNonceValid(AdminRouting::INTEGRATE_WOOCOMMERCE_ACTION)) {
92
+ wp_die('', 403);
93
+ }
94
+
95
+ if (QueryParameters::has('success') && QueryParameters::get('success') === '1') {
96
+ $this->integrationState->integrateWooCommerce();
97
+ }
98
 
99
  $this->redirectToPluginAdminDashboard();
100
  }
133
 
134
  private function redirectToPluginsListDashboard()
135
  {
136
+ $this->redirectToUrl(admin_url('plugins.php'));
 
137
  }
138
 
139
  private function redirectToPluginAdminDashboard()
140
  {
141
+ $url = 'admin.php?page=' . TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME;
142
+ $this->redirectToUrl(admin_url($url));
 
143
  }
144
 
145
  /**
147
  */
148
  private function redirectToPluginAdminDashboardWithError($errorCode)
149
  {
150
+ $url = sprintf('admin.php?page=%s&error=%s', TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME, $errorCode);
151
+ $this->redirectToUrl(admin_url($url));
152
+ }
153
+
154
+ /**
155
+ * @param string $url
156
+ * @return never-return
157
+ */
158
+ private function redirectToUrl($url)
159
+ {
160
+ wp_redirect($url);
161
  die();
162
  }
163
  }
src/Admin/AdminDashboard.php CHANGED
@@ -12,7 +12,7 @@ use WP_Admin_Bar;
12
 
13
  class AdminDashboard
14
  {
15
- const TIDIO_ICON_BASE64 = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIzLjEuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IldhcnN0d2FfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiCgkgdmlld0JveD0iMCAwIDIwIDIwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMCAyMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiNBMEE1QUE7fQo8L3N0eWxlPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMiwxOHYtNS45YzAtMi43LDEuNy01LDQuMy01LjdDNy4xLDMuNyw5LjQsMiwxMi4xLDJDMTUuNCwyLDE4LDQuNiwxOCw3Ljl2NS45aC00LjVsMCwwLjEKCWMtMC44LDIuNS0zLDQuMS01LjYsNC4xSDJ6IE02LjEsOC4xTDYuMSw4LjFjLTEuNiwwLjctMi42LDIuMy0yLjYsNC4xdjQuNGg0LjRjMS44LDAsMy4zLTEsNC4xLTIuNmwwLTAuMWwtMC4xLDAKCWMtMy4xLTAuMi01LjYtMi43LTUuNy01LjZsMC0wLjFMNi4xLDguMXogTTEyLjEsMy41Yy0xLjgsMC0zLjMsMS00LjEsMi42bDAsMC4xbDAuMSwwYzMuMiwwLjEsNS43LDIuNyw1LjcsNS45djAuMWwwLjEsMC4xaDIuN1Y3LjkKCUMxNi41LDUuNSwxNC41LDMuNSwxMi4xLDMuNXogTTcuNiw3LjhMNy42LDcuOGMwLDIuNSwyLDQuNSw0LjQsNC41aDAuMWwwLjEtMC4xYzAtMi41LTItNC41LTQuNC00LjVINy43TDcuNiw3Ljh6Ii8+Cjwvc3ZnPgo=';
16
 
17
  /**
18
  * @var IntegrationState
@@ -31,7 +31,10 @@ class AdminDashboard
31
  {
32
  $this->integrationState = $integrationState;
33
  $this->iframeSetup = $iframeSetup;
 
34
 
 
 
35
  add_action('admin_menu', [$this, 'addAdminMenuLink']);
36
  add_action('admin_bar_menu', [$this, 'addAdminBarItem'], 500);
37
  add_action('admin_enqueue_scripts', [$this, 'topBarStyles']);
@@ -43,9 +46,9 @@ class AdminDashboard
43
  'Tidio Chat',
44
  'Tidio Chat',
45
  'manage_options',
46
- TidioLiveChat::TIDIO_PLUGIN_NAME,
47
  [$this, 'addAdminPage'],
48
- 'data:image/svg+xml;base64,' . self::TIDIO_ICON_BASE64,
49
  '99.12'
50
  );
51
  }
@@ -64,9 +67,9 @@ class AdminDashboard
64
 
65
  public function addAdminBarItem(WP_Admin_Bar $adminBar)
66
  {
67
- $url = admin_url('admin.php?page=' . TidioLiveChat::TIDIO_PLUGIN_NAME);
68
 
69
- $icon = '<span class="custom-icon" style="background-image:url(\'data:image/svg+xml;base64,'. self::TIDIO_ICON_BASE64.'\');"></span>';
70
 
71
  $adminBar->add_node(
72
  [
12
 
13
  class AdminDashboard
14
  {
15
+ const TIDIO_ICON_SVG = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIzLjEuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IldhcnN0d2FfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiCgkgdmlld0JveD0iMCAwIDIwIDIwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMCAyMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiNBMEE1QUE7fQo8L3N0eWxlPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMiwxOHYtNS45YzAtMi43LDEuNy01LDQuMy01LjdDNy4xLDMuNyw5LjQsMiwxMi4xLDJDMTUuNCwyLDE4LDQuNiwxOCw3Ljl2NS45aC00LjVsMCwwLjEKCWMtMC44LDIuNS0zLDQuMS01LjYsNC4xSDJ6IE02LjEsOC4xTDYuMSw4LjFjLTEuNiwwLjctMi42LDIuMy0yLjYsNC4xdjQuNGg0LjRjMS44LDAsMy4zLTEsNC4xLTIuNmwwLTAuMWwtMC4xLDAKCWMtMy4xLTAuMi01LjYtMi43LTUuNy01LjZsMC0wLjFMNi4xLDguMXogTTEyLjEsMy41Yy0xLjgsMC0zLjMsMS00LjEsMi42bDAsMC4xbDAuMSwwYzMuMiwwLjEsNS43LDIuNyw1LjcsNS45djAuMWwwLjEsMC4xaDIuN1Y3LjkKCUMxNi41LDUuNSwxNC41LDMuNSwxMi4xLDMuNXogTTcuNiw3LjhMNy42LDcuOGMwLDIuNSwyLDQuNSw0LjQsNC41aDAuMWwwLjEtMC4xYzAtMi41LTItNC41LTQuNC00LjVINy43TDcuNiw3Ljh6Ii8+Cjwvc3ZnPgo=';
16
 
17
  /**
18
  * @var IntegrationState
31
  {
32
  $this->integrationState = $integrationState;
33
  $this->iframeSetup = $iframeSetup;
34
+ }
35
 
36
+ public function load()
37
+ {
38
  add_action('admin_menu', [$this, 'addAdminMenuLink']);
39
  add_action('admin_bar_menu', [$this, 'addAdminBarItem'], 500);
40
  add_action('admin_enqueue_scripts', [$this, 'topBarStyles']);
46
  'Tidio Chat',
47
  'Tidio Chat',
48
  'manage_options',
49
+ TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME,
50
  [$this, 'addAdminPage'],
51
+ self::TIDIO_ICON_SVG,
52
  '99.12'
53
  );
54
  }
67
 
68
  public function addAdminBarItem(WP_Admin_Bar $adminBar)
69
  {
70
+ $url = admin_url('admin.php?page=' . TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME);
71
 
72
+ $icon = '<span class="custom-icon" style="background-image:url(\'' . self::TIDIO_ICON_SVG . '\');"></span>';
73
 
74
  $adminBar->add_node(
75
  [
src/Admin/AdminNotice.php CHANGED
@@ -8,8 +8,11 @@ if (!defined('WPINC')) {
8
 
9
  use TidioLiveChat\Admin\Notice\DismissibleNoticeService;
10
  use TidioLiveChat\Admin\Notice\Exception\NoticeNameIsNotAllowedException;
 
11
  use TidioLiveChat\Translation\ErrorTranslator;
 
12
  use TidioLiveChat\Utils\QueryParameters;
 
13
 
14
  class AdminNotice
15
  {
@@ -23,17 +26,34 @@ class AdminNotice
23
  */
24
  private $dismissibleNoticeService;
25
 
 
 
 
 
 
 
 
 
 
 
26
  /**
27
  * @param ErrorTranslator $errorTranslator
28
  * @param DismissibleNoticeService $dismissibleNoticeService
 
 
29
  */
30
- public function __construct($errorTranslator, $dismissibleNoticeService)
31
  {
32
  $this->errorTranslator = $errorTranslator;
33
  $this->dismissibleNoticeService = $dismissibleNoticeService;
 
 
 
34
 
 
 
35
  add_action('admin_notices', [$this, 'addAdminErrorNotice']);
36
- add_action('admin_notices', [$this, 'addPhp72RequirementDismissibleNotice']);
37
  }
38
 
39
  public function addAdminErrorNotice()
@@ -47,29 +67,31 @@ class AdminNotice
47
  echo sprintf('<div class="notice notice-error is-dismissible"><p>%s</p></div>', $errorMessage);
48
  }
49
 
50
- public function addPhp72RequirementDismissibleNotice()
51
  {
52
- $script = $this->getNoticeFile(__DIR__ . '/Notice/Views/Php72RequirementNotice.php');
53
-
54
- try {
55
- $this->dismissibleNoticeService->displayNotice(
56
- $script,
57
- DismissibleNoticeService::PHP_7_2_REQUIREMENT_NOTICE
58
- );
59
- } catch (NoticeNameIsNotAllowedException $exception) {
60
- // do not display notice if notice name is invalid
61
  }
 
 
 
 
 
62
  }
63
 
64
  /**
65
- * @param string $path
66
- *
67
- * @return string
68
  */
69
- private function getNoticeFile($path)
70
  {
71
- ob_start();
72
- include $path;
73
- return ob_get_clean();
 
 
74
  }
75
  }
8
 
9
  use TidioLiveChat\Admin\Notice\DismissibleNoticeService;
10
  use TidioLiveChat\Admin\Notice\Exception\NoticeNameIsNotAllowedException;
11
+ use TidioLiveChat\IntegrationState;
12
  use TidioLiveChat\Translation\ErrorTranslator;
13
+ use TidioLiveChat\Translation\I18n;
14
  use TidioLiveChat\Utils\QueryParameters;
15
+ use TidioLiveChat\WooCommerceSdk\WooCommerceIntegrationService;
16
 
17
  class AdminNotice
18
  {
26
  */
27
  private $dismissibleNoticeService;
28
 
29
+ /**
30
+ * @var WooCommerceIntegrationService
31
+ */
32
+ private $wooCommerceIntegrationService;
33
+
34
+ /**
35
+ * @var IntegrationState
36
+ */
37
+ private $integrationState;
38
+
39
  /**
40
  * @param ErrorTranslator $errorTranslator
41
  * @param DismissibleNoticeService $dismissibleNoticeService
42
+ * @param WooCommerceIntegrationService $wooCommerceIntegrationService
43
+ * @param IntegrationState $integrationState
44
  */
45
+ public function __construct($errorTranslator, $dismissibleNoticeService, $wooCommerceIntegrationService, $integrationState)
46
  {
47
  $this->errorTranslator = $errorTranslator;
48
  $this->dismissibleNoticeService = $dismissibleNoticeService;
49
+ $this->wooCommerceIntegrationService = $wooCommerceIntegrationService;
50
+ $this->integrationState = $integrationState;
51
+ }
52
 
53
+ public function load()
54
+ {
55
  add_action('admin_notices', [$this, 'addAdminErrorNotice']);
56
+ add_action('admin_notices', [$this, 'addNewWoocommerceFeaturesNotice']);
57
  }
58
 
59
  public function addAdminErrorNotice()
67
  echo sprintf('<div class="notice notice-error is-dismissible"><p>%s</p></div>', $errorMessage);
68
  }
69
 
70
+ public function addNewWoocommerceFeaturesNotice()
71
  {
72
+ if ($this->wooCommerceIntegrationService->isWooCommerceActivated() === false
73
+ || $this->integrationState->isWooCommerceIntegrated()
74
+ ) {
75
+ return;
 
 
 
 
 
76
  }
77
+
78
+ $this->displayDismissibleNotice(
79
+ __DIR__ . '/Notice/Views/NewWoocommerceFeaturesNotice.php',
80
+ DismissibleNoticeService::NEW_WOOCOMMERCE_FEATURES_NOTICE
81
+ );
82
  }
83
 
84
  /**
85
+ * @param string $templatePath
86
+ * @param string $noticeName
87
+ * @return void
88
  */
89
+ private function displayDismissibleNotice($templatePath, $noticeName)
90
  {
91
+ try {
92
+ $this->dismissibleNoticeService->displayNotice($templatePath, $noticeName);
93
+ } catch (NoticeNameIsNotAllowedException $exception) {
94
+ // do not display notice if notice name is invalid
95
+ }
96
  }
97
  }
src/Admin/AdminRouting.php CHANGED
@@ -13,18 +13,38 @@ class AdminRouting
13
  const CLEAR_ACCOUNT_DATA_ACTION = 'tidio-live-chat-clear-account-data';
14
  const INTEGRATE_PROJECT_ACTION = 'tidio-live-chat-integrate-project';
15
  const TOGGLE_ASYNC_LOADING_ACTION = 'tidio-live-chat-toggle-async-loading';
 
 
16
  const DISMISS_NOTICE_ACTION = 'tidio-live-chat-dismiss-notice';
17
 
 
 
 
 
 
 
 
 
 
 
18
  /**
19
  * @param AdminController $adminController
20
  * @param DismissibleNoticeController $dismissibleNoticeController
21
  */
22
  public function __construct($adminController, $dismissibleNoticeController)
23
  {
24
- add_action('admin_post_' . self::INTEGRATE_PROJECT_ACTION, [$adminController, 'handleIntegrateProjectAction']);
25
- add_action('admin_post_' . self::TOGGLE_ASYNC_LOADING_ACTION, [$adminController, 'handleToggleAsyncLoadingAction']);
26
- add_action('admin_post_' . self::CLEAR_ACCOUNT_DATA_ACTION, [$adminController, 'handleClearAccountDataAction']);
27
- add_action('admin_post_' . self::DISMISS_NOTICE_ACTION, [$dismissibleNoticeController, 'handleDismissNotice']);
 
 
 
 
 
 
 
 
28
  }
29
 
30
  /**
@@ -51,6 +71,22 @@ class AdminRouting
51
  return self::getEndpointForAction(self::CLEAR_ACCOUNT_DATA_ACTION);
52
  }
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  /**
55
  * @param string $noticeOptionName
56
  * @return string
13
  const CLEAR_ACCOUNT_DATA_ACTION = 'tidio-live-chat-clear-account-data';
14
  const INTEGRATE_PROJECT_ACTION = 'tidio-live-chat-integrate-project';
15
  const TOGGLE_ASYNC_LOADING_ACTION = 'tidio-live-chat-toggle-async-loading';
16
+ const AUTHORIZE_WOOCOMMERCE_ACTION = 'tidio-live-chat-authorize-woocommerce';
17
+ const INTEGRATE_WOOCOMMERCE_ACTION = 'tidio-live-chat-integrate-woocommerce';
18
  const DISMISS_NOTICE_ACTION = 'tidio-live-chat-dismiss-notice';
19
 
20
+ /**
21
+ * @var AdminController
22
+ */
23
+ private $adminController;
24
+
25
+ /**
26
+ * @var DismissibleNoticeController
27
+ */
28
+ private $dismissibleNoticeController;
29
+
30
  /**
31
  * @param AdminController $adminController
32
  * @param DismissibleNoticeController $dismissibleNoticeController
33
  */
34
  public function __construct($adminController, $dismissibleNoticeController)
35
  {
36
+ $this->adminController = $adminController;
37
+ $this->dismissibleNoticeController = $dismissibleNoticeController;
38
+ }
39
+
40
+ public function load()
41
+ {
42
+ add_action('admin_post_' . self::INTEGRATE_PROJECT_ACTION, [$this->adminController, 'handleIntegrateProjectAction']);
43
+ add_action('admin_post_' . self::TOGGLE_ASYNC_LOADING_ACTION, [$this->adminController, 'handleToggleAsyncLoadingAction']);
44
+ add_action('admin_post_' . self::CLEAR_ACCOUNT_DATA_ACTION, [$this->adminController, 'handleClearAccountDataAction']);
45
+ add_action('admin_post_' . self::AUTHORIZE_WOOCOMMERCE_ACTION, [$this->adminController, 'handleAuthorizeWooCommerceAction']);
46
+ add_action('admin_post_' . self::INTEGRATE_WOOCOMMERCE_ACTION, [$this->adminController, 'handleIntegrateWooCommerceAction']);
47
+ add_action('admin_post_' . self::DISMISS_NOTICE_ACTION, [$this->dismissibleNoticeController, 'handleDismissNotice']);
48
  }
49
 
50
  /**
71
  return self::getEndpointForAction(self::CLEAR_ACCOUNT_DATA_ACTION);
72
  }
73
 
74
+ /**
75
+ * @return string
76
+ */
77
+ public static function getEndpointForAuthorizeWooCommerceAction()
78
+ {
79
+ return self::getEndpointForAction(self::AUTHORIZE_WOOCOMMERCE_ACTION);
80
+ }
81
+
82
+ /**
83
+ * @return string
84
+ */
85
+ public static function getEndpointForIntegrateWooCommerceAction()
86
+ {
87
+ return self::getEndpointForAction(self::INTEGRATE_WOOCOMMERCE_ACTION);
88
+ }
89
+
90
  /**
91
  * @param string $noticeOptionName
92
  * @return string
src/Admin/IframeSetup.php CHANGED
@@ -9,6 +9,7 @@ if (!defined('WPINC')) {
9
  use Exception;
10
  use TidioLiveChat\IntegrationState;
11
  use TidioLiveChat\Config;
 
12
 
13
  class IframeSetup
14
  {
@@ -16,13 +17,18 @@ class IframeSetup
16
  * @var IntegrationState
17
  */
18
  private $integrationState;
 
 
 
 
19
 
20
  /**
21
  * @param IntegrationState $integrationState
22
  */
23
- public function __construct($integrationState)
24
  {
25
  $this->integrationState = $integrationState;
 
26
  }
27
 
28
  /**
@@ -55,7 +61,8 @@ class IframeSetup
55
  [
56
  'panelUrl' => $this->getPanelRedirectUrl()
57
  ],
58
- $this->getDefaultIframeQueryParams()
 
59
  );
60
 
61
  $iframeBaseUrl = Config::getPanelUrl() . '/integration-success';
9
  use Exception;
10
  use TidioLiveChat\IntegrationState;
11
  use TidioLiveChat\Config;
12
+ use TidioLiveChat\WooCommerceSdk\WooCommerceIntegrationService;
13
 
14
  class IframeSetup
15
  {
17
  * @var IntegrationState
18
  */
19
  private $integrationState;
20
+ /**
21
+ * @var WooCommerceIntegrationService
22
+ */
23
+ private $wooCommerceIntegrationService;
24
 
25
  /**
26
  * @param IntegrationState $integrationState
27
  */
28
+ public function __construct($integrationState, $wooCommerceIntegrationService)
29
  {
30
  $this->integrationState = $integrationState;
31
+ $this->wooCommerceIntegrationService = $wooCommerceIntegrationService;
32
  }
33
 
34
  /**
61
  [
62
  'panelUrl' => $this->getPanelRedirectUrl()
63
  ],
64
+ $this->getDefaultIframeQueryParams(),
65
+ $this->wooCommerceIntegrationService->getIntegrationData()->toIframeData()
66
  );
67
 
68
  $iframeBaseUrl = Config::getPanelUrl() . '/integration-success';
src/Admin/Notice/DismissibleNoticeService.php CHANGED
@@ -12,6 +12,7 @@ use TidioLiveChat\Admin\Notice\Exception\NoticeNameIsNotAllowedException;
12
  class DismissibleNoticeService
13
  {
14
  const PHP_7_2_REQUIREMENT_NOTICE = 'tidio-php-7-2-requirement-notice';
 
15
 
16
  /**
17
  * @return string[]
@@ -20,6 +21,7 @@ class DismissibleNoticeService
20
  {
21
  return [
22
  self::PHP_7_2_REQUIREMENT_NOTICE,
 
23
  ];
24
  }
25
 
@@ -37,11 +39,11 @@ class DismissibleNoticeService
37
  /**
38
  * Remember that your script should contain data-dismissible-url="{dismiss_url}"
39
  *
40
- * @param string $script
41
  * @param string $noticeName
42
  * @return void
43
  */
44
- public function displayNotice($script, $noticeName)
45
  {
46
  $this->validateNoticeName($noticeName);
47
 
@@ -49,6 +51,8 @@ class DismissibleNoticeService
49
  return;
50
  }
51
 
 
 
52
  if (strpos($script, 'data-tidio-dismissible-url="{dismiss_url}"') === false) {
53
  throw new \RuntimeException('Given script should contains \'data-tidio-dismissible-url={dismiss_url}\' to inject dismissible script.');
54
  }
@@ -130,4 +134,11 @@ HTML;
130
  {
131
  return in_array($noticeName, self::getAllowedNoticeOptions(), true) === false;
132
  }
 
 
 
 
 
 
 
133
  }
12
  class DismissibleNoticeService
13
  {
14
  const PHP_7_2_REQUIREMENT_NOTICE = 'tidio-php-7-2-requirement-notice';
15
+ const NEW_WOOCOMMERCE_FEATURES_NOTICE = 'tidio-new-woocommerce-features-notice';
16
 
17
  /**
18
  * @return string[]
21
  {
22
  return [
23
  self::PHP_7_2_REQUIREMENT_NOTICE,
24
+ self::NEW_WOOCOMMERCE_FEATURES_NOTICE,
25
  ];
26
  }
27
 
39
  /**
40
  * Remember that your script should contain data-dismissible-url="{dismiss_url}"
41
  *
42
+ * @param string $templatePath
43
  * @param string $noticeName
44
  * @return void
45
  */
46
+ public function displayNotice($templatePath, $noticeName)
47
  {
48
  $this->validateNoticeName($noticeName);
49
 
51
  return;
52
  }
53
 
54
+ $script = $this->getNoticeFile($templatePath);
55
+
56
  if (strpos($script, 'data-tidio-dismissible-url="{dismiss_url}"') === false) {
57
  throw new \RuntimeException('Given script should contains \'data-tidio-dismissible-url={dismiss_url}\' to inject dismissible script.');
58
  }
134
  {
135
  return in_array($noticeName, self::getAllowedNoticeOptions(), true) === false;
136
  }
137
+
138
+ private function getNoticeFile($path)
139
+ {
140
+ ob_start();
141
+ include $path;
142
+ return ob_get_clean();
143
+ }
144
  }
src/Admin/Notice/Views/{Php72RequirementNotice.php → NewWoocommerceFeaturesNotice.php} RENAMED
@@ -120,17 +120,14 @@ use TidioLiveChat\Translation\I18n;
120
  <section>
121
  <p class="header">
122
  <strong>
123
- <?php I18n::_e('Tidio Chat will be updated soon.'); ?>
124
  </strong>
125
  </p>
126
  <p>
127
- <?php I18n::_e('The WooCommerce users will be able to browse all the products in the Tidio panel and send them as product cards in chat conversations with customers.'); ?>
128
- <strong><?php I18n::_e('This update will require PHP 7.2 or higher.'); ?></strong>
129
  </p>
130
  </section>
131
- <a class="link button" href="https://help.tidio.com/docs/send-woocommerce-products-to-customers-directly-from-tidio" target="_blank">
132
- <?php I18n::_e('Check how product cards work'); ?>
133
- </a>
134
  </div>
135
  <a data-tidio-dismissible-url="{dismiss_url}" class="dissmiss-button"
136
  ><svg
120
  <section>
121
  <p class="header">
122
  <strong>
123
+ <?php I18n::_e('You have successfully installed/updated Tidio Chat. It’s time to unlock new options.'); ?>
124
  </strong>
125
  </p>
126
  <p>
127
+ <?php I18n::_e('Integrate your account with WooCommerce to access these features. It takes just a minute!'); ?>
 
128
  </p>
129
  </section>
130
+ <a class="link button" href="<?php echo admin_url('admin.php?page=tidio-live-chat') ?>"><?php I18n::_e('Integrate now'); ?></a>
 
 
131
  </div>
132
  <a data-tidio-dismissible-url="{dismiss_url}" class="dissmiss-button"
133
  ><svg
src/Container.php ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ use TidioLiveChat\Admin\AdminActionLink;
10
+ use TidioLiveChat\Admin\AdminController;
11
+ use TidioLiveChat\Admin\AdminDashboard;
12
+ use TidioLiveChat\Admin\AdminNotice;
13
+ use TidioLiveChat\Admin\AdminRouting;
14
+ use TidioLiveChat\Admin\IframeSetup;
15
+ use TidioLiveChat\Admin\NonceValidator;
16
+ use TidioLiveChat\Admin\Notice\DismissibleNoticeController;
17
+ use TidioLiveChat\Admin\Notice\DismissibleNoticeService;
18
+ use TidioLiveChat\Encryption\EncryptionService;
19
+ use TidioLiveChat\Encryption\Service\EncryptionServiceFactory;
20
+ use TidioLiveChat\TidioSdk\TidioApiClientFactory;
21
+ use TidioLiveChat\TidioSdk\TidioIntegrationService;
22
+ use TidioLiveChat\Translation\ErrorTranslator;
23
+ use TidioLiveChat\Translation\TranslationLoader;
24
+ use TidioLiveChat\Widget\WidgetLoader;
25
+ use TidioLiveChat\WooCommerceSdk\WooCommerceApiV3ClientFactory;
26
+ use TidioLiveChat\WooCommerceSdk\WooCommerceIntegrationService;
27
+
28
+ class Container
29
+ {
30
+ /**
31
+ * @var array<string, mixed>
32
+ */
33
+ private $serviceStore = [];
34
+
35
+ /**
36
+ * @param string $id
37
+ * @return mixed
38
+ */
39
+ public function get($id)
40
+ {
41
+ if (array_key_exists($id, $this->serviceStore)) {
42
+ return $this->serviceStore[$id];
43
+ }
44
+
45
+ switch ($id) {
46
+ case TranslationLoader::class:
47
+ $service = new TranslationLoader();
48
+ break;
49
+
50
+ case ErrorTranslator::class:
51
+ $service = new ErrorTranslator();
52
+ break;
53
+
54
+ case EncryptionServiceFactory::class:
55
+ $service = new EncryptionServiceFactory();
56
+ break;
57
+
58
+ case TidioApiClientFactory::class:
59
+ $service = new TidioApiClientFactory();
60
+ break;
61
+
62
+ case WooCommerceApiV3ClientFactory::class:
63
+ $service = new WooCommerceApiV3ClientFactory();
64
+ break;
65
+
66
+ case NonceValidator::class:
67
+ $service = new NonceValidator();
68
+ break;
69
+
70
+ case DismissibleNoticeService::class:
71
+ $service = new DismissibleNoticeService();
72
+ break;
73
+
74
+ case EncryptionService::class:
75
+ $service = $this->buildEncryptionService();
76
+ break;
77
+
78
+ case IntegrationState::class:
79
+ $service = $this->buildIntegrationState();
80
+ break;
81
+
82
+ case WidgetLoader::class:
83
+ $service = $this->buildWidgetLoader();
84
+ break;
85
+
86
+ case AdminNotice::class:
87
+ $service = $this->buildAdminNotice();
88
+ break;
89
+
90
+ case AdminActionLink::class:
91
+ $service = $this->buildAdminActionLink();
92
+ break;
93
+
94
+ case TidioIntegrationService::class:
95
+ $service = $this->buildTidioIntegrationService();
96
+ break;
97
+
98
+ case WooCommerceIntegrationService::class:
99
+ $service = $this->buildWooCommerceIntegrationService();
100
+ break;
101
+
102
+ case AdminController::class:
103
+ $service = $this->buildAdminController();
104
+ break;
105
+
106
+ case IframeSetup::class:
107
+ $service = $this->buildIframeSetup();
108
+ break;
109
+
110
+ case AdminRouting::class:
111
+ $service = $this->buildAdminRouting();
112
+ break;
113
+
114
+ case AdminDashboard::class:
115
+ $service = $this->buildAdminDashboard();
116
+ break;
117
+
118
+ case DismissibleNoticeController::class:
119
+ $service = $this->buildDismissibleNoticeController();
120
+ break;
121
+
122
+ default:
123
+ throw new \RuntimeException('Cannot resolve service from container: ' . $id);
124
+ }
125
+
126
+ $this->serviceStore[$id] = $service;
127
+
128
+ return $service;
129
+ }
130
+
131
+ /**
132
+ * @param string $id
133
+ * @return bool void
134
+ */
135
+ public function has($id)
136
+ {
137
+ try {
138
+ $this->get($id);
139
+ } catch (\RuntimeException $exception) {
140
+ return false;
141
+ }
142
+
143
+ return true;
144
+ }
145
+
146
+ /**
147
+ * @return EncryptionService
148
+ */
149
+ private function buildEncryptionService()
150
+ {
151
+ $encryptionServiceFactory = $this->get(EncryptionServiceFactory::class);
152
+ return $encryptionServiceFactory->create();
153
+ }
154
+
155
+ /**
156
+ * @return IntegrationState
157
+ */
158
+ private function buildIntegrationState()
159
+ {
160
+ return new IntegrationState(
161
+ $this->get(EncryptionService::class)
162
+ );
163
+ }
164
+
165
+ /**
166
+ * @return WidgetLoader
167
+ */
168
+ private function buildWidgetLoader()
169
+ {
170
+ return new WidgetLoader(
171
+ $this->get(IntegrationState::class)
172
+ );
173
+ }
174
+
175
+ /**
176
+ * @return AdminNotice
177
+ */
178
+ private function buildAdminNotice()
179
+ {
180
+ return new AdminNotice(
181
+ $this->get(ErrorTranslator::class),
182
+ $this->get(DismissibleNoticeService::class),
183
+ $this->get(WooCommerceIntegrationService::class),
184
+ $this->get(IntegrationState::class)
185
+ );
186
+ }
187
+
188
+ /**
189
+ * @return AdminActionLink
190
+ */
191
+ private function buildAdminActionLink()
192
+ {
193
+ return new AdminActionLink(
194
+ $this->get(IntegrationState::class)
195
+ );
196
+ }
197
+
198
+ /**
199
+ * @return TidioIntegrationService
200
+ */
201
+ private function buildTidioIntegrationService()
202
+ {
203
+ return new TidioIntegrationService(
204
+ $this->get(IntegrationState::class),
205
+ $this->get(TidioApiClientFactory::class)
206
+ );
207
+ }
208
+
209
+ /**
210
+ * @return WooCommerceIntegrationService
211
+ */
212
+ private function buildWooCommerceIntegrationService()
213
+ {
214
+ return new WooCommerceIntegrationService(
215
+ $this->get(IntegrationState::class),
216
+ $this->get(WooCommerceApiV3ClientFactory::class),
217
+ $this->get(TidioIntegrationService::class)
218
+ );
219
+ }
220
+
221
+ /**
222
+ * @return AdminController
223
+ */
224
+ private function buildAdminController()
225
+ {
226
+ return new AdminController(
227
+ $this->get(TidioIntegrationService::class),
228
+ $this->get(IntegrationState::class),
229
+ $this->get(WooCommerceIntegrationService::class),
230
+ $this->get(NonceValidator::class),
231
+ $this->get(DismissibleNoticeService::class)
232
+ );
233
+ }
234
+
235
+ /**
236
+ * @return IframeSetup
237
+ */
238
+ private function buildIframeSetup()
239
+ {
240
+ return new IframeSetup(
241
+ $this->get(IntegrationState::class),
242
+ $this->get(WooCommerceIntegrationService::class)
243
+ );
244
+ }
245
+
246
+ /**
247
+ * @return AdminRouting
248
+ */
249
+ private function buildAdminRouting()
250
+ {
251
+ return new AdminRouting(
252
+ $this->get(AdminController::class),
253
+ $this->get(DismissibleNoticeController::class)
254
+ );
255
+ }
256
+
257
+ /**
258
+ * @return AdminDashboard
259
+ */
260
+ private function buildAdminDashboard()
261
+ {
262
+ return new AdminDashboard(
263
+ $this->get(IntegrationState::class),
264
+ $this->get(IframeSetup::class)
265
+ );
266
+ }
267
+
268
+ private function buildDismissibleNoticeController()
269
+ {
270
+ return new DismissibleNoticeController(
271
+ $this->get(DismissibleNoticeService::class),
272
+ $this->get(NonceValidator::class)
273
+ );
274
+ }
275
+ }
src/{Sdk/Encryption → Encryption}/EncryptionService.php RENAMED
@@ -1,12 +1,12 @@
1
  <?php
2
 
3
- namespace TidioLiveChat\Sdk\Encryption;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
- use TidioLiveChat\Sdk\Encryption\Exception\DecryptionFailedException;
10
 
11
  interface EncryptionService
12
  {
1
  <?php
2
 
3
+ namespace TidioLiveChat\Encryption;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ use TidioLiveChat\Encryption\Exception\DecryptionFailedException;
10
 
11
  interface EncryptionService
12
  {
src/{Sdk/Encryption → Encryption}/Exception/DecryptionFailedException.php RENAMED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- namespace TidioLiveChat\Sdk\Encryption\Exception;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
1
  <?php
2
 
3
+ namespace TidioLiveChat\Encryption\Exception;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
src/{Sdk/Encryption → Encryption}/Service/EncryptionServiceFactory.php RENAMED
@@ -1,13 +1,18 @@
1
  <?php
2
 
3
- namespace TidioLiveChat\Sdk\Encryption\Service;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
 
 
9
  class EncryptionServiceFactory
10
  {
 
 
 
11
  public function create()
12
  {
13
  $encryptionKey = $this->getEncryptionKey();
1
  <?php
2
 
3
+ namespace TidioLiveChat\Encryption\Service;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ use TidioLiveChat\Encryption\EncryptionService;
10
+
11
  class EncryptionServiceFactory
12
  {
13
+ /**
14
+ * @return EncryptionService
15
+ */
16
  public function create()
17
  {
18
  $encryptionKey = $this->getEncryptionKey();
src/{Sdk/Encryption → Encryption}/Service/OpenSslEncryptionService.php RENAMED
@@ -1,13 +1,13 @@
1
  <?php
2
 
3
- namespace TidioLiveChat\Sdk\Encryption\Service;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
- use TidioLiveChat\Sdk\Encryption\Exception\DecryptionFailedException;
10
- use TidioLiveChat\Sdk\Encryption\EncryptionService;
11
 
12
  class OpenSslEncryptionService implements EncryptionService
13
  {
1
  <?php
2
 
3
+ namespace TidioLiveChat\Encryption\Service;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ use TidioLiveChat\Encryption\Exception\DecryptionFailedException;
10
+ use TidioLiveChat\Encryption\EncryptionService;
11
 
12
  class OpenSslEncryptionService implements EncryptionService
13
  {
src/{Sdk/Encryption → Encryption}/Service/PlainTextEncryptionService.php RENAMED
@@ -1,12 +1,12 @@
1
  <?php
2
 
3
- namespace TidioLiveChat\Sdk\Encryption\Service;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
- use TidioLiveChat\Sdk\Encryption\EncryptionService;
10
 
11
  class PlainTextEncryptionService implements EncryptionService
12
  {
1
  <?php
2
 
3
+ namespace TidioLiveChat\Encryption\Service;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ use TidioLiveChat\Encryption\EncryptionService;
10
 
11
  class PlainTextEncryptionService implements EncryptionService
12
  {
src/{Sdk/Api/Client/CurlTidioApiClient.php → Http/Client/CurlHttpClient.php} RENAMED
@@ -1,27 +1,35 @@
1
  <?php
2
 
3
- namespace TidioLiveChat\Sdk\Api\Client;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
- use TidioLiveChat\Sdk\Api\Exception\TidioApiException;
10
- use TidioLiveChat\Sdk\Api\TidioApiClient;
11
- use TidioLiveChat\Config;
 
 
12
 
13
- class CurlTidioApiClient implements TidioApiClient
14
  {
 
 
 
 
15
  /**
16
  * @var string[]
17
  */
18
  private $headers;
19
 
20
  /**
 
21
  * @param string[] $additionalHeaders
22
  */
23
- public function __construct($additionalHeaders = [])
24
  {
 
25
  $this->headers = array_merge(
26
  [
27
  'Content-Type: application/json',
@@ -36,7 +44,7 @@ class CurlTidioApiClient implements TidioApiClient
36
  */
37
  public function sendPostRequest($path, $data = [])
38
  {
39
- $url = Config::getApiUrl() . $path;
40
  $ch = curl_init();
41
 
42
  curl_setopt($ch, CURLOPT_HEADER, 1);
@@ -61,7 +69,7 @@ class CurlTidioApiClient implements TidioApiClient
61
  */
62
  public function sendGetRequest($path)
63
  {
64
- $url = Config::getApiUrl() . $path;
65
  $ch = curl_init();
66
 
67
  curl_setopt($ch, CURLOPT_HEADER, 1);
@@ -100,19 +108,17 @@ class CurlTidioApiClient implements TidioApiClient
100
  /**
101
  * @param array<string, mixed> $responseData
102
  * @param array<string, mixed> $responseInfo
103
- * @throws TidioApiException
104
  */
105
  private function validateResponse($responseData, $responseInfo)
106
  {
107
  $statusCode = $responseInfo['http_code'];
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
  }
1
  <?php
2
 
3
+ namespace TidioLiveChat\Http\Client;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ use TidioLiveChat\Http\Exception\ErrorResponseException;
10
+ use TidioLiveChat\Http\Exception\HttpClientException;
11
+ use TidioLiveChat\Http\Exception\UnauthorizedResponseException;
12
+ use TidioLiveChat\Http\HttpClient;
13
+ use TidioLiveChat\Utils\Url;
14
 
15
+ class CurlHttpClient implements HttpClient
16
  {
17
+ /**
18
+ * @var string
19
+ */
20
+ private $apiUrl;
21
  /**
22
  * @var string[]
23
  */
24
  private $headers;
25
 
26
  /**
27
+ * @param string $apiUrl
28
  * @param string[] $additionalHeaders
29
  */
30
+ public function __construct($apiUrl, $additionalHeaders = [])
31
  {
32
+ $this->apiUrl = $apiUrl;
33
  $this->headers = array_merge(
34
  [
35
  'Content-Type: application/json',
44
  */
45
  public function sendPostRequest($path, $data = [])
46
  {
47
+ $url = Url::build($this->apiUrl, $path);
48
  $ch = curl_init();
49
 
50
  curl_setopt($ch, CURLOPT_HEADER, 1);
69
  */
70
  public function sendGetRequest($path)
71
  {
72
+ $url = Url::build($this->apiUrl, $path);
73
  $ch = curl_init();
74
 
75
  curl_setopt($ch, CURLOPT_HEADER, 1);
108
  /**
109
  * @param array<string, mixed> $responseData
110
  * @param array<string, mixed> $responseInfo
111
+ * @throws HttpClientException
112
  */
113
  private function validateResponse($responseData, $responseInfo)
114
  {
115
  $statusCode = $responseInfo['http_code'];
116
  if ($statusCode === 401) {
117
+ throw new UnauthorizedResponseException();
118
+ }
 
 
 
119
 
120
+ if ($statusCode < 200 || $statusCode >= 300) {
121
+ throw ErrorResponseException::withResponse($statusCode, $responseData);
122
  }
123
  }
124
  }
src/{Sdk/Api/Client/FileGetContentsTidioApiClient.php → Http/Client/FileGetContentsHttpClient.php} RENAMED
@@ -1,27 +1,35 @@
1
  <?php
2
 
3
- namespace TidioLiveChat\Sdk\Api\Client;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
- use TidioLiveChat\Sdk\Api\Exception\TidioApiException;
10
- use TidioLiveChat\Sdk\Api\TidioApiClient;
11
- use TidioLiveChat\Config;
 
 
12
 
13
- class FileGetContentsTidioApiClient implements TidioApiClient
14
  {
 
 
 
 
15
  /**
16
  * @var string[]
17
  */
18
  private $headers;
19
 
20
  /**
 
21
  * @param string[] $additionalHeaders
22
  */
23
- public function __construct($additionalHeaders = [])
24
  {
 
25
  $this->headers = array_merge(
26
  ['Accept: application/json'],
27
  $additionalHeaders
@@ -33,7 +41,7 @@ class FileGetContentsTidioApiClient implements TidioApiClient
33
  */
34
  public function sendPostRequest($path, $data = [])
35
  {
36
- $url = Config::getApiUrl() . $path;
37
  $content = http_build_query($data);
38
  $headers = array_merge([
39
  'Content-Type: application/x-www-form-urlencoded',
@@ -62,7 +70,7 @@ class FileGetContentsTidioApiClient implements TidioApiClient
62
  */
63
  public function sendGetRequest($path)
64
  {
65
- $url = Config::getApiUrl() . $path;
66
  $options = [
67
  'http' => [
68
  'method' => 'GET',
@@ -110,19 +118,17 @@ class FileGetContentsTidioApiClient implements TidioApiClient
110
  /**
111
  * @param array<string, mixed> $responseData
112
  * @param string[] $responseHeaders
113
- * @throws TidioApiException
114
  */
115
  private function validateResponse($responseData, $responseHeaders)
116
  {
117
  $statusCode = $this->parseStatusCodeFromHeaders($responseHeaders);
118
  if ($statusCode === 401) {
119
- throw TidioApiException::withUnauthorizedErrorCode();
120
- } elseif ($statusCode < 200 || $statusCode >= 300) {
121
- if (isset($responseData['error'])) {
122
- throw TidioApiException::withErrorCode($responseData['error']);
123
- }
124
 
125
- throw TidioApiException::withUnknownErrorCode();
 
126
  }
127
  }
128
 
1
  <?php
2
 
3
+ namespace TidioLiveChat\Http\Client;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ use TidioLiveChat\Http\Exception\ErrorResponseException;
10
+ use TidioLiveChat\Http\Exception\HttpClientException;
11
+ use TidioLiveChat\Http\Exception\UnauthorizedResponseException;
12
+ use TidioLiveChat\Http\HttpClient;
13
+ use TidioLiveChat\Utils\Url;
14
 
15
+ class FileGetContentsHttpClient implements HttpClient
16
  {
17
+ /**
18
+ * @var string
19
+ */
20
+ private $apiUrl;
21
  /**
22
  * @var string[]
23
  */
24
  private $headers;
25
 
26
  /**
27
+ * @param string $apiUrl
28
  * @param string[] $additionalHeaders
29
  */
30
+ public function __construct($apiUrl, $additionalHeaders = [])
31
  {
32
+ $this->apiUrl = $apiUrl;
33
  $this->headers = array_merge(
34
  ['Accept: application/json'],
35
  $additionalHeaders
41
  */
42
  public function sendPostRequest($path, $data = [])
43
  {
44
+ $url = Url::build($this->apiUrl, $path);
45
  $content = http_build_query($data);
46
  $headers = array_merge([
47
  'Content-Type: application/x-www-form-urlencoded',
70
  */
71
  public function sendGetRequest($path)
72
  {
73
+ $url = Url::build($this->apiUrl, $path);
74
  $options = [
75
  'http' => [
76
  'method' => 'GET',
118
  /**
119
  * @param array<string, mixed> $responseData
120
  * @param string[] $responseHeaders
121
+ * @throws HttpClientException
122
  */
123
  private function validateResponse($responseData, $responseHeaders)
124
  {
125
  $statusCode = $this->parseStatusCodeFromHeaders($responseHeaders);
126
  if ($statusCode === 401) {
127
+ throw new UnauthorizedResponseException();
128
+ }
 
 
 
129
 
130
+ if ($statusCode < 200 || $statusCode >= 300) {
131
+ throw ErrorResponseException::withResponse($statusCode, $responseData);
132
  }
133
  }
134
 
src/Http/Exception/ErrorResponseException.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\Http\Exception;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ class ErrorResponseException extends HttpClientException
10
+ {
11
+ /**
12
+ * @var int
13
+ */
14
+ private $statusCode;
15
+ /**
16
+ * @var array $responseData
17
+ */
18
+ private $responseData;
19
+
20
+ /**
21
+ * @param int $statusCode
22
+ * @param array $responseData
23
+ */
24
+ public function __construct($statusCode, $responseData = [])
25
+ {
26
+ $this->statusCode = $statusCode;
27
+ $this->responseData = $responseData;
28
+ parent::__construct('Http client exception');
29
+ }
30
+
31
+ /**
32
+ * @return int
33
+ */
34
+ public function getStatusCode()
35
+ {
36
+ return $this->statusCode;
37
+ }
38
+
39
+ /**
40
+ * @return array
41
+ */
42
+ public function getResponseData()
43
+ {
44
+ return $this->responseData;
45
+ }
46
+
47
+ /**
48
+ * @param int $statusCode
49
+ * @param array $responseData
50
+ * @return self
51
+ */
52
+ public static function withResponse($statusCode, $responseData)
53
+ {
54
+ return new self($statusCode, $responseData);
55
+ }
56
+ }
src/Http/Exception/HttpClientException.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\Http\Exception;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ abstract class HttpClientException extends \Exception
10
+ {
11
+ }
src/Http/Exception/UnauthorizedResponseException.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\Http\Exception;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ class UnauthorizedResponseException extends HttpClientException
10
+ {
11
+ }
src/{Sdk/Api/TidioApiClient.php → Http/HttpClient.php} RENAMED
@@ -1,27 +1,30 @@
1
  <?php
2
 
3
- namespace TidioLiveChat\Sdk\Api;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
- use TidioLiveChat\Sdk\Api\Exception\TidioApiException;
 
10
 
11
- interface TidioApiClient
12
  {
13
  /**
14
  * @param string $path
15
  * @param array<string, mixed> $data
16
  * @return array<string, mixed>
17
- * @throws TidioApiException
 
18
  */
19
  public function sendPostRequest($path, $data = []);
20
 
21
  /**
22
  * @param string $path
23
  * @return array<string, mixed>
24
- * @throws TidioApiException
 
25
  */
26
  public function sendGetRequest($path);
27
  }
1
  <?php
2
 
3
+ namespace TidioLiveChat\Http;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ use TidioLiveChat\Http\Exception\ErrorResponseException;
10
+ use TidioLiveChat\Http\Exception\UnauthorizedResponseException;
11
 
12
+ interface HttpClient
13
  {
14
  /**
15
  * @param string $path
16
  * @param array<string, mixed> $data
17
  * @return array<string, mixed>
18
+ * @throws UnauthorizedResponseException
19
+ * @throws ErrorResponseException
20
  */
21
  public function sendPostRequest($path, $data = []);
22
 
23
  /**
24
  * @param string $path
25
  * @return array<string, mixed>
26
+ * @throws UnauthorizedResponseException
27
+ * @throws ErrorResponseException
28
  */
29
  public function sendGetRequest($path);
30
  }
src/IntegrationState.php CHANGED
@@ -6,7 +6,8 @@ if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
- use TidioLiveChat\Sdk\Encryption\Service\OpenSslEncryptionService;
 
10
 
11
  class IntegrationState
12
  {
@@ -15,6 +16,8 @@ class IntegrationState
15
  const ASYNC_LOAD_OPTION = 'tidio-async-load';
16
  const TIDIO_OAUTH_ACCESS_TOKEN_KEY = 'tidio-access-token';
17
  const TIDIO_OAUTH_REFRESH_TOKEN_KEY = 'tidio-refresh-token';
 
 
18
 
19
  /**
20
  * @var OpenSslEncryptionService
@@ -50,7 +53,38 @@ class IntegrationState
50
  */
51
  public function hasProjectPrivateKey()
52
  {
53
- return !empty(get_option(self::PRIVATE_KEY_OPTION));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  }
55
 
56
  /**
@@ -58,7 +92,15 @@ class IntegrationState
58
  */
59
  public function isPluginIntegrated()
60
  {
61
- return !empty(get_option(self::PUBLIC_KEY_OPTION));
 
 
 
 
 
 
 
 
62
  }
63
 
64
  /**
@@ -66,17 +108,30 @@ class IntegrationState
66
  */
67
  public function isAsyncLoadingTurnedOn()
68
  {
69
- return (bool) get_option(self::ASYNC_LOAD_OPTION);
70
  }
71
 
72
  public function integrate($projectPublicKey, $accessToken, $refreshToken)
73
  {
74
- $encryptedRefreshToken = $this->encryptionService->encrypt($refreshToken);
75
 
76
  update_option(self::PUBLIC_KEY_OPTION, $projectPublicKey);
 
 
 
 
 
 
 
77
  update_option(self::TIDIO_OAUTH_ACCESS_TOKEN_KEY, $accessToken);
78
  update_option(self::TIDIO_OAUTH_REFRESH_TOKEN_KEY, $encryptedRefreshToken);
79
- update_option(self::ASYNC_LOAD_OPTION, true);
 
 
 
 
 
 
80
  }
81
 
82
  public function removeIntegration()
@@ -84,8 +139,20 @@ class IntegrationState
84
  delete_option(self::PUBLIC_KEY_OPTION);
85
  delete_option(self::TIDIO_OAUTH_ACCESS_TOKEN_KEY);
86
  delete_option(self::TIDIO_OAUTH_REFRESH_TOKEN_KEY);
 
87
  delete_option(self::ASYNC_LOAD_OPTION);
88
  delete_option(self::PRIVATE_KEY_OPTION);
 
 
 
 
 
 
 
 
 
 
 
89
  }
90
 
91
  public function turnOnAsyncLoading()
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ use TidioLiveChat\Encryption\Exception\DecryptionFailedException;
10
+ use TidioLiveChat\Encryption\Service\OpenSslEncryptionService;
11
 
12
  class IntegrationState
13
  {
16
  const ASYNC_LOAD_OPTION = 'tidio-async-load';
17
  const TIDIO_OAUTH_ACCESS_TOKEN_KEY = 'tidio-access-token';
18
  const TIDIO_OAUTH_REFRESH_TOKEN_KEY = 'tidio-refresh-token';
19
+ const TIDIO_ACCESS_TOKENS_VALID_KEY = 'tidio-access-tokens-valid-token';
20
+ const TIDIO_WOOCOMMERCE_INTEGRATED = 'tidio-woocommerce-integrated';
21
 
22
  /**
23
  * @var OpenSslEncryptionService
53
  */
54
  public function hasProjectPrivateKey()
55
  {
56
+ return !empty(get_option(self::PRIVATE_KEY_OPTION, null));
57
+ }
58
+
59
+ /**
60
+ * @return bool
61
+ */
62
+ private function hasAccessTokens()
63
+ {
64
+ return !empty(get_option(self::TIDIO_OAUTH_ACCESS_TOKEN_KEY, null))
65
+ && !empty(get_option(self::TIDIO_OAUTH_REFRESH_TOKEN_KEY, null));
66
+ }
67
+
68
+ /**
69
+ * @return bool
70
+ */
71
+ public function hasValidAccessTokens()
72
+ {
73
+ if (!$this->hasAccessTokens()) {
74
+ return false;
75
+ }
76
+
77
+ return (bool) get_option(self::TIDIO_ACCESS_TOKENS_VALID_KEY, true);
78
+ }
79
+
80
+ /**
81
+ * @return string
82
+ * @throws DecryptionFailedException
83
+ */
84
+ public function getRefreshToken()
85
+ {
86
+ $encryptedRefreshToken = get_option(self::TIDIO_OAUTH_REFRESH_TOKEN_KEY, '');
87
+ return $this->encryptionService->decrypt($encryptedRefreshToken);
88
  }
89
 
90
  /**
92
  */
93
  public function isPluginIntegrated()
94
  {
95
+ return !empty(get_option(self::PUBLIC_KEY_OPTION, null));
96
+ }
97
+
98
+ /**
99
+ * @return bool
100
+ */
101
+ public function isWooCommerceIntegrated()
102
+ {
103
+ return (bool) get_option(self::TIDIO_WOOCOMMERCE_INTEGRATED, false);
104
  }
105
 
106
  /**
108
  */
109
  public function isAsyncLoadingTurnedOn()
110
  {
111
+ return (bool) get_option(self::ASYNC_LOAD_OPTION, true);
112
  }
113
 
114
  public function integrate($projectPublicKey, $accessToken, $refreshToken)
115
  {
116
+ $this->updateAccessTokens($accessToken, $refreshToken);
117
 
118
  update_option(self::PUBLIC_KEY_OPTION, $projectPublicKey);
119
+ update_option(self::ASYNC_LOAD_OPTION, true);
120
+ }
121
+
122
+ public function updateAccessTokens($accessToken, $refreshToken)
123
+ {
124
+ $encryptedRefreshToken = $this->encryptionService->encrypt($refreshToken);
125
+
126
  update_option(self::TIDIO_OAUTH_ACCESS_TOKEN_KEY, $accessToken);
127
  update_option(self::TIDIO_OAUTH_REFRESH_TOKEN_KEY, $encryptedRefreshToken);
128
+
129
+ $this->markAccessTokensAsValid();
130
+ }
131
+
132
+ public function integrateWooCommerce()
133
+ {
134
+ update_option(self::TIDIO_WOOCOMMERCE_INTEGRATED, true);
135
  }
136
 
137
  public function removeIntegration()
139
  delete_option(self::PUBLIC_KEY_OPTION);
140
  delete_option(self::TIDIO_OAUTH_ACCESS_TOKEN_KEY);
141
  delete_option(self::TIDIO_OAUTH_REFRESH_TOKEN_KEY);
142
+ delete_option(self::TIDIO_ACCESS_TOKENS_VALID_KEY);
143
  delete_option(self::ASYNC_LOAD_OPTION);
144
  delete_option(self::PRIVATE_KEY_OPTION);
145
+ delete_option(self::TIDIO_WOOCOMMERCE_INTEGRATED);
146
+ }
147
+
148
+ private function markAccessTokensAsValid()
149
+ {
150
+ update_option(self::TIDIO_ACCESS_TOKENS_VALID_KEY, true);
151
+ }
152
+
153
+ public function markAccessTokensAsInvalid()
154
+ {
155
+ update_option(self::TIDIO_ACCESS_TOKENS_VALID_KEY, false);
156
  }
157
 
158
  public function turnOnAsyncLoading()
src/Sdk/Api/Client/TidioApiClientFactory.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
-
3
- namespace TidioLiveChat\Sdk\Api\Client;
4
-
5
- if (!defined('WPINC')) {
6
- die('File loaded directly. Exiting.');
7
- }
8
-
9
- use TidioLiveChat\Sdk\Api\TidioApiClient;
10
-
11
- class TidioApiClientFactory
12
- {
13
- /**
14
- * @return TidioApiClient
15
- */
16
- public function create()
17
- {
18
- if (function_exists('curl_version')) {
19
- return new CurlTidioApiClient();
20
- }
21
-
22
- return new FileGetContentsTidioApiClient();
23
- }
24
-
25
- /**
26
- * @param string $token
27
- * @return TidioApiClient
28
- */
29
- public function createAuthenticated($token)
30
- {
31
- $authorizationHeader = ['Authorization: Bearer ' . $token];
32
- if (function_exists('curl_version')) {
33
- return new CurlTidioApiClient($authorizationHeader);
34
- }
35
-
36
- return new FileGetContentsTidioApiClient($authorizationHeader);
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Sdk/IntegrationFacade.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
-
3
- namespace TidioLiveChat\Sdk;
4
-
5
- if (!defined('WPINC')) {
6
- die('File loaded directly. Exiting.');
7
- }
8
-
9
- use TidioLiveChat\Sdk\Api\Client\TidioApiClientFactory;
10
- use TidioLiveChat\Sdk\Api\Exception\TidioApiException;
11
-
12
- class IntegrationFacade
13
- {
14
- const TIDIO_WORDPRESS_OAUTH_CLIENT_ID = '8ea883be-28c3-4bfd-9fe2-4091eb38fe08';
15
-
16
- /**
17
- * @var TidioApiClientFactory
18
- */
19
- private $apiClientFactory;
20
-
21
- /**
22
- * @param TidioApiClientFactory $apiClientFactory
23
- */
24
- public function __construct($apiClientFactory)
25
- {
26
- $this->apiClientFactory = $apiClientFactory;
27
- }
28
-
29
- /**
30
- * @param string $refreshToken
31
- * @return array<string, mixed>
32
- * @throws TidioApiException
33
- */
34
- public function integrateProject($refreshToken)
35
- {
36
- $apiClient = $this->apiClientFactory->create();
37
- $tokens = $apiClient->sendPostRequest('/platforms/oauth/access_token', [
38
- 'grant_type' => 'refresh_token',
39
- 'client_id' => self::TIDIO_WORDPRESS_OAUTH_CLIENT_ID,
40
- 'refresh_token' => $refreshToken
41
- ]);
42
-
43
- $apiClient = $this->apiClientFactory->createAuthenticated($tokens['access_token']);
44
- $data = $apiClient->sendPostRequest('/platforms/wordpress/integrate');
45
-
46
- return [
47
- 'projectPublicKey' => $data['projectPublicKey'],
48
- 'accessToken' => $tokens['access_token'],
49
- 'refreshToken' => $tokens['refresh_token']
50
- ];
51
- }
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/TidioLiveChat.php CHANGED
@@ -7,60 +7,53 @@ if (!defined('WPINC')) {
7
  }
8
 
9
  use TidioLiveChat\Admin\AdminActionLink;
10
- use TidioLiveChat\Admin\AdminController;
11
  use TidioLiveChat\Admin\AdminDashboard;
12
  use TidioLiveChat\Admin\AdminNotice;
13
  use TidioLiveChat\Admin\AdminRouting;
14
- use TidioLiveChat\Admin\IframeSetup;
15
- use TidioLiveChat\Admin\NonceValidator;
16
- use TidioLiveChat\Admin\Notice\DismissibleNoticeController;
17
- use TidioLiveChat\Admin\Notice\DismissibleNoticeService;
18
- use TidioLiveChat\Sdk\Api\Client\TidioApiClientFactory;
19
- use TidioLiveChat\Sdk\Encryption\Service\EncryptionServiceFactory;
20
- use TidioLiveChat\Sdk\IntegrationFacade;
21
- use TidioLiveChat\Translation\ErrorTranslator;
22
  use TidioLiveChat\Translation\TranslationLoader;
23
  use TidioLiveChat\Widget\WidgetLoader;
24
 
25
  class TidioLiveChat
26
  {
27
- const TIDIO_PLUGIN_NAME = 'tidio-live-chat';
 
28
 
29
- public static function load()
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  {
31
- $encryptionService = (new EncryptionServiceFactory())->create();
32
- $integrationState = new IntegrationState($encryptionService);
33
  if (!is_admin()) {
34
- new WidgetLoader($integrationState);
 
35
  return;
36
  }
37
 
38
  if (current_user_can('activate_plugins')) {
39
- $nonceValidator = new NonceValidator();
40
- $dismissibleNoticeService = new DismissibleNoticeService();
41
- $dismissibleNoticeController = new DismissibleNoticeController(
42
- $dismissibleNoticeService,
43
- $nonceValidator
44
- );
45
- new TranslationLoader();
46
- $apiClientFactory = new TidioApiClientFactory();
47
- $integrationFacade = new IntegrationFacade($apiClientFactory);
48
- $adminController = new AdminController(
49
- $integrationFacade,
50
- $integrationState,
51
- $nonceValidator,
52
- $dismissibleNoticeService
53
- );
54
- $iframeSetup = new IframeSetup($integrationState);
55
- $errorTranslator = new ErrorTranslator();
56
 
57
- new AdminRouting(
58
- $adminController,
59
- $dismissibleNoticeController
60
- );
61
- new AdminActionLink($integrationState);
62
- new AdminDashboard($integrationState, $iframeSetup);
63
- new AdminNotice($errorTranslator, $dismissibleNoticeService);
64
  }
65
  }
66
  }
7
  }
8
 
9
  use TidioLiveChat\Admin\AdminActionLink;
 
10
  use TidioLiveChat\Admin\AdminDashboard;
11
  use TidioLiveChat\Admin\AdminNotice;
12
  use TidioLiveChat\Admin\AdminRouting;
 
 
 
 
 
 
 
 
13
  use TidioLiveChat\Translation\TranslationLoader;
14
  use TidioLiveChat\Widget\WidgetLoader;
15
 
16
  class TidioLiveChat
17
  {
18
+ const TIDIO_PLUGIN_TECHNICAL_NAME = 'tidio-live-chat';
19
+ const TIDIO_PLUGIN_NAME = 'Tidio Live Chat & Chatbots';
20
 
21
+ /**
22
+ * @var Container
23
+ */
24
+ private $container;
25
+
26
+ /**
27
+ * @param Container $container
28
+ */
29
+ public function __construct($container)
30
+ {
31
+ $this->container = $container;
32
+ }
33
+
34
+ public function load()
35
  {
 
 
36
  if (!is_admin()) {
37
+ $widgetLoader = $this->container->get(WidgetLoader::class);
38
+ $widgetLoader->load();
39
  return;
40
  }
41
 
42
  if (current_user_can('activate_plugins')) {
43
+ $translationLoader = $this->container->get(TranslationLoader::class);
44
+ $translationLoader->load();
45
+
46
+ $adminRouting = $this->container->get(AdminRouting::class);
47
+ $adminRouting->load();
48
+
49
+ $adminActionLink = $this->container->get(AdminActionLink::class);
50
+ $adminActionLink->load();
51
+
52
+ $adminDashboard = $this->container->get(AdminDashboard::class);
53
+ $adminDashboard->load();
 
 
 
 
 
 
54
 
55
+ $adminNotice = $this->container->get(AdminNotice::class);
56
+ $adminNotice->load();
 
 
 
 
 
57
  }
58
  }
59
  }
src/TidioSdk/Dto/ApiCredentialsDto.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\TidioSdk\Dto;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ class ApiCredentialsDto
10
+ {
11
+ /**
12
+ * @var string
13
+ */
14
+ private $accessToken;
15
+ /**
16
+ * @var string
17
+ */
18
+ private $refreshToken;
19
+
20
+ /**
21
+ * @param string $accessToken
22
+ * @param string $refreshToken
23
+ */
24
+ public function __construct($accessToken, $refreshToken)
25
+ {
26
+ $this->accessToken = $accessToken;
27
+ $this->refreshToken = $refreshToken;
28
+ }
29
+
30
+ /**
31
+ * @return string
32
+ */
33
+ public function getAccessToken()
34
+ {
35
+ return $this->accessToken;
36
+ }
37
+
38
+ /**
39
+ * @return string
40
+ */
41
+ public function getRefreshToken()
42
+ {
43
+ return $this->refreshToken;
44
+ }
45
+ }
src/TidioSdk/Exception/AccessTokensAreNotSetException.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\TidioSdk\Exception;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ class AccessTokensAreNotSetException extends \Exception
10
+ {
11
+ }
src/{Sdk/Api/Exception/TidioApiException.php → TidioSdk/Exception/CannotIntegrateWithProjectException.php} RENAMED
@@ -1,38 +1,60 @@
1
  <?php
2
 
3
- namespace TidioLiveChat\Sdk\Api\Exception;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
- class TidioApiException extends \Exception
10
  {
11
  const UNAUTHORIZED_ERROR_CODE = 'unauthorized';
12
  const UNKNOWN_ERROR_CODE = 'unknown_error';
13
 
 
 
 
 
 
14
  /**
15
  * @param string $errorCode
16
- * @return TidioApiException
17
  */
18
- public static function withErrorCode($errorCode)
19
  {
20
- return new self($errorCode);
 
21
  }
22
 
23
  /**
24
- * @return TidioApiException
25
  */
26
- public static function withUnauthorizedErrorCode()
27
  {
28
- return new self(self::UNAUTHORIZED_ERROR_CODE);
 
 
 
 
 
 
 
 
 
29
  }
30
 
31
  /**
32
- * @return TidioApiException
33
  */
34
  public static function withUnknownErrorCode()
35
  {
36
  return new self(self::UNKNOWN_ERROR_CODE);
37
  }
 
 
 
 
 
 
 
 
38
  }
1
  <?php
2
 
3
+ namespace TidioLiveChat\TidioSdk\Exception;
4
 
5
  if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ class CannotIntegrateWithProjectException extends \Exception
10
  {
11
  const UNAUTHORIZED_ERROR_CODE = 'unauthorized';
12
  const UNKNOWN_ERROR_CODE = 'unknown_error';
13
 
14
+ /**
15
+ * @var string
16
+ */
17
+ private $errorCode;
18
+
19
  /**
20
  * @param string $errorCode
 
21
  */
22
+ public function __construct($errorCode)
23
  {
24
+ $this->errorCode = $errorCode;
25
+ parent::__construct('Cannot integrate with project.');
26
  }
27
 
28
  /**
29
+ * @return string
30
  */
31
+ public function getErrorCode()
32
  {
33
+ return $this->errorCode;
34
+ }
35
+
36
+ /**
37
+ * @param string $errorCode
38
+ * @return self
39
+ */
40
+ public static function withErrorCode($errorCode)
41
+ {
42
+ return new self($errorCode);
43
  }
44
 
45
  /**
46
+ * @return self
47
  */
48
  public static function withUnknownErrorCode()
49
  {
50
  return new self(self::UNKNOWN_ERROR_CODE);
51
  }
52
+
53
+ /**
54
+ * @return self
55
+ */
56
+ public static function withUnauthorizedErrorCode()
57
+ {
58
+ return new self(self::UNAUTHORIZED_ERROR_CODE);
59
+ }
60
  }
src/TidioSdk/Exception/CannotRetrieveAccessTokensException.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\TidioSdk\Exception;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ class CannotRetrieveAccessTokensException extends \Exception
10
+ {
11
+ const ACCESS_TOKENS_NOT_SET_ERROR_CODE = 'access_tokens_not_set';
12
+ const DECRYPTION_FAILED_ERROR_CODE = 'decryption_failed';
13
+ const INVALID_ACCESS_TOKENS_ERROR_CODE = 'invalid_access_tokens';
14
+ const INVALID_RESPONSE_ERROR_CODE = 'invalid_response_code';
15
+ const UNKNOWN_ERROR_CODE = 'access_tokens_unknown_error';
16
+
17
+ /**
18
+ * @var string
19
+ */
20
+ private $errorCode;
21
+
22
+ /**
23
+ * @param string $errorCode
24
+ */
25
+ public function __construct($errorCode)
26
+ {
27
+ $this->errorCode = $errorCode;
28
+ parent::__construct('Cannot retrieve access tokens.');
29
+ }
30
+
31
+ /**
32
+ * @return string
33
+ */
34
+ public function getErrorCode()
35
+ {
36
+ return $this->errorCode;
37
+ }
38
+
39
+ /**
40
+ * @return self
41
+ */
42
+ public static function withAccessTokensNotSetErrorCode()
43
+ {
44
+ return new self(self::ACCESS_TOKENS_NOT_SET_ERROR_CODE);
45
+ }
46
+
47
+ /**
48
+ * @return self
49
+ */
50
+ public static function withDecryptionFailedErrorCode()
51
+ {
52
+ return new self(self::DECRYPTION_FAILED_ERROR_CODE);
53
+ }
54
+
55
+ /**
56
+ * @return self
57
+ */
58
+ public static function withInvalidAccessTokensErrorCode()
59
+ {
60
+ return new self(self::INVALID_ACCESS_TOKENS_ERROR_CODE);
61
+ }
62
+
63
+ /**
64
+ * @param int $statusCode
65
+ * @return self
66
+ */
67
+ public static function withInvalidResponseErrorCode($statusCode)
68
+ {
69
+ $errorCode = sprintf('%s_%d', self::INVALID_RESPONSE_ERROR_CODE, $statusCode);
70
+ return new self($errorCode);
71
+ }
72
+
73
+ /**
74
+ * @return self
75
+ */
76
+ public static function withUnknownErrorCode()
77
+ {
78
+ return new self(self::UNKNOWN_ERROR_CODE);
79
+ }
80
+ }
src/TidioSdk/TidioApiClientFactory.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\TidioSdk;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ use TidioLiveChat\Config;
10
+ use TidioLiveChat\Http\Client\CurlHttpClient;
11
+ use TidioLiveChat\Http\Client\FileGetContentsHttpClient;
12
+ use TidioLiveChat\Http\HttpClient;
13
+
14
+ class TidioApiClientFactory
15
+ {
16
+ /**
17
+ * @return HttpClient
18
+ */
19
+ public function create()
20
+ {
21
+ $apiUrl = Config::getApiUrl();
22
+ if (function_exists('curl_version')) {
23
+ return new CurlHttpClient($apiUrl);
24
+ }
25
+
26
+ return new FileGetContentsHttpClient($apiUrl);
27
+ }
28
+
29
+ /**
30
+ * @param string $token
31
+ * @return HttpClient
32
+ */
33
+ public function createAuthenticated($token)
34
+ {
35
+ $apiUrl = Config::getApiUrl();
36
+ $authorizationHeader = ['Authorization: Bearer ' . $token];
37
+ if (function_exists('curl_version')) {
38
+ return new CurlHttpClient($apiUrl, $authorizationHeader);
39
+ }
40
+
41
+ return new FileGetContentsHttpClient($apiUrl, $authorizationHeader);
42
+ }
43
+ }
src/TidioSdk/TidioIntegrationService.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\TidioSdk;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ use TidioLiveChat\Encryption\Exception\DecryptionFailedException;
10
+ use TidioLiveChat\Http\Exception\HttpClientException;
11
+ use TidioLiveChat\Http\Exception\UnauthorizedResponseException;
12
+ use TidioLiveChat\IntegrationState;
13
+ use TidioLiveChat\Http\Exception\ErrorResponseException;
14
+ use TidioLiveChat\TidioSdk\Dto\ApiCredentialsDto;
15
+ use TidioLiveChat\TidioSdk\Exception\CannotIntegrateWithProjectException;
16
+ use TidioLiveChat\TidioSdk\Exception\CannotRetrieveAccessTokensException;
17
+
18
+ class TidioIntegrationService
19
+ {
20
+ const TIDIO_WORDPRESS_OAUTH_CLIENT_ID = '8ea883be-28c3-4bfd-9fe2-4091eb38fe08';
21
+
22
+ /**
23
+ * @var IntegrationState
24
+ */
25
+ private $integrationState;
26
+ /**
27
+ * @var TidioApiClientFactory
28
+ */
29
+ private $apiClientFactory;
30
+
31
+ /**
32
+ * @param IntegrationState $integrationState
33
+ * @param TidioApiClientFactory $apiClientFactory
34
+ */
35
+ public function __construct($integrationState, $apiClientFactory)
36
+ {
37
+ $this->integrationState = $integrationState;
38
+ $this->apiClientFactory = $apiClientFactory;
39
+ }
40
+
41
+ /**
42
+ * @param string $refreshToken
43
+ * @throws CannotIntegrateWithProjectException
44
+ */
45
+ public function integrateProject($refreshToken)
46
+ {
47
+ try {
48
+ $apiCredentials = $this->getAccessTokens($refreshToken);
49
+ $apiClient = $this->apiClientFactory->createAuthenticated($apiCredentials->getAccessToken());
50
+ $data = $apiClient->sendPostRequest('/platforms/wordpress/integrate');
51
+ } catch (UnauthorizedResponseException $exception) {
52
+ throw CannotIntegrateWithProjectException::withUnauthorizedErrorCode();
53
+ } catch (ErrorResponseException $exception) {
54
+ if (isset($exception->getResponseData()['error'])) {
55
+ throw CannotIntegrateWithProjectException::withErrorCode($exception->getResponseData()['error']);
56
+ }
57
+
58
+ throw CannotIntegrateWithProjectException::withUnknownErrorCode();
59
+ }
60
+
61
+ $this->integrationState->integrate(
62
+ $data['projectPublicKey'],
63
+ $apiCredentials->getAccessToken(),
64
+ $apiCredentials->getRefreshToken()
65
+ );
66
+ }
67
+
68
+ /**
69
+ * @return ApiCredentialsDto
70
+ * @throws CannotRetrieveAccessTokensException
71
+ */
72
+ public function retrieveAccessTokens()
73
+ {
74
+ if (!$this->integrationState->hasValidAccessTokens()) {
75
+ throw CannotRetrieveAccessTokensException::withAccessTokensNotSetErrorCode();
76
+ }
77
+
78
+ try {
79
+ $refreshToken = $this->integrationState->getRefreshToken();
80
+ } catch (DecryptionFailedException $exception) {
81
+ $this->integrationState->markAccessTokensAsInvalid();
82
+
83
+ throw CannotRetrieveAccessTokensException::withDecryptionFailedErrorCode();
84
+ }
85
+
86
+ try {
87
+ $apiCredentials = $this->getAccessTokens($refreshToken);
88
+ } catch (UnauthorizedResponseException $exception) {
89
+ $this->integrationState->markAccessTokensAsInvalid();
90
+
91
+ throw CannotRetrieveAccessTokensException::withInvalidAccessTokensErrorCode();
92
+ } catch (ErrorResponseException $exception) {
93
+ throw CannotRetrieveAccessTokensException::withInvalidResponseErrorCode($exception->getStatusCode());
94
+ } catch (\Exception $exception) {
95
+ throw CannotRetrieveAccessTokensException::withUnknownErrorCode();
96
+ }
97
+
98
+ $this->integrationState->updateAccessTokens($apiCredentials->getAccessToken(), $apiCredentials->getRefreshToken());
99
+
100
+ return $apiCredentials;
101
+ }
102
+
103
+ /**
104
+ * @param string $refreshToken
105
+ * @return ApiCredentialsDto
106
+ * @throws UnauthorizedResponseException
107
+ * @throws ErrorResponseException
108
+ */
109
+ private function getAccessTokens($refreshToken)
110
+ {
111
+ $apiClient = $this->apiClientFactory->create();
112
+ $tokens = $apiClient->sendPostRequest('/platforms/oauth/access_token', [
113
+ 'grant_type' => 'refresh_token',
114
+ 'client_id' => self::TIDIO_WORDPRESS_OAUTH_CLIENT_ID,
115
+ 'refresh_token' => $refreshToken
116
+ ]);
117
+
118
+ return new ApiCredentialsDto(
119
+ $tokens['access_token'],
120
+ $tokens['refresh_token']
121
+ );
122
+ }
123
+ }
src/Translation/I18n.php CHANGED
@@ -15,7 +15,7 @@ class I18n
15
  */
16
  public static function _e($message)
17
  {
18
- _e($message, TidioLiveChat::TIDIO_PLUGIN_NAME);
19
  }
20
 
21
  /**
@@ -23,6 +23,6 @@ class I18n
23
  */
24
  public static function _t($message)
25
  {
26
- return __($message, TidioLiveChat::TIDIO_PLUGIN_NAME);
27
  }
28
  }
15
  */
16
  public static function _e($message)
17
  {
18
+ _e($message, TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME);
19
  }
20
 
21
  /**
23
  */
24
  public static function _t($message)
25
  {
26
+ return __($message, TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME);
27
  }
28
  }
src/Translation/TranslationLoader.php CHANGED
@@ -10,10 +10,10 @@ use TidioLiveChat\TidioLiveChat;
10
 
11
  class TranslationLoader
12
  {
13
- public function __construct()
14
  {
15
  add_filter('load_textdomain_mofile', [$this, 'loadTextDomain'], 10, 2);
16
- load_plugin_textdomain(TidioLiveChat::TIDIO_PLUGIN_NAME);
17
  }
18
 
19
  /**
@@ -23,7 +23,7 @@ class TranslationLoader
23
  */
24
  public function loadTextDomain($mofile, $domain)
25
  {
26
- if (TidioLiveChat::TIDIO_PLUGIN_NAME === $domain && false !== strpos($mofile, WP_LANG_DIR . '/plugins/')) {
27
  $userId = get_current_user_id();
28
  $userLocaleCode = get_user_locale($userId);
29
 
10
 
11
  class TranslationLoader
12
  {
13
+ public function load()
14
  {
15
  add_filter('load_textdomain_mofile', [$this, 'loadTextDomain'], 10, 2);
16
+ load_plugin_textdomain(TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME);
17
  }
18
 
19
  /**
23
  */
24
  public function loadTextDomain($mofile, $domain)
25
  {
26
+ if (TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME === $domain && false !== strpos($mofile, WP_LANG_DIR . '/plugins/')) {
27
  $userId = get_current_user_id();
28
  $userLocaleCode = get_user_locale($userId);
29
 
src/Utils/Url.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\Utils;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ class Url
10
+ {
11
+ /**
12
+ * @param string $url
13
+ * @param string $path
14
+ * @return string
15
+ */
16
+ public static function build($url, $path)
17
+ {
18
+ return sprintf(
19
+ '%s/%s',
20
+ rtrim($url, '/'),
21
+ ltrim($path, '/')
22
+ );
23
+ }
24
+ }
src/Widget/WidgetLoader.php CHANGED
@@ -23,7 +23,10 @@ class WidgetLoader
23
  public function __construct($integrationState)
24
  {
25
  $this->integrationState = $integrationState;
 
26
 
 
 
27
  if (!$this->integrationState->isPluginIntegrated()) {
28
  return;
29
  }
@@ -37,7 +40,8 @@ class WidgetLoader
37
  add_action('wp_enqueue_scripts', [$this, 'enqueueScriptsSync'], 1000);
38
  }
39
 
40
- public function addPreconnectLink() {
 
41
  echo '<link rel="preconnect" href="//code.tidio.co">';
42
  }
43
 
@@ -72,9 +76,9 @@ SRC;
72
  $projectPublicKey = $this->integrationState->getProjectPublicKey();
73
 
74
  $widgetUrl = sprintf('%s/%s.js', Config::getWidgetUrl(), $projectPublicKey);
75
- wp_enqueue_script(TidioLiveChat::TIDIO_PLUGIN_NAME, $widgetUrl, [], TIDIOCHAT_VERSION, true);
76
 
77
  $inlineScriptWithProjectPublicKeyVariable = sprintf('document.tidioChatCode = "%s";', $projectPublicKey);
78
- wp_add_inline_script(TidioLiveChat::TIDIO_PLUGIN_NAME, $inlineScriptWithProjectPublicKeyVariable, 'before');
79
  }
80
  }
23
  public function __construct($integrationState)
24
  {
25
  $this->integrationState = $integrationState;
26
+ }
27
 
28
+ public function load()
29
+ {
30
  if (!$this->integrationState->isPluginIntegrated()) {
31
  return;
32
  }
40
  add_action('wp_enqueue_scripts', [$this, 'enqueueScriptsSync'], 1000);
41
  }
42
 
43
+ public function addPreconnectLink()
44
+ {
45
  echo '<link rel="preconnect" href="//code.tidio.co">';
46
  }
47
 
76
  $projectPublicKey = $this->integrationState->getProjectPublicKey();
77
 
78
  $widgetUrl = sprintf('%s/%s.js', Config::getWidgetUrl(), $projectPublicKey);
79
+ wp_enqueue_script(TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME, $widgetUrl, [], TIDIOCHAT_VERSION, true);
80
 
81
  $inlineScriptWithProjectPublicKeyVariable = sprintf('document.tidioChatCode = "%s";', $projectPublicKey);
82
+ wp_add_inline_script(TidioLiveChat::TIDIO_PLUGIN_TECHNICAL_NAME, $inlineScriptWithProjectPublicKeyVariable, 'before');
83
  }
84
  }
src/WooCommerceSdk/Dto/WooCommerceIntegrationDto.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\WooCommerceSdk\Dto;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ class WooCommerceIntegrationDto
10
+ {
11
+ const WOOCOMMERCE_INTEGRATION_STATUS_INACTIVE = 'inactive';
12
+ const WOOCOMMERCE_INTEGRATION_STATUS_DISABLED = 'disabled';
13
+ const WOOCOMMERCE_INTEGRATION_STATUS_ACTIVE = 'active';
14
+ const WOOCOMMERCE_INTEGRATION_STATUS_INTEGRATED = 'integrated';
15
+
16
+ /**
17
+ * @var string
18
+ */
19
+ private $status;
20
+ /**
21
+ * @var string[]
22
+ */
23
+ private $notMetConditions;
24
+ /**
25
+ * @var string|null
26
+ */
27
+ private $authUrl;
28
+
29
+ /**
30
+ * @param string $status
31
+ * @param string[] $notMetConditions
32
+ * @param string|null $authUrl
33
+ */
34
+ private function __construct($status, $notMetConditions = [], $authUrl = null)
35
+ {
36
+ $this->status = $status;
37
+ $this->notMetConditions = $notMetConditions;
38
+ $this->authUrl = $authUrl;
39
+ }
40
+
41
+ /**
42
+ * @return self
43
+ */
44
+ public static function createInactive()
45
+ {
46
+ return new self(self::WOOCOMMERCE_INTEGRATION_STATUS_INACTIVE);
47
+ }
48
+
49
+ /**
50
+ * @param string[] $notMetConditions
51
+ * @return self
52
+ */
53
+ public static function createDisabled($notMetConditions)
54
+ {
55
+ return new self(self::WOOCOMMERCE_INTEGRATION_STATUS_DISABLED, $notMetConditions);
56
+ }
57
+
58
+ /**
59
+ * @param string $authUrl
60
+ * @return self
61
+ */
62
+ public static function createActive($authUrl)
63
+ {
64
+ return new self(self::WOOCOMMERCE_INTEGRATION_STATUS_ACTIVE, [], $authUrl);
65
+ }
66
+
67
+ /**
68
+ * @param string $authUrl
69
+ * @return self
70
+ */
71
+ public static function createIntegrated($authUrl)
72
+ {
73
+ return new self(self::WOOCOMMERCE_INTEGRATION_STATUS_INTEGRATED, [], $authUrl);
74
+ }
75
+
76
+ /**
77
+ * @return array<string, string>
78
+ */
79
+ public function toIframeData()
80
+ {
81
+ $iframeData = ['wooCommerceIntegrationStatus' => $this->status];
82
+
83
+ if ($this->status === self::WOOCOMMERCE_INTEGRATION_STATUS_INACTIVE) {
84
+ return $iframeData;
85
+ }
86
+
87
+ if ($this->status === self::WOOCOMMERCE_INTEGRATION_STATUS_DISABLED) {
88
+ $iframeData['wooCommerceNotMetConditions'] = implode(',', $this->notMetConditions);
89
+ return $iframeData;
90
+ }
91
+
92
+ $iframeData['wooCommerceAuthUrl'] = $this->authUrl;
93
+ return $iframeData;
94
+ }
95
+ }
src/WooCommerceSdk/WooCommerceApiV3ClientFactory.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\WooCommerceSdk;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ use TidioLiveChat\Http\Client\CurlHttpClient;
10
+ use TidioLiveChat\Http\Client\FileGetContentsHttpClient;
11
+ use TidioLiveChat\Http\HttpClient;
12
+
13
+ class WooCommerceApiV3ClientFactory
14
+ {
15
+ /**
16
+ * @return HttpClient
17
+ */
18
+ public function create()
19
+ {
20
+ $apiUrl = get_rest_url(null, 'wc/v3');
21
+ if (function_exists('curl_version')) {
22
+ return new CurlHttpClient($apiUrl);
23
+ }
24
+
25
+ return new FileGetContentsHttpClient($apiUrl);
26
+ }
27
+ }
src/WooCommerceSdk/WooCommerceIntegrationService.php ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\WooCommerceSdk;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ use TidioLiveChat\Admin\AdminRouting;
10
+ use TidioLiveChat\Config;
11
+ use TidioLiveChat\Http\Exception\HttpClientException;
12
+ use TidioLiveChat\IntegrationState;
13
+ use TidioLiveChat\TidioSdk\Exception\CannotRetrieveAccessTokensException;
14
+ use TidioLiveChat\TidioSdk\TidioIntegrationService;
15
+ use TidioLiveChat\TidioLiveChat;
16
+ use TidioLiveChat\WooCommerceSdk\Dto\WooCommerceIntegrationDto;
17
+
18
+ class WooCommerceIntegrationService
19
+ {
20
+ const MINIMUM_REQUIRED_WOOCOMMERCE_VERSION = '3.4';
21
+
22
+ /**
23
+ * @var IntegrationState
24
+ */
25
+ private $integrationState;
26
+ /**
27
+ * @var WooCommerceApiV3ClientFactory
28
+ */
29
+ private $wooCommerceApiClientFactory;
30
+ /**
31
+ * @var TidioIntegrationService
32
+ */
33
+ private $tidioIntegrationService;
34
+
35
+ /**
36
+ * @param IntegrationState $integrationState
37
+ * @param WooCommerceApiV3ClientFactory $wooCommerceApiClientFactory
38
+ * @param TidioIntegrationService $tidioIntegrationService
39
+ */
40
+ public function __construct($integrationState, $wooCommerceApiClientFactory, $tidioIntegrationService)
41
+ {
42
+ $this->integrationState = $integrationState;
43
+ $this->wooCommerceApiClientFactory = $wooCommerceApiClientFactory;
44
+ $this->tidioIntegrationService = $tidioIntegrationService;
45
+ }
46
+
47
+ /**
48
+ * @return string
49
+ * @throws CannotRetrieveAccessTokensException
50
+ */
51
+ public function getAuthUrl()
52
+ {
53
+ $apiCredentials = $this->tidioIntegrationService->retrieveAccessTokens();
54
+ $callbackUrl = sprintf(
55
+ '%s/platforms/woocommerce/callback?api_url=%s&platformAuthorizationToken=%s',
56
+ Config::getApiUrl(),
57
+ get_rest_url(),
58
+ $apiCredentials->getAccessToken()
59
+ );
60
+
61
+ return sprintf(
62
+ '%s/wc-auth/v1/authorize?%s',
63
+ get_home_url(),
64
+ http_build_query([
65
+ 'app_name' => TidioLiveChat::TIDIO_PLUGIN_NAME,
66
+ 'scope' => 'read',
67
+ 'user_id' => $this->integrationState->getProjectPublicKey(),
68
+ 'return_url' => AdminRouting::getEndpointForIntegrateWooCommerceAction(),
69
+ 'callback_url' => $callbackUrl
70
+ ])
71
+ );
72
+ }
73
+
74
+ /**
75
+ * @return WooCommerceIntegrationDto
76
+ */
77
+ public function getIntegrationData()
78
+ {
79
+ if (!$this->isWooCommerceActivated()) {
80
+ return WooCommerceIntegrationDto::createInactive();
81
+ }
82
+
83
+ $notMetConditions = $this->getNotMetConditions();
84
+ if (!empty($notMetConditions)) {
85
+ return WooCommerceIntegrationDto::createDisabled($notMetConditions);
86
+ }
87
+
88
+ $authUrl = AdminRouting::getEndpointForAuthorizeWooCommerceAction();
89
+ if ($this->integrationState->isWooCommerceIntegrated()) {
90
+ return WooCommerceIntegrationDto::createIntegrated($authUrl);
91
+ }
92
+
93
+ return WooCommerceIntegrationDto::createActive($authUrl);
94
+ }
95
+
96
+ /**
97
+ * @return bool
98
+ */
99
+ public function isWooCommerceActivated()
100
+ {
101
+ return class_exists('woocommerce');
102
+ }
103
+
104
+ /**
105
+ * @return string[]
106
+ */
107
+ private function getNotMetConditions()
108
+ {
109
+ $conditionsNotMet = [];
110
+ if (!$this->integrationState->hasValidAccessTokens()) {
111
+ $conditionsNotMet[] = 'token';
112
+ }
113
+
114
+ if (!$this->hasEnabledPermalink()) {
115
+ $conditionsNotMet[] = 'permalinks';
116
+ }
117
+
118
+ if (!$this->isWooCommerceMinimumVersionInstalled()) {
119
+ $conditionsNotMet[] = 'version';
120
+ }
121
+
122
+ if (!$this->isRestApiEnabled()) {
123
+ $conditionsNotMet[] = 'rest';
124
+ }
125
+
126
+ return $conditionsNotMet;
127
+ }
128
+
129
+ /**
130
+ * @return bool
131
+ */
132
+ private function hasEnabledPermalink()
133
+ {
134
+ return !empty(get_option('permalink_structure'));
135
+ }
136
+
137
+ /**
138
+ * @return bool
139
+ */
140
+ private function isWooCommerceMinimumVersionInstalled()
141
+ {
142
+ return (bool) version_compare($this->getWooCommerceVersion(), self::MINIMUM_REQUIRED_WOOCOMMERCE_VERSION, '>=');
143
+ }
144
+
145
+ /**
146
+ * @return string
147
+ */
148
+ private function getWooCommerceVersion()
149
+ {
150
+ if (defined('WC_VERSION')) {
151
+ return WC_VERSION;
152
+ }
153
+
154
+ return '0';
155
+ }
156
+
157
+ /**
158
+ * @return bool
159
+ */
160
+ private function isRestApiEnabled()
161
+ {
162
+ $apiClient = $this->wooCommerceApiClientFactory->create();
163
+ try {
164
+ $response = $apiClient->sendGetRequest('/');
165
+ } catch (HttpClientException $exception) {
166
+ return false;
167
+ }
168
+
169
+ return isset($response['namespace']) &&
170
+ $response['namespace'] === 'wc/v3';
171
+ }
172
+ }
tidio-elements.php CHANGED
@@ -8,7 +8,7 @@ if (!defined('WPINC')) {
8
  * Plugin Name: Tidio Chat
9
  * Plugin URI: http://www.tidio.com
10
  * Description: Tidio Live Chat - live chat boosted with chatbots for your online business. Integrates with your website in less than 20 seconds.
11
- * Version: 5.4.3
12
  * Author: Tidio Ltd.
13
  * Author URI: http://www.tidio.com
14
  * Text Domain: tidio-live-chat
@@ -16,12 +16,12 @@ if (!defined('WPINC')) {
16
  * License: GPL2
17
  */
18
 
19
- define('TIDIOCHAT_VERSION', '5.4.3');
20
  define('AFFILIATE_CONFIG_FILE_PATH', get_template_directory() . '/tidio_affiliate_ref_id.txt');
21
 
22
  require_once plugin_dir_path(__FILE__) . 'vendor/autoload.php';
23
 
24
- use TidioLiveChat\Sdk\Encryption\Service\EncryptionServiceFactory;
25
  use TidioLiveChat\IntegrationState;
26
  use TidioLiveChat\TidioLiveChat;
27
 
@@ -32,7 +32,9 @@ function initializeTidioLiveChat()
32
  exit;
33
  }
34
 
35
- TidioLiveChat::load();
 
 
36
  }
37
 
38
  add_action('init', 'initializeTidioLiveChat');
8
  * Plugin Name: Tidio Chat
9
  * Plugin URI: http://www.tidio.com
10
  * Description: Tidio Live Chat - live chat boosted with chatbots for your online business. Integrates with your website in less than 20 seconds.
11
+ * Version: 6.0.0
12
  * Author: Tidio Ltd.
13
  * Author URI: http://www.tidio.com
14
  * Text Domain: tidio-live-chat
16
  * License: GPL2
17
  */
18
 
19
+ define('TIDIOCHAT_VERSION', '6.0.0');
20
  define('AFFILIATE_CONFIG_FILE_PATH', get_template_directory() . '/tidio_affiliate_ref_id.txt');
21
 
22
  require_once plugin_dir_path(__FILE__) . 'vendor/autoload.php';
23
 
24
+ use TidioLiveChat\Encryption\Service\EncryptionServiceFactory;
25
  use TidioLiveChat\IntegrationState;
26
  use TidioLiveChat\TidioLiveChat;
27
 
32
  exit;
33
  }
34
 
35
+ $container = new \TidioLiveChat\Container();
36
+ $tidioLiveChat = new TidioLiveChat($container);
37
+ $tidioLiveChat->load();
38
  }
39
 
40
  add_action('init', 'initializeTidioLiveChat');
vendor/composer/InstalledVersions.php CHANGED
@@ -30,7 +30,7 @@ private static $installed = array (
30
  'aliases' =>
31
  array (
32
  ),
33
- 'reference' => '0b929f9fdb17b6dc185478aacd9a025bfba5a30d',
34
  'name' => '__root__',
35
  ),
36
  'versions' =>
@@ -42,7 +42,7 @@ private static $installed = array (
42
  'aliases' =>
43
  array (
44
  ),
45
- 'reference' => '0b929f9fdb17b6dc185478aacd9a025bfba5a30d',
46
  ),
47
  ),
48
  );
30
  'aliases' =>
31
  array (
32
  ),
33
+ 'reference' => 'cb906195547d91fdafebf29181d5c01ea93ef591',
34
  'name' => '__root__',
35
  ),
36
  'versions' =>
42
  'aliases' =>
43
  array (
44
  ),
45
+ 'reference' => 'cb906195547d91fdafebf29181d5c01ea93ef591',
46
  ),
47
  ),
48
  );
vendor/composer/autoload_classmap.php CHANGED
@@ -18,22 +18,33 @@ return array(
18
  'TidioLiveChat\\Admin\\Notice\\DismissibleNoticeService' => $baseDir . '/src/Admin/Notice/DismissibleNoticeService.php',
19
  'TidioLiveChat\\Admin\\Notice\\Exception\\NoticeNameIsNotAllowedException' => $baseDir . '/src/Admin/Notice/Exception/NoticeNameIsNotAllowedException.php',
20
  'TidioLiveChat\\Config' => $baseDir . '/src/Config.php',
 
 
 
 
 
 
 
 
 
 
 
 
21
  'TidioLiveChat\\IntegrationState' => $baseDir . '/src/IntegrationState.php',
22
- 'TidioLiveChat\\Sdk\\Api\\Client\\CurlTidioApiClient' => $baseDir . '/src/Sdk/Api/Client/CurlTidioApiClient.php',
23
- 'TidioLiveChat\\Sdk\\Api\\Client\\FileGetContentsTidioApiClient' => $baseDir . '/src/Sdk/Api/Client/FileGetContentsTidioApiClient.php',
24
- 'TidioLiveChat\\Sdk\\Api\\Client\\TidioApiClientFactory' => $baseDir . '/src/Sdk/Api/Client/TidioApiClientFactory.php',
25
- 'TidioLiveChat\\Sdk\\Api\\Exception\\TidioApiException' => $baseDir . '/src/Sdk/Api/Exception/TidioApiException.php',
26
- 'TidioLiveChat\\Sdk\\Api\\TidioApiClient' => $baseDir . '/src/Sdk/Api/TidioApiClient.php',
27
- 'TidioLiveChat\\Sdk\\Encryption\\EncryptionService' => $baseDir . '/src/Sdk/Encryption/EncryptionService.php',
28
- 'TidioLiveChat\\Sdk\\Encryption\\Exception\\DecryptionFailedException' => $baseDir . '/src/Sdk/Encryption/Exception/DecryptionFailedException.php',
29
- 'TidioLiveChat\\Sdk\\Encryption\\Service\\EncryptionServiceFactory' => $baseDir . '/src/Sdk/Encryption/Service/EncryptionServiceFactory.php',
30
- 'TidioLiveChat\\Sdk\\Encryption\\Service\\OpenSslEncryptionService' => $baseDir . '/src/Sdk/Encryption/Service/OpenSslEncryptionService.php',
31
- 'TidioLiveChat\\Sdk\\Encryption\\Service\\PlainTextEncryptionService' => $baseDir . '/src/Sdk/Encryption/Service/PlainTextEncryptionService.php',
32
- 'TidioLiveChat\\Sdk\\IntegrationFacade' => $baseDir . '/src/Sdk/IntegrationFacade.php',
33
  'TidioLiveChat\\TidioLiveChat' => $baseDir . '/src/TidioLiveChat.php',
 
 
 
 
 
 
34
  'TidioLiveChat\\Translation\\ErrorTranslator' => $baseDir . '/src/Translation/ErrorTranslator.php',
35
  'TidioLiveChat\\Translation\\I18n' => $baseDir . '/src/Translation/I18n.php',
36
  'TidioLiveChat\\Translation\\TranslationLoader' => $baseDir . '/src/Translation/TranslationLoader.php',
37
  'TidioLiveChat\\Utils\\QueryParameters' => $baseDir . '/src/Utils/QueryParameters.php',
 
38
  'TidioLiveChat\\Widget\\WidgetLoader' => $baseDir . '/src/Widget/WidgetLoader.php',
 
 
 
39
  );
18
  'TidioLiveChat\\Admin\\Notice\\DismissibleNoticeService' => $baseDir . '/src/Admin/Notice/DismissibleNoticeService.php',
19
  'TidioLiveChat\\Admin\\Notice\\Exception\\NoticeNameIsNotAllowedException' => $baseDir . '/src/Admin/Notice/Exception/NoticeNameIsNotAllowedException.php',
20
  'TidioLiveChat\\Config' => $baseDir . '/src/Config.php',
21
+ 'TidioLiveChat\\Container' => $baseDir . '/src/Container.php',
22
+ 'TidioLiveChat\\Encryption\\EncryptionService' => $baseDir . '/src/Encryption/EncryptionService.php',
23
+ 'TidioLiveChat\\Encryption\\Exception\\DecryptionFailedException' => $baseDir . '/src/Encryption/Exception/DecryptionFailedException.php',
24
+ 'TidioLiveChat\\Encryption\\Service\\EncryptionServiceFactory' => $baseDir . '/src/Encryption/Service/EncryptionServiceFactory.php',
25
+ 'TidioLiveChat\\Encryption\\Service\\OpenSslEncryptionService' => $baseDir . '/src/Encryption/Service/OpenSslEncryptionService.php',
26
+ 'TidioLiveChat\\Encryption\\Service\\PlainTextEncryptionService' => $baseDir . '/src/Encryption/Service/PlainTextEncryptionService.php',
27
+ 'TidioLiveChat\\Http\\Client\\CurlHttpClient' => $baseDir . '/src/Http/Client/CurlHttpClient.php',
28
+ 'TidioLiveChat\\Http\\Client\\FileGetContentsHttpClient' => $baseDir . '/src/Http/Client/FileGetContentsHttpClient.php',
29
+ 'TidioLiveChat\\Http\\Exception\\ErrorResponseException' => $baseDir . '/src/Http/Exception/ErrorResponseException.php',
30
+ 'TidioLiveChat\\Http\\Exception\\HttpClientException' => $baseDir . '/src/Http/Exception/HttpClientException.php',
31
+ 'TidioLiveChat\\Http\\Exception\\UnauthorizedResponseException' => $baseDir . '/src/Http/Exception/UnauthorizedResponseException.php',
32
+ 'TidioLiveChat\\Http\\HttpClient' => $baseDir . '/src/Http/HttpClient.php',
33
  'TidioLiveChat\\IntegrationState' => $baseDir . '/src/IntegrationState.php',
 
 
 
 
 
 
 
 
 
 
 
34
  'TidioLiveChat\\TidioLiveChat' => $baseDir . '/src/TidioLiveChat.php',
35
+ 'TidioLiveChat\\TidioSdk\\Dto\\ApiCredentialsDto' => $baseDir . '/src/TidioSdk/Dto/ApiCredentialsDto.php',
36
+ 'TidioLiveChat\\TidioSdk\\Exception\\AccessTokensAreNotSetException' => $baseDir . '/src/TidioSdk/Exception/AccessTokensAreNotSetException.php',
37
+ 'TidioLiveChat\\TidioSdk\\Exception\\CannotIntegrateWithProjectException' => $baseDir . '/src/TidioSdk/Exception/CannotIntegrateWithProjectException.php',
38
+ 'TidioLiveChat\\TidioSdk\\Exception\\CannotRetrieveAccessTokensException' => $baseDir . '/src/TidioSdk/Exception/CannotRetrieveAccessTokensException.php',
39
+ 'TidioLiveChat\\TidioSdk\\TidioApiClientFactory' => $baseDir . '/src/TidioSdk/TidioApiClientFactory.php',
40
+ 'TidioLiveChat\\TidioSdk\\TidioIntegrationService' => $baseDir . '/src/TidioSdk/TidioIntegrationService.php',
41
  'TidioLiveChat\\Translation\\ErrorTranslator' => $baseDir . '/src/Translation/ErrorTranslator.php',
42
  'TidioLiveChat\\Translation\\I18n' => $baseDir . '/src/Translation/I18n.php',
43
  'TidioLiveChat\\Translation\\TranslationLoader' => $baseDir . '/src/Translation/TranslationLoader.php',
44
  'TidioLiveChat\\Utils\\QueryParameters' => $baseDir . '/src/Utils/QueryParameters.php',
45
+ 'TidioLiveChat\\Utils\\Url' => $baseDir . '/src/Utils/Url.php',
46
  'TidioLiveChat\\Widget\\WidgetLoader' => $baseDir . '/src/Widget/WidgetLoader.php',
47
+ 'TidioLiveChat\\WooCommerceSdk\\Dto\\WooCommerceIntegrationDto' => $baseDir . '/src/WooCommerceSdk/Dto/WooCommerceIntegrationDto.php',
48
+ 'TidioLiveChat\\WooCommerceSdk\\WooCommerceApiV3ClientFactory' => $baseDir . '/src/WooCommerceSdk/WooCommerceApiV3ClientFactory.php',
49
+ 'TidioLiveChat\\WooCommerceSdk\\WooCommerceIntegrationService' => $baseDir . '/src/WooCommerceSdk/WooCommerceIntegrationService.php',
50
  );
vendor/composer/autoload_static.php CHANGED
@@ -33,24 +33,35 @@ class ComposerStaticInitb9fb3e5de8a6af44b16b566fdbe3e5d5
33
  'TidioLiveChat\\Admin\\Notice\\DismissibleNoticeService' => __DIR__ . '/../..' . '/src/Admin/Notice/DismissibleNoticeService.php',
34
  'TidioLiveChat\\Admin\\Notice\\Exception\\NoticeNameIsNotAllowedException' => __DIR__ . '/../..' . '/src/Admin/Notice/Exception/NoticeNameIsNotAllowedException.php',
35
  'TidioLiveChat\\Config' => __DIR__ . '/../..' . '/src/Config.php',
 
 
 
 
 
 
 
 
 
 
 
 
36
  'TidioLiveChat\\IntegrationState' => __DIR__ . '/../..' . '/src/IntegrationState.php',
37
- 'TidioLiveChat\\Sdk\\Api\\Client\\CurlTidioApiClient' => __DIR__ . '/../..' . '/src/Sdk/Api/Client/CurlTidioApiClient.php',
38
- 'TidioLiveChat\\Sdk\\Api\\Client\\FileGetContentsTidioApiClient' => __DIR__ . '/../..' . '/src/Sdk/Api/Client/FileGetContentsTidioApiClient.php',
39
- 'TidioLiveChat\\Sdk\\Api\\Client\\TidioApiClientFactory' => __DIR__ . '/../..' . '/src/Sdk/Api/Client/TidioApiClientFactory.php',
40
- 'TidioLiveChat\\Sdk\\Api\\Exception\\TidioApiException' => __DIR__ . '/../..' . '/src/Sdk/Api/Exception/TidioApiException.php',
41
- 'TidioLiveChat\\Sdk\\Api\\TidioApiClient' => __DIR__ . '/../..' . '/src/Sdk/Api/TidioApiClient.php',
42
- 'TidioLiveChat\\Sdk\\Encryption\\EncryptionService' => __DIR__ . '/../..' . '/src/Sdk/Encryption/EncryptionService.php',
43
- 'TidioLiveChat\\Sdk\\Encryption\\Exception\\DecryptionFailedException' => __DIR__ . '/../..' . '/src/Sdk/Encryption/Exception/DecryptionFailedException.php',
44
- 'TidioLiveChat\\Sdk\\Encryption\\Service\\EncryptionServiceFactory' => __DIR__ . '/../..' . '/src/Sdk/Encryption/Service/EncryptionServiceFactory.php',
45
- 'TidioLiveChat\\Sdk\\Encryption\\Service\\OpenSslEncryptionService' => __DIR__ . '/../..' . '/src/Sdk/Encryption/Service/OpenSslEncryptionService.php',
46
- 'TidioLiveChat\\Sdk\\Encryption\\Service\\PlainTextEncryptionService' => __DIR__ . '/../..' . '/src/Sdk/Encryption/Service/PlainTextEncryptionService.php',
47
- 'TidioLiveChat\\Sdk\\IntegrationFacade' => __DIR__ . '/../..' . '/src/Sdk/IntegrationFacade.php',
48
  'TidioLiveChat\\TidioLiveChat' => __DIR__ . '/../..' . '/src/TidioLiveChat.php',
 
 
 
 
 
 
49
  'TidioLiveChat\\Translation\\ErrorTranslator' => __DIR__ . '/../..' . '/src/Translation/ErrorTranslator.php',
50
  'TidioLiveChat\\Translation\\I18n' => __DIR__ . '/../..' . '/src/Translation/I18n.php',
51
  'TidioLiveChat\\Translation\\TranslationLoader' => __DIR__ . '/../..' . '/src/Translation/TranslationLoader.php',
52
  'TidioLiveChat\\Utils\\QueryParameters' => __DIR__ . '/../..' . '/src/Utils/QueryParameters.php',
 
53
  'TidioLiveChat\\Widget\\WidgetLoader' => __DIR__ . '/../..' . '/src/Widget/WidgetLoader.php',
 
 
 
54
  );
55
 
56
  public static function getInitializer(ClassLoader $loader)
33
  'TidioLiveChat\\Admin\\Notice\\DismissibleNoticeService' => __DIR__ . '/../..' . '/src/Admin/Notice/DismissibleNoticeService.php',
34
  'TidioLiveChat\\Admin\\Notice\\Exception\\NoticeNameIsNotAllowedException' => __DIR__ . '/../..' . '/src/Admin/Notice/Exception/NoticeNameIsNotAllowedException.php',
35
  'TidioLiveChat\\Config' => __DIR__ . '/../..' . '/src/Config.php',
36
+ 'TidioLiveChat\\Container' => __DIR__ . '/../..' . '/src/Container.php',
37
+ 'TidioLiveChat\\Encryption\\EncryptionService' => __DIR__ . '/../..' . '/src/Encryption/EncryptionService.php',
38
+ 'TidioLiveChat\\Encryption\\Exception\\DecryptionFailedException' => __DIR__ . '/../..' . '/src/Encryption/Exception/DecryptionFailedException.php',
39
+ 'TidioLiveChat\\Encryption\\Service\\EncryptionServiceFactory' => __DIR__ . '/../..' . '/src/Encryption/Service/EncryptionServiceFactory.php',
40
+ 'TidioLiveChat\\Encryption\\Service\\OpenSslEncryptionService' => __DIR__ . '/../..' . '/src/Encryption/Service/OpenSslEncryptionService.php',
41
+ 'TidioLiveChat\\Encryption\\Service\\PlainTextEncryptionService' => __DIR__ . '/../..' . '/src/Encryption/Service/PlainTextEncryptionService.php',
42
+ 'TidioLiveChat\\Http\\Client\\CurlHttpClient' => __DIR__ . '/../..' . '/src/Http/Client/CurlHttpClient.php',
43
+ 'TidioLiveChat\\Http\\Client\\FileGetContentsHttpClient' => __DIR__ . '/../..' . '/src/Http/Client/FileGetContentsHttpClient.php',
44
+ 'TidioLiveChat\\Http\\Exception\\ErrorResponseException' => __DIR__ . '/../..' . '/src/Http/Exception/ErrorResponseException.php',
45
+ 'TidioLiveChat\\Http\\Exception\\HttpClientException' => __DIR__ . '/../..' . '/src/Http/Exception/HttpClientException.php',
46
+ 'TidioLiveChat\\Http\\Exception\\UnauthorizedResponseException' => __DIR__ . '/../..' . '/src/Http/Exception/UnauthorizedResponseException.php',
47
+ 'TidioLiveChat\\Http\\HttpClient' => __DIR__ . '/../..' . '/src/Http/HttpClient.php',
48
  'TidioLiveChat\\IntegrationState' => __DIR__ . '/../..' . '/src/IntegrationState.php',
 
 
 
 
 
 
 
 
 
 
 
49
  'TidioLiveChat\\TidioLiveChat' => __DIR__ . '/../..' . '/src/TidioLiveChat.php',
50
+ 'TidioLiveChat\\TidioSdk\\Dto\\ApiCredentialsDto' => __DIR__ . '/../..' . '/src/TidioSdk/Dto/ApiCredentialsDto.php',
51
+ 'TidioLiveChat\\TidioSdk\\Exception\\AccessTokensAreNotSetException' => __DIR__ . '/../..' . '/src/TidioSdk/Exception/AccessTokensAreNotSetException.php',
52
+ 'TidioLiveChat\\TidioSdk\\Exception\\CannotIntegrateWithProjectException' => __DIR__ . '/../..' . '/src/TidioSdk/Exception/CannotIntegrateWithProjectException.php',
53
+ 'TidioLiveChat\\TidioSdk\\Exception\\CannotRetrieveAccessTokensException' => __DIR__ . '/../..' . '/src/TidioSdk/Exception/CannotRetrieveAccessTokensException.php',
54
+ 'TidioLiveChat\\TidioSdk\\TidioApiClientFactory' => __DIR__ . '/../..' . '/src/TidioSdk/TidioApiClientFactory.php',
55
+ 'TidioLiveChat\\TidioSdk\\TidioIntegrationService' => __DIR__ . '/../..' . '/src/TidioSdk/TidioIntegrationService.php',
56
  'TidioLiveChat\\Translation\\ErrorTranslator' => __DIR__ . '/../..' . '/src/Translation/ErrorTranslator.php',
57
  'TidioLiveChat\\Translation\\I18n' => __DIR__ . '/../..' . '/src/Translation/I18n.php',
58
  'TidioLiveChat\\Translation\\TranslationLoader' => __DIR__ . '/../..' . '/src/Translation/TranslationLoader.php',
59
  'TidioLiveChat\\Utils\\QueryParameters' => __DIR__ . '/../..' . '/src/Utils/QueryParameters.php',
60
+ 'TidioLiveChat\\Utils\\Url' => __DIR__ . '/../..' . '/src/Utils/Url.php',
61
  'TidioLiveChat\\Widget\\WidgetLoader' => __DIR__ . '/../..' . '/src/Widget/WidgetLoader.php',
62
+ 'TidioLiveChat\\WooCommerceSdk\\Dto\\WooCommerceIntegrationDto' => __DIR__ . '/../..' . '/src/WooCommerceSdk/Dto/WooCommerceIntegrationDto.php',
63
+ 'TidioLiveChat\\WooCommerceSdk\\WooCommerceApiV3ClientFactory' => __DIR__ . '/../..' . '/src/WooCommerceSdk/WooCommerceApiV3ClientFactory.php',
64
+ 'TidioLiveChat\\WooCommerceSdk\\WooCommerceIntegrationService' => __DIR__ . '/../..' . '/src/WooCommerceSdk/WooCommerceIntegrationService.php',
65
  );
66
 
67
  public static function getInitializer(ClassLoader $loader)
vendor/composer/installed.php CHANGED
@@ -6,7 +6,7 @@
6
  'aliases' =>
7
  array (
8
  ),
9
- 'reference' => '0b929f9fdb17b6dc185478aacd9a025bfba5a30d',
10
  'name' => '__root__',
11
  ),
12
  'versions' =>
@@ -18,7 +18,7 @@
18
  'aliases' =>
19
  array (
20
  ),
21
- 'reference' => '0b929f9fdb17b6dc185478aacd9a025bfba5a30d',
22
  ),
23
  ),
24
  );
6
  'aliases' =>
7
  array (
8
  ),
9
+ 'reference' => 'cb906195547d91fdafebf29181d5c01ea93ef591',
10
  'name' => '__root__',
11
  ),
12
  'versions' =>
18
  'aliases' =>
19
  array (
20
  ),
21
+ 'reference' => 'cb906195547d91fdafebf29181d5c01ea93ef591',
22
  ),
23
  ),
24
  );