Tidio Live Chat - Version 5.4.0

Version Description

  • Add a notice about coming changes
Download this release

Release Info

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

Code changes from version 5.3.0 to 5.4.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
@@ -4,7 +4,7 @@ Tags: free live chat, live chat, chat, chatbot, livechat, tidio, widget, zendesk
4
  Requires at least: 4.7
5
  Tested up to: 6.0
6
  Requires PHP: 5.6
7
- Stable tag: 5.3.0
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.3.0 =
202
 
203
  - Security update (prevent printing the real path of webroot on misconfigured servers)
4
  Requires at least: 4.7
5
  Tested up to: 6.0
6
  Requires PHP: 5.6
7
+ Stable tag: 5.4.0
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
198
 
199
  == Changelog ==
200
 
201
+ = 5.4.0 =
202
+
203
+ - Add a notice about coming changes
204
+
205
  = 5.3.0 =
206
 
207
  - Security update (prevent printing the real path of webroot on misconfigured servers)
src/Admin/AdminController.php CHANGED
@@ -6,6 +6,7 @@ if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
 
9
  use TidioLiveChat\Sdk\Api\Exception\TidioApiException;
10
  use TidioLiveChat\Sdk\IntegrationFacade;
11
  use TidioLiveChat\IntegrationState;
@@ -22,15 +23,27 @@ class AdminController
22
  * @var IntegrationState
23
  */
24
  private $integrationState;
 
 
 
 
 
 
 
 
25
 
26
  /**
27
  * @param IntegrationFacade $integrationFacade
28
  * @param IntegrationState $integrationState
 
 
29
  */
30
- public function __construct($integrationFacade, $integrationState)
31
  {
32
  $this->integrationFacade = $integrationFacade;
33
  $this->integrationState = $integrationState;
 
 
34
  }
35
 
36
  public function handleIntegrateProjectAction()
@@ -74,6 +87,7 @@ class AdminController
74
  }
75
 
76
  $this->integrationState->removeIntegration();
 
77
 
78
  $this->redirectToPluginsListDashboard();
79
  }
@@ -84,11 +98,7 @@ class AdminController
84
  */
85
  private function isRequestNonceValid($nonce)
86
  {
87
- if (!QueryParameters::has('_wpnonce')) {
88
- return false;
89
- }
90
-
91
- return (bool) wp_verify_nonce(QueryParameters::get('_wpnonce'), $nonce);
92
  }
93
 
94
  private function redirectToPluginsListDashboard()
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ use TidioLiveChat\Admin\Notice\DismissibleNoticeService;
10
  use TidioLiveChat\Sdk\Api\Exception\TidioApiException;
11
  use TidioLiveChat\Sdk\IntegrationFacade;
12
  use TidioLiveChat\IntegrationState;
23
  * @var IntegrationState
24
  */
25
  private $integrationState;
26
+ /**
27
+ * @var NonceValidator
28
+ */
29
+ private $nonceValidator;
30
+ /**
31
+ * @var DismissibleNoticeService
32
+ */
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
  }
48
 
49
  public function handleIntegrateProjectAction()
87
  }
88
 
89
  $this->integrationState->removeIntegration();
90
+ $this->dismissibleNoticeService->clearDismissedNoticesHistory();
91
 
92
  $this->redirectToPluginsListDashboard();
93
  }
98
  */
99
  private function isRequestNonceValid($nonce)
100
  {
101
+ return $this->nonceValidator->isRequestNonceValid($nonce);
 
 
 
 
102
  }
103
 
104
  private function redirectToPluginsListDashboard()
src/Admin/AdminNotice.php CHANGED
@@ -6,6 +6,8 @@ if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
 
 
9
  use TidioLiveChat\Translation\ErrorTranslator;
10
  use TidioLiveChat\Utils\QueryParameters;
11
 
@@ -16,14 +18,22 @@ class AdminNotice
16
  */
17
  private $errorTranslator;
18
 
 
 
 
 
 
19
  /**
20
  * @param ErrorTranslator $errorTranslator
 
21
  */
22
- public function __construct($errorTranslator)
23
  {
24
  $this->errorTranslator = $errorTranslator;
 
25
 
26
  add_action('admin_notices', [$this, 'addAdminErrorNotice']);
 
27
  }
28
 
29
  public function addAdminErrorNotice()
@@ -36,4 +46,30 @@ class AdminNotice
36
  $errorMessage = $this->errorTranslator->translate($errorCode);
37
  echo sprintf('<div class="notice notice-error is-dismissible"><p>%s</p></div>', $errorMessage);
38
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  }
6
  die('File loaded directly. Exiting.');
7
  }
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
 
18
  */
19
  private $errorTranslator;
20
 
21
+ /**
22
+ * @var DismissibleNoticeService
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()
46
  $errorMessage = $this->errorTranslator->translate($errorCode);
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
  }
src/Admin/AdminRouting.php CHANGED
@@ -6,20 +6,25 @@ if (!defined('WPINC')) {
6
  die('File loaded directly. Exiting.');
7
  }
8
 
 
 
9
  class AdminRouting
10
  {
11
  const CLEAR_ACCOUNT_DATA_ACTION = 'tidio-live-chat-clear-account-data';
12
  const INTEGRATE_PROJECT_ACTION = 'tidio-live-chat-integrate-project';
13
  const TOGGLE_ASYNC_LOADING_ACTION = 'tidio-live-chat-toggle-async-loading';
 
14
 
15
  /**
16
  * @param AdminController $adminController
 
17
  */
18
- public function __construct($adminController)
19
  {
20
  add_action('admin_post_' . self::INTEGRATE_PROJECT_ACTION, [$adminController, 'handleIntegrateProjectAction']);
21
  add_action('admin_post_' . self::TOGGLE_ASYNC_LOADING_ACTION, [$adminController, 'handleToggleAsyncLoadingAction']);
22
  add_action('admin_post_' . self::CLEAR_ACCOUNT_DATA_ACTION, [$adminController, 'handleClearAccountDataAction']);
 
23
  }
24
 
25
  /**
@@ -46,16 +51,29 @@ class AdminRouting
46
  return self::getEndpointForAction(self::CLEAR_ACCOUNT_DATA_ACTION);
47
  }
48
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  /**
50
  * @param string $action
51
  * @return string
52
  */
53
- private static function getEndpointForAction($action)
54
  {
55
- $queryString = http_build_query([
56
- 'action' => $action,
57
- '_wpnonce' => wp_create_nonce($action),
58
- ]);
 
59
  return admin_url('admin-post.php?' . $queryString);
60
  }
61
  }
6
  die('File loaded directly. Exiting.');
7
  }
8
 
9
+ use TidioLiveChat\Admin\Notice\DismissibleNoticeController;
10
+
11
  class AdminRouting
12
  {
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
  return self::getEndpointForAction(self::CLEAR_ACCOUNT_DATA_ACTION);
52
  }
53
 
54
+ /**
55
+ * @param string $noticeOptionName
56
+ * @return string
57
+ */
58
+ public static function getEndpointForHandleDismissNotice($noticeOptionName)
59
+ {
60
+ return self::getEndpointForAction(
61
+ self::DISMISS_NOTICE_ACTION,
62
+ [DismissibleNoticeController::TIDIO_NOTICE_QUERY_PARAM_NAME => $noticeOptionName]
63
+ );
64
+ }
65
+
66
  /**
67
  * @param string $action
68
  * @return string
69
  */
70
+ private static function getEndpointForAction($action, array $params = [])
71
  {
72
+ $params['action'] = $action;
73
+ $params['_wpnonce'] = wp_create_nonce($action);
74
+
75
+ $queryString = http_build_query($params);
76
+
77
  return admin_url('admin-post.php?' . $queryString);
78
  }
79
  }
src/Admin/IframeSetup.php CHANGED
@@ -73,6 +73,7 @@ class IframeSetup
73
  return [
74
  'siteUrl' => get_home_url(),
75
  'localeCode' => $localeCode,
 
76
  'utm_source' => 'platform',
77
  'utm_medium' => 'wordpress',
78
  ];
73
  return [
74
  'siteUrl' => get_home_url(),
75
  'localeCode' => $localeCode,
76
+ 'language' => substr($localeCode, 0, 2),
77
  'utm_source' => 'platform',
78
  'utm_medium' => 'wordpress',
79
  ];
src/Admin/NonceValidator.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\Admin;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ use TidioLiveChat\Utils\QueryParameters;
10
+
11
+ class NonceValidator
12
+ {
13
+ /**
14
+ * @param string $nonce
15
+ * @return bool
16
+ */
17
+ public function isRequestNonceValid($nonce)
18
+ {
19
+ if (!QueryParameters::has('_wpnonce')) {
20
+ return false;
21
+ }
22
+
23
+ return (bool) wp_verify_nonce(QueryParameters::get('_wpnonce'), $nonce);
24
+ }
25
+ }
src/Admin/Notice/DismissibleNoticeController.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\Admin\Notice;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ use TidioLiveChat\Admin\AdminRouting;
10
+ use TidioLiveChat\Admin\NonceValidator;
11
+ use TidioLiveChat\Admin\Notice\Exception\NoticeNameIsNotAllowedException;
12
+ use TidioLiveChat\Utils\QueryParameters;
13
+
14
+ class DismissibleNoticeController
15
+ {
16
+ const TIDIO_NOTICE_QUERY_PARAM_NAME = 'tidio_notice';
17
+
18
+ /**
19
+ * @var DismissibleNoticeService
20
+ */
21
+ private $dismissibleNoticeService;
22
+ /**
23
+ * @var NonceValidator
24
+ */
25
+ private $nonceValidator;
26
+
27
+ /**
28
+ * @param DismissibleNoticeService $dismissibleNoticeService
29
+ * @param NonceValidator $nonceValidator
30
+ */
31
+ public function __construct($dismissibleNoticeService, $nonceValidator)
32
+ {
33
+ $this->dismissibleNoticeService = $dismissibleNoticeService;
34
+ $this->nonceValidator = $nonceValidator;
35
+ }
36
+
37
+ public function handleDismissNotice()
38
+ {
39
+ if (!$this->nonceValidator->isRequestNonceValid(AdminRouting::DISMISS_NOTICE_ACTION)) {
40
+ wp_die('', 403);
41
+ }
42
+
43
+ $noticeName = QueryParameters::get(self::TIDIO_NOTICE_QUERY_PARAM_NAME);
44
+
45
+ try {
46
+ $this->dismissibleNoticeService->markAsDismissed($noticeName);
47
+ } catch (NoticeNameIsNotAllowedException $exception) {
48
+ // do nothing if notice name is invalid
49
+ }
50
+
51
+ return true;
52
+ }
53
+ }
src/Admin/Notice/DismissibleNoticeService.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\Admin\Notice;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ use TidioLiveChat\Admin\AdminRouting;
10
+ use TidioLiveChat\Admin\Notice\Exception\NoticeNameIsNotAllowedException;
11
+
12
+ class DismissibleNoticeService
13
+ {
14
+ const PHP_7_2_REQUIREMENT_NOTICE = 'tidio-php-7-2-requirement-notice';
15
+
16
+ /**
17
+ * @return string[]
18
+ */
19
+ private static function getAllowedNoticeOptions()
20
+ {
21
+ return [
22
+ self::PHP_7_2_REQUIREMENT_NOTICE,
23
+ ];
24
+ }
25
+
26
+ /**
27
+ * @param string $noticeName
28
+ * @return void
29
+ */
30
+ public function markAsDismissed($noticeName)
31
+ {
32
+ $this->validateNoticeName($noticeName);
33
+
34
+ update_option($noticeName, true);
35
+ }
36
+
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
+
48
+ if ($this->wasDismissed($noticeName)) {
49
+ return;
50
+ }
51
+
52
+ if (str_contains($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
+ }
55
+
56
+ $dismissibleScript = <<<HTML
57
+ <script type="text/javascript">
58
+ window.onload = function() {
59
+ if (window.jQuery) {
60
+ jQuery(document).ready(function() {
61
+ jQuery('[data-tidio-dismissible-url]').click(function(e) {
62
+ e.preventDefault();
63
+ const noticeParent = jQuery(this).closest('.notice');
64
+
65
+ jQuery.ajax({
66
+ url: jQuery(this).data('tidio-dismissible-url'),
67
+ type: 'post',
68
+ success: function() {
69
+ noticeParent.fadeOut(200);
70
+ },
71
+ error: function() {
72
+ noticeParent.fadeOut(200);
73
+ console.error('Could not dismiss tidio notice');
74
+ }
75
+ });
76
+ });
77
+ });
78
+ }
79
+ }
80
+ </script>
81
+ HTML;
82
+
83
+ $scriptWithDismissiblePart = strtr($script . $dismissibleScript, ['{dismiss_url}' => $this->buildDismissibleNoticeHref($noticeName)]);
84
+
85
+ echo $scriptWithDismissiblePart;
86
+ }
87
+
88
+ public function clearDismissedNoticesHistory()
89
+ {
90
+ foreach (self::getAllowedNoticeOptions() as $noticeOption) {
91
+ delete_option($noticeOption);
92
+ }
93
+ }
94
+
95
+ /**
96
+ * @param string $noticeName
97
+ * @return string
98
+ */
99
+ private function buildDismissibleNoticeHref($noticeName)
100
+ {
101
+ return AdminRouting::getEndpointForHandleDismissNotice($noticeName);
102
+ }
103
+
104
+ /**
105
+ * @param string $name
106
+ * @return bool
107
+ */
108
+ private function wasDismissed($name)
109
+ {
110
+ return (bool) get_option($name);
111
+ }
112
+
113
+ /**
114
+ * @param string $noticeName
115
+ * @return void
116
+ * @throws NoticeNameIsNotAllowedException
117
+ */
118
+ private function validateNoticeName($noticeName)
119
+ {
120
+ if ($this->isNoticeNameAllowed($noticeName)) {
121
+ throw NoticeNameIsNotAllowedException::withName($noticeName);
122
+ }
123
+ }
124
+
125
+ /**
126
+ * @param string $noticeName
127
+ * @return bool
128
+ */
129
+ private function isNoticeNameAllowed($noticeName)
130
+ {
131
+ return in_array($noticeName, self::getAllowedNoticeOptions(), true) === false;
132
+ }
133
+ }
src/Admin/Notice/Exception/NoticeNameIsNotAllowedException.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TidioLiveChat\Admin\Notice\Exception;
4
+
5
+ if (!defined('WPINC')) {
6
+ die('File loaded directly. Exiting.');
7
+ }
8
+
9
+ class NoticeNameIsNotAllowedException extends \InvalidArgumentException
10
+ {
11
+ /**
12
+ * @param string $noticeName
13
+ */
14
+ public function __construct($noticeName)
15
+ {
16
+ $message = sprintf('Notice name \'%s\' is not allowed', $noticeName);
17
+ parent::__construct($message);
18
+ }
19
+
20
+ /**
21
+ * @param string $noticeName
22
+ * @return self
23
+ */
24
+ public static function withName($noticeName)
25
+ {
26
+ return new self($noticeName);
27
+ }
28
+ }
src/Admin/Notice/Views/NoticeTemplate.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) {
3
+ die('File loaded directly. Exiting.');
4
+ }
5
+
6
+ use TidioLiveChat\Translation\I18n;
7
+ ?>
8
+
9
+ <div>
10
+ <style>
11
+ .notice {
12
+ display: flex;
13
+ position: relative;
14
+ }
15
+ .notice p {
16
+
17
+ font-weight: 400;
18
+ font-size: 12px;
19
+ line-height: 16px;
20
+ letter-spacing: -0.01em;
21
+ margin: 12px 0;
22
+ }
23
+ .notice p.header {
24
+ font-size: 14px;
25
+ line-height: 18px;
26
+ }
27
+ .notice p strong {
28
+ font-weight: 600;
29
+ }
30
+ .link.button {
31
+ display: flex;
32
+ justify-content: center;
33
+ align-items: center;
34
+ height: 36px;
35
+ background: #0566ff;
36
+ border-radius: 4px;
37
+ font-size: 14px;
38
+ line-height: 18px;
39
+ color: #ffffff;
40
+ margin-right: 24px;
41
+ margin-left: auto;
42
+ }
43
+ section {
44
+ margin-right: 48px;
45
+ }
46
+ section:last-child {
47
+ margin-right: 24px;
48
+ }
49
+ .link.button:hover {
50
+ color: #fff;
51
+ background-color: #0049bd;
52
+ }
53
+ .notice-content {
54
+ display: flex;
55
+ flex-direction: row;
56
+ align-items: center;
57
+ min-width: 100%;
58
+ }
59
+ .logo {
60
+ width: 32px;
61
+ height: 32px;
62
+ margin-left: 24px;
63
+ margin-right: 24px;
64
+ }
65
+ .dissmiss-button {
66
+ position: absolute;
67
+ top: 4px;
68
+ right: 4px;
69
+ font-size: 13px;
70
+ cursor: pointer;
71
+ }
72
+ @media screen and (max-width: 782px) {
73
+ .notice-content {
74
+ display: block;
75
+ }
76
+ .link.button {
77
+ display: inline-flex;
78
+ margin-right: 0;
79
+ margin-left: 0;
80
+ align-self: flex-start;
81
+ }
82
+ .logo {
83
+ display: none;
84
+ }
85
+ section:last-child {
86
+ margin-right: 0;
87
+ }
88
+ }
89
+ </style>
90
+ <div class="notice notice-info">
91
+ <div class="notice-content">
92
+ <div class="logo">
93
+ <svg
94
+ width="32"
95
+ height="32"
96
+ xmlns="http://www.w3.org/2000/svg"
97
+ viewBox="0 0 32 32"
98
+ style="min-width: 32px; min-height: 32px"
99
+ >
100
+ <g fill="none">
101
+ <path
102
+ d="M20.63 0a11.343 11.343 0 00-11.2 9.42 12.517 12.517 0 00.003 0A11.394 11.394 0 000 20.643V32h11.384a11.37 11.37 0 0011.18-9.25h-2.5H32V11.358C31.985 5.085 26.901.007 20.63 0zM9.263 11.394a11.271 11.271 0 000 .003v-.003z"
103
+ fill="#135EEB"
104
+ ></path>
105
+ <path
106
+ d="M11.408 9.25a12.53 12.53 0 00-1.975.17c-.108.651-.165 1.31-.17 1.97a11.363 11.363 0 0011.37 11.36h1.94c.14-.706.208-1.424.205-2.144a11.34 11.34 0 00-11.37-11.357z"
107
+ fill="#0A60EA"
108
+ ></path>
109
+ <path
110
+ d="M20.654 22.75A11.37 11.37 0 019.263 11.398c.004-.66.061-1.32.17-1.97A11.39 11.39 0 000 20.642V32h11.384a11.37 11.37 0 0011.18-9.25h-1.91z"
111
+ fill="#15C2FF"
112
+ ></path>
113
+ <path
114
+ d="M20.63 0a11.343 11.343 0 00-11.2 9.42 12.524 12.524 0 011.974-.17 11.357 11.357 0 0111.166 13.5H32V11.358C31.985 5.085 26.901.007 20.63 0z"
115
+ fill="#2C82FF"
116
+ ></path>
117
+ </g>
118
+ </svg>
119
+ </div>
120
+ <section>
121
+ <p class="header">
122
+ <strong>
123
+ <?php I18n::_e('Sed ac scelerisque massa.'); ?>
124
+ </strong>
125
+ </p>
126
+ <p>
127
+ <?php I18n::_e('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec pulvinar urna sit amet sapien sagittis lacinia. Etiam mollis ante sed ipsum pretium, et bibendum urna iaculis. '); ?>
128
+ <strong><?php I18n::_e('Praesent tincidunt lorem non mauris tincidunt pharetra.'); ?></strong>
129
+ </p>
130
+ </section>
131
+ <a class="link button"> <?php I18n::_e('Click me'); ?></a>
132
+ </div>
133
+ <a data-tidio-dismissible-url="{dismiss_url}" class="dissmiss-button"
134
+ ><svg
135
+ xmlns="http://www.w3.org/2000/svg"
136
+ width="22"
137
+ height="22"
138
+ viewBox="0 0 24 24"
139
+ style="min-width: 22px; min-height: 22px"
140
+ >
141
+ <path
142
+ d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
143
+ ></path>
144
+ <path d="M0 0h24v24H0z" fill="none"></path>
145
+ </svg>
146
+ </a>
147
+ </div>
148
+ </div>
src/Admin/Notice/Views/Php72RequirementNotice.php ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) {
3
+ die('File loaded directly. Exiting.');
4
+ }
5
+
6
+ use TidioLiveChat\Translation\I18n;
7
+ ?>
8
+
9
+ <div>
10
+ <style>
11
+ .notice {
12
+ display: flex;
13
+ position: relative;
14
+ }
15
+ .notice p {
16
+
17
+ font-weight: 400;
18
+ font-size: 12px;
19
+ line-height: 16px;
20
+ letter-spacing: -0.01em;
21
+ margin: 12px 0;
22
+ }
23
+ .notice p.header {
24
+ font-size: 14px;
25
+ line-height: 18px;
26
+ }
27
+ .notice p strong {
28
+ font-weight: 600;
29
+ }
30
+ .link.button {
31
+ display: flex;
32
+ justify-content: center;
33
+ align-items: center;
34
+ height: 36px;
35
+ background: #0566ff;
36
+ border-radius: 4px;
37
+ font-size: 14px;
38
+ line-height: 18px;
39
+ color: #ffffff;
40
+ margin-right: 24px;
41
+ margin-left: auto;
42
+ }
43
+ section {
44
+ margin-right: 48px;
45
+ }
46
+ section:last-child {
47
+ margin-right: 24px;
48
+ }
49
+ .link.button:hover {
50
+ color: #fff;
51
+ background-color: #0049bd;
52
+ }
53
+ .notice-content {
54
+ display: flex;
55
+ flex-direction: row;
56
+ align-items: center;
57
+ min-width: 100%;
58
+ }
59
+ .logo {
60
+ width: 32px;
61
+ height: 32px;
62
+ margin-left: 24px;
63
+ margin-right: 24px;
64
+ }
65
+ .dissmiss-button {
66
+ position: absolute;
67
+ top: 4px;
68
+ right: 4px;
69
+ font-size: 13px;
70
+ cursor: pointer;
71
+ }
72
+
73
+ @media screen and (max-width: 782px) {
74
+ .notice-content {
75
+ display: block;
76
+ }
77
+ .link.button {
78
+ display: inline-flex;
79
+ margin-right: 0;
80
+ margin-left: 0;
81
+ align-self: flex-start;
82
+ }
83
+ .logo {
84
+ display: none;
85
+ }
86
+ section:last-child {
87
+ margin-right: 0;
88
+ }
89
+ }
90
+ </style>
91
+ <div class="notice notice-info">
92
+ <div class="notice-content">
93
+ <div class="logo">
94
+ <svg
95
+ width="32"
96
+ height="32"
97
+ xmlns="http://www.w3.org/2000/svg"
98
+ viewBox="0 0 32 32"
99
+ style="min-width: 32px; min-height: 32px"
100
+ >
101
+ <g fill="none">
102
+ <path
103
+ d="M20.63 0a11.343 11.343 0 00-11.2 9.42 12.517 12.517 0 00.003 0A11.394 11.394 0 000 20.643V32h11.384a11.37 11.37 0 0011.18-9.25h-2.5H32V11.358C31.985 5.085 26.901.007 20.63 0zM9.263 11.394a11.271 11.271 0 000 .003v-.003z"
104
+ fill="#135EEB"
105
+ ></path>
106
+ <path
107
+ d="M11.408 9.25a12.53 12.53 0 00-1.975.17c-.108.651-.165 1.31-.17 1.97a11.363 11.363 0 0011.37 11.36h1.94c.14-.706.208-1.424.205-2.144a11.34 11.34 0 00-11.37-11.357z"
108
+ fill="#0A60EA"
109
+ ></path>
110
+ <path
111
+ d="M20.654 22.75A11.37 11.37 0 019.263 11.398c.004-.66.061-1.32.17-1.97A11.39 11.39 0 000 20.642V32h11.384a11.37 11.37 0 0011.18-9.25h-1.91z"
112
+ fill="#15C2FF"
113
+ ></path>
114
+ <path
115
+ d="M20.63 0a11.343 11.343 0 00-11.2 9.42 12.524 12.524 0 011.974-.17 11.357 11.357 0 0111.166 13.5H32V11.358C31.985 5.085 26.901.007 20.63 0z"
116
+ fill="#2C82FF"
117
+ ></path>
118
+ </g>
119
+ </svg>
120
+ </div>
121
+ <section>
122
+ <p class="header">
123
+ <strong>
124
+ <?php I18n::_e('Tidio Chat will be updated soon.'); ?>
125
+ </strong>
126
+ </p>
127
+ <p>
128
+ <?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.'); ?>
129
+ <strong><?php I18n::_e('This update will require PHP 7.2 or higher.'); ?></strong>
130
+ </p>
131
+ </section>
132
+ <a class="link button" href="https://help.tidio.com/docs/send-woocommerce-products-to-customers-directly-from-tidio" target="_blank">
133
+ <?php I18n::_e('Check how product cards work'); ?>
134
+ </a>
135
+ </div>
136
+ <a data-tidio-dismissible-url="{dismiss_url}" class="dissmiss-button"
137
+ ><svg
138
+ xmlns="http://www.w3.org/2000/svg"
139
+ width="22"
140
+ height="22"
141
+ viewBox="0 0 24 24"
142
+ style="min-width: 22px; min-height: 22px"
143
+ >
144
+ <path
145
+ d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
146
+ ></path>
147
+ <path d="M0 0h24v24H0z" fill="none"></path>
148
+ </svg>
149
+ </a>
150
+ </div>
151
+ </div>
src/TidioLiveChat.php CHANGED
@@ -12,6 +12,9 @@ use TidioLiveChat\Admin\AdminDashboard;
12
  use TidioLiveChat\Admin\AdminNotice;
13
  use TidioLiveChat\Admin\AdminRouting;
14
  use TidioLiveChat\Admin\IframeSetup;
 
 
 
15
  use TidioLiveChat\Sdk\Api\Client\TidioApiClientFactory;
16
  use TidioLiveChat\Sdk\Encryption\Service\EncryptionServiceFactory;
17
  use TidioLiveChat\Sdk\IntegrationFacade;
@@ -33,17 +36,31 @@ class TidioLiveChat
33
  }
34
 
35
  if (current_user_can('activate_plugins')) {
 
 
 
 
 
 
36
  new TranslationLoader();
37
  $apiClientFactory = new TidioApiClientFactory();
38
  $integrationFacade = new IntegrationFacade($apiClientFactory);
39
- $adminController = new AdminController($integrationFacade, $integrationState);
 
 
 
 
 
40
  $iframeSetup = new IframeSetup($integrationState);
41
  $errorTranslator = new ErrorTranslator();
42
 
43
- new AdminRouting($adminController);
 
 
 
44
  new AdminActionLink($integrationState);
45
  new AdminDashboard($integrationState, $iframeSetup);
46
- new AdminNotice($errorTranslator);
47
  }
48
  }
49
  }
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;
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
  }
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.3.0
12
  * Author: Tidio Ltd.
13
  * Author URI: http://www.tidio.com
14
  * Text Domain: tidio-live-chat
@@ -16,7 +16,7 @@ if (!defined('WPINC')) {
16
  * License: GPL2
17
  */
18
 
19
- define('TIDIOCHAT_VERSION', '5.3.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';
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.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', '5.4.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';
vendor/composer/InstalledVersions.php CHANGED
@@ -25,24 +25,24 @@ class InstalledVersions
25
  private static $installed = array (
26
  'root' =>
27
  array (
28
- 'pretty_version' => 'dev-master',
29
- 'version' => 'dev-master',
30
  'aliases' =>
31
  array (
32
  ),
33
- 'reference' => 'adf8041d1672126bd45b71ae1d70742cfeae7aa8',
34
  'name' => '__root__',
35
  ),
36
  'versions' =>
37
  array (
38
  '__root__' =>
39
  array (
40
- 'pretty_version' => 'dev-master',
41
- 'version' => 'dev-master',
42
  'aliases' =>
43
  array (
44
  ),
45
- 'reference' => 'adf8041d1672126bd45b71ae1d70742cfeae7aa8',
46
  ),
47
  ),
48
  );
25
  private static $installed = array (
26
  'root' =>
27
  array (
28
+ 'pretty_version' => '5.4.0',
29
+ 'version' => '5.4.0.0',
30
  'aliases' =>
31
  array (
32
  ),
33
+ 'reference' => 'e37337253ce0f37ca9129706f21c556b5b8b5d15',
34
  'name' => '__root__',
35
  ),
36
  'versions' =>
37
  array (
38
  '__root__' =>
39
  array (
40
+ 'pretty_version' => '5.4.0',
41
+ 'version' => '5.4.0.0',
42
  'aliases' =>
43
  array (
44
  ),
45
+ 'reference' => 'e37337253ce0f37ca9129706f21c556b5b8b5d15',
46
  ),
47
  ),
48
  );
vendor/composer/autoload_classmap.php CHANGED
@@ -13,6 +13,10 @@ return array(
13
  'TidioLiveChat\\Admin\\AdminNotice' => $baseDir . '/src/Admin/AdminNotice.php',
14
  'TidioLiveChat\\Admin\\AdminRouting' => $baseDir . '/src/Admin/AdminRouting.php',
15
  'TidioLiveChat\\Admin\\IframeSetup' => $baseDir . '/src/Admin/IframeSetup.php',
 
 
 
 
16
  'TidioLiveChat\\Config' => $baseDir . '/src/Config.php',
17
  'TidioLiveChat\\IntegrationState' => $baseDir . '/src/IntegrationState.php',
18
  'TidioLiveChat\\Sdk\\Api\\Client\\CurlTidioApiClient' => $baseDir . '/src/Sdk/Api/Client/CurlTidioApiClient.php',
13
  'TidioLiveChat\\Admin\\AdminNotice' => $baseDir . '/src/Admin/AdminNotice.php',
14
  'TidioLiveChat\\Admin\\AdminRouting' => $baseDir . '/src/Admin/AdminRouting.php',
15
  'TidioLiveChat\\Admin\\IframeSetup' => $baseDir . '/src/Admin/IframeSetup.php',
16
+ 'TidioLiveChat\\Admin\\NonceValidator' => $baseDir . '/src/Admin/NonceValidator.php',
17
+ 'TidioLiveChat\\Admin\\Notice\\DismissibleNoticeController' => $baseDir . '/src/Admin/Notice/DismissibleNoticeController.php',
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',
vendor/composer/autoload_static.php CHANGED
@@ -28,6 +28,10 @@ class ComposerStaticInitb9fb3e5de8a6af44b16b566fdbe3e5d5
28
  'TidioLiveChat\\Admin\\AdminNotice' => __DIR__ . '/../..' . '/src/Admin/AdminNotice.php',
29
  'TidioLiveChat\\Admin\\AdminRouting' => __DIR__ . '/../..' . '/src/Admin/AdminRouting.php',
30
  'TidioLiveChat\\Admin\\IframeSetup' => __DIR__ . '/../..' . '/src/Admin/IframeSetup.php',
 
 
 
 
31
  'TidioLiveChat\\Config' => __DIR__ . '/../..' . '/src/Config.php',
32
  'TidioLiveChat\\IntegrationState' => __DIR__ . '/../..' . '/src/IntegrationState.php',
33
  'TidioLiveChat\\Sdk\\Api\\Client\\CurlTidioApiClient' => __DIR__ . '/../..' . '/src/Sdk/Api/Client/CurlTidioApiClient.php',
28
  'TidioLiveChat\\Admin\\AdminNotice' => __DIR__ . '/../..' . '/src/Admin/AdminNotice.php',
29
  'TidioLiveChat\\Admin\\AdminRouting' => __DIR__ . '/../..' . '/src/Admin/AdminRouting.php',
30
  'TidioLiveChat\\Admin\\IframeSetup' => __DIR__ . '/../..' . '/src/Admin/IframeSetup.php',
31
+ 'TidioLiveChat\\Admin\\NonceValidator' => __DIR__ . '/../..' . '/src/Admin/NonceValidator.php',
32
+ 'TidioLiveChat\\Admin\\Notice\\DismissibleNoticeController' => __DIR__ . '/../..' . '/src/Admin/Notice/DismissibleNoticeController.php',
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',
vendor/composer/installed.php CHANGED
@@ -1,24 +1,24 @@
1
  <?php return array (
2
  'root' =>
3
  array (
4
- 'pretty_version' => 'dev-master',
5
- 'version' => 'dev-master',
6
  'aliases' =>
7
  array (
8
  ),
9
- 'reference' => 'adf8041d1672126bd45b71ae1d70742cfeae7aa8',
10
  'name' => '__root__',
11
  ),
12
  'versions' =>
13
  array (
14
  '__root__' =>
15
  array (
16
- 'pretty_version' => 'dev-master',
17
- 'version' => 'dev-master',
18
  'aliases' =>
19
  array (
20
  ),
21
- 'reference' => 'adf8041d1672126bd45b71ae1d70742cfeae7aa8',
22
  ),
23
  ),
24
  );
1
  <?php return array (
2
  'root' =>
3
  array (
4
+ 'pretty_version' => '5.4.0',
5
+ 'version' => '5.4.0.0',
6
  'aliases' =>
7
  array (
8
  ),
9
+ 'reference' => 'e37337253ce0f37ca9129706f21c556b5b8b5d15',
10
  'name' => '__root__',
11
  ),
12
  'versions' =>
13
  array (
14
  '__root__' =>
15
  array (
16
+ 'pretty_version' => '5.4.0',
17
+ 'version' => '5.4.0.0',
18
  'aliases' =>
19
  array (
20
  ),
21
+ 'reference' => 'e37337253ce0f37ca9129706f21c556b5b8b5d15',
22
  ),
23
  ),
24
  );