Social Share Icons & Social Share Buttons - Version 3.2.1

Version Description

  • Update: Feedback system updated
Download this release

Release Info

Developer socialdude
Plugin Icon 128x128 Social Share Icons & Social Share Buttons
Version 3.2.1
Comparing to
See all releases

Code changes from version 3.2.0 to 3.2.1

Files changed (49) hide show
  1. analyst/{analyst/assets → assets}/css/customize.css +280 -280
  2. analyst/{analyst/assets → assets}/img/pencil.png +0 -0
  3. analyst/{analyst/assets → assets}/img/shield_question.png +0 -0
  4. analyst/{analyst/assets → assets}/img/shield_success.png +0 -0
  5. analyst/{analyst/assets → assets}/img/smile.png +0 -0
  6. analyst/{analyst/assets → assets}/index.php +2 -2
  7. analyst/{analyst/assets → assets}/js/customize.js +29 -29
  8. analyst/{analyst/autoload.php → autoload.php} +40 -40
  9. analyst/{analyst/index.php → index.php} +2 -2
  10. analyst/{analyst/main.php → main.php} +36 -36
  11. analyst/{analyst/sdk_resolver.php → sdk_resolver.php} +79 -79
  12. analyst/{analyst/src → src}/Account/Account.php +606 -606
  13. analyst/{analyst/src → src}/Account/AccountData.php +176 -176
  14. analyst/{analyst/src → src}/Account/AccountDataFactory.php +125 -125
  15. analyst/{analyst/src → src}/Analyst.php +167 -167
  16. analyst/{analyst/src → src}/ApiRequestor.php +257 -257
  17. analyst/{analyst/src → src}/ApiResponse.php +44 -44
  18. analyst/{analyst/src → src}/Cache/DatabaseCache.php +127 -127
  19. analyst/{analyst/src → src}/Collector.php +217 -217
  20. analyst/{analyst/src → src}/Contracts/AnalystContract.php +12 -12
  21. analyst/{analyst/src → src}/Contracts/CacheContract.php +47 -47
  22. analyst/{analyst/src → src}/Contracts/HttpClientContract.php +25 -25
  23. analyst/{analyst/src → src}/Contracts/RequestContract.php +22 -22
  24. analyst/{analyst/src → src}/Contracts/RequestorContract.php +44 -44
  25. analyst/{analyst/src → src}/Contracts/TrackerContract.php +69 -69
  26. analyst/{analyst/src → src}/Core/AbstractFactory.php +27 -27
  27. analyst/{analyst/src → src}/Http/CurlHttpClient.php +102 -102
  28. analyst/{analyst/src → src}/Http/DummyHttpClient.php +33 -33
  29. analyst/{analyst/src → src}/Http/Requests/AbstractLoggerRequest.php +64 -64
  30. analyst/{analyst/src → src}/Http/Requests/ActivateRequest.php +42 -42
  31. analyst/{analyst/src → src}/Http/Requests/DeactivateRequest.php +64 -64
  32. analyst/{analyst/src → src}/Http/Requests/InstallRequest.php +38 -38
  33. analyst/{analyst/src → src}/Http/Requests/OptInRequest.php +42 -42
  34. analyst/{analyst/src → src}/Http/Requests/OptOutRequest.php +40 -40
  35. analyst/{analyst/src → src}/Http/Requests/UninstallRequest.php +36 -36
  36. analyst/{analyst/src → src}/Http/WordPressHttpClient.php +61 -61
  37. analyst/{analyst/src → src}/Mutator.php +103 -103
  38. analyst/{analyst/src → src}/Notices/Notice.php +121 -121
  39. analyst/{analyst/src → src}/Notices/NoticeFactory.php +130 -130
  40. analyst/{analyst/src → src}/helpers.php +84 -84
  41. analyst/{analyst/templates → templates}/forms/deactivate.php +156 -156
  42. analyst/{analyst/templates → templates}/forms/install.php +110 -110
  43. analyst/{analyst/templates → templates}/notice.php +10 -10
  44. analyst/{analyst/templates → templates}/optin.php +60 -60
  45. analyst/{analyst/templates → templates}/optout.php +109 -109
  46. analyst/{analyst/version.php → version.php} +15 -15
  47. libs/sfsi_install_uninstall.php +1 -1
  48. readme.txt +5 -2
  49. ultimate_social_media_icons.php +2 -2
analyst/{analyst/assets → assets}/css/customize.css RENAMED
@@ -1,280 +1,280 @@
1
- .analyst-action-opt {
2
- cursor: pointer;
3
- }
4
-
5
- .analyst-modal {
6
- color: #000000;
7
- display: none;
8
- position: fixed;
9
- z-index: 1000;
10
- padding-top: 100px;
11
- left: 0;
12
- top: 0;
13
- width: 100%;
14
- height: 100%;
15
- overflow: auto;
16
- background-color: rgb(0,0,0);
17
- background-color: rgba(0,0,0,0.4);
18
- }
19
-
20
- .analyst-modal-content {
21
- font-family: Helvetica, serif;
22
- position: relative;
23
- background-color: #fefefe;
24
- margin: auto;
25
- padding: 35px 35px 20px;
26
- border: 1px solid #F2F2F2;
27
- width: 40%;
28
- box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
29
- -webkit-animation-name: analyst-animatetop;
30
- -webkit-animation-duration: 0.4s;
31
- animation-name: analyst-animatetop;
32
- animation-duration: 0.4s
33
- }
34
-
35
- .analyst-btn-success {
36
- cursor: pointer;
37
- color: #ffffff;
38
- background-color: #00AF5E;
39
- border: none;
40
- width: 100%;
41
- font-size: 18px;
42
- padding: 8px;
43
- font-weight: bold;
44
- }
45
-
46
- .analyst-btn-grey {
47
- cursor: pointer;
48
- color: #2D2D2D;
49
- background-color: #D8D8D8;
50
- border: none;
51
- width: 100%;
52
- font-size: 18px;
53
- padding: 8px;
54
- font-weight: bold;
55
- }
56
-
57
- .analyst-btn-secondary-ghost {
58
- cursor: pointer;
59
- background: transparent;
60
- border: none;
61
- color: #898686;
62
- font-size: 18px;
63
- }
64
-
65
- .analyst-modal-def-top-padding {
66
- padding-top: 20px;
67
- }
68
-
69
- .analyst-modal-header {
70
- font-size: 20px;
71
- font-weight: bold;
72
- }
73
-
74
- /*INSTALL STYLES*/
75
- .analyst-install-footer {
76
- padding-top: 10px;
77
- text-align: center;
78
- }
79
-
80
- .analyst-install-image-block {
81
- width: 140px;
82
- }
83
-
84
- .analyst-install-image-block img {
85
- width: inherit;
86
- }
87
-
88
- .analyst-install-description-block {
89
- padding-left: 40px;
90
- padding-top: 5px
91
- }
92
-
93
- .analyst-install-description-text {
94
- font-size: 16px;
95
- color: #000000;
96
- }
97
-
98
- .analyst-install-permissions-list {
99
- list-style: disc inside;
100
- }
101
-
102
- .analyst-install-permissions-list li {
103
- padding-left: 15px;
104
- margin-bottom: 2px;
105
- }
106
-
107
- .analyst-install-footer span {
108
- color: #8a8787;
109
- padding-right: 10px;
110
- padding-left: 10px;
111
- }
112
-
113
- .analyst-install-footer span:not(:last-child) {
114
- border-right: 1px solid #8a8787;
115
- }
116
-
117
- /*INSTALL STYLES*/
118
-
119
- .reason-answer {
120
- padding: 7px;
121
- margin-left: 23px;
122
- border: 1px solid #F2F2F2;
123
- }
124
-
125
- .analyst-link {
126
- color: #00AF5E;
127
- text-decoration: none;
128
- }
129
-
130
- .analyst-action-text {
131
- cursor: pointer;
132
- }
133
-
134
- .analyst-action-text:hover {
135
- color: #9d9a9a;
136
- }
137
-
138
- .analyst-disable-modal-mask {
139
- width: 100%;
140
- height: 100%;
141
- opacity: 0.5;
142
- position: absolute;
143
- background: white;
144
- top: 0;
145
- left: 0;
146
- }
147
-
148
- .analyst-smile-image {
149
- vertical-align: middle;
150
- padding-bottom: 3px;
151
- width: 24px;
152
- }
153
-
154
- #analyst-deactivation-reasons li {
155
- padding-bottom: 3px;
156
- font-size: 16px;
157
- color: #000000;
158
- }
159
-
160
- @-webkit-keyframes analyst-animatetop {
161
- from {top:-300px; opacity:0}
162
- to {top:0; opacity:1}
163
- }
164
-
165
- @keyframes analyst-animatetop {
166
- from {top:-300px; opacity:0}
167
- to {top:0; opacity:1}
168
- }
169
-
170
- .analyst-modal-close {
171
- color: #48036F;
172
- font-size: 28px;
173
- font-weight: bold;
174
- top: 12px;
175
- position: absolute;
176
- right: 15px;
177
- }
178
-
179
- .analyst-modal-close:hover,
180
- .analyst-modal-close:focus {
181
- color: #000;
182
- text-decoration: none;
183
- cursor: pointer;
184
- }
185
-
186
- .analyst-modal-body {padding: 2px 16px;}
187
-
188
- .analyst-modal-footer {
189
- padding: 6px 16px;
190
- background-color: #FFE773;
191
- color: white;
192
- }
193
-
194
- #analyst-deactivate-modal .question-answer input, textarea {
195
- margin-top: 5px;
196
- width: 100%;
197
- }
198
-
199
- .analyst-btn-primary {
200
- cursor: pointer;
201
- border: none;
202
- display:inline-block;
203
- padding:0.7em 1.4em;
204
- margin:0 0.3em 0.3em 0;
205
- border-radius:0.15em;
206
- box-sizing: border-box;
207
- text-decoration:none;
208
- font-family:'Roboto',sans-serif;
209
- text-transform:uppercase;
210
- font-weight:400;
211
- color:#FFFFFF;
212
- background-color:#9F3ED5;
213
- box-shadow:inset 0 -0.6em 0 -0.35em rgba(0,0,0,0.17);
214
- text-align:center;
215
- position:relative;
216
- }
217
-
218
- .analyst-btn-primary:disabled {
219
- background-color: #AD66D5;
220
- cursor: not-allowed;
221
- }
222
-
223
- .analyst-btn-primary:active{
224
- top:0.1em;
225
- }
226
- @media all and (max-width:30em){
227
- .analyst-btn-primary {
228
- display:block;
229
- margin:0.4em auto;
230
- }
231
- }
232
-
233
- .analyst-btn-secondary {
234
- cursor: pointer;
235
- border: none;
236
- display:inline-block;
237
- padding:0.7em 1.4em;
238
- margin:0 0.3em 0.3em 0;
239
- border-radius:0.15em;
240
- box-sizing: border-box;
241
- text-decoration:none;
242
- font-family:'Roboto',sans-serif;
243
- text-transform:uppercase;
244
- font-weight:400;
245
- color:#FFFFFF;
246
- background-color:#6C8CD5;
247
- box-shadow:inset 0 -0.6em 0 -0.35em rgba(0,0,0,0.17);
248
- text-align:center;
249
- position:relative;
250
- }
251
-
252
- .analyst-btn-secondary:disabled {
253
- background-color: #6C8CD5;
254
- cursor: not-allowed;
255
- }
256
-
257
- .analyst-btn-secondary:active{
258
- top:0.1em;
259
- }
260
- @media all and (max-width:30em){
261
- .analyst-btn-secondary {
262
- display:block;
263
- margin:0.4em auto;
264
- }
265
- }
266
-
267
- .analyst-notice {
268
- padding-right: 38px;
269
- position: relative;
270
- margin-bottom: 30px !important;
271
- }
272
-
273
- .analyst-notice .analyst-plugin-name {
274
- background-color: #00000024;
275
- padding-left: 7px;
276
- padding-right: 7px;
277
- position: absolute;
278
- top: 100%;
279
- border-radius: 0 0 5px 5px;
280
- }
1
+ .analyst-action-opt {
2
+ cursor: pointer;
3
+ }
4
+
5
+ .analyst-modal {
6
+ color: #000000;
7
+ display: none;
8
+ position: fixed;
9
+ z-index: 1000;
10
+ padding-top: 100px;
11
+ left: 0;
12
+ top: 0;
13
+ width: 100%;
14
+ height: 100%;
15
+ overflow: auto;
16
+ background-color: rgb(0,0,0);
17
+ background-color: rgba(0,0,0,0.4);
18
+ }
19
+
20
+ .analyst-modal-content {
21
+ font-family: Helvetica, serif;
22
+ position: relative;
23
+ background-color: #fefefe;
24
+ margin: auto;
25
+ padding: 35px 35px 20px;
26
+ border: 1px solid #F2F2F2;
27
+ width: 40%;
28
+ box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
29
+ -webkit-animation-name: analyst-animatetop;
30
+ -webkit-animation-duration: 0.4s;
31
+ animation-name: analyst-animatetop;
32
+ animation-duration: 0.4s
33
+ }
34
+
35
+ .analyst-btn-success {
36
+ cursor: pointer;
37
+ color: #ffffff;
38
+ background-color: #00AF5E;
39
+ border: none;
40
+ width: 100%;
41
+ font-size: 18px;
42
+ padding: 8px;
43
+ font-weight: bold;
44
+ }
45
+
46
+ .analyst-btn-grey {
47
+ cursor: pointer;
48
+ color: #2D2D2D;
49
+ background-color: #D8D8D8;
50
+ border: none;
51
+ width: 100%;
52
+ font-size: 18px;
53
+ padding: 8px;
54
+ font-weight: bold;
55
+ }
56
+
57
+ .analyst-btn-secondary-ghost {
58
+ cursor: pointer;
59
+ background: transparent;
60
+ border: none;
61
+ color: #898686;
62
+ font-size: 18px;
63
+ }
64
+
65
+ .analyst-modal-def-top-padding {
66
+ padding-top: 20px;
67
+ }
68
+
69
+ .analyst-modal-header {
70
+ font-size: 20px;
71
+ font-weight: bold;
72
+ }
73
+
74
+ /*INSTALL STYLES*/
75
+ .analyst-install-footer {
76
+ padding-top: 10px;
77
+ text-align: center;
78
+ }
79
+
80
+ .analyst-install-image-block {
81
+ width: 140px;
82
+ }
83
+
84
+ .analyst-install-image-block img {
85
+ width: inherit;
86
+ }
87
+
88
+ .analyst-install-description-block {
89
+ padding-left: 40px;
90
+ padding-top: 5px
91
+ }
92
+
93
+ .analyst-install-description-text {
94
+ font-size: 16px;
95
+ color: #000000;
96
+ }
97
+
98
+ .analyst-install-permissions-list {
99
+ list-style: disc inside;
100
+ }
101
+
102
+ .analyst-install-permissions-list li {
103
+ padding-left: 15px;
104
+ margin-bottom: 2px;
105
+ }
106
+
107
+ .analyst-install-footer span {
108
+ color: #8a8787;
109
+ padding-right: 10px;
110
+ padding-left: 10px;
111
+ }
112
+
113
+ .analyst-install-footer span:not(:last-child) {
114
+ border-right: 1px solid #8a8787;
115
+ }
116
+
117
+ /*INSTALL STYLES*/
118
+
119
+ .reason-answer {
120
+ padding: 7px;
121
+ margin-left: 23px;
122
+ border: 1px solid #F2F2F2;
123
+ }
124
+
125
+ .analyst-link {
126
+ color: #00AF5E;
127
+ text-decoration: none;
128
+ }
129
+
130
+ .analyst-action-text {
131
+ cursor: pointer;
132
+ }
133
+
134
+ .analyst-action-text:hover {
135
+ color: #9d9a9a;
136
+ }
137
+
138
+ .analyst-disable-modal-mask {
139
+ width: 100%;
140
+ height: 100%;
141
+ opacity: 0.5;
142
+ position: absolute;
143
+ background: white;
144
+ top: 0;
145
+ left: 0;
146
+ }
147
+
148
+ .analyst-smile-image {
149
+ vertical-align: middle;
150
+ padding-bottom: 3px;
151
+ width: 24px;
152
+ }
153
+
154
+ #analyst-deactivation-reasons li {
155
+ padding-bottom: 3px;
156
+ font-size: 16px;
157
+ color: #000000;
158
+ }
159
+
160
+ @-webkit-keyframes analyst-animatetop {
161
+ from {top:-300px; opacity:0}
162
+ to {top:0; opacity:1}
163
+ }
164
+
165
+ @keyframes analyst-animatetop {
166
+ from {top:-300px; opacity:0}
167
+ to {top:0; opacity:1}
168
+ }
169
+
170
+ .analyst-modal-close {
171
+ color: #48036F;
172
+ font-size: 28px;
173
+ font-weight: bold;
174
+ top: 12px;
175
+ position: absolute;
176
+ right: 15px;
177
+ }
178
+
179
+ .analyst-modal-close:hover,
180
+ .analyst-modal-close:focus {
181
+ color: #000;
182
+ text-decoration: none;
183
+ cursor: pointer;
184
+ }
185
+
186
+ .analyst-modal-body {padding: 2px 16px;}
187
+
188
+ .analyst-modal-footer {
189
+ padding: 6px 16px;
190
+ background-color: #FFE773;
191
+ color: white;
192
+ }
193
+
194
+ #analyst-deactivate-modal .question-answer input, textarea {
195
+ margin-top: 5px;
196
+ width: 100%;
197
+ }
198
+
199
+ .analyst-btn-primary {
200
+ cursor: pointer;
201
+ border: none;
202
+ display:inline-block;
203
+ padding:0.7em 1.4em;
204
+ margin:0 0.3em 0.3em 0;
205
+ border-radius:0.15em;
206
+ box-sizing: border-box;
207
+ text-decoration:none;
208
+ font-family:'Roboto',sans-serif;
209
+ text-transform:uppercase;
210
+ font-weight:400;
211
+ color:#FFFFFF;
212
+ background-color:#9F3ED5;
213
+ box-shadow:inset 0 -0.6em 0 -0.35em rgba(0,0,0,0.17);
214
+ text-align:center;
215
+ position:relative;
216
+ }
217
+
218
+ .analyst-btn-primary:disabled {
219
+ background-color: #AD66D5;
220
+ cursor: not-allowed;
221
+ }
222
+
223
+ .analyst-btn-primary:active{
224
+ top:0.1em;
225
+ }
226
+ @media all and (max-width:30em){
227
+ .analyst-btn-primary {
228
+ display:block;
229
+ margin:0.4em auto;
230
+ }
231
+ }
232
+
233
+ .analyst-btn-secondary {
234
+ cursor: pointer;
235
+ border: none;
236
+ display:inline-block;
237
+ padding:0.7em 1.4em;
238
+ margin:0 0.3em 0.3em 0;
239
+ border-radius:0.15em;
240
+ box-sizing: border-box;
241
+ text-decoration:none;
242
+ font-family:'Roboto',sans-serif;
243
+ text-transform:uppercase;
244
+ font-weight:400;
245
+ color:#FFFFFF;
246
+ background-color:#6C8CD5;
247
+ box-shadow:inset 0 -0.6em 0 -0.35em rgba(0,0,0,0.17);
248
+ text-align:center;
249
+ position:relative;
250
+ }
251
+
252
+ .analyst-btn-secondary:disabled {
253
+ background-color: #6C8CD5;
254
+ cursor: not-allowed;
255
+ }
256
+
257
+ .analyst-btn-secondary:active{
258
+ top:0.1em;
259
+ }
260
+ @media all and (max-width:30em){
261
+ .analyst-btn-secondary {
262
+ display:block;
263
+ margin:0.4em auto;
264
+ }
265
+ }
266
+
267
+ .analyst-notice {
268
+ padding-right: 38px;
269
+ position: relative;
270
+ margin-bottom: 30px !important;
271
+ }
272
+
273
+ .analyst-notice .analyst-plugin-name {
274
+ background-color: #00000024;
275
+ padding-left: 7px;
276
+ padding-right: 7px;
277
+ position: absolute;
278
+ top: 100%;
279
+ border-radius: 0 0 5px 5px;
280
+ }
analyst/{analyst/assets → assets}/img/pencil.png RENAMED
File without changes
analyst/{analyst/assets → assets}/img/shield_question.png RENAMED
File without changes
analyst/{analyst/assets → assets}/img/shield_success.png RENAMED
File without changes
analyst/{analyst/assets → assets}/img/smile.png RENAMED
File without changes
analyst/{analyst/assets → assets}/index.php RENAMED
@@ -1,2 +1,2 @@
1
- <?php
2
- // Silence is golden.
1
+ <?php
2
+ // Silence is golden.
analyst/{analyst/assets → assets}/js/customize.js RENAMED
@@ -1,29 +1,29 @@
1
- (function ($) {
2
- $(document).on('click', '.analyst-notice-dismiss', function () {
3
- var id = $(this).attr('analyst-notice-id');
4
- var self = this;
5
-
6
- $.post(ajaxurl, {action: 'analyst_notification_dismiss', id: id})
7
- .done(function () {
8
- $(self).parent().fadeOut()
9
- })
10
- })
11
-
12
- var url = new URL(window.location.href)
13
-
14
- if (url.searchParams.has('verify')) {
15
- var pluginId = url.searchParams.get('plugin_id')
16
-
17
- $.ajax({
18
- url: ajaxurl,
19
- method: 'POST',
20
- data: {
21
- action: 'analyst_install_verified_' + pluginId,
22
- },
23
- success: function () {
24
- // Refresh page without query params
25
- window.location.href = window.location.origin + window.location.pathname
26
- }
27
- })
28
- }
29
- })(jQuery)
1
+ (function ($) {
2
+ $(document).on('click', '.analyst-notice-dismiss', function () {
3
+ var id = $(this).attr('analyst-notice-id');
4
+ var self = this;
5
+
6
+ $.post(ajaxurl, {action: 'analyst_notification_dismiss', id: id})
7
+ .done(function () {
8
+ $(self).parent().fadeOut()
9
+ })
10
+ })
11
+
12
+ var url = new URL(window.location.href)
13
+
14
+ if (url.searchParams.has('verify')) {
15
+ var pluginId = url.searchParams.get('plugin_id')
16
+
17
+ $.ajax({
18
+ url: ajaxurl,
19
+ method: 'POST',
20
+ data: {
21
+ action: 'analyst_install_verified_' + pluginId,
22
+ },
23
+ success: function () {
24
+ // Refresh page without query params
25
+ window.location.href = window.location.origin + window.location.pathname
26
+ }
27
+ })
28
+ }
29
+ })(jQuery)
analyst/{analyst/autoload.php → autoload.php} RENAMED
@@ -1,40 +1,40 @@
1
- <?php
2
-
3
- require_once __DIR__ . '/src/helpers.php';
4
-
5
- require_once __DIR__ . '/src/Contracts/HttpClientContract.php';
6
- require_once __DIR__ . '/src/Contracts/RequestContract.php';
7
- require_once __DIR__ . '/src/Contracts/RequestorContract.php';
8
- require_once __DIR__ . '/src/Contracts/TrackerContract.php';
9
- require_once __DIR__ . '/src/Contracts/CacheContract.php';
10
-
11
- require_once __DIR__ . '/src/Core/AbstractFactory.php';
12
-
13
- require_once __DIR__ . '/src/Cache/DatabaseCache.php';
14
-
15
- require_once __DIR__ . '/src/Account/Account.php';
16
- require_once __DIR__ . '/src/Account/AccountData.php';
17
- require_once __DIR__ . '/src/Account/AccountDataFactory.php';
18
- require_once __DIR__ . '/src/Contracts/AnalystContract.php';
19
-
20
- require_once __DIR__ . '/src/Http/Requests/AbstractLoggerRequest.php';
21
- require_once __DIR__ . '/src/Http/Requests/ActivateRequest.php';
22
- require_once __DIR__ . '/src/Http/Requests/DeactivateRequest.php';
23
- require_once __DIR__ . '/src/Http/Requests/InstallRequest.php';
24
- require_once __DIR__ . '/src/Http/Requests/OptInRequest.php';
25
- require_once __DIR__ . '/src/Http/Requests/OptOutRequest.php';
26
- require_once __DIR__ . '/src/Http/Requests/UninstallRequest.php';
27
-
28
- require_once __DIR__ . '/src/Http/CurlHttpClient.php';
29
- require_once __DIR__ . '/src/Http/DummyHttpClient.php';
30
- require_once __DIR__ . '/src/Http/WordPressHttpClient.php';
31
-
32
- require_once __DIR__ . '/src/Notices/Notice.php';
33
- require_once __DIR__ . '/src/Notices/NoticeFactory.php';
34
-
35
- require_once __DIR__ . '/src/Analyst.php';
36
- require_once __DIR__ . '/src/ApiRequestor.php';
37
- require_once __DIR__ . '/src/ApiResponse.php';
38
- require_once __DIR__ . '/src/Collector.php';
39
- require_once __DIR__ . '/src/Mutator.php';
40
-
1
+ <?php
2
+
3
+ require_once __DIR__ . '/src/helpers.php';
4
+
5
+ require_once __DIR__ . '/src/Contracts/HttpClientContract.php';
6
+ require_once __DIR__ . '/src/Contracts/RequestContract.php';
7
+ require_once __DIR__ . '/src/Contracts/RequestorContract.php';
8
+ require_once __DIR__ . '/src/Contracts/TrackerContract.php';
9
+ require_once __DIR__ . '/src/Contracts/CacheContract.php';
10
+
11
+ require_once __DIR__ . '/src/Core/AbstractFactory.php';
12
+
13
+ require_once __DIR__ . '/src/Cache/DatabaseCache.php';
14
+
15
+ require_once __DIR__ . '/src/Account/Account.php';
16
+ require_once __DIR__ . '/src/Account/AccountData.php';
17
+ require_once __DIR__ . '/src/Account/AccountDataFactory.php';
18
+ require_once __DIR__ . '/src/Contracts/AnalystContract.php';
19
+
20
+ require_once __DIR__ . '/src/Http/Requests/AbstractLoggerRequest.php';
21
+ require_once __DIR__ . '/src/Http/Requests/ActivateRequest.php';
22
+ require_once __DIR__ . '/src/Http/Requests/DeactivateRequest.php';
23
+ require_once __DIR__ . '/src/Http/Requests/InstallRequest.php';
24
+ require_once __DIR__ . '/src/Http/Requests/OptInRequest.php';
25
+ require_once __DIR__ . '/src/Http/Requests/OptOutRequest.php';
26
+ require_once __DIR__ . '/src/Http/Requests/UninstallRequest.php';
27
+
28
+ require_once __DIR__ . '/src/Http/CurlHttpClient.php';
29
+ require_once __DIR__ . '/src/Http/DummyHttpClient.php';
30
+ require_once __DIR__ . '/src/Http/WordPressHttpClient.php';
31
+
32
+ require_once __DIR__ . '/src/Notices/Notice.php';
33
+ require_once __DIR__ . '/src/Notices/NoticeFactory.php';
34
+
35
+ require_once __DIR__ . '/src/Analyst.php';
36
+ require_once __DIR__ . '/src/ApiRequestor.php';
37
+ require_once __DIR__ . '/src/ApiResponse.php';
38
+ require_once __DIR__ . '/src/Collector.php';
39
+ require_once __DIR__ . '/src/Mutator.php';
40
+
analyst/{analyst/index.php → index.php} RENAMED
@@ -1,2 +1,2 @@
1
- <?php
2
- // Silence
1
+ <?php
2
+ // Silence
analyst/{analyst/main.php → main.php} RENAMED
@@ -1,36 +1,36 @@
1
- <?php
2
-
3
- require_once 'sdk_resolver.php';
4
-
5
-
6
- if (!function_exists('analyst_init')) {
7
- /**
8
- * Initialize analyst
9
- *
10
- * @param array $options
11
- */
12
- function analyst_init ($options) {
13
- // Try resolve latest supported SDK
14
- // In case resolving is failed exit the execution
15
- try {
16
- analyst_resolve_sdk($options['base-dir']);
17
- } catch (Exception $exception) {
18
- error_log('[ANALYST] Cannot resolve any supported SDK');
19
- return;
20
- }
21
-
22
- try {
23
- global /** @var Analyst\Analyst $analyst */
24
- $analyst;
25
-
26
- // Set global instance of analyst
27
- if (!$analyst) {
28
- $analyst = Analyst\Analyst::getInstance();
29
- }
30
-
31
- $analyst->registerAccount(new Account\Account($options['client-id'], $options['client-secret'], $options['base-dir']));
32
- } catch (Exception $e) {
33
- error_log('Analyst SDK receive an error: [' . $e->getMessage() . '] Please contact our support at support@analyst.com');
34
- }
35
- }
36
- }
1
+ <?php
2
+
3
+ require_once 'sdk_resolver.php';
4
+
5
+
6
+ if (!function_exists('analyst_init')) {
7
+ /**
8
+ * Initialize analyst
9
+ *
10
+ * @param array $options
11
+ */
12
+ function analyst_init ($options) {
13
+ // Try resolve latest supported SDK
14
+ // In case resolving is failed exit the execution
15
+ try {
16
+ analyst_resolve_sdk($options['base-dir']);
17
+ } catch (Exception $exception) {
18
+ error_log('[ANALYST] Cannot resolve any supported SDK');
19
+ return;
20
+ }
21
+
22
+ try {
23
+ global /** @var Analyst\Analyst $analyst */
24
+ $analyst;
25
+
26
+ // Set global instance of analyst
27
+ if (!$analyst) {
28
+ $analyst = Analyst\Analyst::getInstance();
29
+ }
30
+
31
+ $analyst->registerAccount(new Account\Account($options['client-id'], $options['client-secret'], $options['base-dir']));
32
+ } catch (Exception $e) {
33
+ error_log('Analyst SDK receive an error: [' . $e->getMessage() . '] Please contact our support at support@analyst.com');
34
+ }
35
+ }
36
+ }
analyst/{analyst/sdk_resolver.php → sdk_resolver.php} RENAMED
@@ -1,79 +1,79 @@
1
- <?php
2
-
3
- if (!function_exists('analyst_resolve_sdk')) {
4
-
5
- /**
6
- * Resolve supported sdk versions and load latest supported one
7
- * also bootstrap sdk with autoloader
8
- *
9
- * @since 1.1.3
10
- *
11
- * @param null $thisPluginPath
12
- * @return void
13
- * @throws Exception
14
- */
15
- function analyst_resolve_sdk($thisPluginPath = null) {
16
- static $loaded = false;
17
-
18
- // Exit if we already resolved SDK
19
- if ($loaded) return;
20
-
21
- $plugins = get_option('active_plugins');
22
-
23
- if ($thisPluginPath) {
24
- array_push($plugins, plugin_basename($thisPluginPath));
25
- }
26
-
27
- $pluginsFolder = ABSPATH . 'wp-content/plugins';
28
-
29
- $possibleSDKs = array_map(function ($path) use ($pluginsFolder) {
30
- $sdkFolder = sprintf('%s/%s/analyst/', $pluginsFolder, dirname($path));
31
-
32
- $sdkFolder = str_replace('\\', '/', $sdkFolder);
33
-
34
- $versionPath = $sdkFolder . 'version.php';
35
-
36
- if (file_exists($versionPath)) {
37
- return require $versionPath;
38
- }
39
-
40
- return false;
41
- }, $plugins);
42
-
43
- global $wp_version;
44
-
45
- // Filter out plugins which has no SDK
46
- $SDKs = array_filter($possibleSDKs, function ($s) {return is_array($s);});
47
-
48
- // Filter SDKs which is supported by PHP and WP
49
- $supported = array_values(array_filter($SDKs, function ($sdk) use($wp_version) {
50
- $phpSupported = version_compare(PHP_VERSION, $sdk['php']) >= 0;
51
- $wpSupported = version_compare($wp_version, $sdk['wp']) >= 0;
52
-
53
- return $phpSupported && $wpSupported;
54
- }));
55
-
56
- // Sort SDK by version in descending order
57
- uasort($supported, function ($x, $y) {
58
- return version_compare($y['sdk'], $x['sdk']);
59
- });
60
-
61
- // Reset sorted values keys
62
- $supported = array_values($supported);
63
-
64
- if (!isset($supported[0])) {
65
- throw new Exception('There is no SDK which is support current PHP version and WP version');
66
- }
67
-
68
- // Autoload files for supported SDK
69
- $autoloaderPath = str_replace(
70
- '\\',
71
- '/',
72
- sprintf('%s/autoload.php', $supported[0]['path'])
73
- );
74
-
75
- require_once $autoloaderPath;
76
-
77
- $loaded = true;
78
- }
79
- }
1
+ <?php
2
+
3
+ if (!function_exists('analyst_resolve_sdk')) {
4
+
5
+ /**
6
+ * Resolve supported sdk versions and load latest supported one
7
+ * also bootstrap sdk with autoloader
8
+ *
9
+ * @since 1.1.3
10
+ *
11
+ * @param null $thisPluginPath
12
+ * @return void
13
+ * @throws Exception
14
+ */
15
+ function analyst_resolve_sdk($thisPluginPath = null) {
16
+ static $loaded = false;
17
+
18
+ // Exit if we already resolved SDK
19
+ if ($loaded) return;
20
+
21
+ $plugins = get_option('active_plugins');
22
+
23
+ if ($thisPluginPath) {
24
+ array_push($plugins, plugin_basename($thisPluginPath));
25
+ }
26
+
27
+ $pluginsFolder = ABSPATH . 'wp-content/plugins';
28
+
29
+ $possibleSDKs = array_map(function ($path) use ($pluginsFolder) {
30
+ $sdkFolder = sprintf('%s/%s/analyst/', $pluginsFolder, dirname($path));
31
+
32
+ $sdkFolder = str_replace('\\', '/', $sdkFolder);
33
+
34
+ $versionPath = $sdkFolder . 'version.php';
35
+
36
+ if (file_exists($versionPath)) {
37
+ return require $versionPath;
38
+ }
39
+
40
+ return false;
41
+ }, $plugins);
42
+
43
+ global $wp_version;
44
+
45
+ // Filter out plugins which has no SDK
46
+ $SDKs = array_filter($possibleSDKs, function ($s) {return is_array($s);});
47
+
48
+ // Filter SDKs which is supported by PHP and WP
49
+ $supported = array_values(array_filter($SDKs, function ($sdk) use($wp_version) {
50
+ $phpSupported = version_compare(PHP_VERSION, $sdk['php']) >= 0;
51
+ $wpSupported = version_compare($wp_version, $sdk['wp']) >= 0;
52
+
53
+ return $phpSupported && $wpSupported;
54
+ }));
55
+
56
+ // Sort SDK by version in descending order
57
+ uasort($supported, function ($x, $y) {
58
+ return version_compare($y['sdk'], $x['sdk']);
59
+ });
60
+
61
+ // Reset sorted values keys
62
+ $supported = array_values($supported);
63
+
64
+ if (!isset($supported[0])) {
65
+ throw new Exception('There is no SDK which is support current PHP version and WP version');
66
+ }
67
+
68
+ // Autoload files for supported SDK
69
+ $autoloaderPath = str_replace(
70
+ '\\',
71
+ '/',
72
+ sprintf('%s/autoload.php', $supported[0]['path'])
73
+ );
74
+
75
+ require_once $autoloaderPath;
76
+
77
+ $loaded = true;
78
+ }
79
+ }
analyst/{analyst/src → src}/Account/Account.php RENAMED
@@ -1,606 +1,606 @@
1
- <?php
2
-
3
- namespace Account;
4
-
5
- use Analyst\Analyst;
6
- use Analyst\ApiRequestor;
7
- use Analyst\Cache\DatabaseCache;
8
- use Analyst\Collector;
9
- use Analyst\Http\Requests\ActivateRequest;
10
- use Analyst\Http\Requests\DeactivateRequest;
11
- use Analyst\Http\Requests\InstallRequest;
12
- use Analyst\Http\Requests\OptInRequest;
13
- use Analyst\Http\Requests\OptOutRequest;
14
- use Analyst\Http\Requests\UninstallRequest;
15
- use Analyst\Notices\Notice;
16
- use Analyst\Notices\NoticeFactory;
17
- use Analyst\Contracts\TrackerContract;
18
- use Analyst\Contracts\RequestorContract;
19
-
20
- /**
21
- * Class Account
22
- *
23
- * This is plugin's account object
24
- */
25
- class Account implements TrackerContract
26
- {
27
- /**
28
- * Account id
29
- *
30
- * @var string
31
- */
32
- protected $id;
33
-
34
- /**
35
- * Basename of plugin
36
- *
37
- * @var string
38
- */
39
- protected $path;
40
-
41
- /**
42
- * Whether plugin is active or not
43
- *
44
- * @var bool
45
- */
46
- protected $isInstalled = false;
47
-
48
- /**
49
- * Is user sign in for data tracking
50
- *
51
- * @var bool
52
- */
53
- protected $isOptedIn = false;
54
-
55
- /**
56
- * Is user accepted permissions grant
57
- * for collection site data
58
- *
59
- * @var bool
60
- */
61
- protected $isSigned = false;
62
-
63
- /**
64
- * Is user ever resolved install modal window?
65
- *
66
- * @var bool
67
- */
68
- protected $isInstallResolved = false;
69
-
70
- /**
71
- * Public secret code
72
- *
73
- * @var string
74
- */
75
- protected $clientSecret;
76
-
77
- /**
78
- * @var AccountData
79
- */
80
- protected $data;
81
-
82
- /**
83
- * Base plugin path
84
- *
85
- * @var string
86
- */
87
- protected $basePluginPath;
88
-
89
- /**
90
- * @var RequestorContract
91
- */
92
- protected $requestor;
93
-
94
- /**
95
- * @var Collector
96
- */
97
- protected $collector;
98
-
99
- /**
100
- * Account constructor.
101
- * @param $id
102
- * @param $secret
103
- * @param $baseDir
104
- */
105
- public function __construct($id, $secret, $baseDir)
106
- {
107
- $this->id = $id;
108
- $this->clientSecret = $secret;
109
-
110
- $this->path = $baseDir;
111
-
112
- $this->basePluginPath = plugin_basename($baseDir);
113
- }
114
-
115
- /**
116
- * @return string
117
- */
118
- public function getPath()
119
- {
120
- return $this->path;
121
- }
122
-
123
- /**
124
- * @param string $path
125
- */
126
- public function setPath($path)
127
- {
128
- $this->data->setPath($path);
129
-
130
- $this->path = $path;
131
- }
132
-
133
- /**
134
- * @return bool
135
- */
136
- public function isOptedIn()
137
- {
138
- return $this->isOptedIn;
139
- }
140
-
141
- /**
142
- * @param bool $isOptedIn
143
- */
144
- public function setIsOptedIn($isOptedIn)
145
- {
146
- $this->data->setIsOptedIn($isOptedIn);
147
-
148
- $this->isOptedIn = $isOptedIn;
149
- }
150
-
151
- /**
152
- * Whether plugin is active
153
- *
154
- * @return bool
155
- */
156
- public function isActive()
157
- {
158
- return is_plugin_active($this->path);
159
- }
160
-
161
- /**
162
- * @param string $id
163
- */
164
- public function setId($id)
165
- {
166
- $this->id = $id;
167
- }
168
-
169
- /**
170
- * @return string
171
- */
172
- public function getId()
173
- {
174
- return $this->id;
175
- }
176
-
177
- /**
178
- * @return bool
179
- */
180
- public function isInstalled()
181
- {
182
- return $this->isInstalled;
183
- }
184
-
185
- /**
186
- * @param bool $isInstalled
187
- */
188
- public function setIsInstalled($isInstalled)
189
- {
190
- $this->data->setIsInstalled($isInstalled);
191
-
192
- $this->isInstalled = $isInstalled;
193
- }
194
-
195
- /**
196
- * Should register activation and deactivation
197
- * event hooks
198
- *
199
- * @return void
200
- */
201
- public function registerHooks()
202
- {
203
- register_activation_hook($this->basePluginPath, [&$this, 'onActivePluginListener']);
204
- register_uninstall_hook($this->basePluginPath, ['Account\Account', 'onUninstallPluginListener']);
205
-
206
- $this->addFilter('plugin_action_links', [&$this, 'onRenderActionLinksHook']);
207
-
208
- $this->addAjax('analyst_opt_in', [&$this, 'onOptInListener']);
209
- $this->addAjax('analyst_opt_out', [&$this, 'onOptOutListener']);
210
- $this->addAjax('analyst_plugin_deactivate', [&$this, 'onDeactivatePluginListener']);
211
- $this->addAjax('analyst_install', [&$this, 'onInstallListener']);
212
- $this->addAjax('analyst_skip_install', [&$this, 'onSkipInstallListener']);
213
- $this->addAjax('analyst_install_verified', [&$this, 'onInstallVerifiedListener']);
214
- }
215
-
216
- /**
217
- * Will fire when admin activates plugin
218
- *
219
- * @return void
220
- */
221
- public function onActivePluginListener()
222
- {
223
- if (!$this->isInstallResolved()) {
224
- DatabaseCache::getInstance()->put('plugin_to_install', $this->id);
225
- }
226
-
227
- if (!$this->isAllowingLogging()) return;
228
-
229
- ActivateRequest::make($this->collector, $this->id, $this->path)
230
- ->execute($this->requestor);
231
-
232
- $this->setIsInstalled(true);
233
-
234
- AccountDataFactory::syncData();
235
-
236
- wp_send_json_success();
237
- }
238
-
239
- /**
240
- * Will fire when admin deactivates plugin
241
- *
242
- * @return void
243
- */
244
- public function onDeactivatePluginListener()
245
- {
246
- if (!$this->isAllowingLogging()) return;
247
-
248
- $question = isset($_POST['question']) ? stripslashes($_POST['question']) : null;
249
- $reason = isset($_POST['reason']) ? stripslashes($_POST['reason']) : null;
250
-
251
- $response = DeactivateRequest::make($this->collector, $this->id, $this->path, $question, $reason)
252
- ->execute($this->requestor);
253
-
254
- // Exit if request failed
255
- if (!$response->isSuccess()) {
256
- wp_send_json_error($response->body);
257
- }
258
-
259
- $this->setIsInstalled(false);
260
-
261
- AccountDataFactory::syncData();
262
-
263
- wp_send_json_success();
264
- }
265
-
266
- /**
267
- * Will fire when user opted in
268
- *
269
- * @return void
270
- */
271
- public function onOptInListener()
272
- {
273
- $response = OptInRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
274
-
275
- // Exit if request failed
276
- if (!$response->isSuccess()) {
277
- wp_send_json_error($response->body);
278
- }
279
-
280
- $this->setIsOptedIn(true);
281
-
282
- AccountDataFactory::syncData();
283
-
284
- wp_die();
285
- }
286
-
287
- /**
288
- * Will fire when user opted out
289
- *
290
- * @return void
291
- */
292
- public function onOptOutListener()
293
- {
294
- $response = OptOutRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
295
-
296
- // Exit if request failed
297
- if (!$response->isSuccess()) {
298
- wp_send_json_error($response->body);
299
- }
300
-
301
- $this->setIsOptedIn(false);
302
-
303
- AccountDataFactory::syncData();
304
-
305
- wp_send_json_success();
306
- }
307
-
308
- /**
309
- * Will fire when user accept opt-in
310
- * at first time
311
- *
312
- * @return void
313
- */
314
- public function onInstallListener()
315
- {
316
- $cache = DatabaseCache::getInstance();
317
-
318
- // Set flag to true which indicates that install is resolved
319
- // also remove install plugin id from cache
320
- $this->setIsInstallResolved(true);
321
- $cache->delete('plugin_to_install');
322
-
323
- $response = InstallRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
324
-
325
- // Exit if request failed
326
- if (!$response->isSuccess()) {
327
- wp_send_json_error($response->body);
328
- }
329
-
330
- $this->setIsSigned(true);
331
-
332
- $this->setIsOptedIn(true);
333
-
334
- $factory = NoticeFactory::instance();
335
-
336
- $message = sprintf('Please confirm your email by clicking on the link we sent to %s. This makes sure you’re not a bot.', $this->collector->getGeneralEmailAddress());
337
-
338
- $notificationId = uniqid();
339
-
340
- $notice = Notice::make(
341
- $notificationId,
342
- $this->getId(),
343
- $message,
344
- $this->collector->getPluginName($this->path)
345
- );
346
-
347
- $factory->addNotice($notice);
348
-
349
- AccountDataFactory::syncData();
350
-
351
- // Set email confirmation notification id to cache
352
- // se we can extract and remove it when user confirmed email
353
- $cache->put(
354
- sprintf('account_email_confirmation_%s', $this->getId()),
355
- $notificationId
356
- );
357
-
358
- wp_send_json_success();
359
- }
360
-
361
- /**
362
- * Will fire when user skipped installation
363
- *
364
- * @return void
365
- */
366
- public function onSkipInstallListener()
367
- {
368
- // Set flag to true which indicates that install is resolved
369
- // also remove install plugin id from cache
370
- $this->setIsInstallResolved(true);
371
- DatabaseCache::getInstance()->delete('plugin_to_install');
372
- }
373
-
374
- /**
375
- * Will fire when user delete plugin through admin panel.
376
- * This action will happen if admin at least once
377
- * activated the plugin.
378
- *
379
- * @return void
380
- * @throws \Exception
381
- */
382
- public static function onUninstallPluginListener()
383
- {
384
- $factory = AccountDataFactory::instance();
385
-
386
- $pluginFile = substr(current_filter(), strlen( 'uninstall_' ));
387
-
388
- $account = $factory->getAccountDataByBasePath($pluginFile);
389
-
390
- // If account somehow is not found, exit the execution
391
- if (!$account) return;
392
-
393
- $analyst = Analyst::getInstance();
394
-
395
- $collector = new Collector($analyst);
396
-
397
- $requestor = new ApiRequestor($account->getId(), $account->getSecret(), $analyst->getApiBase());
398
-
399
- // Just send request to log uninstall event not caring about response
400
- UninstallRequest::make($collector, $account->getId(), $account->getPath())->execute($requestor);
401
-
402
- $factory->sync();
403
- }
404
-
405
- /**
406
- * Fires when used verified his account
407
- */
408
- public function onInstallVerifiedListener()
409
- {
410
- $factory = NoticeFactory::instance();
411
-
412
- $notice = Notice::make(
413
- uniqid(),
414
- $this->getId(),
415
- 'Thank you for confirming your email.',
416
- $this->collector->getPluginName($this->path)
417
- );
418
-
419
- $factory->addNotice($notice);
420
-
421
- // Remove confirmation notification
422
- $confirmationNotificationId = DatabaseCache::getInstance()->pop(sprintf('account_email_confirmation_%s', $this->getId()));
423
- $factory->remove($confirmationNotificationId);
424
-
425
- AccountDataFactory::syncData();
426
-
427
- wp_send_json_success();
428
- }
429
-
430
- /**
431
- * Will fire when wp renders plugin
432
- * action buttons
433
- *
434
- * @param $defaultLinks
435
- * @return array
436
- */
437
- public function onRenderActionLinksHook($defaultLinks)
438
- {
439
- $customLinks = [];
440
-
441
- $customLinks[] = $this->isOptedIn()
442
- ? '<a class="analyst-action-opt analyst-opt-out" analyst-plugin-id="' . $this->getId() . '" analyst-plugin-signed="' . (int) $this->isSigned() . '">Opt Out</a>'
443
- : '<a class="analyst-action-opt analyst-opt-in" analyst-plugin-id="' . $this->getId() . '" analyst-plugin-signed="' . (int) $this->isSigned() . '">Opt In</a>';
444
-
445
- // Append anchor to find specific deactivation link
446
- if (isset($defaultLinks['deactivate'])) {
447
- $defaultLinks['deactivate'] .= '<span analyst-plugin-id="' . $this->getId() . '" analyst-plugin-opted-in="' . (int) $this->isOptedIn() . '"></span>';
448
- }
449
-
450
- return array_merge($customLinks, $defaultLinks);
451
- }
452
-
453
- /**
454
- * @return AccountData
455
- */
456
- public function getData()
457
- {
458
- return $this->data;
459
- }
460
-
461
- /**
462
- * @param AccountData $data
463
- */
464
- public function setData(AccountData $data)
465
- {
466
- $this->data = $data;
467
-
468
- $this->setIsOptedIn($data->isOptedIn());
469
- $this->setIsInstalled($data->isInstalled());
470
- $this->setIsSigned($data->isSigned());
471
- $this->setIsInstallResolved($data->isInstallResolved());
472
- }
473
-
474
- /**
475
- * Resolves valid action name
476
- * based on client id
477
- *
478
- * @param $action
479
- * @return string
480
- */
481
- private function resolveActionName($action)
482
- {
483
- return sprintf('%s_%s', $action, $this->id);
484
- }
485
-
486
- /**
487
- * Register action for current plugin
488
- *
489
- * @param $action
490
- * @param $callback
491
- */
492
- private function addFilter($action, $callback)
493
- {
494
- $validAction = sprintf('%s_%s', $action, $this->basePluginPath);
495
-
496
- add_filter($validAction, $callback, 10);
497
- }
498
-
499
- /**
500
- * Add ajax action for current plugin
501
- *
502
- * @param $action
503
- * @param $callback
504
- * @param bool $raw Format action ??
505
- */
506
- private function addAjax($action, $callback, $raw = false)
507
- {
508
- $validAction = $raw ? $action : sprintf('%s%s', 'wp_ajax_', $this->resolveActionName($action));
509
-
510
- add_action($validAction, $callback);
511
- }
512
-
513
- /**
514
- * @return bool
515
- */
516
- public function isSigned()
517
- {
518
- return $this->isSigned;
519
- }
520
-
521
- /**
522
- * @param bool $isSigned
523
- */
524
- public function setIsSigned($isSigned)
525
- {
526
- $this->data->setIsSigned($isSigned);
527
-
528
- $this->isSigned = $isSigned;
529
- }
530
-
531
- /**
532
- * @return RequestorContract
533
- */
534
- public function getRequestor()
535
- {
536
- return $this->requestor;
537
- }
538
-
539
- /**
540
- * @param RequestorContract $requestor
541
- */
542
- public function setRequestor(RequestorContract $requestor)
543
- {
544
- $this->requestor = $requestor;
545
- }
546
-
547
- /**
548
- * @return string
549
- */
550
- public function getClientSecret()
551
- {
552
- return $this->clientSecret;
553
- }
554
-
555
- /**
556
- * @return Collector
557
- */
558
- public function getCollector()
559
- {
560
- return $this->collector;
561
- }
562
-
563
- /**
564
- * @param Collector $collector
565
- */
566
- public function setCollector(Collector $collector)
567
- {
568
- $this->collector = $collector;
569
- }
570
-
571
- /**
572
- * Do we allowing logging
573
- *
574
- * @return bool
575
- */
576
- public function isAllowingLogging()
577
- {
578
- return $this->isOptedIn;
579
- }
580
-
581
- /**
582
- * @return string
583
- */
584
- public function getBasePluginPath()
585
- {
586
- return $this->basePluginPath;
587
- }
588
-
589
- /**
590
- * @return bool
591
- */
592
- public function isInstallResolved()
593
- {
594
- return $this->isInstallResolved;
595
- }
596
-
597
- /**
598
- * @param bool $isInstallResolved
599
- */
600
- public function setIsInstallResolved($isInstallResolved)
601
- {
602
- $this->data->setIsInstallResolved($isInstallResolved);
603
-
604
- $this->isInstallResolved = $isInstallResolved;
605
- }
606
- }
1
+ <?php
2
+
3
+ namespace Account;
4
+
5
+ use Analyst\Analyst;
6
+ use Analyst\ApiRequestor;
7
+ use Analyst\Cache\DatabaseCache;
8
+ use Analyst\Collector;
9
+ use Analyst\Http\Requests\ActivateRequest;
10
+ use Analyst\Http\Requests\DeactivateRequest;
11
+ use Analyst\Http\Requests\InstallRequest;
12
+ use Analyst\Http\Requests\OptInRequest;
13
+ use Analyst\Http\Requests\OptOutRequest;
14
+ use Analyst\Http\Requests\UninstallRequest;
15
+ use Analyst\Notices\Notice;
16
+ use Analyst\Notices\NoticeFactory;
17
+ use Analyst\Contracts\TrackerContract;
18
+ use Analyst\Contracts\RequestorContract;
19
+
20
+ /**
21
+ * Class Account
22
+ *
23
+ * This is plugin's account object
24
+ */
25
+ class Account implements TrackerContract
26
+ {
27
+ /**
28
+ * Account id
29
+ *
30
+ * @var string
31
+ */
32
+ protected $id;
33
+
34
+ /**
35
+ * Basename of plugin
36
+ *
37
+ * @var string
38
+ */
39
+ protected $path;
40
+
41
+ /**
42
+ * Whether plugin is active or not
43
+ *
44
+ * @var bool
45
+ */
46
+ protected $isInstalled = false;
47
+
48
+ /**
49
+ * Is user sign in for data tracking
50
+ *
51
+ * @var bool
52
+ */
53
+ protected $isOptedIn = false;
54
+
55
+ /**
56
+ * Is user accepted permissions grant
57
+ * for collection site data
58
+ *
59
+ * @var bool
60
+ */
61
+ protected $isSigned = false;
62
+
63
+ /**
64
+ * Is user ever resolved install modal window?
65
+ *
66
+ * @var bool
67
+ */
68
+ protected $isInstallResolved = false;
69
+
70
+ /**
71
+ * Public secret code
72
+ *
73
+ * @var string
74
+ */
75
+ protected $clientSecret;
76
+
77
+ /**
78
+ * @var AccountData
79
+ */
80
+ protected $data;
81
+
82
+ /**
83
+ * Base plugin path
84
+ *
85
+ * @var string
86
+ */
87
+ protected $basePluginPath;
88
+
89
+ /**
90
+ * @var RequestorContract
91
+ */
92
+ protected $requestor;
93
+
94
+ /**
95
+ * @var Collector
96
+ */
97
+ protected $collector;
98
+
99
+ /**
100
+ * Account constructor.
101
+ * @param $id
102
+ * @param $secret
103
+ * @param $baseDir
104
+ */
105
+ public function __construct($id, $secret, $baseDir)
106
+ {
107
+ $this->id = $id;
108
+ $this->clientSecret = $secret;
109
+
110
+ $this->path = $baseDir;
111
+
112
+ $this->basePluginPath = plugin_basename($baseDir);
113
+ }
114
+
115
+ /**
116
+ * @return string
117
+ */
118
+ public function getPath()
119
+ {
120
+ return $this->path;
121
+ }
122
+
123
+ /**
124
+ * @param string $path
125
+ */
126
+ public function setPath($path)
127
+ {
128
+ $this->data->setPath($path);
129
+
130
+ $this->path = $path;
131
+ }
132
+
133
+ /**
134
+ * @return bool
135
+ */
136
+ public function isOptedIn()
137
+ {
138
+ return $this->isOptedIn;
139
+ }
140
+
141
+ /**
142
+ * @param bool $isOptedIn
143
+ */
144
+ public function setIsOptedIn($isOptedIn)
145
+ {
146
+ $this->data->setIsOptedIn($isOptedIn);
147
+
148
+ $this->isOptedIn = $isOptedIn;
149
+ }
150
+
151
+ /**
152
+ * Whether plugin is active
153
+ *
154
+ * @return bool
155
+ */
156
+ public function isActive()
157
+ {
158
+ return is_plugin_active($this->path);
159
+ }
160
+
161
+ /**
162
+ * @param string $id
163
+ */
164
+ public function setId($id)
165
+ {
166
+ $this->id = $id;
167
+ }
168
+
169
+ /**
170
+ * @return string
171
+ */
172
+ public function getId()
173
+ {
174
+ return $this->id;
175
+ }
176
+
177
+ /**
178
+ * @return bool
179
+ */
180
+ public function isInstalled()
181
+ {
182
+ return $this->isInstalled;
183
+ }
184
+
185
+ /**
186
+ * @param bool $isInstalled
187
+ */
188
+ public function setIsInstalled($isInstalled)
189
+ {
190
+ $this->data->setIsInstalled($isInstalled);
191
+
192
+ $this->isInstalled = $isInstalled;
193
+ }
194
+
195
+ /**
196
+ * Should register activation and deactivation
197
+ * event hooks
198
+ *
199
+ * @return void
200
+ */
201
+ public function registerHooks()
202
+ {
203
+ register_activation_hook($this->basePluginPath, [&$this, 'onActivePluginListener']);
204
+ register_uninstall_hook($this->basePluginPath, ['Account\Account', 'onUninstallPluginListener']);
205
+
206
+ $this->addFilter('plugin_action_links', [&$this, 'onRenderActionLinksHook']);
207
+
208
+ $this->addAjax('analyst_opt_in', [&$this, 'onOptInListener']);
209
+ $this->addAjax('analyst_opt_out', [&$this, 'onOptOutListener']);
210
+ $this->addAjax('analyst_plugin_deactivate', [&$this, 'onDeactivatePluginListener']);
211
+ $this->addAjax('analyst_install', [&$this, 'onInstallListener']);
212
+ $this->addAjax('analyst_skip_install', [&$this, 'onSkipInstallListener']);
213
+ $this->addAjax('analyst_install_verified', [&$this, 'onInstallVerifiedListener']);
214
+ }
215
+
216
+ /**
217
+ * Will fire when admin activates plugin
218
+ *
219
+ * @return void
220
+ */
221
+ public function onActivePluginListener()
222
+ {
223
+ if (!$this->isInstallResolved()) {
224
+ DatabaseCache::getInstance()->put('plugin_to_install', $this->id);
225
+ }
226
+
227
+ if (!$this->isAllowingLogging()) return;
228
+
229
+ ActivateRequest::make($this->collector, $this->id, $this->path)
230
+ ->execute($this->requestor);
231
+
232
+ $this->setIsInstalled(true);
233
+
234
+ AccountDataFactory::syncData();
235
+
236
+ wp_send_json_success();
237
+ }
238
+
239
+ /**
240
+ * Will fire when admin deactivates plugin
241
+ *
242
+ * @return void
243
+ */
244
+ public function onDeactivatePluginListener()
245
+ {
246
+ if (!$this->isAllowingLogging()) return;
247
+
248
+ $question = isset($_POST['question']) ? stripslashes($_POST['question']) : null;
249
+ $reason = isset($_POST['reason']) ? stripslashes($_POST['reason']) : null;
250
+
251
+ $response = DeactivateRequest::make($this->collector, $this->id, $this->path, $question, $reason)
252
+ ->execute($this->requestor);
253
+
254
+ // Exit if request failed
255
+ if (!$response->isSuccess()) {
256
+ wp_send_json_error($response->body);
257
+ }
258
+
259
+ $this->setIsInstalled(false);
260
+
261
+ AccountDataFactory::syncData();
262
+
263
+ wp_send_json_success();
264
+ }
265
+
266
+ /**
267
+ * Will fire when user opted in
268
+ *
269
+ * @return void
270
+ */
271
+ public function onOptInListener()
272
+ {
273
+ $response = OptInRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
274
+
275
+ // Exit if request failed
276
+ if (!$response->isSuccess()) {
277
+ wp_send_json_error($response->body);
278
+ }
279
+
280
+ $this->setIsOptedIn(true);
281
+
282
+ AccountDataFactory::syncData();
283
+
284
+ wp_die();
285
+ }
286
+
287
+ /**
288
+ * Will fire when user opted out
289
+ *
290
+ * @return void
291
+ */
292
+ public function onOptOutListener()
293
+ {
294
+ $response = OptOutRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
295
+
296
+ // Exit if request failed
297
+ if (!$response->isSuccess()) {
298
+ wp_send_json_error($response->body);
299
+ }
300
+
301
+ $this->setIsOptedIn(false);
302
+
303
+ AccountDataFactory::syncData();
304
+
305
+ wp_send_json_success();
306
+ }
307
+
308
+ /**
309
+ * Will fire when user accept opt-in
310
+ * at first time
311
+ *
312
+ * @return void
313
+ */
314
+ public function onInstallListener()
315
+ {
316
+ $cache = DatabaseCache::getInstance();
317
+
318
+ // Set flag to true which indicates that install is resolved
319
+ // also remove install plugin id from cache
320
+ $this->setIsInstallResolved(true);
321
+ $cache->delete('plugin_to_install');
322
+
323
+ $response = InstallRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
324
+
325
+ // Exit if request failed
326
+ if (!$response->isSuccess()) {
327
+ wp_send_json_error($response->body);
328
+ }
329
+
330
+ $this->setIsSigned(true);
331
+
332
+ $this->setIsOptedIn(true);
333
+
334
+ $factory = NoticeFactory::instance();
335
+
336
+ $message = sprintf('Please confirm your email by clicking on the link we sent to %s. This makes sure you’re not a bot.', $this->collector->getGeneralEmailAddress());
337
+
338
+ $notificationId = uniqid();
339
+
340
+ $notice = Notice::make(
341
+ $notificationId,
342
+ $this->getId(),
343
+ $message,
344
+ $this->collector->getPluginName($this->path)
345
+ );
346
+
347
+ $factory->addNotice($notice);
348
+
349
+ AccountDataFactory::syncData();
350
+
351
+ // Set email confirmation notification id to cache
352
+ // se we can extract and remove it when user confirmed email
353
+ $cache->put(
354
+ sprintf('account_email_confirmation_%s', $this->getId()),
355
+ $notificationId
356
+ );
357
+
358
+ wp_send_json_success();
359
+ }
360
+
361
+ /**
362
+ * Will fire when user skipped installation
363
+ *
364
+ * @return void
365
+ */
366
+ public function onSkipInstallListener()
367
+ {
368
+ // Set flag to true which indicates that install is resolved
369
+ // also remove install plugin id from cache
370
+ $this->setIsInstallResolved(true);
371
+ DatabaseCache::getInstance()->delete('plugin_to_install');
372
+ }
373
+
374
+ /**
375
+ * Will fire when user delete plugin through admin panel.
376
+ * This action will happen if admin at least once
377
+ * activated the plugin.
378
+ *
379
+ * @return void
380
+ * @throws \Exception
381
+ */
382
+ public static function onUninstallPluginListener()
383
+ {
384
+ $factory = AccountDataFactory::instance();
385
+
386
+ $pluginFile = substr(current_filter(), strlen( 'uninstall_' ));
387
+
388
+ $account = $factory->getAccountDataByBasePath($pluginFile);
389
+
390
+ // If account somehow is not found, exit the execution
391
+ if (!$account) return;
392
+
393
+ $analyst = Analyst::getInstance();
394
+
395
+ $collector = new Collector($analyst);
396
+
397
+ $requestor = new ApiRequestor($account->getId(), $account->getSecret(), $analyst->getApiBase());
398
+
399
+ // Just send request to log uninstall event not caring about response
400
+ UninstallRequest::make($collector, $account->getId(), $account->getPath())->execute($requestor);
401
+
402
+ $factory->sync();
403
+ }
404
+
405
+ /**
406
+ * Fires when used verified his account
407
+ */
408
+ public function onInstallVerifiedListener()
409
+ {
410
+ $factory = NoticeFactory::instance();
411
+
412
+ $notice = Notice::make(
413
+ uniqid(),
414
+ $this->getId(),
415
+ 'Thank you for confirming your email.',
416
+ $this->collector->getPluginName($this->path)
417
+ );
418
+
419
+ $factory->addNotice($notice);
420
+
421
+ // Remove confirmation notification
422
+ $confirmationNotificationId = DatabaseCache::getInstance()->pop(sprintf('account_email_confirmation_%s', $this->getId()));
423
+ $factory->remove($confirmationNotificationId);
424
+
425
+ AccountDataFactory::syncData();
426
+
427
+ wp_send_json_success();
428
+ }
429
+
430
+ /**
431
+ * Will fire when wp renders plugin
432
+ * action buttons
433
+ *
434
+ * @param $defaultLinks
435
+ * @return array
436
+ */
437
+ public function onRenderActionLinksHook($defaultLinks)
438
+ {
439
+ $customLinks = [];
440
+
441
+ $customLinks[] = $this->isOptedIn()
442
+ ? '<a class="analyst-action-opt analyst-opt-out" analyst-plugin-id="' . $this->getId() . '" analyst-plugin-signed="' . (int) $this->isSigned() . '">Opt Out</a>'
443
+ : '<a class="analyst-action-opt analyst-opt-in" analyst-plugin-id="' . $this->getId() . '" analyst-plugin-signed="' . (int) $this->isSigned() . '">Opt In</a>';
444
+
445
+ // Append anchor to find specific deactivation link
446
+ if (isset($defaultLinks['deactivate'])) {
447
+ $defaultLinks['deactivate'] .= '<span analyst-plugin-id="' . $this->getId() . '" analyst-plugin-opted-in="' . (int) $this->isOptedIn() . '"></span>';
448
+ }
449
+
450
+ return array_merge($customLinks, $defaultLinks);
451
+ }
452
+
453
+ /**
454
+ * @return AccountData
455
+ */
456
+ public function getData()
457
+ {
458
+ return $this->data;
459
+ }
460
+
461
+ /**
462
+ * @param AccountData $data
463
+ */
464
+ public function setData(AccountData $data)
465
+ {
466
+ $this->data = $data;
467
+
468
+ $this->setIsOptedIn($data->isOptedIn());
469
+ $this->setIsInstalled($data->isInstalled());
470
+ $this->setIsSigned($data->isSigned());
471
+ $this->setIsInstallResolved($data->isInstallResolved());
472
+ }
473
+
474
+ /**
475
+ * Resolves valid action name
476
+ * based on client id
477
+ *
478
+ * @param $action
479
+ * @return string
480
+ */
481
+ private function resolveActionName($action)
482
+ {
483
+ return sprintf('%s_%s', $action, $this->id);
484
+ }
485
+
486
+ /**
487
+ * Register action for current plugin
488
+ *
489
+ * @param $action
490
+ * @param $callback
491
+ */
492
+ private function addFilter($action, $callback)
493
+ {
494
+ $validAction = sprintf('%s_%s', $action, $this->basePluginPath);
495
+
496
+ add_filter($validAction, $callback, 10);
497
+ }
498
+
499
+ /**
500
+ * Add ajax action for current plugin
501
+ *
502
+ * @param $action
503
+ * @param $callback
504
+ * @param bool $raw Format action ??
505
+ */
506
+ private function addAjax($action, $callback, $raw = false)
507
+ {
508
+ $validAction = $raw ? $action : sprintf('%s%s', 'wp_ajax_', $this->resolveActionName($action));
509
+
510
+ add_action($validAction, $callback);
511
+ }
512
+
513
+ /**
514
+ * @return bool
515
+ */
516
+ public function isSigned()
517
+ {
518
+ return $this->isSigned;
519
+ }
520
+
521
+ /**
522
+ * @param bool $isSigned
523
+ */
524
+ public function setIsSigned($isSigned)
525
+ {
526
+ $this->data->setIsSigned($isSigned);
527
+
528
+ $this->isSigned = $isSigned;
529
+ }
530
+
531
+ /**
532
+ * @return RequestorContract
533
+ */
534
+ public function getRequestor()
535
+ {
536
+ return $this->requestor;
537
+ }
538
+
539
+ /**
540
+ * @param RequestorContract $requestor
541
+ */
542
+ public function setRequestor(RequestorContract $requestor)
543
+ {
544
+ $this->requestor = $requestor;
545
+ }
546
+
547
+ /**
548
+ * @return string
549
+ */
550
+ public function getClientSecret()
551
+ {
552
+ return $this->clientSecret;
553
+ }
554
+
555
+ /**
556
+ * @return Collector
557
+ */
558
+ public function getCollector()
559
+ {
560
+ return $this->collector;
561
+ }
562
+
563
+ /**
564
+ * @param Collector $collector
565
+ */
566
+ public function setCollector(Collector $collector)
567
+ {
568
+ $this->collector = $collector;
569
+ }
570
+
571
+ /**
572
+ * Do we allowing logging
573
+ *
574
+ * @return bool
575
+ */
576
+ public function isAllowingLogging()
577
+ {
578
+ return $this->isOptedIn;
579
+ }
580
+
581
+ /**
582
+ * @return string
583
+ */
584
+ public function getBasePluginPath()
585
+ {
586
+ return $this->basePluginPath;
587
+ }
588
+
589
+ /**
590
+ * @return bool
591
+ */
592
+ public function isInstallResolved()
593
+ {
594
+ return $this->isInstallResolved;
595
+ }
596
+
597
+ /**
598
+ * @param bool $isInstallResolved
599
+ */
600
+ public function setIsInstallResolved($isInstallResolved)
601
+ {
602
+ $this->data->setIsInstallResolved($isInstallResolved);
603
+
604
+ $this->isInstallResolved = $isInstallResolved;
605
+ }
606
+ }
analyst/{analyst/src → src}/Account/AccountData.php RENAMED
@@ -1,176 +1,176 @@
1
- <?php
2
-
3
- namespace Account;
4
-
5
- /**
6
- * Class AccountData is the data holder
7
- * for Analyst\Account\Account class
8
- * which is unserialized from database
9
- */
10
- class AccountData
11
- {
12
- /**
13
- * Account id
14
- *
15
- * @var string
16
- */
17
- protected $id;
18
-
19
- /**
20
- * Account secret key
21
- *
22
- * @var string
23
- */
24
- protected $secret;
25
-
26
- /**
27
- * Basename of plugin
28
- *
29
- * @var string
30
- */
31
- protected $path;
32
-
33
- /**
34
- * Whether admin accepted opt in
35
- * terms and permissions
36
- *
37
- * @var bool
38
- */
39
- protected $isInstalled = false;
40
-
41
- /**
42
- * Is user sign in for data tracking
43
- *
44
- * @var bool
45
- */
46
- protected $isOptedIn = false;
47
-
48
- /**
49
- * Is user accepted permissions grant
50
- * for collection site data
51
- *
52
- * @var bool
53
- */
54
- protected $isSigned = false;
55
-
56
- /**
57
- * Is user ever resolved install modal window?
58
- *
59
- * @var bool
60
- */
61
- protected $isInstallResolved;
62
-
63
- /**
64
- * @return string
65
- */
66
- public function getId()
67
- {
68
- return $this->id;
69
- }
70
-
71
- /**
72
- * @param string $id
73
- */
74
- public function setId($id)
75
- {
76
- $this->id = $id;
77
- }
78
-
79
- /**
80
- * @param string $path
81
- * @return AccountData
82
- */
83
- public function setPath($path)
84
- {
85
- $this->path = $path;
86
- return $this;
87
- }
88
-
89
- /**
90
- * @return bool
91
- */
92
- public function isInstalled()
93
- {
94
- return $this->isInstalled;
95
- }
96
-
97
- /**
98
- * @param bool $isInstalled
99
- */
100
- public function setIsInstalled($isInstalled)
101
- {
102
- $this->isInstalled = $isInstalled;
103
- }
104
-
105
- /**
106
- * @return bool
107
- */
108
- public function isOptedIn()
109
- {
110
- return $this->isOptedIn;
111
- }
112
-
113
- /**
114
- * @param bool $isOptedIn
115
- */
116
- public function setIsOptedIn($isOptedIn)
117
- {
118
- $this->isOptedIn = $isOptedIn;
119
- }
120
-
121
- /**
122
- * @return bool
123
- */
124
- public function isSigned()
125
- {
126
- return $this->isSigned;
127
- }
128
-
129
- /**
130
- * @param bool $isSigned
131
- */
132
- public function setIsSigned($isSigned)
133
- {
134
- $this->isSigned = $isSigned;
135
- }
136
-
137
- /**
138
- * @return string
139
- */
140
- public function getPath()
141
- {
142
- return $this->path;
143
- }
144
-
145
- /**
146
- * @return string
147
- */
148
- public function getSecret()
149
- {
150
- return $this->secret;
151
- }
152
-
153
- /**
154
- * @param string $secret
155
- */
156
- public function setSecret($secret)
157
- {
158
- $this->secret = $secret;
159
- }
160
-
161
- /**
162
- * @return bool
163
- */
164
- public function isInstallResolved()
165
- {
166
- return $this->isInstallResolved;
167
- }
168
-
169
- /**
170
- * @param bool $isInstallResolved
171
- */
172
- public function setIsInstallResolved($isInstallResolved)
173
- {
174
- $this->isInstallResolved = $isInstallResolved;
175
- }
176
- }
1
+ <?php
2
+
3
+ namespace Account;
4
+
5
+ /**
6
+ * Class AccountData is the data holder
7
+ * for Analyst\Account\Account class
8
+ * which is unserialized from database
9
+ */
10
+ class AccountData
11
+ {
12
+ /**
13
+ * Account id
14
+ *
15
+ * @var string
16
+ */
17
+ protected $id;
18
+
19
+ /**
20
+ * Account secret key
21
+ *
22
+ * @var string
23
+ */
24
+ protected $secret;
25
+
26
+ /**
27
+ * Basename of plugin
28
+ *
29
+ * @var string
30
+ */
31
+ protected $path;
32
+
33
+ /**
34
+ * Whether admin accepted opt in
35
+ * terms and permissions
36
+ *
37
+ * @var bool
38
+ */
39
+ protected $isInstalled = false;
40
+
41
+ /**
42
+ * Is user sign in for data tracking
43
+ *
44
+ * @var bool
45
+ */
46
+ protected $isOptedIn = false;
47
+
48
+ /**
49
+ * Is user accepted permissions grant
50
+ * for collection site data
51
+ *
52
+ * @var bool
53
+ */
54
+ protected $isSigned = false;
55
+
56
+ /**
57
+ * Is user ever resolved install modal window?
58
+ *
59
+ * @var bool
60
+ */
61
+ protected $isInstallResolved;
62
+
63
+ /**
64
+ * @return string
65
+ */
66
+ public function getId()
67
+ {
68
+ return $this->id;
69
+ }
70
+
71
+ /**
72
+ * @param string $id
73
+ */
74
+ public function setId($id)
75
+ {
76
+ $this->id = $id;
77
+ }
78
+
79
+ /**
80
+ * @param string $path
81
+ * @return AccountData
82
+ */
83
+ public function setPath($path)
84
+ {
85
+ $this->path = $path;
86
+ return $this;
87
+ }
88
+
89
+ /**
90
+ * @return bool
91
+ */
92
+ public function isInstalled()
93
+ {
94
+ return $this->isInstalled;
95
+ }
96
+
97
+ /**
98
+ * @param bool $isInstalled
99
+ */
100
+ public function setIsInstalled($isInstalled)
101
+ {
102
+ $this->isInstalled = $isInstalled;
103
+ }
104
+
105
+ /**
106
+ * @return bool
107
+ */
108
+ public function isOptedIn()
109
+ {
110
+ return $this->isOptedIn;
111
+ }
112
+
113
+ /**
114
+ * @param bool $isOptedIn
115
+ */
116
+ public function setIsOptedIn($isOptedIn)
117
+ {
118
+ $this->isOptedIn = $isOptedIn;
119
+ }
120
+
121
+ /**
122
+ * @return bool
123
+ */
124
+ public function isSigned()
125
+ {
126
+ return $this->isSigned;
127
+ }
128
+
129
+ /**
130
+ * @param bool $isSigned
131
+ */
132
+ public function setIsSigned($isSigned)
133
+ {
134
+ $this->isSigned = $isSigned;
135
+ }
136
+
137
+ /**
138
+ * @return string
139
+ */
140
+ public function getPath()
141
+ {
142
+ return $this->path;
143
+ }
144
+
145
+ /**
146
+ * @return string
147
+ */
148
+ public function getSecret()
149
+ {
150
+ return $this->secret;
151
+ }
152
+
153
+ /**
154
+ * @param string $secret
155
+ */
156
+ public function setSecret($secret)
157
+ {
158
+ $this->secret = $secret;
159
+ }
160
+
161
+ /**
162
+ * @return bool
163
+ */
164
+ public function isInstallResolved()
165
+ {
166
+ return $this->isInstallResolved;
167
+ }
168
+
169
+ /**
170
+ * @param bool $isInstallResolved
171
+ */
172
+ public function setIsInstallResolved($isInstallResolved)
173
+ {
174
+ $this->isInstallResolved = $isInstallResolved;
175
+ }
176
+ }
analyst/{analyst/src → src}/Account/AccountDataFactory.php RENAMED
@@ -1,125 +1,125 @@
1
- <?php
2
-
3
- namespace Account;
4
-
5
-
6
- use Analyst\Core\AbstractFactory;
7
-
8
- /**
9
- * Class AccountDataFactory
10
- *
11
- * Holds information about this
12
- * wordpress project plugins accounts
13
- *
14
- */
15
- class AccountDataFactory extends AbstractFactory
16
- {
17
- private static $instance;
18
-
19
- CONST OPTIONS_KEY = 'analyst_accounts_data';
20
-
21
- /**
22
- * @var AccountData[]
23
- */
24
- protected $accounts = [];
25
-
26
- /**
27
- * Read factory from options or make fresh instance
28
- *
29
- * @return static
30
- */
31
- public static function instance()
32
- {
33
- if (!static::$instance) {
34
- $raw = get_option(self::OPTIONS_KEY);
35
-
36
- // In case object is already unserialized
37
- // and instance of AccountDataFactory we
38
- // return it, in other case deal with
39
- // serialized string data
40
- if ($raw instanceof self) {
41
- static::$instance = $raw;
42
- } else {
43
- static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
44
- }
45
- }
46
-
47
- return static::$instance;
48
- }
49
-
50
- /**
51
- * Sync this object data with cache
52
- */
53
- public function sync()
54
- {
55
- update_option(self::OPTIONS_KEY, serialize($this));
56
- }
57
-
58
- /**
59
- * Sync this instance data with cache
60
- */
61
- public static function syncData()
62
- {
63
- static::instance()->sync();
64
- }
65
-
66
- /**
67
- * Find plugin account data or create fresh one
68
- *
69
- * @param Account $account
70
- * @return AccountData|null
71
- */
72
- public function resolvePluginAccountData(Account $account)
73
- {
74
- $accountData = $this->findAccountDataById($account->getId());
75
-
76
- if (!$accountData) {
77
- $accountData = new AccountData();
78
-
79
- // Set proper default values
80
- $accountData->setPath($account->getPath());
81
- $accountData->setId($account->getId());
82
- $accountData->setSecret($account->getClientSecret());
83
-
84
- array_push($this->accounts, $accountData);
85
- }
86
-
87
- return $accountData;
88
- }
89
-
90
- /**
91
- * Should return account data by base path
92
- *
93
- * @param $basePath
94
- * @return AccountData
95
- */
96
- public function getAccountDataByBasePath($basePath)
97
- {
98
- foreach ($this->accounts as $iterable) {
99
- $iterableBasePath = plugin_basename($iterable->getPath());
100
-
101
- if ($iterableBasePath === $basePath) {
102
- return $iterable;
103
- }
104
- }
105
-
106
- return null;
107
- }
108
-
109
- /**
110
- * Return account by id
111
- *
112
- * @param $id
113
- * @return AccountData|null
114
- */
115
- private function findAccountDataById($id)
116
- {
117
- foreach ($this->accounts as &$iterable) {
118
- if ($iterable->getId() === $id) {
119
- return $iterable;
120
- }
121
- }
122
-
123
- return null;
124
- }
125
- }
1
+ <?php
2
+
3
+ namespace Account;
4
+
5
+
6
+ use Analyst\Core\AbstractFactory;
7
+
8
+ /**
9
+ * Class AccountDataFactory
10
+ *
11
+ * Holds information about this
12
+ * wordpress project plugins accounts
13
+ *
14
+ */
15
+ class AccountDataFactory extends AbstractFactory
16
+ {
17
+ private static $instance;
18
+
19
+ CONST OPTIONS_KEY = 'analyst_accounts_data';
20
+
21
+ /**
22
+ * @var AccountData[]
23
+ */
24
+ protected $accounts = [];
25
+
26
+ /**
27
+ * Read factory from options or make fresh instance
28
+ *
29
+ * @return static
30
+ */
31
+ public static function instance()
32
+ {
33
+ if (!static::$instance) {
34
+ $raw = get_option(self::OPTIONS_KEY);
35
+
36
+ // In case object is already unserialized
37
+ // and instance of AccountDataFactory we
38
+ // return it, in other case deal with
39
+ // serialized string data
40
+ if ($raw instanceof self) {
41
+ static::$instance = $raw;
42
+ } else {
43
+ static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
44
+ }
45
+ }
46
+
47
+ return static::$instance;
48
+ }
49
+
50
+ /**
51
+ * Sync this object data with cache
52
+ */
53
+ public function sync()
54
+ {
55
+ update_option(self::OPTIONS_KEY, serialize($this));
56
+ }
57
+
58
+ /**
59
+ * Sync this instance data with cache
60
+ */
61
+ public static function syncData()
62
+ {
63
+ static::instance()->sync();
64
+ }
65
+
66
+ /**
67
+ * Find plugin account data or create fresh one
68
+ *
69
+ * @param Account $account
70
+ * @return AccountData|null
71
+ */
72
+ public function resolvePluginAccountData(Account $account)
73
+ {
74
+ $accountData = $this->findAccountDataById($account->getId());
75
+
76
+ if (!$accountData) {
77
+ $accountData = new AccountData();
78
+
79
+ // Set proper default values
80
+ $accountData->setPath($account->getPath());
81
+ $accountData->setId($account->getId());
82
+ $accountData->setSecret($account->getClientSecret());
83
+
84
+ array_push($this->accounts, $accountData);
85
+ }
86
+
87
+ return $accountData;
88
+ }
89
+
90
+ /**
91
+ * Should return account data by base path
92
+ *
93
+ * @param $basePath
94
+ * @return AccountData
95
+ */
96
+ public function getAccountDataByBasePath($basePath)
97
+ {
98
+ foreach ($this->accounts as $iterable) {
99
+ $iterableBasePath = plugin_basename($iterable->getPath());
100
+
101
+ if ($iterableBasePath === $basePath) {
102
+ return $iterable;
103
+ }
104
+ }
105
+
106
+ return null;
107
+ }
108
+
109
+ /**
110
+ * Return account by id
111
+ *
112
+ * @param $id
113
+ * @return AccountData|null
114
+ */
115
+ private function findAccountDataById($id)
116
+ {
117
+ foreach ($this->accounts as &$iterable) {
118
+ if ($iterable->getId() === $id) {
119
+ return $iterable;
120
+ }
121
+ }
122
+
123
+ return null;
124
+ }
125
+ }
analyst/{analyst/src → src}/Analyst.php RENAMED
@@ -1,167 +1,167 @@
1
- <?php
2
- namespace Analyst;
3
-
4
- use Account\Account;
5
- use Account\AccountDataFactory;
6
- use Analyst\Contracts\AnalystContract;
7
- use Analyst\Contracts\RequestorContract;
8
-
9
- class Analyst implements AnalystContract
10
- {
11
- /**
12
- * All plugin's accounts
13
- *
14
- * @var array
15
- */
16
- protected $accounts = array();
17
-
18
- /**
19
- * @var Mutator
20
- */
21
- protected $mutator;
22
-
23
- /**
24
- * @var AccountDataFactory
25
- */
26
- protected $accountDataFactory;
27
-
28
- /**
29
- * Base url to api
30
- *
31
- * @var string
32
- */
33
- protected $apiBase = 'https://feedback.sellcodes.com/api/v1';
34
-
35
- /**
36
- * @var Collector
37
- */
38
- protected $collector;
39
-
40
- /**
41
- * Singleton instance
42
- *
43
- * @var static
44
- */
45
- protected static $instance;
46
-
47
- /**
48
- * Get instance of analyst
49
- *
50
- * @return Analyst
51
- * @throws \Exception
52
- */
53
- public static function getInstance()
54
- {
55
- if (!static::$instance) {
56
- static::$instance = new Analyst();
57
- }
58
-
59
- return static::$instance;
60
- }
61
-
62
- protected function __construct()
63
- {
64
- $this->mutator = new Mutator();
65
-
66
- $this->accountDataFactory = AccountDataFactory::instance();
67
-
68
- $this->mutator->initialize();
69
-
70
- $this->collector = new Collector($this);
71
-
72
- $this->initialize();
73
- }
74
-
75
- /**
76
- * Initialize rest of application
77
- */
78
- public function initialize()
79
- {
80
- add_action('init', function () {
81
- $this->collector->loadCurrentUser();
82
- });
83
- }
84
-
85
- /**
86
- * Register new account
87
- *
88
- * @param Account $account
89
- * @return Analyst
90
- * @throws \Exception
91
- */
92
- public function registerAccount($account)
93
- {
94
- // Stop propagation when account is already registered
95
- if ($this->isAccountRegistered($account)) {
96
- return $this;
97
- }
98
-
99
- // Resolve account data from factory
100
- $accountData = $this->accountDataFactory->resolvePluginAccountData($account);
101
-
102
- $account->setData($accountData);
103
-
104
- $account->setRequestor(
105
- $this->resolveRequestorForAccount($account)
106
- );
107
-
108
- $account->setCollector($this->collector);
109
-
110
- $account->registerHooks();
111
-
112
- $this->accounts[$account->getId()] = $account;
113
-
114
- return $this;
115
- }
116
-
117
- /**
118
- * Must return version of analyst
119
- *
120
- * @return string
121
- */
122
- public static function version()
123
- {
124
- $version = require __DIR__ . '/../version.php';
125
-
126
- return $version['sdk'];
127
- }
128
-
129
- /**
130
- * Is this account registered
131
- *
132
- * @param Account $account
133
- * @return bool
134
- */
135
- protected function isAccountRegistered($account)
136
- {
137
- return isset($this->accounts[$account->getId()]);
138
- }
139
-
140
- /**
141
- * Resolves requestor for account
142
- *
143
- * @param Account $account
144
- * @return RequestorContract
145
- * @throws \Exception
146
- */
147
- protected function resolveRequestorForAccount(Account $account)
148
- {
149
- $requestor = new ApiRequestor($account->getId(), $account->getClientSecret(), $this->apiBase);
150
-
151
- // Set SDK version
152
- $requestor->setDefaultHeader(
153
- 'x-analyst-client-user-agent',
154
- sprintf('Analyst/%s', $this->version())
155
- );
156
-
157
- return $requestor;
158
- }
159
-
160
- /**
161
- * @return string
162
- */
163
- public function getApiBase()
164
- {
165
- return $this->apiBase;
166
- }
167
- }
1
+ <?php
2
+ namespace Analyst;
3
+
4
+ use Account\Account;
5
+ use Account\AccountDataFactory;
6
+ use Analyst\Contracts\AnalystContract;
7
+ use Analyst\Contracts\RequestorContract;
8
+
9
+ class Analyst implements AnalystContract
10
+ {
11
+ /**
12
+ * All plugin's accounts
13
+ *
14
+ * @var array
15
+ */
16
+ protected $accounts = array();
17
+
18
+ /**
19
+ * @var Mutator
20
+ */
21
+ protected $mutator;
22
+
23
+ /**
24
+ * @var AccountDataFactory
25
+ */
26
+ protected $accountDataFactory;
27
+
28
+ /**
29
+ * Base url to api
30
+ *
31
+ * @var string
32
+ */
33
+ protected $apiBase = 'https://feedback.sellcodes.com/api/v1';
34
+
35
+ /**
36
+ * @var Collector
37
+ */
38
+ protected $collector;
39
+
40
+ /**
41
+ * Singleton instance
42
+ *
43
+ * @var static
44
+ */
45
+ protected static $instance;
46
+
47
+ /**
48
+ * Get instance of analyst
49
+ *
50
+ * @return Analyst
51
+ * @throws \Exception
52
+ */
53
+ public static function getInstance()
54
+ {
55
+ if (!static::$instance) {
56
+ static::$instance = new Analyst();
57
+ }
58
+
59
+ return static::$instance;
60
+ }
61
+
62
+ protected function __construct()
63
+ {
64
+ $this->mutator = new Mutator();
65
+
66
+ $this->accountDataFactory = AccountDataFactory::instance();
67
+
68
+ $this->mutator->initialize();
69
+
70
+ $this->collector = new Collector($this);
71
+
72
+ $this->initialize();
73
+ }
74
+
75
+ /**
76
+ * Initialize rest of application
77
+ */
78
+ public function initialize()
79
+ {
80
+ add_action('init', function () {
81
+ $this->collector->loadCurrentUser();
82
+ });
83
+ }
84
+
85
+ /**
86
+ * Register new account
87
+ *
88
+ * @param Account $account
89
+ * @return Analyst
90
+ * @throws \Exception
91
+ */
92
+ public function registerAccount($account)
93
+ {
94
+ // Stop propagation when account is already registered
95
+ if ($this->isAccountRegistered($account)) {
96
+ return $this;
97
+ }
98
+
99
+ // Resolve account data from factory
100
+ $accountData = $this->accountDataFactory->resolvePluginAccountData($account);
101
+
102
+ $account->setData($accountData);
103
+
104
+ $account->setRequestor(
105
+ $this->resolveRequestorForAccount($account)
106
+ );
107
+
108
+ $account->setCollector($this->collector);
109
+
110
+ $account->registerHooks();
111
+
112
+ $this->accounts[$account->getId()] = $account;
113
+
114
+ return $this;
115
+ }
116
+
117
+ /**
118
+ * Must return version of analyst
119
+ *
120
+ * @return string
121
+ */
122
+ public static function version()
123
+ {
124
+ $version = require __DIR__ . '/../version.php';
125
+
126
+ return $version['sdk'];
127
+ }
128
+
129
+ /**
130
+ * Is this account registered
131
+ *
132
+ * @param Account $account
133
+ * @return bool
134
+ */
135
+ protected function isAccountRegistered($account)
136
+ {
137
+ return isset($this->accounts[$account->getId()]);
138
+ }
139
+
140
+ /**
141
+ * Resolves requestor for account
142
+ *
143
+ * @param Account $account
144
+ * @return RequestorContract
145
+ * @throws \Exception
146
+ */
147
+ protected function resolveRequestorForAccount(Account $account)
148
+ {
149
+ $requestor = new ApiRequestor($account->getId(), $account->getClientSecret(), $this->apiBase);
150
+
151
+ // Set SDK version
152
+ $requestor->setDefaultHeader(
153
+ 'x-analyst-client-user-agent',
154
+ sprintf('Analyst/%s', $this->version())
155
+ );
156
+
157
+ return $requestor;
158
+ }
159
+
160
+ /**
161
+ * @return string
162
+ */
163
+ public function getApiBase()
164
+ {
165
+ return $this->apiBase;
166
+ }
167
+ }
analyst/{analyst/src → src}/ApiRequestor.php RENAMED
@@ -1,257 +1,257 @@
1
- <?php
2
-
3
- namespace Analyst;
4
-
5
- use Exception;
6
- use Analyst\Contracts\HttpClientContract;
7
- use Analyst\Contracts\RequestorContract;
8
-
9
- class ApiRequestor implements RequestorContract
10
- {
11
- /**
12
- * Supported http client
13
- *
14
- * @var HttpClientContract
15
- */
16
- protected $httpClient;
17
-
18
- /**
19
- * @var string
20
- */
21
- protected $clientId;
22
-
23
- /**
24
- * @var string
25
- */
26
- protected $clientSecret;
27
-
28
- /**
29
- * @var string
30
- */
31
- protected $apiBase;
32
-
33
- /**
34
- * Default headers to be sent
35
- *
36
- * @var array
37
- */
38
- protected $defaultHeaders = [
39
- 'accept' => 'application/json',
40
- 'content-type' => 'application/json'
41
- ];
42
-
43
- /**
44
- * Prioritized http clients
45
- *
46
- * @var array
47
- */
48
- protected $availableClients = [
49
- 'Analyst\Http\WordPressHttpClient',
50
- 'Analyst\Http\CurlHttpClient',
51
- 'Analyst\Http\DummyHttpClient',
52
- ];
53
-
54
- /**
55
- * ApiRequestor constructor.
56
- * @param $id
57
- * @param $secret
58
- * @param $apiBase
59
- * @throws \Exception
60
- */
61
- public function __construct($id, $secret, $apiBase)
62
- {
63
- $this->clientId = $id;
64
- $this->clientSecret = $secret;
65
-
66
- $this->setApiBase($apiBase);
67
-
68
- $this->httpClient = $this->resolveHttpClient();
69
- }
70
-
71
- /**
72
- * Set api base url
73
- *
74
- * @param $url
75
- */
76
- public function setApiBase($url)
77
- {
78
- $this->apiBase = $url;
79
- }
80
-
81
- /**
82
- * Get request
83
- *
84
- * @param $url
85
- * @param array $headers
86
- * @return mixed
87
- */
88
- public function get($url, $headers = [])
89
- {
90
- return $this->request('GET', $url, null, $headers);
91
- }
92
-
93
- /**
94
- * Post request
95
- *
96
- * @param $url
97
- * @param $body
98
- * @param array $headers
99
- * @return mixed
100
- */
101
- public function post($url, $body = [], $headers = [])
102
- {
103
- return $this->request('POST', $url, $body, $headers);
104
- }
105
-
106
- /**
107
- * Put request
108
- *
109
- * @param $url
110
- * @param $body
111
- * @param array $headers
112
- * @return mixed
113
- */
114
- public function put($url, $body = [], $headers = [])
115
- {
116
- return $this->request('PUT', $url, $body, $headers);
117
- }
118
-
119
- /**
120
- * Delete request
121
- *
122
- * @param $url
123
- * @param array $headers
124
- * @return mixed
125
- */
126
- public function delete($url, $headers = [])
127
- {
128
- return $this->request('DELETE', $url, null, $headers);
129
- }
130
-
131
- /**
132
- * Make request to api
133
- *
134
- * @param $method
135
- * @param $url
136
- * @param array $body
137
- * @param array $headers
138
- * @return mixed
139
- */
140
- protected function request($method, $url, $body = [], $headers = [])
141
- {
142
- $fullUrl = $this->resolveFullUrl($url);
143
-
144
- $date = date('r', time());
145
-
146
- $headers['date'] = $date;
147
- $headers['signature'] = $this->resolveSignature($this->clientSecret, $method, $fullUrl, $body, $date);
148
-
149
- // Lowercase header names
150
- $headers = $this->prepareHeaders(
151
- array_merge($headers, $this->defaultHeaders)
152
- );
153
-
154
- $response = $this->httpClient->request($method, $fullUrl, $body, $headers);
155
-
156
- // TODO: Check response code and take actions
157
-
158
- return $response;
159
- }
160
-
161
- /**
162
- * Set one default header
163
- *
164
- * @param $header
165
- * @param $value
166
- */
167
- public function setDefaultHeader($header, $value)
168
- {
169
- $this->defaultHeaders[
170
- $this->resolveValidHeaderName($header)
171
- ] = $value;
172
- }
173
-
174
- /**
175
- * Resolves supported http client
176
- *
177
- * @return HttpClientContract
178
- * @throws Exception
179
- */
180
- protected function resolveHttpClient()
181
- {
182
- $clients = array_filter($this->availableClients, $this->guessClientSupportEnvironment());
183
-
184
- if (!isset($clients[0])) {
185
- throw new Exception('There is no http client which this application can support');
186
- }
187
-
188
- // Instantiate first supported http client
189
- return new $clients[0];
190
- }
191
-
192
- /**
193
- * This will filter out clients which is not supported
194
- * by the current environment
195
- *
196
- * @return \Closure
197
- */
198
- protected function guessClientSupportEnvironment()
199
- {
200
- return function ($client) {
201
- return forward_static_call([$client, 'hasSupport']);
202
- };
203
- }
204
-
205
- /**
206
- * Resolves valid header name
207
- *
208
- * @param $headerName
209
- * @return string
210
- */
211
- private function resolveValidHeaderName($headerName)
212
- {
213
- return strtolower($headerName);
214
- }
215
-
216
- /**
217
- * Lowercase header names
218
- *
219
- * @param $headers
220
- * @return array
221
- */
222
- private function prepareHeaders($headers)
223
- {
224
- return array_change_key_case($headers, CASE_LOWER);
225
- }
226
-
227
- /**
228
- * Sign request
229
- *
230
- * @param $key
231
- * @param $method
232
- * @param $url
233
- * @param $body
234
- * @param $date
235
- *
236
- * @return false|string
237
- */
238
- private function resolveSignature($key, $method, $url, $body, $date)
239
- {
240
- $string = implode('\n', [$method, $url, md5(json_encode($body)), $date]);
241
-
242
- $contentSecret = hash_hmac('sha256', $string, $key);
243
-
244
- return sprintf('%s:%s', $this->clientId, $contentSecret);
245
- }
246
-
247
- /**
248
- * Compose full url
249
- *
250
- * @param $url
251
- * @return string
252
- */
253
- private function resolveFullUrl($url)
254
- {
255
- return sprintf('%s/%s', $this->apiBase, trim($url, '/'));
256
- }
257
- }
1
+ <?php
2
+
3
+ namespace Analyst;
4
+
5
+ use Exception;
6
+ use Analyst\Contracts\HttpClientContract;
7
+ use Analyst\Contracts\RequestorContract;
8
+
9
+ class ApiRequestor implements RequestorContract
10
+ {
11
+ /**
12
+ * Supported http client
13
+ *
14
+ * @var HttpClientContract
15
+ */
16
+ protected $httpClient;
17
+
18
+ /**
19
+ * @var string
20
+ */
21
+ protected $clientId;
22
+
23
+ /**
24
+ * @var string
25
+ */
26
+ protected $clientSecret;
27
+
28
+ /**
29
+ * @var string
30
+ */
31
+ protected $apiBase;
32
+
33
+ /**
34
+ * Default headers to be sent
35
+ *
36
+ * @var array
37
+ */
38
+ protected $defaultHeaders = [
39
+ 'accept' => 'application/json',
40
+ 'content-type' => 'application/json'
41
+ ];
42
+
43
+ /**
44
+ * Prioritized http clients
45
+ *
46
+ * @var array
47
+ */
48
+ protected $availableClients = [
49
+ 'Analyst\Http\WordPressHttpClient',
50
+ 'Analyst\Http\CurlHttpClient',
51
+ 'Analyst\Http\DummyHttpClient',
52
+ ];
53
+
54
+ /**
55
+ * ApiRequestor constructor.
56
+ * @param $id
57
+ * @param $secret
58
+ * @param $apiBase
59
+ * @throws \Exception
60
+ */
61
+ public function __construct($id, $secret, $apiBase)
62
+ {
63
+ $this->clientId = $id;
64
+ $this->clientSecret = $secret;
65
+
66
+ $this->setApiBase($apiBase);
67
+
68
+ $this->httpClient = $this->resolveHttpClient();
69
+ }
70
+
71
+ /**
72
+ * Set api base url
73
+ *
74
+ * @param $url
75
+ */
76
+ public function setApiBase($url)
77
+ {
78
+ $this->apiBase = $url;
79
+ }
80
+
81
+ /**
82
+ * Get request
83
+ *
84
+ * @param $url
85
+ * @param array $headers
86
+ * @return mixed
87
+ */
88
+ public function get($url, $headers = [])
89
+ {
90
+ return $this->request('GET', $url, null, $headers);
91
+ }
92
+
93
+ /**
94
+ * Post request
95
+ *
96
+ * @param $url
97
+ * @param $body
98
+ * @param array $headers
99
+ * @return mixed
100
+ */
101
+ public function post($url, $body = [], $headers = [])
102
+ {
103
+ return $this->request('POST', $url, $body, $headers);
104
+ }
105
+
106
+ /**
107
+ * Put request
108
+ *
109
+ * @param $url
110
+ * @param $body
111
+ * @param array $headers
112
+ * @return mixed
113
+ */
114
+ public function put($url, $body = [], $headers = [])
115
+ {
116
+ return $this->request('PUT', $url, $body, $headers);
117
+ }
118
+
119
+ /**
120
+ * Delete request
121
+ *
122
+ * @param $url
123
+ * @param array $headers
124
+ * @return mixed
125
+ */
126
+ public function delete($url, $headers = [])
127
+ {
128
+ return $this->request('DELETE', $url, null, $headers);
129
+ }
130
+
131
+ /**
132
+ * Make request to api
133
+ *
134
+ * @param $method
135
+ * @param $url
136
+ * @param array $body
137
+ * @param array $headers
138
+ * @return mixed
139
+ */
140
+ protected function request($method, $url, $body = [], $headers = [])
141
+ {
142
+ $fullUrl = $this->resolveFullUrl($url);
143
+
144
+ $date = date('r', time());
145
+
146
+ $headers['date'] = $date;
147
+ $headers['signature'] = $this->resolveSignature($this->clientSecret, $method, $fullUrl, $body, $date);
148
+
149
+ // Lowercase header names
150
+ $headers = $this->prepareHeaders(
151
+ array_merge($headers, $this->defaultHeaders)
152
+ );
153
+
154
+ $response = $this->httpClient->request($method, $fullUrl, $body, $headers);
155
+
156
+ // TODO: Check response code and take actions
157
+
158
+ return $response;
159
+ }
160
+
161
+ /**
162
+ * Set one default header
163
+ *
164
+ * @param $header
165
+ * @param $value
166
+ */
167
+ public function setDefaultHeader($header, $value)
168
+ {
169
+ $this->defaultHeaders[
170
+ $this->resolveValidHeaderName($header)
171
+ ] = $value;
172
+ }
173
+
174
+ /**
175
+ * Resolves supported http client
176
+ *
177
+ * @return HttpClientContract
178
+ * @throws Exception
179
+ */
180
+ protected function resolveHttpClient()
181
+ {
182
+ $clients = array_filter($this->availableClients, $this->guessClientSupportEnvironment());
183
+
184
+ if (!isset($clients[0])) {
185
+ throw new Exception('There is no http client which this application can support');
186
+ }
187
+
188
+ // Instantiate first supported http client
189
+ return new $clients[0];
190
+ }
191
+
192
+ /**
193
+ * This will filter out clients which is not supported
194
+ * by the current environment
195
+ *
196
+ * @return \Closure
197
+ */
198
+ protected function guessClientSupportEnvironment()
199
+ {
200
+ return function ($client) {
201
+ return forward_static_call([$client, 'hasSupport']);
202
+ };
203
+ }
204
+
205
+ /**
206
+ * Resolves valid header name
207
+ *
208
+ * @param $headerName
209
+ * @return string
210
+ */
211
+ private function resolveValidHeaderName($headerName)
212
+ {
213
+ return strtolower($headerName);
214
+ }
215
+
216
+ /**
217
+ * Lowercase header names
218
+ *
219
+ * @param $headers
220
+ * @return array
221
+ */
222
+ private function prepareHeaders($headers)
223
+ {
224
+ return array_change_key_case($headers, CASE_LOWER);
225
+ }
226
+
227
+ /**
228
+ * Sign request
229
+ *
230
+ * @param $key
231
+ * @param $method
232
+ * @param $url
233
+ * @param $body
234
+ * @param $date
235
+ *
236
+ * @return false|string
237
+ */
238
+ private function resolveSignature($key, $method, $url, $body, $date)
239
+ {
240
+ $string = implode('\n', [$method, $url, md5(json_encode($body)), $date]);
241
+
242
+ $contentSecret = hash_hmac('sha256', $string, $key);
243
+
244
+ return sprintf('%s:%s', $this->clientId, $contentSecret);
245
+ }
246
+
247
+ /**
248
+ * Compose full url
249
+ *
250
+ * @param $url
251
+ * @return string
252
+ */
253
+ private function resolveFullUrl($url)
254
+ {
255
+ return sprintf('%s/%s', $this->apiBase, trim($url, '/'));
256
+ }
257
+ }
analyst/{analyst/src → src}/ApiResponse.php RENAMED
@@ -1,44 +1,44 @@
1
- <?php
2
-
3
- namespace Analyst;
4
-
5
- class ApiResponse
6
- {
7
- /**
8
- * Response headers
9
- *
10
- * @var array
11
- */
12
- public $headers;
13
-
14
- /**
15
- * Response body
16
- *
17
- * @var mixed
18
- */
19
- public $body;
20
-
21
- /**
22
- * Status code
23
- *
24
- * @var string
25
- */
26
- public $code;
27
-
28
- public function __construct($body, $code, $headers)
29
- {
30
- $this->body = $body;
31
- $this->code = $code;
32
- $this->headers = $headers;
33
- }
34
-
35
- /**
36
- * Whether status code is successful
37
- *
38
- * @return bool
39
- */
40
- public function isSuccess()
41
- {
42
- return $this->code >= 200 && $this->code < 300;
43
- }
44
- }
1
+ <?php
2
+
3
+ namespace Analyst;
4
+
5
+ class ApiResponse
6
+ {
7
+ /**
8
+ * Response headers
9
+ *
10
+ * @var array
11
+ */
12
+ public $headers;
13
+
14
+ /**
15
+ * Response body
16
+ *
17
+ * @var mixed
18
+ */
19
+ public $body;
20
+
21
+ /**
22
+ * Status code
23
+ *
24
+ * @var string
25
+ */
26
+ public $code;
27
+
28
+ public function __construct($body, $code, $headers)
29
+ {
30
+ $this->body = $body;
31
+ $this->code = $code;
32
+ $this->headers = $headers;
33
+ }
34
+
35
+ /**
36
+ * Whether status code is successful
37
+ *
38
+ * @return bool
39
+ */
40
+ public function isSuccess()
41
+ {
42
+ return $this->code >= 200 && $this->code < 300;
43
+ }
44
+ }
analyst/{analyst/src → src}/Cache/DatabaseCache.php RENAMED
@@ -1,127 +1,127 @@
1
- <?php
2
-
3
- namespace Analyst\Cache;
4
-
5
- use Analyst\Contracts\CacheContract;
6
-
7
- /**
8
- * Class DatabaseCache
9
- *
10
- * @since 1.1.5
11
- */
12
- class DatabaseCache implements CacheContract
13
- {
14
- const OPTION_KEY = 'analyst_cache';
15
-
16
- protected static $instance;
17
-
18
- /**
19
- * Get instance of db cache
20
- *
21
- * @return DatabaseCache
22
- */
23
- public static function getInstance()
24
- {
25
- if (!self::$instance) {
26
- self::$instance = new DatabaseCache();
27
- }
28
-
29
- return self::$instance;
30
- }
31
-
32
- /**
33
- * Key value pair
34
- *
35
- * @var array[]
36
- */
37
- protected $values = [];
38
-
39
- /**
40
- * DatabaseCache constructor.
41
- */
42
- public function __construct()
43
- {
44
- $raw = get_option(self::OPTION_KEY, serialize([]));
45
-
46
- // Raw data may be an array already
47
- $this->values = is_array($raw) ? $raw : @unserialize($raw);
48
-
49
- // In case serialization is failed
50
- // make sure values is an array
51
- if (!is_array($this->values)) {
52
- $this->values = [];
53
- }
54
- }
55
-
56
- /**
57
- * Save value with given key
58
- *
59
- * @param string $key
60
- * @param string $value
61
- *
62
- * @return static
63
- */
64
- public function put($key, $value)
65
- {
66
- $this->values[$key] = $value;
67
-
68
- $this->sync();
69
-
70
- return $this;
71
- }
72
-
73
- /**
74
- * Get value by given key
75
- *
76
- * @param $key
77
- *
78
- * @param null $default
79
- * @return string
80
- */
81
- public function get($key, $default = null)
82
- {
83
- $value = isset($this->values[$key]) ? $this->values[$key] : $default;
84
-
85
- return $value;
86
- }
87
-
88
- /**
89
- * @param $key
90
- *
91
- * @return static
92
- */
93
- public function delete($key)
94
- {
95
- if (isset($this->values[$key])) {
96
- unset($this->values[$key]);
97
-
98
- $this->sync();
99
- }
100
-
101
- return $this;
102
- }
103
-
104
- /**
105
- * Update cache in DB
106
- */
107
- protected function sync()
108
- {
109
- update_option(self::OPTION_KEY, serialize($this->values));
110
- }
111
-
112
- /**
113
- * Should get value and remove it from cache
114
- *
115
- * @param $key
116
- * @param null $default
117
- * @return mixed
118
- */
119
- public function pop($key, $default = null)
120
- {
121
- $value = $this->get($key);
122
-
123
- $this->delete($key);
124
-
125
- return $value;
126
- }
127
- }
1
+ <?php
2
+
3
+ namespace Analyst\Cache;
4
+
5
+ use Analyst\Contracts\CacheContract;
6
+
7
+ /**
8
+ * Class DatabaseCache
9
+ *
10
+ * @since 1.1.5
11
+ */
12
+ class DatabaseCache implements CacheContract
13
+ {
14
+ const OPTION_KEY = 'analyst_cache';
15
+
16
+ protected static $instance;
17
+
18
+ /**
19
+ * Get instance of db cache
20
+ *
21
+ * @return DatabaseCache
22
+ */
23
+ public static function getInstance()
24
+ {
25
+ if (!self::$instance) {
26
+ self::$instance = new DatabaseCache();
27
+ }
28
+
29
+ return self::$instance;
30
+ }
31
+
32
+ /**
33
+ * Key value pair
34
+ *
35
+ * @var array[]
36
+ */
37
+ protected $values = [];
38
+
39
+ /**
40
+ * DatabaseCache constructor.
41
+ */
42
+ public function __construct()
43
+ {
44
+ $raw = get_option(self::OPTION_KEY, serialize([]));
45
+
46
+ // Raw data may be an array already
47
+ $this->values = is_array($raw) ? $raw : @unserialize($raw);
48
+
49
+ // In case serialization is failed
50
+ // make sure values is an array
51
+ if (!is_array($this->values)) {
52
+ $this->values = [];
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Save value with given key
58
+ *
59
+ * @param string $key
60
+ * @param string $value
61
+ *
62
+ * @return static
63
+ */
64
+ public function put($key, $value)
65
+ {
66
+ $this->values[$key] = $value;
67
+
68
+ $this->sync();
69
+
70
+ return $this;
71
+ }
72
+
73
+ /**
74
+ * Get value by given key
75
+ *
76
+ * @param $key
77
+ *
78
+ * @param null $default
79
+ * @return string
80
+ */
81
+ public function get($key, $default = null)
82
+ {
83
+ $value = isset($this->values[$key]) ? $this->values[$key] : $default;
84
+
85
+ return $value;
86
+ }
87
+
88
+ /**
89
+ * @param $key
90
+ *
91
+ * @return static
92
+ */
93
+ public function delete($key)
94
+ {
95
+ if (isset($this->values[$key])) {
96
+ unset($this->values[$key]);
97
+
98
+ $this->sync();
99
+ }
100
+
101
+ return $this;
102
+ }
103
+
104
+ /**
105
+ * Update cache in DB
106
+ */
107
+ protected function sync()
108
+ {
109
+ update_option(self::OPTION_KEY, serialize($this->values));
110
+ }
111
+
112
+ /**
113
+ * Should get value and remove it from cache
114
+ *
115
+ * @param $key
116
+ * @param null $default
117
+ * @return mixed
118
+ */
119
+ public function pop($key, $default = null)
120
+ {
121
+ $value = $this->get($key);
122
+
123
+ $this->delete($key);
124
+
125
+ return $value;
126
+ }
127
+ }
analyst/{analyst/src → src}/Collector.php RENAMED
@@ -1,217 +1,217 @@
1
- <?php
2
-
3
- namespace Analyst;
4
-
5
- use Analyst\Contracts\AnalystContract;
6
-
7
- /**
8
- * Class Collector is a set of getters
9
- * to retrieve some data from wp site
10
- */
11
- class Collector
12
- {
13
- /**
14
- * @var AnalystContract
15
- */
16
- protected $sdk;
17
-
18
- /**
19
- * @var \WP_User
20
- */
21
- protected $user;
22
-
23
- public function __construct(AnalystContract $sdk)
24
- {
25
- $this->sdk = $sdk;
26
- }
27
-
28
- /**
29
- * Load current user into memory
30
- */
31
- public function loadCurrentUser()
32
- {
33
- $this->user = wp_get_current_user();
34
- }
35
-
36
- /**
37
- * Get site url
38
- *
39
- * @return string
40
- */
41
- public function getSiteUrl()
42
- {
43
- return get_option('siteurl');
44
- }
45
-
46
- /**
47
- * Get current user email
48
- *
49
- * @return string
50
- */
51
- public function getCurrentUserEmail()
52
- {
53
- return $this->user->user_email;
54
- }
55
-
56
- /**
57
- * Get's email from general settings
58
- *
59
- * @return string
60
- */
61
- public function getGeneralEmailAddress()
62
- {
63
- return get_option('admin_email');
64
- }
65
-
66
- /**
67
- * Is this user administrator
68
- *
69
- * @return bool
70
- */
71
- public function isUserAdministrator()
72
- {
73
- return in_array('administrator', $this->user->roles);
74
- }
75
-
76
- /**
77
- * User name
78
- *
79
- * @return string
80
- */
81
- public function getCurrentUserName()
82
- {
83
- return $this->user ? $this->user->user_nicename : 'unknown';
84
- }
85
-
86
- /**
87
- * WP version
88
- *
89
- * @return string
90
- */
91
- public function getWordPressVersion()
92
- {
93
- global $wp_version;
94
-
95
- return $wp_version;
96
- }
97
-
98
- /**
99
- * PHP version
100
- *
101
- * @return string
102
- */
103
- public function getPHPVersion()
104
- {
105
- return phpversion();
106
- }
107
-
108
- /**
109
- * Resolves plugin information
110
- *
111
- * @param string $path Absolute path to plugin
112
- * @return array
113
- */
114
- public function resolvePluginData($path)
115
- {
116
- if( !function_exists('get_plugin_data') ){
117
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
118
- }
119
-
120
- return get_plugin_data($path);
121
- }
122
-
123
- /**
124
- * Get plugin name by path
125
- *
126
- * @param $path
127
- * @return string
128
- */
129
- public function getPluginName($path)
130
- {
131
- $data = $this->resolvePluginData($path);
132
-
133
- return $data['Name'];
134
- }
135
-
136
- /**
137
- * Get plugin version
138
- *
139
- * @param $path
140
- * @return string
141
- */
142
- public function getPluginVersion($path)
143
- {
144
- $data = $this->resolvePluginData($path);
145
-
146
- return $data['Version'] ? $data['Version'] : null;
147
- }
148
-
149
- /**
150
- * Get server ip
151
- *
152
- * @return string
153
- */
154
- public function getServerIp()
155
- {
156
- return $_SERVER['SERVER_ADDR'];
157
- }
158
-
159
- /**
160
- * @return string
161
- */
162
- public function getSDKVersion()
163
- {
164
- return $this->sdk->version();
165
- }
166
-
167
- /**
168
- * @return string
169
- */
170
- public function getMysqlVersion()
171
- {
172
- global $wpdb;
173
-
174
- $version = empty($wpdb->use_mysqli) ? mysql_get_server_info() : mysqli_get_server_info($wpdb->dbh);
175
-
176
- return $version ? $version : 'unknown';
177
- }
178
-
179
- /**
180
- * @return string
181
- */
182
- public function getSiteLanguage()
183
- {
184
- return get_locale();
185
- }
186
-
187
-
188
- /**
189
- * Current WP theme
190
- *
191
- * @return false|string
192
- */
193
- public function getCurrentThemeName()
194
- {
195
- return wp_get_theme()->get('Name');
196
- }
197
-
198
- /**
199
- * Get active plugins list
200
- *
201
- * @return array
202
- */
203
- public function getActivePluginsList()
204
- {
205
- if (!function_exists('get_plugins')) {
206
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
207
- }
208
-
209
- $allPlugins = get_plugins();
210
-
211
- $activePluginsNames = array_map(function ($path) use ($allPlugins) {
212
- return $allPlugins[$path]['Name'];
213
- }, get_option('active_plugins'));
214
-
215
- return $activePluginsNames;
216
- }
217
- }
1
+ <?php
2
+
3
+ namespace Analyst;
4
+
5
+ use Analyst\Contracts\AnalystContract;
6
+
7
+ /**
8
+ * Class Collector is a set of getters
9
+ * to retrieve some data from wp site
10
+ */
11
+ class Collector
12
+ {
13
+ /**
14
+ * @var AnalystContract
15
+ */
16
+ protected $sdk;
17
+
18
+ /**
19
+ * @var \WP_User
20
+ */
21
+ protected $user;
22
+
23
+ public function __construct(AnalystContract $sdk)
24
+ {
25
+ $this->sdk = $sdk;
26
+ }
27
+
28
+ /**
29
+ * Load current user into memory
30
+ */
31
+ public function loadCurrentUser()
32
+ {
33
+ $this->user = wp_get_current_user();
34
+ }
35
+
36
+ /**
37
+ * Get site url
38
+ *
39
+ * @return string
40
+ */
41
+ public function getSiteUrl()
42
+ {
43
+ return get_option('siteurl');
44
+ }
45
+
46
+ /**
47
+ * Get current user email
48
+ *
49
+ * @return string
50
+ */
51
+ public function getCurrentUserEmail()
52
+ {
53
+ return $this->user->user_email;
54
+ }
55
+
56
+ /**
57
+ * Get's email from general settings
58
+ *
59
+ * @return string
60
+ */
61
+ public function getGeneralEmailAddress()
62
+ {
63
+ return get_option('admin_email');
64
+ }
65
+
66
+ /**
67
+ * Is this user administrator
68
+ *
69
+ * @return bool
70
+ */
71
+ public function isUserAdministrator()
72
+ {
73
+ return in_array('administrator', $this->user->roles);
74
+ }
75
+
76
+ /**
77
+ * User name
78
+ *
79
+ * @return string
80
+ */
81
+ public function getCurrentUserName()
82
+ {
83
+ return $this->user ? $this->user->user_nicename : 'unknown';
84
+ }
85
+
86
+ /**
87
+ * WP version
88
+ *
89
+ * @return string
90
+ */
91
+ public function getWordPressVersion()
92
+ {
93
+ global $wp_version;
94
+
95
+ return $wp_version;
96
+ }
97
+
98
+ /**
99
+ * PHP version
100
+ *
101
+ * @return string
102
+ */
103
+ public function getPHPVersion()
104
+ {
105
+ return phpversion();
106
+ }
107
+
108
+ /**
109
+ * Resolves plugin information
110
+ *
111
+ * @param string $path Absolute path to plugin
112
+ * @return array
113
+ */
114
+ public function resolvePluginData($path)
115
+ {
116
+ if( !function_exists('get_plugin_data') ){
117
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
118
+ }
119
+
120
+ return get_plugin_data($path);
121
+ }
122
+
123
+ /**
124
+ * Get plugin name by path
125
+ *
126
+ * @param $path
127
+ * @return string
128
+ */
129
+ public function getPluginName($path)
130
+ {
131
+ $data = $this->resolvePluginData($path);
132
+
133
+ return $data['Name'];
134
+ }
135
+
136
+ /**
137
+ * Get plugin version
138
+ *
139
+ * @param $path
140
+ * @return string
141
+ */
142
+ public function getPluginVersion($path)
143
+ {
144
+ $data = $this->resolvePluginData($path);
145
+
146
+ return $data['Version'] ? $data['Version'] : null;
147
+ }
148
+
149
+ /**
150
+ * Get server ip
151
+ *
152
+ * @return string
153
+ */
154
+ public function getServerIp()
155
+ {
156
+ return $_SERVER['SERVER_ADDR'];
157
+ }
158
+
159
+ /**
160
+ * @return string
161
+ */
162
+ public function getSDKVersion()
163
+ {
164
+ return $this->sdk->version();
165
+ }
166
+
167
+ /**
168
+ * @return string
169
+ */
170
+ public function getMysqlVersion()
171
+ {
172
+ global $wpdb;
173
+
174
+ $version = empty($wpdb->use_mysqli) ? mysql_get_server_info() : mysqli_get_server_info($wpdb->dbh);
175
+
176
+ return $version ? $version : 'unknown';
177
+ }
178
+
179
+ /**
180
+ * @return string
181
+ */
182
+ public function getSiteLanguage()
183
+ {
184
+ return get_locale();
185
+ }
186
+
187
+
188
+ /**
189
+ * Current WP theme
190
+ *
191
+ * @return false|string
192
+ */
193
+ public function getCurrentThemeName()
194
+ {
195
+ return wp_get_theme()->get('Name');
196
+ }
197
+
198
+ /**
199
+ * Get active plugins list
200
+ *
201
+ * @return array
202
+ */
203
+ public function getActivePluginsList()
204
+ {
205
+ if (!function_exists('get_plugins')) {
206
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
207
+ }
208
+
209
+ $allPlugins = get_plugins();
210
+
211
+ $activePluginsNames = array_map(function ($path) use ($allPlugins) {
212
+ return $allPlugins[$path]['Name'];
213
+ }, get_option('active_plugins'));
214
+
215
+ return $activePluginsNames;
216
+ }
217
+ }
analyst/{analyst/src → src}/Contracts/AnalystContract.php RENAMED
@@ -1,12 +1,12 @@
1
- <?php
2
- namespace Analyst\Contracts;
3
-
4
- interface AnalystContract
5
- {
6
- /**
7
- * Must return version of analyst
8
- *
9
- * @return string
10
- */
11
- public static function version();
12
- }
1
+ <?php
2
+ namespace Analyst\Contracts;
3
+
4
+ interface AnalystContract
5
+ {
6
+ /**
7
+ * Must return version of analyst
8
+ *
9
+ * @return string
10
+ */
11
+ public static function version();
12
+ }
analyst/{analyst/src → src}/Contracts/CacheContract.php RENAMED
@@ -1,47 +1,47 @@
1
- <?php
2
-
3
- namespace Analyst\Contracts;
4
-
5
- /**
6
- * Interface CacheContract
7
- *
8
- * @since 1.1.5
9
- */
10
- interface CacheContract
11
- {
12
- /**
13
- * Save value with given key
14
- *
15
- * @param string $key
16
- * @param string $value
17
- *
18
- * @return static
19
- */
20
- public function put($key, $value);
21
-
22
- /**
23
- * Get value by given key
24
- *
25
- * @param $key
26
- *
27
- * @param null $default
28
- * @return string
29
- */
30
- public function get($key, $default = null);
31
-
32
- /**
33
- * @param $key
34
- *
35
- * @return static
36
- */
37
- public function delete($key);
38
-
39
- /**
40
- * Should get value and remove it from cache
41
- *
42
- * @param $key
43
- * @param null $default
44
- * @return mixed
45
- */
46
- public function pop($key, $default = null);
47
- }
1
+ <?php
2
+
3
+ namespace Analyst\Contracts;
4
+
5
+ /**
6
+ * Interface CacheContract
7
+ *
8
+ * @since 1.1.5
9
+ */
10
+ interface CacheContract
11
+ {
12
+ /**
13
+ * Save value with given key
14
+ *
15
+ * @param string $key
16
+ * @param string $value
17
+ *
18
+ * @return static
19
+ */
20
+ public function put($key, $value);
21
+
22
+ /**
23
+ * Get value by given key
24
+ *
25
+ * @param $key
26
+ *
27
+ * @param null $default
28
+ * @return string
29
+ */
30
+ public function get($key, $default = null);
31
+
32
+ /**
33
+ * @param $key
34
+ *
35
+ * @return static
36
+ */
37
+ public function delete($key);
38
+
39
+ /**
40
+ * Should get value and remove it from cache
41
+ *
42
+ * @param $key
43
+ * @param null $default
44
+ * @return mixed
45
+ */
46
+ public function pop($key, $default = null);
47
+ }
analyst/{analyst/src → src}/Contracts/HttpClientContract.php RENAMED
@@ -1,25 +1,25 @@
1
- <?php
2
- namespace Analyst\Contracts;
3
-
4
- use Analyst\ApiResponse;
5
-
6
- interface HttpClientContract
7
- {
8
- /**
9
- * Make an http request
10
- *
11
- * @param $method
12
- * @param $url
13
- * @param $body
14
- * @param $headers
15
- * @return ApiResponse
16
- */
17
- public function request($method, $url, $body, $headers);
18
-
19
- /**
20
- * Must return `true` if client is supported
21
- *
22
- * @return bool
23
- */
24
- public static function hasSupport();
25
- }
1
+ <?php
2
+ namespace Analyst\Contracts;
3
+
4
+ use Analyst\ApiResponse;
5
+
6
+ interface HttpClientContract
7
+ {
8
+ /**
9
+ * Make an http request
10
+ *
11
+ * @param $method
12
+ * @param $url
13
+ * @param $body
14
+ * @param $headers
15
+ * @return ApiResponse
16
+ */
17
+ public function request($method, $url, $body, $headers);
18
+
19
+ /**
20
+ * Must return `true` if client is supported
21
+ *
22
+ * @return bool
23
+ */
24
+ public static function hasSupport();
25
+ }
analyst/{analyst/src → src}/Contracts/RequestContract.php RENAMED
@@ -1,22 +1,22 @@
1
- <?php
2
-
3
- namespace Analyst\Contracts;
4
-
5
- use Analyst\ApiResponse;
6
-
7
- interface RequestContract
8
- {
9
- /**
10
- * Cast request data to array
11
- *
12
- * @return array
13
- */
14
- public function toArray();
15
-
16
- /**
17
- * Execute the request
18
- * @param RequestorContract $requestor
19
- * @return ApiResponse
20
- */
21
- public function execute(RequestorContract $requestor);
22
- }
1
+ <?php
2
+
3
+ namespace Analyst\Contracts;
4
+
5
+ use Analyst\ApiResponse;
6
+
7
+ interface RequestContract
8
+ {
9
+ /**
10
+ * Cast request data to array
11
+ *
12
+ * @return array
13
+ */
14
+ public function toArray();
15
+
16
+ /**
17
+ * Execute the request
18
+ * @param RequestorContract $requestor
19
+ * @return ApiResponse
20
+ */
21
+ public function execute(RequestorContract $requestor);
22
+ }
analyst/{analyst/src → src}/Contracts/RequestorContract.php RENAMED
@@ -1,44 +1,44 @@
1
- <?php
2
-
3
- namespace Analyst\Contracts;
4
-
5
- interface RequestorContract
6
- {
7
- /**
8
- * Get request
9
- *
10
- * @param $url
11
- * @param array $headers
12
- * @return mixed
13
- */
14
- public function get($url, $headers = []);
15
-
16
- /**
17
- * Post request
18
- *
19
- * @param $url
20
- * @param $body
21
- * @param array $headers
22
- * @return mixed
23
- */
24
- public function post($url, $body = [], $headers = []);
25
-
26
- /**
27
- * Put request
28
- *
29
- * @param $url
30
- * @param $body
31
- * @param array $headers
32
- * @return mixed
33
- */
34
- public function put($url, $body = [], $headers = []);
35
-
36
- /**
37
- * Delete request
38
- *
39
- * @param $url
40
- * @param array $headers
41
- * @return mixed
42
- */
43
- public function delete($url, $headers = []);
44
- }
1
+ <?php
2
+
3
+ namespace Analyst\Contracts;
4
+
5
+ interface RequestorContract
6
+ {
7
+ /**
8
+ * Get request
9
+ *
10
+ * @param $url
11
+ * @param array $headers
12
+ * @return mixed
13
+ */
14
+ public function get($url, $headers = []);
15
+
16
+ /**
17
+ * Post request
18
+ *
19
+ * @param $url
20
+ * @param $body
21
+ * @param array $headers
22
+ * @return mixed
23
+ */
24
+ public function post($url, $body = [], $headers = []);
25
+
26
+ /**
27
+ * Put request
28
+ *
29
+ * @param $url
30
+ * @param $body
31
+ * @param array $headers
32
+ * @return mixed
33
+ */
34
+ public function put($url, $body = [], $headers = []);
35
+
36
+ /**
37
+ * Delete request
38
+ *
39
+ * @param $url
40
+ * @param array $headers
41
+ * @return mixed
42
+ */
43
+ public function delete($url, $headers = []);
44
+ }
analyst/{analyst/src → src}/Contracts/TrackerContract.php RENAMED
@@ -1,69 +1,69 @@
1
- <?php
2
-
3
- namespace Analyst\Contracts;
4
-
5
- interface TrackerContract
6
- {
7
- /**
8
- * Should register activation and deactivation
9
- * event hooks
10
- *
11
- * @return void
12
- */
13
- public function registerHooks();
14
-
15
- /**
16
- * Will fire when admin activates plugin
17
- *
18
- * @return void
19
- */
20
- public function onActivePluginListener();
21
-
22
- /**
23
- * Will fire when admin deactivates plugin
24
- *
25
- * @return void
26
- */
27
- public function onDeactivatePluginListener();
28
-
29
- /**
30
- * Will fire when user opted in
31
- *
32
- * @return void
33
- */
34
- public function onOptInListener();
35
-
36
- /**
37
- * Will fire when user opted out
38
- *
39
- * @return void
40
- */
41
- public function onOptOutListener();
42
-
43
- /**
44
- * Will fire when user accept opt/in at first time
45
- *
46
- * @return void
47
- */
48
- public function onInstallListener();
49
-
50
- /**
51
- * Will fire when user skipped installation
52
- *
53
- * @return void
54
- */
55
- public function onSkipInstallListener();
56
-
57
- /**
58
- * Will fire when user delete plugin through admin panel.
59
- * This action will happen if admin at least once
60
- * activated the plugin.
61
- *
62
- * The register_uninstall_hook function accepts only static
63
- * function or global function to be executed, so this is
64
- * why this method is static
65
- *
66
- * @return void
67
- */
68
- public static function onUninstallPluginListener();
69
- }
1
+ <?php
2
+
3
+ namespace Analyst\Contracts;
4
+
5
+ interface TrackerContract
6
+ {
7
+ /**
8
+ * Should register activation and deactivation
9
+ * event hooks
10
+ *
11
+ * @return void
12
+ */
13
+ public function registerHooks();
14
+
15
+ /**
16
+ * Will fire when admin activates plugin
17
+ *
18
+ * @return void
19
+ */
20
+ public function onActivePluginListener();
21
+
22
+ /**
23
+ * Will fire when admin deactivates plugin
24
+ *
25
+ * @return void
26
+ */
27
+ public function onDeactivatePluginListener();
28
+
29
+ /**
30
+ * Will fire when user opted in
31
+ *
32
+ * @return void
33
+ */
34
+ public function onOptInListener();
35
+
36
+ /**
37
+ * Will fire when user opted out
38
+ *
39
+ * @return void
40
+ */
41
+ public function onOptOutListener();
42
+
43
+ /**
44
+ * Will fire when user accept opt/in at first time
45
+ *
46
+ * @return void
47
+ */
48
+ public function onInstallListener();
49
+
50
+ /**
51
+ * Will fire when user skipped installation
52
+ *
53
+ * @return void
54
+ */
55
+ public function onSkipInstallListener();
56
+
57
+ /**
58
+ * Will fire when user delete plugin through admin panel.
59
+ * This action will happen if admin at least once
60
+ * activated the plugin.
61
+ *
62
+ * The register_uninstall_hook function accepts only static
63
+ * function or global function to be executed, so this is
64
+ * why this method is static
65
+ *
66
+ * @return void
67
+ */
68
+ public static function onUninstallPluginListener();
69
+ }
analyst/{analyst/src → src}/Core/AbstractFactory.php RENAMED
@@ -1,27 +1,27 @@
1
- <?php
2
-
3
- namespace Analyst\Core;
4
-
5
- abstract class AbstractFactory
6
- {
7
- /**
8
- * Unserialize to NoticeFactory
9
- *
10
- * @param $raw
11
- * @return static
12
- */
13
- protected static function unserialize($raw)
14
- {
15
- $instance = @unserialize($raw);
16
-
17
- $isProperObject = is_object($instance) && $instance instanceof static;
18
-
19
- // In case for some reason unserialized object is not
20
- // NoticeFactory we make sure it is NoticeFactory
21
- if (!$isProperObject) {
22
- $instance = new static();
23
- }
24
-
25
- return $instance;
26
- }
27
- }
1
+ <?php
2
+
3
+ namespace Analyst\Core;
4
+
5
+ abstract class AbstractFactory
6
+ {
7
+ /**
8
+ * Unserialize to NoticeFactory
9
+ *
10
+ * @param $raw
11
+ * @return static
12
+ */
13
+ protected static function unserialize($raw)
14
+ {
15
+ $instance = @unserialize($raw);
16
+
17
+ $isProperObject = is_object($instance) && $instance instanceof static;
18
+
19
+ // In case for some reason unserialized object is not
20
+ // NoticeFactory we make sure it is NoticeFactory
21
+ if (!$isProperObject) {
22
+ $instance = new static();
23
+ }
24
+
25
+ return $instance;
26
+ }
27
+ }
analyst/{analyst/src → src}/Http/CurlHttpClient.php RENAMED
@@ -1,102 +1,102 @@
1
- <?php
2
-
3
- namespace Analyst\Http;
4
-
5
- use Analyst\ApiResponse;
6
- use Analyst\Contracts\HttpClientContract;
7
-
8
- class CurlHttpClient implements HttpClientContract
9
- {
10
- /**
11
- * Make an http request
12
- *
13
- * @param $method
14
- * @param $url
15
- * @param array $body
16
- * @param $headers
17
- * @return mixed
18
- */
19
- public function request($method, $url, $body, $headers)
20
- {
21
- $method = strtoupper($method);
22
-
23
- $options = [
24
- CURLOPT_RETURNTRANSFER => true,
25
- CURLOPT_URL => $url,
26
- CURLOPT_HTTPHEADER => $this->prepareRequestHeaders($headers),
27
- CURLOPT_CUSTOMREQUEST => $method,
28
- CURLOPT_FAILONERROR => true,
29
- CURLOPT_HEADER => true,
30
- CURLOPT_TIMEOUT => 30,
31
- ];
32
-
33
- if ($method === 'POST') {
34
- $options[CURLOPT_POST] = 1;
35
- $options[CURLOPT_POSTFIELDS] = json_encode($body);
36
- }
37
-
38
- $curl = curl_init();
39
-
40
- curl_setopt_array($curl, $options);
41
-
42
- $response = curl_exec($curl);
43
-
44
- list($rawHeaders, $rawBody) = explode("\r\n\r\n", $response, 2);
45
-
46
- $info = curl_getinfo($curl);
47
-
48
- curl_close($curl);
49
-
50
- $responseHeaders = $this->resolveResponseHeaders($rawHeaders);
51
- $responseBody = json_decode($rawBody, true);
52
-
53
- return new ApiResponse($responseBody, $info['http_code'], $responseHeaders);
54
- }
55
-
56
- /**
57
- * Must return `true` if client is supported
58
- *
59
- * @return bool
60
- */
61
- public static function hasSupport()
62
- {
63
- return function_exists('curl_version');
64
- }
65
-
66
- /**
67
- * Modify request headers from key value pair
68
- * to vector array
69
- *
70
- * @param array $headers
71
- * @return array
72
- */
73
- protected function prepareRequestHeaders ($headers)
74
- {
75
- return array_map(function ($key, $value) {
76
- return sprintf('%s:%s', $key, $value);
77
- }, array_keys($headers), $headers);
78
- }
79
-
80
- /**
81
- * Resolve raw response headers as
82
- * associative array
83
- *
84
- * @param $rawHeaders
85
- * @return array
86
- */
87
- private function resolveResponseHeaders($rawHeaders)
88
- {
89
- $headers = [];
90
-
91
- foreach (explode("\r\n", $rawHeaders) as $i => $line) {
92
- $parts = explode(': ', $line);
93
-
94
- if (count($parts) === 1) {
95
- continue;
96
- }
97
-
98
- $headers[$parts[0]] = $parts[1];
99
- }
100
- return $headers;
101
- }
102
- }
1
+ <?php
2
+
3
+ namespace Analyst\Http;
4
+
5
+ use Analyst\ApiResponse;
6
+ use Analyst\Contracts\HttpClientContract;
7
+
8
+ class CurlHttpClient implements HttpClientContract
9
+ {
10
+ /**
11
+ * Make an http request
12
+ *
13
+ * @param $method
14
+ * @param $url
15
+ * @param array $body
16
+ * @param $headers
17
+ * @return mixed
18
+ */
19
+ public function request($method, $url, $body, $headers)
20
+ {
21
+ $method = strtoupper($method);
22
+
23
+ $options = [
24
+ CURLOPT_RETURNTRANSFER => true,
25
+ CURLOPT_URL => $url,
26
+ CURLOPT_HTTPHEADER => $this->prepareRequestHeaders($headers),
27
+ CURLOPT_CUSTOMREQUEST => $method,
28
+ CURLOPT_FAILONERROR => true,
29
+ CURLOPT_HEADER => true,
30
+ CURLOPT_TIMEOUT => 30,
31
+ ];
32
+
33
+ if ($method === 'POST') {
34
+ $options[CURLOPT_POST] = 1;
35
+ $options[CURLOPT_POSTFIELDS] = json_encode($body);
36
+ }
37
+
38
+ $curl = curl_init();
39
+
40
+ curl_setopt_array($curl, $options);
41
+
42
+ $response = curl_exec($curl);
43
+
44
+ list($rawHeaders, $rawBody) = explode("\r\n\r\n", $response, 2);
45
+
46
+ $info = curl_getinfo($curl);
47
+
48
+ curl_close($curl);
49
+
50
+ $responseHeaders = $this->resolveResponseHeaders($rawHeaders);
51
+ $responseBody = json_decode($rawBody, true);
52
+
53
+ return new ApiResponse($responseBody, $info['http_code'], $responseHeaders);
54
+ }
55
+
56
+ /**
57
+ * Must return `true` if client is supported
58
+ *
59
+ * @return bool
60
+ */
61
+ public static function hasSupport()
62
+ {
63
+ return function_exists('curl_version');
64
+ }
65
+
66
+ /**
67
+ * Modify request headers from key value pair
68
+ * to vector array
69
+ *
70
+ * @param array $headers
71
+ * @return array
72
+ */
73
+ protected function prepareRequestHeaders ($headers)
74
+ {
75
+ return array_map(function ($key, $value) {
76
+ return sprintf('%s:%s', $key, $value);
77
+ }, array_keys($headers), $headers);
78
+ }
79
+
80
+ /**
81
+ * Resolve raw response headers as
82
+ * associative array
83
+ *
84
+ * @param $rawHeaders
85
+ * @return array
86
+ */
87
+ private function resolveResponseHeaders($rawHeaders)
88
+ {
89
+ $headers = [];
90
+
91
+ foreach (explode("\r\n", $rawHeaders) as $i => $line) {
92
+ $parts = explode(': ', $line);
93
+
94
+ if (count($parts) === 1) {
95
+ continue;
96
+ }
97
+
98
+ $headers[$parts[0]] = $parts[1];
99
+ }
100
+ return $headers;
101
+ }
102
+ }
analyst/{analyst/src → src}/Http/DummyHttpClient.php RENAMED
@@ -1,33 +1,33 @@
1
- <?php
2
-
3
- namespace Analyst\Http;
4
-
5
- use Analyst\ApiResponse;
6
- use Analyst\Contracts\HttpClientContract;
7
-
8
- class DummyHttpClient implements HttpClientContract
9
- {
10
- /**
11
- * Make an http request
12
- *
13
- * @param $method
14
- * @param $url
15
- * @param $body
16
- * @param $headers
17
- * @return ApiResponse
18
- */
19
- public function request($method, $url, $body, $headers)
20
- {
21
- return new ApiResponse('Dummy response', 200, []);
22
- }
23
-
24
- /**
25
- * Must return `true` if client is supported
26
- *
27
- * @return bool
28
- */
29
- public static function hasSupport()
30
- {
31
- return true;
32
- }
33
- }
1
+ <?php
2
+
3
+ namespace Analyst\Http;
4
+
5
+ use Analyst\ApiResponse;
6
+ use Analyst\Contracts\HttpClientContract;
7
+
8
+ class DummyHttpClient implements HttpClientContract
9
+ {
10
+ /**
11
+ * Make an http request
12
+ *
13
+ * @param $method
14
+ * @param $url
15
+ * @param $body
16
+ * @param $headers
17
+ * @return ApiResponse
18
+ */
19
+ public function request($method, $url, $body, $headers)
20
+ {
21
+ return new ApiResponse('Dummy response', 200, []);
22
+ }
23
+
24
+ /**
25
+ * Must return `true` if client is supported
26
+ *
27
+ * @return bool
28
+ */
29
+ public static function hasSupport()
30
+ {
31
+ return true;
32
+ }
33
+ }
analyst/{analyst/src → src}/Http/Requests/AbstractLoggerRequest.php RENAMED
@@ -1,64 +1,64 @@
1
- <?php
2
-
3
- namespace Analyst\Http\Requests;
4
-
5
- use Analyst\ApiResponse;
6
- use Analyst\Collector;
7
- use Analyst\Contracts\RequestContract;
8
- use Analyst\Contracts\RequestorContract;
9
-
10
- abstract class AbstractLoggerRequest implements RequestContract
11
- {
12
- /**
13
- * @var Collector
14
- */
15
- protected $collector;
16
-
17
- /**
18
- * @var integer
19
- */
20
- protected $id;
21
-
22
- /**
23
- * @var string
24
- */
25
- protected $path;
26
-
27
- public function __construct(Collector $collector, $pluginId, $path)
28
- {
29
- $this->collector = $collector;
30
- $this->id = $pluginId;
31
- $this->path = $path;
32
- }
33
-
34
- /**
35
- * Cast request data to array
36
- *
37
- * @return array
38
- */
39
- public function toArray()
40
- {
41
- return [
42
- 'plugin_id' => $this->id,
43
- 'php_version' => $this->collector->getPHPVersion(),
44
- 'wp_version' => $this->collector->getWordPressVersion(),
45
- 'plugin_version' => $this->collector->getPluginVersion($this->path),
46
- 'url' => $this->collector->getSiteUrl(),
47
- 'sdk_version' => $this->collector->getSDKVersion(),
48
- 'ip' => $this->collector->getServerIp(),
49
- 'mysql_version' => $this->collector->getMysqlVersion(),
50
- 'locale' => $this->collector->getSiteLanguage(),
51
- 'current_theme' => $this->collector->getCurrentThemeName(),
52
- 'active_plugins_list' => implode(', ', $this->collector->getActivePluginsList()),
53
- 'email' => $this->collector->getGeneralEmailAddress(),
54
- 'name' => $this->collector->getCurrentUserName()
55
- ];
56
- }
57
-
58
- /**
59
- * Execute the request
60
- * @param RequestorContract $requestor
61
- * @return ApiResponse
62
- */
63
- public abstract function execute(RequestorContract $requestor);
64
- }
1
+ <?php
2
+
3
+ namespace Analyst\Http\Requests;
4
+
5
+ use Analyst\ApiResponse;
6
+ use Analyst\Collector;
7
+ use Analyst\Contracts\RequestContract;
8
+ use Analyst\Contracts\RequestorContract;
9
+
10
+ abstract class AbstractLoggerRequest implements RequestContract
11
+ {
12
+ /**
13
+ * @var Collector
14
+ */
15
+ protected $collector;
16
+
17
+ /**
18
+ * @var integer
19
+ */
20
+ protected $id;
21
+
22
+ /**
23
+ * @var string
24
+ */
25
+ protected $path;
26
+
27
+ public function __construct(Collector $collector, $pluginId, $path)
28
+ {
29
+ $this->collector = $collector;
30
+ $this->id = $pluginId;
31
+ $this->path = $path;
32
+ }
33
+
34
+ /**
35
+ * Cast request data to array
36
+ *
37
+ * @return array
38
+ */
39
+ public function toArray()
40
+ {
41
+ return [
42
+ 'plugin_id' => $this->id,
43
+ 'php_version' => $this->collector->getPHPVersion(),
44
+ 'wp_version' => $this->collector->getWordPressVersion(),
45
+ 'plugin_version' => $this->collector->getPluginVersion($this->path),
46
+ 'url' => $this->collector->getSiteUrl(),
47
+ 'sdk_version' => $this->collector->getSDKVersion(),
48
+ 'ip' => $this->collector->getServerIp(),
49
+ 'mysql_version' => $this->collector->getMysqlVersion(),
50
+ 'locale' => $this->collector->getSiteLanguage(),
51
+ 'current_theme' => $this->collector->getCurrentThemeName(),
52
+ 'active_plugins_list' => implode(', ', $this->collector->getActivePluginsList()),
53
+ 'email' => $this->collector->getGeneralEmailAddress(),
54
+ 'name' => $this->collector->getCurrentUserName()
55
+ ];
56
+ }
57
+
58
+ /**
59
+ * Execute the request
60
+ * @param RequestorContract $requestor
61
+ * @return ApiResponse
62
+ */
63
+ public abstract function execute(RequestorContract $requestor);
64
+ }
analyst/{analyst/src → src}/Http/Requests/ActivateRequest.php RENAMED
@@ -1,42 +1,42 @@
1
- <?php
2
-
3
- namespace Analyst\Http\Requests;
4
-
5
- use Analyst\ApiResponse;
6
- use Analyst\Collector;
7
- use Analyst\Contracts\RequestContract;
8
- use Analyst\Contracts\RequestorContract;
9
-
10
- /**
11
- * Class ActivateRequest
12
- *
13
- * Is is very similar to install request
14
- * but with different path
15
- *
16
- * @since 0.9.12
17
- */
18
- class ActivateRequest extends AbstractLoggerRequest
19
- {
20
- /**
21
- * Execute the request
22
- * @param RequestorContract $requestor
23
- * @return ApiResponse
24
- */
25
- public function execute(RequestorContract $requestor)
26
- {
27
- return $requestor->post('logger/activate', $this->toArray());
28
- }
29
-
30
- /**
31
- * Make request instance
32
- *
33
- * @param Collector $collector
34
- * @param $pluginId
35
- * @param $path
36
- * @return static
37
- */
38
- public static function make(Collector $collector, $pluginId, $path)
39
- {
40
- return new static($collector, $pluginId, $path);
41
- }
42
- }
1
+ <?php
2
+
3
+ namespace Analyst\Http\Requests;
4
+
5
+ use Analyst\ApiResponse;
6
+ use Analyst\Collector;
7
+ use Analyst\Contracts\RequestContract;
8
+ use Analyst\Contracts\RequestorContract;
9
+
10
+ /**
11
+ * Class ActivateRequest
12
+ *
13
+ * Is is very similar to install request
14
+ * but with different path
15
+ *
16
+ * @since 0.9.12
17
+ */
18
+ class ActivateRequest extends AbstractLoggerRequest
19
+ {
20
+ /**
21
+ * Execute the request
22
+ * @param RequestorContract $requestor
23
+ * @return ApiResponse
24
+ */
25
+ public function execute(RequestorContract $requestor)
26
+ {
27
+ return $requestor->post('logger/activate', $this->toArray());
28
+ }
29
+
30
+ /**
31
+ * Make request instance
32
+ *
33
+ * @param Collector $collector
34
+ * @param $pluginId
35
+ * @param $path
36
+ * @return static
37
+ */
38
+ public static function make(Collector $collector, $pluginId, $path)
39
+ {
40
+ return new static($collector, $pluginId, $path);
41
+ }
42
+ }
analyst/{analyst/src → src}/Http/Requests/DeactivateRequest.php RENAMED
@@ -1,64 +1,64 @@
1
- <?php
2
-
3
- namespace Analyst\Http\Requests;
4
-
5
- use Analyst\ApiResponse;
6
- use Analyst\Collector;
7
- use Analyst\Contracts\RequestorContract;
8
-
9
- /**
10
- * Class DeactivateRequest
11
- *
12
- * @since 0.9.10
13
- */
14
- class DeactivateRequest extends AbstractLoggerRequest
15
- {
16
- /**
17
- * @var string
18
- */
19
- protected $question;
20
-
21
- /**
22
- * @var string
23
- */
24
- protected $answer;
25
-
26
- /**
27
- * @param Collector $collector
28
- * @param $pluginId
29
- * @param $path
30
- * @param $question
31
- * @param $answer
32
- * @return static
33
- */
34
- public static function make(Collector $collector, $pluginId, $path, $question, $answer)
35
- {
36
- return new static($collector, $pluginId, $path, $question, $answer);
37
- }
38
-
39
- public function __construct(Collector $collector, $pluginId, $path, $question, $answer)
40
- {
41
- parent::__construct($collector, $pluginId, $path);
42
-
43
- $this->question = $question;
44
- $this->answer = $answer;
45
- }
46
-
47
- public function toArray()
48
- {
49
- return array_merge(parent::toArray(), [
50
- 'question' => $this->question,
51
- 'answer' => $this->answer,
52
- ]);
53
- }
54
-
55
- /**
56
- * Execute the request
57
- * @param RequestorContract $requestor
58
- * @return ApiResponse
59
- */
60
- public function execute(RequestorContract $requestor)
61
- {
62
- return $requestor->post('logger/deactivate', $this->toArray());
63
- }
64
- }
1
+ <?php
2
+
3
+ namespace Analyst\Http\Requests;
4
+
5
+ use Analyst\ApiResponse;
6
+ use Analyst\Collector;
7
+ use Analyst\Contracts\RequestorContract;
8
+
9
+ /**
10
+ * Class DeactivateRequest
11
+ *
12
+ * @since 0.9.10
13
+ */
14
+ class DeactivateRequest extends AbstractLoggerRequest
15
+ {
16
+ /**
17
+ * @var string
18
+ */
19
+ protected $question;
20
+
21
+ /**
22
+ * @var string
23
+ */
24
+ protected $answer;
25
+
26
+ /**
27
+ * @param Collector $collector
28
+ * @param $pluginId
29
+ * @param $path
30
+ * @param $question
31
+ * @param $answer
32
+ * @return static
33
+ */
34
+ public static function make(Collector $collector, $pluginId, $path, $question, $answer)
35
+ {
36
+ return new static($collector, $pluginId, $path, $question, $answer);
37
+ }
38
+
39
+ public function __construct(Collector $collector, $pluginId, $path, $question, $answer)
40
+ {
41
+ parent::__construct($collector, $pluginId, $path);
42
+
43
+ $this->question = $question;
44
+ $this->answer = $answer;
45
+ }
46
+
47
+ public function toArray()
48
+ {
49
+ return array_merge(parent::toArray(), [
50
+ 'question' => $this->question,
51
+ 'answer' => $this->answer,
52
+ ]);
53
+ }
54
+
55
+ /**
56
+ * Execute the request
57
+ * @param RequestorContract $requestor
58
+ * @return ApiResponse
59
+ */
60
+ public function execute(RequestorContract $requestor)
61
+ {
62
+ return $requestor->post('logger/deactivate', $this->toArray());
63
+ }
64
+ }
analyst/{analyst/src → src}/Http/Requests/InstallRequest.php RENAMED
@@ -1,38 +1,38 @@
1
- <?php
2
-
3
- namespace Analyst\Http\Requests;
4
-
5
- use Analyst\ApiResponse;
6
- use Analyst\Collector;
7
- use Analyst\Contracts\RequestorContract;
8
-
9
- /**
10
- * Class InstallRequest
11
- *
12
- * @since 0.9.4
13
- */
14
- class InstallRequest extends AbstractLoggerRequest
15
- {
16
- /**
17
- * Execute the request
18
- * @param RequestorContract $requestor
19
- * @return ApiResponse
20
- */
21
- public function execute(RequestorContract $requestor)
22
- {
23
- return $requestor->post('logger/install', $this->toArray());
24
- }
25
-
26
- /**
27
- * Make request instance
28
- *
29
- * @param Collector $collector
30
- * @param $pluginId
31
- * @param $path
32
- * @return static
33
- */
34
- public static function make(Collector $collector, $pluginId, $path)
35
- {
36
- return new static($collector, $pluginId, $path);
37
- }
38
- }
1
+ <?php
2
+
3
+ namespace Analyst\Http\Requests;
4
+
5
+ use Analyst\ApiResponse;
6
+ use Analyst\Collector;
7
+ use Analyst\Contracts\RequestorContract;
8
+
9
+ /**
10
+ * Class InstallRequest
11
+ *
12
+ * @since 0.9.4
13
+ */
14
+ class InstallRequest extends AbstractLoggerRequest
15
+ {
16
+ /**
17
+ * Execute the request
18
+ * @param RequestorContract $requestor
19
+ * @return ApiResponse
20
+ */
21
+ public function execute(RequestorContract $requestor)
22
+ {
23
+ return $requestor->post('logger/install', $this->toArray());
24
+ }
25
+
26
+ /**
27
+ * Make request instance
28
+ *
29
+ * @param Collector $collector
30
+ * @param $pluginId
31
+ * @param $path
32
+ * @return static
33
+ */
34
+ public static function make(Collector $collector, $pluginId, $path)
35
+ {
36
+ return new static($collector, $pluginId, $path);
37
+ }
38
+ }
analyst/{analyst/src → src}/Http/Requests/OptInRequest.php RENAMED
@@ -1,42 +1,42 @@
1
- <?php
2
-
3
- namespace Analyst\Http\Requests;
4
-
5
- use Analyst\ApiResponse;
6
- use Analyst\Collector;
7
- use Analyst\Contracts\RequestContract;
8
- use Analyst\Contracts\RequestorContract;
9
-
10
- /**
11
- * Class OptInRequest
12
- *
13
- * Is is very similar to install request
14
- * but with different path
15
- *
16
- * @since 0.9.5
17
- */
18
- class OptInRequest extends AbstractLoggerRequest
19
- {
20
- /**
21
- * Execute the request
22
- * @param RequestorContract $requestor
23
- * @return ApiResponse
24
- */
25
- public function execute(RequestorContract $requestor)
26
- {
27
- return $requestor->post('logger/opt-in', $this->toArray());
28
- }
29
-
30
- /**
31
- * Make request instance
32
- *
33
- * @param Collector $collector
34
- * @param $pluginId
35
- * @param $path
36
- * @return static
37
- */
38
- public static function make(Collector $collector, $pluginId, $path)
39
- {
40
- return new static($collector, $pluginId, $path);
41
- }
42
- }
1
+ <?php
2
+
3
+ namespace Analyst\Http\Requests;
4
+
5
+ use Analyst\ApiResponse;
6
+ use Analyst\Collector;
7
+ use Analyst\Contracts\RequestContract;
8
+ use Analyst\Contracts\RequestorContract;
9
+
10
+ /**
11
+ * Class OptInRequest
12
+ *
13
+ * Is is very similar to install request
14
+ * but with different path
15
+ *
16
+ * @since 0.9.5
17
+ */
18
+ class OptInRequest extends AbstractLoggerRequest
19
+ {
20
+ /**
21
+ * Execute the request
22
+ * @param RequestorContract $requestor
23
+ * @return ApiResponse
24
+ */
25
+ public function execute(RequestorContract $requestor)
26
+ {
27
+ return $requestor->post('logger/opt-in', $this->toArray());
28
+ }
29
+
30
+ /**
31
+ * Make request instance
32
+ *
33
+ * @param Collector $collector
34
+ * @param $pluginId
35
+ * @param $path
36
+ * @return static
37
+ */
38
+ public static function make(Collector $collector, $pluginId, $path)
39
+ {
40
+ return new static($collector, $pluginId, $path);
41
+ }
42
+ }
analyst/{analyst/src → src}/Http/Requests/OptOutRequest.php RENAMED
@@ -1,40 +1,40 @@
1
- <?php
2
-
3
- namespace Analyst\Http\Requests;
4
-
5
- use Analyst\ApiResponse;
6
- use Analyst\Collector;
7
- use Analyst\Contracts\RequestContract;
8
- use Analyst\Contracts\RequestorContract;
9
-
10
- /**
11
- * Class OptOutRequest
12
- *
13
- * Is is very similar to install request
14
- * but with different path
15
- *
16
- * @since 0.9.9
17
- */
18
- class OptOutRequest extends AbstractLoggerRequest
19
- {
20
- /**
21
- * @param Collector $collector
22
- * @param $pluginId
23
- * @param $path
24
- * @return static
25
- */
26
- public static function make(Collector $collector, $pluginId, $path)
27
- {
28
- return new static($collector, $pluginId, $path);
29
- }
30
-
31
- /**
32
- * Execute the request
33
- * @param RequestorContract $requestor
34
- * @return ApiResponse
35
- */
36
- public function execute(RequestorContract $requestor)
37
- {
38
- return $requestor->post('logger/opt-out', $this->toArray());
39
- }
40
- }
1
+ <?php
2
+
3
+ namespace Analyst\Http\Requests;
4
+
5
+ use Analyst\ApiResponse;
6
+ use Analyst\Collector;
7
+ use Analyst\Contracts\RequestContract;
8
+ use Analyst\Contracts\RequestorContract;
9
+
10
+ /**
11
+ * Class OptOutRequest
12
+ *
13
+ * Is is very similar to install request
14
+ * but with different path
15
+ *
16
+ * @since 0.9.9
17
+ */
18
+ class OptOutRequest extends AbstractLoggerRequest
19
+ {
20
+ /**
21
+ * @param Collector $collector
22
+ * @param $pluginId
23
+ * @param $path
24
+ * @return static
25
+ */
26
+ public static function make(Collector $collector, $pluginId, $path)
27
+ {
28
+ return new static($collector, $pluginId, $path);
29
+ }
30
+
31
+ /**
32
+ * Execute the request
33
+ * @param RequestorContract $requestor
34
+ * @return ApiResponse
35
+ */
36
+ public function execute(RequestorContract $requestor)
37
+ {
38
+ return $requestor->post('logger/opt-out', $this->toArray());
39
+ }
40
+ }
analyst/{analyst/src → src}/Http/Requests/UninstallRequest.php RENAMED
@@ -1,36 +1,36 @@
1
- <?php
2
-
3
- namespace Analyst\Http\Requests;
4
-
5
- use Analyst\ApiResponse;
6
- use Analyst\Collector;
7
- use Analyst\Contracts\RequestorContract;
8
-
9
- /**
10
- * Class DeactivateRequest
11
- *
12
- * @since 0.9.13
13
- */
14
- class UninstallRequest extends AbstractLoggerRequest
15
- {
16
- /**
17
- * @param Collector $collector
18
- * @param $pluginId
19
- * @param $path
20
- * @return static
21
- */
22
- public static function make(Collector $collector, $pluginId, $path)
23
- {
24
- return new static($collector, $pluginId, $path);
25
- }
26
-
27
- /**
28
- * Execute the request
29
- * @param RequestorContract $requestor
30
- * @return ApiResponse
31
- */
32
- public function execute(RequestorContract $requestor)
33
- {
34
- return $requestor->post('logger/uninstall', $this->toArray());
35
- }
36
- }
1
+ <?php
2
+
3
+ namespace Analyst\Http\Requests;
4
+
5
+ use Analyst\ApiResponse;
6
+ use Analyst\Collector;
7
+ use Analyst\Contracts\RequestorContract;
8
+
9
+ /**
10
+ * Class DeactivateRequest
11
+ *
12
+ * @since 0.9.13
13
+ */
14
+ class UninstallRequest extends AbstractLoggerRequest
15
+ {
16
+ /**
17
+ * @param Collector $collector
18
+ * @param $pluginId
19
+ * @param $path
20
+ * @return static
21
+ */
22
+ public static function make(Collector $collector, $pluginId, $path)
23
+ {
24
+ return new static($collector, $pluginId, $path);
25
+ }
26
+
27
+ /**
28
+ * Execute the request
29
+ * @param RequestorContract $requestor
30
+ * @return ApiResponse
31
+ */
32
+ public function execute(RequestorContract $requestor)
33
+ {
34
+ return $requestor->post('logger/uninstall', $this->toArray());
35
+ }
36
+ }
analyst/{analyst/src → src}/Http/WordPressHttpClient.php RENAMED
@@ -1,61 +1,61 @@
1
- <?php
2
-
3
- namespace Analyst\Http;
4
-
5
- use WP_Error;
6
- use Analyst\ApiResponse;
7
- use Analyst\Contracts\HttpClientContract;
8
- use Requests_Utility_CaseInsensitiveDictionary;
9
-
10
- class WordPressHttpClient implements HttpClientContract
11
- {
12
- /**
13
- * Make an http request
14
- *
15
- * @param $method
16
- * @param $url
17
- * @param $body
18
- * @param $headers
19
- * @return ApiResponse
20
- */
21
- public function request($method, $url, $body, $headers)
22
- {
23
- $options = [
24
- 'body' => json_encode($body),
25
- 'headers' => $headers,
26
- 'method' => $method,
27
- 'timeout' => 30,
28
- ];
29
-
30
- $response = wp_remote_request($url, $options);
31
-
32
- $body = [];
33
- $responseHeaders = [];
34
-
35
- if ($response instanceof WP_Error) {
36
- $code = $response->get_error_code();
37
- } else {
38
- /** @var Requests_Utility_CaseInsensitiveDictionary $headers */
39
- $responseHeaders = $response['headers']->getAll();
40
- $body = json_decode($response['body'], true);
41
- $code = $response['response']['code'];
42
- }
43
-
44
-
45
- return new ApiResponse(
46
- $body,
47
- $code,
48
- $responseHeaders
49
- );
50
- }
51
-
52
- /**
53
- * Must return `true` if client is supported
54
- *
55
- * @return bool
56
- */
57
- public static function hasSupport()
58
- {
59
- return function_exists('wp_remote_request');
60
- }
61
- }
1
+ <?php
2
+
3
+ namespace Analyst\Http;
4
+
5
+ use WP_Error;
6
+ use Analyst\ApiResponse;
7
+ use Analyst\Contracts\HttpClientContract;
8
+ use Requests_Utility_CaseInsensitiveDictionary;
9
+
10
+ class WordPressHttpClient implements HttpClientContract
11
+ {
12
+ /**
13
+ * Make an http request
14
+ *
15
+ * @param $method
16
+ * @param $url
17
+ * @param $body
18
+ * @param $headers
19
+ * @return ApiResponse
20
+ */
21
+ public function request($method, $url, $body, $headers)
22
+ {
23
+ $options = [
24
+ 'body' => json_encode($body),
25
+ 'headers' => $headers,
26
+ 'method' => $method,
27
+ 'timeout' => 30,
28
+ ];
29
+
30
+ $response = wp_remote_request($url, $options);
31
+
32
+ $body = [];
33
+ $responseHeaders = [];
34
+
35
+ if ($response instanceof WP_Error) {
36
+ $code = $response->get_error_code();
37
+ } else {
38
+ /** @var Requests_Utility_CaseInsensitiveDictionary $headers */
39
+ $responseHeaders = $response['headers']->getAll();
40
+ $body = json_decode($response['body'], true);
41
+ $code = $response['response']['code'];
42
+ }
43
+
44
+
45
+ return new ApiResponse(
46
+ $body,
47
+ $code,
48
+ $responseHeaders
49
+ );
50
+ }
51
+
52
+ /**
53
+ * Must return `true` if client is supported
54
+ *
55
+ * @return bool
56
+ */
57
+ public static function hasSupport()
58
+ {
59
+ return function_exists('wp_remote_request');
60
+ }
61
+ }
analyst/{analyst/src → src}/Mutator.php RENAMED
@@ -1,103 +1,103 @@
1
- <?php
2
-
3
- namespace Analyst;
4
-
5
- use Analyst\Cache\DatabaseCache;
6
- use Analyst\Contracts\CacheContract;
7
- use Analyst\Notices\NoticeFactory;
8
-
9
- /**
10
- * Class Mutator mutates (modifies) UX with additional
11
- * functional
12
- */
13
- class Mutator
14
- {
15
- protected $notices = [];
16
-
17
- /**
18
- * @var NoticeFactory
19
- */
20
- protected $factory;
21
-
22
- /**
23
- * @var CacheContract
24
- */
25
- protected $cache;
26
-
27
- public function __construct()
28
- {
29
- $this->factory = NoticeFactory::instance();
30
-
31
- $this->notices = $this->factory->getNotices();
32
-
33
- $this->cache = DatabaseCache::getInstance();
34
- }
35
-
36
- /**
37
- * Register filters all necessary stuff.
38
- * Can be invoked only once.
39
- *
40
- * @return void
41
- */
42
- public function initialize()
43
- {
44
- $this->registerLinks();
45
- $this->registerAssets();
46
- $this->registerHooks();
47
- }
48
-
49
- /**
50
- * Register all necessary filters and templates
51
- *
52
- * @return void
53
- */
54
- protected function registerLinks()
55
- {
56
- add_action('admin_footer', function () {
57
- analyst_require_template('optout.php', [
58
- 'shieldImage' => analyst_assets_url('img/shield_question.png')
59
- ]);
60
-
61
- analyst_require_template('optin.php');
62
-
63
- analyst_require_template('forms/deactivate.php', [
64
- 'pencilImage' => analyst_assets_url('img/pencil.png'),
65
- 'smileImage' => analyst_assets_url('img/smile.png'),
66
- ]);
67
-
68
- analyst_require_template('forms/install.php', [
69
- 'pluginToInstall' => $this->cache->get('plugin_to_install'),
70
- 'shieldImage' => analyst_assets_url('img/shield_success.png'),
71
- ]);
72
- });
73
-
74
- add_action('admin_notices',function () {
75
- foreach ($this->notices as $notice) {
76
- analyst_require_template('notice.php', ['notice' => $notice]);
77
- }
78
- });
79
- }
80
-
81
- /**
82
- * Register all assets
83
- */
84
- public function registerAssets()
85
- {
86
- add_action('admin_enqueue_scripts', function () {
87
- wp_enqueue_style('custom', analyst_assets_url('/css/customize.css'));
88
- wp_enqueue_script('custom', analyst_assets_url('/js/customize.js'));
89
- });
90
- }
91
-
92
- /**
93
- * Register action hooks
94
- */
95
- public function registerHooks()
96
- {
97
- add_action('wp_ajax_analyst_notification_dismiss', function () {
98
- $this->factory->remove($_POST['id']);
99
-
100
- $this->factory->sync();
101
- });
102
- }
103
- }
1
+ <?php
2
+
3
+ namespace Analyst;
4
+
5
+ use Analyst\Cache\DatabaseCache;
6
+ use Analyst\Contracts\CacheContract;
7
+ use Analyst\Notices\NoticeFactory;
8
+
9
+ /**
10
+ * Class Mutator mutates (modifies) UX with additional
11
+ * functional
12
+ */
13
+ class Mutator
14
+ {
15
+ protected $notices = [];
16
+
17
+ /**
18
+ * @var NoticeFactory
19
+ */
20
+ protected $factory;
21
+
22
+ /**
23
+ * @var CacheContract
24
+ */
25
+ protected $cache;
26
+
27
+ public function __construct()
28
+ {
29
+ $this->factory = NoticeFactory::instance();
30
+
31
+ $this->notices = $this->factory->getNotices();
32
+
33
+ $this->cache = DatabaseCache::getInstance();
34
+ }
35
+
36
+ /**
37
+ * Register filters all necessary stuff.
38
+ * Can be invoked only once.
39
+ *
40
+ * @return void
41
+ */
42
+ public function initialize()
43
+ {
44
+ $this->registerLinks();
45
+ $this->registerAssets();
46
+ $this->registerHooks();
47
+ }
48
+
49
+ /**
50
+ * Register all necessary filters and templates
51
+ *
52
+ * @return void
53
+ */
54
+ protected function registerLinks()
55
+ {
56
+ add_action('admin_footer', function () {
57
+ analyst_require_template('optout.php', [
58
+ 'shieldImage' => analyst_assets_url('img/shield_question.png')
59
+ ]);
60
+
61
+ analyst_require_template('optin.php');
62
+
63
+ analyst_require_template('forms/deactivate.php', [
64
+ 'pencilImage' => analyst_assets_url('img/pencil.png'),
65
+ 'smileImage' => analyst_assets_url('img/smile.png'),
66
+ ]);
67
+
68
+ analyst_require_template('forms/install.php', [
69
+ 'pluginToInstall' => $this->cache->get('plugin_to_install'),
70
+ 'shieldImage' => analyst_assets_url('img/shield_success.png'),
71
+ ]);
72
+ });
73
+
74
+ add_action('admin_notices',function () {
75
+ foreach ($this->notices as $notice) {
76
+ analyst_require_template('notice.php', ['notice' => $notice]);
77
+ }
78
+ });
79
+ }
80
+
81
+ /**
82
+ * Register all assets
83
+ */
84
+ public function registerAssets()
85
+ {
86
+ add_action('admin_enqueue_scripts', function () {
87
+ wp_enqueue_style('custom', analyst_assets_url('/css/customize.css'));
88
+ wp_enqueue_script('custom', analyst_assets_url('/js/customize.js'));
89
+ });
90
+ }
91
+
92
+ /**
93
+ * Register action hooks
94
+ */
95
+ public function registerHooks()
96
+ {
97
+ add_action('wp_ajax_analyst_notification_dismiss', function () {
98
+ $this->factory->remove($_POST['id']);
99
+
100
+ $this->factory->sync();
101
+ });
102
+ }
103
+ }
analyst/{analyst/src → src}/Notices/Notice.php RENAMED
@@ -1,121 +1,121 @@
1
- <?php
2
-
3
- namespace Analyst\Notices;
4
-
5
- class Notice
6
- {
7
- /**
8
- * Id of notice
9
- *
10
- * @var string
11
- */
12
- protected $id;
13
-
14
- /**
15
- * Body of notice
16
- *
17
- * @var string
18
- */
19
- protected $body;
20
-
21
- /**
22
- * Account id
23
- *
24
- * @var string
25
- */
26
- protected $accountId;
27
-
28
- /**
29
- * The plugin name
30
- *
31
- * @var string
32
- */
33
- protected $pluginName;
34
-
35
- /**
36
- * New notice
37
- *
38
- * @param $id
39
- * @param $accountId
40
- * @param $body
41
- * @param null $pluginName
42
- *
43
- * @return Notice
44
- */
45
- public static function make($id, $accountId, $body, $pluginName = null)
46
- {
47
- return new Notice($id, $accountId, $body, $pluginName);
48
- }
49
-
50
- public function __construct($id, $accountId, $body, $pluginName)
51
- {
52
- $this->setId($id);
53
- $this->setBody($body);
54
- $this->setAccountId($accountId);
55
- $this->setPluginName($pluginName);
56
- }
57
-
58
- /**
59
- * @return string
60
- */
61
- public function getId()
62
- {
63
- return $this->id;
64
- }
65
-
66
- /**
67
- * @param string $id
68
- */
69
- public function setId($id)
70
- {
71
- $this->id = $id;
72
- }
73
-
74
- /**
75
- * @return string
76
- */
77
- public function getBody()
78
- {
79
- return $this->body;
80
- }
81
-
82
- /**
83
- * @param string $body
84
- */
85
- public function setBody($body)
86
- {
87
- $this->body = $body;
88
- }
89
-
90
- /**
91
- * @return string
92
- */
93
- public function getAccountId()
94
- {
95
- return $this->accountId;
96
- }
97
-
98
- /**
99
- * @param string $accountId
100
- */
101
- public function setAccountId($accountId)
102
- {
103
- $this->accountId = $accountId;
104
- }
105
-
106
- /**
107
- * @return string|null
108
- */
109
- public function getPluginName()
110
- {
111
- return $this->pluginName;
112
- }
113
-
114
- /**
115
- * @param string $pluginName
116
- */
117
- public function setPluginName($pluginName)
118
- {
119
- $this->pluginName = $pluginName;
120
- }
121
- }
1
+ <?php
2
+
3
+ namespace Analyst\Notices;
4
+
5
+ class Notice
6
+ {
7
+ /**
8
+ * Id of notice
9
+ *
10
+ * @var string
11
+ */
12
+ protected $id;
13
+
14
+ /**
15
+ * Body of notice
16
+ *
17
+ * @var string
18
+ */
19
+ protected $body;
20
+
21
+ /**
22
+ * Account id
23
+ *
24
+ * @var string
25
+ */
26
+ protected $accountId;
27
+
28
+ /**
29
+ * The plugin name
30
+ *
31
+ * @var string
32
+ */
33
+ protected $pluginName;
34
+
35
+ /**
36
+ * New notice
37
+ *
38
+ * @param $id
39
+ * @param $accountId
40
+ * @param $body
41
+ * @param null $pluginName
42
+ *
43
+ * @return Notice
44
+ */
45
+ public static function make($id, $accountId, $body, $pluginName = null)
46
+ {
47
+ return new Notice($id, $accountId, $body, $pluginName);
48
+ }
49
+
50
+ public function __construct($id, $accountId, $body, $pluginName)
51
+ {
52
+ $this->setId($id);
53
+ $this->setBody($body);
54
+ $this->setAccountId($accountId);
55
+ $this->setPluginName($pluginName);
56
+ }
57
+
58
+ /**
59
+ * @return string
60
+ */
61
+ public function getId()
62
+ {
63
+ return $this->id;
64
+ }
65
+
66
+ /**
67
+ * @param string $id
68
+ */
69
+ public function setId($id)
70
+ {
71
+ $this->id = $id;
72
+ }
73
+
74
+ /**
75
+ * @return string
76
+ */
77
+ public function getBody()
78
+ {
79
+ return $this->body;
80
+ }
81
+
82
+ /**
83
+ * @param string $body
84
+ */
85
+ public function setBody($body)
86
+ {
87
+ $this->body = $body;
88
+ }
89
+
90
+ /**
91
+ * @return string
92
+ */
93
+ public function getAccountId()
94
+ {
95
+ return $this->accountId;
96
+ }
97
+
98
+ /**
99
+ * @param string $accountId
100
+ */
101
+ public function setAccountId($accountId)
102
+ {
103
+ $this->accountId = $accountId;
104
+ }
105
+
106
+ /**
107
+ * @return string|null
108
+ */
109
+ public function getPluginName()
110
+ {
111
+ return $this->pluginName;
112
+ }
113
+
114
+ /**
115
+ * @param string $pluginName
116
+ */
117
+ public function setPluginName($pluginName)
118
+ {
119
+ $this->pluginName = $pluginName;
120
+ }
121
+ }
analyst/{analyst/src → src}/Notices/NoticeFactory.php RENAMED
@@ -1,130 +1,130 @@
1
- <?php
2
-
3
- namespace Analyst\Notices;
4
-
5
- use Analyst\Core\AbstractFactory;
6
-
7
- class NoticeFactory extends AbstractFactory
8
- {
9
- private static $instance;
10
-
11
- CONST OPTIONS_KEY = 'analyst_notices';
12
-
13
- /**
14
- * Application notifications
15
- *
16
- * @var array
17
- */
18
- protected $notices = [];
19
-
20
- /**
21
- * Read factory from options or make fresh instance
22
- *
23
- * @return NoticeFactory
24
- */
25
- public static function instance()
26
- {
27
- if (!static::$instance) {
28
- $raw = get_option(self::OPTIONS_KEY);
29
-
30
- // In case object is already unserialized
31
- // and instance of AccountDataFactory we
32
- // return it, in other case deal with
33
- // serialized string data
34
- if ($raw instanceof self) {
35
- static::$instance = $raw;
36
- } else {
37
- static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
38
- }
39
- }
40
-
41
- return static::$instance;
42
- }
43
-
44
- /**
45
- * Sync this object data with cache
46
- */
47
- public function sync()
48
- {
49
- update_option(self::OPTIONS_KEY, serialize($this));
50
- }
51
-
52
- /**
53
- * Sync this instance data with cache
54
- */
55
- public static function syncData()
56
- {
57
- static::instance()->sync();
58
- }
59
-
60
- /**
61
- * @return array
62
- */
63
- public function getNotices()
64
- {
65
- return $this->notices;
66
- }
67
-
68
- /**
69
- * Filter out notices for certain account
70
- *
71
- * @param $accountId
72
- * @return array
73
- */
74
- public function getNoticesForAccount($accountId)
75
- {
76
- return array_filter($this->notices, function (Notice $notice) use ($accountId) {
77
- return $notice->getAccountId() === $accountId;
78
- });
79
- }
80
-
81
- /**
82
- * Add new notice
83
- *
84
- * @param $notice
85
- *
86
- * @return $this
87
- */
88
- public function addNotice($notice)
89
- {
90
- array_push($this->notices, $notice);
91
-
92
- $this->sync();
93
-
94
- return $this;
95
- }
96
-
97
- /**
98
- * Find notice by id
99
- *
100
- * @param $id
101
- * @return Notice|null
102
- */
103
- public function find($id)
104
- {
105
- $notices = array_filter($this->notices, function (Notice $notice) use ($id) {
106
- return $notice->getId() === $id;
107
- });
108
-
109
- return array_pop($notices);
110
- }
111
-
112
- /**
113
- * Remove notice by it's id
114
- *
115
- * @param $id
116
- */
117
- public function remove($id)
118
- {
119
- // Get key of notice to remove
120
- $key = array_search(
121
- $this->find($id),
122
- $this->notices
123
- );
124
-
125
- // Unset notice with key
126
- unset($this->notices[$key]);
127
-
128
- $this->sync();
129
- }
130
- }
1
+ <?php
2
+
3
+ namespace Analyst\Notices;
4
+
5
+ use Analyst\Core\AbstractFactory;
6
+
7
+ class NoticeFactory extends AbstractFactory
8
+ {
9
+ private static $instance;
10
+
11
+ CONST OPTIONS_KEY = 'analyst_notices';
12
+
13
+ /**
14
+ * Application notifications
15
+ *
16
+ * @var array
17
+ */
18
+ protected $notices = [];
19
+
20
+ /**
21
+ * Read factory from options or make fresh instance
22
+ *
23
+ * @return NoticeFactory
24
+ */
25
+ public static function instance()
26
+ {
27
+ if (!static::$instance) {
28
+ $raw = get_option(self::OPTIONS_KEY);
29
+
30
+ // In case object is already unserialized
31
+ // and instance of AccountDataFactory we
32
+ // return it, in other case deal with
33
+ // serialized string data
34
+ if ($raw instanceof self) {
35
+ static::$instance = $raw;
36
+ } else {
37
+ static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
38
+ }
39
+ }
40
+
41
+ return static::$instance;
42
+ }
43
+
44
+ /**
45
+ * Sync this object data with cache
46
+ */
47
+ public function sync()
48
+ {
49
+ update_option(self::OPTIONS_KEY, serialize($this));
50
+ }
51
+
52
+ /**
53
+ * Sync this instance data with cache
54
+ */
55
+ public static function syncData()
56
+ {
57
+ static::instance()->sync();
58
+ }
59
+
60
+ /**
61
+ * @return array
62
+ */
63
+ public function getNotices()
64
+ {
65
+ return $this->notices;
66
+ }
67
+
68
+ /**
69
+ * Filter out notices for certain account
70
+ *
71
+ * @param $accountId
72
+ * @return array
73
+ */
74
+ public function getNoticesForAccount($accountId)
75
+ {
76
+ return array_filter($this->notices, function (Notice $notice) use ($accountId) {
77
+ return $notice->getAccountId() === $accountId;
78
+ });
79
+ }
80
+
81
+ /**
82
+ * Add new notice
83
+ *
84
+ * @param $notice
85
+ *
86
+ * @return $this
87
+ */
88
+ public function addNotice($notice)
89
+ {
90
+ array_push($this->notices, $notice);
91
+
92
+ $this->sync();
93
+
94
+ return $this;
95
+ }
96
+
97
+ /**
98
+ * Find notice by id
99
+ *
100
+ * @param $id
101
+ * @return Notice|null
102
+ */
103
+ public function find($id)
104
+ {
105
+ $notices = array_filter($this->notices, function (Notice $notice) use ($id) {
106
+ return $notice->getId() === $id;
107
+ });
108
+
109
+ return array_pop($notices);
110
+ }
111
+
112
+ /**
113
+ * Remove notice by it's id
114
+ *
115
+ * @param $id
116
+ */
117
+ public function remove($id)
118
+ {
119
+ // Get key of notice to remove
120
+ $key = array_search(
121
+ $this->find($id),
122
+ $this->notices
123
+ );
124
+
125
+ // Unset notice with key
126
+ unset($this->notices[$key]);
127
+
128
+ $this->sync();
129
+ }
130
+ }
analyst/{analyst/src → src}/helpers.php RENAMED
@@ -1,84 +1,84 @@
1
- <?php
2
-
3
- if (! function_exists('analyst_assets_path')) {
4
- /**
5
- * Generates path to file in assets folder
6
- *
7
- * @param $file
8
- * @return string
9
- */
10
- function analyst_assets_path($file)
11
- {
12
- $path = sprintf('%s/assets/%s', realpath(__DIR__ . '/..'), trim($file, '/'));
13
-
14
- return wp_normalize_path($path);
15
- }
16
- }
17
-
18
-
19
- if (! function_exists('analyst_assets_url')) {
20
- /**
21
- * Generates url to file in assets folder
22
- *
23
- * @param $file
24
- * @return string
25
- */
26
- function analyst_assets_url($file)
27
- {
28
- $absolutePath = analyst_assets_path($file);
29
-
30
- // We can always rely on WP_PLUGIN_DIR, because that's where
31
- // wordpress install it's plugin's. So we remove last segment
32
- // of that path to get the content dir AKA directly where
33
- // plugins are installed and make the magic...
34
- $contentDir = is_link(WP_PLUGIN_DIR) ?
35
- dirname(wp_normalize_path(readlink(WP_PLUGIN_DIR))) :
36
- dirname(wp_normalize_path(WP_PLUGIN_DIR));
37
-
38
- $relativePath = str_replace( $contentDir, '', $absolutePath);
39
-
40
- return content_url(wp_normalize_path($relativePath));
41
- }
42
- }
43
-
44
- if (! function_exists('analyst_templates_path')) {
45
- /**
46
- * Generates path to file in templates folder
47
- *
48
- * @param $file
49
- * @return string
50
- */
51
- function analyst_templates_path($file)
52
- {
53
- $path = sprintf('%s/templates/%s', realpath(__DIR__ . '/..'), trim($file, '/'));
54
-
55
- return wp_normalize_path($path);
56
- }
57
- }
58
-
59
- if (! function_exists('analyst_require_template')) {
60
- /**
61
- * Require certain template with data
62
- *
63
- * @param $file
64
- * @param array $data
65
- */
66
- function analyst_require_template($file, $data = [])
67
- {
68
- // Extract data to current scope table
69
- extract($data);
70
-
71
- require analyst_templates_path($file);
72
- }
73
- }
74
-
75
- if (! function_exists('dd')) {
76
- /**
77
- * Dump some data
78
- */
79
- function dd ()
80
- {
81
- var_dump(func_get_args());
82
- die();
83
- }
84
- }
1
+ <?php
2
+
3
+ if (! function_exists('analyst_assets_path')) {
4
+ /**
5
+ * Generates path to file in assets folder
6
+ *
7
+ * @param $file
8
+ * @return string
9
+ */
10
+ function analyst_assets_path($file)
11
+ {
12
+ $path = sprintf('%s/assets/%s', realpath(__DIR__ . '/..'), trim($file, '/'));
13
+
14
+ return wp_normalize_path($path);
15
+ }
16
+ }
17
+
18
+
19
+ if (! function_exists('analyst_assets_url')) {
20
+ /**
21
+ * Generates url to file in assets folder
22
+ *
23
+ * @param $file
24
+ * @return string
25
+ */
26
+ function analyst_assets_url($file)
27
+ {
28
+ $absolutePath = analyst_assets_path($file);
29
+
30
+ // We can always rely on WP_PLUGIN_DIR, because that's where
31
+ // wordpress install it's plugin's. So we remove last segment
32
+ // of that path to get the content dir AKA directly where
33
+ // plugins are installed and make the magic...
34
+ $contentDir = is_link(WP_PLUGIN_DIR) ?
35
+ dirname(wp_normalize_path(readlink(WP_PLUGIN_DIR))) :
36
+ dirname(wp_normalize_path(WP_PLUGIN_DIR));
37
+
38
+ $relativePath = str_replace( $contentDir, '', $absolutePath);
39
+
40
+ return content_url(wp_normalize_path($relativePath));
41
+ }
42
+ }
43
+
44
+ if (! function_exists('analyst_templates_path')) {
45
+ /**
46
+ * Generates path to file in templates folder
47
+ *
48
+ * @param $file
49
+ * @return string
50
+ */
51
+ function analyst_templates_path($file)
52
+ {
53
+ $path = sprintf('%s/templates/%s', realpath(__DIR__ . '/..'), trim($file, '/'));
54
+
55
+ return wp_normalize_path($path);
56
+ }
57
+ }
58
+
59
+ if (! function_exists('analyst_require_template')) {
60
+ /**
61
+ * Require certain template with data
62
+ *
63
+ * @param $file
64
+ * @param array $data
65
+ */
66
+ function analyst_require_template($file, $data = [])
67
+ {
68
+ // Extract data to current scope table
69
+ extract($data);
70
+
71
+ require analyst_templates_path($file);
72
+ }
73
+ }
74
+
75
+ if (! function_exists('dd')) {
76
+ /**
77
+ * Dump some data
78
+ */
79
+ function dd ()
80
+ {
81
+ var_dump(func_get_args());
82
+ die();
83
+ }
84
+ }
analyst/{analyst/templates → templates}/forms/deactivate.php RENAMED
@@ -1,156 +1,156 @@
1
- <div id="analyst-deactivate-modal" class="analyst-modal" style="display: none">
2
- <div class="analyst-modal-content" style="width: 500px">
3
- <div class="analyst-disable-modal-mask" id="analyst-disable-deactivate-modal-mask" style="display: none"></div>
4
- <div style="display: flex">
5
- <div class="analyst-install-image-block" style="width: 80px">
6
- <img src="<?=$pencilImage?>"/>
7
- </div>
8
- <div class="analyst-install-description-block" style="padding-left: 20px">
9
- <strong class="analyst-modal-header">Why do you deactivate?</strong>
10
- <div class="analyst-install-description-text" style="padding-top: 2px">
11
- Please let us know, so we can improve it! Thank you <img class="analyst-smile-image" src="<?=$smileImage?>" alt="">
12
- </div>
13
- </div>
14
- </div>
15
- <div>
16
- <ul id="analyst-deactivation-reasons">
17
- <li>
18
- <label>
19
- <span>
20
- <input type="radio" name="deactivation-reason">
21
- </span>
22
- <span class="question" data-question="I couldn't understand how to make it work">I couldn't understand how to make it work</span>
23
- </label>
24
- </li>
25
- <li data-input-type="textarea" data-input-placeholder="What should have worked, but didn’t?">
26
- <label>
27
- <span>
28
- <input type="radio" name="deactivation-reason">
29
- </span>
30
- <span class="question" data-question="The plugin didn't work as expected">The plugin didn't work as expected</span>
31
- </label>
32
- <div class="question-answer"></div>
33
- </li>
34
- <li data-input-type="input" data-input-placeholder="What is the plugin name?">
35
- <label>
36
- <span>
37
- <input type="radio" name="deactivation-reason">
38
- </span>
39
- <span class="question" data-question="I found a better plugin">I found a better plugin</span>
40
- </label>
41
- <div class="question-answer"></div>
42
- </li>
43
- <li>
44
- <label>
45
- <span>
46
- <input type="radio" name="deactivation-reason">
47
- </span>
48
- <span class="question" data-question="It's a temporary deactivation">It's a temporary deactivation</span>
49
- </label>
50
- <div class="question-answer"></div>
51
- </li>
52
- <li data-input-type="textarea" data-input-placeholder="Please provide the reason of deactivation">
53
- <label>
54
- <span>
55
- <input type="radio" name="deactivation-reason">
56
- </span>
57
- <span class="question" data-question="Other">Other</span>
58
- </label>
59
- <div class="question-answer"></div>
60
- </li>
61
- </ul>
62
- <p id="analyst-deactivation-error" style="color: #dc3232; font-size: 16px; display: none">Please let us know the reason for de-activation. Thank you!</p>
63
- </div>
64
- <div>
65
- <button class="analyst-btn-grey" id="analyst-disabled-plugin-action">Deactivate</button>
66
- </div>
67
- <div class="" style="text-align: center; font-size: 18px; padding-top: 10px">
68
- <button class="analyst-btn-secondary-ghost analyst-deactivate-modal-close" style="color: #cccccc">Cancel</button>
69
- </div>
70
- </div>
71
- </div>
72
-
73
- <script type="text/javascript">
74
- (function ($) {
75
- $('.deactivate').click(function (e) {
76
- var anchor = $(this).find('[analyst-plugin-id]')
77
- var pluginId = anchor.attr('analyst-plugin-id')
78
- var isOptedIn = anchor.attr('analyst-plugin-opted-in') === '1'
79
-
80
- // Do not ask for reason if not opted in
81
- if (!isOptedIn) {
82
- return
83
- }
84
-
85
- e.preventDefault()
86
-
87
- $('#analyst-deactivate-modal')
88
- .attr({
89
- 'analyst-plugin-id': pluginId,
90
- 'analyst-redirect-url': $(this).find('a').attr('href')
91
- })
92
- .show()
93
- })
94
-
95
- $('.analyst-deactivate-modal-close').click(function () {
96
- $('#analyst-deactivate-modal').hide()
97
- })
98
-
99
- $('#analyst-deactivation-reasons input[name="deactivation-reason"]').change(function () {
100
- $('.question-answer').empty()
101
-
102
- var root = $('#analyst-deactivation-reasons input[name="deactivation-reason"]:checked').parents('li')
103
-
104
- $('#analyst-deactivation-error').hide()
105
-
106
- if (!root.attr('data-input-type')) return
107
-
108
- var reasonInput = $('<' + root.attr('data-input-type') + '/>').attr({placeholder: root.attr('data-input-placeholder'), class: 'reason-answer'})
109
-
110
- root.find('.question-answer').append(reasonInput)
111
- })
112
-
113
- $('#analyst-disabled-plugin-action').click(function () {
114
- var pluginId = $('#analyst-deactivate-modal').attr('analyst-plugin-id')
115
- var pluginDeactivationUrl = $('#analyst-deactivate-modal').attr('analyst-redirect-url')
116
-
117
- var root = $('#analyst-deactivation-reasons input[name="deactivation-reason"]:checked').parents('li');
118
-
119
- var reason = root.find('.question-answer .reason-answer').val();
120
-
121
- var question = root.find('.question').attr('data-question').trim()
122
-
123
- var $errorBlock = $('#analyst-deactivation-error')
124
-
125
- if (!question) {
126
- return $errorBlock.show()
127
- }
128
-
129
- $errorBlock.hide()
130
-
131
- var data = {
132
- action: 'analyst_plugin_deactivate_' + pluginId,
133
- question: question
134
- }
135
-
136
- if (reason) {
137
- data['reason'] = reason.trim();
138
- }
139
-
140
- $(this).attr('disabled', true).text('Deactivating...');
141
-
142
- $('#analyst-disable-deactivate-modal-mask').show();
143
-
144
- $.ajax({
145
- url: ajaxurl,
146
- method: 'POST',
147
- data: data
148
- }).done(function () {
149
- window.location.href = pluginDeactivationUrl
150
-
151
- $('#analyst-disable-deactivate-modal-mask').hide();
152
- })
153
- })
154
-
155
- })(jQuery)
156
- </script>
1
+ <div id="analyst-deactivate-modal" class="analyst-modal" style="display: none">
2
+ <div class="analyst-modal-content" style="width: 500px">
3
+ <div class="analyst-disable-modal-mask" id="analyst-disable-deactivate-modal-mask" style="display: none"></div>
4
+ <div style="display: flex">
5
+ <div class="analyst-install-image-block" style="width: 80px">
6
+ <img src="<?=$pencilImage?>"/>
7
+ </div>
8
+ <div class="analyst-install-description-block" style="padding-left: 20px">
9
+ <strong class="analyst-modal-header">Why do you deactivate?</strong>
10
+ <div class="analyst-install-description-text" style="padding-top: 2px">
11
+ Please let us know, so we can improve it! Thank you <img class="analyst-smile-image" src="<?=$smileImage?>" alt="">
12
+ </div>
13
+ </div>
14
+ </div>
15
+ <div>
16
+ <ul id="analyst-deactivation-reasons">
17
+ <li>
18
+ <label>
19
+ <span>
20
+ <input type="radio" name="deactivation-reason">
21
+ </span>
22
+ <span class="question" data-question="I couldn't understand how to make it work">I couldn't understand how to make it work</span>
23
+ </label>
24
+ </li>
25
+ <li data-input-type="textarea" data-input-placeholder="What should have worked, but didn’t?">
26
+ <label>
27
+ <span>
28
+ <input type="radio" name="deactivation-reason">
29
+ </span>
30
+ <span class="question" data-question="The plugin didn't work as expected">The plugin didn't work as expected</span>
31
+ </label>
32
+ <div class="question-answer"></div>
33
+ </li>
34
+ <li data-input-type="input" data-input-placeholder="What is the plugin name?">
35
+ <label>
36
+ <span>
37
+ <input type="radio" name="deactivation-reason">
38
+ </span>
39
+ <span class="question" data-question="I found a better plugin">I found a better plugin</span>
40
+ </label>
41
+ <div class="question-answer"></div>
42
+ </li>
43
+ <li>
44
+ <label>
45
+ <span>
46
+ <input type="radio" name="deactivation-reason">
47
+ </span>
48
+ <span class="question" data-question="It's a temporary deactivation">It's a temporary deactivation</span>
49
+ </label>
50
+ <div class="question-answer"></div>
51
+ </li>
52
+ <li data-input-type="textarea" data-input-placeholder="Please provide the reason of deactivation">
53
+ <label>
54
+ <span>
55
+ <input type="radio" name="deactivation-reason">
56
+ </span>
57
+ <span class="question" data-question="Other">Other</span>
58
+ </label>
59
+ <div class="question-answer"></div>
60
+ </li>
61
+ </ul>
62
+ <p id="analyst-deactivation-error" style="color: #dc3232; font-size: 16px; display: none">Please let us know the reason for de-activation. Thank you!</p>
63
+ </div>
64
+ <div>
65
+ <button class="analyst-btn-grey" id="analyst-disabled-plugin-action">Deactivate</button>
66
+ </div>
67
+ <div class="" style="text-align: center; font-size: 18px; padding-top: 10px">
68
+ <button class="analyst-btn-secondary-ghost analyst-deactivate-modal-close" style="color: #cccccc">Cancel</button>
69
+ </div>
70
+ </div>
71
+ </div>
72
+
73
+ <script type="text/javascript">
74
+ (function ($) {
75
+ $('.deactivate').click(function (e) {
76
+ var anchor = $(this).find('[analyst-plugin-id]')
77
+ var pluginId = anchor.attr('analyst-plugin-id')
78
+ var isOptedIn = anchor.attr('analyst-plugin-opted-in') === '1'
79
+
80
+ // Do not ask for reason if not opted in
81
+ if (!isOptedIn) {
82
+ return
83
+ }
84
+
85
+ e.preventDefault()
86
+
87
+ $('#analyst-deactivate-modal')
88
+ .attr({
89
+ 'analyst-plugin-id': pluginId,
90
+ 'analyst-redirect-url': $(this).find('a').attr('href')
91
+ })
92
+ .show()
93
+ })
94
+
95
+ $('.analyst-deactivate-modal-close').click(function () {
96
+ $('#analyst-deactivate-modal').hide()
97
+ })
98
+
99
+ $('#analyst-deactivation-reasons input[name="deactivation-reason"]').change(function () {
100
+ $('.question-answer').empty()
101
+
102
+ var root = $('#analyst-deactivation-reasons input[name="deactivation-reason"]:checked').parents('li')
103
+
104
+ $('#analyst-deactivation-error').hide()
105
+
106
+ if (!root.attr('data-input-type')) return
107
+
108
+ var reasonInput = $('<' + root.attr('data-input-type') + '/>').attr({placeholder: root.attr('data-input-placeholder'), class: 'reason-answer'})
109
+
110
+ root.find('.question-answer').append(reasonInput)
111
+ })
112
+
113
+ $('#analyst-disabled-plugin-action').click(function () {
114
+ var pluginId = $('#analyst-deactivate-modal').attr('analyst-plugin-id')
115
+ var pluginDeactivationUrl = $('#analyst-deactivate-modal').attr('analyst-redirect-url')
116
+
117
+ var root = $('#analyst-deactivation-reasons input[name="deactivation-reason"]:checked').parents('li');
118
+
119
+ var reason = root.find('.question-answer .reason-answer').val();
120
+
121
+ var question = root.find('.question').attr('data-question').trim()
122
+
123
+ var $errorBlock = $('#analyst-deactivation-error')
124
+
125
+ if (!question) {
126
+ return $errorBlock.show()
127
+ }
128
+
129
+ $errorBlock.hide()
130
+
131
+ var data = {
132
+ action: 'analyst_plugin_deactivate_' + pluginId,
133
+ question: question
134
+ }
135
+
136
+ if (reason) {
137
+ data['reason'] = reason.trim();
138
+ }
139
+
140
+ $(this).attr('disabled', true).text('Deactivating...');
141
+
142
+ $('#analyst-disable-deactivate-modal-mask').show();
143
+
144
+ $.ajax({
145
+ url: ajaxurl,
146
+ method: 'POST',
147
+ data: data
148
+ }).done(function () {
149
+ window.location.href = pluginDeactivationUrl
150
+
151
+ $('#analyst-disable-deactivate-modal-mask').hide();
152
+ })
153
+ })
154
+
155
+ })(jQuery)
156
+ </script>
analyst/{analyst/templates → templates}/forms/install.php RENAMED
@@ -1,110 +1,110 @@
1
- <div id="analyst-install-modal" class="analyst-modal" style="display: none" analyst-plugin-id="<?=$pluginToInstall?>">
2
- <div class="analyst-modal-content" style="width: 450px">
3
- <div class="analyst-disable-modal-mask" id="analyst-disable-install-modal-mask" style="display: none"></div>
4
- <div style="display: flex">
5
- <div class="analyst-install-image-block">
6
- <img src="<?=$shieldImage?>"/>
7
- </div>
8
- <div class="analyst-install-description-block">
9
- <strong class="analyst-modal-header">Stay on the safe side</strong>
10
- <p class="analyst-install-description-text">Receive our plugin’s alerts in
11
- case of <strong>critical security</strong> & feature
12
- updates and allow non-sensitive
13
- diagnostic tracking.</p>
14
- </div>
15
- </div>
16
- <div class="analyst-modal-def-top-padding">
17
- <button class="analyst-btn-success" id="analyst-install-action">Allow & Continue ></button>
18
- </div>
19
- <div class="analyst-modal-def-top-padding" id="analyst-permissions-block" style="display: none">
20
- <span>You’re granting these permissions:</span>
21
- <ul class="analyst-install-permissions-list">
22
- <li><strong>Your profile information</strong> (name and email) ​</li>
23
- <li><strong>Your site information</strong> (URL, WP version, PHP info, plugins & themes)</li>
24
- <li><strong>Plugin notices</strong> (updates, announcements, marketing, no spam)</li>
25
- <li><strong>Plugin events</strong> (activation, deactivation and uninstall)​</li>
26
- </ul>
27
- </div>
28
- <div class="analyst-install-footer analyst-modal-def-top-padding">
29
- <span class="analyst-action-text" id="analyst-permissions-toggle">Learn more</span>
30
- <span>Powered by <a href="https://sellcodes.com/blog/wordpress-feedback-system-for-plugin-creators/?utm_source=optin_screen" target="_blank" class="analyst-link">Sellcodes.com</a></span>
31
- <span class="analyst-action-text analyst-install-modal-close" id="analyst-install-skip">Skip</span>
32
- </div>
33
- <div id="analyst-install-error" class="analyst-modal-def-top-padding" style="display: none; text-align: center">
34
- <span style="color: #dc3232; font-size: 16px">Service unavailable. Please try again later</span>
35
- </div>
36
- </div>
37
- </div>
38
-
39
- <script type="text/javascript">
40
- (function ($) {
41
-
42
- var installPlugin = function (pluginId) {
43
- var $error = $('#analyst-install-error')
44
-
45
- $error.hide()
46
-
47
- $.ajax({
48
- url: ajaxurl,
49
- method: 'POST',
50
- data: {
51
- action: 'analyst_install_' + pluginId
52
- },
53
- success: function (data) {
54
- if (data && !data.success) {
55
- //error
56
- $('#analyst-install-modal').hide()
57
-
58
- return
59
- }
60
-
61
- window.location.reload()
62
- },
63
- error: function () {
64
- $('#analyst-install-modal').hide()
65
- }
66
- }).done(function () {
67
- $('#analyst-disable-install-modal-mask').hide()
68
-
69
- $('#analyst-install-action')
70
- .attr('disabled', false)
71
- .text('Allow & Continue >')
72
- })
73
- }
74
-
75
- if ($('#analyst-install-modal').attr('analyst-plugin-id')) {
76
- $('#analyst-install-modal').show()
77
- }
78
-
79
-
80
- $('.analyst-install-modal-close').click(function () {
81
- $('#analyst-install-modal').hide()
82
- })
83
-
84
- $('#analyst-install-action').click(function () {
85
- var pluginId = $('#analyst-install-modal').attr('analyst-plugin-id')
86
-
87
- $('#analyst-install-action')
88
- .attr('disabled', true)
89
- .text('Please wait...')
90
-
91
- $('#analyst-disable-install-modal-mask').show()
92
-
93
- installPlugin(pluginId)
94
- })
95
-
96
- $('#analyst-permissions-toggle').click(function () {
97
- var isVisible = $('#analyst-permissions-block').toggle().is(':visible')
98
-
99
- isVisible ? $(this).text('Close section') : $(this).text('Learn more')
100
- })
101
-
102
- $('#analyst-install-skip').click(function () {
103
- var pluginId = $('#analyst-install-modal').attr('analyst-plugin-id')
104
-
105
- $.post(ajaxurl, {action: 'analyst_skip_install_' + pluginId}).done(function () {
106
- $('#analyst-install-modal').hide()
107
- })
108
- })
109
- })(jQuery)
110
- </script>
1
+ <div id="analyst-install-modal" class="analyst-modal" style="display: none" analyst-plugin-id="<?=$pluginToInstall?>">
2
+ <div class="analyst-modal-content" style="width: 450px">
3
+ <div class="analyst-disable-modal-mask" id="analyst-disable-install-modal-mask" style="display: none"></div>
4
+ <div style="display: flex">
5
+ <div class="analyst-install-image-block">
6
+ <img src="<?=$shieldImage?>"/>
7
+ </div>
8
+ <div class="analyst-install-description-block">
9
+ <strong class="analyst-modal-header">Stay on the safe side</strong>
10
+ <p class="analyst-install-description-text">Receive our plugin’s alerts in
11
+ case of <strong>critical security</strong> & feature
12
+ updates and allow non-sensitive
13
+ diagnostic tracking.</p>
14
+ </div>
15
+ </div>
16
+ <div class="analyst-modal-def-top-padding">
17
+ <button class="analyst-btn-success" id="analyst-install-action">Allow & Continue ></button>
18
+ </div>
19
+ <div class="analyst-modal-def-top-padding" id="analyst-permissions-block" style="display: none">
20
+ <span>You’re granting these permissions:</span>
21
+ <ul class="analyst-install-permissions-list">
22
+ <li><strong>Your profile information</strong> (name and email) ​</li>
23
+ <li><strong>Your site information</strong> (URL, WP version, PHP info, plugins & themes)</li>
24
+ <li><strong>Plugin notices</strong> (updates, announcements, marketing, no spam)</li>
25
+ <li><strong>Plugin events</strong> (activation, deactivation and uninstall)​</li>
26
+ </ul>
27
+ </div>
28
+ <div class="analyst-install-footer analyst-modal-def-top-padding">
29
+ <span class="analyst-action-text" id="analyst-permissions-toggle">Learn more</span>
30
+ <span>Powered by <a href="https://sellcodes.com/blog/wordpress-feedback-system-for-plugin-creators/?utm_source=optin_screen" target="_blank" class="analyst-link">Sellcodes.com</a></span>
31
+ <span class="analyst-action-text analyst-install-modal-close" id="analyst-install-skip">Skip</span>
32
+ </div>
33
+ <div id="analyst-install-error" class="analyst-modal-def-top-padding" style="display: none; text-align: center">
34
+ <span style="color: #dc3232; font-size: 16px">Service unavailable. Please try again later</span>
35
+ </div>
36
+ </div>
37
+ </div>
38
+
39
+ <script type="text/javascript">
40
+ (function ($) {
41
+
42
+ var installPlugin = function (pluginId) {
43
+ var $error = $('#analyst-install-error')
44
+
45
+ $error.hide()
46
+
47
+ $.ajax({
48
+ url: ajaxurl,
49
+ method: 'POST',
50
+ data: {
51
+ action: 'analyst_install_' + pluginId
52
+ },
53
+ success: function (data) {
54
+ if (data && !data.success) {
55
+ //error
56
+ $('#analyst-install-modal').hide()
57
+
58
+ return
59
+ }
60
+
61
+ window.location.reload()
62
+ },
63
+ error: function () {
64
+ $('#analyst-install-modal').hide()
65
+ }
66
+ }).done(function () {
67
+ $('#analyst-disable-install-modal-mask').hide()
68
+
69
+ $('#analyst-install-action')
70
+ .attr('disabled', false)
71
+ .text('Allow & Continue >')
72
+ })
73
+ }
74
+
75
+ if ($('#analyst-install-modal').attr('analyst-plugin-id')) {
76
+ $('#analyst-install-modal').show()
77
+ }
78
+
79
+
80
+ $('.analyst-install-modal-close').click(function () {
81
+ $('#analyst-install-modal').hide()
82
+ })
83
+
84
+ $('#analyst-install-action').click(function () {
85
+ var pluginId = $('#analyst-install-modal').attr('analyst-plugin-id')
86
+
87
+ $('#analyst-install-action')
88
+ .attr('disabled', true)
89
+ .text('Please wait...')
90
+
91
+ $('#analyst-disable-install-modal-mask').show()
92
+
93
+ installPlugin(pluginId)
94
+ })
95
+
96
+ $('#analyst-permissions-toggle').click(function () {
97
+ var isVisible = $('#analyst-permissions-block').toggle().is(':visible')
98
+
99
+ isVisible ? $(this).text('Close section') : $(this).text('Learn more')
100
+ })
101
+
102
+ $('#analyst-install-skip').click(function () {
103
+ var pluginId = $('#analyst-install-modal').attr('analyst-plugin-id')
104
+
105
+ $.post(ajaxurl, {action: 'analyst_skip_install_' + pluginId}).done(function () {
106
+ $('#analyst-install-modal').hide()
107
+ })
108
+ })
109
+ })(jQuery)
110
+ </script>
analyst/{analyst/templates → templates}/notice.php RENAMED
@@ -1,10 +1,10 @@
1
- <div class="notice notice-success analyst-notice">
2
- <p>
3
- <strong class="analyst-plugin-name"><?=$notice->getPluginName()?></strong>
4
- <?=$notice->getBody()?>
5
- </p>
6
-
7
- <button type="button" class="analyst-notice-dismiss notice-dismiss" analyst-notice-id="<?=$notice->getId()?>">
8
- <span class="screen-reader-text">Dismiss this notice.</span>
9
- </button>
10
- </div>
1
+ <div class="notice notice-success analyst-notice">
2
+ <p>
3
+ <strong class="analyst-plugin-name"><?=$notice->getPluginName()?></strong>
4
+ <?=$notice->getBody()?>
5
+ </p>
6
+
7
+ <button type="button" class="analyst-notice-dismiss notice-dismiss" analyst-notice-id="<?=$notice->getId()?>">
8
+ <span class="screen-reader-text">Dismiss this notice.</span>
9
+ </button>
10
+ </div>
analyst/{analyst/templates → templates}/optin.php RENAMED
@@ -1,60 +1,60 @@
1
- <script type="text/javascript">
2
-
3
- (function ($) {
4
- var isOptingIn = false
5
-
6
- $('#analyst-opt-in-modal').appendTo($('body'))
7
-
8
- var makeOptIn = function (pluginId) {
9
- if (isOptingIn) return
10
-
11
- isOptingIn = true
12
-
13
- $.ajax({
14
- url: ajaxurl,
15
- method: 'POST',
16
- data: {
17
- action: 'analyst_opt_in_' + pluginId,
18
- },
19
- success: function () {
20
- $('#analyst-opt-in-modal').hide()
21
-
22
- isOptingIn = false
23
-
24
- var optOutAction = $('<a />').attr({
25
- class: 'analyst-action-opt analyst-opt-out',
26
- 'analyst-plugin-id': pluginId,
27
- 'analyst-plugin-signed': '1'
28
- })
29
- .text('Opt Out')
30
- $('.analyst-opt-in[analyst-plugin-id="'+ pluginId +'"').replaceWith(optOutAction)
31
-
32
- $('[analyst-plugin-id="' + pluginId + '"').attr('analyst-plugin-opted-in', 1)
33
- }
34
- })
35
- }
36
-
37
- $(document).on('click', '.analyst-opt-in:not([loading])', function() {
38
- var pluginId = $(this).attr('analyst-plugin-id')
39
- var isSigned = $(this).attr('analyst-plugin-signed') === '1'
40
-
41
- if (!isSigned) {
42
- $('#analyst-install-modal')
43
- .attr('analyst-plugin-id', pluginId)
44
- .show()
45
-
46
- return;
47
- }
48
-
49
- $('#analyst-install-modal').attr({'analyst-plugin-id': pluginId})
50
-
51
- $(this).attr('loading', true).text('Opting In...')
52
-
53
- makeOptIn(pluginId);
54
- })
55
-
56
- $('.opt-in-modal-close').click(function () {
57
- $('#analyst-opt-in-modal').hide()
58
- })
59
- })(jQuery)
60
- </script>
1
+ <script type="text/javascript">
2
+
3
+ (function ($) {
4
+ var isOptingIn = false
5
+
6
+ $('#analyst-opt-in-modal').appendTo($('body'))
7
+
8
+ var makeOptIn = function (pluginId) {
9
+ if (isOptingIn) return
10
+
11
+ isOptingIn = true
12
+
13
+ $.ajax({
14
+ url: ajaxurl,
15
+ method: 'POST',
16
+ data: {
17
+ action: 'analyst_opt_in_' + pluginId,
18
+ },
19
+ success: function () {
20
+ $('#analyst-opt-in-modal').hide()
21
+
22
+ isOptingIn = false
23
+
24
+ var optOutAction = $('<a />').attr({
25
+ class: 'analyst-action-opt analyst-opt-out',
26
+ 'analyst-plugin-id': pluginId,
27
+ 'analyst-plugin-signed': '1'
28
+ })
29
+ .text('Opt Out')
30
+ $('.analyst-opt-in[analyst-plugin-id="'+ pluginId +'"').replaceWith(optOutAction)
31
+
32
+ $('[analyst-plugin-id="' + pluginId + '"').attr('analyst-plugin-opted-in', 1)
33
+ }
34
+ })
35
+ }
36
+
37
+ $(document).on('click', '.analyst-opt-in:not([loading])', function() {
38
+ var pluginId = $(this).attr('analyst-plugin-id')
39
+ var isSigned = $(this).attr('analyst-plugin-signed') === '1'
40
+
41
+ if (!isSigned) {
42
+ $('#analyst-install-modal')
43
+ .attr('analyst-plugin-id', pluginId)
44
+ .show()
45
+
46
+ return;
47
+ }
48
+
49
+ $('#analyst-install-modal').attr({'analyst-plugin-id': pluginId})
50
+
51
+ $(this).attr('loading', true).text('Opting In...')
52
+
53
+ makeOptIn(pluginId);
54
+ })
55
+
56
+ $('.opt-in-modal-close').click(function () {
57
+ $('#analyst-opt-in-modal').hide()
58
+ })
59
+ })(jQuery)
60
+ </script>
analyst/{analyst/templates → templates}/optout.php RENAMED
@@ -1,109 +1,109 @@
1
- <div id="analyst-opt-out-modal" class="analyst-modal" style="display: none">
2
- <div class="analyst-modal-content" style="width: 600px">
3
- <div class="analyst-disable-modal-mask" id="analyst-disable-opt-out-modal-mask" style="display: none"></div>
4
- <div style="display: flex">
5
- <div class="analyst-install-image-block" style="width: 120px">
6
- <img src="<?=$shieldImage?>"/>
7
- </div>
8
- <div class="analyst-install-description-block">
9
- <strong class="analyst-modal-header">By opting out, we cannot alert you anymore in case of important security updates.</strong>
10
- <p class="analyst-install-description-text">
11
- In addition, we won’t get pointers how to further improve the plugin based on your integration with our plugin.
12
- </p>
13
- </div>
14
- </div>
15
- <div class="analyst-modal-def-top-padding">
16
- <button class="analyst-btn-success opt-out-modal-close">Ok, don't opt out</button>
17
- </div>
18
- <div class="analyst-modal-def-top-padding" style="text-align: center;">
19
- <button class="analyst-btn-secondary-ghost" id="opt-out-action">Opt out</button>
20
- </div>
21
- <div id="analyst-opt-out-error" class="analyst-modal-def-top-padding" style="display: none;">
22
- <span style="color: #dc3232; font-size: 16px">Service unavailable. Please try again later</span>
23
- </div>
24
- </div>
25
- </div>
26
- </div>
27
-
28
- <script type="text/javascript">
29
-
30
- (function ($) {
31
- var isOptingOut = false
32
-
33
- $('#analyst-opt-out-modal').appendTo($('body'))
34
-
35
- $(document).on('click', '.analyst-opt-out', function() {
36
- var pluginId = $(this).attr('analyst-plugin-id')
37
-
38
- $('#analyst-opt-out-modal')
39
- .attr({'analyst-plugin-id': pluginId})
40
- .show()
41
- })
42
-
43
- $('.opt-out-modal-close').click(function () {
44
- $('#analyst-opt-out-modal').hide()
45
- })
46
-
47
- $('#opt-out-action').click(function () {
48
- if (isOptingOut) return
49
-
50
- var $mask = $('#analyst-disable-opt-out-modal-mask')
51
- var $error = $('#analyst-opt-out-error')
52
-
53
- var pluginId = $('#analyst-opt-out-modal').attr('analyst-plugin-id')
54
-
55
- $mask.show()
56
- $error.hide()
57
-
58
- var self = this
59
-
60
- isOptingOut = true
61
-
62
- $(self).text('Opting out...')
63
-
64
- $.ajax({
65
- url: ajaxurl,
66
- method: 'POST',
67
- data: {
68
- action: 'analyst_opt_out_' + pluginId,
69
- },
70
- success: function (data) {
71
- $(self).text('Opt out')
72
-
73
- if (data && !data.success) {
74
- $('#analyst-opt-out-modal').hide()
75
-
76
- return
77
- }
78
-
79
- $error.hide()
80
-
81
- $('#analyst-opt-out-modal').hide()
82
-
83
- isOptingOut = false
84
-
85
- var optInAction = $('<a />').attr({
86
- class: 'analyst-action-opt analyst-opt-in',
87
- 'analyst-plugin-id': pluginId,
88
- 'analyst-plugin-signed': '1'
89
- })
90
- .text('Opt In')
91
- $('.analyst-opt-out[analyst-plugin-id="'+ pluginId +'"').replaceWith(optInAction)
92
-
93
- $('[analyst-plugin-id="' + pluginId + '"').attr('analyst-plugin-opted-in', 0)
94
-
95
- $mask.hide()
96
- },
97
- error: function () {
98
- $('#analyst-opt-out-error').show()
99
-
100
- $(self).text('Opt out')
101
- }
102
- }).done(function () {
103
- $mask.hide()
104
-
105
- isOptingOut = false
106
- })
107
- })
108
- })(jQuery)
109
- </script>
1
+ <div id="analyst-opt-out-modal" class="analyst-modal" style="display: none">
2
+ <div class="analyst-modal-content" style="width: 600px">
3
+ <div class="analyst-disable-modal-mask" id="analyst-disable-opt-out-modal-mask" style="display: none"></div>
4
+ <div style="display: flex">
5
+ <div class="analyst-install-image-block" style="width: 120px">
6
+ <img src="<?=$shieldImage?>"/>
7
+ </div>
8
+ <div class="analyst-install-description-block">
9
+ <strong class="analyst-modal-header">By opting out, we cannot alert you anymore in case of important security updates.</strong>
10
+ <p class="analyst-install-description-text">
11
+ In addition, we won’t get pointers how to further improve the plugin based on your integration with our plugin.
12
+ </p>
13
+ </div>
14
+ </div>
15
+ <div class="analyst-modal-def-top-padding">
16
+ <button class="analyst-btn-success opt-out-modal-close">Ok, don't opt out</button>
17
+ </div>
18
+ <div class="analyst-modal-def-top-padding" style="text-align: center;">
19
+ <button class="analyst-btn-secondary-ghost" id="opt-out-action">Opt out</button>
20
+ </div>
21
+ <div id="analyst-opt-out-error" class="analyst-modal-def-top-padding" style="display: none;">
22
+ <span style="color: #dc3232; font-size: 16px">Service unavailable. Please try again later</span>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </div>
27
+
28
+ <script type="text/javascript">
29
+
30
+ (function ($) {
31
+ var isOptingOut = false
32
+
33
+ $('#analyst-opt-out-modal').appendTo($('body'))
34
+
35
+ $(document).on('click', '.analyst-opt-out', function() {
36
+ var pluginId = $(this).attr('analyst-plugin-id')
37
+
38
+ $('#analyst-opt-out-modal')
39
+ .attr({'analyst-plugin-id': pluginId})
40
+ .show()
41
+ })
42
+
43
+ $('.opt-out-modal-close').click(function () {
44
+ $('#analyst-opt-out-modal').hide()
45
+ })
46
+
47
+ $('#opt-out-action').click(function () {
48
+ if (isOptingOut) return
49
+
50
+ var $mask = $('#analyst-disable-opt-out-modal-mask')
51
+ var $error = $('#analyst-opt-out-error')
52
+
53
+ var pluginId = $('#analyst-opt-out-modal').attr('analyst-plugin-id')
54
+
55
+ $mask.show()
56
+ $error.hide()
57
+
58
+ var self = this
59
+
60
+ isOptingOut = true
61
+
62
+ $(self).text('Opting out...')
63
+
64
+ $.ajax({
65
+ url: ajaxurl,
66
+ method: 'POST',
67
+ data: {
68
+ action: 'analyst_opt_out_' + pluginId,
69
+ },
70
+ success: function (data) {
71
+ $(self).text('Opt out')
72
+
73
+ if (data && !data.success) {
74
+ $('#analyst-opt-out-modal').hide()
75
+
76
+ return
77
+ }
78
+
79
+ $error.hide()
80
+
81
+ $('#analyst-opt-out-modal').hide()
82
+
83
+ isOptingOut = false
84
+
85
+ var optInAction = $('<a />').attr({
86
+ class: 'analyst-action-opt analyst-opt-in',
87
+ 'analyst-plugin-id': pluginId,
88
+ 'analyst-plugin-signed': '1'
89
+ })
90
+ .text('Opt In')
91
+ $('.analyst-opt-out[analyst-plugin-id="'+ pluginId +'"').replaceWith(optInAction)
92
+
93
+ $('[analyst-plugin-id="' + pluginId + '"').attr('analyst-plugin-opted-in', 0)
94
+
95
+ $mask.hide()
96
+ },
97
+ error: function () {
98
+ $('#analyst-opt-out-error').show()
99
+
100
+ $(self).text('Opt out')
101
+ }
102
+ }).done(function () {
103
+ $mask.hide()
104
+
105
+ isOptingOut = false
106
+ })
107
+ })
108
+ })(jQuery)
109
+ </script>
analyst/{analyst/version.php → version.php} RENAMED
@@ -1,15 +1,15 @@
1
- <?php
2
-
3
- return array(
4
- // The sdk version
5
- 'sdk' => '1.3.23',
6
-
7
- // Minimum supported WordPress version
8
- 'wp' => '4.7',
9
-
10
- // Supported PHP version
11
- 'php' => '5.4',
12
-
13
- // Path to current SDK$
14
- 'path' => __DIR__,
15
- );
1
+ <?php
2
+
3
+ return array(
4
+ // The sdk version
5
+ 'sdk' => '1.3.23',
6
+
7
+ // Minimum supported WordPress version
8
+ 'wp' => '4.7',
9
+
10
+ // Supported PHP version
11
+ 'php' => '5.4',
12
+
13
+ // Path to current SDK$
14
+ 'path' => __DIR__,
15
+ );
libs/sfsi_install_uninstall.php CHANGED
@@ -12,7 +12,7 @@ function sfsi_plus_update_plugin()
12
  }
13
 
14
  //Install version
15
- update_option("sfsi_plus_pluginVersion", "3.20");
16
 
17
  if(!get_option('sfsi_plus_serverphpVersionnotification'))
18
  {
12
  }
13
 
14
  //Install version
15
+ update_option("sfsi_plus_pluginVersion", "3.21");
16
 
17
  if(!get_option('sfsi_plus_serverphpVersionnotification'))
18
  {
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: socialsharepro
3
  Tags: Share, sharing, share buttons, share button, share social media, share icons, social buttons, sharing buttons, sharing icons, social media icons, social share, social sharing
4
  Requires at least: 3.0
5
  Tested up to: 5.2
6
- Stable tag: 3.2.0
7
  License: GPLv2
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -446,6 +446,9 @@ The premium plugin offrs many more social buttons from other social media platfo
446
 
447
 
448
  == Changelog ==
 
 
 
449
  = 3.2.0 =
450
  * Update: SDK.
451
  * Update: Grammer Errors.
@@ -898,5 +901,5 @@ The premium plugin offrs many more social buttons from other social media platfo
898
 
899
  == Upgrade Notice ==
900
 
901
- = 3.2.0 =
902
  * Please update
3
  Tags: Share, sharing, share buttons, share button, share social media, share icons, social buttons, sharing buttons, sharing icons, social media icons, social share, social sharing
4
  Requires at least: 3.0
5
  Tested up to: 5.2
6
+ Stable tag: 3.2.1
7
  License: GPLv2
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
446
 
447
 
448
  == Changelog ==
449
+ = 3.2.1 =
450
+ * Update: Feedback system updated
451
+
452
  = 3.2.0 =
453
  * Update: SDK.
454
  * Update: Grammer Errors.
901
 
902
  == Upgrade Notice ==
903
 
904
+ = 3.2.1 =
905
  * Please update
ultimate_social_media_icons.php CHANGED
@@ -7,7 +7,7 @@ Author: social share pro
7
  Text Domain: ultimate-social-media-plus
8
  Domain Path: /languages
9
  Author URI: http://socialshare.pro/
10
- Version: 3.2.0
11
  License: GPLv2
12
  */
13
 
@@ -111,7 +111,7 @@ register_deactivation_hook(__FILE__, 'sfsi_plus_deactivate_plugin');
111
  //register_uninstall_hook(__FILE__, 'sfsi_plus_Unistall_plugin');
112
 
113
  /*Plugin version setup*/
114
- if (!get_option('sfsi_plus_pluginVersion') || get_option('sfsi_plus_pluginVersion') < 3.20) {
115
  add_action("init", "sfsi_plus_update_plugin");
116
  }
117
 
7
  Text Domain: ultimate-social-media-plus
8
  Domain Path: /languages
9
  Author URI: http://socialshare.pro/
10
+ Version: 3.2.1
11
  License: GPLv2
12
  */
13
 
111
  //register_uninstall_hook(__FILE__, 'sfsi_plus_Unistall_plugin');
112
 
113
  /*Plugin version setup*/
114
+ if (!get_option('sfsi_plus_pluginVersion') || get_option('sfsi_plus_pluginVersion') < 3.21) {
115
  add_action("init", "sfsi_plus_update_plugin");
116
  }
117