Social Media Share Buttons & Social Sharing Icons - Version 2.4.7

Version Description

  • Added Margins above and below responsive icons
  • Updated the display for widget
  • Replaced with icons which reduces the loading time
Download this release

Release Info

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

Code changes from version 2.4.6 to 2.4.7

Files changed (68) hide show
  1. analyst/assets/css/customize.css +280 -280
  2. analyst/assets/index.php +2 -2
  3. analyst/assets/js/customize.js +29 -29
  4. analyst/autoload.php +40 -40
  5. analyst/index.php +2 -2
  6. analyst/main.php +36 -36
  7. analyst/sdk_resolver.php +79 -79
  8. analyst/src/Account/AccountData.php +176 -176
  9. analyst/src/Account/AccountDataFactory.php +125 -125
  10. analyst/src/Analyst.php +167 -167
  11. analyst/src/ApiRequestor.php +257 -257
  12. analyst/src/ApiResponse.php +44 -44
  13. analyst/src/Cache/DatabaseCache.php +127 -127
  14. analyst/src/Collector.php +217 -217
  15. analyst/src/Contracts/AnalystContract.php +12 -12
  16. analyst/src/Contracts/CacheContract.php +47 -47
  17. analyst/src/Contracts/HttpClientContract.php +25 -25
  18. analyst/src/Contracts/RequestContract.php +22 -22
  19. analyst/src/Contracts/RequestorContract.php +44 -44
  20. analyst/src/Contracts/TrackerContract.php +69 -69
  21. analyst/src/Core/AbstractFactory.php +27 -27
  22. analyst/src/Http/CurlHttpClient.php +102 -102
  23. analyst/src/Http/DummyHttpClient.php +33 -33
  24. analyst/src/Http/Requests/AbstractLoggerRequest.php +64 -64
  25. analyst/src/Http/Requests/ActivateRequest.php +42 -42
  26. analyst/src/Http/Requests/DeactivateRequest.php +64 -64
  27. analyst/src/Http/Requests/InstallRequest.php +38 -38
  28. analyst/src/Http/Requests/OptInRequest.php +42 -42
  29. analyst/src/Http/Requests/OptOutRequest.php +40 -40
  30. analyst/src/Http/Requests/UninstallRequest.php +36 -36
  31. analyst/src/Http/WordPressHttpClient.php +61 -61
  32. analyst/src/Mutator.php +103 -103
  33. analyst/src/Notices/Notice.php +121 -121
  34. analyst/src/Notices/NoticeFactory.php +130 -130
  35. analyst/templates/forms/deactivate.php +156 -156
  36. analyst/templates/forms/install.php +113 -113
  37. analyst/templates/notice.php +10 -10
  38. analyst/templates/optin.php +60 -60
  39. analyst/templates/optout.php +109 -109
  40. css/jquery-ui-1.10.4/jquery-ui.css +1177 -1177
  41. css/sfsi-style.css +28 -3
  42. helpers/common_helper.php +202 -202
  43. helpers/linkedin-api/linkedin-api.php +136 -136
  44. helpers/sfsi_OAuth.php +910 -910
  45. helpers/twitteroauth/src/TwitterOAuth.php +506 -506
  46. images/responsive-icon/Twitter.svg +3 -3
  47. images/responsive-icon/facebook.svg +3 -3
  48. images/visit_icons/en_US_Follow.svg +16 -0
  49. images/visit_icons/en_US_Tweet.svg +18 -0
  50. images/visit_icons/en_US_save.svg +23 -0
  51. js/custom-admin.js +3 -0
  52. js/custom-form.js +148 -148
  53. js/index.php +3 -3
  54. js/shuffle/jquery.shuffle.js +1267 -1267
  55. libs/controllers/sfsi_buttons_controller.php +3 -1
  56. libs/controllers/sfsi_iconsUpload_contoller.php +529 -529
  57. libs/controllers/sfsi_socialhelper.php +63 -24
  58. libs/controllers/sfsiocns_OnPosts.php +164 -125
  59. libs/sfsi_Init_JqueryCss.php +132 -132
  60. libs/sfsi_ajax_social_sharing_settings_updater.php +15 -15
  61. libs/sfsi_install_uninstall.php +1 -1
  62. libs/sfsi_widget.php +3 -4
  63. readme.txt +7 -2
  64. ultimate_social_media_icons.php +2 -2
  65. views/deactivation/sfsi_deactivation_popup.php +121 -121
  66. views/sfsi_chat_on_admin_pannel.php +117 -117
  67. views/sfsi_option_view3.php +400 -400
  68. views/sfsi_option_view6.php +17 -2
analyst/assets/css/customize.css CHANGED
@@ -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/assets/index.php CHANGED
@@ -1,2 +1,2 @@
1
- <?php
2
- // Silence is golden.
1
+ <?php
2
+ // Silence is golden.
analyst/assets/js/customize.js CHANGED
@@ -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/autoload.php CHANGED
@@ -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/index.php CHANGED
@@ -1,2 +1,2 @@
1
- <?php
2
- // Silence
1
+ <?php
2
+ // Silence
analyst/main.php CHANGED
@@ -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/sdk_resolver.php CHANGED
@@ -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 = WP_PLUGIN_DIR;
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 = WP_PLUGIN_DIR;
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/src/Account/AccountData.php CHANGED
@@ -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/src/Account/AccountDataFactory.php CHANGED
@@ -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/src/Analyst.php CHANGED
@@ -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/src/ApiRequestor.php CHANGED
@@ -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/src/ApiResponse.php CHANGED
@@ -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/src/Cache/DatabaseCache.php CHANGED
@@ -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/src/Collector.php CHANGED
@@ -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
- $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
173
-
174
- $version = mysqli_get_server_info($conn);
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
+ $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
173
+
174
+ $version = mysqli_get_server_info($conn);
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/src/Contracts/AnalystContract.php CHANGED
@@ -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/src/Contracts/CacheContract.php CHANGED
@@ -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/src/Contracts/HttpClientContract.php CHANGED
@@ -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/src/Contracts/RequestContract.php CHANGED
@@ -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/src/Contracts/RequestorContract.php CHANGED
@@ -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/src/Contracts/TrackerContract.php CHANGED
@@ -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/src/Core/AbstractFactory.php CHANGED
@@ -1,27 +1,27 @@
1
- <?php
2
-
3
- namespace Analyst\Core;
4
-
5
- abstract class AbstractFactory
6
- {
7
- /**
8
- * Unserialize to static::class instance
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
- // static::class we make sure it is static::class
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 static::class instance
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
+ // static::class we make sure it is static::class
21
+ if (!$isProperObject) {
22
+ $instance = new static();
23
+ }
24
+
25
+ return $instance;
26
+ }
27
+ }
analyst/src/Http/CurlHttpClient.php CHANGED
@@ -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/src/Http/DummyHttpClient.php CHANGED
@@ -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/src/Http/Requests/AbstractLoggerRequest.php CHANGED
@@ -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/src/Http/Requests/ActivateRequest.php CHANGED
@@ -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/src/Http/Requests/DeactivateRequest.php CHANGED
@@ -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/src/Http/Requests/InstallRequest.php CHANGED
@@ -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/src/Http/Requests/OptInRequest.php CHANGED
@@ -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/src/Http/Requests/OptOutRequest.php CHANGED
@@ -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/src/Http/Requests/UninstallRequest.php CHANGED
@@ -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/src/Http/WordPressHttpClient.php CHANGED
@@ -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/src/Mutator.php CHANGED
@@ -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('analyst_custom', analyst_assets_url('/css/customize.css'));
88
- wp_enqueue_script('analyst_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('analyst_custom', analyst_assets_url('/css/customize.css'));
88
+ wp_enqueue_script('analyst_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/src/Notices/Notice.php CHANGED
@@ -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/src/Notices/NoticeFactory.php CHANGED
@@ -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/templates/forms/deactivate.php CHANGED
@@ -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/templates/forms/install.php CHANGED
@@ -1,113 +1,113 @@
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 id="analyst-powered-by" style="display: none;">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
- var poweredBy = $('#analyst-powered-by')
102
- isVisible ? poweredBy.show() : poweredBy.hide()
103
- })
104
-
105
- $('#analyst-install-skip').click(function () {
106
- var pluginId = $('#analyst-install-modal').attr('analyst-plugin-id')
107
-
108
- $.post(ajaxurl, {action: 'analyst_skip_install_' + pluginId}).done(function () {
109
- $('#analyst-install-modal').hide()
110
- })
111
- })
112
- })(jQuery)
113
- </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 id="analyst-powered-by" style="display: none;">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
+ var poweredBy = $('#analyst-powered-by')
102
+ isVisible ? poweredBy.show() : poweredBy.hide()
103
+ })
104
+
105
+ $('#analyst-install-skip').click(function () {
106
+ var pluginId = $('#analyst-install-modal').attr('analyst-plugin-id')
107
+
108
+ $.post(ajaxurl, {action: 'analyst_skip_install_' + pluginId}).done(function () {
109
+ $('#analyst-install-modal').hide()
110
+ })
111
+ })
112
+ })(jQuery)
113
+ </script>
analyst/templates/notice.php CHANGED
@@ -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/templates/optin.php CHANGED
@@ -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/templates/optout.php CHANGED
@@ -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>
css/jquery-ui-1.10.4/jquery-ui.css CHANGED
@@ -1,1177 +1,1177 @@
1
-
2
- /*! jQuery UI - v1.10.4 - 2014-01-17
3
- * http://jqueryui.com
4
- * Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
5
- * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
6
- * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
7
-
8
- /* Layout helpers
9
- ----------------------------------*/
10
-
11
- @font-face {
12
- font-family: 'helveticaregular';
13
- src: url('../fonts/helvetica_0-webfont.eot');
14
- src: url('../fonts/helvetica_0-webfont.eot?#iefix') format('embedded-opentype'),
15
- url('../fonts/helvetica_0-webfont.woff') format('woff'),
16
- url('../fonts/helvetica_0-webfont.ttf') format('truetype'),
17
- url('../fonts/helvetica_0-webfont.svg#helveticaregular') format('svg');
18
- font-weight: normal;
19
- font-style: normal;
20
-
21
- }
22
- .ui-helper-hidden {
23
- display: none;
24
- }
25
- .ui-helper-hidden-accessible {
26
- border: 0;
27
- clip: rect(0 0 0 0);
28
- height: 1px;
29
- margin: -1px;
30
- overflow: hidden;
31
- padding: 0;
32
- position: absolute;
33
- width: 1px;
34
- }
35
- .ui-helper-reset {
36
- margin: 0;
37
- padding: 0;
38
- border: 0;
39
- outline: 0;
40
- line-height: 1.3;
41
- text-decoration: none;
42
- font-size: 100%;
43
- list-style: none;
44
- }
45
- .ui-helper-clearfix:before,
46
- .ui-helper-clearfix:after {
47
- content: "";
48
- display: table;
49
- border-collapse: collapse;
50
- }
51
- .ui-helper-clearfix:after {
52
- clear: both;
53
- }
54
- .ui-helper-clearfix {
55
- min-height: 0; /* support: IE7 */
56
- }
57
- .ui-helper-zfix {
58
- width: 100%;
59
- height: 100%;
60
- top: 0;
61
- left: 0;
62
- position: absolute;
63
- opacity: 0;
64
- filter:Alpha(Opacity=0);
65
- }
66
-
67
- .ui-front {
68
- z-index: 100;
69
- }
70
- /* Interaction Cues
71
- ----------------------------------*/
72
- .ui-state-disabled {
73
- cursor: default !important;
74
- }
75
- /* Icons
76
- ----------------------------------*/
77
-
78
- /* states and images */
79
- .ui-icon {
80
- display: block;
81
- text-indent: -99999px;
82
- overflow: hidden;
83
- background-repeat: no-repeat;
84
- }
85
- /* Misc visuals
86
- ----------------------------------*/
87
-
88
- /* Overlays */
89
- .ui-widget-overlay {
90
- position: fixed;
91
- top: 0;
92
- left: 0;
93
- width: 100%;
94
- height: 100%;
95
- }
96
- .ui-accordion .ui-accordion-header {
97
- display: block;
98
- cursor: pointer;
99
- position: relative;
100
- margin-top: 10px;
101
- padding: .6em .5em;
102
- min-height: 0; /* support: IE7 */
103
- font-size:20px;
104
- font-weight:normal;
105
- }
106
- .ui-accordion .ui-accordion-icons {
107
- padding-left: 62px;
108
- padding-right: 40px;
109
- }
110
- .ui-accordion .ui-accordion-noicons {
111
- padding-left: .7em;
112
- }
113
- .ui-accordion .ui-accordion-icons .ui-accordion-icons {
114
- padding-left: 2.2em;
115
- }
116
- .ui-accordion .ui-accordion-header .ui-accordion-header-icon {
117
- position: absolute;
118
- left: .5em;
119
- top: 50%;
120
- margin-top: -8px;
121
- display:none;
122
- }
123
- .ui-accordion .ui-accordion-content {
124
- padding:1.6em 2em 1.4em 2em;
125
- border-top: 0;
126
- }
127
- .ui-autocomplete {
128
- position: absolute;
129
- top: 0;
130
- left: 0;
131
- cursor: default;
132
- }
133
- .ui-button {
134
- display: inline-block;
135
- position: relative;
136
- padding: 0;
137
- line-height: normal;
138
- margin-right: .1em;
139
- cursor: pointer;
140
- vertical-align: middle;
141
- text-align: center;
142
- overflow: visible; /* removes extra width in IE */
143
- }
144
- .ui-button,
145
- .ui-button:link,
146
- .ui-button:visited,
147
- .ui-button:hover,
148
- .ui-button:active {
149
- text-decoration: none;
150
- }
151
- /* to make room for the icon, a width needs to be set here */
152
- .ui-button-icon-only {
153
- width: 2.2em;
154
- }
155
- /* button elements seem to need a little more width */
156
- button.ui-button-icon-only {
157
- width: 2.4em;
158
- }
159
- .ui-button-icons-only {
160
- width: 3.4em;
161
- }
162
- button.ui-button-icons-only {
163
- width: 3.7em;
164
- }
165
-
166
- /* button text element */
167
- .ui-button .ui-button-text {
168
- display: block;
169
- line-height: normal;
170
- }
171
- .ui-button-text-only .ui-button-text {
172
- padding: .4em 1em;
173
- }
174
- .ui-button-icon-only .ui-button-text,
175
- .ui-button-icons-only .ui-button-text {
176
- padding: .4em;
177
- text-indent: -9999999px;
178
- }
179
- .ui-button-text-icon-primary .ui-button-text,
180
- .ui-button-text-icons .ui-button-text {
181
- padding: .4em 1em .4em 2.1em;
182
- }
183
- .ui-button-text-icon-secondary .ui-button-text,
184
- .ui-button-text-icons .ui-button-text {
185
- padding: .4em 2.1em .4em 1em;
186
- }
187
- .ui-button-text-icons .ui-button-text {
188
- padding-left: 2.1em;
189
- padding-right: 2.1em;
190
- }
191
- /* no icon support for input elements, provide padding by default */
192
- input.ui-button {
193
- padding: .4em 1em;
194
- }
195
-
196
- /* button icon element(s) */
197
- .ui-button-icon-only .ui-icon,
198
- .ui-button-text-icon-primary .ui-icon,
199
- .ui-button-text-icon-secondary .ui-icon,
200
- .ui-button-text-icons .ui-icon,
201
- .ui-button-icons-only .ui-icon {
202
- position: absolute;
203
- top: 50%;
204
- margin-top: -8px;
205
- }
206
- .ui-button-icon-only .ui-icon {
207
- left: 50%;
208
- margin-left: -8px;
209
- }
210
- .ui-button-text-icon-primary .ui-button-icon-primary,
211
- .ui-button-text-icons .ui-button-icon-primary,
212
- .ui-button-icons-only .ui-button-icon-primary {
213
- left: .5em;
214
- }
215
- .ui-button-text-icon-secondary .ui-button-icon-secondary,
216
- .ui-button-text-icons .ui-button-icon-secondary,
217
- .ui-button-icons-only .ui-button-icon-secondary {
218
- right: .5em;
219
- }
220
-
221
- /* button sets */
222
- .ui-buttonset {
223
- margin-right: 7px;
224
- }
225
- .ui-buttonset .ui-button {
226
- margin-left: 0;
227
- margin-right: -.3em;
228
- }
229
-
230
- /* workarounds */
231
- /* reset extra padding in Firefox, see h5bp.com/l */
232
- input.ui-button::-moz-focus-inner,
233
- button.ui-button::-moz-focus-inner {
234
- border: 0;
235
- padding: 0;
236
- }
237
- .ui-datepicker {
238
- width: 17em;
239
- padding: .2em .2em 0;
240
- display: none;
241
- }
242
- .ui-datepicker .ui-datepicker-header {
243
- position: relative;
244
- padding: .2em 0;
245
- }
246
- .ui-datepicker .ui-datepicker-prev,
247
- .ui-datepicker .ui-datepicker-next {
248
- position: absolute;
249
- top: 2px;
250
- width: 1.8em;
251
- height: 1.8em;
252
- }
253
- .ui-datepicker .ui-datepicker-prev-hover,
254
- .ui-datepicker .ui-datepicker-next-hover {
255
- top: 1px;
256
- }
257
- .ui-datepicker .ui-datepicker-prev {
258
- left: 2px;
259
- }
260
- .ui-datepicker .ui-datepicker-next {
261
- right: 2px;
262
- }
263
- .ui-datepicker .ui-datepicker-prev-hover {
264
- left: 1px;
265
- }
266
- .ui-datepicker .ui-datepicker-next-hover {
267
- right: 1px;
268
- }
269
- .ui-datepicker .ui-datepicker-prev span,
270
- .ui-datepicker .ui-datepicker-next span {
271
- display: block;
272
- position: absolute;
273
- left: 50%;
274
- margin-left: -8px;
275
- top: 50%;
276
- margin-top: -8px;
277
- }
278
- .ui-datepicker .ui-datepicker-title {
279
- margin: 0 2.3em;
280
- line-height: 1.8em;
281
- text-align: center;
282
- }
283
- .ui-datepicker .ui-datepicker-title select {
284
- font-size: 1em;
285
- margin: 1px 0;
286
- }
287
- .ui-datepicker select.ui-datepicker-month,
288
- .ui-datepicker select.ui-datepicker-year {
289
- width: 49%;
290
- }
291
- .ui-datepicker table {
292
- width: 100%;
293
- font-size: .9em;
294
- border-collapse: collapse;
295
- margin: 0 0 .4em;
296
- }
297
- .ui-datepicker th {
298
- padding: .7em .3em;
299
- text-align: center;
300
- font-weight: bold;
301
- border: 0;
302
- }
303
- .ui-datepicker td {
304
- border: 0;
305
- padding: 1px;
306
- }
307
- .ui-datepicker td span,
308
- .ui-datepicker td a {
309
- display: block;
310
- padding: .2em;
311
- text-align: right;
312
- text-decoration: none;
313
- }
314
- .ui-datepicker .ui-datepicker-buttonpane {
315
- background-image: none;
316
- margin: .7em 0 0 0;
317
- padding: 0 .2em;
318
- border-left: 0;
319
- border-right: 0;
320
- border-bottom: 0;
321
- }
322
- .ui-datepicker .ui-datepicker-buttonpane button {
323
- float: right;
324
- margin: .5em .2em .4em;
325
- cursor: pointer;
326
- padding: .2em .6em .3em .6em;
327
- width: auto;
328
- overflow: visible;
329
- }
330
- .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
331
- float: left;
332
- }
333
-
334
- /* with multiple calendars */
335
- .ui-datepicker.ui-datepicker-multi {
336
- width: auto;
337
- }
338
- .ui-datepicker-multi .ui-datepicker-group {
339
- float: left;
340
- }
341
- .ui-datepicker-multi .ui-datepicker-group table {
342
- width: 95%;
343
- margin: 0 auto .4em;
344
- }
345
- .ui-datepicker-multi-2 .ui-datepicker-group {
346
- width: 50%;
347
- }
348
- .ui-datepicker-multi-3 .ui-datepicker-group {
349
- width: 33.3%;
350
- }
351
- .ui-datepicker-multi-4 .ui-datepicker-group {
352
- width: 25%;
353
- }
354
- .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
355
- .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
356
- border-left-width: 0;
357
- }
358
- .ui-datepicker-multi .ui-datepicker-buttonpane {
359
- clear: left;
360
- }
361
- .ui-datepicker-row-break {
362
- clear: both;
363
- width: 100%;
364
- font-size: 0;
365
- }
366
-
367
- /* RTL support */
368
- .ui-datepicker-rtl {
369
- direction: rtl;
370
- }
371
- .ui-datepicker-rtl .ui-datepicker-prev {
372
- right: 2px;
373
- left: auto;
374
- }
375
- .ui-datepicker-rtl .ui-datepicker-next {
376
- left: 2px;
377
- right: auto;
378
- }
379
- .ui-datepicker-rtl .ui-datepicker-prev:hover {
380
- right: 1px;
381
- left: auto;
382
- }
383
- .ui-datepicker-rtl .ui-datepicker-next:hover {
384
- left: 1px;
385
- right: auto;
386
- }
387
- .ui-datepicker-rtl .ui-datepicker-buttonpane {
388
- clear: right;
389
- }
390
- .ui-datepicker-rtl .ui-datepicker-buttonpane button {
391
- float: left;
392
- }
393
- .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
394
- .ui-datepicker-rtl .ui-datepicker-group {
395
- float: right;
396
- }
397
- .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
398
- .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
399
- border-right-width: 0;
400
- border-left-width: 1px;
401
- }
402
- .ui-dialog {
403
- overflow: hidden;
404
- position: absolute;
405
- top: 0;
406
- left: 0;
407
- padding: .2em;
408
- outline: 0;
409
- }
410
- .ui-dialog .ui-dialog-titlebar {
411
- padding: .4em 1em;
412
- position: relative;
413
- }
414
- .ui-dialog .ui-dialog-title {
415
- float: left;
416
- margin: .1em 0;
417
- white-space: nowrap;
418
- width: 90%;
419
- overflow: hidden;
420
- text-overflow: ellipsis;
421
- }
422
- .ui-dialog .ui-dialog-titlebar-close {
423
- position: absolute;
424
- right: .3em;
425
- top: 50%;
426
- width: 20px;
427
- margin: -10px 0 0 0;
428
- padding: 1px;
429
- height: 20px;
430
- }
431
- .ui-dialog .ui-dialog-content {
432
- position: relative;
433
- border: 0;
434
- padding: .5em 1em;
435
- background: none;
436
- overflow: auto;
437
- }
438
- .ui-dialog .ui-dialog-buttonpane {
439
- text-align: left;
440
- border-width: 1px 0 0 0;
441
- background-image: none;
442
- margin-top: .5em;
443
- padding: .3em 1em .5em .4em;
444
- }
445
- .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
446
- float: right;
447
- }
448
- .ui-dialog .ui-dialog-buttonpane button {
449
- margin: .5em .4em .5em 0;
450
- cursor: pointer;
451
- }
452
- .ui-dialog .ui-resizable-se {
453
- width: 12px;
454
- height: 12px;
455
- right: -5px;
456
- bottom: -5px;
457
- background-position: 16px 16px;
458
- }
459
- .ui-draggable .ui-dialog-titlebar {
460
- cursor: move;
461
- }
462
- .ui-menu {
463
- list-style: none;
464
- padding: 2px;
465
- margin: 0;
466
- display: block;
467
- outline: none;
468
- }
469
- .ui-menu .ui-menu {
470
- margin-top: -3px;
471
- position: absolute;
472
- }
473
- .ui-menu .ui-menu-item {
474
- margin: 0;
475
- padding: 0;
476
- width: 100%;
477
- /* support: IE10, see #8844 */
478
- list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
479
- }
480
- .ui-menu .ui-menu-divider {
481
- margin: 5px -2px 5px -2px;
482
- height: 0;
483
- font-size: 0;
484
- line-height: 0;
485
- border-width: 1px 0 0 0;
486
- }
487
- .ui-menu .ui-menu-item a {
488
- text-decoration: none;
489
- display: block;
490
- padding: 2px .4em;
491
- line-height: 1.5;
492
- min-height: 0; /* support: IE7 */
493
- font-weight: normal;
494
- }
495
- .ui-menu .ui-menu-item a.ui-state-focus,
496
- .ui-menu .ui-menu-item a.ui-state-active {
497
- font-weight: normal;
498
- margin: -1px;
499
- }
500
-
501
- .ui-menu .ui-state-disabled {
502
- font-weight: normal;
503
- margin: .4em 0 .2em;
504
- line-height: 1.5;
505
- }
506
- .ui-menu .ui-state-disabled a {
507
- cursor: default;
508
- }
509
-
510
- /* icon support */
511
- .ui-menu-icons {
512
- position: relative;
513
- }
514
- .ui-menu-icons .ui-menu-item a {
515
- position: relative;
516
- padding-left: 2em;
517
- }
518
-
519
- /* left-aligned */
520
- .ui-menu .ui-icon {
521
- position: absolute;
522
- top: .2em;
523
- left: .2em;
524
- }
525
-
526
- /* right-aligned */
527
- .ui-menu .ui-menu-icon {
528
- position: static;
529
- float: right;
530
- }
531
- .ui-progressbar {
532
- height: 2em;
533
- text-align: left;
534
- overflow: hidden;
535
- }
536
- .ui-progressbar .ui-progressbar-value {
537
- margin: -1px;
538
- height: 100%;
539
- }
540
- .ui-progressbar .ui-progressbar-overlay {
541
- background: url("images/animated-overlay.gif");
542
- height: 100%;
543
- filter: alpha(opacity=25);
544
- opacity: 0.25;
545
- }
546
- .ui-progressbar-indeterminate .ui-progressbar-value {
547
- background-image: none;
548
- }
549
- .ui-resizable {
550
- position: relative;
551
- }
552
- .ui-resizable-handle {
553
- position: absolute;
554
- font-size: 0.1px;
555
- display: block;
556
- }
557
- .ui-resizable-disabled .ui-resizable-handle,
558
- .ui-resizable-autohide .ui-resizable-handle {
559
- display: none;
560
- }
561
- .ui-resizable-n {
562
- cursor: n-resize;
563
- height: 7px;
564
- width: 100%;
565
- top: -5px;
566
- left: 0;
567
- }
568
- .ui-resizable-s {
569
- cursor: s-resize;
570
- height: 7px;
571
- width: 100%;
572
- bottom: -5px;
573
- left: 0;
574
- }
575
- .ui-resizable-e {
576
- cursor: e-resize;
577
- width: 7px;
578
- right: -5px;
579
- top: 0;
580
- height: 100%;
581
- }
582
- .ui-resizable-w {
583
- cursor: w-resize;
584
- width: 7px;
585
- left: -5px;
586
- top: 0;
587
- height: 100%;
588
- }
589
- .ui-resizable-se {
590
- cursor: se-resize;
591
- width: 12px;
592
- height: 12px;
593
- right: 1px;
594
- bottom: 1px;
595
- }
596
- .ui-resizable-sw {
597
- cursor: sw-resize;
598
- width: 9px;
599
- height: 9px;
600
- left: -5px;
601
- bottom: -5px;
602
- }
603
- .ui-resizable-nw {
604
- cursor: nw-resize;
605
- width: 9px;
606
- height: 9px;
607
- left: -5px;
608
- top: -5px;
609
- }
610
- .ui-resizable-ne {
611
- cursor: ne-resize;
612
- width: 9px;
613
- height: 9px;
614
- right: -5px;
615
- top: -5px;
616
- }
617
- .ui-selectable-helper {
618
- position: absolute;
619
- z-index: 100;
620
- border: 1px dotted black;
621
- }
622
- .ui-slider {
623
- position: relative;
624
- text-align: left;
625
- }
626
- .ui-slider .ui-slider-handle {
627
- position: absolute;
628
- z-index: 2;
629
- width: 1.2em;
630
- height: 1.2em;
631
- cursor: default;
632
- }
633
- .ui-slider .ui-slider-range {
634
- position: absolute;
635
- z-index: 1;
636
- font-size: .7em;
637
- display: block;
638
- border: 0;
639
- background-position: 0 0;
640
- }
641
-
642
- /* For IE8 - See #6727 */
643
- .ui-slider.ui-state-disabled .ui-slider-handle,
644
- .ui-slider.ui-state-disabled .ui-slider-range {
645
- filter: inherit;
646
- }
647
-
648
- .ui-slider-horizontal {
649
- height: .8em;
650
- }
651
- .ui-slider-horizontal .ui-slider-handle {
652
- top: -.3em;
653
- margin-left: -.6em;
654
- }
655
- .ui-slider-horizontal .ui-slider-range {
656
- top: 0;
657
- height: 100%;
658
- }
659
- .ui-slider-horizontal .ui-slider-range-min {
660
- left: 0;
661
- }
662
- .ui-slider-horizontal .ui-slider-range-max {
663
- right: 0;
664
- }
665
-
666
- .ui-slider-vertical {
667
- width: .8em;
668
- height: 100px;
669
- }
670
- .ui-slider-vertical .ui-slider-handle {
671
- left: -.3em;
672
- margin-left: 0;
673
- margin-bottom: -.6em;
674
- }
675
- .ui-slider-vertical .ui-slider-range {
676
- left: 0;
677
- width: 100%;
678
- }
679
- .ui-slider-vertical .ui-slider-range-min {
680
- bottom: 0;
681
- }
682
- .ui-slider-vertical .ui-slider-range-max {
683
- top: 0;
684
- }
685
- .ui-spinner {
686
- position: relative;
687
- display: inline-block;
688
- overflow: hidden;
689
- padding: 0;
690
- vertical-align: middle;
691
- }
692
- .ui-spinner-input {
693
- border: none;
694
- background: none;
695
- color: inherit;
696
- padding: 0;
697
- margin: .2em 0;
698
- vertical-align: middle;
699
- margin-left: .4em;
700
- margin-right: 22px;
701
- }
702
- .ui-spinner-button {
703
- width: 16px;
704
- height: 50%;
705
- font-size: .5em;
706
- padding: 0;
707
- margin: 0;
708
- text-align: center;
709
- position: absolute;
710
- cursor: default;
711
- display: block;
712
- overflow: hidden;
713
- right: 0;
714
- }
715
- /* more specificity required here to override default borders */
716
- .ui-spinner a.ui-spinner-button {
717
- border-top: none;
718
- border-bottom: none;
719
- border-right: none;
720
- }
721
- /* vertically center icon */
722
- .ui-spinner .ui-icon {
723
- position: absolute;
724
- margin-top: -8px;
725
- top: 50%;
726
- left: 0;
727
- }
728
- .ui-spinner-up {
729
- top: 0;
730
- }
731
- .ui-spinner-down {
732
- bottom: 0;
733
- }
734
-
735
- /* TR overrides */
736
- .ui-spinner .ui-icon-triangle-1-s {
737
- /* need to fix icons sprite */
738
- background-position: -65px -16px;
739
- }
740
- .ui-tabs {
741
- position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
742
- padding: .2em;
743
- }
744
- .ui-tabs .ui-tabs-nav {
745
- margin: 0;
746
- padding: .2em .2em 0;
747
- }
748
- .ui-tabs .ui-tabs-nav li {
749
- list-style: none;
750
- float: left;
751
- position: relative;
752
- top: 0;
753
- margin: 1px .2em 0 0;
754
- border-bottom-width: 0;
755
- padding: 0;
756
- white-space: nowrap;
757
- }
758
- .ui-tabs .ui-tabs-nav .ui-tabs-anchor {
759
- float: left;
760
- padding: .5em 1em;
761
- text-decoration: none;
762
- }
763
- .ui-tabs .ui-tabs-nav li.ui-tabs-active {
764
- margin-bottom: -1px;
765
- padding-bottom: 1px;
766
- }
767
- .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
768
- .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
769
- .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
770
- cursor: text;
771
- }
772
- .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
773
- cursor: pointer;
774
- }
775
- .ui-tabs .ui-tabs-panel {
776
- display: block;
777
- border-width: 0;
778
- padding: 1em 1.4em;
779
- background: none;
780
- }
781
- .ui-tooltip {
782
- padding: 8px;
783
- position: absolute;
784
- z-index: 9999;
785
- max-width: 300px;
786
- -webkit-box-shadow: 0 0 5px #aaa;
787
- box-shadow: 0 0 5px #aaa;
788
- }
789
- body .ui-tooltip {
790
- border-width: 2px;
791
- }
792
-
793
- /* Component containers
794
- ----------------------------------*/
795
- .ui-widget {
796
- font-family: 'helveticaregular';
797
- font-size: 1.1em;
798
- }
799
- .ui-widget .ui-widget {
800
- font-size: 1em;
801
- }
802
- .ui-widget input,
803
- .ui-widget select,
804
- .ui-widget textarea,
805
- .ui-widget button {
806
- font-family: 'helveticaregular';
807
- font-size:17px;
808
- }
809
- .ui-widget-content {
810
- background: #ffffff;
811
- color: #414951;
812
- }
813
- .ui-widget-content a {
814
- color: #222222;
815
- }
816
- .ui-widget-header {
817
- background: #fff;
818
- color: #222222;
819
- }
820
- .ui-widget-header a {
821
- color: #222222;
822
- }
823
-
824
- /* Interaction states
825
- ----------------------------------*/
826
- .ui-state-default,
827
- .ui-widget-content .ui-state-default,
828
- .ui-widget-header .ui-state-default {
829
- background: #fff url(../images/arrow.png) right top no-repeat;
830
- font-weight: normal;
831
- color: #414951;
832
- }
833
- .ui-state-default a,
834
- .ui-state-default a:link,
835
- .ui-state-default a:visited {
836
- color: #555555;
837
- text-decoration: none;
838
- }
839
- .ui-state-hover,
840
- .ui-widget-content .ui-state-hover,
841
- .ui-widget-header .ui-state-hover,
842
- /*.ui-state-focus, */
843
- .ui-widget-content .ui-state-focus,
844
- .ui-widget-header .ui-state-focus {
845
- background: #d22b30 url(../images/arrow.png) right -50px no-repeat;
846
- font-weight: normal;
847
- color: #eee;
848
- }
849
- .ui-state-hover a,
850
- .ui-state-hover a:hover,
851
- .ui-state-hover a:link,
852
- .ui-state-hover a:visited,
853
- .ui-state-focus a,
854
- .ui-state-focus a:hover,
855
- .ui-state-focus a:link,
856
- .ui-state-focus a:visited {
857
- color: #212121;
858
- text-decoration: none;
859
- }
860
- /*.ui-state-active,
861
- .ui-widget-content .ui-state-active,
862
- .ui-widget-header .ui-state-active {
863
- background: #d22b30 url(../images/arrow.png) right -50px no-repeat;
864
- font-weight: normal;
865
- color: #fff;
866
- }*/
867
- .ui-state-active,
868
- .ui-widget-content .ui-state-active,
869
- .ui-widget-header .ui-state-active {
870
- background: #d22b30 url(../images/arrow.png) right -105px no-repeat;
871
- font-weight: normal;
872
- color:#eeeeee;
873
- }
874
-
875
- .ui-state-active a,
876
- .ui-state-active a:link,
877
- .ui-state-active a:visited {
878
- color: #212121;
879
- text-decoration: none;
880
- }
881
-
882
- /* Interaction Cues
883
- ----------------------------------*/
884
- .ui-state-highlight,
885
- .ui-widget-content .ui-state-highlight,
886
- .ui-widget-header .ui-state-highlight {
887
- border: 1px solid #fcefa1;
888
- background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;
889
- color: #363636;
890
- }
891
- .ui-state-highlight a,
892
- .ui-widget-content .ui-state-highlight a,
893
- .ui-widget-header .ui-state-highlight a {
894
- color: #363636;
895
- }
896
- .ui-state-error,
897
- .ui-widget-content .ui-state-error,
898
- .ui-widget-header .ui-state-error {
899
- border: 1px solid #cd0a0a;
900
- background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;
901
- color: #cd0a0a;
902
- }
903
- .ui-state-error a,
904
- .ui-widget-content .ui-state-error a,
905
- .ui-widget-header .ui-state-error a {
906
- color: #cd0a0a;
907
- }
908
- .ui-state-error-text,
909
- .ui-widget-content .ui-state-error-text,
910
- .ui-widget-header .ui-state-error-text {
911
- color: #cd0a0a;
912
- }
913
- .ui-priority-primary,
914
- .ui-widget-content .ui-priority-primary,
915
- .ui-widget-header .ui-priority-primary {
916
- font-weight: bold;
917
- }
918
- .ui-priority-secondary,
919
- .ui-widget-content .ui-priority-secondary,
920
- .ui-widget-header .ui-priority-secondary {
921
- opacity: .7;
922
- filter:Alpha(Opacity=70);
923
- font-weight: normal;
924
- }
925
- .ui-state-disabled,
926
- .ui-widget-content .ui-state-disabled,
927
- .ui-widget-header .ui-state-disabled {
928
- opacity: .35;
929
- filter:Alpha(Opacity=35);
930
- background-image: none;
931
- }
932
- .ui-state-disabled .ui-icon {
933
- filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
934
- }
935
-
936
- /* Icons
937
- ----------------------------------*/
938
-
939
- /* states and images */
940
- .ui-icon {
941
- width: 16px;
942
- height: 16px;
943
- }
944
- .ui-icon,
945
- .ui-widget-content .ui-icon {
946
- background-image: url(images/ui-icons_222222_256x240.png);
947
- }
948
- .ui-widget-header .ui-icon {
949
- background-image: url(images/ui-icons_222222_256x240.png);
950
- }
951
- .ui-state-default .ui-icon {
952
- background-image: url(images/ui-icons_888888_256x240.png);
953
- }
954
- .ui-state-hover .ui-icon,
955
- .ui-state-focus .ui-icon {
956
- background-image: url(images/ui-icons_454545_256x240.png);
957
- }
958
- .ui-state-active .ui-icon {
959
- background-image: url(images/ui-icons_454545_256x240.png);
960
- }
961
- .ui-state-highlight .ui-icon {
962
- background-image: url(images/ui-icons_2e83ff_256x240.png);
963
- }
964
- .ui-state-error .ui-icon,
965
- .ui-state-error-text .ui-icon {
966
- background-image: url(images/ui-icons_cd0a0a_256x240.png);
967
- }
968
-
969
- /* positioning */
970
- .ui-icon-blank { background-position: 16px 16px; }
971
- .ui-icon-carat-1-n { background-position: 0 0; }
972
- .ui-icon-carat-1-ne { background-position: -16px 0; }
973
- .ui-icon-carat-1-e { background-position: -32px 0; }
974
- .ui-icon-carat-1-se { background-position: -48px 0; }
975
- .ui-icon-carat-1-s { background-position: -64px 0; }
976
- .ui-icon-carat-1-sw { background-position: -80px 0; }
977
- .ui-icon-carat-1-w { background-position: -96px 0; }
978
- .ui-icon-carat-1-nw { background-position: -112px 0; }
979
- .ui-icon-carat-2-n-s { background-position: -128px 0; }
980
- .ui-icon-carat-2-e-w { background-position: -144px 0; }
981
- .ui-icon-triangle-1-n { background-position: 0 -16px; }
982
- .ui-icon-triangle-1-ne { background-position: -16px -16px; }
983
- .ui-icon-triangle-1-e { background-position: -32px -16px; }
984
- .ui-icon-triangle-1-se { background-position: -48px -16px; }
985
- .ui-icon-triangle-1-s { background-position: -64px -16px; }
986
- .ui-icon-triangle-1-sw { background-position: -80px -16px; }
987
- .ui-icon-triangle-1-w { background-position: -96px -16px; }
988
- .ui-icon-triangle-1-nw { background-position: -112px -16px; }
989
- .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
990
- .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
991
- .ui-icon-arrow-1-n { background-position: 0 -32px; }
992
- .ui-icon-arrow-1-ne { background-position: -16px -32px; }
993
- .ui-icon-arrow-1-e { background-position: -32px -32px; }
994
- .ui-icon-arrow-1-se { background-position: -48px -32px; }
995
- .ui-icon-arrow-1-s { background-position: -64px -32px; }
996
- .ui-icon-arrow-1-sw { background-position: -80px -32px; }
997
- .ui-icon-arrow-1-w { background-position: -96px -32px; }
998
- .ui-icon-arrow-1-nw { background-position: -112px -32px; }
999
- .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
1000
- .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
1001
- .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
1002
- .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
1003
- .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
1004
- .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
1005
- .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
1006
- .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
1007
- .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
1008
- .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
1009
- .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
1010
- .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
1011
- .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
1012
- .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
1013
- .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
1014
- .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
1015
- .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
1016
- .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
1017
- .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
1018
- .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
1019
- .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
1020
- .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
1021
- .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
1022
- .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
1023
- .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
1024
- .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
1025
- .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
1026
- .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
1027
- .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
1028
- .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
1029
- .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
1030
- .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
1031
- .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
1032
- .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
1033
- .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
1034
- .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
1035
- .ui-icon-arrow-4 { background-position: 0 -80px; }
1036
- .ui-icon-arrow-4-diag { background-position: -16px -80px; }
1037
- .ui-icon-extlink { background-position: -32px -80px; }
1038
- .ui-icon-newwin { background-position: -48px -80px; }
1039
- .ui-icon-refresh { background-position: -64px -80px; }
1040
- .ui-icon-shuffle { background-position: -80px -80px; }
1041
- .ui-icon-transfer-e-w { background-position: -96px -80px; }
1042
- .ui-icon-transferthick-e-w { background-position: -112px -80px; }
1043
- .ui-icon-folder-collapsed { background-position: 0 -96px; }
1044
- .ui-icon-folder-open { background-position: -16px -96px; }
1045
- .ui-icon-document { background-position: -32px -96px; }
1046
- .ui-icon-document-b { background-position: -48px -96px; }
1047
- .ui-icon-note { background-position: -64px -96px; }
1048
- .ui-icon-mail-closed { background-position: -80px -96px; }
1049
- .ui-icon-mail-open { background-position: -96px -96px; }
1050
- .ui-icon-suitcase { background-position: -112px -96px; }
1051
- .ui-icon-comment { background-position: -128px -96px; }
1052
- .ui-icon-person { background-position: -144px -96px; }
1053
- .ui-icon-print { background-position: -160px -96px; }
1054
- .ui-icon-trash { background-position: -176px -96px; }
1055
- .ui-icon-locked { background-position: -192px -96px; }
1056
- .ui-icon-unlocked { background-position: -208px -96px; }
1057
- .ui-icon-bookmark { background-position: -224px -96px; }
1058
- .ui-icon-tag { background-position: -240px -96px; }
1059
- .ui-icon-home { background-position: 0 -112px; }
1060
- .ui-icon-flag { background-position: -16px -112px; }
1061
- .ui-icon-calendar { background-position: -32px -112px; }
1062
- .ui-icon-cart { background-position: -48px -112px; }
1063
- .ui-icon-pencil { background-position: -64px -112px; }
1064
- .ui-icon-clock { background-position: -80px -112px; }
1065
- .ui-icon-disk { background-position: -96px -112px; }
1066
- .ui-icon-calculator { background-position: -112px -112px; }
1067
- .ui-icon-zoomin { background-position: -128px -112px; }
1068
- .ui-icon-zoomout { background-position: -144px -112px; }
1069
- .ui-icon-search { background-position: -160px -112px; }
1070
- .ui-icon-wrench { background-position: -176px -112px; }
1071
- .ui-icon-gear { background-position: -192px -112px; }
1072
- .ui-icon-heart { background-position: -208px -112px; }
1073
- .ui-icon-star { background-position: -224px -112px; }
1074
- .ui-icon-link { background-position: -240px -112px; }
1075
- .ui-icon-cancel { background-position: 0 -128px; }
1076
- .ui-icon-plus { background-position: -16px -128px; }
1077
- .ui-icon-plusthick { background-position: -32px -128px; }
1078
- .ui-icon-minus { background-position: -48px -128px; }
1079
- .ui-icon-minusthick { background-position: -64px -128px; }
1080
- .ui-icon-close { background-position: -80px -128px; }
1081
- .ui-icon-closethick { background-position: -96px -128px; }
1082
- .ui-icon-key { background-position: -112px -128px; }
1083
- .ui-icon-lightbulb { background-position: -128px -128px; }
1084
- .ui-icon-scissors { background-position: -144px -128px; }
1085
- .ui-icon-clipboard { background-position: -160px -128px; }
1086
- .ui-icon-copy { background-position: -176px -128px; }
1087
- .ui-icon-contact { background-position: -192px -128px; }
1088
- .ui-icon-image { background-position: -208px -128px; }
1089
- .ui-icon-video { background-position: -224px -128px; }
1090
- .ui-icon-script { background-position: -240px -128px; }
1091
- .ui-icon-alert { background-position: 0 -144px; }
1092
- .ui-icon-info { background-position: -16px -144px; }
1093
- .ui-icon-notice { background-position: -32px -144px; }
1094
- .ui-icon-help { background-position: -48px -144px; }
1095
- .ui-icon-check { background-position: -64px -144px; }
1096
- .ui-icon-bullet { background-position: -80px -144px; }
1097
- .ui-icon-radio-on { background-position: -96px -144px; }
1098
- .ui-icon-radio-off { background-position: -112px -144px; }
1099
- .ui-icon-pin-w { background-position: -128px -144px; }
1100
- .ui-icon-pin-s { background-position: -144px -144px; }
1101
- .ui-icon-play { background-position: 0 -160px; }
1102
- .ui-icon-pause { background-position: -16px -160px; }
1103
- .ui-icon-seek-next { background-position: -32px -160px; }
1104
- .ui-icon-seek-prev { background-position: -48px -160px; }
1105
- .ui-icon-seek-end { background-position: -64px -160px; }
1106
- .ui-icon-seek-start { background-position: -80px -160px; }
1107
- /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
1108
- .ui-icon-seek-first { background-position: -80px -160px; }
1109
- .ui-icon-stop { background-position: -96px -160px; }
1110
- .ui-icon-eject { background-position: -112px -160px; }
1111
- .ui-icon-volume-off { background-position: -128px -160px; }
1112
- .ui-icon-volume-on { background-position: -144px -160px; }
1113
- .ui-icon-power { background-position: 0 -176px; }
1114
- .ui-icon-signal-diag { background-position: -16px -176px; }
1115
- .ui-icon-signal { background-position: -32px -176px; }
1116
- .ui-icon-battery-0 { background-position: -48px -176px; }
1117
- .ui-icon-battery-1 { background-position: -64px -176px; }
1118
- .ui-icon-battery-2 { background-position: -80px -176px; }
1119
- .ui-icon-battery-3 { background-position: -96px -176px; }
1120
- .ui-icon-circle-plus { background-position: 0 -192px; }
1121
- .ui-icon-circle-minus { background-position: -16px -192px; }
1122
- .ui-icon-circle-close { background-position: -32px -192px; }
1123
- .ui-icon-circle-triangle-e { background-position: -48px -192px; }
1124
- .ui-icon-circle-triangle-s { background-position: -64px -192px; }
1125
- .ui-icon-circle-triangle-w { background-position: -80px -192px; }
1126
- .ui-icon-circle-triangle-n { background-position: -96px -192px; }
1127
- .ui-icon-circle-arrow-e { background-position: -112px -192px; }
1128
- .ui-icon-circle-arrow-s { background-position: -128px -192px; }
1129
- .ui-icon-circle-arrow-w { background-position: -144px -192px; }
1130
- .ui-icon-circle-arrow-n { background-position: -160px -192px; }
1131
- .ui-icon-circle-zoomin { background-position: -176px -192px; }
1132
- .ui-icon-circle-zoomout { background-position: -192px -192px; }
1133
- .ui-icon-circle-check { background-position: -208px -192px; }
1134
- .ui-icon-circlesmall-plus { background-position: 0 -208px; }
1135
- .ui-icon-circlesmall-minus { background-position: -16px -208px; }
1136
- .ui-icon-circlesmall-close { background-position: -32px -208px; }
1137
- .ui-icon-squaresmall-plus { background-position: -48px -208px; }
1138
- .ui-icon-squaresmall-minus { background-position: -64px -208px; }
1139
- .ui-icon-squaresmall-close { background-position: -80px -208px; }
1140
- .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
1141
- .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
1142
- .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
1143
- .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
1144
- .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
1145
- .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
1146
- /* Misc visuals
1147
- ----------------------------------*/
1148
-
1149
- /* Corner radius */
1150
- .ui-corner-all,
1151
- .ui-corner-top,
1152
- .ui-corner-left,
1153
- .ui-corner-tl {
1154
- border-top-left-radius: 0px;
1155
- }
1156
- .ui-corner-all,
1157
- .ui-corner-top,
1158
- .ui-corner-right,
1159
- .ui-corner-tr {
1160
- border-top-right-radius: 0px;
1161
- }
1162
- .ui-corner-all,
1163
- .ui-corner-bottom,
1164
- .ui-corner-left,
1165
- .ui-corner-bl {
1166
- border-bottom-left-radius: 0px;
1167
- }
1168
- .ui-corner-all,
1169
- .ui-corner-bottom,
1170
- .ui-corner-right,
1171
- .ui-corner-br {
1172
- border-bottom-right-radius: 0px;
1173
- }
1174
- #accordion h3 span,#accordion1 h3 span{ position: absolute; left:0px; top:0px; width:50px; height:49px; background:#31373d; line-height:50px; text-align: center; font-family: 'helveticaregular'; font-size:20px; color:#FFF;}
1175
-
1176
- #accordion h3:hover span, #accordion1 h3:hover span{ background:#b8262a; color:#eee;}
1177
- #accordion h3.ui-state-active span, #accordion1 h3.ui-state-active span{ background:#b8262a; color:#eee;}
1
+
2
+ /*! jQuery UI - v1.10.4 - 2014-01-17
3
+ * http://jqueryui.com
4
+ * Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
5
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
6
+ * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
7
+
8
+ /* Layout helpers
9
+ ----------------------------------*/
10
+
11
+ @font-face {
12
+ font-family: 'helveticaregular';
13
+ src: url('../fonts/helvetica_0-webfont.eot');
14
+ src: url('../fonts/helvetica_0-webfont.eot?#iefix') format('embedded-opentype'),
15
+ url('../fonts/helvetica_0-webfont.woff') format('woff'),
16
+ url('../fonts/helvetica_0-webfont.ttf') format('truetype'),
17
+ url('../fonts/helvetica_0-webfont.svg#helveticaregular') format('svg');
18
+ font-weight: normal;
19
+ font-style: normal;
20
+
21
+ }
22
+ .ui-helper-hidden {
23
+ display: none;
24
+ }
25
+ .ui-helper-hidden-accessible {
26
+ border: 0;
27
+ clip: rect(0 0 0 0);
28
+ height: 1px;
29
+ margin: -1px;
30
+ overflow: hidden;
31
+ padding: 0;
32
+ position: absolute;
33
+ width: 1px;
34
+ }
35
+ .ui-helper-reset {
36
+ margin: 0;
37
+ padding: 0;
38
+ border: 0;
39
+ outline: 0;
40
+ line-height: 1.3;
41
+ text-decoration: none;
42
+ font-size: 100%;
43
+ list-style: none;
44
+ }
45
+ .ui-helper-clearfix:before,
46
+ .ui-helper-clearfix:after {
47
+ content: "";
48
+ display: table;
49
+ border-collapse: collapse;
50
+ }
51
+ .ui-helper-clearfix:after {
52
+ clear: both;
53
+ }
54
+ .ui-helper-clearfix {
55
+ min-height: 0; /* support: IE7 */
56
+ }
57
+ .ui-helper-zfix {
58
+ width: 100%;
59
+ height: 100%;
60
+ top: 0;
61
+ left: 0;
62
+ position: absolute;
63
+ opacity: 0;
64
+ filter:Alpha(Opacity=0);
65
+ }
66
+
67
+ .ui-front {
68
+ z-index: 100;
69
+ }
70
+ /* Interaction Cues
71
+ ----------------------------------*/
72
+ .ui-state-disabled {
73
+ cursor: default !important;
74
+ }
75
+ /* Icons
76
+ ----------------------------------*/
77
+
78
+ /* states and images */
79
+ .ui-icon {
80
+ display: block;
81
+ text-indent: -99999px;
82
+ overflow: hidden;
83
+ background-repeat: no-repeat;
84
+ }
85
+ /* Misc visuals
86
+ ----------------------------------*/
87
+
88
+ /* Overlays */
89
+ .ui-widget-overlay {
90
+ position: fixed;
91
+ top: 0;
92
+ left: 0;
93
+ width: 100%;
94
+ height: 100%;
95
+ }
96
+ .ui-accordion .ui-accordion-header {
97
+ display: block;
98
+ cursor: pointer;
99
+ position: relative;
100
+ margin-top: 10px;
101
+ padding: .6em .5em;
102
+ min-height: 0; /* support: IE7 */
103
+ font-size:20px;
104
+ font-weight:normal;
105
+ }
106
+ .ui-accordion .ui-accordion-icons {
107
+ padding-left: 62px;
108
+ padding-right: 40px;
109
+ }
110
+ .ui-accordion .ui-accordion-noicons {
111
+ padding-left: .7em;
112
+ }
113
+ .ui-accordion .ui-accordion-icons .ui-accordion-icons {
114
+ padding-left: 2.2em;
115
+ }
116
+ .ui-accordion .ui-accordion-header .ui-accordion-header-icon {
117
+ position: absolute;
118
+ left: .5em;
119
+ top: 50%;
120
+ margin-top: -8px;
121
+ display:none;
122
+ }
123
+ .ui-accordion .ui-accordion-content {
124
+ padding:1.6em 2em 1.4em 2em;
125
+ border-top: 0;
126
+ }
127
+ .ui-autocomplete {
128
+ position: absolute;
129
+ top: 0;
130
+ left: 0;
131
+ cursor: default;
132
+ }
133
+ .ui-button {
134
+ display: inline-block;
135
+ position: relative;
136
+ padding: 0;
137
+ line-height: normal;
138
+ margin-right: .1em;
139
+ cursor: pointer;
140
+ vertical-align: middle;
141
+ text-align: center;
142
+ overflow: visible; /* removes extra width in IE */
143
+ }
144
+ .ui-button,
145
+ .ui-button:link,
146
+ .ui-button:visited,
147
+ .ui-button:hover,
148
+ .ui-button:active {
149
+ text-decoration: none;
150
+ }
151
+ /* to make room for the icon, a width needs to be set here */
152
+ .ui-button-icon-only {
153
+ width: 2.2em;
154
+ }
155
+ /* button elements seem to need a little more width */
156
+ button.ui-button-icon-only {
157
+ width: 2.4em;
158
+ }
159
+ .ui-button-icons-only {
160
+ width: 3.4em;
161
+ }
162
+ button.ui-button-icons-only {
163
+ width: 3.7em;
164
+ }
165
+
166
+ /* button text element */
167
+ .ui-button .ui-button-text {
168
+ display: block;
169
+ line-height: normal;
170
+ }
171
+ .ui-button-text-only .ui-button-text {
172
+ padding: .4em 1em;
173
+ }
174
+ .ui-button-icon-only .ui-button-text,
175
+ .ui-button-icons-only .ui-button-text {
176
+ padding: .4em;
177
+ text-indent: -9999999px;
178
+ }
179
+ .ui-button-text-icon-primary .ui-button-text,
180
+ .ui-button-text-icons .ui-button-text {
181
+ padding: .4em 1em .4em 2.1em;
182
+ }
183
+ .ui-button-text-icon-secondary .ui-button-text,
184
+ .ui-button-text-icons .ui-button-text {
185
+ padding: .4em 2.1em .4em 1em;
186
+ }
187
+ .ui-button-text-icons .ui-button-text {
188
+ padding-left: 2.1em;
189
+ padding-right: 2.1em;
190
+ }
191
+ /* no icon support for input elements, provide padding by default */
192
+ input.ui-button {
193
+ padding: .4em 1em;
194
+ }
195
+
196
+ /* button icon element(s) */
197
+ .ui-button-icon-only .ui-icon,
198
+ .ui-button-text-icon-primary .ui-icon,
199
+ .ui-button-text-icon-secondary .ui-icon,
200
+ .ui-button-text-icons .ui-icon,
201
+ .ui-button-icons-only .ui-icon {
202
+ position: absolute;
203
+ top: 50%;
204
+ margin-top: -8px;
205
+ }
206
+ .ui-button-icon-only .ui-icon {
207
+ left: 50%;
208
+ margin-left: -8px;
209
+ }
210
+ .ui-button-text-icon-primary .ui-button-icon-primary,
211
+ .ui-button-text-icons .ui-button-icon-primary,
212
+ .ui-button-icons-only .ui-button-icon-primary {
213
+ left: .5em;
214
+ }
215
+ .ui-button-text-icon-secondary .ui-button-icon-secondary,
216
+ .ui-button-text-icons .ui-button-icon-secondary,
217
+ .ui-button-icons-only .ui-button-icon-secondary {
218
+ right: .5em;
219
+ }
220
+
221
+ /* button sets */
222
+ .ui-buttonset {
223
+ margin-right: 7px;
224
+ }
225
+ .ui-buttonset .ui-button {
226
+ margin-left: 0;
227
+ margin-right: -.3em;
228
+ }
229
+
230
+ /* workarounds */
231
+ /* reset extra padding in Firefox, see h5bp.com/l */
232
+ input.ui-button::-moz-focus-inner,
233
+ button.ui-button::-moz-focus-inner {
234
+ border: 0;
235
+ padding: 0;
236
+ }
237
+ .ui-datepicker {
238
+ width: 17em;
239
+ padding: .2em .2em 0;
240
+ display: none;
241
+ }
242
+ .ui-datepicker .ui-datepicker-header {
243
+ position: relative;
244
+ padding: .2em 0;
245
+ }
246
+ .ui-datepicker .ui-datepicker-prev,
247
+ .ui-datepicker .ui-datepicker-next {
248
+ position: absolute;
249
+ top: 2px;
250
+ width: 1.8em;
251
+ height: 1.8em;
252
+ }
253
+ .ui-datepicker .ui-datepicker-prev-hover,
254
+ .ui-datepicker .ui-datepicker-next-hover {
255
+ top: 1px;
256
+ }
257
+ .ui-datepicker .ui-datepicker-prev {
258
+ left: 2px;
259
+ }
260
+ .ui-datepicker .ui-datepicker-next {
261
+ right: 2px;
262
+ }
263
+ .ui-datepicker .ui-datepicker-prev-hover {
264
+ left: 1px;
265
+ }
266
+ .ui-datepicker .ui-datepicker-next-hover {
267
+ right: 1px;
268
+ }
269
+ .ui-datepicker .ui-datepicker-prev span,
270
+ .ui-datepicker .ui-datepicker-next span {
271
+ display: block;
272
+ position: absolute;
273
+ left: 50%;
274
+ margin-left: -8px;
275
+ top: 50%;
276
+ margin-top: -8px;
277
+ }
278
+ .ui-datepicker .ui-datepicker-title {
279
+ margin: 0 2.3em;
280
+ line-height: 1.8em;
281
+ text-align: center;
282
+ }
283
+ .ui-datepicker .ui-datepicker-title select {
284
+ font-size: 1em;
285
+ margin: 1px 0;
286
+ }
287
+ .ui-datepicker select.ui-datepicker-month,
288
+ .ui-datepicker select.ui-datepicker-year {
289
+ width: 49%;
290
+ }
291
+ .ui-datepicker table {
292
+ width: 100%;
293
+ font-size: .9em;
294
+ border-collapse: collapse;
295
+ margin: 0 0 .4em;
296
+ }
297
+ .ui-datepicker th {
298
+ padding: .7em .3em;
299
+ text-align: center;
300
+ font-weight: bold;
301
+ border: 0;
302
+ }
303
+ .ui-datepicker td {
304
+ border: 0;
305
+ padding: 1px;
306
+ }
307
+ .ui-datepicker td span,
308
+ .ui-datepicker td a {
309
+ display: block;
310
+ padding: .2em;
311
+ text-align: right;
312
+ text-decoration: none;
313
+ }
314
+ .ui-datepicker .ui-datepicker-buttonpane {
315
+ background-image: none;
316
+ margin: .7em 0 0 0;
317
+ padding: 0 .2em;
318
+ border-left: 0;
319
+ border-right: 0;
320
+ border-bottom: 0;
321
+ }
322
+ .ui-datepicker .ui-datepicker-buttonpane button {
323
+ float: right;
324
+ margin: .5em .2em .4em;
325
+ cursor: pointer;
326
+ padding: .2em .6em .3em .6em;
327
+ width: auto;
328
+ overflow: visible;
329
+ }
330
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
331
+ float: left;
332
+ }
333
+
334
+ /* with multiple calendars */
335
+ .ui-datepicker.ui-datepicker-multi {
336
+ width: auto;
337
+ }
338
+ .ui-datepicker-multi .ui-datepicker-group {
339
+ float: left;
340
+ }
341
+ .ui-datepicker-multi .ui-datepicker-group table {
342
+ width: 95%;
343
+ margin: 0 auto .4em;
344
+ }
345
+ .ui-datepicker-multi-2 .ui-datepicker-group {
346
+ width: 50%;
347
+ }
348
+ .ui-datepicker-multi-3 .ui-datepicker-group {
349
+ width: 33.3%;
350
+ }
351
+ .ui-datepicker-multi-4 .ui-datepicker-group {
352
+ width: 25%;
353
+ }
354
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
355
+ .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
356
+ border-left-width: 0;
357
+ }
358
+ .ui-datepicker-multi .ui-datepicker-buttonpane {
359
+ clear: left;
360
+ }
361
+ .ui-datepicker-row-break {
362
+ clear: both;
363
+ width: 100%;
364
+ font-size: 0;
365
+ }
366
+
367
+ /* RTL support */
368
+ .ui-datepicker-rtl {
369
+ direction: rtl;
370
+ }
371
+ .ui-datepicker-rtl .ui-datepicker-prev {
372
+ right: 2px;
373
+ left: auto;
374
+ }
375
+ .ui-datepicker-rtl .ui-datepicker-next {
376
+ left: 2px;
377
+ right: auto;
378
+ }
379
+ .ui-datepicker-rtl .ui-datepicker-prev:hover {
380
+ right: 1px;
381
+ left: auto;
382
+ }
383
+ .ui-datepicker-rtl .ui-datepicker-next:hover {
384
+ left: 1px;
385
+ right: auto;
386
+ }
387
+ .ui-datepicker-rtl .ui-datepicker-buttonpane {
388
+ clear: right;
389
+ }
390
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button {
391
+ float: left;
392
+ }
393
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
394
+ .ui-datepicker-rtl .ui-datepicker-group {
395
+ float: right;
396
+ }
397
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
398
+ .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
399
+ border-right-width: 0;
400
+ border-left-width: 1px;
401
+ }
402
+ .ui-dialog {
403
+ overflow: hidden;
404
+ position: absolute;
405
+ top: 0;
406
+ left: 0;
407
+ padding: .2em;
408
+ outline: 0;
409
+ }
410
+ .ui-dialog .ui-dialog-titlebar {
411
+ padding: .4em 1em;
412
+ position: relative;
413
+ }
414
+ .ui-dialog .ui-dialog-title {
415
+ float: left;
416
+ margin: .1em 0;
417
+ white-space: nowrap;
418
+ width: 90%;
419
+ overflow: hidden;
420
+ text-overflow: ellipsis;
421
+ }
422
+ .ui-dialog .ui-dialog-titlebar-close {
423
+ position: absolute;
424
+ right: .3em;
425
+ top: 50%;
426
+ width: 20px;
427
+ margin: -10px 0 0 0;
428
+ padding: 1px;
429
+ height: 20px;
430
+ }
431
+ .ui-dialog .ui-dialog-content {
432
+ position: relative;
433
+ border: 0;
434
+ padding: .5em 1em;
435
+ background: none;
436
+ overflow: auto;
437
+ }
438
+ .ui-dialog .ui-dialog-buttonpane {
439
+ text-align: left;
440
+ border-width: 1px 0 0 0;
441
+ background-image: none;
442
+ margin-top: .5em;
443
+ padding: .3em 1em .5em .4em;
444
+ }
445
+ .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
446
+ float: right;
447
+ }
448
+ .ui-dialog .ui-dialog-buttonpane button {
449
+ margin: .5em .4em .5em 0;
450
+ cursor: pointer;
451
+ }
452
+ .ui-dialog .ui-resizable-se {
453
+ width: 12px;
454
+ height: 12px;
455
+ right: -5px;
456
+ bottom: -5px;
457
+ background-position: 16px 16px;
458
+ }
459
+ .ui-draggable .ui-dialog-titlebar {
460
+ cursor: move;
461
+ }
462
+ .ui-menu {
463
+ list-style: none;
464
+ padding: 2px;
465
+ margin: 0;
466
+ display: block;
467
+ outline: none;
468
+ }
469
+ .ui-menu .ui-menu {
470
+ margin-top: -3px;
471
+ position: absolute;
472
+ }
473
+ .ui-menu .ui-menu-item {
474
+ margin: 0;
475
+ padding: 0;
476
+ width: 100%;
477
+ /* support: IE10, see #8844 */
478
+ list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
479
+ }
480
+ .ui-menu .ui-menu-divider {
481
+ margin: 5px -2px 5px -2px;
482
+ height: 0;
483
+ font-size: 0;
484
+ line-height: 0;
485
+ border-width: 1px 0 0 0;
486
+ }
487
+ .ui-menu .ui-menu-item a {
488
+ text-decoration: none;
489
+ display: block;
490
+ padding: 2px .4em;
491
+ line-height: 1.5;
492
+ min-height: 0; /* support: IE7 */
493
+ font-weight: normal;
494
+ }
495
+ .ui-menu .ui-menu-item a.ui-state-focus,
496
+ .ui-menu .ui-menu-item a.ui-state-active {
497
+ font-weight: normal;
498
+ margin: -1px;
499
+ }
500
+
501
+ .ui-menu .ui-state-disabled {
502
+ font-weight: normal;
503
+ margin: .4em 0 .2em;
504
+ line-height: 1.5;
505
+ }
506
+ .ui-menu .ui-state-disabled a {
507
+ cursor: default;
508
+ }
509
+
510
+ /* icon support */
511
+ .ui-menu-icons {
512
+ position: relative;
513
+ }
514
+ .ui-menu-icons .ui-menu-item a {
515
+ position: relative;
516
+ padding-left: 2em;
517
+ }
518
+
519
+ /* left-aligned */
520
+ .ui-menu .ui-icon {
521
+ position: absolute;
522
+ top: .2em;
523
+ left: .2em;
524
+ }
525
+
526
+ /* right-aligned */
527
+ .ui-menu .ui-menu-icon {
528
+ position: static;
529
+ float: right;
530
+ }
531
+ .ui-progressbar {
532
+ height: 2em;
533
+ text-align: left;
534
+ overflow: hidden;
535
+ }
536
+ .ui-progressbar .ui-progressbar-value {
537
+ margin: -1px;
538
+ height: 100%;
539
+ }
540
+ .ui-progressbar .ui-progressbar-overlay {
541
+ background: url("images/animated-overlay.gif");
542
+ height: 100%;
543
+ filter: alpha(opacity=25);
544
+ opacity: 0.25;
545
+ }
546
+ .ui-progressbar-indeterminate .ui-progressbar-value {
547
+ background-image: none;
548
+ }
549
+ .ui-resizable {
550
+ position: relative;
551
+ }
552
+ .ui-resizable-handle {
553
+ position: absolute;
554
+ font-size: 0.1px;
555
+ display: block;
556
+ }
557
+ .ui-resizable-disabled .ui-resizable-handle,
558
+ .ui-resizable-autohide .ui-resizable-handle {
559
+ display: none;
560
+ }
561
+ .ui-resizable-n {
562
+ cursor: n-resize;
563
+ height: 7px;
564
+ width: 100%;
565
+ top: -5px;
566
+ left: 0;
567
+ }
568
+ .ui-resizable-s {
569
+ cursor: s-resize;
570
+ height: 7px;
571
+ width: 100%;
572
+ bottom: -5px;
573
+ left: 0;
574
+ }
575
+ .ui-resizable-e {
576
+ cursor: e-resize;
577
+ width: 7px;
578
+ right: -5px;
579
+ top: 0;
580
+ height: 100%;
581
+ }
582
+ .ui-resizable-w {
583
+ cursor: w-resize;
584
+ width: 7px;
585
+ left: -5px;
586
+ top: 0;
587
+ height: 100%;
588
+ }
589
+ .ui-resizable-se {
590
+ cursor: se-resize;
591
+ width: 12px;
592
+ height: 12px;
593
+ right: 1px;
594
+ bottom: 1px;
595
+ }
596
+ .ui-resizable-sw {
597
+ cursor: sw-resize;
598
+ width: 9px;
599
+ height: 9px;
600
+ left: -5px;
601
+ bottom: -5px;
602
+ }
603
+ .ui-resizable-nw {
604
+ cursor: nw-resize;
605
+ width: 9px;
606
+ height: 9px;
607
+ left: -5px;
608
+ top: -5px;
609
+ }
610
+ .ui-resizable-ne {
611
+ cursor: ne-resize;
612
+ width: 9px;
613
+ height: 9px;
614
+ right: -5px;
615
+ top: -5px;
616
+ }
617
+ .ui-selectable-helper {
618
+ position: absolute;
619
+ z-index: 100;
620
+ border: 1px dotted black;
621
+ }
622
+ .ui-slider {
623
+ position: relative;
624
+ text-align: left;
625
+ }
626
+ .ui-slider .ui-slider-handle {
627
+ position: absolute;
628
+ z-index: 2;
629
+ width: 1.2em;
630
+ height: 1.2em;
631
+ cursor: default;
632
+ }
633
+ .ui-slider .ui-slider-range {
634
+ position: absolute;
635
+ z-index: 1;
636
+ font-size: .7em;
637
+ display: block;
638
+ border: 0;
639
+ background-position: 0 0;
640
+ }
641
+
642
+ /* For IE8 - See #6727 */
643
+ .ui-slider.ui-state-disabled .ui-slider-handle,
644
+ .ui-slider.ui-state-disabled .ui-slider-range {
645
+ filter: inherit;
646
+ }
647
+
648
+ .ui-slider-horizontal {
649
+ height: .8em;
650
+ }
651
+ .ui-slider-horizontal .ui-slider-handle {
652
+ top: -.3em;
653
+ margin-left: -.6em;
654
+ }
655
+ .ui-slider-horizontal .ui-slider-range {
656
+ top: 0;
657
+ height: 100%;
658
+ }
659
+ .ui-slider-horizontal .ui-slider-range-min {
660
+ left: 0;
661
+ }
662
+ .ui-slider-horizontal .ui-slider-range-max {
663
+ right: 0;
664
+ }
665
+
666
+ .ui-slider-vertical {
667
+ width: .8em;
668
+ height: 100px;
669
+ }
670
+ .ui-slider-vertical .ui-slider-handle {
671
+ left: -.3em;
672
+ margin-left: 0;
673
+ margin-bottom: -.6em;
674
+ }
675
+ .ui-slider-vertical .ui-slider-range {
676
+ left: 0;
677
+ width: 100%;
678
+ }
679
+ .ui-slider-vertical .ui-slider-range-min {
680
+ bottom: 0;
681
+ }
682
+ .ui-slider-vertical .ui-slider-range-max {
683
+ top: 0;
684
+ }
685
+ .ui-spinner {
686
+ position: relative;
687
+ display: inline-block;
688
+ overflow: hidden;
689
+ padding: 0;
690
+ vertical-align: middle;
691
+ }
692
+ .ui-spinner-input {
693
+ border: none;
694
+ background: none;
695
+ color: inherit;
696
+ padding: 0;
697
+ margin: .2em 0;
698
+ vertical-align: middle;
699
+ margin-left: .4em;
700
+ margin-right: 22px;
701
+ }
702
+ .ui-spinner-button {
703
+ width: 16px;
704
+ height: 50%;
705
+ font-size: .5em;
706
+ padding: 0;
707
+ margin: 0;
708
+ text-align: center;
709
+ position: absolute;
710
+ cursor: default;
711
+ display: block;
712
+ overflow: hidden;
713
+ right: 0;
714
+ }
715
+ /* more specificity required here to override default borders */
716
+ .ui-spinner a.ui-spinner-button {
717
+ border-top: none;
718
+ border-bottom: none;
719
+ border-right: none;
720
+ }
721
+ /* vertically center icon */
722
+ .ui-spinner .ui-icon {
723
+ position: absolute;
724
+ margin-top: -8px;
725
+ top: 50%;
726
+ left: 0;
727
+ }
728
+ .ui-spinner-up {
729
+ top: 0;
730
+ }
731
+ .ui-spinner-down {
732
+ bottom: 0;
733
+ }
734
+
735
+ /* TR overrides */
736
+ .ui-spinner .ui-icon-triangle-1-s {
737
+ /* need to fix icons sprite */
738
+ background-position: -65px -16px;
739
+ }
740
+ .ui-tabs {
741
+ position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
742
+ padding: .2em;
743
+ }
744
+ .ui-tabs .ui-tabs-nav {
745
+ margin: 0;
746
+ padding: .2em .2em 0;
747
+ }
748
+ .ui-tabs .ui-tabs-nav li {
749
+ list-style: none;
750
+ float: left;
751
+ position: relative;
752
+ top: 0;
753
+ margin: 1px .2em 0 0;
754
+ border-bottom-width: 0;
755
+ padding: 0;
756
+ white-space: nowrap;
757
+ }
758
+ .ui-tabs .ui-tabs-nav .ui-tabs-anchor {
759
+ float: left;
760
+ padding: .5em 1em;
761
+ text-decoration: none;
762
+ }
763
+ .ui-tabs .ui-tabs-nav li.ui-tabs-active {
764
+ margin-bottom: -1px;
765
+ padding-bottom: 1px;
766
+ }
767
+ .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
768
+ .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
769
+ .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
770
+ cursor: text;
771
+ }
772
+ .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
773
+ cursor: pointer;
774
+ }
775
+ .ui-tabs .ui-tabs-panel {
776
+ display: block;
777
+ border-width: 0;
778
+ padding: 1em 1.4em;
779
+ background: none;
780
+ }
781
+ .ui-tooltip {
782
+ padding: 8px;
783
+ position: absolute;
784
+ z-index: 9999;
785
+ max-width: 300px;
786
+ -webkit-box-shadow: 0 0 5px #aaa;
787
+ box-shadow: 0 0 5px #aaa;
788
+ }
789
+ body .ui-tooltip {
790
+ border-width: 2px;
791
+ }
792
+
793
+ /* Component containers
794
+ ----------------------------------*/
795
+ .ui-widget {
796
+ font-family: 'helveticaregular';
797
+ font-size: 1.1em;
798
+ }
799
+ .ui-widget .ui-widget {
800
+ font-size: 1em;
801
+ }
802
+ .ui-widget input,
803
+ .ui-widget select,
804
+ .ui-widget textarea,
805
+ .ui-widget button {
806
+ font-family: 'helveticaregular';
807
+ font-size:17px;
808
+ }
809
+ .ui-widget-content {
810
+ background: #ffffff;
811
+ color: #414951;
812
+ }
813
+ .ui-widget-content a {
814
+ color: #222222;
815
+ }
816
+ .ui-widget-header {
817
+ background: #fff;
818
+ color: #222222;
819
+ }
820
+ .ui-widget-header a {
821
+ color: #222222;
822
+ }
823
+
824
+ /* Interaction states
825
+ ----------------------------------*/
826
+ .ui-state-default,
827
+ .ui-widget-content .ui-state-default,
828
+ .ui-widget-header .ui-state-default {
829
+ background: #fff url(../images/arrow.png) right top no-repeat;
830
+ font-weight: normal;
831
+ color: #414951;
832
+ }
833
+ .ui-state-default a,
834
+ .ui-state-default a:link,
835
+ .ui-state-default a:visited {
836
+ color: #555555;
837
+ text-decoration: none;
838
+ }
839
+ .ui-state-hover,
840
+ .ui-widget-content .ui-state-hover,
841
+ .ui-widget-header .ui-state-hover,
842
+ /*.ui-state-focus, */
843
+ .ui-widget-content .ui-state-focus,
844
+ .ui-widget-header .ui-state-focus {
845
+ background: #d22b30 url(../images/arrow.png) right -50px no-repeat;
846
+ font-weight: normal;
847
+ color: #eee;
848
+ }
849
+ .ui-state-hover a,
850
+ .ui-state-hover a:hover,
851
+ .ui-state-hover a:link,
852
+ .ui-state-hover a:visited,
853
+ .ui-state-focus a,
854
+ .ui-state-focus a:hover,
855
+ .ui-state-focus a:link,
856
+ .ui-state-focus a:visited {
857
+ color: #212121;
858
+ text-decoration: none;
859
+ }
860
+ /*.ui-state-active,
861
+ .ui-widget-content .ui-state-active,
862
+ .ui-widget-header .ui-state-active {
863
+ background: #d22b30 url(../images/arrow.png) right -50px no-repeat;
864
+ font-weight: normal;
865
+ color: #fff;
866
+ }*/
867
+ .ui-state-active,
868
+ .ui-widget-content .ui-state-active,
869
+ .ui-widget-header .ui-state-active {
870
+ background: #d22b30 url(../images/arrow.png) right -105px no-repeat;
871
+ font-weight: normal;
872
+ color:#eeeeee;
873
+ }
874
+
875
+ .ui-state-active a,
876
+ .ui-state-active a:link,
877
+ .ui-state-active a:visited {
878
+ color: #212121;
879
+ text-decoration: none;
880
+ }
881
+
882
+ /* Interaction Cues
883
+ ----------------------------------*/
884
+ .ui-state-highlight,
885
+ .ui-widget-content .ui-state-highlight,
886
+ .ui-widget-header .ui-state-highlight {
887
+ border: 1px solid #fcefa1;
888
+ background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;
889
+ color: #363636;
890
+ }
891
+ .ui-state-highlight a,
892
+ .ui-widget-content .ui-state-highlight a,
893
+ .ui-widget-header .ui-state-highlight a {
894
+ color: #363636;
895
+ }
896
+ .ui-state-error,
897
+ .ui-widget-content .ui-state-error,
898
+ .ui-widget-header .ui-state-error {
899
+ border: 1px solid #cd0a0a;
900
+ background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;
901
+ color: #cd0a0a;
902
+ }
903
+ .ui-state-error a,
904
+ .ui-widget-content .ui-state-error a,
905
+ .ui-widget-header .ui-state-error a {
906
+ color: #cd0a0a;
907
+ }
908
+ .ui-state-error-text,
909
+ .ui-widget-content .ui-state-error-text,
910
+ .ui-widget-header .ui-state-error-text {
911
+ color: #cd0a0a;
912
+ }
913
+ .ui-priority-primary,
914
+ .ui-widget-content .ui-priority-primary,
915
+ .ui-widget-header .ui-priority-primary {
916
+ font-weight: bold;
917
+ }
918
+ .ui-priority-secondary,
919
+ .ui-widget-content .ui-priority-secondary,
920
+ .ui-widget-header .ui-priority-secondary {
921
+ opacity: .7;
922
+ filter:Alpha(Opacity=70);
923
+ font-weight: normal;
924
+ }
925
+ .ui-state-disabled,
926
+ .ui-widget-content .ui-state-disabled,
927
+ .ui-widget-header .ui-state-disabled {
928
+ opacity: .35;
929
+ filter:Alpha(Opacity=35);
930
+ background-image: none;
931
+ }
932
+ .ui-state-disabled .ui-icon {
933
+ filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
934
+ }
935
+
936
+ /* Icons
937
+ ----------------------------------*/
938
+
939
+ /* states and images */
940
+ .ui-icon {
941
+ width: 16px;
942
+ height: 16px;
943
+ }
944
+ .ui-icon,
945
+ .ui-widget-content .ui-icon {
946
+ background-image: url(images/ui-icons_222222_256x240.png);
947
+ }
948
+ .ui-widget-header .ui-icon {
949
+ background-image: url(images/ui-icons_222222_256x240.png);
950
+ }
951
+ .ui-state-default .ui-icon {
952
+ background-image: url(images/ui-icons_888888_256x240.png);
953
+ }
954
+ .ui-state-hover .ui-icon,
955
+ .ui-state-focus .ui-icon {
956
+ background-image: url(images/ui-icons_454545_256x240.png);
957
+ }
958
+ .ui-state-active .ui-icon {
959
+ background-image: url(images/ui-icons_454545_256x240.png);
960
+ }
961
+ .ui-state-highlight .ui-icon {
962
+ background-image: url(images/ui-icons_2e83ff_256x240.png);
963
+ }
964
+ .ui-state-error .ui-icon,
965
+ .ui-state-error-text .ui-icon {
966
+ background-image: url(images/ui-icons_cd0a0a_256x240.png);
967
+ }
968
+
969
+ /* positioning */
970
+ .ui-icon-blank { background-position: 16px 16px; }
971
+ .ui-icon-carat-1-n { background-position: 0 0; }
972
+ .ui-icon-carat-1-ne { background-position: -16px 0; }
973
+ .ui-icon-carat-1-e { background-position: -32px 0; }
974
+ .ui-icon-carat-1-se { background-position: -48px 0; }
975
+ .ui-icon-carat-1-s { background-position: -64px 0; }
976
+ .ui-icon-carat-1-sw { background-position: -80px 0; }
977
+ .ui-icon-carat-1-w { background-position: -96px 0; }
978
+ .ui-icon-carat-1-nw { background-position: -112px 0; }
979
+ .ui-icon-carat-2-n-s { background-position: -128px 0; }
980
+ .ui-icon-carat-2-e-w { background-position: -144px 0; }
981
+ .ui-icon-triangle-1-n { background-position: 0 -16px; }
982
+ .ui-icon-triangle-1-ne { background-position: -16px -16px; }
983
+ .ui-icon-triangle-1-e { background-position: -32px -16px; }
984
+ .ui-icon-triangle-1-se { background-position: -48px -16px; }
985
+ .ui-icon-triangle-1-s { background-position: -64px -16px; }
986
+ .ui-icon-triangle-1-sw { background-position: -80px -16px; }
987
+ .ui-icon-triangle-1-w { background-position: -96px -16px; }
988
+ .ui-icon-triangle-1-nw { background-position: -112px -16px; }
989
+ .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
990
+ .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
991
+ .ui-icon-arrow-1-n { background-position: 0 -32px; }
992
+ .ui-icon-arrow-1-ne { background-position: -16px -32px; }
993
+ .ui-icon-arrow-1-e { background-position: -32px -32px; }
994
+ .ui-icon-arrow-1-se { background-position: -48px -32px; }
995
+ .ui-icon-arrow-1-s { background-position: -64px -32px; }
996
+ .ui-icon-arrow-1-sw { background-position: -80px -32px; }
997
+ .ui-icon-arrow-1-w { background-position: -96px -32px; }
998
+ .ui-icon-arrow-1-nw { background-position: -112px -32px; }
999
+ .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
1000
+ .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
1001
+ .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
1002
+ .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
1003
+ .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
1004
+ .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
1005
+ .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
1006
+ .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
1007
+ .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
1008
+ .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
1009
+ .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
1010
+ .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
1011
+ .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
1012
+ .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
1013
+ .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
1014
+ .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
1015
+ .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
1016
+ .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
1017
+ .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
1018
+ .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
1019
+ .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
1020
+ .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
1021
+ .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
1022
+ .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
1023
+ .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
1024
+ .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
1025
+ .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
1026
+ .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
1027
+ .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
1028
+ .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
1029
+ .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
1030
+ .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
1031
+ .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
1032
+ .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
1033
+ .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
1034
+ .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
1035
+ .ui-icon-arrow-4 { background-position: 0 -80px; }
1036
+ .ui-icon-arrow-4-diag { background-position: -16px -80px; }
1037
+ .ui-icon-extlink { background-position: -32px -80px; }
1038
+ .ui-icon-newwin { background-position: -48px -80px; }
1039
+ .ui-icon-refresh { background-position: -64px -80px; }
1040
+ .ui-icon-shuffle { background-position: -80px -80px; }
1041
+ .ui-icon-transfer-e-w { background-position: -96px -80px; }
1042
+ .ui-icon-transferthick-e-w { background-position: -112px -80px; }
1043
+ .ui-icon-folder-collapsed { background-position: 0 -96px; }
1044
+ .ui-icon-folder-open { background-position: -16px -96px; }
1045
+ .ui-icon-document { background-position: -32px -96px; }
1046
+ .ui-icon-document-b { background-position: -48px -96px; }
1047
+ .ui-icon-note { background-position: -64px -96px; }
1048
+ .ui-icon-mail-closed { background-position: -80px -96px; }
1049
+ .ui-icon-mail-open { background-position: -96px -96px; }
1050
+ .ui-icon-suitcase { background-position: -112px -96px; }
1051
+ .ui-icon-comment { background-position: -128px -96px; }
1052
+ .ui-icon-person { background-position: -144px -96px; }
1053
+ .ui-icon-print { background-position: -160px -96px; }
1054
+ .ui-icon-trash { background-position: -176px -96px; }
1055
+ .ui-icon-locked { background-position: -192px -96px; }
1056
+ .ui-icon-unlocked { background-position: -208px -96px; }
1057
+ .ui-icon-bookmark { background-position: -224px -96px; }
1058
+ .ui-icon-tag { background-position: -240px -96px; }
1059
+ .ui-icon-home { background-position: 0 -112px; }
1060
+ .ui-icon-flag { background-position: -16px -112px; }
1061
+ .ui-icon-calendar { background-position: -32px -112px; }
1062
+ .ui-icon-cart { background-position: -48px -112px; }
1063
+ .ui-icon-pencil { background-position: -64px -112px; }
1064
+ .ui-icon-clock { background-position: -80px -112px; }
1065
+ .ui-icon-disk { background-position: -96px -112px; }
1066
+ .ui-icon-calculator { background-position: -112px -112px; }
1067
+ .ui-icon-zoomin { background-position: -128px -112px; }
1068
+ .ui-icon-zoomout { background-position: -144px -112px; }
1069
+ .ui-icon-search { background-position: -160px -112px; }
1070
+ .ui-icon-wrench { background-position: -176px -112px; }
1071
+ .ui-icon-gear { background-position: -192px -112px; }
1072
+ .ui-icon-heart { background-position: -208px -112px; }
1073
+ .ui-icon-star { background-position: -224px -112px; }
1074
+ .ui-icon-link { background-position: -240px -112px; }
1075
+ .ui-icon-cancel { background-position: 0 -128px; }
1076
+ .ui-icon-plus { background-position: -16px -128px; }
1077
+ .ui-icon-plusthick { background-position: -32px -128px; }
1078
+ .ui-icon-minus { background-position: -48px -128px; }
1079
+ .ui-icon-minusthick { background-position: -64px -128px; }
1080
+ .ui-icon-close { background-position: -80px -128px; }
1081
+ .ui-icon-closethick { background-position: -96px -128px; }
1082
+ .ui-icon-key { background-position: -112px -128px; }
1083
+ .ui-icon-lightbulb { background-position: -128px -128px; }
1084
+ .ui-icon-scissors { background-position: -144px -128px; }
1085
+ .ui-icon-clipboard { background-position: -160px -128px; }
1086
+ .ui-icon-copy { background-position: -176px -128px; }
1087
+ .ui-icon-contact { background-position: -192px -128px; }
1088
+ .ui-icon-image { background-position: -208px -128px; }
1089
+ .ui-icon-video { background-position: -224px -128px; }
1090
+ .ui-icon-script { background-position: -240px -128px; }
1091
+ .ui-icon-alert { background-position: 0 -144px; }
1092
+ .ui-icon-info { background-position: -16px -144px; }
1093
+ .ui-icon-notice { background-position: -32px -144px; }
1094
+ .ui-icon-help { background-position: -48px -144px; }
1095
+ .ui-icon-check { background-position: -64px -144px; }
1096
+ .ui-icon-bullet { background-position: -80px -144px; }
1097
+ .ui-icon-radio-on { background-position: -96px -144px; }
1098
+ .ui-icon-radio-off { background-position: -112px -144px; }
1099
+ .ui-icon-pin-w { background-position: -128px -144px; }
1100
+ .ui-icon-pin-s { background-position: -144px -144px; }
1101
+ .ui-icon-play { background-position: 0 -160px; }
1102
+ .ui-icon-pause { background-position: -16px -160px; }
1103
+ .ui-icon-seek-next { background-position: -32px -160px; }
1104
+ .ui-icon-seek-prev { background-position: -48px -160px; }
1105
+ .ui-icon-seek-end { background-position: -64px -160px; }
1106
+ .ui-icon-seek-start { background-position: -80px -160px; }
1107
+ /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
1108
+ .ui-icon-seek-first { background-position: -80px -160px; }
1109
+ .ui-icon-stop { background-position: -96px -160px; }
1110
+ .ui-icon-eject { background-position: -112px -160px; }
1111
+ .ui-icon-volume-off { background-position: -128px -160px; }
1112
+ .ui-icon-volume-on { background-position: -144px -160px; }
1113
+ .ui-icon-power { background-position: 0 -176px; }
1114
+ .ui-icon-signal-diag { background-position: -16px -176px; }
1115
+ .ui-icon-signal { background-position: -32px -176px; }
1116
+ .ui-icon-battery-0 { background-position: -48px -176px; }
1117
+ .ui-icon-battery-1 { background-position: -64px -176px; }
1118
+ .ui-icon-battery-2 { background-position: -80px -176px; }
1119
+ .ui-icon-battery-3 { background-position: -96px -176px; }
1120
+ .ui-icon-circle-plus { background-position: 0 -192px; }
1121
+ .ui-icon-circle-minus { background-position: -16px -192px; }
1122
+ .ui-icon-circle-close { background-position: -32px -192px; }
1123
+ .ui-icon-circle-triangle-e { background-position: -48px -192px; }
1124
+ .ui-icon-circle-triangle-s { background-position: -64px -192px; }
1125
+ .ui-icon-circle-triangle-w { background-position: -80px -192px; }
1126
+ .ui-icon-circle-triangle-n { background-position: -96px -192px; }
1127
+ .ui-icon-circle-arrow-e { background-position: -112px -192px; }
1128
+ .ui-icon-circle-arrow-s { background-position: -128px -192px; }
1129
+ .ui-icon-circle-arrow-w { background-position: -144px -192px; }
1130
+ .ui-icon-circle-arrow-n { background-position: -160px -192px; }
1131
+ .ui-icon-circle-zoomin { background-position: -176px -192px; }
1132
+ .ui-icon-circle-zoomout { background-position: -192px -192px; }
1133
+ .ui-icon-circle-check { background-position: -208px -192px; }
1134
+ .ui-icon-circlesmall-plus { background-position: 0 -208px; }
1135
+ .ui-icon-circlesmall-minus { background-position: -16px -208px; }
1136
+ .ui-icon-circlesmall-close { background-position: -32px -208px; }
1137
+ .ui-icon-squaresmall-plus { background-position: -48px -208px; }
1138
+ .ui-icon-squaresmall-minus { background-position: -64px -208px; }
1139
+ .ui-icon-squaresmall-close { background-position: -80px -208px; }
1140
+ .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
1141
+ .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
1142
+ .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
1143
+ .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
1144
+ .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
1145
+ .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
1146
+ /* Misc visuals
1147
+ ----------------------------------*/
1148
+
1149
+ /* Corner radius */
1150
+ .ui-corner-all,
1151
+ .ui-corner-top,
1152
+ .ui-corner-left,
1153
+ .ui-corner-tl {
1154
+ border-top-left-radius: 0px;
1155
+ }
1156
+ .ui-corner-all,
1157
+ .ui-corner-top,
1158
+ .ui-corner-right,
1159
+ .ui-corner-tr {
1160
+ border-top-right-radius: 0px;
1161
+ }
1162
+ .ui-corner-all,
1163
+ .ui-corner-bottom,
1164
+ .ui-corner-left,
1165
+ .ui-corner-bl {
1166
+ border-bottom-left-radius: 0px;
1167
+ }
1168
+ .ui-corner-all,
1169
+ .ui-corner-bottom,
1170
+ .ui-corner-right,
1171
+ .ui-corner-br {
1172
+ border-bottom-right-radius: 0px;
1173
+ }
1174
+ #accordion h3 span,#accordion1 h3 span{ position: absolute; left:0px; top:0px; width:50px; height:49px; background:#31373d; line-height:50px; text-align: center; font-family: 'helveticaregular'; font-size:20px; color:#FFF;}
1175
+
1176
+ #accordion h3:hover span, #accordion1 h3:hover span{ background:#b8262a; color:#eee;}
1177
+ #accordion h3.ui-state-active span, #accordion1 h3.ui-state-active span{ background:#b8262a; color:#eee;}
css/sfsi-style.css CHANGED
@@ -1159,10 +1159,13 @@ ul.tab_3_icns li .radio {
1159
 
1160
  .sfsi_Sicons .fb_iframe_widget {
1161
  float: left;
1162
- /*min-width: 98px;*/
1163
  width: 73px;
1164
  margin: 2px 0 0;
1165
  }
 
 
 
1166
 
1167
  .sfsi_pop_up .button a:hover {
1168
  color: #fff;
@@ -2811,15 +2814,16 @@ ul.cstmskin_iconlist {
2811
  left: 67px;
2812
  line-height: 18px !important;
2813
  margin-left: 0px;
2814
- margin-top: 8px;
2815
  padding: 1px 0;
2816
- position: absolute;
2817
  text-align: center;
2818
  top: -8px;
2819
  white-space: pre;
2820
  width: 33px;
2821
  height: 24px;
2822
  z-index: 9;
 
2823
  }
2824
 
2825
  .sfsi_wicons a.sficn,
@@ -3485,4 +3489,25 @@ ul.sfsi_icn_listing8 li .tb_4_ck{
3485
  padding-right: 11px;
3486
  text-decoration: underline;
3487
  cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3488
  }
1159
 
1160
  .sfsi_Sicons .fb_iframe_widget {
1161
  float: left;
1162
+ min-width: 115px;
1163
  width: 73px;
1164
  margin: 2px 0 0;
1165
  }
1166
+ .sfsi_Sicons .fb_iframe_widget[data-layout="button_count"]{
1167
+ min-width:125px;
1168
+ }
1169
 
1170
  .sfsi_pop_up .button a:hover {
1171
  color: #fff;
2814
  left: 67px;
2815
  line-height: 18px !important;
2816
  margin-left: 0px;
2817
+ margin-top: 0px;
2818
  padding: 1px 0;
2819
+ /*position: absolute;*/
2820
  text-align: center;
2821
  top: -8px;
2822
  white-space: pre;
2823
  width: 33px;
2824
  height: 24px;
2825
  z-index: 9;
2826
+ float:left;
2827
  }
2828
 
2829
  .sfsi_wicons a.sficn,
3489
  padding-right: 11px;
3490
  text-decoration: underline;
3491
  cursor: pointer;
3492
+ }
3493
+
3494
+ .sf_subscrbe .bot_no,
3495
+ .sf_fb .bot_no,
3496
+ .sf_twiter .bot_no,
3497
+ .sf_pinit .bot_no,
3498
+ .sf_linkedin .bot_no
3499
+ {
3500
+ background: rgba(0, 0, 0, 0) url(images/count_left_arow.png) no-repeat scroll 0 0 / 27px auto;
3501
+ font-size: 12px !important;
3502
+ left: 67px;
3503
+ line-height: 17px !important;
3504
+ margin-left: 0;
3505
+ padding: 1px 0;
3506
+ text-align: center;
3507
+ white-space: pre;
3508
+ width: 33px;
3509
+ height: 19px;
3510
+ z-index: 9;
3511
+ display: inline-block;
3512
+ vertical-align:top!important;
3513
  }
helpers/common_helper.php CHANGED
@@ -1,203 +1,203 @@
1
- <?php
2
- if(!function_exists('sfsi_get_displayed_std_desktop_icons')){
3
-
4
- function sfsi_get_displayed_std_desktop_icons($option1=false){
5
-
6
- $option1 = false !== $option1 && is_array($option1) ? $option1 : unserialize(get_option('sfsi_section1_options',false));
7
-
8
- $arrDisplay = array();
9
-
10
- if(false !== $option1 && is_array($option1) ){
11
-
12
- foreach ($option1 as $key => $value) {
13
-
14
- if(strpos($key, '_display') !== false){
15
-
16
- $arrDisplay[$key] = isset($option1[$key]) ? sanitize_text_field($option1[$key]) : '';
17
-
18
- }
19
- }
20
- }
21
-
22
- return $arrDisplay;
23
-
24
- }
25
- }
26
-
27
- if(!function_exists('sfsi_get_displayed_custom_desktop_icons')){
28
-
29
- function sfsi_get_displayed_custom_desktop_icons($option1=false){
30
-
31
- $option1 = false != $option1 && is_array($option1) ? $option1 : unserialize(get_option('sfsi_section1_options',false));
32
-
33
- $arrDisplay = array();
34
-
35
- if(!empty($option1) && is_array($option1) && isset($option1['sfsi_custom_files'])
36
- && !empty($option1['sfsi_custom_files']) ) :
37
-
38
- $arrdbDisplay = unserialize($option1['sfsi_custom_files']);
39
-
40
- if(is_array($arrdbDisplay)):
41
-
42
- $arrDisplay = $arrdbDisplay;
43
-
44
- endif;
45
-
46
- endif;
47
-
48
- return $arrDisplay;
49
- }
50
-
51
- }
52
-
53
- if(!function_exists('sfsi_icon_get_icon_image')){
54
- function sfsi_icon_get_icon_image($icon_name,$iconImgName=false){
55
-
56
- $icon = false;
57
-
58
- $option3 = unserialize(get_option('sfsi_section3_options',false));
59
-
60
- if(isset($option3['sfsi_actvite_theme']) && !empty($option3['sfsi_actvite_theme'])){
61
-
62
- $active_theme = $option3['sfsi_actvite_theme'];
63
-
64
- $icons_baseUrl = SFSI_PLUGURL."images/icons_theme/".$active_theme."/";
65
- $visit_iconsUrl = SFSI_PLUGURL."images/visit_icons/";
66
-
67
- if(isset($icon_name) && !empty($icon_name)):
68
-
69
- if($active_theme == 'custom_support')
70
- {
71
- switch (strtolower($icon_name)) {
72
-
73
- case 'facebook':
74
- $custom_icon_name = "fb";
75
- break;
76
-
77
- case 'pinterest':
78
- $custom_icon_name = "pintrest";
79
- break;
80
-
81
- default:
82
- $custom_icon_name = $icon_name;
83
- break;
84
- }
85
-
86
- $key = $custom_icon_name."_skin";
87
-
88
- $skin = get_option($key,false);
89
-
90
- $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https" : "http";
91
-
92
- if($skin)
93
- {
94
- $skin_url = parse_url($skin);
95
- if($skin_url['scheme']==='http' && $scheme==='https'){
96
- $icon = str_replace('http','https',$skin);
97
- }else if($skin_url['scheme']==='https' && $scheme==='http'){
98
- $icon = str_replace('https','http',$skin);
99
- }else{
100
- $icon = $skin;
101
- }
102
- }
103
- else
104
- {
105
- $active_theme = 'default';
106
- $icons_baseUrl = SFSI_PLUGURL."images/icons_theme/default/";
107
-
108
- $iconImgName = false != $iconImgName ? $iconImgName: $icon_name;
109
- $icon = $icons_baseUrl.$active_theme."_".$iconImgName.".png";
110
- }
111
- }
112
- else
113
- {
114
- $iconImgName = false != $iconImgName ? $iconImgName: $icon_name;
115
- $icon = $icons_baseUrl.$active_theme."_".$iconImgName.".png";
116
- }
117
-
118
- endif;
119
-
120
- }
121
-
122
- return $icon;
123
- }
124
- }
125
-
126
- if(!function_exists('sfsi_icon_generate_other_icon_effect_admin_html')){
127
-
128
- function sfsi_icon_generate_other_icon_effect_admin_html($iconName,$arrActiveDesktopIcons,$customIconIndex=-1,$customIconImgUrl=null,$customIconSrNo=null){
129
-
130
- $iconImgVal = false;
131
- $activeIconImgUrl = false;
132
-
133
- $classForRevertLink = 'hide';
134
- $defaultIconImgUrl = false;
135
-
136
- $displayIconClass = "hide";
137
-
138
- $arruploadDir = wp_upload_dir();
139
-
140
- if( isset($iconName) && !empty($iconName)){
141
-
142
- if("custom" == $iconName && $customIconIndex >-1){
143
-
144
- if(null !== $customIconImgUrl){
145
-
146
- $activeIconImgUrl = $customIconImgUrl;
147
- $defaultIconImgUrl = $customIconImgUrl;
148
-
149
- // Check if icon is selected under Question 1
150
- if(in_array($customIconImgUrl, $arrActiveDesktopIcons)){
151
- $displayIconClass = "show";
152
- }
153
-
154
- $iconNameStr = $iconName.$customIconSrNo;
155
-
156
- }
157
-
158
- }
159
-
160
- else{
161
-
162
- $dbKey = "sfsi_".$iconName."_display";
163
-
164
- if(isset($arrActiveDesktopIcons[$dbKey]) && !empty($arrActiveDesktopIcons[$dbKey])
165
- && "yes" == $arrActiveDesktopIcons[$dbKey]){
166
- $displayIconClass = "show";
167
- }
168
-
169
- $activeIconImgUrl = sfsi_icon_get_icon_image($iconName);
170
-
171
- $iconNameStr = $iconName;
172
- }
173
- if(false != $iconImgVal && !filter_var($iconImgVal, FILTER_VALIDATE_URL)){
174
-
175
- $iconImgVal = SFSI_UPLOAD_DIR_BASEURL.$iconImgVal;
176
- }
177
-
178
- $attrCustomIconSrNo = null !== $customIconSrNo ? 'data-customiconsrno="'.$customIconSrNo.'"': null;
179
- $attrCustomIconIndex = -1 != $customIconIndex ? 'data-customiconindex="'.$customIconIndex.'"': null;
180
-
181
- $attrIconName = 'data-iconname="'.$iconName.'"';
182
-
183
- ?>
184
- <div <?php echo $attrCustomIconIndex;?><?php echo $attrIconName; ?> class="col-md-3 bottommargin20 <?php echo $displayIconClass; ?>">
185
-
186
- <label <?php echo $attrCustomIconSrNo; ?> class="mouseover_other_icon_label"><?php echo ucfirst($iconNameStr); ?> </label>
187
-
188
- <img data-defaultImg="<?php echo $defaultIconImgUrl; ?>" class="mouseover_other_icon_img" src="<?php echo $activeIconImgUrl; ?>" alt="error">
189
-
190
- <input <?php echo $attrCustomIconIndex; ?><?php echo $attrIconName; ?> type="hidden" value="<?php echo $iconImgVal; ?>" name="mouseover_other_icon_<?php echo $iconName; ?>">
191
-
192
- <a <?php echo $attrCustomIconIndex; ?><?php echo $attrIconName; ?> id="btn_mouseover_other_icon_<?php echo $iconName; ?>" class="mouseover_other_icon_change_link mouseover_other_icon" href="javascript:void(0)" >Change</a>
193
-
194
- <a <?php echo $attrCustomIconIndex; ?><?php echo $attrIconName; ?> class="<?php echo $classForRevertLink; ?> mouseover_other_icon_revert_link mouseover_other_icon" href="javascript:void(0)">Revert</a>
195
-
196
- </div>
197
-
198
- <?php
199
-
200
- }
201
-
202
- }
203
  }
1
+ <?php
2
+ if(!function_exists('sfsi_get_displayed_std_desktop_icons')){
3
+
4
+ function sfsi_get_displayed_std_desktop_icons($option1=false){
5
+
6
+ $option1 = false !== $option1 && is_array($option1) ? $option1 : unserialize(get_option('sfsi_section1_options',false));
7
+
8
+ $arrDisplay = array();
9
+
10
+ if(false !== $option1 && is_array($option1) ){
11
+
12
+ foreach ($option1 as $key => $value) {
13
+
14
+ if(strpos($key, '_display') !== false){
15
+
16
+ $arrDisplay[$key] = isset($option1[$key]) ? sanitize_text_field($option1[$key]) : '';
17
+
18
+ }
19
+ }
20
+ }
21
+
22
+ return $arrDisplay;
23
+
24
+ }
25
+ }
26
+
27
+ if(!function_exists('sfsi_get_displayed_custom_desktop_icons')){
28
+
29
+ function sfsi_get_displayed_custom_desktop_icons($option1=false){
30
+
31
+ $option1 = false != $option1 && is_array($option1) ? $option1 : unserialize(get_option('sfsi_section1_options',false));
32
+
33
+ $arrDisplay = array();
34
+
35
+ if(!empty($option1) && is_array($option1) && isset($option1['sfsi_custom_files'])
36
+ && !empty($option1['sfsi_custom_files']) ) :
37
+
38
+ $arrdbDisplay = unserialize($option1['sfsi_custom_files']);
39
+
40
+ if(is_array($arrdbDisplay)):
41
+
42
+ $arrDisplay = $arrdbDisplay;
43
+
44
+ endif;
45
+
46
+ endif;
47
+
48
+ return $arrDisplay;
49
+ }
50
+
51
+ }
52
+
53
+ if(!function_exists('sfsi_icon_get_icon_image')){
54
+ function sfsi_icon_get_icon_image($icon_name,$iconImgName=false){
55
+
56
+ $icon = false;
57
+
58
+ $option3 = unserialize(get_option('sfsi_section3_options',false));
59
+
60
+ if(isset($option3['sfsi_actvite_theme']) && !empty($option3['sfsi_actvite_theme'])){
61
+
62
+ $active_theme = $option3['sfsi_actvite_theme'];
63
+
64
+ $icons_baseUrl = SFSI_PLUGURL."images/icons_theme/".$active_theme."/";
65
+ $visit_iconsUrl = SFSI_PLUGURL."images/visit_icons/";
66
+
67
+ if(isset($icon_name) && !empty($icon_name)):
68
+
69
+ if($active_theme == 'custom_support')
70
+ {
71
+ switch (strtolower($icon_name)) {
72
+
73
+ case 'facebook':
74
+ $custom_icon_name = "fb";
75
+ break;
76
+
77
+ case 'pinterest':
78
+ $custom_icon_name = "pintrest";
79
+ break;
80
+
81
+ default:
82
+ $custom_icon_name = $icon_name;
83
+ break;
84
+ }
85
+
86
+ $key = $custom_icon_name."_skin";
87
+
88
+ $skin = get_option($key,false);
89
+
90
+ $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https" : "http";
91
+
92
+ if($skin)
93
+ {
94
+ $skin_url = parse_url($skin);
95
+ if($skin_url['scheme']==='http' && $scheme==='https'){
96
+ $icon = str_replace('http','https',$skin);
97
+ }else if($skin_url['scheme']==='https' && $scheme==='http'){
98
+ $icon = str_replace('https','http',$skin);
99
+ }else{
100
+ $icon = $skin;
101
+ }
102
+ }
103
+ else
104
+ {
105
+ $active_theme = 'default';
106
+ $icons_baseUrl = SFSI_PLUGURL."images/icons_theme/default/";
107
+
108
+ $iconImgName = false != $iconImgName ? $iconImgName: $icon_name;
109
+ $icon = $icons_baseUrl.$active_theme."_".$iconImgName.".png";
110
+ }
111
+ }
112
+ else
113
+ {
114
+ $iconImgName = false != $iconImgName ? $iconImgName: $icon_name;
115
+ $icon = $icons_baseUrl.$active_theme."_".$iconImgName.".png";
116
+ }
117
+
118
+ endif;
119
+
120
+ }
121
+
122
+ return $icon;
123
+ }
124
+ }
125
+
126
+ if(!function_exists('sfsi_icon_generate_other_icon_effect_admin_html')){
127
+
128
+ function sfsi_icon_generate_other_icon_effect_admin_html($iconName,$arrActiveDesktopIcons,$customIconIndex=-1,$customIconImgUrl=null,$customIconSrNo=null){
129
+
130
+ $iconImgVal = false;
131
+ $activeIconImgUrl = false;
132
+
133
+ $classForRevertLink = 'hide';
134
+ $defaultIconImgUrl = false;
135
+
136
+ $displayIconClass = "hide";
137
+
138
+ $arruploadDir = wp_upload_dir();
139
+
140
+ if( isset($iconName) && !empty($iconName)){
141
+
142
+ if("custom" == $iconName && $customIconIndex >-1){
143
+
144
+ if(null !== $customIconImgUrl){
145
+
146
+ $activeIconImgUrl = $customIconImgUrl;
147
+ $defaultIconImgUrl = $customIconImgUrl;
148
+
149
+ // Check if icon is selected under Question 1
150
+ if(in_array($customIconImgUrl, $arrActiveDesktopIcons)){
151
+ $displayIconClass = "show";
152
+ }
153
+
154
+ $iconNameStr = $iconName.$customIconSrNo;
155
+
156
+ }
157
+
158
+ }
159
+
160
+ else{
161
+
162
+ $dbKey = "sfsi_".$iconName."_display";
163
+
164
+ if(isset($arrActiveDesktopIcons[$dbKey]) && !empty($arrActiveDesktopIcons[$dbKey])
165
+ && "yes" == $arrActiveDesktopIcons[$dbKey]){
166
+ $displayIconClass = "show";
167
+ }
168
+
169
+ $activeIconImgUrl = sfsi_icon_get_icon_image($iconName);
170
+
171
+ $iconNameStr = $iconName;
172
+ }
173
+ if(false != $iconImgVal && !filter_var($iconImgVal, FILTER_VALIDATE_URL)){
174
+
175
+ $iconImgVal = SFSI_UPLOAD_DIR_BASEURL.$iconImgVal;
176
+ }
177
+
178
+ $attrCustomIconSrNo = null !== $customIconSrNo ? 'data-customiconsrno="'.$customIconSrNo.'"': null;
179
+ $attrCustomIconIndex = -1 != $customIconIndex ? 'data-customiconindex="'.$customIconIndex.'"': null;
180
+
181
+ $attrIconName = 'data-iconname="'.$iconName.'"';
182
+
183
+ ?>
184
+ <div <?php echo $attrCustomIconIndex;?><?php echo $attrIconName; ?> class="col-md-3 bottommargin20 <?php echo $displayIconClass; ?>">
185
+
186
+ <label <?php echo $attrCustomIconSrNo; ?> class="mouseover_other_icon_label"><?php echo ucfirst($iconNameStr); ?> </label>
187
+
188
+ <img data-defaultImg="<?php echo $defaultIconImgUrl; ?>" class="mouseover_other_icon_img" src="<?php echo $activeIconImgUrl; ?>" alt="error">
189
+
190
+ <input <?php echo $attrCustomIconIndex; ?><?php echo $attrIconName; ?> type="hidden" value="<?php echo $iconImgVal; ?>" name="mouseover_other_icon_<?php echo $iconName; ?>">
191
+
192
+ <a <?php echo $attrCustomIconIndex; ?><?php echo $attrIconName; ?> id="btn_mouseover_other_icon_<?php echo $iconName; ?>" class="mouseover_other_icon_change_link mouseover_other_icon" href="javascript:void(0)" >Change</a>
193
+
194
+ <a <?php echo $attrCustomIconIndex; ?><?php echo $attrIconName; ?> class="<?php echo $classForRevertLink; ?> mouseover_other_icon_revert_link mouseover_other_icon" href="javascript:void(0)">Revert</a>
195
+
196
+ </div>
197
+
198
+ <?php
199
+
200
+ }
201
+
202
+ }
203
  }
helpers/linkedin-api/linkedin-api.php CHANGED
@@ -1,136 +1,136 @@
1
- <?php
2
- require_once(SFSI_DOCROOT.'/helpers/sfsi_OAuth.php');
3
-
4
- class LinkedIn {
5
- public $base_url = "http://api.linkedin.com";
6
- public $secure_base_url = "https://api.linkedin.com";
7
- public $oauth_callback = "oob";
8
- public $consumer;
9
- public $request_token;
10
- public $access_token;
11
- public $oauth_verifier;
12
- public $signature_method;
13
- public $request_token_path;
14
- public $access_token_path;
15
- public $authorize_path;
16
-
17
- function __construct($consumer_key, $consumer_secret,$request_token, $oauth_callback = NULL)
18
- {
19
-
20
- if($oauth_callback) {
21
- $this->oauth_callback = $oauth_callback;
22
- }
23
- $this->request_token=
24
- $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret, $this->oauth_callback);
25
- $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1();
26
- $this->request_token_path = $this->secure_base_url . "/uas/oauth/requestToken?scope=r_basicprofile+r_emailaddress+r_network+w_messages";
27
- $this->access_token_path = $this->secure_base_url . "/uas/oauth/accessToken";
28
- $this->authorize_path = $this->secure_base_url . "/uas/oauth/authorize";
29
- }
30
-
31
- function getRequestToken()
32
- {
33
- $consumer = $this->consumer;
34
- $request = OAuthRequest::from_consumer_and_token($consumer, NULL, "GET", $this->request_token_path);
35
- $request->set_parameter("oauth_callback", $this->oauth_callback);
36
- $request->sign_request($this->signature_method, $consumer, NULL);
37
- $headers = Array();
38
- $url = $request->to_url();
39
- $response = $this->httpRequest($url, $headers, "GET");
40
- parse_str($response, $response_params);
41
- $this->request_token = new OAuthConsumer($response_params['oauth_token'], $response_params['oauth_token_secret'], 1);
42
- }
43
-
44
- function generateAuthorizeUrl()
45
- {
46
- $consumer = $this->consumer;
47
- $request_token = $this->request_token;
48
- return $this->authorize_path . "?oauth_token=" . $request_token->key;
49
- }
50
-
51
- function getAccessToken($oauth_verifier)
52
- {
53
- $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->request_token, "GET", $this->access_token_path);
54
- $request->set_parameter("oauth_verifier", $oauth_verifier);
55
- $request->sign_request($this->signature_method, $this->consumer, $this->request_token);
56
- $headers = Array();
57
- $url = $request->to_url();
58
- $response = $this->httpRequest($url, $headers, "GET");
59
- parse_str($response, $response_params);
60
- $this->access_token = new OAuthConsumer($response_params['oauth_token'], $response_params['oauth_token_secret'], 1);
61
- }
62
-
63
- function getCompanyFollowersById($companyID = "")
64
- {
65
- $api_url = $this->base_url . "/v1/companies/".$companyID.":(num-followers)/";
66
- $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->access_token, "GET", $api_url);
67
- $request->sign_request($this->signature_method, $this->consumer, $this->access_token);
68
- $auth_header = $request->to_header("https://api.linkedin.com"); # this is the realm
69
- $response = $this->httpRequest($api_url, $auth_header, "GET");
70
- return $response;
71
- }
72
- function getCompanyFollowersByName($companyName = "")
73
- {
74
- $api_url = $this->base_url . "/v1/companies/universal-name=".$companyName.":(num-followers)/";
75
- $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->access_token, "GET", $api_url);
76
- $request->sign_request($this->signature_method, $this->consumer, $this->access_token);
77
- $auth_header = $request->to_header("https://api.linkedin.com"); # this is the realm
78
- $response = $this->httpRequest($api_url, $auth_header, "GET");
79
-
80
- return $response;
81
- }
82
-
83
-
84
-
85
- function httpRequest($url, $auth_header, $method, $body = NULL)
86
- {
87
- if (!$method) {
88
- $method = "GET";
89
- };
90
-
91
- $args = array(
92
- 'headers' => array($auth_header),
93
- 'blocking' => true,
94
- );
95
-
96
- if ($body) {
97
- $args2 = array(
98
- 'headers' => array($auth_header),
99
- 'blocking' => true,
100
- 'body' => $body,
101
- 'method' => $method,
102
- 'headers' => array($auth_header, "Content-Type: text/xml;charset=utf-8")
103
- );
104
- $args =array_merge($args,$args2);
105
- }
106
- $curl = wp_remote_get($url, $args);
107
-
108
- return $curl['body'];
109
- }
110
-
111
- }
112
-
113
- function array_msort($array, $cols)
114
- {
115
- $colarr = array();
116
- foreach ($cols as $col => $order) {
117
- $colarr[$col] = array();
118
- foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
119
- }
120
- $eval = 'array_multisort(';
121
- foreach ($cols as $col => $order) {
122
- $eval .= '$colarr[\''.$col.'\'],'.$order.',';
123
- }
124
- $eval = substr($eval,0,-1).');';
125
- eval($eval);
126
- $ret = array();
127
- foreach ($colarr as $col => $arr) {
128
- foreach ($arr as $k => $v) {
129
- $k = substr($k,1);
130
- if (!isset($ret[$k])) $ret[$k] = $array[$k];
131
- $ret[$k][$col] = $array[$k][$col];
132
- }
133
- }
134
- return $ret;
135
-
136
- }
1
+ <?php
2
+ require_once(SFSI_DOCROOT.'/helpers/sfsi_OAuth.php');
3
+
4
+ class LinkedIn {
5
+ public $base_url = "http://api.linkedin.com";
6
+ public $secure_base_url = "https://api.linkedin.com";
7
+ public $oauth_callback = "oob";
8
+ public $consumer;
9
+ public $request_token;
10
+ public $access_token;
11
+ public $oauth_verifier;
12
+ public $signature_method;
13
+ public $request_token_path;
14
+ public $access_token_path;
15
+ public $authorize_path;
16
+
17
+ function __construct($consumer_key, $consumer_secret,$request_token, $oauth_callback = NULL)
18
+ {
19
+
20
+ if($oauth_callback) {
21
+ $this->oauth_callback = $oauth_callback;
22
+ }
23
+ $this->request_token=
24
+ $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret, $this->oauth_callback);
25
+ $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1();
26
+ $this->request_token_path = $this->secure_base_url . "/uas/oauth/requestToken?scope=r_basicprofile+r_emailaddress+r_network+w_messages";
27
+ $this->access_token_path = $this->secure_base_url . "/uas/oauth/accessToken";
28
+ $this->authorize_path = $this->secure_base_url . "/uas/oauth/authorize";
29
+ }
30
+
31
+ function getRequestToken()
32
+ {
33
+ $consumer = $this->consumer;
34
+ $request = OAuthRequest::from_consumer_and_token($consumer, NULL, "GET", $this->request_token_path);
35
+ $request->set_parameter("oauth_callback", $this->oauth_callback);
36
+ $request->sign_request($this->signature_method, $consumer, NULL);
37
+ $headers = Array();
38
+ $url = $request->to_url();
39
+ $response = $this->httpRequest($url, $headers, "GET");
40
+ parse_str($response, $response_params);
41
+ $this->request_token = new OAuthConsumer($response_params['oauth_token'], $response_params['oauth_token_secret'], 1);
42
+ }
43
+
44
+ function generateAuthorizeUrl()
45
+ {
46
+ $consumer = $this->consumer;
47
+ $request_token = $this->request_token;
48
+ return $this->authorize_path . "?oauth_token=" . $request_token->key;
49
+ }
50
+
51
+ function getAccessToken($oauth_verifier)
52
+ {
53
+ $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->request_token, "GET", $this->access_token_path);
54
+ $request->set_parameter("oauth_verifier", $oauth_verifier);
55
+ $request->sign_request($this->signature_method, $this->consumer, $this->request_token);
56
+ $headers = Array();
57
+ $url = $request->to_url();
58
+ $response = $this->httpRequest($url, $headers, "GET");
59
+ parse_str($response, $response_params);
60
+ $this->access_token = new OAuthConsumer($response_params['oauth_token'], $response_params['oauth_token_secret'], 1);
61
+ }
62
+
63
+ function getCompanyFollowersById($companyID = "")
64
+ {
65
+ $api_url = $this->base_url . "/v1/companies/".$companyID.":(num-followers)/";
66
+ $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->access_token, "GET", $api_url);
67
+ $request->sign_request($this->signature_method, $this->consumer, $this->access_token);
68
+ $auth_header = $request->to_header("https://api.linkedin.com"); # this is the realm
69
+ $response = $this->httpRequest($api_url, $auth_header, "GET");
70
+ return $response;
71
+ }
72
+ function getCompanyFollowersByName($companyName = "")
73
+ {
74
+ $api_url = $this->base_url . "/v1/companies/universal-name=".$companyName.":(num-followers)/";
75
+ $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->access_token, "GET", $api_url);
76
+ $request->sign_request($this->signature_method, $this->consumer, $this->access_token);
77
+ $auth_header = $request->to_header("https://api.linkedin.com"); # this is the realm
78
+ $response = $this->httpRequest($api_url, $auth_header, "GET");
79
+
80
+ return $response;
81
+ }
82
+
83
+
84
+
85
+ function httpRequest($url, $auth_header, $method, $body = NULL)
86
+ {
87
+ if (!$method) {
88
+ $method = "GET";
89
+ };
90
+
91
+ $args = array(
92
+ 'headers' => array($auth_header),
93
+ 'blocking' => true,
94
+ );
95
+
96
+ if ($body) {
97
+ $args2 = array(
98
+ 'headers' => array($auth_header),
99
+ 'blocking' => true,
100
+ 'body' => $body,
101
+ 'method' => $method,
102
+ 'headers' => array($auth_header, "Content-Type: text/xml;charset=utf-8")
103
+ );
104
+ $args =array_merge($args,$args2);
105
+ }
106
+ $curl = wp_remote_get($url, $args);
107
+
108
+ return $curl['body'];
109
+ }
110
+
111
+ }
112
+
113
+ function array_msort($array, $cols)
114
+ {
115
+ $colarr = array();
116
+ foreach ($cols as $col => $order) {
117
+ $colarr[$col] = array();
118
+ foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
119
+ }
120
+ $eval = 'array_multisort(';
121
+ foreach ($cols as $col => $order) {
122
+ $eval .= '$colarr[\''.$col.'\'],'.$order.',';
123
+ }
124
+ $eval = substr($eval,0,-1).');';
125
+ eval($eval);
126
+ $ret = array();
127
+ foreach ($colarr as $col => $arr) {
128
+ foreach ($arr as $k => $v) {
129
+ $k = substr($k,1);
130
+ if (!isset($ret[$k])) $ret[$k] = $array[$k];
131
+ $ret[$k][$col] = $array[$k][$col];
132
+ }
133
+ }
134
+ return $ret;
135
+
136
+ }
helpers/sfsi_OAuth.php CHANGED
@@ -1,911 +1,911 @@
1
- <?php
2
- // vim: foldmethod=marker
3
-
4
- /* Generic exception class
5
- */
6
- if (!class_exists('OAuthException'))
7
- {
8
- class OAuthException extends Exception
9
- {
10
- // pass
11
- }
12
- }
13
-
14
- if (!class_exists('OAuthConsumer'))
15
- {
16
- class OAuthConsumer
17
- {
18
- public $key;
19
- public $secret;
20
-
21
- function __construct($key, $secret, $callback_url=NULL) {
22
- $this->key = $key;
23
- $this->secret = $secret;
24
- $this->callback_url = $callback_url;
25
- }
26
-
27
- function __toString() {
28
- return "OAuthConsumer[key=$this->key,secret=$this->secret]";
29
- }
30
- }
31
- }
32
-
33
- if (!class_exists('OAuthToken'))
34
- {
35
- class OAuthToken
36
- {
37
- // access tokens and request tokens
38
- public $key;
39
- public $secret;
40
-
41
- /**
42
- * key = the token
43
- * secret = the token secret
44
- */
45
- function __construct($key, $secret)
46
- {
47
- $this->key = $key;
48
- $this->secret = $secret;
49
- }
50
-
51
- /**
52
- * generates the basic string serialization of a token that a server
53
- * would respond to request_token and access_token calls with
54
- */
55
- function to_string()
56
- {
57
- return "oauth_token=" .
58
- OAuthUtil::urlencode_rfc3986($this->key) .
59
- "&oauth_token_secret=" .
60
- OAuthUtil::urlencode_rfc3986($this->secret);
61
- }
62
-
63
- function __toString()
64
- {
65
- return $this->to_string();
66
- }
67
- }
68
- }
69
- /**
70
- * A class for implementing a Signature Method
71
- * See section 9 ("Signing Requests") in the spec
72
- */
73
-
74
- if (!class_exists('OAuthSignatureMethod'))
75
- {
76
- abstract class OAuthSignatureMethod {
77
- /**
78
- * Needs to return the name of the Signature Method (ie HMAC-SHA1)
79
- * @return string
80
- */
81
- abstract public function get_name();
82
-
83
- /**
84
- * Build up the signature
85
- * NOTE: The output of this function MUST NOT be urlencoded.
86
- * the encoding is handled in OAuthRequest when the final
87
- * request is serialized
88
- * @param OAuthRequest $request
89
- * @param OAuthConsumer $consumer
90
- * @param OAuthToken $token
91
- * @return string
92
- */
93
- abstract public function build_signature($request, $consumer, $token);
94
-
95
- /**
96
- * Verifies that a given signature is correct
97
- * @param OAuthRequest $request
98
- * @param OAuthConsumer $consumer
99
- * @param OAuthToken $token
100
- * @param string $signature
101
- * @return bool
102
- */
103
- public function check_signature($request, $consumer, $token, $signature) {
104
- $built = $this->build_signature($request, $consumer, $token);
105
- return $built == $signature;
106
- }
107
- }
108
- }
109
- /**
110
- * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
111
- * where the Signature Base String is the text and the key is the concatenated values (each first
112
- * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
113
- * character (ASCII code 38) even if empty.
114
- * - Chapter 9.2 ("HMAC-SHA1")
115
- */
116
-
117
- if (!class_exists('OAuthSignatureMethod_HMAC_SHA1'))
118
- {
119
- class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
120
- {
121
- function get_name()
122
- {
123
- return "HMAC-SHA1";
124
- }
125
-
126
- public function build_signature($request, $consumer, $token)
127
- {
128
- $base_string = $request->get_signature_base_string();
129
- $request->base_string = $base_string;
130
-
131
- $key_parts = array(
132
- $consumer->secret,
133
- ($token) ? $token->secret : ""
134
- );
135
-
136
- $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
137
- $key = implode('&', $key_parts);
138
-
139
- return base64_encode(hash_hmac('sha1', $base_string, $key, true));
140
- }
141
- }
142
- }
143
-
144
- /**
145
- * The PLAINTEXT method does not provide any security protection and SHOULD only be used
146
- * over a secure channel such as HTTPS. It does not use the Signature Base String.
147
- * - Chapter 9.4 ("PLAINTEXT")
148
- */
149
- if (!class_exists('OAuthSignatureMethod_PLAINTEXT'))
150
- {
151
- class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
152
- {
153
- public function get_name() {
154
- return "PLAINTEXT";
155
- }
156
-
157
- /**
158
- * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
159
- * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
160
- * empty. The result MUST be encoded again.
161
- * - Chapter 9.4.1 ("Generating Signatures")
162
- *
163
- * Please note that the second encoding MUST NOT happen in the SignatureMethod, as
164
- * OAuthRequest handles this!
165
- */
166
- public function build_signature($request, $consumer, $token) {
167
- $key_parts = array(
168
- $consumer->secret,
169
- ($token) ? $token->secret : ""
170
- );
171
-
172
- $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
173
- $key = implode('&', $key_parts);
174
- $request->base_string = $key;
175
-
176
- return $key;
177
- }
178
- }
179
- }
180
-
181
- /**
182
- * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
183
- * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
184
- * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
185
- * verified way to the Service Provider, in a manner which is beyond the scope of this
186
- * specification.
187
- * - Chapter 9.3 ("RSA-SHA1")
188
- */
189
-
190
- if (!class_exists('OAuthSignatureMethod_RSA_SHA1'))
191
- {
192
- abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
193
- public function get_name() {
194
- return "RSA-SHA1";
195
- }
196
-
197
- // Up to the SP to implement this lookup of keys. Possible ideas are:
198
- // (1) do a lookup in a table of trusted certs keyed off of consumer
199
- // (2) fetch via http using a url provided by the requester
200
- // (3) some sort of specific discovery code based on request
201
- //
202
- // Either way should return a string representation of the certificate
203
- protected abstract function fetch_public_cert(&$request);
204
-
205
- // Up to the SP to implement this lookup of keys. Possible ideas are:
206
- // (1) do a lookup in a table of trusted certs keyed off of consumer
207
- //
208
- // Either way should return a string representation of the certificate
209
- protected abstract function fetch_private_cert(&$request);
210
-
211
- public function build_signature($request, $consumer, $token) {
212
- $base_string = $request->get_signature_base_string();
213
- $request->base_string = $base_string;
214
-
215
- // Fetch the private key cert based on the request
216
- $cert = $this->fetch_private_cert($request);
217
-
218
- // Pull the private key ID from the certificate
219
- $privatekeyid = openssl_get_privatekey($cert);
220
-
221
- // Sign using the key
222
- $ok = openssl_sign($base_string, $signature, $privatekeyid);
223
-
224
- // Release the key resource
225
- openssl_free_key($privatekeyid);
226
-
227
- return base64_encode($signature);
228
- }
229
-
230
- public function check_signature($request, $consumer, $token, $signature) {
231
- $decoded_sig = base64_decode($signature);
232
-
233
- $base_string = $request->get_signature_base_string();
234
-
235
- // Fetch the public key cert based on the request
236
- $cert = $this->fetch_public_cert($request);
237
-
238
- // Pull the public key ID from the certificate
239
- $publickeyid = openssl_get_publickey($cert);
240
-
241
- // Check the computed signature against the one passed in the query
242
- $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
243
-
244
- // Release the key resource
245
- openssl_free_key($publickeyid);
246
-
247
- return $ok == 1;
248
- }
249
- }
250
- }
251
-
252
- if (!class_exists('OAuthRequest'))
253
- {
254
- class OAuthRequest
255
- {
256
- private $parameters;
257
- private $http_method;
258
- private $http_url;
259
- // for debug purposes
260
- public $base_string;
261
- public static $version = '1.0';
262
- public static $POST_INPUT = 'php://input';
263
-
264
- function __construct($http_method, $http_url, $parameters=NULL) {
265
- @$parameters or $parameters = array();
266
- $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
267
- $this->parameters = $parameters;
268
- $this->http_method = $http_method;
269
- $this->http_url = $http_url;
270
- }
271
- /**
272
- * attempt to build up a request from what was passed to the server
273
- */
274
- public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
275
- $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
276
- ? 'http'
277
- : 'https';
278
- @$http_url or $http_url = $scheme .
279
- '://' . $_SERVER['HTTP_HOST'] .
280
- ':' .
281
- $_SERVER['SERVER_PORT'] .
282
- $_SERVER['REQUEST_URI'];
283
- @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
284
-
285
- // We weren't handed any parameters, so let's find the ones relevant to
286
- // this request.
287
- // If you run XML-RPC or similar you should use this to provide your own
288
- // parsed parameter-list
289
- if (!$parameters) {
290
- // Find request headers
291
- $request_headers = OAuthUtil::get_headers();
292
-
293
- // Parse the query-string to find GET parameters
294
- $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
295
-
296
- // It's a POST request of the proper content-type, so parse POST
297
- // parameters and add those overriding any duplicates from GET
298
- if ($http_method == "POST"
299
- && @strstr($request_headers["Content-Type"],
300
- "application/x-www-form-urlencoded")
301
- ) {
302
- $post_data = OAuthUtil::parse_parameters(
303
- file_get_contents(self::$POST_INPUT)
304
- );
305
- $parameters = array_merge($parameters, $post_data);
306
- }
307
-
308
- // We have a Authorization-header with OAuth data. Parse the header
309
- // and add those overriding any duplicates from GET or POST
310
- if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
311
- $header_parameters = OAuthUtil::split_header(
312
- $request_headers['Authorization']
313
- );
314
- $parameters = array_merge($parameters, $header_parameters);
315
- }
316
-
317
- }
318
-
319
- return new OAuthRequest($http_method, $http_url, $parameters);
320
- }
321
-
322
- /**
323
- * pretty much a helper function to set up the request
324
- */
325
- public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
326
- @$parameters or $parameters = array();
327
- $defaults = array("oauth_version" => OAuthRequest::$version,
328
- "oauth_nonce" => OAuthRequest::generate_nonce(),
329
- "oauth_timestamp" => OAuthRequest::generate_timestamp(),
330
- "oauth_consumer_key" => $consumer->key);
331
- if ($token)
332
- $defaults['oauth_token'] = $token->key;
333
-
334
- $parameters = array_merge($defaults, $parameters);
335
-
336
- return new OAuthRequest($http_method, $http_url, $parameters);
337
- }
338
-
339
- public function set_parameter($name, $value, $allow_duplicates = true) {
340
- if ($allow_duplicates && isset($this->parameters[$name])) {
341
- // We have already added parameter(s) with this name, so add to the list
342
- if (is_scalar($this->parameters[$name])) {
343
- // This is the first duplicate, so transform scalar (string)
344
- // into an array so we can add the duplicates
345
- $this->parameters[$name] = array($this->parameters[$name]);
346
- }
347
-
348
- $this->parameters[$name][] = $value;
349
- } else {
350
- $this->parameters[$name] = $value;
351
- }
352
- }
353
-
354
- public function get_parameter($name) {
355
- return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
356
- }
357
-
358
- public function get_parameters() {
359
- return $this->parameters;
360
- }
361
-
362
- public function unset_parameter($name) {
363
- unset($this->parameters[$name]);
364
- }
365
-
366
- /**
367
- * The request parameters, sorted and concatenated into a normalized string.
368
- * @return string
369
- */
370
- public function get_signable_parameters() {
371
- // Grab all parameters
372
- $params = $this->parameters;
373
-
374
- // Remove oauth_signature if present
375
- // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
376
- if (isset($params['oauth_signature'])) {
377
- unset($params['oauth_signature']);
378
- }
379
-
380
- return OAuthUtil::build_http_query($params);
381
- }
382
-
383
- /**
384
- * Returns the base string of this request
385
- *
386
- * The base string defined as the method, the url
387
- * and the parameters (normalized), each urlencoded
388
- * and the concated with &.
389
- */
390
- public function get_signature_base_string() {
391
- $parts = array(
392
- $this->get_normalized_http_method(),
393
- $this->get_normalized_http_url(),
394
- $this->get_signable_parameters()
395
- );
396
-
397
- $parts = OAuthUtil::urlencode_rfc3986($parts);
398
-
399
- return implode('&', $parts);
400
- }
401
-
402
- /**
403
- * just uppercases the http method
404
- */
405
- public function get_normalized_http_method() {
406
- return strtoupper($this->http_method);
407
- }
408
-
409
- /**
410
- * parses the url and rebuilds it to be
411
- * scheme://host/path
412
- */
413
- public function get_normalized_http_url() {
414
- $parts = parse_url($this->http_url);
415
-
416
- $port = @$parts['port'];
417
- $scheme = $parts['scheme'];
418
- $host = $parts['host'];
419
- $path = @$parts['path'];
420
-
421
- $port or $port = ($scheme == 'https') ? '443' : '80';
422
-
423
- if (($scheme == 'https' && $port != '443')
424
- || ($scheme == 'http' && $port != '80')) {
425
- $host = "$host:$port";
426
- }
427
- return "$scheme://$host$path";
428
- }
429
-
430
- /**
431
- * builds a url usable for a GET request
432
- */
433
- public function to_url() {
434
- $post_data = $this->to_postdata();
435
- $out = $this->get_normalized_http_url();
436
- if ($post_data) {
437
- $out .= '?'.$post_data;
438
- }
439
- return $out;
440
- }
441
-
442
- /**
443
- * builds the data one would send in a POST request
444
- */
445
- public function to_postdata() {
446
- return OAuthUtil::build_http_query($this->parameters);
447
- }
448
-
449
- /**
450
- * builds the Authorization: header
451
- */
452
- public function to_header($realm=null) {
453
- $first = true;
454
- if($realm) {
455
- $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
456
- $first = false;
457
- } else
458
- $out = 'Authorization: OAuth';
459
-
460
- $total = array();
461
- foreach ($this->parameters as $k => $v) {
462
- if (substr($k, 0, 5) != "oauth") continue;
463
- if (is_array($v)) {
464
- throw new OAuthException('Arrays not supported in headers');
465
- }
466
- $out .= ($first) ? ' ' : ',';
467
- $out .= OAuthUtil::urlencode_rfc3986($k) .
468
- '="' .
469
- OAuthUtil::urlencode_rfc3986($v) .
470
- '"';
471
- $first = false;
472
- }
473
- return $out;
474
- }
475
-
476
- public function __toString() {
477
- return $this->to_url();
478
- }
479
- public function sign_request($signature_method, $consumer, $token) {
480
- $this->set_parameter(
481
- "oauth_signature_method",
482
- $signature_method->get_name(),
483
- false
484
- );
485
- $signature = $this->build_signature($signature_method, $consumer, $token);
486
- $this->set_parameter("oauth_signature", $signature, false);
487
- }
488
-
489
- public function build_signature($signature_method, $consumer, $token) {
490
- $signature = $signature_method->build_signature($this, $consumer, $token);
491
- return $signature;
492
- }
493
-
494
- /**
495
- * util function: current timestamp
496
- */
497
- private static function generate_timestamp() {
498
- return time();
499
- }
500
-
501
- /**
502
- * util function: current nonce
503
- */
504
- private static function generate_nonce() {
505
- $mt = microtime();
506
- $rand = mt_rand();
507
-
508
- return md5($mt . $rand); // md5s look nicer than numbers
509
- }
510
- }
511
- }
512
-
513
- if (!class_exists('OAuthServer'))
514
- {
515
- class OAuthServer {
516
- protected $timestamp_threshold = 300; // in seconds, five minutes
517
- protected $version = '1.0'; // hi blaine
518
- protected $signature_methods = array();
519
-
520
- protected $data_store;
521
-
522
- function __construct($data_store) {
523
- $this->data_store = $data_store;
524
- }
525
-
526
- public function add_signature_method($signature_method) {
527
- $this->signature_methods[$signature_method->get_name()] =
528
- $signature_method;
529
- }
530
-
531
- // high level functions
532
-
533
- /**
534
- * process a request_token request
535
- * returns the request token on success
536
- */
537
- public function fetch_request_token(&$request) {
538
- $this->get_version($request);
539
-
540
- $consumer = $this->get_consumer($request);
541
-
542
- // no token required for the initial token request
543
- $token = NULL;
544
-
545
- $this->check_signature($request, $consumer, $token);
546
-
547
- // Rev A change
548
- $callback = $request->get_parameter('oauth_callback');
549
- $new_token = $this->data_store->new_request_token($consumer, $callback);
550
-
551
- return $new_token;
552
- }
553
-
554
- /**
555
- * process an access_token request
556
- * returns the access token on success
557
- */
558
- public function fetch_access_token(&$request) {
559
- $this->get_version($request);
560
-
561
- $consumer = $this->get_consumer($request);
562
-
563
- // requires authorized request token
564
- $token = $this->get_token($request, $consumer, "request");
565
-
566
- $this->check_signature($request, $consumer, $token);
567
-
568
- // Rev A change
569
- $verifier = $request->get_parameter('oauth_verifier');
570
- $new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
571
-
572
- return $new_token;
573
- }
574
-
575
- /**
576
- * verify an api call, checks all the parameters
577
- */
578
- public function verify_request(&$request) {
579
- $this->get_version($request);
580
- $consumer = $this->get_consumer($request);
581
- $token = $this->get_token($request, $consumer, "access");
582
- $this->check_signature($request, $consumer, $token);
583
- return array($consumer, $token);
584
- }
585
-
586
- // Internals from here
587
- /**
588
- * version 1
589
- */
590
- private function get_version(&$request) {
591
- $version = $request->get_parameter("oauth_version");
592
- if (!$version) {
593
- // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
594
- // Chapter 7.0 ("Accessing Protected Ressources")
595
- $version = '1.0';
596
- }
597
- if ($version !== $this->version) {
598
- throw new OAuthException("OAuth version '$version' not supported");
599
- }
600
- return $version;
601
- }
602
-
603
- /**
604
- * figure out the signature with some defaults
605
- */
606
- private function get_signature_method(&$request) {
607
- $signature_method =
608
- @$request->get_parameter("oauth_signature_method");
609
-
610
- if (!$signature_method) {
611
- // According to chapter 7 ("Accessing Protected Ressources") the signature-method
612
- // parameter is required, and we can't just fallback to PLAINTEXT
613
- throw new OAuthException('No signature method parameter. This parameter is required');
614
- }
615
-
616
- if (!in_array($signature_method,
617
- array_keys($this->signature_methods))) {
618
- throw new OAuthException(
619
- "Signature method '$signature_method' not supported " .
620
- "try one of the following: " .
621
- implode(", ", array_keys($this->signature_methods))
622
- );
623
- }
624
- return $this->signature_methods[$signature_method];
625
- }
626
-
627
- /**
628
- * try to find the consumer for the provided request's consumer key
629
- */
630
- private function get_consumer(&$request) {
631
- $consumer_key = @$request->get_parameter("oauth_consumer_key");
632
- if (!$consumer_key) {
633
- throw new OAuthException("Invalid consumer key");
634
- }
635
-
636
- $consumer = $this->data_store->lookup_consumer($consumer_key);
637
- if (!$consumer) {
638
- throw new OAuthException("Invalid consumer");
639
- }
640
-
641
- return $consumer;
642
- }
643
-
644
- /**
645
- * try to find the token for the provided request's token key
646
- */
647
- private function get_token(&$request, $consumer, $token_type="access") {
648
- $token_field = @$request->get_parameter('oauth_token');
649
- $token = $this->data_store->lookup_token(
650
- $consumer, $token_type, $token_field
651
- );
652
- if (!$token) {
653
- throw new OAuthException("Invalid $token_type token: $token_field");
654
- }
655
- return $token;
656
- }
657
-
658
- /**
659
- * all-in-one function to check the signature on a request
660
- * should guess the signature method appropriately
661
- */
662
- private function check_signature(&$request, $consumer, $token) {
663
- // this should probably be in a different method
664
- $timestamp = @$request->get_parameter('oauth_timestamp');
665
- $nonce = @$request->get_parameter('oauth_nonce');
666
-
667
- $this->check_timestamp($timestamp);
668
- $this->check_nonce($consumer, $token, $nonce, $timestamp);
669
-
670
- $signature_method = $this->get_signature_method($request);
671
-
672
- $signature = $request->get_parameter('oauth_signature');
673
- $valid_sig = $signature_method->check_signature(
674
- $request,
675
- $consumer,
676
- $token,
677
- $signature
678
- );
679
-
680
- if (!$valid_sig) {
681
- throw new OAuthException("Invalid signature");
682
- }
683
- }
684
-
685
- /**
686
- * check that the timestamp is new enough
687
- */
688
- private function check_timestamp($timestamp) {
689
- if( ! $timestamp )
690
- throw new OAuthException(
691
- 'Missing timestamp parameter. The parameter is required'
692
- );
693
-
694
- // verify that timestamp is recentish
695
- $now = time();
696
- if (abs($now - $timestamp) > $this->timestamp_threshold) {
697
- throw new OAuthException(
698
- "Expired timestamp, yours $timestamp, ours $now"
699
- );
700
- }
701
- }
702
-
703
- /**
704
- * check that the nonce is not repeated
705
- */
706
- private function check_nonce($consumer, $token, $nonce, $timestamp) {
707
- if( ! $nonce )
708
- throw new OAuthException(
709
- 'Missing nonce parameter. The parameter is required'
710
- );
711
-
712
- // verify that the nonce is uniqueish
713
- $found = $this->data_store->lookup_nonce(
714
- $consumer,
715
- $token,
716
- $nonce,
717
- $timestamp
718
- );
719
- if ($found) {
720
- throw new OAuthException("Nonce already used: $nonce");
721
- }
722
- }
723
- }
724
- }
725
- if (!class_exists('OAuthDataStore'))
726
- {
727
- class OAuthDataStore {
728
- function lookup_consumer($consumer_key) {
729
- // implement me
730
- }
731
-
732
- function lookup_token($consumer, $token_type, $token) {
733
- // implement me
734
- }
735
-
736
- function lookup_nonce($consumer, $token, $nonce, $timestamp) {
737
- // implement me
738
- }
739
-
740
- function new_request_token($consumer, $callback = null) {
741
- // return a new token attached to this consumer
742
- }
743
-
744
- function new_access_token($token, $consumer, $verifier = null) {
745
- // return a new access token attached to this consumer
746
- // for the user associated with this token if the request token
747
- // is authorized
748
- // should also invalidate the request token
749
- }
750
-
751
- }
752
- }
753
-
754
- if (!class_exists('OAuthUtil'))
755
- {
756
- class OAuthUtil {
757
- public static function urlencode_rfc3986($input) {
758
- if (is_array($input)) {
759
- return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
760
- } else if (is_scalar($input)) {
761
- return str_replace(
762
- '+',
763
- ' ',
764
- str_replace('%7E', '~', rawurlencode($input))
765
- );
766
- } else {
767
- return '';
768
- }
769
- }
770
-
771
-
772
- // This decode function isn't taking into consideration the above
773
- // modifications to the encoding process. However, this method doesn't
774
- // seem to be used anywhere so leaving it as is.
775
- public static function urldecode_rfc3986($string) {
776
- return urldecode($string);
777
- }
778
-
779
- // Utility function for turning the Authorization: header into
780
- // parameters, has to do some unescaping
781
- // Can filter out any non-oauth parameters if needed (default behaviour)
782
- public static function split_header($header, $only_allow_oauth_parameters = true) {
783
- $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
784
- $offset = 0;
785
- $params = array();
786
- while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
787
- $match = $matches[0];
788
- $header_name = $matches[2][0];
789
- $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
790
- if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) {
791
- $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content);
792
- }
793
- $offset = $match[1] + strlen($match[0]);
794
- }
795
-
796
- if (isset($params['realm'])) {
797
- unset($params['realm']);
798
- }
799
-
800
- return $params;
801
- }
802
-
803
- // helper to try to sort out headers for people who aren't running apache
804
- public static function get_headers() {
805
- if (function_exists('apache_request_headers')) {
806
- // we need this to get the actual Authorization: header
807
- // because apache tends to tell us it doesn't exist
808
- $headers = apache_request_headers();
809
-
810
- // sanitize the output of apache_request_headers because
811
- // we always want the keys to be Cased-Like-This and arh()
812
- // returns the headers in the same case as they are in the
813
- // request
814
- $out = array();
815
- foreach( $headers AS $key => $value ) {
816
- $key = str_replace(
817
- " ",
818
- "-",
819
- ucwords(strtolower(str_replace("-", " ", $key)))
820
- );
821
- $out[$key] = $value;
822
- }
823
- } else {
824
- // otherwise we don't have apache and are just going to have to hope
825
- // that $_SERVER actually contains what we need
826
- $out = array();
827
- if( isset($_SERVER['CONTENT_TYPE']) )
828
- $out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
829
- if( isset($_ENV['CONTENT_TYPE']) )
830
- $out['Content-Type'] = $_ENV['CONTENT_TYPE'];
831
-
832
- foreach ($_SERVER as $key => $value) {
833
- if (substr($key, 0, 5) == "HTTP_") {
834
- // this is chaos, basically it is just there to capitalize the first
835
- // letter of every word that is not an initial HTTP and strip HTTP
836
- // code from przemek
837
- $key = str_replace(
838
- " ",
839
- "-",
840
- ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
841
- );
842
- $out[$key] = $value;
843
- }
844
- }
845
- }
846
- return $out;
847
- }
848
-
849
- // This function takes a input like a=b&a=c&d=e and returns the parsed
850
- // parameters like this
851
- // array('a' => array('b','c'), 'd' => 'e')
852
- public static function parse_parameters( $input ) {
853
- if (!isset($input) || !$input) return array();
854
-
855
- $pairs = explode('&', $input);
856
-
857
- $parsed_parameters = array();
858
- foreach ($pairs as $pair) {
859
- $split = explode('=', $pair, 2);
860
- $parameter = OAuthUtil::urldecode_rfc3986($split[0]);
861
- $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
862
-
863
- if (isset($parsed_parameters[$parameter])) {
864
- // We have already recieved parameter(s) with this name, so add to the list
865
- // of parameters with this name
866
-
867
- if (is_scalar($parsed_parameters[$parameter])) {
868
- // This is the first duplicate, so transform scalar (string) into an array
869
- // so we can add the duplicates
870
- $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
871
- }
872
-
873
- $parsed_parameters[$parameter][] = $value;
874
- } else {
875
- $parsed_parameters[$parameter] = $value;
876
- }
877
- }
878
- return $parsed_parameters;
879
- }
880
-
881
- public static function build_http_query($params) {
882
- if (!$params) return '';
883
-
884
- // Urlencode both keys and values
885
- $keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
886
- $values = OAuthUtil::urlencode_rfc3986(array_values($params));
887
- $params = array_combine($keys, $values);
888
-
889
- // Parameters are sorted by name, using lexicographical byte value ordering.
890
- // Ref: Spec: 9.1.1 (1)
891
- uksort($params, 'strcmp');
892
-
893
- $pairs = array();
894
- foreach ($params as $parameter => $value) {
895
- if (is_array($value)) {
896
- // If two or more parameters share the same name, they are sorted by their value
897
- // Ref: Spec: 9.1.1 (1)
898
- natsort($value);
899
- foreach ($value as $duplicate_value) {
900
- $pairs[] = $parameter . '=' . $duplicate_value;
901
- }
902
- } else {
903
- $pairs[] = $parameter . '=' . $value;
904
- }
905
- }
906
- // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
907
- // Each name-value pair is separated by an '&' character (ASCII code 38)
908
- return implode('&', $pairs);
909
- }
910
- }
911
  }
1
+ <?php
2
+ // vim: foldmethod=marker
3
+
4
+ /* Generic exception class
5
+ */
6
+ if (!class_exists('OAuthException'))
7
+ {
8
+ class OAuthException extends Exception
9
+ {
10
+ // pass
11
+ }
12
+ }
13
+
14
+ if (!class_exists('OAuthConsumer'))
15
+ {
16
+ class OAuthConsumer
17
+ {
18
+ public $key;
19
+ public $secret;
20
+
21
+ function __construct($key, $secret, $callback_url=NULL) {
22
+ $this->key = $key;
23
+ $this->secret = $secret;
24
+ $this->callback_url = $callback_url;
25
+ }
26
+
27
+ function __toString() {
28
+ return "OAuthConsumer[key=$this->key,secret=$this->secret]";
29
+ }
30
+ }
31
+ }
32
+
33
+ if (!class_exists('OAuthToken'))
34
+ {
35
+ class OAuthToken
36
+ {
37
+ // access tokens and request tokens
38
+ public $key;
39
+ public $secret;
40
+
41
+ /**
42
+ * key = the token
43
+ * secret = the token secret
44
+ */
45
+ function __construct($key, $secret)
46
+ {
47
+ $this->key = $key;
48
+ $this->secret = $secret;
49
+ }
50
+
51
+ /**
52
+ * generates the basic string serialization of a token that a server
53
+ * would respond to request_token and access_token calls with
54
+ */
55
+ function to_string()
56
+ {
57
+ return "oauth_token=" .
58
+ OAuthUtil::urlencode_rfc3986($this->key) .
59
+ "&oauth_token_secret=" .
60
+ OAuthUtil::urlencode_rfc3986($this->secret);
61
+ }
62
+
63
+ function __toString()
64
+ {
65
+ return $this->to_string();
66
+ }
67
+ }
68
+ }
69
+ /**
70
+ * A class for implementing a Signature Method
71
+ * See section 9 ("Signing Requests") in the spec
72
+ */
73
+
74
+ if (!class_exists('OAuthSignatureMethod'))
75
+ {
76
+ abstract class OAuthSignatureMethod {
77
+ /**
78
+ * Needs to return the name of the Signature Method (ie HMAC-SHA1)
79
+ * @return string
80
+ */
81
+ abstract public function get_name();
82
+
83
+ /**
84
+ * Build up the signature
85
+ * NOTE: The output of this function MUST NOT be urlencoded.
86
+ * the encoding is handled in OAuthRequest when the final
87
+ * request is serialized
88
+ * @param OAuthRequest $request
89
+ * @param OAuthConsumer $consumer
90
+ * @param OAuthToken $token
91
+ * @return string
92
+ */
93
+ abstract public function build_signature($request, $consumer, $token);
94
+
95
+ /**
96
+ * Verifies that a given signature is correct
97
+ * @param OAuthRequest $request
98
+ * @param OAuthConsumer $consumer
99
+ * @param OAuthToken $token
100
+ * @param string $signature
101
+ * @return bool
102
+ */
103
+ public function check_signature($request, $consumer, $token, $signature) {
104
+ $built = $this->build_signature($request, $consumer, $token);
105
+ return $built == $signature;
106
+ }
107
+ }
108
+ }
109
+ /**
110
+ * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
111
+ * where the Signature Base String is the text and the key is the concatenated values (each first
112
+ * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
113
+ * character (ASCII code 38) even if empty.
114
+ * - Chapter 9.2 ("HMAC-SHA1")
115
+ */
116
+
117
+ if (!class_exists('OAuthSignatureMethod_HMAC_SHA1'))
118
+ {
119
+ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
120
+ {
121
+ function get_name()
122
+ {
123
+ return "HMAC-SHA1";
124
+ }
125
+
126
+ public function build_signature($request, $consumer, $token)
127
+ {
128
+ $base_string = $request->get_signature_base_string();
129
+ $request->base_string = $base_string;
130
+
131
+ $key_parts = array(
132
+ $consumer->secret,
133
+ ($token) ? $token->secret : ""
134
+ );
135
+
136
+ $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
137
+ $key = implode('&', $key_parts);
138
+
139
+ return base64_encode(hash_hmac('sha1', $base_string, $key, true));
140
+ }
141
+ }
142
+ }
143
+
144
+ /**
145
+ * The PLAINTEXT method does not provide any security protection and SHOULD only be used
146
+ * over a secure channel such as HTTPS. It does not use the Signature Base String.
147
+ * - Chapter 9.4 ("PLAINTEXT")
148
+ */
149
+ if (!class_exists('OAuthSignatureMethod_PLAINTEXT'))
150
+ {
151
+ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
152
+ {
153
+ public function get_name() {
154
+ return "PLAINTEXT";
155
+ }
156
+
157
+ /**
158
+ * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
159
+ * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
160
+ * empty. The result MUST be encoded again.
161
+ * - Chapter 9.4.1 ("Generating Signatures")
162
+ *
163
+ * Please note that the second encoding MUST NOT happen in the SignatureMethod, as
164
+ * OAuthRequest handles this!
165
+ */
166
+ public function build_signature($request, $consumer, $token) {
167
+ $key_parts = array(
168
+ $consumer->secret,
169
+ ($token) ? $token->secret : ""
170
+ );
171
+
172
+ $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
173
+ $key = implode('&', $key_parts);
174
+ $request->base_string = $key;
175
+
176
+ return $key;
177
+ }
178
+ }
179
+ }
180
+
181
+ /**
182
+ * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
183
+ * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
184
+ * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
185
+ * verified way to the Service Provider, in a manner which is beyond the scope of this
186
+ * specification.
187
+ * - Chapter 9.3 ("RSA-SHA1")
188
+ */
189
+
190
+ if (!class_exists('OAuthSignatureMethod_RSA_SHA1'))
191
+ {
192
+ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
193
+ public function get_name() {
194
+ return "RSA-SHA1";
195
+ }
196
+
197
+ // Up to the SP to implement this lookup of keys. Possible ideas are:
198
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
199
+ // (2) fetch via http using a url provided by the requester
200
+ // (3) some sort of specific discovery code based on request
201
+ //
202
+ // Either way should return a string representation of the certificate
203
+ protected abstract function fetch_public_cert(&$request);
204
+
205
+ // Up to the SP to implement this lookup of keys. Possible ideas are:
206
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
207
+ //
208
+ // Either way should return a string representation of the certificate
209
+ protected abstract function fetch_private_cert(&$request);
210
+
211
+ public function build_signature($request, $consumer, $token) {
212
+ $base_string = $request->get_signature_base_string();
213
+ $request->base_string = $base_string;
214
+
215
+ // Fetch the private key cert based on the request
216
+ $cert = $this->fetch_private_cert($request);
217
+
218
+ // Pull the private key ID from the certificate
219
+ $privatekeyid = openssl_get_privatekey($cert);
220
+
221
+ // Sign using the key
222
+ $ok = openssl_sign($base_string, $signature, $privatekeyid);
223
+
224
+ // Release the key resource
225
+ openssl_free_key($privatekeyid);
226
+
227
+ return base64_encode($signature);
228
+ }
229
+
230
+ public function check_signature($request, $consumer, $token, $signature) {
231
+ $decoded_sig = base64_decode($signature);
232
+
233
+ $base_string = $request->get_signature_base_string();
234
+
235
+ // Fetch the public key cert based on the request
236
+ $cert = $this->fetch_public_cert($request);
237
+
238
+ // Pull the public key ID from the certificate
239
+ $publickeyid = openssl_get_publickey($cert);
240
+
241
+ // Check the computed signature against the one passed in the query
242
+ $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
243
+
244
+ // Release the key resource
245
+ openssl_free_key($publickeyid);
246
+
247
+ return $ok == 1;
248
+ }
249
+ }
250
+ }
251
+
252
+ if (!class_exists('OAuthRequest'))
253
+ {
254
+ class OAuthRequest
255
+ {
256
+ private $parameters;
257
+ private $http_method;
258
+ private $http_url;
259
+ // for debug purposes
260
+ public $base_string;
261
+ public static $version = '1.0';
262
+ public static $POST_INPUT = 'php://input';
263
+
264
+ function __construct($http_method, $http_url, $parameters=NULL) {
265
+ @$parameters or $parameters = array();
266
+ $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
267
+ $this->parameters = $parameters;
268
+ $this->http_method = $http_method;
269
+ $this->http_url = $http_url;
270
+ }
271
+ /**
272
+ * attempt to build up a request from what was passed to the server
273
+ */
274
+ public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
275
+ $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
276
+ ? 'http'
277
+ : 'https';
278
+ @$http_url or $http_url = $scheme .
279
+ '://' . $_SERVER['HTTP_HOST'] .
280
+ ':' .
281
+ $_SERVER['SERVER_PORT'] .
282
+ $_SERVER['REQUEST_URI'];
283
+ @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
284
+
285
+ // We weren't handed any parameters, so let's find the ones relevant to
286
+ // this request.
287
+ // If you run XML-RPC or similar you should use this to provide your own
288
+ // parsed parameter-list
289
+ if (!$parameters) {
290
+ // Find request headers
291
+ $request_headers = OAuthUtil::get_headers();
292
+
293
+ // Parse the query-string to find GET parameters
294
+ $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
295
+
296
+ // It's a POST request of the proper content-type, so parse POST
297
+ // parameters and add those overriding any duplicates from GET
298
+ if ($http_method == "POST"
299
+ && @strstr($request_headers["Content-Type"],
300
+ "application/x-www-form-urlencoded")
301
+ ) {
302
+ $post_data = OAuthUtil::parse_parameters(
303
+ file_get_contents(self::$POST_INPUT)
304
+ );
305
+ $parameters = array_merge($parameters, $post_data);
306
+ }
307
+
308
+ // We have a Authorization-header with OAuth data. Parse the header
309
+ // and add those overriding any duplicates from GET or POST
310
+ if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
311
+ $header_parameters = OAuthUtil::split_header(
312
+ $request_headers['Authorization']
313
+ );
314
+ $parameters = array_merge($parameters, $header_parameters);
315
+ }
316
+
317
+ }
318
+
319
+ return new OAuthRequest($http_method, $http_url, $parameters);
320
+ }
321
+
322
+ /**
323
+ * pretty much a helper function to set up the request
324
+ */
325
+ public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
326
+ @$parameters or $parameters = array();
327
+ $defaults = array("oauth_version" => OAuthRequest::$version,
328
+ "oauth_nonce" => OAuthRequest::generate_nonce(),
329
+ "oauth_timestamp" => OAuthRequest::generate_timestamp(),
330
+ "oauth_consumer_key" => $consumer->key);
331
+ if ($token)
332
+ $defaults['oauth_token'] = $token->key;
333
+
334
+ $parameters = array_merge($defaults, $parameters);
335
+
336
+ return new OAuthRequest($http_method, $http_url, $parameters);
337
+ }
338
+
339
+ public function set_parameter($name, $value, $allow_duplicates = true) {
340
+ if ($allow_duplicates && isset($this->parameters[$name])) {
341
+ // We have already added parameter(s) with this name, so add to the list
342
+ if (is_scalar($this->parameters[$name])) {
343
+ // This is the first duplicate, so transform scalar (string)
344
+ // into an array so we can add the duplicates
345
+ $this->parameters[$name] = array($this->parameters[$name]);
346
+ }
347
+
348
+ $this->parameters[$name][] = $value;
349
+ } else {
350
+ $this->parameters[$name] = $value;
351
+ }
352
+ }
353
+
354
+ public function get_parameter($name) {
355
+ return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
356
+ }
357
+
358
+ public function get_parameters() {
359
+ return $this->parameters;
360
+ }
361
+
362
+ public function unset_parameter($name) {
363
+ unset($this->parameters[$name]);
364
+ }
365
+
366
+ /**
367
+ * The request parameters, sorted and concatenated into a normalized string.
368
+ * @return string
369
+ */
370
+ public function get_signable_parameters() {
371
+ // Grab all parameters
372
+ $params = $this->parameters;
373
+
374
+ // Remove oauth_signature if present
375
+ // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
376
+ if (isset($params['oauth_signature'])) {
377
+ unset($params['oauth_signature']);
378
+ }
379
+
380
+ return OAuthUtil::build_http_query($params);
381
+ }
382
+
383
+ /**
384
+ * Returns the base string of this request
385
+ *
386
+ * The base string defined as the method, the url
387
+ * and the parameters (normalized), each urlencoded
388
+ * and the concated with &.
389
+ */
390
+ public function get_signature_base_string() {
391
+ $parts = array(
392
+ $this->get_normalized_http_method(),
393
+ $this->get_normalized_http_url(),
394
+ $this->get_signable_parameters()
395
+ );
396
+
397
+ $parts = OAuthUtil::urlencode_rfc3986($parts);
398
+
399
+ return implode('&', $parts);
400
+ }
401
+
402
+ /**
403
+ * just uppercases the http method
404
+ */
405
+ public function get_normalized_http_method() {
406
+ return strtoupper($this->http_method);
407
+ }
408
+
409
+ /**
410
+ * parses the url and rebuilds it to be
411
+ * scheme://host/path
412
+ */
413
+ public function get_normalized_http_url() {
414
+ $parts = parse_url($this->http_url);
415
+
416
+ $port = @$parts['port'];
417
+ $scheme = $parts['scheme'];
418
+ $host = $parts['host'];
419
+ $path = @$parts['path'];
420
+
421
+ $port or $port = ($scheme == 'https') ? '443' : '80';
422
+
423
+ if (($scheme == 'https' && $port != '443')
424
+ || ($scheme == 'http' && $port != '80')) {
425
+ $host = "$host:$port";
426
+ }
427
+ return "$scheme://$host$path";
428
+ }
429
+
430
+ /**
431
+ * builds a url usable for a GET request
432
+ */
433
+ public function to_url() {
434
+ $post_data = $this->to_postdata();
435
+ $out = $this->get_normalized_http_url();
436
+ if ($post_data) {
437
+ $out .= '?'.$post_data;
438
+ }
439
+ return $out;
440
+ }
441
+
442
+ /**
443
+ * builds the data one would send in a POST request
444
+ */
445
+ public function to_postdata() {
446
+ return OAuthUtil::build_http_query($this->parameters);
447
+ }
448
+
449
+ /**
450
+ * builds the Authorization: header
451
+ */
452
+ public function to_header($realm=null) {
453
+ $first = true;
454
+ if($realm) {
455
+ $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
456
+ $first = false;
457
+ } else
458
+ $out = 'Authorization: OAuth';
459
+
460
+ $total = array();
461
+ foreach ($this->parameters as $k => $v) {
462
+ if (substr($k, 0, 5) != "oauth") continue;
463
+ if (is_array($v)) {
464
+ throw new OAuthException('Arrays not supported in headers');
465
+ }
466
+ $out .= ($first) ? ' ' : ',';
467
+ $out .= OAuthUtil::urlencode_rfc3986($k) .
468
+ '="' .
469
+ OAuthUtil::urlencode_rfc3986($v) .
470
+ '"';
471
+ $first = false;
472
+ }
473
+ return $out;
474
+ }
475
+
476
+ public function __toString() {
477
+ return $this->to_url();
478
+ }
479
+ public function sign_request($signature_method, $consumer, $token) {
480
+ $this->set_parameter(
481
+ "oauth_signature_method",
482
+ $signature_method->get_name(),
483
+ false
484
+ );
485
+ $signature = $this->build_signature($signature_method, $consumer, $token);
486
+ $this->set_parameter("oauth_signature", $signature, false);
487
+ }
488
+
489
+ public function build_signature($signature_method, $consumer, $token) {
490
+ $signature = $signature_method->build_signature($this, $consumer, $token);
491
+ return $signature;
492
+ }
493
+
494
+ /**
495
+ * util function: current timestamp
496
+ */
497
+ private static function generate_timestamp() {
498
+ return time();
499
+ }
500
+
501
+ /**
502
+ * util function: current nonce
503
+ */
504
+ private static function generate_nonce() {
505
+ $mt = microtime();
506
+ $rand = mt_rand();
507
+
508
+ return md5($mt . $rand); // md5s look nicer than numbers
509
+ }
510
+ }
511
+ }
512
+
513
+ if (!class_exists('OAuthServer'))
514
+ {
515
+ class OAuthServer {
516
+ protected $timestamp_threshold = 300; // in seconds, five minutes
517
+ protected $version = '1.0'; // hi blaine
518
+ protected $signature_methods = array();
519
+
520
+ protected $data_store;
521
+
522
+ function __construct($data_store) {
523
+ $this->data_store = $data_store;
524
+ }
525
+
526
+ public function add_signature_method($signature_method) {
527
+ $this->signature_methods[$signature_method->get_name()] =
528
+ $signature_method;
529
+ }
530
+
531
+ // high level functions
532
+
533
+ /**
534
+ * process a request_token request
535
+ * returns the request token on success
536
+ */
537
+ public function fetch_request_token(&$request) {
538
+ $this->get_version($request);
539
+
540
+ $consumer = $this->get_consumer($request);
541
+
542
+ // no token required for the initial token request
543
+ $token = NULL;
544
+
545
+ $this->check_signature($request, $consumer, $token);
546
+
547
+ // Rev A change
548
+ $callback = $request->get_parameter('oauth_callback');
549
+ $new_token = $this->data_store->new_request_token($consumer, $callback);
550
+
551
+ return $new_token;
552
+ }
553
+
554
+ /**
555
+ * process an access_token request
556
+ * returns the access token on success
557
+ */
558
+ public function fetch_access_token(&$request) {
559
+ $this->get_version($request);
560
+
561
+ $consumer = $this->get_consumer($request);
562
+
563
+ // requires authorized request token
564
+ $token = $this->get_token($request, $consumer, "request");
565
+
566
+ $this->check_signature($request, $consumer, $token);
567
+
568
+ // Rev A change
569
+ $verifier = $request->get_parameter('oauth_verifier');
570
+ $new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
571
+
572
+ return $new_token;
573
+ }
574
+
575
+ /**
576
+ * verify an api call, checks all the parameters
577
+ */
578
+ public function verify_request(&$request) {
579
+ $this->get_version($request);
580
+ $consumer = $this->get_consumer($request);
581
+ $token = $this->get_token($request, $consumer, "access");
582
+ $this->check_signature($request, $consumer, $token);
583
+ return array($consumer, $token);
584
+ }
585
+
586
+ // Internals from here
587
+ /**
588
+ * version 1
589
+ */
590
+ private function get_version(&$request) {
591
+ $version = $request->get_parameter("oauth_version");
592
+ if (!$version) {
593
+ // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
594
+ // Chapter 7.0 ("Accessing Protected Ressources")
595
+ $version = '1.0';
596
+ }
597
+ if ($version !== $this->version) {
598
+ throw new OAuthException("OAuth version '$version' not supported");
599
+ }
600
+ return $version;
601
+ }
602
+
603
+ /**
604
+ * figure out the signature with some defaults
605
+ */
606
+ private function get_signature_method(&$request) {
607
+ $signature_method =
608
+ @$request->get_parameter("oauth_signature_method");
609
+
610
+ if (!$signature_method) {
611
+ // According to chapter 7 ("Accessing Protected Ressources") the signature-method
612
+ // parameter is required, and we can't just fallback to PLAINTEXT
613
+ throw new OAuthException('No signature method parameter. This parameter is required');
614
+ }
615
+
616
+ if (!in_array($signature_method,
617
+ array_keys($this->signature_methods))) {
618
+ throw new OAuthException(
619
+ "Signature method '$signature_method' not supported " .
620
+ "try one of the following: " .
621
+ implode(", ", array_keys($this->signature_methods))
622
+ );
623
+ }
624
+ return $this->signature_methods[$signature_method];
625
+ }
626
+
627
+ /**
628
+ * try to find the consumer for the provided request's consumer key
629
+ */
630
+ private function get_consumer(&$request) {
631
+ $consumer_key = @$request->get_parameter("oauth_consumer_key");
632
+ if (!$consumer_key) {
633
+ throw new OAuthException("Invalid consumer key");
634
+ }
635
+
636
+ $consumer = $this->data_store->lookup_consumer($consumer_key);
637
+ if (!$consumer) {
638
+ throw new OAuthException("Invalid consumer");
639
+ }
640
+
641
+ return $consumer;
642
+ }
643
+
644
+ /**
645
+ * try to find the token for the provided request's token key
646
+ */
647
+ private function get_token(&$request, $consumer, $token_type="access") {
648
+ $token_field = @$request->get_parameter('oauth_token');
649
+ $token = $this->data_store->lookup_token(
650
+ $consumer, $token_type, $token_field
651
+ );
652
+ if (!$token) {
653
+ throw new OAuthException("Invalid $token_type token: $token_field");
654
+ }
655
+ return $token;
656
+ }
657
+
658
+ /**
659
+ * all-in-one function to check the signature on a request
660
+ * should guess the signature method appropriately
661
+ */
662
+ private function check_signature(&$request, $consumer, $token) {
663
+ // this should probably be in a different method
664
+ $timestamp = @$request->get_parameter('oauth_timestamp');
665
+ $nonce = @$request->get_parameter('oauth_nonce');
666
+
667
+ $this->check_timestamp($timestamp);
668
+ $this->check_nonce($consumer, $token, $nonce, $timestamp);
669
+
670
+ $signature_method = $this->get_signature_method($request);
671
+
672
+ $signature = $request->get_parameter('oauth_signature');
673
+ $valid_sig = $signature_method->check_signature(
674
+ $request,
675
+ $consumer,
676
+ $token,
677
+ $signature
678
+ );
679
+
680
+ if (!$valid_sig) {
681
+ throw new OAuthException("Invalid signature");
682
+ }
683
+ }
684
+
685
+ /**
686
+ * check that the timestamp is new enough
687
+ */
688
+ private function check_timestamp($timestamp) {
689
+ if( ! $timestamp )
690
+ throw new OAuthException(
691
+ 'Missing timestamp parameter. The parameter is required'
692
+ );
693
+
694
+ // verify that timestamp is recentish
695
+ $now = time();
696
+ if (abs($now - $timestamp) > $this->timestamp_threshold) {
697
+ throw new OAuthException(
698
+ "Expired timestamp, yours $timestamp, ours $now"
699
+ );
700
+ }
701
+ }
702
+
703
+ /**
704
+ * check that the nonce is not repeated
705
+ */
706
+ private function check_nonce($consumer, $token, $nonce, $timestamp) {
707
+ if( ! $nonce )
708
+ throw new OAuthException(
709
+ 'Missing nonce parameter. The parameter is required'
710
+ );
711
+
712
+ // verify that the nonce is uniqueish
713
+ $found = $this->data_store->lookup_nonce(
714
+ $consumer,
715
+ $token,
716
+ $nonce,
717
+ $timestamp
718
+ );
719
+ if ($found) {
720
+ throw new OAuthException("Nonce already used: $nonce");
721
+ }
722
+ }
723
+ }
724
+ }
725
+ if (!class_exists('OAuthDataStore'))
726
+ {
727
+ class OAuthDataStore {
728
+ function lookup_consumer($consumer_key) {
729
+ // implement me
730
+ }
731
+
732
+ function lookup_token($consumer, $token_type, $token) {
733
+ // implement me
734
+ }
735
+
736
+ function lookup_nonce($consumer, $token, $nonce, $timestamp) {
737
+ // implement me
738
+ }
739
+
740
+ function new_request_token($consumer, $callback = null) {
741
+ // return a new token attached to this consumer
742
+ }
743
+
744
+ function new_access_token($token, $consumer, $verifier = null) {
745
+ // return a new access token attached to this consumer
746
+ // for the user associated with this token if the request token
747
+ // is authorized
748
+ // should also invalidate the request token
749
+ }
750
+
751
+ }
752
+ }
753
+
754
+ if (!class_exists('OAuthUtil'))
755
+ {
756
+ class OAuthUtil {
757
+ public static function urlencode_rfc3986($input) {
758
+ if (is_array($input)) {
759
+ return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
760
+ } else if (is_scalar($input)) {
761
+ return str_replace(
762
+ '+',
763
+ ' ',
764
+ str_replace('%7E', '~', rawurlencode($input))
765
+ );
766
+ } else {
767
+ return '';
768
+ }
769
+ }
770
+
771
+
772
+ // This decode function isn't taking into consideration the above
773
+ // modifications to the encoding process. However, this method doesn't
774
+ // seem to be used anywhere so leaving it as is.
775
+ public static function urldecode_rfc3986($string) {
776
+ return urldecode($string);
777
+ }
778
+
779
+ // Utility function for turning the Authorization: header into
780
+ // parameters, has to do some unescaping
781
+ // Can filter out any non-oauth parameters if needed (default behaviour)
782
+ public static function split_header($header, $only_allow_oauth_parameters = true) {
783
+ $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
784
+ $offset = 0;
785
+ $params = array();
786
+ while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
787
+ $match = $matches[0];
788
+ $header_name = $matches[2][0];
789
+ $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
790
+ if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) {
791
+ $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content);
792
+ }
793
+ $offset = $match[1] + strlen($match[0]);
794
+ }
795
+
796
+ if (isset($params['realm'])) {
797
+ unset($params['realm']);
798
+ }
799
+
800
+ return $params;
801
+ }
802
+
803
+ // helper to try to sort out headers for people who aren't running apache
804
+ public static function get_headers() {
805
+ if (function_exists('apache_request_headers')) {
806
+ // we need this to get the actual Authorization: header
807
+ // because apache tends to tell us it doesn't exist
808
+ $headers = apache_request_headers();
809
+
810
+ // sanitize the output of apache_request_headers because
811
+ // we always want the keys to be Cased-Like-This and arh()
812
+ // returns the headers in the same case as they are in the
813
+ // request
814
+ $out = array();
815
+ foreach( $headers AS $key => $value ) {
816
+ $key = str_replace(
817
+ " ",
818
+ "-",
819
+ ucwords(strtolower(str_replace("-", " ", $key)))
820
+ );
821
+ $out[$key] = $value;
822
+ }
823
+ } else {
824
+ // otherwise we don't have apache and are just going to have to hope
825
+ // that $_SERVER actually contains what we need
826
+ $out = array();
827
+ if( isset($_SERVER['CONTENT_TYPE']) )
828
+ $out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
829
+ if( isset($_ENV['CONTENT_TYPE']) )
830
+ $out['Content-Type'] = $_ENV['CONTENT_TYPE'];
831
+
832
+ foreach ($_SERVER as $key => $value) {
833
+ if (substr($key, 0, 5) == "HTTP_") {
834
+ // this is chaos, basically it is just there to capitalize the first
835
+ // letter of every word that is not an initial HTTP and strip HTTP
836
+ // code from przemek
837
+ $key = str_replace(
838
+ " ",
839
+ "-",
840
+ ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
841
+ );
842
+ $out[$key] = $value;
843
+ }
844
+ }
845
+ }
846
+ return $out;
847
+ }
848
+
849
+ // This function takes a input like a=b&a=c&d=e and returns the parsed
850
+ // parameters like this
851
+ // array('a' => array('b','c'), 'd' => 'e')
852
+ public static function parse_parameters( $input ) {
853
+ if (!isset($input) || !$input) return array();
854
+
855
+ $pairs = explode('&', $input);
856
+
857
+ $parsed_parameters = array();
858
+ foreach ($pairs as $pair) {
859
+ $split = explode('=', $pair, 2);
860
+ $parameter = OAuthUtil::urldecode_rfc3986($split[0]);
861
+ $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
862
+
863
+ if (isset($parsed_parameters[$parameter])) {
864
+ // We have already recieved parameter(s) with this name, so add to the list
865
+ // of parameters with this name
866
+
867
+ if (is_scalar($parsed_parameters[$parameter])) {
868
+ // This is the first duplicate, so transform scalar (string) into an array
869
+ // so we can add the duplicates
870
+ $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
871
+ }
872
+
873
+ $parsed_parameters[$parameter][] = $value;
874
+ } else {
875
+ $parsed_parameters[$parameter] = $value;
876
+ }
877
+ }
878
+ return $parsed_parameters;
879
+ }
880
+
881
+ public static function build_http_query($params) {
882
+ if (!$params) return '';
883
+
884
+ // Urlencode both keys and values
885
+ $keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
886
+ $values = OAuthUtil::urlencode_rfc3986(array_values($params));
887
+ $params = array_combine($keys, $values);
888
+
889
+ // Parameters are sorted by name, using lexicographical byte value ordering.
890
+ // Ref: Spec: 9.1.1 (1)
891
+ uksort($params, 'strcmp');
892
+
893
+ $pairs = array();
894
+ foreach ($params as $parameter => $value) {
895
+ if (is_array($value)) {
896
+ // If two or more parameters share the same name, they are sorted by their value
897
+ // Ref: Spec: 9.1.1 (1)
898
+ natsort($value);
899
+ foreach ($value as $duplicate_value) {
900
+ $pairs[] = $parameter . '=' . $duplicate_value;
901
+ }
902
+ } else {
903
+ $pairs[] = $parameter . '=' . $value;
904
+ }
905
+ }
906
+ // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
907
+ // Each name-value pair is separated by an '&' character (ASCII code 38)
908
+ return implode('&', $pairs);
909
+ }
910
+ }
911
  }
helpers/twitteroauth/src/TwitterOAuth.php CHANGED
@@ -1,506 +1,506 @@
1
- <?php
2
- /**
3
- * The most popular PHP library for use with the Twitter OAuth REST API.
4
- *
5
- * @license MIT
6
- */
7
- namespace Abraham\TwitterOAuth;
8
-
9
- use Abraham\TwitterOAuth\Util\JsonDecoder;
10
-
11
- /**
12
- * TwitterOAuth class for interacting with the Twitter API.
13
- *
14
- * @author Abraham Williams <abraham@abrah.am>
15
- */
16
- class TwitterOAuth extends Config
17
- {
18
- const API_VERSION = '1.1';
19
- const API_HOST = 'https://api.twitter.com';
20
- const UPLOAD_HOST = 'https://upload.twitter.com';
21
-
22
- /** @var Response details about the result of the last request */
23
- private $response;
24
- /** @var string|null Application bearer token */
25
- private $bearer;
26
- /** @var Consumer Twitter application details */
27
- private $consumer;
28
- /** @var Token|null User access token details */
29
- private $token;
30
- /** @var HmacSha1 OAuth 1 signature type used by Twitter */
31
- private $signatureMethod;
32
-
33
- /**
34
- * Constructor
35
- *
36
- * @param string $consumerKey The Application Consumer Key
37
- * @param string $consumerSecret The Application Consumer Secret
38
- * @param string|null $oauthToken The Client Token (optional)
39
- * @param string|null $oauthTokenSecret The Client Token Secret (optional)
40
- */
41
- public function __construct($consumerKey, $consumerSecret, $oauthToken = null, $oauthTokenSecret = null)
42
- {
43
- $this->resetLastResponse();
44
- $this->signatureMethod = new HmacSha1();
45
- $this->consumer = new Consumer($consumerKey, $consumerSecret);
46
- if (!empty($oauthToken) && !empty($oauthTokenSecret)) {
47
- $this->token = new Token($oauthToken, $oauthTokenSecret);
48
- }
49
- if (empty($oauthToken) && !empty($oauthTokenSecret)) {
50
- $this->bearer = $oauthTokenSecret;
51
- }
52
- }
53
-
54
- /**
55
- * @param string $oauthToken
56
- * @param string $oauthTokenSecret
57
- */
58
- public function setOauthToken($oauthToken, $oauthTokenSecret)
59
- {
60
- $this->token = new Token($oauthToken, $oauthTokenSecret);
61
- }
62
-
63
- /**
64
- * @return string|null
65
- */
66
- public function getLastApiPath()
67
- {
68
- return $this->response->getApiPath();
69
- }
70
-
71
- /**
72
- * @return int
73
- */
74
- public function getLastHttpCode()
75
- {
76
- return $this->response->getHttpCode();
77
- }
78
-
79
- /**
80
- * @return array
81
- */
82
- public function getLastXHeaders()
83
- {
84
- return $this->response->getXHeaders();
85
- }
86
-
87
- /**
88
- * @return array|object|null
89
- */
90
- public function getLastBody()
91
- {
92
- return $this->response->getBody();
93
- }
94
-
95
- /**
96
- * Resets the last response cache.
97
- */
98
- public function resetLastResponse()
99
- {
100
- $this->response = new Response();
101
- }
102
-
103
- /**
104
- * Make URLs for user browser navigation.
105
- *
106
- * @param string $path
107
- * @param array $parameters
108
- *
109
- * @return string
110
- */
111
- public function url($path, array $parameters)
112
- {
113
- $this->resetLastResponse();
114
- $this->response->setApiPath($path);
115
- $query = http_build_query($parameters);
116
- return sprintf('%s/%s?%s', self::API_HOST, $path, $query);
117
- }
118
-
119
- /**
120
- * Make /oauth/* requests to the API.
121
- *
122
- * @param string $path
123
- * @param array $parameters
124
- *
125
- * @return array
126
- * @throws TwitterOAuthException
127
- */
128
- public function oauth($path, array $parameters = [])
129
- {
130
- $response = [];
131
- $this->resetLastResponse();
132
- $this->response->setApiPath($path);
133
- $url = sprintf('%s/%s', self::API_HOST, $path);
134
- $result = $this->oAuthRequest($url, 'POST', $parameters);
135
-
136
- if ($this->getLastHttpCode() != 200) {
137
- throw new TwitterOAuthException($result);
138
- }
139
-
140
- parse_str($result, $response);
141
- $this->response->setBody($response);
142
-
143
- return $response;
144
- }
145
-
146
- /**
147
- * Make /oauth2/* requests to the API.
148
- *
149
- * @param string $path
150
- * @param array $parameters
151
- *
152
- * @return array|object
153
- */
154
- public function oauth2($path, array $parameters = [])
155
- {
156
- $method = 'POST';
157
- $this->resetLastResponse();
158
- $this->response->setApiPath($path);
159
- $url = sprintf('%s/%s', self::API_HOST, $path);
160
- $request = Request::fromConsumerAndToken($this->consumer, $this->token, $method, $url, $parameters);
161
- $authorization = 'Authorization: Basic ' . $this->encodeAppAuthorization($this->consumer);
162
- $result = $this->request($request->getNormalizedHttpUrl(), $method, $authorization, $parameters);
163
- $response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
164
- $this->response->setBody($response);
165
- return $response;
166
- }
167
-
168
- /**
169
- * Make GET requests to the API.
170
- *
171
- * @param string $path
172
- * @param array $parameters
173
- *
174
- * @return array|object
175
- */
176
- public function get($path, array $parameters = [])
177
- {
178
- return $this->http('GET', self::API_HOST, $path, $parameters);
179
- }
180
-
181
- /**
182
- * Make POST requests to the API.
183
- *
184
- * @param string $path
185
- * @param array $parameters
186
- *
187
- * @return array|object
188
- */
189
- public function post($path, array $parameters = [])
190
- {
191
- return $this->http('POST', self::API_HOST, $path, $parameters);
192
- }
193
-
194
- /**
195
- * Make DELETE requests to the API.
196
- *
197
- * @param string $path
198
- * @param array $parameters
199
- *
200
- * @return array|object
201
- */
202
- public function delete($path, array $parameters = [])
203
- {
204
- return $this->http('DELETE', self::API_HOST, $path, $parameters);
205
- }
206
-
207
- /**
208
- * Make PUT requests to the API.
209
- *
210
- * @param string $path
211
- * @param array $parameters
212
- *
213
- * @return array|object
214
- */
215
- public function put($path, array $parameters = [])
216
- {
217
- return $this->http('PUT', self::API_HOST, $path, $parameters);
218
- }
219
-
220
- /**
221
- * Upload media to upload.twitter.com.
222
- *
223
- * @param string $path
224
- * @param array $parameters
225
- * @param boolean $chunked
226
- *
227
- * @return array|object
228
- */
229
- public function upload($path, array $parameters = [], $chunked = false)
230
- {
231
- if ($chunked) {
232
- return $this->uploadMediaChunked($path, $parameters);
233
- } else {
234
- return $this->uploadMediaNotChunked($path, $parameters);
235
- }
236
- }
237
-
238
- /**
239
- * Private method to upload media (not chunked) to upload.twitter.com.
240
- *
241
- * @param string $path
242
- * @param array $parameters
243
- *
244
- * @return array|object
245
- */
246
- private function uploadMediaNotChunked($path, array $parameters)
247
- {
248
- $file = file_get_contents($parameters['media']);
249
- $base = base64_encode($file);
250
- $parameters['media'] = $base;
251
- return $this->http('POST', self::UPLOAD_HOST, $path, $parameters);
252
- }
253
-
254
- /**
255
- * Private method to upload media (chunked) to upload.twitter.com.
256
- *
257
- * @param string $path
258
- * @param array $parameters
259
- *
260
- * @return array|object
261
- */
262
- private function uploadMediaChunked($path, array $parameters)
263
- {
264
- $init = $this->http('POST', self::UPLOAD_HOST, $path, $this->mediaInitParameters($parameters));
265
- // Append
266
- $segmentIndex = 0;
267
- $media = fopen($parameters['media'], 'rb');
268
- while (!feof($media))
269
- {
270
- $this->http('POST', self::UPLOAD_HOST, 'media/upload', [
271
- 'command' => 'APPEND',
272
- 'media_id' => $init->media_id_string,
273
- 'segment_index' => $segmentIndex++,
274
- 'media_data' => base64_encode(fread($media, $this->chunkSize))
275
- ]);
276
- }
277
- fclose($media);
278
- // Finalize
279
- $finalize = $this->http('POST', self::UPLOAD_HOST, 'media/upload', [
280
- 'command' => 'FINALIZE',
281
- 'media_id' => $init->media_id_string
282
- ]);
283
- return $finalize;
284
- }
285
-
286
- /**
287
- * Private method to get params for upload media chunked init.
288
- * Twitter docs: https://dev.twitter.com/rest/reference/post/media/upload-init.html
289
- *
290
- * @param array $parameters
291
- *
292
- * @return array
293
- */
294
- private function mediaInitParameters(array $parameters)
295
- {
296
- $return = [
297
- 'command' => 'INIT',
298
- 'media_type' => $parameters['media_type'],
299
- 'total_bytes' => filesize($parameters['media'])
300
- ];
301
- if (isset($parameters['additional_owners'])) {
302
- $return['additional_owners'] = $parameters['additional_owners'];
303
- }
304
- if (isset($parameters['media_category'])) {
305
- $return['media_category'] = $parameters['media_category'];
306
- }
307
- return $return;
308
- }
309
-
310
- /**
311
- * @param string $method
312
- * @param string $host
313
- * @param string $path
314
- * @param array $parameters
315
- *
316
- * @return array|object
317
- */
318
- private function http($method, $host, $path, array $parameters)
319
- {
320
- $this->resetLastResponse();
321
- $url = sprintf('%s/%s/%s.json', $host, self::API_VERSION, $path);
322
- $this->response->setApiPath($path);
323
- $result = $this->oAuthRequest($url, $method, $parameters);
324
- $response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
325
- $this->response->setBody($response);
326
- return $response;
327
- }
328
-
329
- /**
330
- * Format and sign an OAuth / API request
331
- *
332
- * @param string $url
333
- * @param string $method
334
- * @param array $parameters
335
- *
336
- * @return string
337
- * @throws TwitterOAuthException
338
- */
339
- private function oAuthRequest($url, $method, array $parameters)
340
- {
341
- $request = Request::fromConsumerAndToken($this->consumer, $this->token, $method, $url, $parameters);
342
- if (array_key_exists('oauth_callback', $parameters)) {
343
- // Twitter doesn't like oauth_callback as a parameter.
344
- unset($parameters['oauth_callback']);
345
- }
346
- if ($this->bearer === null) {
347
- $request->signRequest($this->signatureMethod, $this->consumer, $this->token);
348
- $authorization = $request->toHeader();
349
- if (array_key_exists('oauth_verifier', $parameters)) {
350
- // Twitter doesn't always work with oauth in the body and in the header
351
- // and it's already included in the $authorization header
352
- unset($parameters['oauth_verifier']);
353
- }
354
- } else {
355
- $authorization = 'Authorization: Bearer ' . $this->bearer;
356
- }
357
- return $this->request($request->getNormalizedHttpUrl(), $method, $authorization, $parameters);
358
- }
359
-
360
- /**
361
- * Set Curl options.
362
- *
363
- * @return array
364
- */
365
- private function curlOptions()
366
- {
367
- $options = [
368
- // CURLOPT_VERBOSE => true,
369
- CURLOPT_CONNECTTIMEOUT => $this->connectionTimeout,
370
- CURLOPT_HEADER => true,
371
- CURLOPT_RETURNTRANSFER => true,
372
- CURLOPT_SSL_VERIFYHOST => 2,
373
- CURLOPT_SSL_VERIFYPEER => true,
374
- CURLOPT_TIMEOUT => $this->timeout,
375
- CURLOPT_USERAGENT => $this->userAgent,
376
- ];
377
-
378
- if ($this->useCAFile()) {
379
- $options[CURLOPT_CAINFO] = __DIR__ . DIRECTORY_SEPARATOR . 'cacert.pem';
380
- }
381
-
382
- if($this->gzipEncoding) {
383
- $options[CURLOPT_ENCODING] = 'gzip';
384
- }
385
-
386
- if (!empty($this->proxy)) {
387
- $options[CURLOPT_PROXY] = $this->proxy['CURLOPT_PROXY'];
388
- $options[CURLOPT_PROXYUSERPWD] = $this->proxy['CURLOPT_PROXYUSERPWD'];
389
- $options[CURLOPT_PROXYPORT] = $this->proxy['CURLOPT_PROXYPORT'];
390
- $options[CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
391
- $options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
392
- }
393
-
394
- return $options;
395
- }
396
-
397
- /**
398
- * Make an HTTP request
399
- *
400
- * @param string $url
401
- * @param string $method
402
- * @param string $authorization
403
- * @param array $postfields
404
- *
405
- * @return string
406
- * @throws TwitterOAuthException
407
- */
408
- private function request($url, $method, $authorization, array $postfields)
409
- {
410
- $options = $this->curlOptions($url, $authorization);
411
- $options[CURLOPT_URL] = $url;
412
- $options[CURLOPT_HTTPHEADER] = ['Accept: application/json', $authorization, 'Expect:'];
413
-
414
- switch ($method) {
415
- case 'GET':
416
- break;
417
- case 'POST':
418
- $options[CURLOPT_POST] = true;
419
- $options[CURLOPT_POSTFIELDS] = Util::buildHttpQuery($postfields);
420
- break;
421
- case 'DELETE':
422
- $options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
423
- break;
424
- case 'PUT':
425
- $options[CURLOPT_CUSTOMREQUEST] = 'PUT';
426
- break;
427
- }
428
-
429
- if (in_array($method, ['GET', 'PUT', 'DELETE']) && !empty($postfields)) {
430
- $options[CURLOPT_URL] .= '?' . Util::buildHttpQuery($postfields);
431
- }
432
- $curlHandle = curl_init();
433
- curl_setopt_array($curlHandle, $options);
434
- $response = curl_exec($curlHandle);
435
-
436
- // Throw exceptions on cURL errors.
437
- if (curl_errno($curlHandle) > 0) {
438
- throw new TwitterOAuthException(curl_error($curlHandle), curl_errno($curlHandle));
439
- }
440
-
441
- $this->response->setHttpCode(curl_getinfo($curlHandle, CURLINFO_HTTP_CODE));
442
- $parts = explode("\r\n\r\n", $response);
443
- $responseBody = array_pop($parts);
444
- $responseHeader = array_pop($parts);
445
- $this->response->setHeaders($this->parseHeaders($responseHeader));
446
-
447
- curl_close($curlHandle);
448
-
449
- return $responseBody;
450
- }
451
-
452
- /**
453
- * Get the header info to store.
454
- *
455
- * @param string $header
456
- *
457
- * @return array
458
- */
459
- private function parseHeaders($header)
460
- {
461
- $headers = [];
462
- foreach (explode("\r\n", $header) as $line) {
463
- if (strpos($line, ':') !== false) {
464
- list ($key, $value) = explode(': ', $line);
465
- $key = str_replace('-', '_', strtolower($key));
466
- $headers[$key] = trim($value);
467
- }
468
- }
469
- return $headers;
470
- }
471
-
472
- /**
473
- * Encode application authorization header with base64.
474
- *
475
- * @param Consumer $consumer
476
- *
477
- * @return string
478
- */
479
- private function encodeAppAuthorization(Consumer $consumer)
480
- {
481
- $key = rawurlencode($consumer->key);
482
- $secret = rawurlencode($consumer->secret);
483
- return base64_encode($key . ':' . $secret);
484
- }
485
-
486
- /**
487
- * Is the code running from a Phar module.
488
- *
489
- * @return boolean
490
- */
491
- private function pharRunning()
492
- {
493
- return class_exists('Phar') && \Phar::running(false) !== '';
494
- }
495
-
496
- /**
497
- * Use included CA file instead of OS provided list.
498
- *
499
- * @return boolean
500
- */
501
- private function useCAFile()
502
- {
503
- /* Use CACert file when not in a PHAR file. */
504
- return !$this->pharRunning();
505
- }
506
- }
1
+ <?php
2
+ /**
3
+ * The most popular PHP library for use with the Twitter OAuth REST API.
4
+ *
5
+ * @license MIT
6
+ */
7
+ namespace Abraham\TwitterOAuth;
8
+
9
+ use Abraham\TwitterOAuth\Util\JsonDecoder;
10
+
11
+ /**
12
+ * TwitterOAuth class for interacting with the Twitter API.
13
+ *
14
+ * @author Abraham Williams <abraham@abrah.am>
15
+ */
16
+ class TwitterOAuth extends Config
17
+ {
18
+ const API_VERSION = '1.1';
19
+ const API_HOST = 'https://api.twitter.com';
20
+ const UPLOAD_HOST = 'https://upload.twitter.com';
21
+
22
+ /** @var Response details about the result of the last request */
23
+ private $response;
24
+ /** @var string|null Application bearer token */
25
+ private $bearer;
26
+ /** @var Consumer Twitter application details */
27
+ private $consumer;
28
+ /** @var Token|null User access token details */
29
+ private $token;
30
+ /** @var HmacSha1 OAuth 1 signature type used by Twitter */
31
+ private $signatureMethod;
32
+
33
+ /**
34
+ * Constructor
35
+ *
36
+ * @param string $consumerKey The Application Consumer Key
37
+ * @param string $consumerSecret The Application Consumer Secret
38
+ * @param string|null $oauthToken The Client Token (optional)
39
+ * @param string|null $oauthTokenSecret The Client Token Secret (optional)
40
+ */
41
+ public function __construct($consumerKey, $consumerSecret, $oauthToken = null, $oauthTokenSecret = null)
42
+ {
43
+ $this->resetLastResponse();
44
+ $this->signatureMethod = new HmacSha1();
45
+ $this->consumer = new Consumer($consumerKey, $consumerSecret);
46
+ if (!empty($oauthToken) && !empty($oauthTokenSecret)) {
47
+ $this->token = new Token($oauthToken, $oauthTokenSecret);
48
+ }
49
+ if (empty($oauthToken) && !empty($oauthTokenSecret)) {
50
+ $this->bearer = $oauthTokenSecret;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * @param string $oauthToken
56
+ * @param string $oauthTokenSecret
57
+ */
58
+ public function setOauthToken($oauthToken, $oauthTokenSecret)
59
+ {
60
+ $this->token = new Token($oauthToken, $oauthTokenSecret);
61
+ }
62
+
63
+ /**
64
+ * @return string|null
65
+ */
66
+ public function getLastApiPath()
67
+ {
68
+ return $this->response->getApiPath();
69
+ }
70
+
71
+ /**
72
+ * @return int
73
+ */
74
+ public function getLastHttpCode()
75
+ {
76
+ return $this->response->getHttpCode();
77
+ }
78
+
79
+ /**
80
+ * @return array
81
+ */
82
+ public function getLastXHeaders()
83
+ {
84
+ return $this->response->getXHeaders();
85
+ }
86
+
87
+ /**
88
+ * @return array|object|null
89
+ */
90
+ public function getLastBody()
91
+ {
92
+ return $this->response->getBody();
93
+ }
94
+
95
+ /**
96
+ * Resets the last response cache.
97
+ */
98
+ public function resetLastResponse()
99
+ {
100
+ $this->response = new Response();
101
+ }
102
+
103
+ /**
104
+ * Make URLs for user browser navigation.
105
+ *
106
+ * @param string $path
107
+ * @param array $parameters
108
+ *
109
+ * @return string
110
+ */
111
+ public function url($path, array $parameters)
112
+ {
113
+ $this->resetLastResponse();
114
+ $this->response->setApiPath($path);
115
+ $query = http_build_query($parameters);
116
+ return sprintf('%s/%s?%s', self::API_HOST, $path, $query);
117
+ }
118
+
119
+ /**
120
+ * Make /oauth/* requests to the API.
121
+ *
122
+ * @param string $path
123
+ * @param array $parameters
124
+ *
125
+ * @return array
126
+ * @throws TwitterOAuthException
127
+ */
128
+ public function oauth($path, array $parameters = [])
129
+ {
130
+ $response = [];
131
+ $this->resetLastResponse();
132
+ $this->response->setApiPath($path);
133
+ $url = sprintf('%s/%s', self::API_HOST, $path);
134
+ $result = $this->oAuthRequest($url, 'POST', $parameters);
135
+
136
+ if ($this->getLastHttpCode() != 200) {
137
+ throw new TwitterOAuthException($result);
138
+ }
139
+
140
+ parse_str($result, $response);
141
+ $this->response->setBody($response);
142
+
143
+ return $response;
144
+ }
145
+
146
+ /**
147
+ * Make /oauth2/* requests to the API.
148
+ *
149
+ * @param string $path
150
+ * @param array $parameters
151
+ *
152
+ * @return array|object
153
+ */
154
+ public function oauth2($path, array $parameters = [])
155
+ {
156
+ $method = 'POST';
157
+ $this->resetLastResponse();
158
+ $this->response->setApiPath($path);
159
+ $url = sprintf('%s/%s', self::API_HOST, $path);
160
+ $request = Request::fromConsumerAndToken($this->consumer, $this->token, $method, $url, $parameters);
161
+ $authorization = 'Authorization: Basic ' . $this->encodeAppAuthorization($this->consumer);
162
+ $result = $this->request($request->getNormalizedHttpUrl(), $method, $authorization, $parameters);
163
+ $response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
164
+ $this->response->setBody($response);
165
+ return $response;
166
+ }
167
+
168
+ /**
169
+ * Make GET requests to the API.
170
+ *
171
+ * @param string $path
172
+ * @param array $parameters
173
+ *
174
+ * @return array|object
175
+ */
176
+ public function get($path, array $parameters = [])
177
+ {
178
+ return $this->http('GET', self::API_HOST, $path, $parameters);
179
+ }
180
+
181
+ /**
182
+ * Make POST requests to the API.
183
+ *
184
+ * @param string $path
185
+ * @param array $parameters
186
+ *
187
+ * @return array|object
188
+ */
189
+ public function post($path, array $parameters = [])
190
+ {
191
+ return $this->http('POST', self::API_HOST, $path, $parameters);
192
+ }
193
+
194
+ /**
195
+ * Make DELETE requests to the API.
196
+ *
197
+ * @param string $path
198
+ * @param array $parameters
199
+ *
200
+ * @return array|object
201
+ */
202
+ public function delete($path, array $parameters = [])
203
+ {
204
+ return $this->http('DELETE', self::API_HOST, $path, $parameters);
205
+ }
206
+
207
+ /**
208
+ * Make PUT requests to the API.
209
+ *
210
+ * @param string $path
211
+ * @param array $parameters
212
+ *
213
+ * @return array|object
214
+ */
215
+ public function put($path, array $parameters = [])
216
+ {
217
+ return $this->http('PUT', self::API_HOST, $path, $parameters);
218
+ }
219
+
220
+ /**
221
+ * Upload media to upload.twitter.com.
222
+ *
223
+ * @param string $path
224
+ * @param array $parameters
225
+ * @param boolean $chunked
226
+ *
227
+ * @return array|object
228
+ */
229
+ public function upload($path, array $parameters = [], $chunked = false)
230
+ {
231
+ if ($chunked) {
232
+ return $this->uploadMediaChunked($path, $parameters);
233
+ } else {
234
+ return $this->uploadMediaNotChunked($path, $parameters);
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Private method to upload media (not chunked) to upload.twitter.com.
240
+ *
241
+ * @param string $path
242
+ * @param array $parameters
243
+ *
244
+ * @return array|object
245
+ */
246
+ private function uploadMediaNotChunked($path, array $parameters)
247
+ {
248
+ $file = file_get_contents($parameters['media']);
249
+ $base = base64_encode($file);
250
+ $parameters['media'] = $base;
251
+ return $this->http('POST', self::UPLOAD_HOST, $path, $parameters);
252
+ }
253
+
254
+ /**
255
+ * Private method to upload media (chunked) to upload.twitter.com.
256
+ *
257
+ * @param string $path
258
+ * @param array $parameters
259
+ *
260
+ * @return array|object
261
+ */
262
+ private function uploadMediaChunked($path, array $parameters)
263
+ {
264
+ $init = $this->http('POST', self::UPLOAD_HOST, $path, $this->mediaInitParameters($parameters));
265
+ // Append
266
+ $segmentIndex = 0;
267
+ $media = fopen($parameters['media'], 'rb');
268
+ while (!feof($media))
269
+ {
270
+ $this->http('POST', self::UPLOAD_HOST, 'media/upload', [
271
+ 'command' => 'APPEND',
272
+ 'media_id' => $init->media_id_string,
273
+ 'segment_index' => $segmentIndex++,
274
+ 'media_data' => base64_encode(fread($media, $this->chunkSize))
275
+ ]);
276
+ }
277
+ fclose($media);
278
+ // Finalize
279
+ $finalize = $this->http('POST', self::UPLOAD_HOST, 'media/upload', [
280
+ 'command' => 'FINALIZE',
281
+ 'media_id' => $init->media_id_string
282
+ ]);
283
+ return $finalize;
284
+ }
285
+
286
+ /**
287
+ * Private method to get params for upload media chunked init.
288
+ * Twitter docs: https://dev.twitter.com/rest/reference/post/media/upload-init.html
289
+ *
290
+ * @param array $parameters
291
+ *
292
+ * @return array
293
+ */
294
+ private function mediaInitParameters(array $parameters)
295
+ {
296
+ $return = [
297
+ 'command' => 'INIT',
298
+ 'media_type' => $parameters['media_type'],
299
+ 'total_bytes' => filesize($parameters['media'])
300
+ ];
301
+ if (isset($parameters['additional_owners'])) {
302
+ $return['additional_owners'] = $parameters['additional_owners'];
303
+ }
304
+ if (isset($parameters['media_category'])) {
305
+ $return['media_category'] = $parameters['media_category'];
306
+ }
307
+ return $return;
308
+ }
309
+
310
+ /**
311
+ * @param string $method
312
+ * @param string $host
313
+ * @param string $path
314
+ * @param array $parameters
315
+ *
316
+ * @return array|object
317
+ */
318
+ private function http($method, $host, $path, array $parameters)
319
+ {
320
+ $this->resetLastResponse();
321
+ $url = sprintf('%s/%s/%s.json', $host, self::API_VERSION, $path);
322
+ $this->response->setApiPath($path);
323
+ $result = $this->oAuthRequest($url, $method, $parameters);
324
+ $response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
325
+ $this->response->setBody($response);
326
+ return $response;
327
+ }
328
+
329
+ /**
330
+ * Format and sign an OAuth / API request
331
+ *
332
+ * @param string $url
333
+ * @param string $method
334
+ * @param array $parameters
335
+ *
336
+ * @return string
337
+ * @throws TwitterOAuthException
338
+ */
339
+ private function oAuthRequest($url, $method, array $parameters)
340
+ {
341
+ $request = Request::fromConsumerAndToken($this->consumer, $this->token, $method, $url, $parameters);
342
+ if (array_key_exists('oauth_callback', $parameters)) {
343
+ // Twitter doesn't like oauth_callback as a parameter.
344
+ unset($parameters['oauth_callback']);
345
+ }
346
+ if ($this->bearer === null) {
347
+ $request->signRequest($this->signatureMethod, $this->consumer, $this->token);
348
+ $authorization = $request->toHeader();
349
+ if (array_key_exists('oauth_verifier', $parameters)) {
350
+ // Twitter doesn't always work with oauth in the body and in the header
351
+ // and it's already included in the $authorization header
352
+ unset($parameters['oauth_verifier']);
353
+ }
354
+ } else {
355
+ $authorization = 'Authorization: Bearer ' . $this->bearer;
356
+ }
357
+ return $this->request($request->getNormalizedHttpUrl(), $method, $authorization, $parameters);
358
+ }
359
+
360
+ /**
361
+ * Set Curl options.
362
+ *
363
+ * @return array
364
+ */
365
+ private function curlOptions()
366
+ {
367
+ $options = [
368
+ // CURLOPT_VERBOSE => true,
369
+ CURLOPT_CONNECTTIMEOUT => $this->connectionTimeout,
370
+ CURLOPT_HEADER => true,
371
+ CURLOPT_RETURNTRANSFER => true,
372
+ CURLOPT_SSL_VERIFYHOST => 2,
373
+ CURLOPT_SSL_VERIFYPEER => true,
374
+ CURLOPT_TIMEOUT => $this->timeout,
375
+ CURLOPT_USERAGENT => $this->userAgent,
376
+ ];
377
+
378
+ if ($this->useCAFile()) {
379
+ $options[CURLOPT_CAINFO] = __DIR__ . DIRECTORY_SEPARATOR . 'cacert.pem';
380
+ }
381
+
382
+ if($this->gzipEncoding) {
383
+ $options[CURLOPT_ENCODING] = 'gzip';
384
+ }
385
+
386
+ if (!empty($this->proxy)) {
387
+ $options[CURLOPT_PROXY] = $this->proxy['CURLOPT_PROXY'];
388
+ $options[CURLOPT_PROXYUSERPWD] = $this->proxy['CURLOPT_PROXYUSERPWD'];
389
+ $options[CURLOPT_PROXYPORT] = $this->proxy['CURLOPT_PROXYPORT'];
390
+ $options[CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
391
+ $options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
392
+ }
393
+
394
+ return $options;
395
+ }
396
+
397
+ /**
398
+ * Make an HTTP request
399
+ *
400
+ * @param string $url
401
+ * @param string $method
402
+ * @param string $authorization
403
+ * @param array $postfields
404
+ *
405
+ * @return string
406
+ * @throws TwitterOAuthException
407
+ */
408
+ private function request($url, $method, $authorization, array $postfields)
409
+ {
410
+ $options = $this->curlOptions($url, $authorization);
411
+ $options[CURLOPT_URL] = $url;
412
+ $options[CURLOPT_HTTPHEADER] = ['Accept: application/json', $authorization, 'Expect:'];
413
+
414
+ switch ($method) {
415
+ case 'GET':
416
+ break;
417
+ case 'POST':
418
+ $options[CURLOPT_POST] = true;
419
+ $options[CURLOPT_POSTFIELDS] = Util::buildHttpQuery($postfields);
420
+ break;
421
+ case 'DELETE':
422
+ $options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
423
+ break;
424
+ case 'PUT':
425
+ $options[CURLOPT_CUSTOMREQUEST] = 'PUT';
426
+ break;
427
+ }
428
+
429
+ if (in_array($method, ['GET', 'PUT', 'DELETE']) && !empty($postfields)) {
430
+ $options[CURLOPT_URL] .= '?' . Util::buildHttpQuery($postfields);
431
+ }
432
+ $curlHandle = curl_init();
433
+ curl_setopt_array($curlHandle, $options);
434
+ $response = curl_exec($curlHandle);
435
+
436
+ // Throw exceptions on cURL errors.
437
+ if (curl_errno($curlHandle) > 0) {
438
+ throw new TwitterOAuthException(curl_error($curlHandle), curl_errno($curlHandle));
439
+ }
440
+
441
+ $this->response->setHttpCode(curl_getinfo($curlHandle, CURLINFO_HTTP_CODE));
442
+ $parts = explode("\r\n\r\n", $response);
443
+ $responseBody = array_pop($parts);
444
+ $responseHeader = array_pop($parts);
445
+ $this->response->setHeaders($this->parseHeaders($responseHeader));
446
+
447
+ curl_close($curlHandle);
448
+
449
+ return $responseBody;
450
+ }
451
+
452
+ /**
453
+ * Get the header info to store.
454
+ *
455
+ * @param string $header
456
+ *
457
+ * @return array
458
+ */
459
+ private function parseHeaders($header)
460
+ {
461
+ $headers = [];
462
+ foreach (explode("\r\n", $header) as $line) {
463
+ if (strpos($line, ':') !== false) {
464
+ list ($key, $value) = explode(': ', $line);
465
+ $key = str_replace('-', '_', strtolower($key));
466
+ $headers[$key] = trim($value);
467
+ }
468
+ }
469
+ return $headers;
470
+ }
471
+
472
+ /**
473
+ * Encode application authorization header with base64.
474
+ *
475
+ * @param Consumer $consumer
476
+ *
477
+ * @return string
478
+ */
479
+ private function encodeAppAuthorization(Consumer $consumer)
480
+ {
481
+ $key = rawurlencode($consumer->key);
482
+ $secret = rawurlencode($consumer->secret);
483
+ return base64_encode($key . ':' . $secret);
484
+ }
485
+
486
+ /**
487
+ * Is the code running from a Phar module.
488
+ *
489
+ * @return boolean
490
+ */
491
+ private function pharRunning()
492
+ {
493
+ return class_exists('Phar') && \Phar::running(false) !== '';
494
+ }
495
+
496
+ /**
497
+ * Use included CA file instead of OS provided list.
498
+ *
499
+ * @return boolean
500
+ */
501
+ private function useCAFile()
502
+ {
503
+ /* Use CACert file when not in a PHAR file. */
504
+ return !$this->pharRunning();
505
+ }
506
+ }
images/responsive-icon/Twitter.svg CHANGED
@@ -1,3 +1,3 @@
1
- <svg width="60" height="49" viewBox="0 0 60 49" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path fill-rule="evenodd" clip-rule="evenodd" d="M58.292 1.08755C56.5487 2.20994 52.546 3.84093 50.572 3.84093V3.84428C48.318 1.47754 45.1447 0 41.6253 0C34.79 0 29.2473 5.57109 29.2473 12.4388C29.2473 13.393 29.3573 14.3237 29.5607 15.2163H29.5587C20.2867 14.9717 10.146 10.3006 4.04133 2.30576C0.288 8.83575 3.536 16.0981 7.79533 18.7443C6.33733 18.8549 3.65333 18.5754 2.39 17.3365C2.30533 21.6706 4.37867 27.4132 11.9387 29.4965C10.4827 30.2838 7.90533 30.058 6.78467 29.8905C7.178 33.5492 12.2753 38.3322 17.8493 38.3322C15.8627 40.642 8.388 44.8314 0 43.4986C5.69667 46.9824 12.336 49 19.3633 49C39.3333 49 54.842 32.7323 54.0073 12.6639C54.004 12.6418 54.004 12.6197 54.002 12.5956C54.004 12.544 54.0073 12.4924 54.0073 12.4388C54.0073 12.3765 54.002 12.3175 54 12.2572C55.818 11.0075 58.2573 8.79688 60 5.88737C58.9893 6.44689 55.9573 7.56728 53.136 7.84536C54.9467 6.86302 57.6293 3.64594 58.292 1.08755Z" fill="white"/>
3
- </svg>
1
+ <svg width="60" height="49" viewBox="0 0 60 49" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M58.292 1.08755C56.5487 2.20994 52.546 3.84093 50.572 3.84093V3.84428C48.318 1.47754 45.1447 0 41.6253 0C34.79 0 29.2473 5.57109 29.2473 12.4388C29.2473 13.393 29.3573 14.3237 29.5607 15.2163H29.5587C20.2867 14.9717 10.146 10.3006 4.04133 2.30576C0.288 8.83575 3.536 16.0981 7.79533 18.7443C6.33733 18.8549 3.65333 18.5754 2.39 17.3365C2.30533 21.6706 4.37867 27.4132 11.9387 29.4965C10.4827 30.2838 7.90533 30.058 6.78467 29.8905C7.178 33.5492 12.2753 38.3322 17.8493 38.3322C15.8627 40.642 8.388 44.8314 0 43.4986C5.69667 46.9824 12.336 49 19.3633 49C39.3333 49 54.842 32.7323 54.0073 12.6639C54.004 12.6418 54.004 12.6197 54.002 12.5956C54.004 12.544 54.0073 12.4924 54.0073 12.4388C54.0073 12.3765 54.002 12.3175 54 12.2572C55.818 11.0075 58.2573 8.79688 60 5.88737C58.9893 6.44689 55.9573 7.56728 53.136 7.84536C54.9467 6.86302 57.6293 3.64594 58.292 1.08755Z" fill="white"/>
3
+ </svg>
images/responsive-icon/facebook.svg CHANGED
@@ -1,3 +1,3 @@
1
- <svg width="26" height="60" viewBox="0 0 26 60" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path fill-rule="evenodd" clip-rule="evenodd" d="M5.42204 60H16.2608V30.0147H24.3919L26 20.6453H16.2608V13.856C16.2608 11.6673 17.6659 9.36933 19.6741 9.36933H25.2092V0H18.4257V0.042C7.8117 0.43 5.63099 6.62133 5.44188 13.1247H5.42204V20.6453H0V30.0147H5.42204V60Z" fill="white"/>
3
- </svg>
1
+ <svg width="26" height="60" viewBox="0 0 26 60" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M5.42204 60H16.2608V30.0147H24.3919L26 20.6453H16.2608V13.856C16.2608 11.6673 17.6659 9.36933 19.6741 9.36933H25.2092V0H18.4257V0.042C7.8117 0.43 5.63099 6.62133 5.44188 13.1247H5.42204V20.6453H0V30.0147H5.42204V60Z" fill="white"/>
3
+ </svg>
images/visit_icons/en_US_Follow.svg ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg width="73" height="23" viewBox="0 0 73 23" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="73" height="23">
3
+ <path d="M69.1 0H3.79999C1.69999 0 0 1.69999 0 3.79999V19.2C0 21.3 1.69999 23 3.79999 23H69.1C71.2 23 72.9 21.3 72.9 19.2V3.79999C72.9 1.69999 71.2 0 69.1 0Z" fill="#50ABF1"/>
4
+ </mask>
5
+ <g mask="url(#mask0)">
6
+ <rect width="73" height="23" fill="#0274B3"/>
7
+ <rect width="73" height="23" fill="#50ABF1"/>
8
+ <path d="M27.6 16V7H33.7V8.5H29.4V10.6H33.1V12.1H29.4V15.9H27.6V16Z" fill="white"/>
9
+ <path d="M34.8 12.6C34.8 12 34.9 11.5 35.2 10.9C35.5 10.4 35.9 10 36.4 9.70001C36.9 9.40001 37.5 9.29999 38.1 9.29999C39.1 9.29999 39.9 9.59999 40.5 10.3C41.1 11 41.4 11.7 41.4 12.7C41.4 13.7 41.1 14.5 40.5 15.1C39.9 15.7 39.1 16.1 38.1 16.1C37.5 16.1 36.9 16 36.4 15.7C35.9 15.4 35.4 15 35.2 14.5C35 14 34.8 13.4 34.8 12.6ZM36.6 12.7C36.6 13.3 36.8 13.8 37.1 14.2C37.4 14.5 37.8 14.7 38.2 14.7C38.6 14.7 39 14.5 39.3 14.2C39.6 13.9 39.8 13.4 39.8 12.7C39.8 12.1 39.6 11.6 39.3 11.2C39 10.9 38.6 10.7 38.2 10.7C37.8 10.7 37.4 10.9 37.1 11.2C36.8 11.6 36.6 12.1 36.6 12.7Z" fill="white"/>
10
+ <path d="M42.9 16V7H44.6V16H42.9Z" fill="white"/>
11
+ <path d="M46.4 16V7H48.1V16H46.4Z" fill="white"/>
12
+ <path d="M49.4 12.6C49.4 12 49.5 11.5 49.8 10.9C50.1 10.4 50.5 10 51 9.70001C51.5 9.40001 52.1 9.29999 52.7 9.29999C53.7 9.29999 54.5 9.59999 55.1 10.3C55.7 10.9 56 11.7 56 12.7C56 13.7 55.7 14.5 55 15.1C54.4 15.7 53.6 16.1 52.6 16.1C52 16.1 51.4 16 50.9 15.7C50.4 15.4 49.9 15 49.7 14.5C49.5 14 49.4 13.4 49.4 12.6ZM51.2 12.7C51.2 13.3 51.4 13.8 51.7 14.2C52 14.5 52.4 14.7 52.8 14.7C53.2 14.7 53.6 14.5 53.9 14.2C54.2 13.9 54.4 13.4 54.4 12.7C54.4 12.1 54.2 11.6 53.9 11.2C53.6 10.9 53.2 10.7 52.8 10.7C52.4 10.7 52 10.9 51.7 11.2C51.4 11.6 51.2 12.1 51.2 12.7Z" fill="white"/>
13
+ <path d="M58.7 16L56.6 9.5H58.3L59.5 13.8L60.6 9.5H62.3L63.4 13.8L64.6001 9.5H66.3L64.2 16H62.5L61.4 11.8L60.3 16H58.7Z" fill="white"/>
14
+ <path d="M11.3726 14.3343C10.7002 14.3343 10.1959 14.0751 9.69158 13.6431C9.35537 13.3839 9.18726 12.9519 9.01916 12.6063C9.35537 12.6927 9.77563 12.6926 10.1118 12.5198C9.52347 12.3471 9.01915 12.0879 8.68294 11.5695C8.34674 11.0511 8.09459 10.5327 8.09459 9.92787C8.43079 10.1007 8.85105 10.2735 9.18726 10.2735C8.5989 9.84149 8.17864 9.23671 8.09459 8.45912C8.01053 7.85432 8.17864 7.33588 8.4308 6.90389C9.77563 8.54548 11.5407 9.4095 13.5579 9.5823C13.5579 9.4959 13.558 9.40951 13.4739 9.32311C13.3899 8.89112 13.4739 8.45912 13.642 8.02712C13.9782 7.24953 14.5666 6.64469 15.4071 6.47189C16.3317 6.29909 17.0881 6.55833 17.7605 7.16313C17.7605 7.16313 17.7605 7.16313 17.8446 7.16313C18.3489 7.07673 18.8532 6.81752 19.3575 6.55832C19.3575 6.64472 19.1054 7.16309 18.9373 7.33588C18.7692 7.59508 18.517 7.76789 18.2648 7.94069C18.7692 7.85429 19.1894 7.76789 19.6937 7.50869C19.6937 7.50869 19.6937 7.50873 19.6937 7.59512C19.6937 7.59512 19.6937 7.5951 19.6937 7.6815C19.4416 8.0271 19.1054 8.37271 18.7692 8.71831C18.6851 8.80471 18.6011 8.89112 18.517 8.89112C18.517 8.89112 18.517 8.89109 18.517 8.97749C18.517 9.40949 18.517 9.84151 18.4329 10.1871C18.3489 10.8783 18.1808 11.5695 17.8446 12.2607C17.5924 12.8655 17.1722 13.4703 16.7519 14.0751C16.1636 14.7663 15.5752 15.2846 14.7347 15.7166C14.1463 16.0622 13.4739 16.3214 12.8015 16.4078C12.2131 16.4942 11.6248 16.5806 10.9524 16.5806C10.1118 16.5806 9.27131 16.3214 8.51484 15.9758C8.17864 15.803 7.84243 15.6302 7.50623 15.4575C9.10321 15.5438 10.2799 15.1983 11.3726 14.3343Z" fill="white"/>
15
+ </g>
16
+ </svg>
images/visit_icons/en_US_Tweet.svg ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg width="69" height="23" viewBox="0 0 69 23" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="69" height="23">
3
+ <path d="M65.1 0H3.8C1.7 0 0 1.7 0 3.8V19.2C0 21.3 1.7 23 3.8 23H65.1C67.2 23 68.9 21.3 68.9 19.2V3.8C68.8 1.7 67.1 0 65.1 0Z" fill="#50ABF1"/>
4
+ </mask>
5
+ <g mask="url(#mask0)">
6
+ <rect width="69" height="23" fill="#0274B3"/>
7
+ <rect width="69" height="23" fill="#E1E7EC"/>
8
+ <rect width="69" height="23" fill="#CB1F24"/>
9
+ <rect width="69" height="23" fill="#3A559F"/>
10
+ <rect width="69" height="23" fill="#50ABF1"/>
11
+ <path d="M30.7 15.9V8.5H28V7H35.1V8.5H32.4V15.9H30.7Z" fill="white"/>
12
+ <path d="M36.6 15.9L34.5 9.39999H36.2L37.4 13.7L38.5 9.39999H40.2L41.3 13.7L42.5 9.39999H44.2L42.1 15.9H40.4L39.3 11.7L38.2 15.9H36.6Z" fill="white"/>
13
+ <path d="M48.9 13.9L50.6 14.2C50.4 14.8 50 15.3 49.6 15.6C49.2 15.9 48.5 16.1 47.8 16.1C46.7 16.1 45.8 15.7 45.3 15C44.9 14.4 44.7 13.7 44.7 12.8C44.7 11.7 45 10.9 45.5 10.3C46.1 9.69999 46.8 9.39999 47.6 9.39999C48.6 9.39999 49.3 9.69999 49.9 10.4C50.5 11 50.7 12 50.7 13.3H46.4C46.4 13.8 46.6 14.2 46.8 14.5C47.1 14.8 47.4 14.9 47.8 14.9C48.1 14.9 48.3 14.8 48.5 14.7C48.7 14.4 48.8 14.2 48.9 13.9ZM49 12.1C49 11.6 48.9 11.2 48.6 11C48.3 10.8 48.1 10.6 47.7 10.6C47.3 10.6 47 10.7 46.8 11C46.6 11.3 46.4 11.6 46.4 12.1H49Z" fill="white"/>
14
+ <path d="M55.9 13.9L57.6 14.2C57.4 14.8 57 15.3 56.6 15.6C56.2 15.9 55.5 16.1 54.8 16.1C53.7 16.1 52.8 15.7 52.3 15C51.9 14.4 51.7 13.7 51.7 12.8C51.7 11.7 52 10.9 52.5 10.3C53.1 9.69999 53.8 9.39999 54.6 9.39999C55.6 9.39999 56.3 9.69999 56.9 10.4C57.5 11 57.7 12 57.7 13.3H53.4C53.4 13.8 53.6 14.2 53.8 14.5C54.1 14.8 54.4 14.9 54.8 14.9C55.1 14.9 55.3 14.8 55.5 14.7C55.6 14.4 55.8 14.2 55.9 13.9ZM56 12.1C56 11.6 55.9 11.2 55.6 11C55.3 10.8 55.1 10.6 54.7 10.6C54.3 10.6 54 10.7 53.8 11C53.6 11.3 53.4 11.6 53.4 12.1H56Z" fill="white"/>
15
+ <path d="M62 9.4V10.8H60.8V13.4C60.8 13.9 60.8 14.2 60.8 14.3C60.8 14.4 60.9 14.5 61 14.5C61.1 14.6 61.2 14.6 61.3 14.6C61.5 14.6 61.7 14.5 62 14.4L62.1 15.7C61.7 15.9 61.2 16 60.7 16C60.4 16 60.1 15.9 59.9 15.8C59.7 15.7 59.5 15.6 59.4 15.4C59.3 15.2 59.2 15 59.2 14.7C59.2 14.5 59.1 14.1 59.1 13.5V10.7H58.3V9.3H59.1V8L60.8 7V9.3H62V9.4Z" fill="white"/>
16
+ <path d="M10.3726 14.3343C9.7002 14.3343 9.19589 14.0751 8.69158 13.6431C8.35537 13.3839 8.18726 12.9519 8.01916 12.6063C8.35537 12.6927 8.77563 12.6926 9.11183 12.5198C8.52347 12.3471 8.01915 12.0879 7.68294 11.5695C7.34674 11.0511 7.09459 10.5327 7.09459 9.92787C7.43079 10.1007 7.85105 10.2735 8.18726 10.2735C7.5989 9.84149 7.17864 9.23671 7.09459 8.45912C7.01053 7.85432 7.17864 7.33588 7.4308 6.90389C8.77563 8.54548 10.5407 9.4095 12.5579 9.5823C12.5579 9.4959 12.558 9.40951 12.4739 9.32311C12.3899 8.89112 12.4739 8.45912 12.642 8.02712C12.9782 7.24953 13.5666 6.64469 14.4071 6.47189C15.3317 6.29909 16.0881 6.55833 16.7605 7.16313C16.7605 7.16313 16.7605 7.16313 16.8446 7.16313C17.3489 7.07673 17.8532 6.81752 18.3575 6.55832C18.3575 6.64472 18.1054 7.16309 17.9373 7.33588C17.7692 7.59508 17.517 7.76789 17.2648 7.94069C17.7692 7.85429 18.1894 7.76789 18.6937 7.50869C18.6937 7.50869 18.6937 7.50873 18.6937 7.59512C18.6937 7.59512 18.6937 7.5951 18.6937 7.6815C18.4416 8.0271 18.1054 8.37271 17.7692 8.71831C17.6851 8.80471 17.6011 8.89112 17.517 8.89112C17.517 8.89112 17.517 8.89109 17.517 8.97749C17.517 9.40949 17.517 9.84151 17.4329 10.1871C17.3489 10.8783 17.1808 11.5695 16.8446 12.2607C16.5924 12.8655 16.1722 13.4703 15.7519 14.0751C15.1636 14.7663 14.5752 15.2846 13.7347 15.7166C13.1463 16.0622 12.4739 16.3214 11.8015 16.4078C11.2131 16.4942 10.6248 16.5806 9.95235 16.5806C9.11183 16.5806 8.27131 16.3214 7.51484 15.9758C7.17864 15.803 6.84243 15.6302 6.50623 15.4575C8.10321 15.5438 9.27994 15.1983 10.3726 14.3343Z" fill="white"/>
17
+ </g>
18
+ </svg>
images/visit_icons/en_US_save.svg ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg width="62" height="23" viewBox="0 0 62 23" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="62" height="23">
3
+ <path d="M58.1 0H3.80002C1.70002 0 0 1.70002 0 3.80002V19.2C0 21.3 1.70002 23 3.80002 23H58.1C60.2 23 61.9 21.3 61.9 19.2V3.80002C61.8 1.70002 60.1 0 58.1 0Z" fill="#50ABF1"/>
4
+ </mask>
5
+ <g mask="url(#mask0)">
6
+ <rect width="63" height="23" fill="#0274B3"/>
7
+ <rect width="63" height="23" fill="#E1E7EC"/>
8
+ <rect width="63" height="23" fill="#CB1F24"/>
9
+ <path d="M27.5 13.3L29.3 13.1C29.4 13.7 29.6 14.1 29.9 14.4C30.2 14.7 30.7 14.8 31.2 14.8C31.8 14.8 32.2 14.7 32.5 14.4C32.8 14.2 32.9 13.9 32.9 13.5C32.9 13.3 32.8 13.1 32.7 13C32.6 12.9 32.4 12.7 32 12.6C31.8 12.5 31.3 12.4 30.6 12.2C29.6 12 28.9 11.7 28.6 11.3C28 10.8 27.8 10.2 27.8 9.5C27.8 9 27.9 8.59998 28.2 8.19998C28.5 7.79998 28.8 7.49999 29.3 7.29999C29.8 7.09999 30.4 7 31.1 7C32.2 7 33.1 7.19998 33.6 7.69998C34.2 8.19998 34.5 8.89998 34.5 9.69998L32.7 9.79999C32.6 9.29999 32.5 8.99999 32.2 8.79999C31.9 8.59999 31.6 8.5 31.1 8.5C30.6 8.5 30.2 8.59999 29.9 8.79999C29.7 8.89999 29.6 9.09999 29.6 9.39999C29.6 9.59999 29.7 9.79999 29.9 9.89999C30.1 10.1 30.7 10.3 31.6 10.5C32.5 10.7 33.1 10.9 33.6 11.1C34 11.3 34.4 11.6 34.6 12C34.8 12.4 35 12.9 35 13.4C35 13.9 34.9 14.4 34.6 14.8C34.3 15.2 33.9 15.6 33.4 15.8C32.9 16 32.2 16.1 31.5 16.1C30.4 16.1 29.5 15.8 28.9 15.3C28 15 27.6 14.3 27.5 13.3Z" fill="white"/>
10
+ <path d="M37.6 11.7L36 11.4C36.2 10.8 36.5 10.3 36.9 10C37.3 9.7 38 9.5 38.8 9.5C39.6 9.5 40.1 9.59999 40.5 9.79999C40.9 9.99999 41.1 10.2 41.3 10.5C41.5 10.8 41.5 11.3 41.5 12V14C41.5 14.6 41.5 15 41.6 15.3C41.7 15.6 41.8 15.9 41.9 16.2H40.2C40.2 16.1 40.1 15.9 40 15.7C40 15.6 40 15.5 39.9 15.5C39.6 15.8 39.3 16 39 16.1C38.7 16.2 38.3 16.3 37.9 16.3C37.2 16.3 36.7 16.1 36.3 15.8C35.9 15.4 35.7 15 35.7 14.4C35.7 14 35.8 13.7 36 13.4C36.2 13.1 36.4 12.9 36.7 12.7C37 12.5 37.5 12.4 38.1 12.3C38.9 12.1 39.5 12 39.8 11.9V11.7C39.8 11.4 39.7 11.1 39.6 11C39.5 10.9 39.1 10.8 38.7 10.8C38.4 10.8 38.2 10.9 38 11C37.8 11.2 37.7 11.4 37.6 11.7ZM39.9 13.1C39.7 13.2 39.3 13.3 38.9 13.4C38.5 13.5 38.1 13.6 38 13.7C37.8 13.9 37.7 14.1 37.7 14.3C37.7 14.5 37.8 14.7 38 14.9C38.2 15.1 38.4 15.2 38.7 15.2C39 15.2 39.3 15.1 39.6 14.9C39.8 14.7 39.9 14.6 40 14.3C40 14.2 40.1 13.9 40.1 13.5V13.1H39.9Z" fill="white"/>
11
+ <path d="M45 16.2L42.4 9.69998H44.2L45.4 13L45.8 14.1C45.9 13.8 46 13.6 46 13.5C46.1 13.3 46.1 13.1 46.2 12.9L47.4 9.59998H49.2L46.6 16.1H45V16.2Z" fill="white"/>
12
+ <path d="M54 14.1L55.7 14.4C55.5 15 55.1 15.5 54.7 15.8C54.2 16.1 53.6 16.3 52.9 16.3C51.8 16.3 50.9 15.9 50.4 15.2C50 14.6 49.8 13.9 49.8 13C49.8 11.9 50.1 11.1 50.6 10.5C51.2 9.9 51.9 9.59998 52.7 9.59998C53.7 9.59998 54.4 9.89998 55 10.6C55.6 11.2 55.8 12.2 55.8 13.5H51.5C51.5 14 51.7 14.4 51.9 14.7C52.1 15 52.5 15.1 52.9 15.1C53.2 15.1 53.4 15 53.6 14.9C53.7 14.7 53.9 14.4 54 14.1ZM54.1 12.4C54.1 11.9 54 11.5 53.7 11.3C53.5 11 53.2 10.9 52.8 10.9C52.4 10.9 52.1 11 51.9 11.3C51.7 11.6 51.5 11.9 51.5 12.4H54.1Z" fill="white"/>
13
+ <g clip-path="url(#clip0)">
14
+ <path d="M13.3656 4.48386C9.62208 4.48386 6.58044 7.62361 6.58044 11.4879C6.58044 14.362 8.24165 16.8255 10.6515 17.9123C10.6281 17.4293 10.6515 16.8255 10.7685 16.2941C10.9089 15.7145 11.6342 12.4781 11.6342 12.4781C11.6342 12.4781 11.4237 12.0193 11.4237 11.3671C11.4237 10.3286 12.0086 9.55575 12.7339 9.55575C13.3422 9.55575 13.6464 10.0388 13.6464 10.6184C13.6464 11.2464 13.2486 12.2124 13.038 13.1061C12.8743 13.8548 13.389 14.4586 14.1143 14.4586C15.4012 14.4586 16.2669 12.7438 16.2669 10.7392C16.2669 9.19342 15.2608 8.0583 13.4358 8.0583C11.3768 8.0583 10.09 9.65233 10.09 11.4154C10.09 12.0192 10.2538 12.4539 10.5346 12.7921C10.6515 12.937 10.675 13.0094 10.6281 13.1785C10.6047 13.2992 10.5112 13.6132 10.4877 13.734C10.4409 13.903 10.3006 13.9755 10.1368 13.903C9.17752 13.4924 8.75636 12.4298 8.75636 11.2222C8.75636 9.24171 10.3708 6.85068 13.5996 6.85068C16.1967 6.85068 17.9047 8.78284 17.9047 10.8599C17.9047 13.6132 16.4306 15.6661 14.2547 15.6661C13.5294 15.6661 12.8275 15.2555 12.5935 14.7967C12.5935 14.7967 12.1958 16.4148 12.1256 16.7288C11.9852 17.2602 11.7044 17.8157 11.4471 18.2262C12.0554 18.4195 12.7105 18.5161 13.3656 18.5161C17.1092 18.5161 20.1508 15.3763 20.1508 11.512C20.1508 7.64772 17.1092 4.48386 13.3656 4.48386Z" fill="#CB1F24"/>
15
+ <path d="M13.3656 4.48386C9.62208 4.48386 6.58044 7.62361 6.58044 11.4879C6.58044 14.362 8.24165 16.8255 10.6515 17.9123C10.6281 17.4293 10.6515 16.8255 10.7685 16.2941C10.9089 15.7145 11.6342 12.4781 11.6342 12.4781C11.6342 12.4781 11.4237 12.0193 11.4237 11.3671C11.4237 10.3286 12.0086 9.55575 12.7339 9.55575C13.3422 9.55575 13.6464 10.0388 13.6464 10.6184C13.6464 11.2464 13.2486 12.2124 13.038 13.1061C12.8743 13.8548 13.389 14.4586 14.1143 14.4586C15.4012 14.4586 16.2669 12.7438 16.2669 10.7392C16.2669 9.19342 15.2608 8.0583 13.4358 8.0583C11.3768 8.0583 10.09 9.65233 10.09 11.4154C10.09 12.0192 10.2538 12.4539 10.5346 12.7921C10.6515 12.937 10.675 13.0094 10.6281 13.1785C10.6047 13.2992 10.5112 13.6132 10.4877 13.734C10.4409 13.903 10.3006 13.9755 10.1368 13.903C9.17752 13.4924 8.75636 12.4298 8.75636 11.2222C8.75636 9.24171 10.3708 6.85068 13.5996 6.85068C16.1967 6.85068 17.9047 8.78284 17.9047 10.8599C17.9047 13.6132 16.4306 15.6661 14.2547 15.6661C13.5294 15.6661 12.8275 15.2555 12.5935 14.7967C12.5935 14.7967 12.1958 16.4148 12.1256 16.7288C11.9852 17.2602 11.7044 17.8157 11.4471 18.2262C12.0554 18.4195 12.7105 18.5161 13.3656 18.5161C17.1092 18.5161 20.1508 15.3763 20.1508 11.512C20.1508 7.64772 17.1092 4.48386 13.3656 4.48386Z" fill="white"/>
16
+ </g>
17
+ </g>
18
+ <defs>
19
+ <clipPath id="clip0">
20
+ <rect width="13.5938" height="14.0323" fill="white" transform="matrix(-1 0 0 1 20.1625 4.48386)"/>
21
+ </clipPath>
22
+ </defs>
23
+ </svg>
js/custom-admin.js CHANGED
@@ -836,6 +836,9 @@ function sfsi_update_step6() {
836
  responsive_icons.settings.counter_bg_color = SFSI('input[name="sfsi_responsive_counter_bg_color"]').val();
837
  responsive_icons.settings.share_count_text = SFSI('input[name="sfsi_responsive_counter_share_count_text"]').val();
838
  responsive_icons.settings.show_count = countshare;
 
 
 
839
  n = {
840
  action: "updateSrcn6",
841
  sfsi_show_Onposts: s,
836
  responsive_icons.settings.counter_bg_color = SFSI('input[name="sfsi_responsive_counter_bg_color"]').val();
837
  responsive_icons.settings.share_count_text = SFSI('input[name="sfsi_responsive_counter_share_count_text"]').val();
838
  responsive_icons.settings.show_count = countshare;
839
+ responsive_icons.settings.margin_above = SFSI('input[name="sfsi_responsive_icons_settings_margin_above"]').val();
840
+ responsive_icons.settings.margin_below = SFSI('input[name="sfsi_responsive_icons_settings_margin_below"]').val();
841
+
842
  n = {
843
  action: "updateSrcn6",
844
  sfsi_show_Onposts: s,
js/custom-form.js CHANGED
@@ -1,149 +1,149 @@
1
- /*
2
-
3
- CUSTOM FORM ELEMENTS
4
-
5
- Created by Ryan Fait
6
- www.ryanfait.com
7
-
8
- The only things you may need to change in this file are the following
9
- variables: checkboxHeight, radioHeight and selectWidth (lines 24, 25, 26)
10
-
11
- The numbers you set for checkboxHeight and radioHeight should be one quarter
12
- of the total height of the image want to use for checkboxes and radio
13
- buttons. Both images should contain the four stages of both inputs stacked
14
- on top of each other in this order: unchecked, unchecked-clicked, checked,
15
- checked-clicked.
16
-
17
- You may need to adjust your images a bit if there is a slight vertical
18
- movement during the different stages of the button activation.
19
-
20
- The value of selectWidth should be the width of your select list image.
21
-
22
- Visit http://ryanfait.com/ for more information.
23
-
24
- */
25
-
26
- var checkboxHeight = "18";
27
- var radioHeight = "20.5";
28
- var selectWidth = "";
29
- /* No need to change anything after this */
30
- document.write('<style type="text/css">input.styled { display: none; } select.styled { position: relative; width: ' + selectWidth + 'px; opacity: 0; filter: alpha(opacity=0); z-index: 5; } .disabled { opacity: 0.5; filter: alpha(opacity=50); }</style>');
31
-
32
- var Custom = {
33
- init: function() {
34
- var inputs = document.getElementsByTagName("input"), span = Array(), textnode, option, active;
35
- for(a = 0; a < inputs.length; a++) {
36
- if((inputs[a].type == "checkbox" || inputs[a].type == "radio") && inputs[a].className == "styled") {
37
- span[a] = document.createElement("span");
38
- span[a].className = inputs[a].type;
39
-
40
- if(inputs[a].checked == true) {
41
- if(inputs[a].type == "checkbox") {
42
- position = "0 -" + (checkboxHeight*2) + "px";
43
- span[a].style.backgroundPosition = position;
44
- } else {
45
- position = "0 -" + (radioHeight*2) + "px";
46
- span[a].style.backgroundPosition = position;
47
- }
48
- }
49
- inputs[a].parentNode.insertBefore(span[a], inputs[a]);
50
- inputs[a].onchange = Custom.clear;
51
- if(!inputs[a].getAttribute("disabled")) {
52
- span[a].onclick = Custom.pushed;
53
- span[a].onclick = Custom.check;
54
- } else {
55
- span[a].className = span[a].className += " disabled";
56
- }
57
- }
58
- }
59
- inputs = document.getElementsByTagName("select");
60
- for(a = 0; a < inputs.length; a++) {
61
- if(inputs[a].className == "styled") {
62
- option = inputs[a].getElementsByTagName("option");
63
- active = option[0].childNodes[0].nodeValue;
64
- textnode = document.createTextNode(active);
65
- for(b = 0; b < option.length; b++) {
66
- if(option[b].selected == true) {
67
- textnode = document.createTextNode(option[b].childNodes[0].nodeValue);
68
- }
69
- }
70
- span[a] = document.createElement("span");
71
- span[a].className = "select";
72
- span[a].id = "select" + inputs[a].name;
73
- span[a].appendChild(textnode);
74
- inputs[a].parentNode.insertBefore(span[a], inputs[a]);
75
- if(!inputs[a].getAttribute("disabled")) {
76
- inputs[a].onchange = Custom.choose;
77
- } else {
78
- inputs[a].previousSibling.className = inputs[a].previousSibling.className += " disabled";
79
- }
80
- }
81
- }
82
- document.onmouseup = Custom.clear;
83
- },
84
- pushed: function() {
85
- element = this.nextSibling;
86
- if(element.checked == true && element.type == "checkbox") {
87
- this.style.backgroundPosition = "0 -" + checkboxHeight*3 + "px";
88
- } else if(element.checked == true && element.type == "radio") {
89
- this.style.backgroundPosition = "0 -" + radioHeight*3 + "px";
90
- } else if(element.checked != true && element.type == "checkbox") {
91
- this.style.backgroundPosition = "0 -" + checkboxHeight + "px";
92
- } else {
93
- this.style.backgroundPosition = "0 -" + radioHeight + "px";
94
- }
95
- },
96
- check: function() {
97
- element = this.nextSibling;
98
- if(element.checked == true && element.type == "checkbox") {
99
- this.style.backgroundPosition = "0 0";
100
- element.checked = false;
101
- } else {
102
- if(element.type == "checkbox") {
103
- this.style.backgroundPosition = "0 -" + checkboxHeight*2 + "px";
104
- } else {
105
- this.style.backgroundPosition = "0 -" + radioHeight*2 + "px";
106
- group = this.nextSibling.name;
107
- inputs = document.getElementsByTagName("input");
108
- for(a = 0; a < inputs.length; a++) {
109
- if(inputs[a].name == group && inputs[a] != this.nextSibling) {
110
- inputs[a].previousSibling.style.backgroundPosition = "0 0";
111
- }
112
- }
113
- }
114
- element.checked = true;
115
- }
116
- },
117
- clear: function() {
118
- inputs = document.getElementsByTagName("input");
119
- for(var b = 0; b < inputs.length; b++) {
120
- if(inputs[b].type == "checkbox" && inputs[b].checked == true && inputs[b].className == "styled") {
121
- inputs[b].previousSibling.style.backgroundPosition = "0 -" + checkboxHeight*2 + "px";
122
- } else if(inputs[b].type == "checkbox" && inputs[b].className == "styled") {
123
- inputs[b].previousSibling.style.backgroundPosition = "0 0";
124
- } else if(inputs[b].type == "radio" && inputs[b].checked == true && inputs[b].className == "styled") {
125
- inputs[b].previousSibling.style.backgroundPosition = "0 -" + radioHeight*2 + "px";
126
- } else if(inputs[b].type == "radio" && inputs[b].className == "styled") {
127
- inputs[b].previousSibling.style.backgroundPosition = "0 0";
128
- }
129
- }
130
- },
131
- choose: function() {
132
- option = this.getElementsByTagName("option");
133
- for(d = 0; d < option.length; d++) {
134
- if(option[d].selected == true) {
135
- document.getElementById("select" + this.name).childNodes[0].nodeValue = option[d].childNodes[0].nodeValue;
136
- }
137
- }
138
- }
139
- }
140
-
141
- var prev_onload = window.onload;
142
- window.sfsi_styled_input=Custom;
143
-
144
- if('function' === typeof prev_onload){
145
- prev_onload(),Custom.init();
146
- }
147
- else{
148
- Custom.init();
149
  }
1
+ /*
2
+
3
+ CUSTOM FORM ELEMENTS
4
+
5
+ Created by Ryan Fait
6
+ www.ryanfait.com
7
+
8
+ The only things you may need to change in this file are the following
9
+ variables: checkboxHeight, radioHeight and selectWidth (lines 24, 25, 26)
10
+
11
+ The numbers you set for checkboxHeight and radioHeight should be one quarter
12
+ of the total height of the image want to use for checkboxes and radio
13
+ buttons. Both images should contain the four stages of both inputs stacked
14
+ on top of each other in this order: unchecked, unchecked-clicked, checked,
15
+ checked-clicked.
16
+
17
+ You may need to adjust your images a bit if there is a slight vertical
18
+ movement during the different stages of the button activation.
19
+
20
+ The value of selectWidth should be the width of your select list image.
21
+
22
+ Visit http://ryanfait.com/ for more information.
23
+
24
+ */
25
+
26
+ var checkboxHeight = "18";
27
+ var radioHeight = "20.5";
28
+ var selectWidth = "";
29
+ /* No need to change anything after this */
30
+ document.write('<style type="text/css">input.styled { display: none; } select.styled { position: relative; width: ' + selectWidth + 'px; opacity: 0; filter: alpha(opacity=0); z-index: 5; } .disabled { opacity: 0.5; filter: alpha(opacity=50); }</style>');
31
+
32
+ var Custom = {
33
+ init: function() {
34
+ var inputs = document.getElementsByTagName("input"), span = Array(), textnode, option, active;
35
+ for(a = 0; a < inputs.length; a++) {
36
+ if((inputs[a].type == "checkbox" || inputs[a].type == "radio") && inputs[a].className == "styled") {
37
+ span[a] = document.createElement("span");
38
+ span[a].className = inputs[a].type;
39
+
40
+ if(inputs[a].checked == true) {
41
+ if(inputs[a].type == "checkbox") {
42
+ position = "0 -" + (checkboxHeight*2) + "px";
43
+ span[a].style.backgroundPosition = position;
44
+ } else {
45
+ position = "0 -" + (radioHeight*2) + "px";
46
+ span[a].style.backgroundPosition = position;
47
+ }
48
+ }
49
+ inputs[a].parentNode.insertBefore(span[a], inputs[a]);
50
+ inputs[a].onchange = Custom.clear;
51
+ if(!inputs[a].getAttribute("disabled")) {
52
+ span[a].onclick = Custom.pushed;
53
+ span[a].onclick = Custom.check;
54
+ } else {
55
+ span[a].className = span[a].className += " disabled";
56
+ }
57
+ }
58
+ }
59
+ inputs = document.getElementsByTagName("select");
60
+ for(a = 0; a < inputs.length; a++) {
61
+ if(inputs[a].className == "styled") {
62
+ option = inputs[a].getElementsByTagName("option");
63
+ active = option[0].childNodes[0].nodeValue;
64
+ textnode = document.createTextNode(active);
65
+ for(b = 0; b < option.length; b++) {
66
+ if(option[b].selected == true) {
67
+ textnode = document.createTextNode(option[b].childNodes[0].nodeValue);
68
+ }
69
+ }
70
+ span[a] = document.createElement("span");
71
+ span[a].className = "select";
72
+ span[a].id = "select" + inputs[a].name;
73
+ span[a].appendChild(textnode);
74
+ inputs[a].parentNode.insertBefore(span[a], inputs[a]);
75
+ if(!inputs[a].getAttribute("disabled")) {
76
+ inputs[a].onchange = Custom.choose;
77
+ } else {
78
+ inputs[a].previousSibling.className = inputs[a].previousSibling.className += " disabled";
79
+ }
80
+ }
81
+ }
82
+ document.onmouseup = Custom.clear;
83
+ },
84
+ pushed: function() {
85
+ element = this.nextSibling;
86
+ if(element.checked == true && element.type == "checkbox") {
87
+ this.style.backgroundPosition = "0 -" + checkboxHeight*3 + "px";
88
+ } else if(element.checked == true && element.type == "radio") {
89
+ this.style.backgroundPosition = "0 -" + radioHeight*3 + "px";
90
+ } else if(element.checked != true && element.type == "checkbox") {
91
+ this.style.backgroundPosition = "0 -" + checkboxHeight + "px";
92
+ } else {
93
+ this.style.backgroundPosition = "0 -" + radioHeight + "px";
94
+ }
95
+ },
96
+ check: function() {
97
+ element = this.nextSibling;
98
+ if(element.checked == true && element.type == "checkbox") {
99
+ this.style.backgroundPosition = "0 0";
100
+ element.checked = false;
101
+ } else {
102
+ if(element.type == "checkbox") {
103
+ this.style.backgroundPosition = "0 -" + checkboxHeight*2 + "px";
104
+ } else {
105
+ this.style.backgroundPosition = "0 -" + radioHeight*2 + "px";
106
+ group = this.nextSibling.name;
107
+ inputs = document.getElementsByTagName("input");
108
+ for(a = 0; a < inputs.length; a++) {
109
+ if(inputs[a].name == group && inputs[a] != this.nextSibling) {
110
+ inputs[a].previousSibling.style.backgroundPosition = "0 0";
111
+ }
112
+ }
113
+ }
114
+ element.checked = true;
115
+ }
116
+ },
117
+ clear: function() {
118
+ inputs = document.getElementsByTagName("input");
119
+ for(var b = 0; b < inputs.length; b++) {
120
+ if(inputs[b].type == "checkbox" && inputs[b].checked == true && inputs[b].className == "styled") {
121
+ inputs[b].previousSibling.style.backgroundPosition = "0 -" + checkboxHeight*2 + "px";
122
+ } else if(inputs[b].type == "checkbox" && inputs[b].className == "styled") {
123
+ inputs[b].previousSibling.style.backgroundPosition = "0 0";
124
+ } else if(inputs[b].type == "radio" && inputs[b].checked == true && inputs[b].className == "styled") {
125
+ inputs[b].previousSibling.style.backgroundPosition = "0 -" + radioHeight*2 + "px";
126
+ } else if(inputs[b].type == "radio" && inputs[b].className == "styled") {
127
+ inputs[b].previousSibling.style.backgroundPosition = "0 0";
128
+ }
129
+ }
130
+ },
131
+ choose: function() {
132
+ option = this.getElementsByTagName("option");
133
+ for(d = 0; d < option.length; d++) {
134
+ if(option[d].selected == true) {
135
+ document.getElementById("select" + this.name).childNodes[0].nodeValue = option[d].childNodes[0].nodeValue;
136
+ }
137
+ }
138
+ }
139
+ }
140
+
141
+ var prev_onload = window.onload;
142
+ window.sfsi_styled_input=Custom;
143
+
144
+ if('function' === typeof prev_onload){
145
+ prev_onload(),Custom.init();
146
+ }
147
+ else{
148
+ Custom.init();
149
  }
js/index.php CHANGED
@@ -1,3 +1,3 @@
1
- <?php
2
- echo _('Access Denied');
3
- ?>
1
+ <?php
2
+ echo _('Access Denied');
3
+ ?>
js/shuffle/jquery.shuffle.js CHANGED
@@ -1,1267 +1,1267 @@
1
- /*!
2
- * Shuffle.js by @Vestride
3
- * Categorize, sort, and filter a responsive grid of items.
4
- * Dependencies: jQuery 1.9+, Modernizr 2.6.2+
5
- * @license MIT license
6
- * @version 2.1.2
7
- */
8
- (function (factory) {
9
- if (typeof define === 'function' && define.amd) {
10
- define(['jquery', 'modernizr'], factory);
11
- } else {
12
- factory(window.jQuery, window.Modernizr);
13
- }
14
- })(function($, Modernizr, undefined) {
15
-
16
- 'use strict';
17
- // Validate Modernizr exists.
18
- // Shuffle requires `csstransitions`, `csstransforms`, `csstransforms3d`,
19
- // and `prefixed` to exist on the Modernizr object.
20
- if (typeof Modernizr !== 'object') {
21
- throw new Error('Shuffle.js requires Modernizr.\n' +
22
- 'http://vestride.github.io/Shuffle/#dependencies');
23
- }
24
- /**
25
- * Returns css prefixed properties like `-webkit-transition` or `box-sizing`
26
- * from `transition` or `boxSizing`, respectively.
27
- * @param {(string|boolean)} prop Property to be prefixed.
28
- * @return {string} The prefixed css property.
29
- */
30
- function dashify( prop ) {
31
- if (!prop) {
32
- return '';
33
- }
34
-
35
- // Replace upper case with dash-lowercase,
36
- // then fix ms- prefixes because they're not capitalized.
37
- return prop.replace(/([A-Z])/g, function( str, m1 ) {
38
- return '-' + m1.toLowerCase();
39
- }).replace(/^ms-/,'-ms-');
40
- }
41
-
42
- // Constant, prefixed variables.
43
- var TRANSITION = Modernizr.prefixed('transition');
44
- var TRANSITION_DELAY = Modernizr.prefixed('transitionDelay');
45
- var TRANSITION_DURATION = Modernizr.prefixed('transitionDuration');
46
- var TRANSITIONEND = {
47
- 'WebkitTransition' : 'webkitTransitionEnd',
48
- 'transition' : 'transitionend'
49
- }[ TRANSITION ];
50
- var TRANSFORM = Modernizr.prefixed('transform');
51
- var CSS_TRANSFORM = dashify(TRANSFORM);
52
-
53
- // Constants
54
- var CAN_TRANSITION_TRANSFORMS = Modernizr.csstransforms && Modernizr.csstransitions;
55
- var HAS_TRANSFORMS_3D = Modernizr.csstransforms3d;
56
- var SHUFFLE = 'shuffle';
57
-
58
- // Configurable. You can change these constants to fit your application.
59
- // The default scale and concealed scale, however, have to be different values.
60
- var ALL_ITEMS = 'all';
61
- var FILTER_ATTRIBUTE_KEY = 'groups';
62
- var DEFAULT_SCALE = 1;
63
- var CONCEALED_SCALE = 0.001;
64
- // Underscore's throttle function.
65
- function throttle(func, wait, options) {
66
- var context, args, result;
67
- var timeout = null;
68
- var previous = 0;
69
- options = options || {};
70
- var later = function() {
71
- previous = options.leading === false ? 0 : $.now();
72
- timeout = null;
73
- result = func.apply(context, args);
74
- context = args = null;
75
- };
76
- return function() {
77
- var now = $.now();
78
- if (!previous && options.leading === false) {
79
- previous = now;
80
- }
81
- var remaining = wait - (now - previous);
82
- context = this;
83
- args = arguments;
84
- if (remaining <= 0 || remaining > wait) {
85
- clearTimeout(timeout);
86
- timeout = null;
87
- previous = now;
88
- result = func.apply(context, args);
89
- context = args = null;
90
- } else if (!timeout && options.trailing !== false) {
91
- timeout = setTimeout(later, remaining);
92
- }
93
- return result;
94
- };
95
- }
96
-
97
- // Used for unique instance variables
98
- var id = 0;
99
- /**
100
- * Categorize, sort, and filter a responsive grid of items.
101
- *
102
- * @param {Element|jQuery} element An element or a jQuery collection which
103
- * is the parent container for the grid items.
104
- * @param {Object} [options=Shuffle.options] Options object.
105
- * @constructor
106
- */
107
- var Shuffle = function( element, options ) {
108
- options = options || {};
109
- $.extend( this, Shuffle.options, options, Shuffle.settings );
110
-
111
- this.$el = $(element);
112
- this.$window = $(window);
113
- this.unique = 'shuffle_' + id++;
114
-
115
- this._fire( Shuffle.EventType.LOADING );
116
- this._init();
117
-
118
- // Dispatch the done event asynchronously so that people can bind to it after
119
- // Shuffle has been initialized.
120
- setTimeout( $.proxy(function() {
121
- this.initialized = true;
122
- this._fire( Shuffle.EventType.DONE );
123
- }, this), 16 );
124
- };
125
- /**
126
- * Events the container element emits with the .shuffle namespace.
127
- * For example, "done.shuffle".
128
- * @enum {string}
129
- */
130
- Shuffle.EventType = {
131
- LOADING: 'loading',
132
- DONE: 'done',
133
- SHRINK: 'shrink',
134
- SHRUNK: 'shrunk',
135
- FILTER: 'filter',
136
- FILTERED: 'filtered',
137
- SORTED: 'sorted',
138
- LAYOUT: 'layout',
139
- REMOVED: 'removed'
140
- };
141
- Shuffle.prototype = {
142
-
143
- _init : function() {
144
- var self = this,
145
- containerCSS,
146
- containerWidth,
147
- resizeFunction = $.proxy( self._onResize, self ),
148
- debouncedResize = self.throttle ?
149
- self.throttle( resizeFunction, self.throttleTime ) :
150
- resizeFunction,
151
- sort = self.initialSort ? self.initialSort : null;
152
- self._layoutList = [];
153
- self._shrinkList = [];
154
-
155
- self._setVars();
156
-
157
- // Zero out all columns
158
- self._resetCols();
159
-
160
- // Add classes and invalidate styles
161
- self._addClasses();
162
-
163
- // Set initial css for each item
164
- self._initItems();
165
-
166
- // Bind resize events
167
- // http://stackoverflow.com/questions/1852751/window-resize-event-firing-in-internet-explorer
168
- self.$window.on('resize.' + SHUFFLE + '.' + self.unique, debouncedResize);
169
-
170
- // Get container css all in one request. Causes reflow
171
- containerCSS = self.$el.css(['paddingLeft', 'paddingRight', 'position']);
172
- containerWidth = self._getOuterWidth( self.$el[0] );
173
-
174
- // Position cannot be static.
175
- if ( containerCSS.position === 'static' ) {
176
- self.$el[0].style.position = 'relative';
177
- }
178
-
179
- // Get offset from container
180
- self.offset = {
181
- left: parseInt( containerCSS.paddingLeft, 10 ) || 0,
182
- top: parseInt( containerCSS.paddingTop, 10 ) || 0
183
- };
184
-
185
- // We already got the container's width above, no need to cause another reflow getting it again...
186
- // Calculate the number of columns there will be
187
- self._setColumns( parseInt( containerWidth, 10 ) );
188
-
189
- // Kick off!
190
- self.shuffle( self.group, sort );
191
-
192
- // The shuffle items haven't had transitions set on them yet
193
- // so the user doesn't see the first layout. Set them now that the first layout is done.
194
- if ( self.supported ) {
195
- setTimeout(function() {
196
- self._setTransitions();
197
- self.$el[0].style[ TRANSITION ] = 'height ' + self.speed + 'ms ' + self.easing;
198
- }, 0);
199
- }
200
- },
201
-
202
- // Will invalidate styles
203
- _addClasses : function() {
204
- this.$el.addClass( SHUFFLE );
205
- this.$items.addClass('shuffle-item filtered');
206
- },
207
-
208
- _setVars : function() {
209
- var self = this,
210
- columnWidth = self.columnWidth;
211
-
212
- self.$items = self._getItems();
213
-
214
- // Column width is the default setting and sizer is not (meaning passed in)
215
- // Assume they meant column width to be the sizer
216
- if ( columnWidth === 0 && self.sizer !== null ) {
217
- columnWidth = self.sizer;
218
- }
219
-
220
- // If column width is a string, treat is as a selector and search for the
221
- // sizer element within the outermost container
222
- if ( typeof columnWidth === 'string' ) {
223
- self.$sizer = self.$el.find( columnWidth );
224
-
225
- // Check for an element
226
- } else if ( columnWidth && columnWidth.nodeType && columnWidth.nodeType === 1 ) {
227
- // Wrap it in jQuery
228
- self.$sizer = $( columnWidth );
229
-
230
- // Check for jQuery object
231
- } else if ( columnWidth && columnWidth.jquery ) {
232
- self.$sizer = columnWidth;
233
- }
234
-
235
- if ( self.$sizer && self.$sizer.length ) {
236
- self.useSizer = true;
237
- self.sizer = self.$sizer[0];
238
- }
239
- },
240
- /**
241
- * Filter the elements by a category.
242
- * @param {string} [category] Category to filter by. If it's given, the last
243
- * category will be used to filter the items.
244
- * @param {jQuery} [$collection] Optionally filter a collection. Defaults to
245
- * all the items.
246
- * @return {jQuery} Filtered items.
247
- */
248
- _filter : function( category, $collection ) {
249
- var self = this,
250
- isPartialSet = $collection !== undefined,
251
- $items = isPartialSet ? $collection : self.$items,
252
- $filtered = $();
253
-
254
- category = category || self.lastFilter;
255
-
256
- self._fire( Shuffle.EventType.FILTER );
257
-
258
- // Loop through each item and use provided function to determine
259
- // whether to hide it or not.
260
- if ( $.isFunction( category ) ) {
261
- $items.each(function() {
262
- var $item = $(this);
263
- if ( category.call($item[0], $item, self) ) {
264
- $filtered = $filtered.add( $item );
265
- }
266
- });
267
-
268
- // Otherwise we've been passed a category to filter by
269
- } else {
270
- self.group = category;
271
-
272
- // category === 'all', add filtered class to everything
273
- if ( category === ALL_ITEMS ) {
274
- $filtered = $items;
275
-
276
- // Check each element's data-groups attribute against the given category.
277
- } else {
278
- $items.each(function() {
279
- var $item = $(this),
280
- groups = $item.data( FILTER_ATTRIBUTE_KEY ),
281
- keys = self.delimeter && !$.isArray( groups ) ?
282
- groups.split( self.delimeter ) :
283
- groups;
284
-
285
- if ( $.inArray(category, keys) > -1 ) {
286
- $filtered = $filtered.add( $item );
287
- }
288
- });
289
- }
290
- }
291
-
292
- // Individually add/remove concealed/filtered classes
293
- self._toggleFilterClasses( $items, $filtered );
294
-
295
- $items = null;
296
- $collection = null;
297
-
298
- return $filtered;
299
- },
300
- _toggleFilterClasses : function( $items, $filtered ) {
301
- var concealed = 'concealed',
302
- filtered = 'filtered';
303
-
304
- $items.filter( $filtered ).each(function() {
305
- var $filteredItem = $(this);
306
- // Remove concealed if it's there
307
- if ( $filteredItem.hasClass( concealed ) ) {
308
- $filteredItem.removeClass( concealed );
309
- }
310
- // Add filtered class if it's not there
311
- if ( !$filteredItem.hasClass( filtered ) ) {
312
- $filteredItem.addClass( filtered );
313
- }
314
- });
315
-
316
- $items.not( $filtered ).each(function() {
317
- var $filteredItem = $(this);
318
- // Add concealed if it's not there
319
- if ( !$filteredItem.hasClass( concealed ) ) {
320
- $filteredItem.addClass( concealed );
321
- }
322
- // Remove filtered class if it's there
323
- if ( $filteredItem.hasClass( filtered ) ) {
324
- $filteredItem.removeClass( filtered );
325
- }
326
- });
327
- },
328
-
329
- /**
330
- * Set the initial css for each item
331
- * @param {jQuery} [$items] Optionally specifiy at set to initialize
332
- */
333
- _initItems : function( $items ) {
334
- $items = $items || this.$items;
335
- $items.css( this.itemCss ).data('position', {x: 0, y: 0});
336
- },
337
-
338
- _updateItemCount : function() {
339
- this.visibleItems = this.$items.filter('.filtered').length;
340
- },
341
-
342
- _setTransition : function( element ) {
343
- element.style[ TRANSITION ] = CSS_TRANSFORM + ' ' + this.speed + 'ms ' + this.easing;
344
- },
345
-
346
- _setTransitions : function( $items ) {
347
- var self = this;
348
-
349
- $items = $items || self.$items;
350
- $items.each(function() {
351
- self._setTransition( this );
352
- });
353
- },
354
-
355
- _setSequentialDelay : function( $collection ) {
356
- var self = this;
357
-
358
- if ( !self.supported ) {
359
- return;
360
- }
361
-
362
- // $collection can be an array of dom elements or jquery object
363
- $.each($collection, function(i, el) {
364
- // This works because the transition-property: transform, opacity;
365
- el.style[ TRANSITION_DELAY ] = '0ms,' + ((i + 1) * self.sequentialFadeDelay) + 'ms';
366
-
367
- // Set the delay back to zero after one transition
368
- $(el).on(TRANSITIONEND + '.' + self.unique, function(evt) {
369
- var target = evt.currentTarget;
370
- if ( target === evt.target ) {
371
- target.style[ TRANSITION_DELAY ] = '0ms';
372
- $(target).off(TRANSITIONEND + '.' + self.unique);
373
- }
374
- });
375
- });
376
- },
377
-
378
- _getItems : function() {
379
- return this.$el.children( this.itemSelector );
380
- },
381
-
382
- _getPreciseDimension : function( element, style ) {
383
- var dimension;
384
- if ( window.getComputedStyle ) {
385
- dimension = window.getComputedStyle( element, null )[ style ];
386
- } else {
387
- dimension = $( element ).css( style );
388
- }
389
- return parseFloat( dimension );
390
- },
391
- /**
392
- * Returns the outer width of an element, optionally including its margins.
393
- * @param {Element} element The element.
394
- * @param {boolean} [includeMargins] Whether to include margins. Default is false.
395
- * @return {number} The width.
396
- */
397
- _getOuterWidth : function( element, includeMargins ) {
398
- var width = element.offsetWidth;
399
-
400
- // Use jQuery here because it uses getComputedStyle internally and is
401
- // cross-browser. Using the style property of the element will only work
402
- // if there are inline styles.
403
- if (includeMargins) {
404
- var styles = $(element).css(['marginLeft', 'marginRight']);
405
-
406
- // Defaults to zero if parsing fails because IE will return 'auto' when
407
- // the element doesn't have margins instead of the computed style.
408
- var marginLeft = parseFloat(styles.marginLeft) || 0;
409
- var marginRight = parseFloat(styles.marginRight) || 0;
410
- width += marginLeft + marginRight;
411
- }
412
-
413
- return width;
414
- },
415
- /**
416
- * Returns the outer height of an element, optionally including its margins.
417
- * @param {Element} element The element.
418
- * @param {boolean} [includeMargins] Whether to include margins. Default is false.
419
- * @return {number} The height.
420
- */
421
- _getOuterHeight : function( element, includeMargins ) {
422
- var height = element.offsetHeight;
423
-
424
- if (includeMargins) {
425
- var styles = $(element).css(['marginTop', 'marginBottom']);
426
- var marginTop = parseFloat(styles.marginTop) || 0;
427
- var marginBottom = parseFloat(styles.marginBottom) || 0;
428
- height += marginTop + marginBottom;
429
- }
430
-
431
- return height;
432
- },
433
- _getColumnSize : function( gutterSize, containerWidth ) {
434
- var size;
435
-
436
- // If the columnWidth property is a function, then the grid is fluid
437
- if ( $.isFunction( this.columnWidth ) ) {
438
- size = this.columnWidth(containerWidth);
439
-
440
- // columnWidth option isn't a function, are they using a sizing element?
441
- } else if ( this.useSizer ) {
442
- size = this._getPreciseDimension(this.sizer, 'width');
443
-
444
- // if not, how about the explicitly set option?
445
- } else if ( this.columnWidth ) {
446
- size = this.columnWidth;
447
-
448
- // or use the size of the first item
449
- } else if ( this.$items.length > 0 ) {
450
- size = this._getOuterWidth(this.$items[0], true);
451
-
452
- // if there's no items, use size of container
453
- } else {
454
- size = containerWidth;
455
- }
456
-
457
- // Don't let them set a column width of zero.
458
- if ( size === 0 ) {
459
- size = containerWidth;
460
- }
461
-
462
- return size + gutterSize;
463
- },
464
- _getGutterSize : function( containerWidth ) {
465
- var size;
466
- if ( $.isFunction( this.gutterWidth ) ) {
467
- size = this.gutterWidth(containerWidth);
468
- } else if ( this.useSizer ) {
469
- size = this._getPreciseDimension(this.sizer, 'marginLeft');
470
- } else {
471
- size = this.gutterWidth;
472
- }
473
-
474
- return size;
475
- },
476
- /**
477
- * Calculate the number of columns to be used. Gets css if using sizer element.
478
- * @param {number} [theContainerWidth] Optionally specify a container width if it's already available.
479
- */
480
- _setColumns : function( theContainerWidth ) {
481
- var containerWidth = theContainerWidth || this._getOuterWidth(this.$el[0]);
482
- var gutter = this._getGutterSize(containerWidth);
483
- var columnWidth = this._getColumnSize(gutter, containerWidth);
484
- var calculatedColumns = (containerWidth + gutter) / columnWidth;
485
-
486
- // Widths given from getComputedStyle are not precise enough...
487
- if ( Math.abs(Math.round(calculatedColumns) - calculatedColumns) < 0.03 ) {
488
- // e.g. calculatedColumns = 11.998876
489
- calculatedColumns = Math.round( calculatedColumns );
490
- }
491
-
492
- this.cols = Math.max( Math.floor(calculatedColumns), 1 );
493
- this.containerWidth = containerWidth;
494
- this.colWidth = columnWidth;
495
- },
496
-
497
- /**
498
- * Adjust the height of the grid
499
- */
500
- _setContainerSize : function() {
501
- this.$el.css( 'height', Math.max.apply( Math, this.colYs ) );
502
- },
503
-
504
- /**
505
- * Fire events with .shuffle namespace
506
- */
507
- _fire : function( name, args ) {
508
- this.$el.trigger( name + '.' + SHUFFLE, args && args.length ? args : [ this ] );
509
- },
510
- /**
511
- * Loops through each item that should be shown and calculates the x, y position.
512
- * @param {Array.<Element>} items Array of items that will be shown/layed out in order in their array.
513
- * Because jQuery collection are always ordered in DOM order, we can't pass a jq collection.
514
- * @param {function} fn Callback function.
515
- * @param {boolean} isOnlyPosition If true this will position the items with zero opacity.
516
- */
517
- _layout : function( items, fn, isOnlyPosition ) {
518
- var self = this;
519
-
520
- fn = fn || self._filterEnd;
521
-
522
- $.each(items, function(index, item) {
523
- var $item = $(item);
524
- var itemData = $item.data();
525
- var currPos = itemData.position;
526
- var pos = self._getItemPosition( $item );
527
-
528
- // Save data for shrink
529
- $item.data( 'position', pos );
530
-
531
- // If the item will not change its position, do not add it to the render
532
- // queue. Transitions don't fire when setting a property to the same value.
533
- if ( pos.x === currPos.x && pos.y === currPos.y && itemData.scale === DEFAULT_SCALE ) {
534
- return;
535
- }
536
-
537
- var transitionObj = {
538
- $item: $item,
539
- x: pos.x,
540
- y: pos.y,
541
- scale: DEFAULT_SCALE
542
- };
543
-
544
- if ( isOnlyPosition ) {
545
- transitionObj.skipTransition = true;
546
- transitionObj.opacity = 0;
547
- } else {
548
- transitionObj.opacity = 1;
549
- transitionObj.callback = fn;
550
- }
551
-
552
- self.styleQueue.push( transitionObj );
553
- self._layoutList.push( $item[0] );
554
- });
555
-
556
- // `_layout` always happens after `_shrink`, so it's safe to process the style
557
- // queue here with styles from the shrink method
558
- self._processStyleQueue();
559
-
560
- // Adjust the height of the container
561
- self._setContainerSize();
562
- },
563
-
564
- // Reset columns.
565
- _resetCols : function() {
566
- var i = this.cols;
567
- this.colYs = [];
568
- while (i--) {
569
- this.colYs.push( 0 );
570
- }
571
- },
572
-
573
- _reLayout : function() {
574
- this._resetCols();
575
-
576
- // If we've already sorted the elements, keep them sorted
577
- if ( this.lastSort ) {
578
- this.sort( this.lastSort, true );
579
- } else {
580
- this._layout( this.$items.filter('.filtered').get(), this._filterEnd );
581
- }
582
- },
583
-
584
- _getItemPosition : function( $item ) {
585
- var self = this;
586
- var itemWidth = self._getOuterWidth( $item[0], true );
587
- var columnSpan = itemWidth / self.colWidth;
588
-
589
- // If the difference between the rounded column span number and the
590
- // calculated column span number is really small, round the number to
591
- // make it fit.
592
- if ( Math.abs(Math.round(columnSpan) - columnSpan) < 0.03 ) {
593
- // e.g. columnSpan = 4.0089945390298745
594
- columnSpan = Math.round( columnSpan );
595
- }
596
-
597
- // How many columns does this item span. Ensure it's not more than the
598
- // amount of columns in the whole layout.
599
- var colSpan = Math.min( Math.ceil(columnSpan), self.cols );
600
-
601
- // The item spans only one column.
602
- if ( colSpan === 1 ) {
603
- return self._placeItem( $item, self.colYs );
604
-
605
- // The item spans more than one column, figure out how many different
606
- // places it could fit horizontally
607
- } else {
608
- var groupCount = self.cols + 1 - colSpan,
609
- groupY = [],
610
- groupColY,
611
- i;
612
-
613
- // for each group potential horizontal position
614
- for ( i = 0; i < groupCount; i++ ) {
615
- // make an array of colY values for that one group
616
- groupColY = self.colYs.slice( i, i + colSpan );
617
- // and get the max value of the array
618
- groupY[i] = Math.max.apply( Math, groupColY );
619
- }
620
-
621
- return self._placeItem( $item, groupY );
622
- }
623
- },
624
-
625
- // worker method that places item in the columnSet with the the minY
626
- _placeItem : function( $item, setY ) {
627
- // get the minimum Y value from the columns
628
- var self = this,
629
- minimumY = Math.min.apply( Math, setY ),
630
- shortCol = 0;
631
-
632
- // Find index of short column, the first from the left where this item will go
633
- // if ( setY[i] === minimumY ) requires items' height to be exact every time.
634
- // The buffer value is very useful when the height is a percentage of the width
635
- for (var i = 0, len = setY.length; i < len; i++) {
636
- if ( setY[i] >= minimumY - self.buffer && setY[i] <= minimumY + self.buffer ) {
637
- shortCol = i;
638
- break;
639
- }
640
- }
641
-
642
- // Position the item
643
- var position = {
644
- x: Math.round( (self.colWidth * shortCol) + self.offset.left ),
645
- y: Math.round( minimumY + self.offset.top )
646
- };
647
-
648
- // Apply setHeight to necessary columns
649
- var setHeight = minimumY + self._getOuterHeight( $item[0], true ),
650
- setSpan = self.cols + 1 - len;
651
- for ( i = 0; i < setSpan; i++ ) {
652
- self.colYs[ shortCol + i ] = setHeight;
653
- }
654
-
655
- return position;
656
- },
657
-
658
- /**
659
- * Hides the elements that don't match our filter.
660
- * @param {jQuery} $collection jQuery collection to shrink.
661
- * @param {Function} fn Callback function.
662
- * @private
663
- */
664
- _shrink : function( $collection, fn ) {
665
- var self = this,
666
- $concealed = $collection || self.$items.filter('.concealed');
667
-
668
- fn = fn || self._shrinkEnd;
669
-
670
- // Abort if no items
671
- if ( !$concealed.length ) {
672
- return;
673
- }
674
-
675
- self._fire( Shuffle.EventType.SHRINK );
676
-
677
- $concealed.each(function() {
678
- var $item = $(this);
679
- var itemData = $item.data();
680
- var alreadyShrunk = itemData.scale === CONCEALED_SCALE;
681
-
682
- // Continuing would add a transitionend event listener to the element, but
683
- // that listener would execute because the transform and opacity would
684
- // stay the same.
685
- if ( alreadyShrunk ) {
686
- return;
687
- }
688
-
689
- var transitionObj = {
690
- $item: $item,
691
- x: itemData.position.x,
692
- y: itemData.position.y,
693
- scale : CONCEALED_SCALE,
694
- opacity: 0,
695
- callback: fn
696
- };
697
-
698
- self.styleQueue.push( transitionObj );
699
- self._shrinkList.push( $item[0] );
700
- });
701
- },
702
-
703
- _onResize : function() {
704
- // If shuffle is disabled, destroyed, don't do anything
705
- if ( !this.enabled || this.destroyed ) {
706
- return;
707
- }
708
-
709
- // Will need to check height in the future if it's layed out horizontaly
710
- var containerWidth = this._getOuterWidth(this.$el[0]);
711
-
712
- // containerWidth hasn't changed, don't do anything
713
- if ( containerWidth === this.containerWidth ) {
714
- return;
715
- }
716
-
717
- this.resized();
718
- },
719
- /**
720
- * If the browser has 3d transforms available, build a string with those,
721
- * otherwise use 2d transforms.
722
- * @param {number} x X position.
723
- * @param {number} y Y position.
724
- * @param {number} scale Scale amount.
725
- * @return {string} A normalized string which can be used with the transform style.
726
- * @private
727
- */
728
- _getItemTransformString : function(x, y, scale) {
729
- if ( HAS_TRANSFORMS_3D ) {
730
- return 'translate3d(' + x + 'px, ' + y + 'px, 0) scale3d(' + scale + ', ' + scale + ', 1)';
731
- } else {
732
- return 'translate(' + x + 'px, ' + y + 'px) scale(' + scale + ', ' + scale + ')';
733
- }
734
- },
735
-
736
- _getStylesForTransition : function( opts ) {
737
-
738
- var styles = {
739
- opacity: opts.opacity
740
- };
741
-
742
- if ( this.supported ) {
743
- if ( opts.x !== undefined ) {
744
- styles[ TRANSFORM ] = this._getItemTransformString( opts.x, opts.y, opts.scale );
745
- }
746
- } else {
747
- styles.left = opts.x;
748
- styles.top = opts.y;
749
- }
750
- // Show the item if its opacity will be 1.
751
- if ( opts.opacity === 1 ) {
752
- styles.visibility = 'visible';
753
- }
754
-
755
- return styles;
756
- },
757
-
758
- /**
759
- * Transitions an item in the grid
760
- *
761
- * @param {Object} opts options
762
- * @param {jQuery} opts.$item jQuery object representing the current item
763
- * @param {number} opts.x translate's x
764
- * @param {number} opts.y translate's y
765
- * @param {number} opts.scale amount to scale the item
766
- * @param {number} opts.opacity opacity of the item
767
- * @param {Function} opts.callback complete function for the animation
768
- * @private
769
- */
770
- _transition : function( opts ) {
771
- opts.$item.data('scale', opts.scale);
772
-
773
- var styles = this._getStylesForTransition( opts );
774
- this._startItemAnimation( opts.$item, styles, opts.callback );
775
- },
776
- _startItemAnimation : function( $item, styles, callback ) {
777
- var willBeVisible = styles.opacity === 1;
778
- var complete = $.proxy( this._handleItemAnimationEnd, this,
779
- callback || $.noop, $item[0], willBeVisible );
780
-
781
- // Use CSS Transforms if we have them
782
- if ( this.supported ) {
783
-
784
- $item.css( styles );
785
-
786
- // Transitions are not set until shuffle has loaded to avoid the initial transition.
787
- if ( this.initialized ) {
788
- // Namespaced because the reveal appended function also wants to know
789
- // about the transition end event.
790
- $item.on( TRANSITIONEND + '.shuffleitem', complete );
791
- } else {
792
- complete();
793
- }
794
-
795
- // Use jQuery to animate left/top
796
- } else {
797
- // jQuery cannot animate visibility, set it immediately.
798
- if ( 'visibility' in styles ) {
799
- $item.css('visibility', styles.visibility);
800
- delete styles.visibility;
801
- }
802
- $item.stop( true ).animate( styles, this.speed, 'swing', complete );
803
- }
804
- },
805
- _handleItemAnimationEnd : function( callback, item, willBeVisible, evt ) {
806
- // Make sure this event handler has not bubbled up from a child.
807
- if ( evt ) {
808
- if ( evt.target === item ) {
809
- $( item ).off( '.shuffleitem' );
810
- } else {
811
- return;
812
- }
813
- }
814
-
815
- if ( this._layoutList.length > 0 && $.inArray( item, this._layoutList ) > -1 ) {
816
- this._fire( Shuffle.EventType.LAYOUT );
817
- callback.call( this );
818
- this._layoutList.length = 0;
819
- } else if ( this._shrinkList.length > 0 && $.inArray( item, this._shrinkList ) > -1 ) {
820
- callback.call( this );
821
- this._shrinkList.length = 0;
822
- }
823
-
824
- if ( !willBeVisible ) {
825
- item.style.visibility = 'hidden';
826
- }
827
- },
828
-
829
- _processStyleQueue : function() {
830
- var self = this;
831
-
832
- $.each(this.styleQueue, function(i, transitionObj) {
833
-
834
- if ( transitionObj.skipTransition ) {
835
- self._skipTransition(transitionObj.$item[0], function() {
836
- transitionObj.$item.css( self._getStylesForTransition( transitionObj ) );
837
- });
838
- } else {
839
- self._transition( transitionObj );
840
- }
841
- });
842
-
843
- // Remove everything in the style queue
844
- self.styleQueue.length = 0;
845
- },
846
-
847
- _shrinkEnd : function() {
848
- this._fire( Shuffle.EventType.SHRUNK );
849
- },
850
-
851
- _filterEnd : function() {
852
- this._fire( Shuffle.EventType.FILTERED );
853
- },
854
-
855
- _sortEnd : function() {
856
- this._fire( Shuffle.EventType.SORTED );
857
- },
858
-
859
- /**
860
- * Change a property or execute a function which will not have a transition
861
- * @param {Element} element DOM element that won't be transitioned
862
- * @param {(string|Function)} property The new style property which will be set or a function which will be called
863
- * @param {string} [value] The value that `property` should be.
864
- * @private
865
- */
866
- _skipTransition : function( element, property, value ) {
867
- var duration = element.style[ TRANSITION_DURATION ];
868
-
869
- // Set the duration to zero so it happens immediately
870
- element.style[ TRANSITION_DURATION ] = '0ms'; // ms needed for firefox!
871
-
872
- if ( $.isFunction( property ) ) {
873
- property();
874
- } else {
875
- element.style[ property ] = value;
876
- }
877
-
878
- // Force reflow
879
- var reflow = element.offsetWidth;
880
- // Avoid jshint warnings: unused variables and expressions.
881
- reflow = null;
882
-
883
- // Put the duration back
884
- element.style[ TRANSITION_DURATION ] = duration;
885
- },
886
-
887
- _addItems : function( $newItems, animateIn, isSequential ) {
888
- var self = this;
889
-
890
- if ( !self.supported ) {
891
- animateIn = false;
892
- }
893
-
894
- $newItems.addClass('shuffle-item');
895
- self._initItems( $newItems );
896
- self._setTransitions( $newItems );
897
- self.$items = self._getItems();
898
-
899
- // Hide all items
900
- $newItems.css('opacity', 0);
901
-
902
- // Get ones that passed the current filter
903
- var $passed = self._filter( undefined, $newItems );
904
- var passed = $passed.get();
905
-
906
- // How many filtered elements?
907
- self._updateItemCount();
908
-
909
- if ( animateIn ) {
910
- self._layout( passed, null, true );
911
-
912
- if ( isSequential ) {
913
- self._setSequentialDelay( $passed );
914
- }
915
-
916
- self._revealAppended( $passed );
917
- } else {
918
- self._layout( passed );
919
- }
920
- },
921
-
922
- _revealAppended : function( $newFilteredItems ) {
923
- var self = this;
924
-
925
- setTimeout(function() {
926
- $newFilteredItems.each(function(i, el) {
927
- self._transition({
928
- $item: $(el),
929
- opacity: 1,
930
- scale: DEFAULT_SCALE
931
- });
932
- });
933
- }, self.revealAppendedDelay);
934
- },
935
- /**
936
- * Public Methods
937
- */
938
-
939
- /**
940
- * The magic. This is what makes the plugin 'shuffle'
941
- * @param {(string|Function)} [category] Category to filter by. Can be a function
942
- * @param {Object} [sortObj] A sort object which can sort the filtered set
943
- */
944
- shuffle : function( category, sortObj ) {
945
- var self = this;
946
-
947
- if ( !self.enabled ) {
948
- return;
949
- }
950
-
951
- if ( !category ) {
952
- category = ALL_ITEMS;
953
- }
954
-
955
- self._filter( category );
956
- // Save the last filter in case elements are appended.
957
- self.lastFilter = category;
958
-
959
- // How many filtered elements?
960
- self._updateItemCount();
961
-
962
- // Shrink each concealed item
963
- self._shrink();
964
-
965
- // If given a valid sort object, save it so that _reLayout() will sort the items
966
- if ( sortObj ) {
967
- self.lastSort = sortObj;
968
- }
969
- // Update transforms on .filtered elements so they will animate to their new positions
970
- self._reLayout();
971
- },
972
-
973
- /**
974
- * Gets the .filtered elements, sorts them, and passes them to layout
975
- *
976
- * @param {Object} opts the options object for the sorted plugin
977
- * @param {boolean} [fromFilter] was called from Shuffle.filter method.
978
- */
979
- sort : function( opts, fromFilter ) {
980
- var self = this,
981
- items = self.$items.filter('.filtered').sorted(opts);
982
-
983
- if ( !fromFilter ) {
984
- self._resetCols();
985
- }
986
-
987
- self._layout(items, function() {
988
- if (fromFilter) {
989
- self._filterEnd();
990
- }
991
- self._sortEnd();
992
- });
993
-
994
- self.lastSort = opts;
995
- },
996
-
997
- /**
998
- * Relayout everything
999
- */
1000
- resized : function( isOnlyLayout ) {
1001
- if ( this.enabled ) {
1002
-
1003
- if ( !isOnlyLayout ) {
1004
- // Get updated colCount
1005
- this._setColumns();
1006
- }
1007
-
1008
- // Layout items
1009
- this._reLayout();
1010
- }
1011
- },
1012
-
1013
- /**
1014
- * Use this instead of `update()` if you don't need the columns and gutters updated
1015
- * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations
1016
- * could be off.
1017
- */
1018
- layout : function() {
1019
- this.update( true );
1020
- },
1021
-
1022
- update : function( isOnlyLayout ) {
1023
- this.resized( isOnlyLayout );
1024
- },
1025
-
1026
- /**
1027
- * New items have been appended to shuffle. Fade them in sequentially
1028
- * @param {jQuery} $newItems jQuery collection of new items
1029
- * @param {boolean} [animateIn] If false, the new items won't animate in
1030
- * @param {boolean} [isSequential] If false, new items won't sequentially fade in
1031
- */
1032
- appended : function( $newItems, animateIn, isSequential ) {
1033
- // True if undefined
1034
- animateIn = animateIn === false ? false : true;
1035
- isSequential = isSequential === false ? false : true;
1036
-
1037
- this._addItems( $newItems, animateIn, isSequential );
1038
- },
1039
-
1040
- /**
1041
- * Disables shuffle from updating dimensions and layout on resize
1042
- */
1043
- disable : function() {
1044
- this.enabled = false;
1045
- },
1046
-
1047
- /**
1048
- * Enables shuffle again
1049
- * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters
1050
- */
1051
- enable : function( isUpdateLayout ) {
1052
- this.enabled = true;
1053
- if ( isUpdateLayout !== false ) {
1054
- this.update();
1055
- }
1056
- },
1057
-
1058
- /**
1059
- * Remove 1 or more shuffle items
1060
- * @param {jQuery} $collection A jQuery object containing one or more element in shuffle
1061
- * @return {Shuffle} The shuffle object
1062
- */
1063
- remove : function( $collection ) {
1064
-
1065
- // If this isn't a jquery object, exit
1066
- if ( !$collection.length || !$collection.jquery ) {
1067
- return;
1068
- }
1069
-
1070
- var self = this;
1071
-
1072
- // Hide collection first
1073
- self._shrink( $collection, function() {
1074
- var shuffle = this;
1075
-
1076
- // Remove the collection in the callback
1077
- $collection.remove();
1078
-
1079
- // Update the items, layout, count and fire off `removed` event
1080
- setTimeout(function() {
1081
- shuffle.$items = shuffle._getItems();
1082
- shuffle.layout();
1083
- shuffle._updateItemCount();
1084
- shuffle._fire( Shuffle.EventType.REMOVED, [ $collection, shuffle ] );
1085
-
1086
- // Let it get garbage collected
1087
- $collection = null;
1088
- }, 0);
1089
- });
1090
-
1091
- // Process changes
1092
- self._processStyleQueue();
1093
-
1094
- return self;
1095
- },
1096
-
1097
- /**
1098
- * Destroys shuffle, removes events, styles, and classes
1099
- */
1100
- destroy : function() {
1101
- var self = this;
1102
-
1103
- // If there is more than one shuffle instance on the page,
1104
- // removing the resize handler from the window would remove them
1105
- // all. This is why a unique value is needed.
1106
- self.$window.off('.' + self.unique);
1107
-
1108
- // Reset container styles
1109
- self.$el
1110
- .removeClass( SHUFFLE )
1111
- .removeAttr('style')
1112
- .removeData( SHUFFLE );
1113
-
1114
- // Reset individual item styles
1115
- self.$items
1116
- .removeAttr('style')
1117
- .removeClass('concealed filtered shuffle-item');
1118
-
1119
- // Null DOM references
1120
- self.$window = null;
1121
- self.$items = null;
1122
- self.$el = null;
1123
- self.$sizer = null;
1124
- self.sizer = null;
1125
-
1126
- // Set a flag so if a debounced resize has been triggered,
1127
- // it can first check if it is actually destroyed and not doing anything
1128
- self.destroyed = true;
1129
- }
1130
- };
1131
- // Overrideable options
1132
- Shuffle.options = {
1133
- group: ALL_ITEMS, // Filter group
1134
- speed: 250, // Transition/animation speed (milliseconds)
1135
- easing: 'ease-out', // css easing function to use
1136
- itemSelector: '', // e.g. '.picture-item'
1137
- sizer: null, // sizer element. Can be anything columnWidth is
1138
- gutterWidth: 0, // a static number or function that tells the plugin how wide the gutters between columns are (in pixels)
1139
- columnWidth: 0, // a static number or function that returns a number which tells the plugin how wide the columns are (in pixels)
1140
- delimeter: null, // if your group is not json, and is comma delimeted, you could set delimeter to ','
1141
- buffer: 0, // useful for percentage based heights when they might not always be exactly the same (in pixels)
1142
- initialSort: null, // Shuffle can be initialized with a sort object. It is the same object given to the sort method
1143
- throttle: throttle, // By default, shuffle will try to throttle the resize event. This option will change the method it uses
1144
- throttleTime: 300, // How often shuffle can be called on resize (in milliseconds)
1145
- sequentialFadeDelay: 150, // Delay between each item that fades in when adding items
1146
- supported: CAN_TRANSITION_TRANSFORMS // supports transitions and transforms
1147
- };
1148
- // Not overrideable
1149
- Shuffle.settings = {
1150
- $sizer: null,
1151
- useSizer: false,
1152
- itemCss : { // default CSS for each item
1153
- position: 'absolute',
1154
- top: 0,
1155
- left: 0
1156
- },
1157
- offset: { top: 0, left: 0 },
1158
- revealAppendedDelay: 300,
1159
- enabled: true,
1160
- destroyed: false,
1161
- initialized: false,
1162
- styleQueue: []
1163
- };
1164
- // Plugin definition
1165
- $.fn.shuffle = function( opts ) {
1166
- var args = Array.prototype.slice.call( arguments, 1 );
1167
- return this.each(function() {
1168
- var $this = $( this ),
1169
- shuffle = $this.data( SHUFFLE );
1170
-
1171
- // If we don't have a stored shuffle, make a new one and save it
1172
- if ( !shuffle ) {
1173
- shuffle = new Shuffle( $this, opts );
1174
- $this.data( SHUFFLE, shuffle );
1175
- }
1176
-
1177
- if ( typeof opts === 'string' && shuffle[ opts ] ) {
1178
- shuffle[ opts ].apply( shuffle, args );
1179
- }
1180
- });
1181
- };
1182
- // You can return `undefined` from the `by` function to revert to DOM order
1183
- // This plugin does NOT return a jQuery object. It returns a plain array because
1184
- // jQuery sorts everything in DOM order.
1185
- $.fn.sorted = function(options) {
1186
- var opts = $.extend({}, $.fn.sorted.defaults, options),
1187
- arr = this.get(),
1188
- revert = false;
1189
-
1190
- if ( !arr.length ) {
1191
- return [];
1192
- }
1193
-
1194
- if ( opts.randomize ) {
1195
- return $.fn.sorted.randomize( arr );
1196
- }
1197
-
1198
- // Sort the elements by the opts.by function.
1199
- // If we don't have opts.by, default to DOM order
1200
- if (opts.by !== $.noop && opts.by !== null && opts.by !== undefined) {
1201
- arr.sort(function(a, b) {
1202
-
1203
- // Exit early if we already know we want to revert
1204
- if ( revert ) {
1205
- return 0;
1206
- }
1207
-
1208
- var valA = opts.by($(a)),
1209
- valB = opts.by($(b));
1210
-
1211
- // If both values are undefined, use the DOM order
1212
- if ( valA === undefined && valB === undefined ) {
1213
- revert = true;
1214
- return 0;
1215
- }
1216
-
1217
- if ( valA === 'sortFirst' || valB === 'sortLast' ) {
1218
- return -1;
1219
- }
1220
-
1221
- if ( valA === 'sortLast' || valB === 'sortFirst' ) {
1222
- return 1;
1223
- }
1224
-
1225
- return (valA < valB) ? -1 :
1226
- (valA > valB) ? 1 : 0;
1227
- });
1228
- }
1229
-
1230
- // Revert to the original array if necessary
1231
- if ( revert ) {
1232
- return this.get();
1233
- }
1234
-
1235
- if ( opts.reverse ) {
1236
- arr.reverse();
1237
- }
1238
-
1239
- return arr;
1240
- };
1241
- $.fn.sorted.defaults = {
1242
- reverse: false, // Use array.reverse() to reverse the results
1243
- by: null, // Sorting function
1244
- randomize: false // If true, this will skip the sorting and return a randomized order in the array
1245
- };
1246
- // http://stackoverflow.com/a/962890/373422
1247
- $.fn.sorted.randomize = function( array ) {
1248
- var top = array.length,
1249
- tmp, current;
1250
-
1251
- if ( !top ) {
1252
- return array;
1253
- }
1254
-
1255
- while ( --top ) {
1256
- current = Math.floor( Math.random() * (top + 1) );
1257
- tmp = array[ current ];
1258
- array[ current ] = array[ top ];
1259
- array[ top ] = tmp;
1260
- }
1261
-
1262
- return array;
1263
- };
1264
-
1265
- return Shuffle;
1266
-
1267
- });
1
+ /*!
2
+ * Shuffle.js by @Vestride
3
+ * Categorize, sort, and filter a responsive grid of items.
4
+ * Dependencies: jQuery 1.9+, Modernizr 2.6.2+
5
+ * @license MIT license
6
+ * @version 2.1.2
7
+ */
8
+ (function (factory) {
9
+ if (typeof define === 'function' && define.amd) {
10
+ define(['jquery', 'modernizr'], factory);
11
+ } else {
12
+ factory(window.jQuery, window.Modernizr);
13
+ }
14
+ })(function($, Modernizr, undefined) {
15
+
16
+ 'use strict';
17
+ // Validate Modernizr exists.
18
+ // Shuffle requires `csstransitions`, `csstransforms`, `csstransforms3d`,
19
+ // and `prefixed` to exist on the Modernizr object.
20
+ if (typeof Modernizr !== 'object') {
21
+ throw new Error('Shuffle.js requires Modernizr.\n' +
22
+ 'http://vestride.github.io/Shuffle/#dependencies');
23
+ }
24
+ /**
25
+ * Returns css prefixed properties like `-webkit-transition` or `box-sizing`
26
+ * from `transition` or `boxSizing`, respectively.
27
+ * @param {(string|boolean)} prop Property to be prefixed.
28
+ * @return {string} The prefixed css property.
29
+ */
30
+ function dashify( prop ) {
31
+ if (!prop) {
32
+ return '';
33
+ }
34
+
35
+ // Replace upper case with dash-lowercase,
36
+ // then fix ms- prefixes because they're not capitalized.
37
+ return prop.replace(/([A-Z])/g, function( str, m1 ) {
38
+ return '-' + m1.toLowerCase();
39
+ }).replace(/^ms-/,'-ms-');
40
+ }
41
+
42
+ // Constant, prefixed variables.
43
+ var TRANSITION = Modernizr.prefixed('transition');
44
+ var TRANSITION_DELAY = Modernizr.prefixed('transitionDelay');
45
+ var TRANSITION_DURATION = Modernizr.prefixed('transitionDuration');
46
+ var TRANSITIONEND = {
47
+ 'WebkitTransition' : 'webkitTransitionEnd',
48
+ 'transition' : 'transitionend'
49
+ }[ TRANSITION ];
50
+ var TRANSFORM = Modernizr.prefixed('transform');
51
+ var CSS_TRANSFORM = dashify(TRANSFORM);
52
+
53
+ // Constants
54
+ var CAN_TRANSITION_TRANSFORMS = Modernizr.csstransforms && Modernizr.csstransitions;
55
+ var HAS_TRANSFORMS_3D = Modernizr.csstransforms3d;
56
+ var SHUFFLE = 'shuffle';
57
+
58
+ // Configurable. You can change these constants to fit your application.
59
+ // The default scale and concealed scale, however, have to be different values.
60
+ var ALL_ITEMS = 'all';
61
+ var FILTER_ATTRIBUTE_KEY = 'groups';
62
+ var DEFAULT_SCALE = 1;
63
+ var CONCEALED_SCALE = 0.001;
64
+ // Underscore's throttle function.
65
+ function throttle(func, wait, options) {
66
+ var context, args, result;
67
+ var timeout = null;
68
+ var previous = 0;
69
+ options = options || {};
70
+ var later = function() {
71
+ previous = options.leading === false ? 0 : $.now();
72
+ timeout = null;
73
+ result = func.apply(context, args);
74
+ context = args = null;
75
+ };
76
+ return function() {
77
+ var now = $.now();
78
+ if (!previous && options.leading === false) {
79
+ previous = now;
80
+ }
81
+ var remaining = wait - (now - previous);
82
+ context = this;
83
+ args = arguments;
84
+ if (remaining <= 0 || remaining > wait) {
85
+ clearTimeout(timeout);
86
+ timeout = null;
87
+ previous = now;
88
+ result = func.apply(context, args);
89
+ context = args = null;
90
+ } else if (!timeout && options.trailing !== false) {
91
+ timeout = setTimeout(later, remaining);
92
+ }
93
+ return result;
94
+ };
95
+ }
96
+
97
+ // Used for unique instance variables
98
+ var id = 0;
99
+ /**
100
+ * Categorize, sort, and filter a responsive grid of items.
101
+ *
102
+ * @param {Element|jQuery} element An element or a jQuery collection which
103
+ * is the parent container for the grid items.
104
+ * @param {Object} [options=Shuffle.options] Options object.
105
+ * @constructor
106
+ */
107
+ var Shuffle = function( element, options ) {
108
+ options = options || {};
109
+ $.extend( this, Shuffle.options, options, Shuffle.settings );
110
+
111
+ this.$el = $(element);
112
+ this.$window = $(window);
113
+ this.unique = 'shuffle_' + id++;
114
+
115
+ this._fire( Shuffle.EventType.LOADING );
116
+ this._init();
117
+
118
+ // Dispatch the done event asynchronously so that people can bind to it after
119
+ // Shuffle has been initialized.
120
+ setTimeout( $.proxy(function() {
121
+ this.initialized = true;
122
+ this._fire( Shuffle.EventType.DONE );
123
+ }, this), 16 );
124
+ };
125
+ /**
126
+ * Events the container element emits with the .shuffle namespace.
127
+ * For example, "done.shuffle".
128
+ * @enum {string}
129
+ */
130
+ Shuffle.EventType = {
131
+ LOADING: 'loading',
132
+ DONE: 'done',
133
+ SHRINK: 'shrink',
134
+ SHRUNK: 'shrunk',
135
+ FILTER: 'filter',
136
+ FILTERED: 'filtered',
137
+ SORTED: 'sorted',
138
+ LAYOUT: 'layout',
139
+ REMOVED: 'removed'
140
+ };
141
+ Shuffle.prototype = {
142
+
143
+ _init : function() {
144
+ var self = this,
145
+ containerCSS,
146
+ containerWidth,
147
+ resizeFunction = $.proxy( self._onResize, self ),
148
+ debouncedResize = self.throttle ?
149
+ self.throttle( resizeFunction, self.throttleTime ) :
150
+ resizeFunction,
151
+ sort = self.initialSort ? self.initialSort : null;
152
+ self._layoutList = [];
153
+ self._shrinkList = [];
154
+
155
+ self._setVars();
156
+
157
+ // Zero out all columns
158
+ self._resetCols();
159
+
160
+ // Add classes and invalidate styles
161
+ self._addClasses();
162
+
163
+ // Set initial css for each item
164
+ self._initItems();
165
+
166
+ // Bind resize events
167
+ // http://stackoverflow.com/questions/1852751/window-resize-event-firing-in-internet-explorer
168
+ self.$window.on('resize.' + SHUFFLE + '.' + self.unique, debouncedResize);
169
+
170
+ // Get container css all in one request. Causes reflow
171
+ containerCSS = self.$el.css(['paddingLeft', 'paddingRight', 'position']);
172
+ containerWidth = self._getOuterWidth( self.$el[0] );
173
+
174
+ // Position cannot be static.
175
+ if ( containerCSS.position === 'static' ) {
176
+ self.$el[0].style.position = 'relative';
177
+ }
178
+
179
+ // Get offset from container
180
+ self.offset = {
181
+ left: parseInt( containerCSS.paddingLeft, 10 ) || 0,
182
+ top: parseInt( containerCSS.paddingTop, 10 ) || 0
183
+ };
184
+
185
+ // We already got the container's width above, no need to cause another reflow getting it again...
186
+ // Calculate the number of columns there will be
187
+ self._setColumns( parseInt( containerWidth, 10 ) );
188
+
189
+ // Kick off!
190
+ self.shuffle( self.group, sort );
191
+
192
+ // The shuffle items haven't had transitions set on them yet
193
+ // so the user doesn't see the first layout. Set them now that the first layout is done.
194
+ if ( self.supported ) {
195
+ setTimeout(function() {
196
+ self._setTransitions();
197
+ self.$el[0].style[ TRANSITION ] = 'height ' + self.speed + 'ms ' + self.easing;
198
+ }, 0);
199
+ }
200
+ },
201
+
202
+ // Will invalidate styles
203
+ _addClasses : function() {
204
+ this.$el.addClass( SHUFFLE );
205
+ this.$items.addClass('shuffle-item filtered');
206
+ },
207
+
208
+ _setVars : function() {
209
+ var self = this,
210
+ columnWidth = self.columnWidth;
211
+
212
+ self.$items = self._getItems();
213
+
214
+ // Column width is the default setting and sizer is not (meaning passed in)
215
+ // Assume they meant column width to be the sizer
216
+ if ( columnWidth === 0 && self.sizer !== null ) {
217
+ columnWidth = self.sizer;
218
+ }
219
+
220
+ // If column width is a string, treat is as a selector and search for the
221
+ // sizer element within the outermost container
222
+ if ( typeof columnWidth === 'string' ) {
223
+ self.$sizer = self.$el.find( columnWidth );
224
+
225
+ // Check for an element
226
+ } else if ( columnWidth && columnWidth.nodeType && columnWidth.nodeType === 1 ) {
227
+ // Wrap it in jQuery
228
+ self.$sizer = $( columnWidth );
229
+
230
+ // Check for jQuery object
231
+ } else if ( columnWidth && columnWidth.jquery ) {
232
+ self.$sizer = columnWidth;
233
+ }
234
+
235
+ if ( self.$sizer && self.$sizer.length ) {
236
+ self.useSizer = true;
237
+ self.sizer = self.$sizer[0];
238
+ }
239
+ },
240
+ /**
241
+ * Filter the elements by a category.
242
+ * @param {string} [category] Category to filter by. If it's given, the last
243
+ * category will be used to filter the items.
244
+ * @param {jQuery} [$collection] Optionally filter a collection. Defaults to
245
+ * all the items.
246
+ * @return {jQuery} Filtered items.
247
+ */
248
+ _filter : function( category, $collection ) {
249
+ var self = this,
250
+ isPartialSet = $collection !== undefined,
251
+ $items = isPartialSet ? $collection : self.$items,
252
+ $filtered = $();
253
+
254
+ category = category || self.lastFilter;
255
+
256
+ self._fire( Shuffle.EventType.FILTER );
257
+
258
+ // Loop through each item and use provided function to determine
259
+ // whether to hide it or not.
260
+ if ( $.isFunction( category ) ) {
261
+ $items.each(function() {
262
+ var $item = $(this);
263
+ if ( category.call($item[0], $item, self) ) {
264
+ $filtered = $filtered.add( $item );
265
+ }
266
+ });
267
+
268
+ // Otherwise we've been passed a category to filter by
269
+ } else {
270
+ self.group = category;
271
+
272
+ // category === 'all', add filtered class to everything
273
+ if ( category === ALL_ITEMS ) {
274
+ $filtered = $items;
275
+
276
+ // Check each element's data-groups attribute against the given category.
277
+ } else {
278
+ $items.each(function() {
279
+ var $item = $(this),
280
+ groups = $item.data( FILTER_ATTRIBUTE_KEY ),
281
+ keys = self.delimeter && !$.isArray( groups ) ?
282
+ groups.split( self.delimeter ) :
283
+ groups;
284
+
285
+ if ( $.inArray(category, keys) > -1 ) {
286
+ $filtered = $filtered.add( $item );
287
+ }
288
+ });
289
+ }
290
+ }
291
+
292
+ // Individually add/remove concealed/filtered classes
293
+ self._toggleFilterClasses( $items, $filtered );
294
+
295
+ $items = null;
296
+ $collection = null;
297
+
298
+ return $filtered;
299
+ },
300
+ _toggleFilterClasses : function( $items, $filtered ) {
301
+ var concealed = 'concealed',
302
+ filtered = 'filtered';
303
+
304
+ $items.filter( $filtered ).each(function() {
305
+ var $filteredItem = $(this);
306
+ // Remove concealed if it's there
307
+ if ( $filteredItem.hasClass( concealed ) ) {
308
+ $filteredItem.removeClass( concealed );
309
+ }
310
+ // Add filtered class if it's not there
311
+ if ( !$filteredItem.hasClass( filtered ) ) {
312
+ $filteredItem.addClass( filtered );
313
+ }
314
+ });
315
+
316
+ $items.not( $filtered ).each(function() {
317
+ var $filteredItem = $(this);
318
+ // Add concealed if it's not there
319
+ if ( !$filteredItem.hasClass( concealed ) ) {
320
+ $filteredItem.addClass( concealed );
321
+ }
322
+ // Remove filtered class if it's there
323
+ if ( $filteredItem.hasClass( filtered ) ) {
324
+ $filteredItem.removeClass( filtered );
325
+ }
326
+ });
327
+ },
328
+
329
+ /**
330
+ * Set the initial css for each item
331
+ * @param {jQuery} [$items] Optionally specifiy at set to initialize
332
+ */
333
+ _initItems : function( $items ) {
334
+ $items = $items || this.$items;
335
+ $items.css( this.itemCss ).data('position', {x: 0, y: 0});
336
+ },
337
+
338
+ _updateItemCount : function() {
339
+ this.visibleItems = this.$items.filter('.filtered').length;
340
+ },
341
+
342
+ _setTransition : function( element ) {
343
+ element.style[ TRANSITION ] = CSS_TRANSFORM + ' ' + this.speed + 'ms ' + this.easing;
344
+ },
345
+
346
+ _setTransitions : function( $items ) {
347
+ var self = this;
348
+
349
+ $items = $items || self.$items;
350
+ $items.each(function() {
351
+ self._setTransition( this );
352
+ });
353
+ },
354
+
355
+ _setSequentialDelay : function( $collection ) {
356
+ var self = this;
357
+
358
+ if ( !self.supported ) {
359
+ return;
360
+ }
361
+
362
+ // $collection can be an array of dom elements or jquery object
363
+ $.each($collection, function(i, el) {
364
+ // This works because the transition-property: transform, opacity;
365
+ el.style[ TRANSITION_DELAY ] = '0ms,' + ((i + 1) * self.sequentialFadeDelay) + 'ms';
366
+
367
+ // Set the delay back to zero after one transition
368
+ $(el).on(TRANSITIONEND + '.' + self.unique, function(evt) {
369
+ var target = evt.currentTarget;
370
+ if ( target === evt.target ) {
371
+ target.style[ TRANSITION_DELAY ] = '0ms';
372
+ $(target).off(TRANSITIONEND + '.' + self.unique);
373
+ }
374
+ });
375
+ });
376
+ },
377
+
378
+ _getItems : function() {
379
+ return this.$el.children( this.itemSelector );
380
+ },
381
+
382
+ _getPreciseDimension : function( element, style ) {
383
+ var dimension;
384
+ if ( window.getComputedStyle ) {
385
+ dimension = window.getComputedStyle( element, null )[ style ];
386
+ } else {
387
+ dimension = $( element ).css( style );
388
+ }
389
+ return parseFloat( dimension );
390
+ },
391
+ /**
392
+ * Returns the outer width of an element, optionally including its margins.
393
+ * @param {Element} element The element.
394
+ * @param {boolean} [includeMargins] Whether to include margins. Default is false.
395
+ * @return {number} The width.
396
+ */
397
+ _getOuterWidth : function( element, includeMargins ) {
398
+ var width = element.offsetWidth;
399
+
400
+ // Use jQuery here because it uses getComputedStyle internally and is
401
+ // cross-browser. Using the style property of the element will only work
402
+ // if there are inline styles.
403
+ if (includeMargins) {
404
+ var styles = $(element).css(['marginLeft', 'marginRight']);
405
+
406
+ // Defaults to zero if parsing fails because IE will return 'auto' when
407
+ // the element doesn't have margins instead of the computed style.
408
+ var marginLeft = parseFloat(styles.marginLeft) || 0;
409
+ var marginRight = parseFloat(styles.marginRight) || 0;
410
+ width += marginLeft + marginRight;
411
+ }
412
+
413
+ return width;
414
+ },
415
+ /**
416
+ * Returns the outer height of an element, optionally including its margins.
417
+ * @param {Element} element The element.
418
+ * @param {boolean} [includeMargins] Whether to include margins. Default is false.
419
+ * @return {number} The height.
420
+ */
421
+ _getOuterHeight : function( element, includeMargins ) {
422
+ var height = element.offsetHeight;
423
+
424
+ if (includeMargins) {
425
+ var styles = $(element).css(['marginTop', 'marginBottom']);
426
+ var marginTop = parseFloat(styles.marginTop) || 0;
427
+ var marginBottom = parseFloat(styles.marginBottom) || 0;
428
+ height += marginTop + marginBottom;
429
+ }
430
+
431
+ return height;
432
+ },
433
+ _getColumnSize : function( gutterSize, containerWidth ) {
434
+ var size;
435
+
436
+ // If the columnWidth property is a function, then the grid is fluid
437
+ if ( $.isFunction( this.columnWidth ) ) {
438
+ size = this.columnWidth(containerWidth);
439
+
440
+ // columnWidth option isn't a function, are they using a sizing element?
441
+ } else if ( this.useSizer ) {
442
+ size = this._getPreciseDimension(this.sizer, 'width');
443
+
444
+ // if not, how about the explicitly set option?
445
+ } else if ( this.columnWidth ) {
446
+ size = this.columnWidth;
447
+
448
+ // or use the size of the first item
449
+ } else if ( this.$items.length > 0 ) {
450
+ size = this._getOuterWidth(this.$items[0], true);
451
+
452
+ // if there's no items, use size of container
453
+ } else {
454
+ size = containerWidth;
455
+ }
456
+
457
+ // Don't let them set a column width of zero.
458
+ if ( size === 0 ) {
459
+ size = containerWidth;
460
+ }
461
+
462
+ return size + gutterSize;
463
+ },
464
+ _getGutterSize : function( containerWidth ) {
465
+ var size;
466
+ if ( $.isFunction( this.gutterWidth ) ) {
467
+ size = this.gutterWidth(containerWidth);
468
+ } else if ( this.useSizer ) {
469
+ size = this._getPreciseDimension(this.sizer, 'marginLeft');
470
+ } else {
471
+ size = this.gutterWidth;
472
+ }
473
+
474
+ return size;
475
+ },
476
+ /**
477
+ * Calculate the number of columns to be used. Gets css if using sizer element.
478
+ * @param {number} [theContainerWidth] Optionally specify a container width if it's already available.
479
+ */
480
+ _setColumns : function( theContainerWidth ) {
481
+ var containerWidth = theContainerWidth || this._getOuterWidth(this.$el[0]);
482
+ var gutter = this._getGutterSize(containerWidth);
483
+ var columnWidth = this._getColumnSize(gutter, containerWidth);
484
+ var calculatedColumns = (containerWidth + gutter) / columnWidth;
485
+
486
+ // Widths given from getComputedStyle are not precise enough...
487
+ if ( Math.abs(Math.round(calculatedColumns) - calculatedColumns) < 0.03 ) {
488
+ // e.g. calculatedColumns = 11.998876
489
+ calculatedColumns = Math.round( calculatedColumns );
490
+ }
491
+
492
+ this.cols = Math.max( Math.floor(calculatedColumns), 1 );
493
+ this.containerWidth = containerWidth;
494
+ this.colWidth = columnWidth;
495
+ },
496
+
497
+ /**
498
+ * Adjust the height of the grid
499
+ */
500
+ _setContainerSize : function() {
501
+ this.$el.css( 'height', Math.max.apply( Math, this.colYs ) );
502
+ },
503
+
504
+ /**
505
+ * Fire events with .shuffle namespace
506
+ */
507
+ _fire : function( name, args ) {
508
+ this.$el.trigger( name + '.' + SHUFFLE, args && args.length ? args : [ this ] );
509
+ },
510
+ /**
511
+ * Loops through each item that should be shown and calculates the x, y position.
512
+ * @param {Array.<Element>} items Array of items that will be shown/layed out in order in their array.
513
+ * Because jQuery collection are always ordered in DOM order, we can't pass a jq collection.
514
+ * @param {function} fn Callback function.
515
+ * @param {boolean} isOnlyPosition If true this will position the items with zero opacity.
516
+ */
517
+ _layout : function( items, fn, isOnlyPosition ) {
518
+ var self = this;
519
+
520
+ fn = fn || self._filterEnd;
521
+
522
+ $.each(items, function(index, item) {
523
+ var $item = $(item);
524
+ var itemData = $item.data();
525
+ var currPos = itemData.position;
526
+ var pos = self._getItemPosition( $item );
527
+
528
+ // Save data for shrink
529
+ $item.data( 'position', pos );
530
+
531
+ // If the item will not change its position, do not add it to the render
532
+ // queue. Transitions don't fire when setting a property to the same value.
533
+ if ( pos.x === currPos.x && pos.y === currPos.y && itemData.scale === DEFAULT_SCALE ) {
534
+ return;
535
+ }
536
+
537
+ var transitionObj = {
538
+ $item: $item,
539
+ x: pos.x,
540
+ y: pos.y,
541
+ scale: DEFAULT_SCALE
542
+ };
543
+
544
+ if ( isOnlyPosition ) {
545
+ transitionObj.skipTransition = true;
546
+ transitionObj.opacity = 0;
547
+ } else {
548
+ transitionObj.opacity = 1;
549
+ transitionObj.callback = fn;
550
+ }
551
+
552
+ self.styleQueue.push( transitionObj );
553
+ self._layoutList.push( $item[0] );
554
+ });
555
+
556
+ // `_layout` always happens after `_shrink`, so it's safe to process the style
557
+ // queue here with styles from the shrink method
558
+ self._processStyleQueue();
559
+
560
+ // Adjust the height of the container
561
+ self._setContainerSize();
562
+ },
563
+
564
+ // Reset columns.
565
+ _resetCols : function() {
566
+ var i = this.cols;
567
+ this.colYs = [];
568
+ while (i--) {
569
+ this.colYs.push( 0 );
570
+ }
571
+ },
572
+
573
+ _reLayout : function() {
574
+ this._resetCols();
575
+
576
+ // If we've already sorted the elements, keep them sorted
577
+ if ( this.lastSort ) {
578
+ this.sort( this.lastSort, true );
579
+ } else {
580
+ this._layout( this.$items.filter('.filtered').get(), this._filterEnd );
581
+ }
582
+ },
583
+
584
+ _getItemPosition : function( $item ) {
585
+ var self = this;
586
+ var itemWidth = self._getOuterWidth( $item[0], true );
587
+ var columnSpan = itemWidth / self.colWidth;
588
+
589
+ // If the difference between the rounded column span number and the
590
+ // calculated column span number is really small, round the number to
591
+ // make it fit.
592
+ if ( Math.abs(Math.round(columnSpan) - columnSpan) < 0.03 ) {
593
+ // e.g. columnSpan = 4.0089945390298745
594
+ columnSpan = Math.round( columnSpan );
595
+ }
596
+
597
+ // How many columns does this item span. Ensure it's not more than the
598
+ // amount of columns in the whole layout.
599
+ var colSpan = Math.min( Math.ceil(columnSpan), self.cols );
600
+
601
+ // The item spans only one column.
602
+ if ( colSpan === 1 ) {
603
+ return self._placeItem( $item, self.colYs );
604
+
605
+ // The item spans more than one column, figure out how many different
606
+ // places it could fit horizontally
607
+ } else {
608
+ var groupCount = self.cols + 1 - colSpan,
609
+ groupY = [],
610
+ groupColY,
611
+ i;
612
+
613
+ // for each group potential horizontal position
614
+ for ( i = 0; i < groupCount; i++ ) {
615
+ // make an array of colY values for that one group
616
+ groupColY = self.colYs.slice( i, i + colSpan );
617
+ // and get the max value of the array
618
+ groupY[i] = Math.max.apply( Math, groupColY );
619
+ }
620
+
621
+ return self._placeItem( $item, groupY );
622
+ }
623
+ },
624
+
625
+ // worker method that places item in the columnSet with the the minY
626
+ _placeItem : function( $item, setY ) {
627
+ // get the minimum Y value from the columns
628
+ var self = this,
629
+ minimumY = Math.min.apply( Math, setY ),
630
+ shortCol = 0;
631
+
632
+ // Find index of short column, the first from the left where this item will go
633
+ // if ( setY[i] === minimumY ) requires items' height to be exact every time.
634
+ // The buffer value is very useful when the height is a percentage of the width
635
+ for (var i = 0, len = setY.length; i < len; i++) {
636
+ if ( setY[i] >= minimumY - self.buffer && setY[i] <= minimumY + self.buffer ) {
637
+ shortCol = i;
638
+ break;
639
+ }
640
+ }
641
+
642
+ // Position the item
643
+ var position = {
644
+ x: Math.round( (self.colWidth * shortCol) + self.offset.left ),
645
+ y: Math.round( minimumY + self.offset.top )
646
+ };
647
+
648
+ // Apply setHeight to necessary columns
649
+ var setHeight = minimumY + self._getOuterHeight( $item[0], true ),
650
+ setSpan = self.cols + 1 - len;
651
+ for ( i = 0; i < setSpan; i++ ) {
652
+ self.colYs[ shortCol + i ] = setHeight;
653
+ }
654
+
655
+ return position;
656
+ },
657
+
658
+ /**
659
+ * Hides the elements that don't match our filter.
660
+ * @param {jQuery} $collection jQuery collection to shrink.
661
+ * @param {Function} fn Callback function.
662
+ * @private
663
+ */
664
+ _shrink : function( $collection, fn ) {
665
+ var self = this,
666
+ $concealed = $collection || self.$items.filter('.concealed');
667
+
668
+ fn = fn || self._shrinkEnd;
669
+
670
+ // Abort if no items
671
+ if ( !$concealed.length ) {
672
+ return;
673
+ }
674
+
675
+ self._fire( Shuffle.EventType.SHRINK );
676
+
677
+ $concealed.each(function() {
678
+ var $item = $(this);
679
+ var itemData = $item.data();
680
+ var alreadyShrunk = itemData.scale === CONCEALED_SCALE;
681
+
682
+ // Continuing would add a transitionend event listener to the element, but
683
+ // that listener would execute because the transform and opacity would
684
+ // stay the same.
685
+ if ( alreadyShrunk ) {
686
+ return;
687
+ }
688
+
689
+ var transitionObj = {
690
+ $item: $item,
691
+ x: itemData.position.x,
692
+ y: itemData.position.y,
693
+ scale : CONCEALED_SCALE,
694
+ opacity: 0,
695
+ callback: fn
696
+ };
697
+
698
+ self.styleQueue.push( transitionObj );
699
+ self._shrinkList.push( $item[0] );
700
+ });
701
+ },
702
+
703
+ _onResize : function() {
704
+ // If shuffle is disabled, destroyed, don't do anything
705
+ if ( !this.enabled || this.destroyed ) {
706
+ return;
707
+ }
708
+
709
+ // Will need to check height in the future if it's layed out horizontaly
710
+ var containerWidth = this._getOuterWidth(this.$el[0]);
711
+
712
+ // containerWidth hasn't changed, don't do anything
713
+ if ( containerWidth === this.containerWidth ) {
714
+ return;
715
+ }
716
+
717
+ this.resized();
718
+ },
719
+ /**
720
+ * If the browser has 3d transforms available, build a string with those,
721
+ * otherwise use 2d transforms.
722
+ * @param {number} x X position.
723
+ * @param {number} y Y position.
724
+ * @param {number} scale Scale amount.
725
+ * @return {string} A normalized string which can be used with the transform style.
726
+ * @private
727
+ */
728
+ _getItemTransformString : function(x, y, scale) {
729
+ if ( HAS_TRANSFORMS_3D ) {
730
+ return 'translate3d(' + x + 'px, ' + y + 'px, 0) scale3d(' + scale + ', ' + scale + ', 1)';
731
+ } else {
732
+ return 'translate(' + x + 'px, ' + y + 'px) scale(' + scale + ', ' + scale + ')';
733
+ }
734
+ },
735
+
736
+ _getStylesForTransition : function( opts ) {
737
+
738
+ var styles = {
739
+ opacity: opts.opacity
740
+ };
741
+
742
+ if ( this.supported ) {
743
+ if ( opts.x !== undefined ) {
744
+ styles[ TRANSFORM ] = this._getItemTransformString( opts.x, opts.y, opts.scale );
745
+ }
746
+ } else {
747
+ styles.left = opts.x;
748
+ styles.top = opts.y;
749
+ }
750
+ // Show the item if its opacity will be 1.
751
+ if ( opts.opacity === 1 ) {
752
+ styles.visibility = 'visible';
753
+ }
754
+
755
+ return styles;
756
+ },
757
+
758
+ /**
759
+ * Transitions an item in the grid
760
+ *
761
+ * @param {Object} opts options
762
+ * @param {jQuery} opts.$item jQuery object representing the current item
763
+ * @param {number} opts.x translate's x
764
+ * @param {number} opts.y translate's y
765
+ * @param {number} opts.scale amount to scale the item
766
+ * @param {number} opts.opacity opacity of the item
767
+ * @param {Function} opts.callback complete function for the animation
768
+ * @private
769
+ */
770
+ _transition : function( opts ) {
771
+ opts.$item.data('scale', opts.scale);
772
+
773
+ var styles = this._getStylesForTransition( opts );
774
+ this._startItemAnimation( opts.$item, styles, opts.callback );
775
+ },
776
+ _startItemAnimation : function( $item, styles, callback ) {
777
+ var willBeVisible = styles.opacity === 1;
778
+ var complete = $.proxy( this._handleItemAnimationEnd, this,
779
+ callback || $.noop, $item[0], willBeVisible );
780
+
781
+ // Use CSS Transforms if we have them
782
+ if ( this.supported ) {
783
+
784
+ $item.css( styles );
785
+
786
+ // Transitions are not set until shuffle has loaded to avoid the initial transition.
787
+ if ( this.initialized ) {
788
+ // Namespaced because the reveal appended function also wants to know
789
+ // about the transition end event.
790
+ $item.on( TRANSITIONEND + '.shuffleitem', complete );
791
+ } else {
792
+ complete();
793
+ }
794
+
795
+ // Use jQuery to animate left/top
796
+ } else {
797
+ // jQuery cannot animate visibility, set it immediately.
798
+ if ( 'visibility' in styles ) {
799
+ $item.css('visibility', styles.visibility);
800
+ delete styles.visibility;
801
+ }
802
+ $item.stop( true ).animate( styles, this.speed, 'swing', complete );
803
+ }
804
+ },
805
+ _handleItemAnimationEnd : function( callback, item, willBeVisible, evt ) {
806
+ // Make sure this event handler has not bubbled up from a child.
807
+ if ( evt ) {
808
+ if ( evt.target === item ) {
809
+ $( item ).off( '.shuffleitem' );
810
+ } else {
811
+ return;
812
+ }
813
+ }
814
+
815
+ if ( this._layoutList.length > 0 && $.inArray( item, this._layoutList ) > -1 ) {
816
+ this._fire( Shuffle.EventType.LAYOUT );
817
+ callback.call( this );
818
+ this._layoutList.length = 0;
819
+ } else if ( this._shrinkList.length > 0 && $.inArray( item, this._shrinkList ) > -1 ) {
820
+ callback.call( this );
821
+ this._shrinkList.length = 0;
822
+ }
823
+
824
+ if ( !willBeVisible ) {
825
+ item.style.visibility = 'hidden';
826
+ }
827
+ },
828
+
829
+ _processStyleQueue : function() {
830
+ var self = this;
831
+
832
+ $.each(this.styleQueue, function(i, transitionObj) {
833
+
834
+ if ( transitionObj.skipTransition ) {
835
+ self._skipTransition(transitionObj.$item[0], function() {
836
+ transitionObj.$item.css( self._getStylesForTransition( transitionObj ) );
837
+ });
838
+ } else {
839
+ self._transition( transitionObj );
840
+ }
841
+ });
842
+
843
+ // Remove everything in the style queue
844
+ self.styleQueue.length = 0;
845
+ },
846
+
847
+ _shrinkEnd : function() {
848
+ this._fire( Shuffle.EventType.SHRUNK );
849
+ },
850
+
851
+ _filterEnd : function() {
852
+ this._fire( Shuffle.EventType.FILTERED );
853
+ },
854
+
855
+ _sortEnd : function() {
856
+ this._fire( Shuffle.EventType.SORTED );
857
+ },
858
+
859
+ /**
860
+ * Change a property or execute a function which will not have a transition
861
+ * @param {Element} element DOM element that won't be transitioned
862
+ * @param {(string|Function)} property The new style property which will be set or a function which will be called
863
+ * @param {string} [value] The value that `property` should be.
864
+ * @private
865
+ */
866
+ _skipTransition : function( element, property, value ) {
867
+ var duration = element.style[ TRANSITION_DURATION ];
868
+
869
+ // Set the duration to zero so it happens immediately
870
+ element.style[ TRANSITION_DURATION ] = '0ms'; // ms needed for firefox!
871
+
872
+ if ( $.isFunction( property ) ) {
873
+ property();
874
+ } else {
875
+ element.style[ property ] = value;
876
+ }
877
+
878
+ // Force reflow
879
+ var reflow = element.offsetWidth;
880
+ // Avoid jshint warnings: unused variables and expressions.
881
+ reflow = null;
882
+
883
+ // Put the duration back
884
+ element.style[ TRANSITION_DURATION ] = duration;
885
+ },
886
+
887
+ _addItems : function( $newItems, animateIn, isSequential ) {
888
+ var self = this;
889
+
890
+ if ( !self.supported ) {
891
+ animateIn = false;
892
+ }
893
+
894
+ $newItems.addClass('shuffle-item');
895
+ self._initItems( $newItems );
896
+ self._setTransitions( $newItems );
897
+ self.$items = self._getItems();
898
+
899
+ // Hide all items
900
+ $newItems.css('opacity', 0);
901
+
902
+ // Get ones that passed the current filter
903
+ var $passed = self._filter( undefined, $newItems );
904
+ var passed = $passed.get();
905
+
906
+ // How many filtered elements?
907
+ self._updateItemCount();
908
+
909
+ if ( animateIn ) {
910
+ self._layout( passed, null, true );
911
+
912
+ if ( isSequential ) {
913
+ self._setSequentialDelay( $passed );
914
+ }
915
+
916
+ self._revealAppended( $passed );
917
+ } else {
918
+ self._layout( passed );
919
+ }
920
+ },
921
+
922
+ _revealAppended : function( $newFilteredItems ) {
923
+ var self = this;
924
+
925
+ setTimeout(function() {
926
+ $newFilteredItems.each(function(i, el) {
927
+ self._transition({
928
+ $item: $(el),
929
+ opacity: 1,
930
+ scale: DEFAULT_SCALE
931
+ });
932
+ });
933
+ }, self.revealAppendedDelay);
934
+ },
935
+ /**
936
+ * Public Methods
937
+ */
938
+
939
+ /**
940
+ * The magic. This is what makes the plugin 'shuffle'
941
+ * @param {(string|Function)} [category] Category to filter by. Can be a function
942
+ * @param {Object} [sortObj] A sort object which can sort the filtered set
943
+ */
944
+ shuffle : function( category, sortObj ) {
945
+ var self = this;
946
+
947
+ if ( !self.enabled ) {
948
+ return;
949
+ }
950
+
951
+ if ( !category ) {
952
+ category = ALL_ITEMS;
953
+ }
954
+
955
+ self._filter( category );
956
+ // Save the last filter in case elements are appended.
957
+ self.lastFilter = category;
958
+
959
+ // How many filtered elements?
960
+ self._updateItemCount();
961
+
962
+ // Shrink each concealed item
963
+ self._shrink();
964
+
965
+ // If given a valid sort object, save it so that _reLayout() will sort the items
966
+ if ( sortObj ) {
967
+ self.lastSort = sortObj;
968
+ }
969
+ // Update transforms on .filtered elements so they will animate to their new positions
970
+ self._reLayout();
971
+ },
972
+
973
+ /**
974
+ * Gets the .filtered elements, sorts them, and passes them to layout
975
+ *
976
+ * @param {Object} opts the options object for the sorted plugin
977
+ * @param {boolean} [fromFilter] was called from Shuffle.filter method.
978
+ */
979
+ sort : function( opts, fromFilter ) {
980
+ var self = this,
981
+ items = self.$items.filter('.filtered').sorted(opts);
982
+
983
+ if ( !fromFilter ) {
984
+ self._resetCols();
985
+ }
986
+
987
+ self._layout(items, function() {
988
+ if (fromFilter) {
989
+ self._filterEnd();
990
+ }
991
+ self._sortEnd();
992
+ });
993
+
994
+ self.lastSort = opts;
995
+ },
996
+
997
+ /**
998
+ * Relayout everything
999
+ */
1000
+ resized : function( isOnlyLayout ) {
1001
+ if ( this.enabled ) {
1002
+
1003
+ if ( !isOnlyLayout ) {
1004
+ // Get updated colCount
1005
+ this._setColumns();
1006
+ }
1007
+
1008
+ // Layout items
1009
+ this._reLayout();
1010
+ }
1011
+ },
1012
+
1013
+ /**
1014
+ * Use this instead of `update()` if you don't need the columns and gutters updated
1015
+ * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations
1016
+ * could be off.
1017
+ */
1018
+ layout : function() {
1019
+ this.update( true );
1020
+ },
1021
+
1022
+ update : function( isOnlyLayout ) {
1023
+ this.resized( isOnlyLayout );
1024
+ },
1025
+
1026
+ /**
1027
+ * New items have been appended to shuffle. Fade them in sequentially
1028
+ * @param {jQuery} $newItems jQuery collection of new items
1029
+ * @param {boolean} [animateIn] If false, the new items won't animate in
1030
+ * @param {boolean} [isSequential] If false, new items won't sequentially fade in
1031
+ */
1032
+ appended : function( $newItems, animateIn, isSequential ) {
1033
+ // True if undefined
1034
+ animateIn = animateIn === false ? false : true;
1035
+ isSequential = isSequential === false ? false : true;
1036
+
1037
+ this._addItems( $newItems, animateIn, isSequential );
1038
+ },
1039
+
1040
+ /**
1041
+ * Disables shuffle from updating dimensions and layout on resize
1042
+ */
1043
+ disable : function() {
1044
+ this.enabled = false;
1045
+ },
1046
+
1047
+ /**
1048
+ * Enables shuffle again
1049
+ * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters
1050
+ */
1051
+ enable : function( isUpdateLayout ) {
1052
+ this.enabled = true;
1053
+ if ( isUpdateLayout !== false ) {
1054
+ this.update();
1055
+ }
1056
+ },
1057
+
1058
+ /**
1059
+ * Remove 1 or more shuffle items
1060
+ * @param {jQuery} $collection A jQuery object containing one or more element in shuffle
1061
+ * @return {Shuffle} The shuffle object
1062
+ */
1063
+ remove : function( $collection ) {
1064
+
1065
+ // If this isn't a jquery object, exit
1066
+ if ( !$collection.length || !$collection.jquery ) {
1067
+ return;
1068
+ }
1069
+
1070
+ var self = this;
1071
+
1072
+ // Hide collection first
1073
+ self._shrink( $collection, function() {
1074
+ var shuffle = this;
1075
+
1076
+ // Remove the collection in the callback
1077
+ $collection.remove();
1078
+
1079
+ // Update the items, layout, count and fire off `removed` event
1080
+ setTimeout(function() {
1081
+ shuffle.$items = shuffle._getItems();
1082
+ shuffle.layout();
1083
+ shuffle._updateItemCount();
1084
+ shuffle._fire( Shuffle.EventType.REMOVED, [ $collection, shuffle ] );
1085
+
1086
+ // Let it get garbage collected
1087
+ $collection = null;
1088
+ }, 0);
1089
+ });
1090
+
1091
+ // Process changes
1092
+ self._processStyleQueue();
1093
+
1094
+ return self;
1095
+ },
1096
+
1097
+ /**
1098
+ * Destroys shuffle, removes events, styles, and classes
1099
+ */
1100
+ destroy : function() {
1101
+ var self = this;
1102
+
1103
+ // If there is more than one shuffle instance on the page,
1104
+ // removing the resize handler from the window would remove them
1105
+ // all. This is why a unique value is needed.
1106
+ self.$window.off('.' + self.unique);
1107
+
1108
+ // Reset container styles
1109
+ self.$el
1110
+ .removeClass( SHUFFLE )
1111
+ .removeAttr('style')
1112
+ .removeData( SHUFFLE );
1113
+
1114
+ // Reset individual item styles
1115
+ self.$items
1116
+ .removeAttr('style')
1117
+ .removeClass('concealed filtered shuffle-item');
1118
+
1119
+ // Null DOM references
1120
+ self.$window = null;
1121
+ self.$items = null;
1122
+ self.$el = null;
1123
+ self.$sizer = null;
1124
+ self.sizer = null;
1125
+
1126
+ // Set a flag so if a debounced resize has been triggered,
1127
+ // it can first check if it is actually destroyed and not doing anything
1128
+ self.destroyed = true;
1129
+ }
1130
+ };
1131
+ // Overrideable options
1132
+ Shuffle.options = {
1133
+ group: ALL_ITEMS, // Filter group
1134
+ speed: 250, // Transition/animation speed (milliseconds)
1135
+ easing: 'ease-out', // css easing function to use
1136
+ itemSelector: '', // e.g. '.picture-item'
1137
+ sizer: null, // sizer element. Can be anything columnWidth is
1138
+ gutterWidth: 0, // a static number or function that tells the plugin how wide the gutters between columns are (in pixels)
1139
+ columnWidth: 0, // a static number or function that returns a number which tells the plugin how wide the columns are (in pixels)
1140
+ delimeter: null, // if your group is not json, and is comma delimeted, you could set delimeter to ','
1141
+ buffer: 0, // useful for percentage based heights when they might not always be exactly the same (in pixels)
1142
+ initialSort: null, // Shuffle can be initialized with a sort object. It is the same object given to the sort method
1143
+ throttle: throttle, // By default, shuffle will try to throttle the resize event. This option will change the method it uses
1144
+ throttleTime: 300, // How often shuffle can be called on resize (in milliseconds)
1145
+ sequentialFadeDelay: 150, // Delay between each item that fades in when adding items
1146
+ supported: CAN_TRANSITION_TRANSFORMS // supports transitions and transforms
1147
+ };
1148
+ // Not overrideable
1149
+ Shuffle.settings = {
1150
+ $sizer: null,
1151
+ useSizer: false,
1152
+ itemCss : { // default CSS for each item
1153
+ position: 'absolute',
1154
+ top: 0,
1155
+ left: 0
1156
+ },
1157
+ offset: { top: 0, left: 0 },
1158
+ revealAppendedDelay: 300,
1159
+ enabled: true,
1160
+ destroyed: false,
1161
+ initialized: false,
1162
+ styleQueue: []
1163
+ };
1164
+ // Plugin definition
1165
+ $.fn.shuffle = function( opts ) {
1166
+ var args = Array.prototype.slice.call( arguments, 1 );
1167
+ return this.each(function() {
1168
+ var $this = $( this ),
1169
+ shuffle = $this.data( SHUFFLE );
1170
+
1171
+ // If we don't have a stored shuffle, make a new one and save it
1172
+ if ( !shuffle ) {
1173
+ shuffle = new Shuffle( $this, opts );
1174
+ $this.data( SHUFFLE, shuffle );
1175
+ }
1176
+
1177
+ if ( typeof opts === 'string' && shuffle[ opts ] ) {
1178
+ shuffle[ opts ].apply( shuffle, args );
1179
+ }
1180
+ });
1181
+ };
1182
+ // You can return `undefined` from the `by` function to revert to DOM order
1183
+ // This plugin does NOT return a jQuery object. It returns a plain array because
1184
+ // jQuery sorts everything in DOM order.
1185
+ $.fn.sorted = function(options) {
1186
+ var opts = $.extend({}, $.fn.sorted.defaults, options),
1187
+ arr = this.get(),
1188
+ revert = false;
1189
+
1190
+ if ( !arr.length ) {
1191
+ return [];
1192
+ }
1193
+
1194
+ if ( opts.randomize ) {
1195
+ return $.fn.sorted.randomize( arr );
1196
+ }
1197
+
1198
+ // Sort the elements by the opts.by function.
1199
+ // If we don't have opts.by, default to DOM order
1200
+ if (opts.by !== $.noop && opts.by !== null && opts.by !== undefined) {
1201
+ arr.sort(function(a, b) {
1202
+
1203
+ // Exit early if we already know we want to revert
1204
+ if ( revert ) {
1205
+ return 0;
1206
+ }
1207
+
1208
+ var valA = opts.by($(a)),
1209
+ valB = opts.by($(b));
1210
+
1211
+ // If both values are undefined, use the DOM order
1212
+ if ( valA === undefined && valB === undefined ) {
1213
+ revert = true;
1214
+ return 0;
1215
+ }
1216
+
1217
+ if ( valA === 'sortFirst' || valB === 'sortLast' ) {
1218
+ return -1;
1219
+ }
1220
+
1221
+ if ( valA === 'sortLast' || valB === 'sortFirst' ) {
1222
+ return 1;
1223
+ }
1224
+
1225
+ return (valA < valB) ? -1 :
1226
+ (valA > valB) ? 1 : 0;
1227
+ });
1228
+ }
1229
+
1230
+ // Revert to the original array if necessary
1231
+ if ( revert ) {
1232
+ return this.get();
1233
+ }
1234
+
1235
+ if ( opts.reverse ) {
1236
+ arr.reverse();
1237
+ }
1238
+
1239
+ return arr;
1240
+ };
1241
+ $.fn.sorted.defaults = {
1242
+ reverse: false, // Use array.reverse() to reverse the results
1243
+ by: null, // Sorting function
1244
+ randomize: false // If true, this will skip the sorting and return a randomized order in the array
1245
+ };
1246
+ // http://stackoverflow.com/a/962890/373422
1247
+ $.fn.sorted.randomize = function( array ) {
1248
+ var top = array.length,
1249
+ tmp, current;
1250
+
1251
+ if ( !top ) {
1252
+ return array;
1253
+ }
1254
+
1255
+ while ( --top ) {
1256
+ current = Math.floor( Math.random() * (top + 1) );
1257
+ tmp = array[ current ];
1258
+ array[ current ] = array[ top ];
1259
+ array[ top ] = tmp;
1260
+ }
1261
+
1262
+ return array;
1263
+ };
1264
+
1265
+ return Shuffle;
1266
+
1267
+ });
libs/controllers/sfsi_buttons_controller.php CHANGED
@@ -583,7 +583,9 @@ function sfsi_options_updater6()
583
  "show_count" => "no",
584
  "counter_color" => "#aaaaaa",
585
  "counter_bg_color" => "#fff",
586
- "share_count_text" => "SHARES"
 
 
587
  )
588
  );
589
  $sfsi_responsive_icons = array();
583
  "show_count" => "no",
584
  "counter_color" => "#aaaaaa",
585
  "counter_bg_color" => "#fff",
586
+ "share_count_text" => "SHARES",
587
+ "margin_above" => 10,
588
+ "margin_below" => 10,
589
  )
590
  );
591
  $sfsi_responsive_icons = array();
libs/controllers/sfsi_iconsUpload_contoller.php CHANGED
@@ -1,530 +1,530 @@
1
- <?php
2
- /* upload custom Skins {Monad}*/
3
- add_action('wp_ajax_UploadSkins','sfsi_UploadSkins');
4
- function sfsi_UploadSkins()
5
- {
6
- // extract($_REQUEST);
7
- if ( !wp_verify_nonce( $_POST['nonce'], "UploadSkins")) {
8
- echo json_encode(array("wrong_nonce")); exit;
9
- }
10
- if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
11
-
12
- $custom_imgurl = (isset($_POST['custom_imgurl']))?sanitize_text_field($_POST['custom_imgurl']):'';
13
-
14
- $upload_dir = wp_upload_dir();
15
-
16
- $ThumbSquareSize = 100; //Thumbnail will be 57X57
17
- $Quality = 90; //jpeg quality
18
- $DestinationDirectory = $upload_dir['path'].'/'; //specify upload directory ends with / (slash)
19
- $AcceessUrl = $upload_dir['url'].'/';
20
- $ThumbPrefix = "cmicon_";
21
-
22
- $data = $custom_imgurl;
23
- $params = array();
24
- parse_str($data, $params);
25
- // var_dump($params);die();
26
- $site_url = home_url();
27
- foreach($params as $key => $value)
28
- {
29
-
30
- $custom_imgurl = $value;
31
- if(!empty($custom_imgurl))
32
- {
33
- if(strpos($custom_imgurl, $site_url) === false){
34
- die(json_encode(array('res'=>'thumb_error')));
35
- }
36
- $sfsi_custom_files[] = $custom_imgurl;
37
-
38
- list($CurWidth, $CurHeight) = getimagesize($custom_imgurl);
39
-
40
- $info = explode("/", $custom_imgurl);
41
- $iconName = array_pop($info);
42
- $ImageExt = substr($iconName, strrpos($iconName, '.'));
43
- $ImageExt = str_replace('.','',$ImageExt);
44
-
45
- $iconName = str_replace(' ','-',strtolower($iconName)); // get image name
46
- $ImageType = 'image/'.$ImageExt;
47
-
48
- switch(strtolower($ImageType))
49
- {
50
- case 'image/png':
51
- // Create a new image from file
52
- $CreatedImage = imagecreatefrompng($custom_imgurl);
53
- break;
54
- case 'image/gif':
55
- $CreatedImage = imagecreatefromgif($custom_imgurl);
56
- break;
57
- case 'image/jpg':
58
- $CreatedImage = imagecreatefromjpeg($custom_imgurl);
59
- break;
60
- case 'image/jpeg':
61
- case 'image/pjpeg':
62
- $CreatedImage = imagecreatefromjpeg($custom_imgurl);
63
- break;
64
- default:
65
- die(json_encode(array('res'=>'type_error'))); //output error and exit
66
- }
67
-
68
- $ImageName = preg_replace("/\\.[^.\\s]{3,4}$/", "", $iconName);
69
-
70
- $NewIconName = "/custom_icon".$key.'.'.$ImageExt;
71
- $iconPath = $DestinationDirectory.$NewIconName; //Thumbnail name with destination directory
72
-
73
- //Create a square Thumbnail right after, this time we are using cropImage() function
74
- if(cropImage($CurWidth,$CurHeight,$ThumbSquareSize,$iconPath,$CreatedImage,$Quality,$ImageType))
75
- {
76
- //update database information
77
- $AccressImagePath=$AcceessUrl.$NewIconName;
78
- update_option($key,$AccressImagePath);
79
- die(json_encode(array('res'=>'success')));
80
- }
81
- else
82
- {
83
- die(json_encode(array('res'=>'thumb_error')));
84
- }
85
- }
86
- }
87
- }
88
-
89
- /* Delete custom Skins {Monad}*/
90
- add_action('wp_ajax_DeleteSkin','sfsi_DeleteSkin');
91
- function sfsi_DeleteSkin()
92
- {
93
- if ( !wp_verify_nonce( $_POST['nonce'], "deleteCustomSkin")) {
94
- echo json_encode(array('res'=>"error")); exit;
95
- }
96
- if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
97
-
98
- $upload_dir = wp_upload_dir();
99
-
100
- if(sanitize_text_field($_POST['action']) == 'DeleteSkin' && isset($_POST['iconname']) && !empty($_POST['iconname']) && current_user_can('manage_options'))
101
- {
102
- $iconsArray = array(
103
- "rss_skin","email_skin","facebook_skin","twitter_skin",
104
- "share_skin","youtube_skin","linkedin_skin","pintrest_skin","instagram_skin"
105
- );
106
- if(in_array(sanitize_text_field($_POST['iconname']), $iconsArray))
107
- {
108
- $imgurl = get_option( sanitize_text_field($_POST['iconname']) );
109
- $path = parse_url($imgurl, PHP_URL_PATH);
110
-
111
- if(is_file($_SERVER['DOCUMENT_ROOT'] . $path))
112
- {
113
- unlink($_SERVER['DOCUMENT_ROOT'] . $path);
114
- }
115
-
116
- delete_option( sanitize_text_field($_POST['iconname']) );
117
- die(json_encode(array('res'=>'success')));
118
- }
119
- else
120
- {
121
- die(json_encode(array('res'=>'error')));
122
- }
123
- }
124
- else
125
- {
126
- die(json_encode(array('res'=>'error')));
127
- }
128
- }
129
-
130
- /* add ajax action for custom skin done & save{Monad}*/
131
- add_action('wp_ajax_Iamdone','sfsi_Iamdone');
132
- function sfsi_Iamdone()
133
- {
134
- $return = '';
135
- if ( !wp_verify_nonce( $_POST['nonce'], "Iamdone")) {
136
- echo json_encode(array('res'=>"error")); exit;
137
- }
138
- if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
139
-
140
- if(get_option("rss_skin"))
141
- {
142
- $icon = get_option("rss_skin");
143
- $return .= '<span class="row_17_1 rss_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
144
- }else
145
- {
146
- $return .= '<span class="row_17_1 rss_section" style="background-position:-1px 0;"></span>';
147
- }
148
-
149
- if(get_option("email_skin"))
150
- {
151
- $icon = get_option("email_skin");
152
- $return .= '<span class="row_17_2 email_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
153
- }else
154
- {
155
- $return .= '<span class="row_17_2 email_section" style="background-position:-58px 0;"></span>';
156
- }
157
-
158
- if(get_option("facebook_skin"))
159
- {
160
- $icon = get_option("facebook_skin");
161
- $return .= '<span class="row_17_3 facebook_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
162
- }else
163
- {
164
- $return .= '<span class="row_17_3 facebook_section" style="background-position:-118px 0;"></span>';
165
- }
166
-
167
- if(get_option("twitter_skin"))
168
- {
169
- $icon = get_option("twitter_skin");
170
- $return .= '<span class="row_17_5 twitter_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
171
- }else
172
- {
173
- $return .= '<span class="row_17_5 twitter_section" style="background-position:-235px 0;"></span>';
174
- }
175
-
176
- if(get_option("share_skin"))
177
- {
178
- $icon = get_option("share_skin");
179
- $return .= '<span class="row_17_6 share_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
180
- }else
181
- {
182
- $return .= '<span class="row_17_6 share_section" style="background-position:-293px 0;"></span>';
183
- }
184
-
185
- if(get_option("youtube_skin"))
186
- {
187
- $icon = get_option("youtube_skin");
188
- $return .= '<span class="row_17_7 youtube_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
189
- }else
190
- {
191
- $return .= '<span class="row_17_7 youtube_section" style="background-position:-350px 0;"></span>';
192
- }
193
-
194
- if(get_option("pintrest_skin"))
195
- {
196
- $icon = get_option("pintrest_skin");
197
- $return .= '<span class="row_17_8 pinterest_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
198
- }else
199
- {
200
- $return .= '<span class="row_17_8 pinterest_section" style="background-position:-409px 0;"></span>';
201
- }
202
-
203
- if(get_option("linkedin_skin"))
204
- {
205
- $icon = get_option("linkedin_skin");
206
- $return .= '<span class="row_17_9 linkedin_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
207
- }else
208
- {
209
- $return .= '<span class="row_17_9 linkedin_section" style="background-position:-467px 0;"></span>';
210
- }
211
-
212
- if(get_option("instagram_skin"))
213
- {
214
- $icon = get_option("instagram_skin");
215
- $return .= '<span class="row_17_10 instagram_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
216
- }else
217
- {
218
- $return .= '<span class="row_17_10 instagram_section" style="background-position:-526px 0;"></span>';
219
- }
220
- if(get_option("telegram_skin"))
221
- {
222
- $icon = get_option("telegram_skin");
223
- $return .= '<span class="row_17_10 telegram_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
224
- }else
225
- {
226
- $return .= '<span class="row_17_10 telegram_section" style="background-position:-773px 0;"></span>';
227
- }
228
- if(get_option("vk_skin"))
229
- {
230
- $icon = get_option("vk_skin");
231
- $return .= '<span class="row_17_10 vk_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
232
- }else
233
- {
234
- $return .= '<span class="row_17_10 vk_section" style="background-position:-838px 0;"></span>';
235
- }
236
- if(get_option("ok_skin"))
237
- {
238
- $icon = get_option("ok_skin");
239
- $return .= '<span class="row_17_10 ok_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
240
- }else
241
- {
242
- $return .= '<span class="row_17_10 ok_section" style="background-position:-909px 0;"></span>';
243
- }
244
- if(get_option("weibo_skin"))
245
- {
246
- $icon = get_option("weibo_skin");
247
- $return .= '<span class="row_17_10 weibo_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
248
- }else
249
- {
250
- $return .= '<span class="row_17_10 weibo_section" style="background-position:-977px 0;"></span>';
251
- }
252
- if(get_option("wechat_skin"))
253
- {
254
- $icon = get_option("wechat_skin");
255
- $return .= '<span class="row_17_10 wechat_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
256
- }else
257
- {
258
- $return .= '<span class="row_1_18 wechat_section"></span>';
259
- }
260
- die($return);
261
- }
262
-
263
- /* add ajax action for custom icons upload {Monad}*/
264
- add_action('wp_ajax_UploadIcons','sfsi_UploadIcons');
265
-
266
- /* uplaod custom icon {change by monad}*/
267
- function sfsi_UploadIcons()
268
- {
269
- if ( !wp_verify_nonce( $_POST['nonce'], "UploadIcons")) {
270
- echo json_encode(array('res'=>"error")); exit;
271
- }
272
- if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
273
-
274
- // extract($_POST);
275
- $custom_imgurl = isset($_POST) && isset($_POST['custom_imgurl']) ? esc_url($_POST['custom_imgurl']):'';
276
-
277
- if(strpos($custom_imgurl, home_url()) === false){
278
- die(json_encode(array('res'=>'thumb_error')));
279
- }
280
-
281
- $upload_dir = wp_upload_dir();
282
-
283
- $ThumbSquareSize = 100; //Thumbnail will be 57X57
284
- $Quality = 90; //jpeg quality
285
- $DestinationDirectory = $upload_dir['path'].'/'; //specify upload directory ends with / (slash)
286
- $AcceessUrl = $upload_dir['url'].'/';
287
- $ThumbPrefix = "cmicon_";
288
-
289
- if(!empty($custom_imgurl))
290
- {
291
- $sfsi_custom_files[] = $custom_imgurl;
292
-
293
- list($CurWidth, $CurHeight) = getimagesize($custom_imgurl);
294
-
295
- $info = explode("/", $custom_imgurl);
296
- $iconName = array_pop($info);
297
- $ImageExt = substr($iconName, strrpos($iconName, '.'));
298
- $ImageExt = str_replace('.','',$ImageExt);
299
-
300
- $iconName = str_replace(' ','-',strtolower($iconName)); // get image name
301
- $ImageType = 'image/'.$ImageExt;
302
-
303
- switch(strtolower($ImageType))
304
- {
305
- case 'image/png':
306
- // Create a new image from file
307
- $CreatedImage = imagecreatefrompng($custom_imgurl);
308
- break;
309
- case 'image/gif':
310
- $CreatedImage = imagecreatefromgif($custom_imgurl);
311
- break;
312
- case 'image/jpg':
313
- $CreatedImage = imagecreatefromjpeg($custom_imgurl);
314
- break;
315
- case 'image/jpeg':
316
- case 'image/pjpeg':
317
- $CreatedImage = imagecreatefromjpeg($custom_imgurl);
318
- break;
319
- default:
320
- die(json_encode(array('res'=>'type_error'))); //output error and exit
321
- }
322
-
323
-
324
- $ImageName = preg_replace("/\\.[^.\\s]{3,4}$/", "", $iconName);
325
- //$cnt=$i+1;
326
-
327
- $sec_options= (get_option('sfsi_section1_options',false)) ? unserialize(get_option('sfsi_section1_options',false)) : '' ;
328
- $icons = (is_array(unserialize($sec_options['sfsi_custom_files']))) ? unserialize($sec_options['sfsi_custom_files']) : array();
329
- if(empty($icons))
330
- {
331
- end($icons);
332
- $new=0;
333
- }
334
- else {
335
- end($icons);
336
- $cnt=key($icons);
337
- $new=$cnt+1;
338
- }
339
- $NewIconName = "custom_icon".$new.'.'.$ImageExt;
340
- $iconPath = $DestinationDirectory.$NewIconName; //Thumbnail name with destination directory
341
-
342
- //Create a square Thumbnail right after, this time we are using cropImage() function
343
- if(cropImage($CurWidth,$CurHeight,$ThumbSquareSize,$iconPath,$CreatedImage,$Quality,$ImageType))
344
- {
345
- //update database information
346
- $AccressImagePath=$AcceessUrl.$NewIconName;
347
- $sec_options= (get_option('sfsi_section1_options',false)) ? unserialize(get_option('sfsi_section1_options',false)) : '' ;
348
- $icons = (is_array(unserialize($sec_options['sfsi_custom_files']))) ? unserialize($sec_options['sfsi_custom_files']) : array();
349
- $icons[] = $AccressImagePath;
350
-
351
- $sec_options['sfsi_custom_files'] = serialize($icons);
352
- $total_uploads = ( isset($icons) && is_array($icons) )?count($icons):0; end($icons); $key = key($icons);
353
- update_option('sfsi_section1_options',serialize($sec_options));
354
- die(json_encode(array('res'=>'success','img_path'=>$AccressImagePath,'element'=>$total_uploads,'key'=>$key)));
355
- }
356
- else
357
- {
358
- die(json_encode(array('res'=>'thumb_error')));
359
- }
360
-
361
- }
362
- }
363
- /* delete uploaded icons */
364
- add_action('wp_ajax_deleteIcons','sfsi_deleteIcons');
365
-
366
- function sfsi_deleteIcons()
367
- {
368
- if ( !wp_verify_nonce( $_POST['nonce'], "deleteIcons")) {
369
- echo json_encode(array('res'=>"error")); exit;
370
- }
371
- if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
372
-
373
- if(isset($_POST['icon_name']) && !empty($_POST['icon_name']))
374
- {
375
- /* get icons details to delete it from plugin folder */
376
- $custom_icon_name= sanitize_text_field($_POST['icon_name']);
377
- preg_match_all('/\d+/', $custom_icon_name, $custom_icon_numbers);
378
- $custom_icon_number = count($custom_icon_numbers)>0?((is_array($custom_icon_numbers[0])&&count($custom_icon_numbers[0])>0)?$custom_icon_numbers[0][0]:0):0;
379
- $sec_options1 = (get_option('sfsi_section1_options',false)) ? unserialize(get_option('sfsi_section1_options',false)) : array() ;
380
- $sec_options2 = (get_option('sfsi_section2_options',false)) ? unserialize(get_option('sfsi_section2_options',false)) : array() ;
381
- $up_icons = (is_array(unserialize($sec_options1['sfsi_custom_files']))) ? unserialize($sec_options1['sfsi_custom_files']) : array();
382
- $icons_links = (is_array(unserialize($sec_options2['sfsi_CustomIcon_links']))) ? unserialize($sec_options2['sfsi_CustomIcon_links']) : array();
383
- $icon_url=$up_icons[$custom_icon_number];
384
- $url_info= pathinfo($icon_url);
385
- // Changes By {Monad}
386
- /*if(is_file(SFSI_DOCROOT.'/images/custom_icons/'.$path['basename']))
387
- {
388
-
389
- unlink(SFSI_DOCROOT.'/images/custom_icons/'.$path['basename']);
390
- }*/
391
- $imgpath = parse_url($icon_url, PHP_URL_PATH);
392
-
393
- if(is_file($_SERVER['DOCUMENT_ROOT'] . $imgpath))
394
- {
395
- unlink($_SERVER['DOCUMENT_ROOT'] . $imgpath);
396
- }
397
-
398
- if(isset($up_icons[$custom_icon_number]))
399
- {
400
- unset($up_icons[$custom_icon_number]);
401
- unset($icons_links[$custom_icon_number]);
402
- }
403
- else
404
- {
405
- unset($up_icons[0]);
406
- unset($icons_links[0]);
407
- }
408
-
409
- /* update database after delete */
410
- $sec_options1['sfsi_custom_files']=serialize($up_icons);
411
- $sec_options2['sfsi_CustomIcon_links']=serialize($icons_links);
412
-
413
- end($up_icons);
414
- $key=(key($up_icons))? key($up_icons) :$custom_icon_number;
415
- $total_uploads=(isset($up_icons) && is_array($up_icons))?count($up_icons):0;
416
-
417
- update_option('sfsi_section1_options',serialize($sec_options1));
418
- update_option('sfsi_section2_options',serialize($sec_options2));
419
-
420
- die(json_encode(array('res'=>'success','last_index'=>$key,'total_up'=>$total_uploads)));
421
- }
422
- }
423
-
424
- /* This function will proportionally resize image */
425
- function resizeImage($CurWidth,$CurHeight,$MaxSize,$DestFolder,$SrcImage,$Quality,$ImageType)
426
- {
427
- /* Check Image size is not 0 */
428
- if($CurWidth <= 0 || $CurHeight <= 0)
429
- {
430
- return false;
431
- }
432
- /* Construct a proportional size of new image */
433
- $ImageScale = min($MaxSize/$CurWidth, $MaxSize/$CurHeight);
434
- $NewWidth = ceil($ImageScale*$CurWidth);
435
- $NewHeight = ceil($ImageScale*$CurHeight);
436
- $NewCanves = imagecreatetruecolor($NewWidth, $NewHeight);
437
-
438
- /* Resize Image */
439
- if(imagecopyresampled($NewCanves, $SrcImage,0, 0, 0, 0, $NewWidth, $NewHeight, $CurWidth, $CurHeight))
440
- {
441
- return $ImageType;
442
- switch(strtolower($ImageType))
443
- {
444
- case 'image/png':
445
- imagepng($NewCanves,$DestFolder);
446
- break;
447
- case 'image/gif':
448
- imagegif($NewCanves,$DestFolder);
449
- break;
450
- case 'image/jpg':
451
- imagejpeg($NewCanves,$DestFolder,$Quality);
452
- break;
453
- case 'image/jpeg':
454
- case 'image/pjpeg':
455
- imagejpeg($NewCanves,$DestFolder,$Quality);
456
- break;
457
- default:
458
- return false;
459
- }
460
- /* Destroy image, frees memory */
461
- if(is_resource($NewCanves)) {imagedestroy($NewCanves);}
462
- return true;
463
- }
464
- }
465
-
466
- /* This function corps image to create exact square images, no matter what its original size! */
467
- function cropImage($CurWidth,$CurHeight,$iSize,$DestFolder,$SrcImage,$Quality,$ImageType)
468
- {
469
- //Check Image size is not 0
470
- if($CurWidth <= 0 || $CurHeight <= 0)
471
- {
472
- return false;
473
- }
474
-
475
- if($CurWidth>$CurHeight)
476
- {
477
- $y_offset = 0;
478
- $x_offset = ($CurWidth - $CurHeight) / 2;
479
- $square_size = $CurWidth - ($x_offset * 2);
480
- }else{
481
- $x_offset = 0;
482
- $y_offset = ($CurHeight - $CurWidth) / 2;
483
- $square_size = $CurHeight - ($y_offset * 2);
484
- }
485
-
486
- $NewCanves = imagecreatetruecolor($iSize, $iSize);
487
- imagealphablending($NewCanves, false);
488
- imagesavealpha($NewCanves,true);
489
- $white = imagecolorallocate($NewCanves, 255, 255, 255);
490
- $alpha_channel = imagecolorallocatealpha($NewCanves, 255, 255, 255, 127);
491
- imagecolortransparent($NewCanves, $alpha_channel);
492
- $maketransparent = imagecolortransparent($NewCanves,$white);
493
- imagefill($NewCanves, 0, 0, $maketransparent);
494
-
495
- /*
496
- * Change offset for increase image quality ($x_offset, $y_offset)
497
- * imagecopyresampled($NewCanves, $SrcImage,0, 0, $x_offset, $y_offset, $iSize, $iSize, $square_size, $square_size)
498
- */
499
- if(imagecopyresampled($NewCanves, $SrcImage,0, 0, 0, 0, $iSize, $iSize, $square_size, $square_size))
500
- {
501
- imagesavealpha($NewCanves,true);
502
- switch(strtolower($ImageType))
503
- {
504
- case 'image/png':
505
- imagepng($NewCanves,$DestFolder);
506
- break;
507
- case 'image/gif':
508
- imagegif($NewCanves,$DestFolder);
509
- break;
510
- case 'image/jpg':
511
- imagejpeg($NewCanves,$DestFolder,$Quality);
512
- break;
513
- case 'image/jpeg':
514
- case 'image/pjpeg':
515
- imagejpeg($NewCanves,$DestFolder,$Quality);
516
- break;
517
- default:
518
- return false;
519
- }
520
-
521
- /* Destroy image, frees memory */
522
- if(is_resource($NewCanves)) {imagedestroy($NewCanves);}
523
- return true;
524
- }
525
- else
526
- {
527
- return false;
528
- }
529
- }
530
  ?>
1
+ <?php
2
+ /* upload custom Skins {Monad}*/
3
+ add_action('wp_ajax_UploadSkins','sfsi_UploadSkins');
4
+ function sfsi_UploadSkins()
5
+ {
6
+ // extract($_REQUEST);
7
+ if ( !wp_verify_nonce( $_POST['nonce'], "UploadSkins")) {
8
+ echo json_encode(array("wrong_nonce")); exit;
9
+ }
10
+ if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
11
+
12
+ $custom_imgurl = (isset($_POST['custom_imgurl']))?sanitize_text_field($_POST['custom_imgurl']):'';
13
+
14
+ $upload_dir = wp_upload_dir();
15
+
16
+ $ThumbSquareSize = 100; //Thumbnail will be 57X57
17
+ $Quality = 90; //jpeg quality
18
+ $DestinationDirectory = $upload_dir['path'].'/'; //specify upload directory ends with / (slash)
19
+ $AcceessUrl = $upload_dir['url'].'/';
20
+ $ThumbPrefix = "cmicon_";
21
+
22
+ $data = $custom_imgurl;
23
+ $params = array();
24
+ parse_str($data, $params);
25
+ // var_dump($params);die();
26
+ $site_url = home_url();
27
+ foreach($params as $key => $value)
28
+ {
29
+
30
+ $custom_imgurl = $value;
31
+ if(!empty($custom_imgurl))
32
+ {
33
+ if(strpos($custom_imgurl, $site_url) === false){
34
+ die(json_encode(array('res'=>'thumb_error')));
35
+ }
36
+ $sfsi_custom_files[] = $custom_imgurl;
37
+
38
+ list($CurWidth, $CurHeight) = getimagesize($custom_imgurl);
39
+
40
+ $info = explode("/", $custom_imgurl);
41
+ $iconName = array_pop($info);
42
+ $ImageExt = substr($iconName, strrpos($iconName, '.'));
43
+ $ImageExt = str_replace('.','',$ImageExt);
44
+
45
+ $iconName = str_replace(' ','-',strtolower($iconName)); // get image name
46
+ $ImageType = 'image/'.$ImageExt;
47
+
48
+ switch(strtolower($ImageType))
49
+ {
50
+ case 'image/png':
51
+ // Create a new image from file
52
+ $CreatedImage = imagecreatefrompng($custom_imgurl);
53
+ break;
54
+ case 'image/gif':
55
+ $CreatedImage = imagecreatefromgif($custom_imgurl);
56
+ break;
57
+ case 'image/jpg':
58
+ $CreatedImage = imagecreatefromjpeg($custom_imgurl);
59
+ break;
60
+ case 'image/jpeg':
61
+ case 'image/pjpeg':
62
+ $CreatedImage = imagecreatefromjpeg($custom_imgurl);
63
+ break;
64
+ default:
65
+ die(json_encode(array('res'=>'type_error'))); //output error and exit
66
+ }
67
+
68
+ $ImageName = preg_replace("/\\.[^.\\s]{3,4}$/", "", $iconName);
69
+
70
+ $NewIconName = "/custom_icon".$key.'.'.$ImageExt;
71
+ $iconPath = $DestinationDirectory.$NewIconName; //Thumbnail name with destination directory
72
+
73
+ //Create a square Thumbnail right after, this time we are using cropImage() function
74
+ if(cropImage($CurWidth,$CurHeight,$ThumbSquareSize,$iconPath,$CreatedImage,$Quality,$ImageType))
75
+ {
76
+ //update database information
77
+ $AccressImagePath=$AcceessUrl.$NewIconName;
78
+ update_option($key,$AccressImagePath);
79
+ die(json_encode(array('res'=>'success')));
80
+ }
81
+ else
82
+ {
83
+ die(json_encode(array('res'=>'thumb_error')));
84
+ }
85
+ }
86
+ }
87
+ }
88
+
89
+ /* Delete custom Skins {Monad}*/
90
+ add_action('wp_ajax_DeleteSkin','sfsi_DeleteSkin');
91
+ function sfsi_DeleteSkin()
92
+ {
93
+ if ( !wp_verify_nonce( $_POST['nonce'], "deleteCustomSkin")) {
94
+ echo json_encode(array('res'=>"error")); exit;
95
+ }
96
+ if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
97
+
98
+ $upload_dir = wp_upload_dir();
99
+
100
+ if(sanitize_text_field($_POST['action']) == 'DeleteSkin' && isset($_POST['iconname']) && !empty($_POST['iconname']) && current_user_can('manage_options'))
101
+ {
102
+ $iconsArray = array(
103
+ "rss_skin","email_skin","facebook_skin","twitter_skin",
104
+ "share_skin","youtube_skin","linkedin_skin","pintrest_skin","instagram_skin"
105
+ );
106
+ if(in_array(sanitize_text_field($_POST['iconname']), $iconsArray))
107
+ {
108
+ $imgurl = get_option( sanitize_text_field($_POST['iconname']) );
109
+ $path = parse_url($imgurl, PHP_URL_PATH);
110
+
111
+ if(is_file($_SERVER['DOCUMENT_ROOT'] . $path))
112
+ {
113
+ unlink($_SERVER['DOCUMENT_ROOT'] . $path);
114
+ }
115
+
116
+ delete_option( sanitize_text_field($_POST['iconname']) );
117
+ die(json_encode(array('res'=>'success')));
118
+ }
119
+ else
120
+ {
121
+ die(json_encode(array('res'=>'error')));
122
+ }
123
+ }
124
+ else
125
+ {
126
+ die(json_encode(array('res'=>'error')));
127
+ }
128
+ }
129
+
130
+ /* add ajax action for custom skin done & save{Monad}*/
131
+ add_action('wp_ajax_Iamdone','sfsi_Iamdone');
132
+ function sfsi_Iamdone()
133
+ {
134
+ $return = '';
135
+ if ( !wp_verify_nonce( $_POST['nonce'], "Iamdone")) {
136
+ echo json_encode(array('res'=>"error")); exit;
137
+ }
138
+ if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
139
+
140
+ if(get_option("rss_skin"))
141
+ {
142
+ $icon = get_option("rss_skin");
143
+ $return .= '<span class="row_17_1 rss_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
144
+ }else
145
+ {
146
+ $return .= '<span class="row_17_1 rss_section" style="background-position:-1px 0;"></span>';
147
+ }
148
+
149
+ if(get_option("email_skin"))
150
+ {
151
+ $icon = get_option("email_skin");
152
+ $return .= '<span class="row_17_2 email_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
153
+ }else
154
+ {
155
+ $return .= '<span class="row_17_2 email_section" style="background-position:-58px 0;"></span>';
156
+ }
157
+
158
+ if(get_option("facebook_skin"))
159
+ {
160
+ $icon = get_option("facebook_skin");
161
+ $return .= '<span class="row_17_3 facebook_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
162
+ }else
163
+ {
164
+ $return .= '<span class="row_17_3 facebook_section" style="background-position:-118px 0;"></span>';
165
+ }
166
+
167
+ if(get_option("twitter_skin"))
168
+ {
169
+ $icon = get_option("twitter_skin");
170
+ $return .= '<span class="row_17_5 twitter_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
171
+ }else
172
+ {
173
+ $return .= '<span class="row_17_5 twitter_section" style="background-position:-235px 0;"></span>';
174
+ }
175
+
176
+ if(get_option("share_skin"))
177
+ {
178
+ $icon = get_option("share_skin");
179
+ $return .= '<span class="row_17_6 share_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
180
+ }else
181
+ {
182
+ $return .= '<span class="row_17_6 share_section" style="background-position:-293px 0;"></span>';
183
+ }
184
+
185
+ if(get_option("youtube_skin"))
186
+ {
187
+ $icon = get_option("youtube_skin");
188
+ $return .= '<span class="row_17_7 youtube_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
189
+ }else
190
+ {
191
+ $return .= '<span class="row_17_7 youtube_section" style="background-position:-350px 0;"></span>';
192
+ }
193
+
194
+ if(get_option("pintrest_skin"))
195
+ {
196
+ $icon = get_option("pintrest_skin");
197
+ $return .= '<span class="row_17_8 pinterest_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
198
+ }else
199
+ {
200
+ $return .= '<span class="row_17_8 pinterest_section" style="background-position:-409px 0;"></span>';
201
+ }
202
+
203
+ if(get_option("linkedin_skin"))
204
+ {
205
+ $icon = get_option("linkedin_skin");
206
+ $return .= '<span class="row_17_9 linkedin_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
207
+ }else
208
+ {
209
+ $return .= '<span class="row_17_9 linkedin_section" style="background-position:-467px 0;"></span>';
210
+ }
211
+
212
+ if(get_option("instagram_skin"))
213
+ {
214
+ $icon = get_option("instagram_skin");
215
+ $return .= '<span class="row_17_10 instagram_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
216
+ }else
217
+ {
218
+ $return .= '<span class="row_17_10 instagram_section" style="background-position:-526px 0;"></span>';
219
+ }
220
+ if(get_option("telegram_skin"))
221
+ {
222
+ $icon = get_option("telegram_skin");
223
+ $return .= '<span class="row_17_10 telegram_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
224
+ }else
225
+ {
226
+ $return .= '<span class="row_17_10 telegram_section" style="background-position:-773px 0;"></span>';
227
+ }
228
+ if(get_option("vk_skin"))
229
+ {
230
+ $icon = get_option("vk_skin");
231
+ $return .= '<span class="row_17_10 vk_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
232
+ }else
233
+ {
234
+ $return .= '<span class="row_17_10 vk_section" style="background-position:-838px 0;"></span>';
235
+ }
236
+ if(get_option("ok_skin"))
237
+ {
238
+ $icon = get_option("ok_skin");
239
+ $return .= '<span class="row_17_10 ok_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
240
+ }else
241
+ {
242
+ $return .= '<span class="row_17_10 ok_section" style="background-position:-909px 0;"></span>';
243
+ }
244
+ if(get_option("weibo_skin"))
245
+ {
246
+ $icon = get_option("weibo_skin");
247
+ $return .= '<span class="row_17_10 weibo_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
248
+ }else
249
+ {
250
+ $return .= '<span class="row_17_10 weibo_section" style="background-position:-977px 0;"></span>';
251
+ }
252
+ if(get_option("wechat_skin"))
253
+ {
254
+ $icon = get_option("wechat_skin");
255
+ $return .= '<span class="row_17_10 wechat_section sfsi-bgimage" style="background: url('.$icon.') no-repeat;"></span>';
256
+ }else
257
+ {
258
+ $return .= '<span class="row_1_18 wechat_section"></span>';
259
+ }
260
+ die($return);
261
+ }
262
+
263
+ /* add ajax action for custom icons upload {Monad}*/
264
+ add_action('wp_ajax_UploadIcons','sfsi_UploadIcons');
265
+
266
+ /* uplaod custom icon {change by monad}*/
267
+ function sfsi_UploadIcons()
268
+ {
269
+ if ( !wp_verify_nonce( $_POST['nonce'], "UploadIcons")) {
270
+ echo json_encode(array('res'=>"error")); exit;
271
+ }
272
+ if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
273
+
274
+ // extract($_POST);
275
+ $custom_imgurl = isset($_POST) && isset($_POST['custom_imgurl']) ? esc_url($_POST['custom_imgurl']):'';
276
+
277
+ if(strpos($custom_imgurl, home_url()) === false){
278
+ die(json_encode(array('res'=>'thumb_error')));
279
+ }
280
+
281
+ $upload_dir = wp_upload_dir();
282
+
283
+ $ThumbSquareSize = 100; //Thumbnail will be 57X57
284
+ $Quality = 90; //jpeg quality
285
+ $DestinationDirectory = $upload_dir['path'].'/'; //specify upload directory ends with / (slash)
286
+ $AcceessUrl = $upload_dir['url'].'/';
287
+ $ThumbPrefix = "cmicon_";
288
+
289
+ if(!empty($custom_imgurl))
290
+ {
291
+ $sfsi_custom_files[] = $custom_imgurl;
292
+
293
+ list($CurWidth, $CurHeight) = getimagesize($custom_imgurl);
294
+
295
+ $info = explode("/", $custom_imgurl);
296
+ $iconName = array_pop($info);
297
+ $ImageExt = substr($iconName, strrpos($iconName, '.'));
298
+ $ImageExt = str_replace('.','',$ImageExt);
299
+
300
+ $iconName = str_replace(' ','-',strtolower($iconName)); // get image name
301
+ $ImageType = 'image/'.$ImageExt;
302
+
303
+ switch(strtolower($ImageType))
304
+ {
305
+ case 'image/png':
306
+ // Create a new image from file
307
+ $CreatedImage = imagecreatefrompng($custom_imgurl);
308
+ break;
309
+ case 'image/gif':
310
+ $CreatedImage = imagecreatefromgif($custom_imgurl);
311
+ break;
312
+ case 'image/jpg':
313
+ $CreatedImage = imagecreatefromjpeg($custom_imgurl);
314
+ break;
315
+ case 'image/jpeg':
316
+ case 'image/pjpeg':
317
+ $CreatedImage = imagecreatefromjpeg($custom_imgurl);
318
+ break;
319
+ default:
320
+ die(json_encode(array('res'=>'type_error'))); //output error and exit
321
+ }
322
+
323
+
324
+ $ImageName = preg_replace("/\\.[^.\\s]{3,4}$/", "", $iconName);
325
+ //$cnt=$i+1;
326
+
327
+ $sec_options= (get_option('sfsi_section1_options',false)) ? unserialize(get_option('sfsi_section1_options',false)) : '' ;
328
+ $icons = (is_array(unserialize($sec_options['sfsi_custom_files']))) ? unserialize($sec_options['sfsi_custom_files']) : array();
329
+ if(empty($icons))
330
+ {
331
+ end($icons);
332
+ $new=0;
333
+ }
334
+ else {
335
+ end($icons);
336
+ $cnt=key($icons);
337
+ $new=$cnt+1;
338
+ }
339
+ $NewIconName = "custom_icon".$new.'.'.$ImageExt;
340
+ $iconPath = $DestinationDirectory.$NewIconName; //Thumbnail name with destination directory
341
+
342
+ //Create a square Thumbnail right after, this time we are using cropImage() function
343
+ if(cropImage($CurWidth,$CurHeight,$ThumbSquareSize,$iconPath,$CreatedImage,$Quality,$ImageType))
344
+ {
345
+ //update database information
346
+ $AccressImagePath=$AcceessUrl.$NewIconName;
347
+ $sec_options= (get_option('sfsi_section1_options',false)) ? unserialize(get_option('sfsi_section1_options',false)) : '' ;
348
+ $icons = (is_array(unserialize($sec_options['sfsi_custom_files']))) ? unserialize($sec_options['sfsi_custom_files']) : array();
349
+ $icons[] = $AccressImagePath;
350
+
351
+ $sec_options['sfsi_custom_files'] = serialize($icons);
352
+ $total_uploads = ( isset($icons) && is_array($icons) )?count($icons):0; end($icons); $key = key($icons);
353
+ update_option('sfsi_section1_options',serialize($sec_options));
354
+ die(json_encode(array('res'=>'success','img_path'=>$AccressImagePath,'element'=>$total_uploads,'key'=>$key)));
355
+ }
356
+ else
357
+ {
358
+ die(json_encode(array('res'=>'thumb_error')));
359
+ }
360
+
361
+ }
362
+ }
363
+ /* delete uploaded icons */
364
+ add_action('wp_ajax_deleteIcons','sfsi_deleteIcons');
365
+
366
+ function sfsi_deleteIcons()
367
+ {
368
+ if ( !wp_verify_nonce( $_POST['nonce'], "deleteIcons")) {
369
+ echo json_encode(array('res'=>"error")); exit;
370
+ }
371
+ if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
372
+
373
+ if(isset($_POST['icon_name']) && !empty($_POST['icon_name']))
374
+ {
375
+ /* get icons details to delete it from plugin folder */
376
+ $custom_icon_name= sanitize_text_field($_POST['icon_name']);
377
+ preg_match_all('/\d+/', $custom_icon_name, $custom_icon_numbers);
378
+ $custom_icon_number = count($custom_icon_numbers)>0?((is_array($custom_icon_numbers[0])&&count($custom_icon_numbers[0])>0)?$custom_icon_numbers[0][0]:0):0;
379
+ $sec_options1 = (get_option('sfsi_section1_options',false)) ? unserialize(get_option('sfsi_section1_options',false)) : array() ;
380
+ $sec_options2 = (get_option('sfsi_section2_options',false)) ? unserialize(get_option('sfsi_section2_options',false)) : array() ;
381
+ $up_icons = (is_array(unserialize($sec_options1['sfsi_custom_files']))) ? unserialize($sec_options1['sfsi_custom_files']) : array();
382
+ $icons_links = (is_array(unserialize($sec_options2['sfsi_CustomIcon_links']))) ? unserialize($sec_options2['sfsi_CustomIcon_links']) : array();
383
+ $icon_url=$up_icons[$custom_icon_number];
384
+ $url_info= pathinfo($icon_url);
385
+ // Changes By {Monad}
386
+ /*if(is_file(SFSI_DOCROOT.'/images/custom_icons/'.$path['basename']))
387
+ {
388
+
389
+ unlink(SFSI_DOCROOT.'/images/custom_icons/'.$path['basename']);
390
+ }*/
391
+ $imgpath = parse_url($icon_url, PHP_URL_PATH);
392
+
393
+ if(is_file($_SERVER['DOCUMENT_ROOT'] . $imgpath))
394
+ {
395
+ unlink($_SERVER['DOCUMENT_ROOT'] . $imgpath);
396
+ }
397
+
398
+ if(isset($up_icons[$custom_icon_number]))
399
+ {
400
+ unset($up_icons[$custom_icon_number]);
401
+ unset($icons_links[$custom_icon_number]);
402
+ }
403
+ else
404
+ {
405
+ unset($up_icons[0]);
406
+ unset($icons_links[0]);
407
+ }
408
+
409
+ /* update database after delete */
410
+ $sec_options1['sfsi_custom_files']=serialize($up_icons);
411
+ $sec_options2['sfsi_CustomIcon_links']=serialize($icons_links);
412
+
413
+ end($up_icons);
414
+ $key=(key($up_icons))? key($up_icons) :$custom_icon_number;
415
+ $total_uploads=(isset($up_icons) && is_array($up_icons))?count($up_icons):0;
416
+
417
+ update_option('sfsi_section1_options',serialize($sec_options1));
418
+ update_option('sfsi_section2_options',serialize($sec_options2));
419
+
420
+ die(json_encode(array('res'=>'success','last_index'=>$key,'total_up'=>$total_uploads)));
421
+ }
422
+ }
423
+
424
+ /* This function will proportionally resize image */
425
+ function resizeImage($CurWidth,$CurHeight,$MaxSize,$DestFolder,$SrcImage,$Quality,$ImageType)
426
+ {
427
+ /* Check Image size is not 0 */
428
+ if($CurWidth <= 0 || $CurHeight <= 0)
429
+ {
430
+ return false;
431
+ }
432
+ /* Construct a proportional size of new image */
433
+ $ImageScale = min($MaxSize/$CurWidth, $MaxSize/$CurHeight);
434
+ $NewWidth = ceil($ImageScale*$CurWidth);
435
+ $NewHeight = ceil($ImageScale*$CurHeight);
436
+ $NewCanves = imagecreatetruecolor($NewWidth, $NewHeight);
437
+
438
+ /* Resize Image */
439
+ if(imagecopyresampled($NewCanves, $SrcImage,0, 0, 0, 0, $NewWidth, $NewHeight, $CurWidth, $CurHeight))
440
+ {
441
+ return $ImageType;
442
+ switch(strtolower($ImageType))
443
+ {
444
+ case 'image/png':
445
+ imagepng($NewCanves,$DestFolder);
446
+ break;
447
+ case 'image/gif':
448
+ imagegif($NewCanves,$DestFolder);
449
+ break;
450
+ case 'image/jpg':
451
+ imagejpeg($NewCanves,$DestFolder,$Quality);
452
+ break;
453
+ case 'image/jpeg':
454
+ case 'image/pjpeg':
455
+ imagejpeg($NewCanves,$DestFolder,$Quality);
456
+ break;
457
+ default:
458
+ return false;
459
+ }
460
+ /* Destroy image, frees memory */
461
+ if(is_resource($NewCanves)) {imagedestroy($NewCanves);}
462
+ return true;
463
+ }
464
+ }
465
+
466
+ /* This function corps image to create exact square images, no matter what its original size! */
467
+ function cropImage($CurWidth,$CurHeight,$iSize,$DestFolder,$SrcImage,$Quality,$ImageType)
468
+ {
469
+ //Check Image size is not 0
470
+ if($CurWidth <= 0 || $CurHeight <= 0)
471
+ {
472
+ return false;
473
+ }
474
+
475
+ if($CurWidth>$CurHeight)
476
+ {
477
+ $y_offset = 0;
478
+ $x_offset = ($CurWidth - $CurHeight) / 2;
479
+ $square_size = $CurWidth - ($x_offset * 2);
480
+ }else{
481
+ $x_offset = 0;
482
+ $y_offset = ($CurHeight - $CurWidth) / 2;
483
+ $square_size = $CurHeight - ($y_offset * 2);
484
+ }
485
+
486
+ $NewCanves = imagecreatetruecolor($iSize, $iSize);
487
+ imagealphablending($NewCanves, false);
488
+ imagesavealpha($NewCanves,true);
489
+ $white = imagecolorallocate($NewCanves, 255, 255, 255);
490
+ $alpha_channel = imagecolorallocatealpha($NewCanves, 255, 255, 255, 127);
491
+ imagecolortransparent($NewCanves, $alpha_channel);
492
+ $maketransparent = imagecolortransparent($NewCanves,$white);
493
+ imagefill($NewCanves, 0, 0, $maketransparent);
494
+
495
+ /*
496
+ * Change offset for increase image quality ($x_offset, $y_offset)
497
+ * imagecopyresampled($NewCanves, $SrcImage,0, 0, $x_offset, $y_offset, $iSize, $iSize, $square_size, $square_size)
498
+ */
499
+ if(imagecopyresampled($NewCanves, $SrcImage,0, 0, 0, 0, $iSize, $iSize, $square_size, $square_size))
500
+ {
501
+ imagesavealpha($NewCanves,true);
502
+ switch(strtolower($ImageType))
503
+ {
504
+ case 'image/png':
505
+ imagepng($NewCanves,$DestFolder);
506
+ break;
507
+ case 'image/gif':
508
+ imagegif($NewCanves,$DestFolder);
509
+ break;
510
+ case 'image/jpg':
511
+ imagejpeg($NewCanves,$DestFolder,$Quality);
512
+ break;
513
+ case 'image/jpeg':
514
+ case 'image/pjpeg':
515
+ imagejpeg($NewCanves,$DestFolder,$Quality);
516
+ break;
517
+ default:
518
+ return false;
519
+ }
520
+
521
+ /* Destroy image, frees memory */
522
+ if(is_resource($NewCanves)) {imagedestroy($NewCanves);}
523
+ return true;
524
+ }
525
+ else
526
+ {
527
+ return false;
528
+ }
529
+ }
530
  ?>
libs/controllers/sfsi_socialhelper.php CHANGED
@@ -257,11 +257,11 @@ class sfsi_SocialHelper
257
  }
258
 
259
  /*twitter like*/
260
- function sfsi_twitterlike($permalink, $show_count)
261
- {
262
- $twitter_text = '';
263
- return sfsi_twitterShare($permalink,$twitter_text);
264
- }
265
 
266
  /* create on page facebook share option */
267
  public function sfsiFB_Share($permalink)
@@ -270,40 +270,77 @@ class sfsi_SocialHelper
270
  $fb_share_html .= 'type="button"';
271
  $fb_share_html .= '></fb:share-button>';*/
272
  $fb_share_html = '';
273
- $fb_share_html .= '<div class="fb-share-button" data-href="'.$permalink.'" data-layout="button"></div>';
274
- return $fb_share_html;
 
 
 
 
 
275
  }
 
 
 
276
  /* create on page twitter follow option */
277
  public function sfsi_twitterFollow($tw_username)
278
  {
279
- $twitter_html = '<a href="https://twitter.com/'.trim($tw_username).'" class="twitter-follow-button" data-show-count="false" data-show-screen-name="false">Follow </a>';
 
 
 
 
280
  return $twitter_html;
281
  }
282
 
283
  /* create on page twitter share icon */
284
  public function sfsi_twitterShare($permalink,$tweettext)
285
  {
286
- if($tweettext){
287
- $twitter_html = '<a rel="nofollow" href="http://twitter.com/share" data-count="none" class="sr-twitter-button twitter-share-button" lang="en" data-url="'.$permalink.'" data-text="'.stripslashes($tweettext).'" ></a>';
288
- }else{
289
- $twitter_html = '<a rel="nofollow" href="http://twitter.com/share" data-count="none" class="sr-twitter-button twitter-share-button" lang="en" data-url="'.$permalink.'" data-text="&nbsp;" ></a>';
290
 
291
- }
 
 
 
 
292
  return $twitter_html;
293
  }
294
 
295
  /* create on page twitter share icon with count */
296
  public function sfsi_twitterSharewithcount($permalink,$tweettext, $show_count)
297
  {
298
- if($show_count)
299
- {
300
- $twitter_html = '<a href="http://twitter.com/share" class="sr-twitter-button twitter-share-button" lang="en" data-counturl="'.$permalink.'" data-url="'.$permalink.'" data-text="'.$tweettext.'" ></a>';
301
- }
302
- else
303
- {
304
- $twitter_html = '<a href="http://twitter.com/share" data-count="none" class="sr-twitter-button twitter-share-button" lang="en" data-url="'.$permalink.'" data-text="'.$tweettext.'" ></a>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  }
306
- return $twitter_html;
 
 
 
 
 
 
307
  }
308
 
309
  /* create on page youtube subscribe icon */
@@ -332,6 +369,8 @@ class sfsi_SocialHelper
332
  return $pin_it_html;
333
  }
334
 
 
 
335
  /* get instragram followers */
336
  public function sfsi_get_instagramFollowers($user_name)
337
  {
@@ -413,8 +452,9 @@ class sfsi_SocialHelper
413
  /* create linkedIn share button */
414
  public function sfsi_LinkedInShare($url='')
415
  {
416
- $url=(isset($url))? $url : home_url();
417
- return $ifollow='<script type="IN/Share" data-url="'.$url.'"></script>';
 
418
  }
419
 
420
  /* get no of subscribers from specificfeeds for current blog */
@@ -524,4 +564,3 @@ class sfsi_SocialHelper
524
 
525
  }
526
  /* end of class */
527
- ?>
257
  }
258
 
259
  /*twitter like*/
260
+ // function sfsi_twitterlike($permalink, $show_count)
261
+ // {
262
+ // $twitter_text = '';
263
+ // return sfsi_twitterShare($permalink,$twitter_text);
264
+ // }
265
 
266
  /* create on page facebook share option */
267
  public function sfsiFB_Share($permalink)
270
  $fb_share_html .= 'type="button"';
271
  $fb_share_html .= '></fb:share-button>';*/
272
  $fb_share_html = '';
273
+ // $fb_share_html .= '<div class="fb-share-button" data-href="'.$permalink.'" data-layout="button"></div>';
274
+ // return $fb_share_html;
275
+ $shareurl = "https://www.facebook.com/sharer/sharer.php?u=";
276
+ $shareurl = $shareurl . urlencode(urldecode($permalink));
277
+
278
+ $fb_share_html = "<a href='" . $shareurl . "' style='display:inline-block;' > <img class='sfsi_wicon' data-pin-nopin='true' width='auto' height='auto' alt='fb-share-icon' title='Facebook Share' src='" . SFSI_PLUGURL . "images/visit_icons/fbshare_bck.png" . "' /></a>";
279
+ return $fb_share_html;
280
  }
281
+
282
+
283
+
284
  /* create on page twitter follow option */
285
  public function sfsi_twitterFollow($tw_username)
286
  {
287
+ $twitter_html = '<a target="_blank" href="https://twitter.com/intent/user?screen_name='.trim($tw_username).'">
288
+ <img nopin="nopin" width="auto" src="'. SFSI_PLUGURL .'images/visit_icons/en_US_Follow.svg" class="sfsi_wicon" alt="Follow Me" title="Follow Me" style="opacity: 1;" />
289
+ </a>';
290
+
291
+ // $twitter_html = '<a href="https://twitter.com/'.trim($tw_username).'" class="twitter-follow-button" data-show-count="false" data-show-screen-name="false">Follow </a>';
292
  return $twitter_html;
293
  }
294
 
295
  /* create on page twitter share icon */
296
  public function sfsi_twitterShare($permalink,$tweettext)
297
  {
298
+ $tweet_icon = SFSI_PLUGURL . 'images/visit_icons/en_US_Tweet.svg';
 
 
 
299
 
300
+ $twitter_html = "<div class='sf_twiter' style='display: inline-block;vertical-align: middle;width: auto;'>
301
+ <a href='https://twitter.com/intent/tweet?text=" . urlencode($tweettext).' '.$permalink. "'style='display:inline-block' >
302
+ <img nopin=nopin width='auto' class='sfsi_wicon' src='" . $tweet_icon . "' alt='Tweet' title='Tweet' >
303
+ </a>
304
+ </div>";
305
  return $twitter_html;
306
  }
307
 
308
  /* create on page twitter share icon with count */
309
  public function sfsi_twitterSharewithcount($permalink,$tweettext, $show_count)
310
  {
311
+ $sfsi_section4 = unserialize(get_option('sfsi_section4_options', false));
312
+ $tweet_icon = SFSI_PLUGURL . 'images/visit_icons/en_US_Tweet.svg';
313
+ $socialObj = new sfsi_SocialHelper();
314
+ if ($show_count ) {
315
+ /* get twitter counts */
316
+ if ($sfsi_section4['sfsi_twitter_countsFrom'] == "source") {
317
+ $option2 = unserialize(get_option('sfsi_section2_options', false));
318
+
319
+ $twitter_user = $option2['sfsi_twitter_followUserName'];
320
+ $tw_settings = array(
321
+ 'tw_consumer_key' => $sfsi_section4['tw_consumer_key'],
322
+ 'tw_consumer_secret' => $sfsi_section4['tw_consumer_secret'],
323
+ 'tw_oauth_access_token' => $sfsi_section4['tw_oauth_access_token'],
324
+ 'tw_oauth_access_token_secret' => $sfsi_section4['tw_oauth_access_token_secret']
325
+ );
326
+
327
+ $followers = $socialObj->sfsi_get_tweets($twitter_user, $tw_settings);
328
+ $counts = $socialObj->format_num($followers);
329
+ } else {
330
+ $counts = $socialObj->format_num($sfsi_section4['sfsi_twitter_manualCounts']);
331
+
332
+ }
333
+ if($counts>0){
334
+ $count_html = '<span class="bot_no">'.$counts.'</span>';
335
+ }
336
  }
337
+ $twitter_html = "<div class='sf_twiter' style='display: inline-block;vertical-align: middle;width: auto;'>
338
+ <a href='https://twitter.com/intent/tweet?text=" . urlencode($tweettext) . ' ' . $permalink . "'style='display:inline-block' >
339
+ <img nopin=nopin width='auto' class='sfsi_wicon' src='" . $tweet_icon . "' alt='Tweet' title='Tweet' >
340
+ </a>".$count_html."
341
+ </div>";
342
+ // $twitter_html = '<a href="http://twitter.com/share" data-count="none" class="sr-twitter-button twitter-share-button" lang="en" data-url="'.$permalink.'" data-text="'.$tweettext.'" ></a>';
343
+ return $twitter_html;
344
  }
345
 
346
  /* create on page youtube subscribe icon */
369
  return $pin_it_html;
370
  }
371
 
372
+
373
+
374
  /* get instragram followers */
375
  public function sfsi_get_instagramFollowers($user_name)
376
  {
452
  /* create linkedIn share button */
453
  public function sfsi_LinkedInShare($url='')
454
  {
455
+ $url=(isset($url) && ''!==$url)? $url : home_url();
456
+ return '<a href="https://www.linkedin.com/shareArticle?url='.urlencode($url).'"><img class="sfsi_wicon" nopin="nopin" alt="Share" title="Share" src="'.SFSI_PLUGURL.'images/visit_icons/lnkdin_share_bck.png"></a>';
457
+ // return $ifollow='<script type="IN/Share" data-url="'.$url.'"></script>';
458
  }
459
 
460
  /* get no of subscribers from specificfeeds for current blog */
564
 
565
  }
566
  /* end of class */
 
libs/controllers/sfsiocns_OnPosts.php CHANGED
@@ -59,61 +59,78 @@ function sfsi_social_buttons_below($content)
59
  //adding wrapper div
60
  $icons .= "<div class='sfsi_socialwpr'>";
61
  if ($sfsi_section6['sfsi_rectsub'] == 'yes' && $sfsi_section6['sfsi_show_Onposts'] == "yes") {
62
- if ($show_count) {
63
- $sfsiLikeWithsub = "93px";
64
- } else {
65
- $sfsiLikeWithsub = "64px";
66
- }
67
- if (!isset($sfsiLikeWithsub)) {
68
- $sfsiLikeWithsub = $sfsiLikeWith;
69
- }
70
- $icons .= "<div class='sf_subscrbe' style='text-align:left;vertical-align: middle;float:left;width:" . $sfsiLikeWithsub . "'>" . sfsi_Subscribelike($permalink, $show_count) . "</div>";
71
  }
72
- if (($sfsi_section6['sfsi_show_Onposts'] == "yes") && ($sfsi_section6['sfsi_rectfb'] == 'yes' || $sfsi_section6['sfsi_rectfbshare'] == 'yes')) {
73
- if ($sfsi_section6['sfsi_rectfb'] == 'yes') {
74
- if ($show_count) {
75
- $sfsiLikeWithfb = "80px";
76
- } else {
77
- $sfsiLikeWithfb = "52px";
78
- }
79
- }
80
- if ($sfsi_section6['sfsi_rectfbshare'] == 'yes') {
81
- if ($show_count) {
82
- $sfsiLikeWithfb = "88px";
83
- } else {
84
- $sfsiLikeWithfb = "60px";
85
- }
86
- }
87
- if ($sfsi_section6['sfsi_rectfb'] == 'yes' && $sfsi_section6['sfsi_rectfbshare'] == 'yes') {
88
- if ($show_count) {
89
- $sfsiLikeWithfb = "125px";
90
- } else {
91
- $sfsiLikeWithfb = "98px";
 
 
92
  }
93
  }
94
-
95
- $icons .= "<div class='sf_fb' style='text-align:left;vertical-align: middle;width:" . $sfsiLikeWithfb . "'>" . sfsi_FBlike($permalink, $show_count) . "</div>";
96
  }
97
  if (($sfsi_section6['sfsi_recttwtr'] == "yes" && $sfsi_section6['sfsi_show_Onposts'] == "yes")) {
98
- if ($show_count) {
99
- $sfsiLikeWithtwtr = "62px";
100
- } else {
101
- $sfsiLikeWithtwtr = "62px";
102
- }
103
- if (!isset($sfsiLikeWithtwtr)) {
104
- $sfsiLikeWithtwtr = $sfsiLikeWith;
105
- }
106
- $icons .= "<div class='sf_twiter' style='text-align:left;float:left;vertical-align: middle;width:auto'>" . sfsi_twitterlike($permalink, $show_count) . "</div>";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  }
108
 
109
  if (($sfsi_section6['sfsi_show_Onposts'] == "yes") && $sfsi_section6['sfsi_rectpinit'] == 'yes') {
110
- $sfsi_pinwidth = "47px";
111
- if ($show_count) {
112
- $sfsi_pinwidth = "100px";
113
- } else {
114
- $sfsi_pinwidth = "47px";
 
 
 
 
 
 
 
115
  }
116
- $icons .= "<div class='sf_pinit' style='text-align:left;vertical-align: middle;float:left;line-height: 20px;width:" . $sfsi_pinwidth . "'>" . sfsi_pinterest($permalink, $show_count) . "</div>";
117
  }
118
  $icons .= "</div>";
119
  //closing wrapper div
@@ -159,6 +176,27 @@ function sfsi_Subscribelike($permalink, $show_count)
159
  /*twitter like*/
160
  function sfsi_twitterlike($permalink, $show_count)
161
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  global $socialObj;
163
  $socialObj = new sfsi_SocialHelper();
164
  $twitter_text = '';
@@ -170,35 +208,39 @@ function sfsi_twitterlike($permalink, $show_count)
170
  }
171
  return $socialObj->sfsi_twitterSharewithcount($permalink, $twitter_text, $show_count);
172
  }
 
173
  /*twitter like*/
174
  /* create pinit button */
175
- function sfsi_pinterest($permalink, $show_count)
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  {
177
- $pinit_html = '<a href="https://www.pinterest.com/pin/create/button/?url=&media=&description=" data-pin-do="buttonPin" data-pin-save="true"';
178
- if ($show_count) {
179
- $pinit_html .= 'data-pin-count="beside"';
180
- } else {
181
- $pinit_html .= 'data-pin-count="none"';
182
- }
183
- $pinit_html .= '></a>';
184
 
185
- return $pinit_html;
 
186
  }
187
 
188
  /* create fb like button */
189
  function sfsi_FBlike($permalink, $show_count)
190
  {
191
  $send = 'false';
192
- $width = 180;
193
  $fb_like_html = '';
194
 
195
  $option6 = unserialize(get_option('sfsi_section6_options', false));
196
  if ($option6['sfsi_rectfbshare'] == 'yes' && $option6['sfsi_rectfb'] == 'yes') {
197
- $fb_like_html .= '<div class="fb-like" data-href="' . $permalink . '" data-width="' . $width . '" data-send="' . $send . '" data-show-faces="false" data-action="like" data-share="true"';
198
- } else if ($option6['sfsi_rectfb'] == 'no' && $option6['sfsi_rectfbshare'] == 'yes') {
199
- $fb_like_html .= '<div class="fb-share-button" href="' . $permalink . '" data-width="' . $width . '" data-send="' . $send . '" ';
200
- } else {
201
- $fb_like_html .= '<div class="fb-like" data-href="' . $permalink . '" data-width="' . $width . '" data-send="' . $send . '" data-show-faces="false" data-action="like" data-share="false" ';
202
  }
203
  if ($show_count == 1) {
204
  $fb_like_html .= 'data-layout="button_count"';
@@ -209,6 +251,15 @@ function sfsi_FBlike($permalink, $show_count)
209
  return $fb_like_html;
210
  }
211
 
 
 
 
 
 
 
 
 
 
212
  /* add all external javascript to wp_footer */
213
  function sfsi_footer_script()
214
  {
@@ -239,7 +290,7 @@ function sfsi_footer_script()
239
  $sfsi_section6['sfsi_show_Onposts'] = isset($sfsi_section6['sfsi_show_Onposts']) && !empty($sfsi_section6['sfsi_show_Onposts']) ? $sfsi_section6['sfsi_show_Onposts'] : "no";
240
  if ($sfsi_section1['sfsi_facebook_display'] == "yes") {
241
  // var_dump($sfsi_section6['sfsi_rectfb'],$sfsi_section6['sfsi_show_Onposts']);
242
- if ((($sfsi_section6['sfsi_rectfb'] == "yes" || $sfsi_section6['sfsi_rectfbshare'] == "yes") && $sfsi_section6['sfsi_show_Onposts'] == "yes") || $sisi_common_options_check && ($sfsi_section2['sfsi_facebookPage_option'] == "yes" || $sfsi_section2['sfsi_facebookLike_option'] == "yes" || $sfsi_section2['sfsi_facebookShare_option'] == "yes")) {
243
  ?>
244
  <!--facebook like and share js -->
245
  <div id="fb-root"></div>
@@ -256,72 +307,55 @@ function sfsi_footer_script()
256
  <?php
257
  }
258
  }
259
- if ($sfsi_section1['sfsi_youtube_display'] == "yes") {
260
- if ($sisi_common_options_check && ($sfsi_section2['sfsi_youtube_page'] == 'yes' || ($sfsi_section2['sfsi_youtube_follow'] == 'yes'))) {
261
- ?>
262
- <script type="text/javascript">
263
- window.___gcfg = {
264
- lang: 'en-US'
265
- };
266
- (function() {
267
- var po = document.createElement('script');
268
- po.type = 'text/javascript';
269
- po.async = true;
270
- po.src = 'https://apis.google.com/js/plusone.js';
271
- var s = document.getElementsByTagName('script')[0];
272
- s.parentNode.insertBefore(po, s);
273
- })();
274
- </script>
275
-
276
- <script type="text/javascript">
277
- (function() {
278
- var po = document.createElement('script');
279
- po.type = 'text/javascript';
280
- po.async = true;
281
- po.src = 'https://apis.google.com/js/platform.js';
282
- var s = document.getElementsByTagName('script')[0];
283
- s.parentNode.insertBefore(po, s);
284
- })();
285
- </script>
286
- <?php
287
- }
 
 
 
 
 
288
  }
 
289
 
290
- if ($sfsi_section1['sfsi_linkedin_display'] == "yes") {
291
- if ($sisi_common_options_check && ($sfsi_section2['sfsi_linkedin_page'] == 'yes' || $sfsi_section2['sfsi_linkedin_follow'] == 'yes' || $sfsi_section2['sfsi_linkedin_SharePage'] == 'yes' || $sfsi_section2['sfsi_linkedin_recommendBusines'] == 'yes')) {
 
292
 
293
- ?>
294
- <script src="//platform.linkedin.com/in.js" type="text/javascript">
295
- lang: en_US
296
- </script>
297
- <?php
298
- }
299
- }
300
- if ($sfsi_section1['sfsi_pinterest_display'] == "yes") {
301
- if (($sfsi_section6['sfsi_rectpinit'] == "yes" && $sfsi_section6['sfsi_show_Onposts'] == "yes") || $sisi_common_options_check && ($sfsi_section2['sfsi_pinterest_page'] == 'yes' || $sfsi_section2['sfsi_pinterest_pingBlog'] == 'yes')) { ?>
302
- <!--pinit js -->
303
- <script type="text/javascript" src="//assets.pinterest.com/js/pinit.js"></script>
304
- <?php
305
- }
306
  }
307
 
308
- if ($sfsi_section1['sfsi_twitter_display'] == "yes") {
309
- if (($sfsi_section6['sfsi_recttwtr'] == "yes" && $sfsi_section6['sfsi_show_Onposts'] == "yes") || ($sisi_common_options_check && ($sfsi_section2['sfsi_twitter_page'] == 'yes' || $sfsi_section2['sfsi_twitter_followme'] == 'yes' || $sfsi_section2['sfsi_twitter_aboutPage'] == 'yes'))) { ?>
310
- <!-- twitter JS End -->
311
- <script>
312
- ! function(d, s, id) {
313
- var js, fjs = d.getElementsByTagName(s)[0];
314
- if (!d.getElementById(id)) {
315
- js = d.createElement(s);
316
- js.id = id;
317
- js.src = "https://platform.twitter.com/widgets.js";
318
- fjs.parentNode.insertBefore(js, fjs);
319
- }
320
- }(document, "script", "twitter-wjs");
321
- </script>
322
- <?php
323
- }
324
- }
325
  /* activate footer credit link */
326
  if (get_option('sfsi_footer_sec') == "yes") {
327
  if (!is_admin()) {
@@ -394,7 +428,10 @@ function sfsi_footer_script()
394
  "show_count" => "no",
395
  "counter_color" => "#aaaaaa",
396
  "counter_bg_color" => "#fff",
397
- "share_count_text" => "SHARES"
 
 
 
398
  )
399
  );
400
  } else {
@@ -404,6 +441,8 @@ function sfsi_footer_script()
404
  $twitter_text = isset($option2['sfsi_twitter_aboutPageText']) && !empty($option2['sfsi_twitter_aboutPageText']) ? $option2['sfsi_twitter_aboutPageText'] : false;
405
 
406
  $icon_width_type = $sfsi_responsive_icons["settings"]["icon_width_type"];
 
 
407
  if ($option4['sfsi_display_counts'] == 'yes' && isset($sfsi_responsive_icons["settings"]['show_count']) && $sfsi_responsive_icons["settings"]['show_count'] == "yes") :
408
  $counter_class = "sfsi_responsive_with_counter_icons";
409
  $couter_display = "inline-block";
@@ -421,7 +460,7 @@ function sfsi_footer_script()
421
  $counter_class = "sfsi_responsive_without_counter_icons";
422
  $couter_display = "none";
423
  endif;
424
- $icons .= "<div class='sfsi_responsive_icons' style='display:inline-block; " . ($icon_width_type == "Fully Responsive" ? "width:100%;display:flex; " : 'width:100%') . "' data-icon-width-type='" . $icon_width_type . "' data-icon-width-size='" . $sfsi_responsive_icons["settings"]['icon_width_size'] . "' data-edge-type='" . $sfsi_responsive_icons["settings"]['edge_type'] . "' data-edge-radius='" . $sfsi_responsive_icons["settings"]['edge_radius'] . "' >";
425
  $sfsi_anchor_div_style = "";
426
  if ($sfsi_responsive_icons["settings"]["edge_type"] === "Round") {
427
  $sfsi_anchor_div_style .= " border-radius:";
59
  //adding wrapper div
60
  $icons .= "<div class='sfsi_socialwpr'>";
61
  if ($sfsi_section6['sfsi_rectsub'] == 'yes' && $sfsi_section6['sfsi_show_Onposts'] == "yes") {
62
+
63
+ $icons .= "<div class='sf_subscrbe' style='text-align:left;vertical-align: middle;float:left;width:auto'>" . sfsi_Subscribelike($permalink, $show_count) . "</div>";
 
 
 
 
 
 
 
64
  }
65
+ if ($sfsi_section6['sfsi_show_Onposts'] == "yes" && $sfsi_section6['sfsi_rectfb'] == 'yes') {
66
+
67
+ $icons .= "<div class='sf_fb' style='text-align:left;vertical-align: middle;'>" . sfsi_FBlike($permalink, $show_count) . "</div>";
68
+ }
69
+ if ($sfsi_section6['sfsi_show_Onposts'] == "yes" && $sfsi_section6['sfsi_rectfbshare'] == 'yes') {
70
+ $sfsi_section4 = unserialize(get_option('sfsi_section4_options', false));
71
+ $socialObj = new sfsi_SocialHelper();
72
+ $count_html="";
73
+ if ($show_count>0) {
74
+ if ($sfsi_section4['sfsi_facebook_countsDisplay'] == "yes" && $sfsi_section4['sfsi_display_counts'] == "yes") {
75
+
76
+ if ($sfsi_section4['sfsi_facebook_countsFrom'] == "manual") {
77
+ $counts = $sfsi_section4['sfsi_facebook_manualCounts'];
78
+ } else if ($sfsi_section4['sfsi_facebook_countsFrom'] == "likes") {
79
+ $counts = $socialObj->sfsi_get_fb($permalink);
80
+ } else if ($sfsi_section4['sfsi_facebook_countsFrom'] == "followers") {
81
+ $counts = $socialObj->sfsi_get_fb($permalink);
82
+ } else if ($sfsi_section4['sfsi_facebook_countsFrom'] == "mypage") {
83
+ $current_url = $sfsi_section4['sfsi_facebook_mypageCounts'];
84
+ $counts = $socialObj->sfsi_get_fb_pagelike($current_url);
85
+ }
86
+ $count_html = '<span class="bot_no">'.$counts.'</span>';
87
  }
88
  }
89
+ $icons .= "<div class='sf_fb' style='text-align:left;vertical-align: middle;'>" . sfsiFB_Share_Custom($permalink, $show_count) .$count_html. "</div>";
 
90
  }
91
  if (($sfsi_section6['sfsi_recttwtr'] == "yes" && $sfsi_section6['sfsi_show_Onposts'] == "yes")) {
92
+ // if ($show_count ) {
93
+ // /* get twitter counts */
94
+ // if ($sfsi_section4['sfsi_twitter_countsFrom'] == "source") {
95
+ // $option2 = unserialize(get_option('sfsi_section2_options', false));
96
+
97
+ // $twitter_user = $option2['sfsi_twitter_followUserName'];
98
+ // $tw_settings = array(
99
+ // 'tw_consumer_key' => $sfsi_section4['tw_consumer_key'],
100
+ // 'tw_consumer_secret' => $sfsi_section4['tw_consumer_secret'],
101
+ // 'tw_oauth_access_token' => $sfsi_section4['tw_oauth_access_token'],
102
+ // 'tw_oauth_access_token_secret' => $sfsi_section4['tw_oauth_access_token_secret']
103
+ // );
104
+
105
+ // $followers = $socialObj->sfsi_get_tweets($twitter_user, $tw_settings);
106
+ // $counts = $socialObj->format_num($followers);
107
+ // } else {
108
+ // $counts = $socialObj->format_num($sfsi_section4['sfsi_twitter_manualCounts']);
109
+
110
+ // }
111
+ // if($counts>0){
112
+ // $count_html = '<span class="bot_no">'.$counts.'</span>';
113
+ // }
114
+ // }
115
+ $icons .= sfsi_twitterlike($permalink, $show_count);
116
+ // $icons .= "<div class='sf_twiter' style='text-align:left;float:left;vertical-align: middle;width:auto'>" . . "</div>";
117
  }
118
 
119
  if (($sfsi_section6['sfsi_show_Onposts'] == "yes") && $sfsi_section6['sfsi_rectpinit'] == 'yes') {
120
+ if ($show_count ) {
121
+ /* get Pinterest counts */
122
+ if ($sfsi_section4['sfsi_pinterest_countsFrom'] == "pins") {
123
+ $url = home_url();
124
+ $pins = $socialObj->sfsi_get_pinterest($url);
125
+ $counts = $socialObj->format_num($pins);
126
+ } else {
127
+ $counts = $sfsi_section4['sfsi_pinterest_manualCounts'];
128
+ }
129
+ if($counts>0){
130
+ $count_html = '<span class="bot_no">'.$counts.'</span>';
131
+ }
132
  }
133
+ $icons .= "<div class='sf_pinit' style='text-align:left;vertical-align: middle;float:left;line-height: 20px;width:auto'>" . sfsi_pinterest_Customs($permalink, $show_count) .$count_html. "</div>";
134
  }
135
  $icons .= "</div>";
136
  //closing wrapper div
176
  /*twitter like*/
177
  function sfsi_twitterlike($permalink, $show_count)
178
  {
179
+ // $twitter_text = '';
180
+ // if (!empty($permalink)) {
181
+ // $postid = url_to_postid($permalink);
182
+ // }
183
+ // if (!empty($postid)) {
184
+ // $twitter_text = get_the_title($postid);
185
+ // }
186
+ // $socialObj = new sfsi_SocialHelper();
187
+
188
+ // if($show_count>0){
189
+ // $count_html = '<span class="bot_no">'.$show_count.'</span>';
190
+ // }
191
+
192
+ // $tweet_icon = SFSI_PLUGURL . 'images/share_icons/Twitter_Tweet/en_US_Tweet.svg';
193
+ // $icons = "<div class='sf_twiter' style='display: inline-block;vertical-align: middle;width: auto;'>
194
+ // <a href='https://twitter.com/intent/tweet?text=" . urlencode($twitter_text).' '.$permalink. "'style='display:inline-block' >
195
+ // <img nopin=nopin width='auto' class='sfsi_premium_wicon' src='" . $tweet_icon . "' alt='Tweet' title='Tweet' >
196
+ // </a>
197
+ // <span class='bot_no'>".$count_html."</span>
198
+ // </div>";
199
+ // return $icons;
200
  global $socialObj;
201
  $socialObj = new sfsi_SocialHelper();
202
  $twitter_text = '';
208
  }
209
  return $socialObj->sfsi_twitterSharewithcount($permalink, $twitter_text, $show_count);
210
  }
211
+
212
  /*twitter like*/
213
  /* create pinit button */
214
+ // function sfsi_pinterest($permalink, $show_count)
215
+ // {
216
+ // $pinit_html = '<a href="https://www.pinterest.com/pin/create/button/?url=&media=&description=" data-pin-do="buttonPin" data-pin-save="true"';
217
+ // if ($show_count) {
218
+ // $pinit_html .= 'data-pin-count="beside"';
219
+ // } else {
220
+ // $pinit_html .= 'data-pin-count="none"';
221
+ // }
222
+ // $pinit_html .= '></a>';
223
+
224
+ // return $pinit_html;8
225
+ // }
226
+
227
+ function sfsi_pinterest_Customs($permalink, $show_count = false)
228
  {
229
+ $pinit_html = 'https://www.pinterest.com/pin/create/button/?url=&media=&description';
 
 
 
 
 
 
230
 
231
+ $pinit_html = "<a href='" . $pinit_html . "' style='display:inline-block;' > <img class='sfsi_wicon' data-pin-nopin='true' width='auto' height='auto' alt='fb-share-icon' title='Facebook Share' src='" . SFSI_PLUGURL . "images/visit_icons/en_US_save.svg" . "' /></a>";
232
+ return $pinit_html;
233
  }
234
 
235
  /* create fb like button */
236
  function sfsi_FBlike($permalink, $show_count)
237
  {
238
  $send = 'false';
 
239
  $fb_like_html = '';
240
 
241
  $option6 = unserialize(get_option('sfsi_section6_options', false));
242
  if ($option6['sfsi_rectfbshare'] == 'yes' && $option6['sfsi_rectfb'] == 'yes') {
243
+ $fb_like_html .= '<div class="fb-like" data-href="' . $permalink . '" data-send="' . $send . '" ';
 
 
 
 
244
  }
245
  if ($show_count == 1) {
246
  $fb_like_html .= 'data-layout="button_count"';
251
  return $fb_like_html;
252
  }
253
 
254
+ function sfsiFB_Share_Custom($permalink, $show_count = false)
255
+ {
256
+ $shareurl = "https://www.facebook.com/sharer/sharer.php?u=";
257
+ $shareurl = $shareurl . urlencode(urldecode($permalink));
258
+
259
+ $fb_share_html = "<a href='" . $shareurl . "' style='display:inline-block;' > <img class='sfsi_wicon' data-pin-nopin='true' width='auto' height='auto' alt='fb-share-icon' title='Facebook Share' src='" . SFSI_PLUGURL . "images/visit_icons/fbshare_bck.png" . "' /></a>";
260
+ return $fb_share_html;
261
+ }
262
+
263
  /* add all external javascript to wp_footer */
264
  function sfsi_footer_script()
265
  {
290
  $sfsi_section6['sfsi_show_Onposts'] = isset($sfsi_section6['sfsi_show_Onposts']) && !empty($sfsi_section6['sfsi_show_Onposts']) ? $sfsi_section6['sfsi_show_Onposts'] : "no";
291
  if ($sfsi_section1['sfsi_facebook_display'] == "yes") {
292
  // var_dump($sfsi_section6['sfsi_rectfb'],$sfsi_section6['sfsi_show_Onposts']);
293
+ if ((($sfsi_section6['sfsi_rectfb'] == "yes" ) && $sfsi_section6['sfsi_show_Onposts'] == "yes") || $sisi_common_options_check && ($sfsi_section2['sfsi_facebookLike_option'] == "yes")) {
294
  ?>
295
  <!--facebook like and share js -->
296
  <div id="fb-root"></div>
307
  <?php
308
  }
309
  }
310
+ $isYoutubeFollowFeatureActive = (
311
+ "yes" == $sfsi_section2['sfsi_youtube_follow']) &&
312
+ (
313
+ isset($sfsi_section2['sfsi_youtubeusernameorid']) &&
314
+ !empty($sfsi_section2['sfsi_youtubeusernameorid'])
315
+ ) &&
316
+ (
317
+ (
318
+ "name" == $sfsi_section2['sfsi_youtubeusernameorid'] &&
319
+ isset($sfsi_section2['sfsi_ytube_user']) &&
320
+ !empty($sfsi_section2['sfsi_ytube_user'])
321
+ ) ||
322
+ (
323
+ "id" == $sfsi_section2['sfsi_youtubeusernameorid'] &&
324
+ isset($sfsi_section2['sfsi_ytube_chnlid']) &&
325
+ !empty($sfsi_section2['sfsi_ytube_chnlid'])
326
+ )
327
+ );
328
+ if ($sfsi_section1['sfsi_youtube_display'] == "yes" && $sisi_common_options_check && $isYoutubeFollowFeatureActive) {
329
+ ?>
330
+ <script type="text/javascript">
331
+ window.___gcfg = {
332
+ lang: 'en-US'
333
+ };
334
+ (function() {
335
+ var po = document.createElement('script');
336
+ po.type = 'text/javascript';
337
+ po.async = true;
338
+ po.src = 'https://apis.google.com/js/plusone.js';
339
+ var s = document.getElementsByTagName('script')[0];
340
+ s.parentNode.insertBefore(po, s);
341
+ })();
342
+ </script>
343
+ <?php
344
  }
345
+ $isLinkedInFollowFeatureActive = (isset($sfsi_section2['sfsi_linkedin_follow']) && !empty($sfsi_section2['sfsi_linkedin_follow']) && ("yes" == $sfsi_section2['sfsi_linkedin_follow']) && isset($sfsi_section2['sfsi_linkedin_followCompany']) && !empty($sfsi_section2['sfsi_linkedin_followCompany']));
346
 
347
+ $isLinkedInRecommnedFeatureActive = (isset($sfsi_section2['sfsi_linkedin_recommendBusines']) && !empty($sfsi_section2['sfsi_linkedin_recommendBusines']) && ("yes" == $sfsi_section2['sfsi_linkedin_recommendBusines'])
348
+ && isset($sfsi_section2['sfsi_linkedin_recommendProductId']) && !empty($sfsi_section2['sfsi_linkedin_recommendProductId'])
349
+ && isset($sfsi_section2['sfsi_linkedin_recommendCompany']) && !empty($sfsi_section2['sfsi_linkedin_recommendCompany']));
350
 
351
+ if ($sfsi_section1['sfsi_linkedin_display'] == "yes" && ( $isLinkedInFollowFeatureActive || $isLinkedInRecommnedFeatureActive) && $sisi_common_options_check) {
352
+ ?>
353
+ <script src="//platform.linkedin.com/in.js" type="text/javascript">
354
+ lang: en_US
355
+ </script>
356
+ <?php
 
 
 
 
 
 
 
357
  }
358
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  /* activate footer credit link */
360
  if (get_option('sfsi_footer_sec') == "yes") {
361
  if (!is_admin()) {
428
  "show_count" => "no",
429
  "counter_color" => "#aaaaaa",
430
  "counter_bg_color" => "#fff",
431
+ "share_count_text" => "SHARES",
432
+ "margin_above" => 10,
433
+ "margin_below" => 10,
434
+
435
  )
436
  );
437
  } else {
441
  $twitter_text = isset($option2['sfsi_twitter_aboutPageText']) && !empty($option2['sfsi_twitter_aboutPageText']) ? $option2['sfsi_twitter_aboutPageText'] : false;
442
 
443
  $icon_width_type = $sfsi_responsive_icons["settings"]["icon_width_type"];
444
+ $margin_above = $sfsi_responsive_icons["settings"]["margin_above"];
445
+ $margin_below = $sfsi_responsive_icons["settings"]["margin_below"];
446
  if ($option4['sfsi_display_counts'] == 'yes' && isset($sfsi_responsive_icons["settings"]['show_count']) && $sfsi_responsive_icons["settings"]['show_count'] == "yes") :
447
  $counter_class = "sfsi_responsive_with_counter_icons";
448
  $couter_display = "inline-block";
460
  $counter_class = "sfsi_responsive_without_counter_icons";
461
  $couter_display = "none";
462
  endif;
463
+ $icons .= "<div class='sfsi_responsive_icons' style='display:inline-block;margin-top:".$margin_above."px; margin-bottom: ".$margin_below."px; " . ($icon_width_type == "Fully Responsive" ? "width:100%;display:flex; " : 'width:100%') . "' data-icon-width-type='" . $icon_width_type . "' data-icon-width-size='" . $sfsi_responsive_icons["settings"]['icon_width_size'] . "' data-edge-type='" . $sfsi_responsive_icons["settings"]['edge_type'] . "' data-edge-radius='" . $sfsi_responsive_icons["settings"]['edge_radius'] . "' >";
464
  $sfsi_anchor_div_style = "";
465
  if ($sfsi_responsive_icons["settings"]["edge_type"] === "Round") {
466
  $sfsi_anchor_div_style .= " border-radius:";
libs/sfsi_Init_JqueryCss.php CHANGED
@@ -1,133 +1,133 @@
1
- <?php
2
- /* instalation of javascript and css */
3
- function theme_back_enqueue_script()
4
- {
5
- if (isset($_GET['page'])) {
6
- if ($_GET['page'] == 'sfsi-options') {
7
- wp_enqueue_style("SFSImainAdminCss", SFSI_PLUGURL . 'css/sfsi-admin-style.css');
8
- /* include CSS for backend */
9
- wp_enqueue_style('thickbox');
10
- wp_enqueue_style("SFSImainCss", SFSI_PLUGURL . 'css/sfsi-style.css');
11
- wp_enqueue_style("SFSIJqueryCSS", SFSI_PLUGURL . 'css/jquery-ui-1.10.4/jquery-ui-min.css');
12
- wp_enqueue_style("wp-color-picker");
13
- }
14
- }
15
-
16
- //including floating option css
17
- $option9 = unserialize(get_option('sfsi_section9_options', false));
18
-
19
- if ($option9['sfsi_disable_floaticons'] == 'yes') {
20
- wp_enqueue_style("disable_sfsi", SFSI_PLUGURL . 'css/disable_sfsi.css');
21
- }
22
-
23
- if (isset($_GET['page'])) {
24
- if ($_GET['page'] == 'sfsi-options') {
25
- wp_enqueue_script('jquery');
26
- wp_enqueue_script("jquery-migrate");
27
-
28
- wp_enqueue_script('media-upload');
29
- wp_enqueue_script('thickbox');
30
-
31
- wp_register_script('SFSIJqueryFRM', SFSI_PLUGURL . 'js/jquery.form-min.js', '', '', true);
32
- wp_enqueue_script("SFSIJqueryFRM");
33
- wp_enqueue_script("jquery-ui-accordion");
34
- wp_enqueue_script("wp-color-picker");
35
- wp_enqueue_script("jquery-effects-core");
36
- wp_enqueue_script("jquery-ui-sortable");
37
-
38
- wp_register_script('SFSICustomFormJs', SFSI_PLUGURL . 'js/custom-form-min.js', '', '', true);
39
- wp_enqueue_script("SFSICustomFormJs");
40
-
41
- wp_register_script('SFSICustomJs', SFSI_PLUGURL . 'js/custom-admin.js', '', '', true);
42
- wp_enqueue_script("SFSICustomJs");
43
- /* end cusotm js */
44
-
45
- /* initilaize the ajax url in javascript */
46
- wp_localize_script('SFSICustomJs', 'sfsi_icon_ajax_object', array('ajax_url' => admin_url('admin-ajax.php')));
47
- wp_localize_script('SFSICustomJs', 'sfsi_icon_ajax_object', array('ajax_url' => admin_url('admin-ajax.php'), 'plugin_url' => SFSI_PLUGURL));
48
- }
49
- }
50
- }
51
- add_action('admin_enqueue_scripts', 'theme_back_enqueue_script');
52
-
53
- function theme_front_enqueue_script()
54
- {
55
- wp_enqueue_script('jquery');
56
- wp_enqueue_script("jquery-migrate");
57
-
58
- wp_enqueue_script('jquery-ui-core');
59
-
60
- wp_register_script('SFSIjqueryModernizr', SFSI_PLUGURL . 'js/shuffle/modernizr.custom.min.js', array('jquery'), '', true);
61
- wp_enqueue_script("SFSIjqueryModernizr");
62
-
63
- wp_register_script('SFSIjqueryShuffle', SFSI_PLUGURL . 'js/shuffle/jquery.shuffle.min.js', array('jquery'), '', true);
64
- wp_enqueue_script("SFSIjqueryShuffle");
65
-
66
- wp_register_script('SFSIjqueryrandom-shuffle', SFSI_PLUGURL . 'js/shuffle/random-shuffle-min.js', array('jquery'), '', true);
67
- wp_enqueue_script("SFSIjqueryrandom-shuffle");
68
- $option1 = unserialize(get_option('sfsi_section1_options', false));
69
-
70
- if (isset($option1["sfsi_wechat_display"]) && $option1["sfsi_wechat_display"] == "yes") {
71
- wp_register_script('SFSIPLUSqrcode.js', SFSI_PLUGURL . 'js/qrcode.min.js', '', '', true);
72
- wp_enqueue_script("SFSIPLUSqrcode.js");
73
- }
74
- wp_register_script('SFSICustomJs', SFSI_PLUGURL . 'js/custom.js', array('jquery'), '', true);
75
- wp_enqueue_script("SFSICustomJs");
76
- /* end cusotm js */
77
-
78
- /* initilaize the ajax url in javascript */
79
- wp_localize_script('SFSICustomJs', 'sfsi_icon_ajax_object', array('ajax_url' => admin_url('admin-ajax.php')));
80
- wp_localize_script('SFSICustomJs', 'sfsi_icon_ajax_object', array('ajax_url' => admin_url('admin-ajax.php'), 'plugin_url' => SFSI_PLUGURL));
81
-
82
- /* include CSS for front-end and backend */
83
- wp_enqueue_style("SFSImainCss", SFSI_PLUGURL . 'css/sfsi-style.css', true);
84
-
85
- //including floating option css
86
- $option9 = unserialize(get_option('sfsi_section9_options', false));
87
- if ($option9['sfsi_disable_floaticons'] == 'yes') {
88
- wp_enqueue_style("disable_sfsi", SFSI_PLUGURL . 'css/disable_sfsi.css');
89
- }
90
- }
91
- add_action('wp_enqueue_scripts', 'theme_front_enqueue_script');
92
-
93
- function sfsi_footerFeedbackScript()
94
- {
95
- ?>
96
- <style>
97
- @charset "utf-8";
98
- @font-face {
99
- font-family: helveticabold;
100
- src: url(<?php echo SFSI_PLUGURL; ?>css/fonts/helvetica_bold_0-webfont.eot);
101
- src: url(<?php echo SFSI_PLUGURL; ?>css/fonts/helvetica_bold_0-webfont.eot?#iefix) format('embedded-opentype'), url(<?php echo SFSI_PLUGURL; ?>css/fonts/helvetica_bold_0-webfont.woff) format('woff'), url(<?php echo SFSI_PLUGURL; ?>css/fonts/helvetica_bold_0-webfont.ttf) format('truetype'), url(<?php echo SFSI_PLUGURL; ?>css/fonts/helvetica_bold_0-webfont.svg#helveticabold) format('svg');
102
- font-weight: 400;
103
- font-style: normal;
104
- }
105
- ul#adminmenu li.toplevel_page_sfsi-options div.wp-menu-image {
106
- display: none;
107
- }
108
- #adminmenu li.toplevel_page_sfsi-options a.toplevel_page_sfsi-options {
109
- padding: 0 0 0 38px;
110
- font-family: helveticabold;
111
- }
112
- ul#adminmenu li.toplevel_page_sfsi-options a.toplevel_page_sfsi-options {
113
- color: #e12522;
114
- transition: 0s;
115
- background: url(<?php echo SFSI_PLUGURL; ?>css/images/left_log_icn.png) 6px 15px no-repeat #23282d;
116
- background: url(<?php echo SFSI_PLUGURL; ?>css/images/left_log_icn.png) 6px -43px no-repeat #23282d;
117
- color: #fafafa;
118
- font-family: Arial, Helvetica, sans-serif;
119
- }
120
- ul#adminmenu li.toplevel_page_sfsi-options a.toplevel_page_sfsi-options:hover {
121
- background: url(<?php echo SFSI_PLUGURL; ?>css/images/left_log_icn.png) 6px -43px no-repeat black;
122
- color: #fafafa;
123
- }
124
- ul#adminmenu li.toplevel_page_sfsi-options a.current,
125
- ul#adminmenu li.toplevel_page_sfsi-options a.current:hover {
126
- background: url(<?php echo SFSI_PLUGURL; ?>css/images/left_log_icn.png) 6px 15px no-repeat #000000;
127
- color: #e12522;
128
- }
129
- </style>
130
- <?php
131
- }
132
- add_action('admin_footer', 'sfsi_footerFeedbackScript');
133
  ?>
1
+ <?php
2
+ /* instalation of javascript and css */
3
+ function theme_back_enqueue_script()
4
+ {
5
+ if (isset($_GET['page'])) {
6
+ if ($_GET['page'] == 'sfsi-options') {
7
+ wp_enqueue_style("SFSImainAdminCss", SFSI_PLUGURL . 'css/sfsi-admin-style.css');
8
+ /* include CSS for backend */
9
+ wp_enqueue_style('thickbox');
10
+ wp_enqueue_style("SFSImainCss", SFSI_PLUGURL . 'css/sfsi-style.css');
11
+ wp_enqueue_style("SFSIJqueryCSS", SFSI_PLUGURL . 'css/jquery-ui-1.10.4/jquery-ui-min.css');
12
+ wp_enqueue_style("wp-color-picker");
13
+ }
14
+ }
15
+
16
+ //including floating option css
17
+ $option9 = unserialize(get_option('sfsi_section9_options', false));
18
+
19
+ if ($option9['sfsi_disable_floaticons'] == 'yes') {
20
+ wp_enqueue_style("disable_sfsi", SFSI_PLUGURL . 'css/disable_sfsi.css');
21
+ }
22
+
23
+ if (isset($_GET['page'])) {
24
+ if ($_GET['page'] == 'sfsi-options') {
25
+ wp_enqueue_script('jquery');
26
+ wp_enqueue_script("jquery-migrate");
27
+
28
+ wp_enqueue_script('media-upload');
29
+ wp_enqueue_script('thickbox');
30
+
31
+ wp_register_script('SFSIJqueryFRM', SFSI_PLUGURL . 'js/jquery.form-min.js', '', '', true);
32
+ wp_enqueue_script("SFSIJqueryFRM");
33
+ wp_enqueue_script("jquery-ui-accordion");
34
+ wp_enqueue_script("wp-color-picker");
35
+ wp_enqueue_script("jquery-effects-core");
36
+ wp_enqueue_script("jquery-ui-sortable");
37
+
38
+ wp_register_script('SFSICustomFormJs', SFSI_PLUGURL . 'js/custom-form-min.js', '', '', true);
39
+ wp_enqueue_script("SFSICustomFormJs");
40
+
41
+ wp_register_script('SFSICustomJs', SFSI_PLUGURL . 'js/custom-admin.js', '', '', true);
42
+ wp_enqueue_script("SFSICustomJs");
43
+ /* end cusotm js */
44
+
45
+ /* initilaize the ajax url in javascript */
46
+ wp_localize_script('SFSICustomJs', 'sfsi_icon_ajax_object', array('ajax_url' => admin_url('admin-ajax.php')));
47
+ wp_localize_script('SFSICustomJs', 'sfsi_icon_ajax_object', array('ajax_url' => admin_url('admin-ajax.php'), 'plugin_url' => SFSI_PLUGURL));
48
+ }
49
+ }
50
+ }
51
+ add_action('admin_enqueue_scripts', 'theme_back_enqueue_script');
52
+
53
+ function theme_front_enqueue_script()
54
+ {
55
+ wp_enqueue_script('jquery');
56
+ wp_enqueue_script("jquery-migrate");
57
+
58
+ wp_enqueue_script('jquery-ui-core');
59
+
60
+ wp_register_script('SFSIjqueryModernizr', SFSI_PLUGURL . 'js/shuffle/modernizr.custom.min.js', array('jquery'), '', true);
61
+ wp_enqueue_script("SFSIjqueryModernizr");
62
+
63
+ wp_register_script('SFSIjqueryShuffle', SFSI_PLUGURL . 'js/shuffle/jquery.shuffle.min.js', array('jquery'), '', true);
64
+ wp_enqueue_script("SFSIjqueryShuffle");
65
+
66
+ wp_register_script('SFSIjqueryrandom-shuffle', SFSI_PLUGURL . 'js/shuffle/random-shuffle-min.js', array('jquery'), '', true);
67
+ wp_enqueue_script("SFSIjqueryrandom-shuffle");
68
+ $option1 = unserialize(get_option('sfsi_section1_options', false));
69
+
70
+ if (isset($option1["sfsi_wechat_display"]) && $option1["sfsi_wechat_display"] == "yes") {
71
+ wp_register_script('SFSIPLUSqrcode.js', SFSI_PLUGURL . 'js/qrcode.min.js', '', '', true);
72
+ wp_enqueue_script("SFSIPLUSqrcode.js");
73
+ }
74
+ wp_register_script('SFSICustomJs', SFSI_PLUGURL . 'js/custom.js', array('jquery'), '', true);
75
+ wp_enqueue_script("SFSICustomJs");
76
+ /* end cusotm js */
77
+
78
+ /* initilaize the ajax url in javascript */
79
+ wp_localize_script('SFSICustomJs', 'sfsi_icon_ajax_object', array('ajax_url' => admin_url('admin-ajax.php')));
80
+ wp_localize_script('SFSICustomJs', 'sfsi_icon_ajax_object', array('ajax_url' => admin_url('admin-ajax.php'), 'plugin_url' => SFSI_PLUGURL));
81
+
82
+ /* include CSS for front-end and backend */
83
+ wp_enqueue_style("SFSImainCss", SFSI_PLUGURL . 'css/sfsi-style.css', true);
84
+
85
+ //including floating option css
86
+ $option9 = unserialize(get_option('sfsi_section9_options', false));
87
+ if ($option9['sfsi_disable_floaticons'] == 'yes') {
88
+ wp_enqueue_style("disable_sfsi", SFSI_PLUGURL . 'css/disable_sfsi.css');
89
+ }
90
+ }
91
+ add_action('wp_enqueue_scripts', 'theme_front_enqueue_script');
92
+
93
+ function sfsi_footerFeedbackScript()
94
+ {
95
+ ?>
96
+ <style>
97
+ @charset "utf-8";
98
+ @font-face {
99
+ font-family: helveticabold;
100
+ src: url(<?php echo SFSI_PLUGURL; ?>css/fonts/helvetica_bold_0-webfont.eot);
101
+ src: url(<?php echo SFSI_PLUGURL; ?>css/fonts/helvetica_bold_0-webfont.eot?#iefix) format('embedded-opentype'), url(<?php echo SFSI_PLUGURL; ?>css/fonts/helvetica_bold_0-webfont.woff) format('woff'), url(<?php echo SFSI_PLUGURL; ?>css/fonts/helvetica_bold_0-webfont.ttf) format('truetype'), url(<?php echo SFSI_PLUGURL; ?>css/fonts/helvetica_bold_0-webfont.svg#helveticabold) format('svg');
102
+ font-weight: 400;
103
+ font-style: normal;
104
+ }
105
+ ul#adminmenu li.toplevel_page_sfsi-options div.wp-menu-image {
106
+ display: none;
107
+ }
108
+ #adminmenu li.toplevel_page_sfsi-options a.toplevel_page_sfsi-options {
109
+ padding: 0 0 0 38px;
110
+ font-family: helveticabold;
111
+ }
112
+ ul#adminmenu li.toplevel_page_sfsi-options a.toplevel_page_sfsi-options {
113
+ color: #e12522;
114
+ transition: 0s;
115
+ background: url(<?php echo SFSI_PLUGURL; ?>css/images/left_log_icn.png) 6px 15px no-repeat #23282d;
116
+ background: url(<?php echo SFSI_PLUGURL; ?>css/images/left_log_icn.png) 6px -43px no-repeat #23282d;
117
+ color: #fafafa;
118
+ font-family: Arial, Helvetica, sans-serif;
119
+ }
120
+ ul#adminmenu li.toplevel_page_sfsi-options a.toplevel_page_sfsi-options:hover {
121
+ background: url(<?php echo SFSI_PLUGURL; ?>css/images/left_log_icn.png) 6px -43px no-repeat black;
122
+ color: #fafafa;
123
+ }
124
+ ul#adminmenu li.toplevel_page_sfsi-options a.current,
125
+ ul#adminmenu li.toplevel_page_sfsi-options a.current:hover {
126
+ background: url(<?php echo SFSI_PLUGURL; ?>css/images/left_log_icn.png) 6px 15px no-repeat #000000;
127
+ color: #e12522;
128
+ }
129
+ </style>
130
+ <?php
131
+ }
132
+ add_action('admin_footer', 'sfsi_footerFeedbackScript');
133
  ?>
libs/sfsi_ajax_social_sharing_settings_updater.php CHANGED
@@ -1,16 +1,16 @@
1
- <?php
2
- add_action( 'wp_ajax_update_sharing_settings', 'update_sharing_settings' );
3
-
4
- function update_sharing_settings() {
5
- if ( !wp_verify_nonce( $_POST['nonce'], "update_sharing_settings")) {
6
- echo json_encode(array('res'=>"error")); exit;
7
- }
8
- if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
9
-
10
- $option5 = unserialize(get_option('sfsi_section5_options',false));
11
- $option5['sfsi_custom_social_hide'] = $_POST['sfsi_custom_social_hide'];
12
- update_option('sfsi_section5_options',serialize($option5));
13
- echo true;
14
- wp_die(); // this is required to terminate immediately and return a proper response
15
- }
16
  ?>
1
+ <?php
2
+ add_action( 'wp_ajax_update_sharing_settings', 'update_sharing_settings' );
3
+
4
+ function update_sharing_settings() {
5
+ if ( !wp_verify_nonce( $_POST['nonce'], "update_sharing_settings")) {
6
+ echo json_encode(array('res'=>"error")); exit;
7
+ }
8
+ if(!current_user_can('manage_options')){ echo json_encode(array('res'=>'not allowed'));die(); }
9
+
10
+ $option5 = unserialize(get_option('sfsi_section5_options',false));
11
+ $option5['sfsi_custom_social_hide'] = $_POST['sfsi_custom_social_hide'];
12
+ update_option('sfsi_section5_options',serialize($option5));
13
+ echo true;
14
+ wp_die(); // this is required to terminate immediately and return a proper response
15
+ }
16
  ?>
libs/sfsi_install_uninstall.php CHANGED
@@ -39,7 +39,7 @@ function sfsi_update_plugin()
39
  update_option("sfsi_custom_icons", "yes");
40
  }
41
  //Install version
42
- update_option("sfsi_pluginVersion", "2.46");
43
 
44
  if (!get_option('sfsi_serverphpVersionnotification')) {
45
  add_option("sfsi_serverphpVersionnotification", "yes");
39
  update_option("sfsi_custom_icons", "yes");
40
  }
41
  //Install version
42
+ update_option("sfsi_pluginVersion", "2.47");
43
 
44
  if (!get_option('sfsi_serverphpVersionnotification')) {
45
  add_option("sfsi_serverphpVersionnotification", "yes");
libs/sfsi_widget.php CHANGED
@@ -41,7 +41,7 @@ class Sfsi_Widget extends WP_Widget
41
  /* Display the widget title */
42
  if ($title) echo $before_title . $title . $after_title;
43
  ?>
44
- <div class="sfsi_widget" data-position="widget" style="display:flex;justify-content:<?php echo $icons_alignment_widget; ?>">
45
  <div id='sfsi_wDiv'></div>
46
  <?php
47
  /* Link the main icons function */
@@ -283,16 +283,15 @@ class Sfsi_Widget extends WP_Widget
283
  $main_width = $main_width . "px";
284
  } else {
285
  $width = ((int) $icons_space + (int) $icons_size);
286
- $main_width = "35%";
287
  }
288
 
289
 
290
 
291
  /* built the main widget div */
292
  if ($shortcode) {
293
- $icons_main = '<div class="norm_row sfsi_wDiv " style="width:' . $main_width . ';text-align:' . $icons_alignment . ';">';
294
  } else {
295
- $icons_main = '<div class="norm_row sfsi_wDiv " style="width:' . $main_width . ';text-align:' . $icons_alignment . ';' . $position1 . '">';
296
  }
297
  $icons = "";
298
  /* loop through icons and bulit the icons with all settings applied in admin */
41
  /* Display the widget title */
42
  if ($title) echo $before_title . $title . $after_title;
43
  ?>
44
+ <div class="sfsi_widget" data-position="widget" style="display:flex;flex-wrap:wrap;">
45
  <div id='sfsi_wDiv'></div>
46
  <?php
47
  /* Link the main icons function */
283
  $main_width = $main_width . "px";
284
  } else {
285
  $width = ((int) $icons_space + (int) $icons_size);
 
286
  }
287
 
288
 
289
 
290
  /* built the main widget div */
291
  if ($shortcode) {
292
+ $icons_main = '<div class="norm_row sfsi_wDiv " style="' . (isset($main_width)?'width:'.$main_width:'') . ';text-align:' . $icons_alignment . ';">';
293
  } else {
294
+ $icons_main = '<div class="norm_row sfsi_wDiv " style="' . (isset($main_width)?'width:'.$main_width. ';' . $position1:'') . ';text-align:' . $icons_alignment . '">';
295
  }
296
  $icons = "";
297
  /* loop through icons and bulit the icons with all settings applied in admin */
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: socialdude, socialtech
3
  Tags: social media, share, buttons, social widget, icons, share icons, share buttons, sharing icons, sharing buttons, social share, sharing, social sharing
4
  Requires at least: 3.5
5
  Tested up to: 5.3
6
- Stable tag: 2.4.6
7
  License: GPLv2
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -275,6 +275,11 @@ You cannot use the same plugin twice, however you can install both the USM as we
275
 
276
  == Changelog ==
277
 
 
 
 
 
 
278
  = 2.4.6 =
279
  * Updated Tweet about my page can be empty.
280
  * Updated Export section aligned center to button.
@@ -894,5 +899,5 @@ You cannot use the same plugin twice, however you can install both the USM as we
894
 
895
  == Upgrade Notice ==
896
 
897
- = 2.4.6 =
898
  Please upgrade
3
  Tags: social media, share, buttons, social widget, icons, share icons, share buttons, sharing icons, sharing buttons, social share, sharing, social sharing
4
  Requires at least: 3.5
5
  Tested up to: 5.3
6
+ Stable tag: 2.4.7
7
  License: GPLv2
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
275
 
276
  == Changelog ==
277
 
278
+ = 2.4.7 =
279
+ * Added Margins above and below responsive icons
280
+ * Updated the display for widget
281
+ * Replaced with icons which reduces the loading time
282
+
283
  = 2.4.6 =
284
  * Updated Tweet about my page can be empty.
285
  * Updated Export section aligned center to button.
899
 
900
  == Upgrade Notice ==
901
 
902
+ = 2.4.7 =
903
  Please upgrade
ultimate_social_media_icons.php CHANGED
@@ -6,7 +6,7 @@ Description: Easy to use and 100% FREE social media plugin which adds social med
6
 
7
  Author: UltimatelySocial
8
  Author URI: http://ultimatelysocial.com
9
- Version: 2.4.6
10
  License: GPLv2 or later
11
  */
12
  require_once 'analyst/main.php';
@@ -88,7 +88,7 @@ register_deactivation_hook(__FILE__, 'sfsi_deactivate_plugin');
88
 
89
  register_uninstall_hook(__FILE__, 'sfsi_Unistall_plugin');
90
 
91
- if (!get_option('sfsi_pluginVersion') || get_option('sfsi_pluginVersion') < 2.46) {
92
 
93
  add_action("init", "sfsi_update_plugin");
94
  }
6
 
7
  Author: UltimatelySocial
8
  Author URI: http://ultimatelysocial.com
9
+ Version: 2.4.7
10
  License: GPLv2 or later
11
  */
12
  require_once 'analyst/main.php';
88
 
89
  register_uninstall_hook(__FILE__, 'sfsi_Unistall_plugin');
90
 
91
+ if (!get_option('sfsi_pluginVersion') || get_option('sfsi_pluginVersion') < 2.47) {
92
 
93
  add_action("init", "sfsi_update_plugin");
94
  }
views/deactivation/sfsi_deactivation_popup.php CHANGED
@@ -1,122 +1,122 @@
1
- <style>
2
- .sfsi-top-header .sfsi-sad-image,.sfsi-top-header h2{vertical-align:middle;display:inline-block}.banner_support_forum{margin:50px auto;text-align:center;width:80%}.banner_support_forum .banner-1 img{width:100%}.sfsi-deactivation-popup{width:100%;height:100%;display:none;position:fixed;top:0;left:0;background:rgba(0,0,0,.75)}.sfsi-deactivation-popup-content{max-width:540px;width:90%;position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);box-shadow:0 2px 6px rgba(0,0,0,1);border-radius:3px;background:#fff}.sfsi-deactivation-popup-close{padding:0 5px 3px;display:inline-block;position:absolute;top:25px;right:25px;transition:ease .25s all;-webkit-transform:translate(50%,-50%);transform:translate(50%,-50%);border-radius:100%;background:#FEFEFE;font-size:20px;text-align:center;line-height:100%;color:#acacac;border:1px solid #acacac;text-decoration:none}.sfsi-deactivation-popup-close:active,.sfsi-deactivation-popup-close:focus,.sfsi-deactivation-popup-close:hover{color:#acacac;border:1px solid #acacac}.sfsi-deactivation-popup-close:focus{box-shadow:none!important}.sfsi-top-header{text-align:center;padding:30px 30px 0}.sfsi-top-header h2{font-size:22.92px;margin-right:12px}.sfsi-popup-content{padding:0 30px}.sfsi-text{text-align:center;padding-bottom:14px}.sfsi-text .sfsi-please{font-size:16.92px;font-weight:900;display:inline;text-decoration:none!important;border-bottom:1px solid #000!important}.sfsi-text .sfsi-please-other-text{font-size:14.92px;display:inline}.sfsi-go-to-support{text-align:center}.sfsi-go-to-support .go-to-support-forum{display:inline-block;background:#26B654;padding:14px 35px;font-size:19.34px;color:#fff;text-decoration:none;font-weight:700}.sfsi-info-text{text-align:center;margin-left:auto;width:70%;margin-right:auto;padding-top:10px;padding-bottom:23px}.sfsi-info-text p{font-size:9.31px!important}.sfsi-popup-footer{border-top:2px solid #f2f2f2}.sfsi-popup-footer .sfsi-deactivation-reason-link{text-align:center;padding:28px}.sfsi-popup-footer .sfsi-deactivation-reason-link a{text-decoration:none!important;font-size:12.73px;color:#000;border-bottom:1px Solid #000}.sfsi-radio-button-content{padding:23px 30px}.sfsi-deactivate-radio-text{font-size:16.92px!important;display:inline-block;margin:10px 0;padding-top:5px;cursor:pointer}.sfsi-reason-1-section .sfsi-popup-content .sfsi-text .sfsi-please-other-text img,.sfsi-reason-2-section .sfsi-popup-content .sfsi-text .sfsi-please-other-text img{vertical-align:middle!important;width:16px!important;margin-bottom:3px!important}.sfsi-deactivate-radio-text .sfsi-bold-text{font-weight:700!important}.sfsi-reason-1-section .sfsi-popup-content .sfsi-text,.sfsi-reason-3-section .sfsi-popup-content .sfsi-text{text-align:left;padding-top:10px;padding-bottom:14px;padding-left:23px}.sfsi-reason-1-section .sfsi-popup-content,.sfsi-reason-2-section .sfsi-popup-content,.sfsi-reason-3-section .sfsi-popup-content{padding:0!important}.sfsi-reason-1-section .sfsi-popup-content .sfsi-text .sfsi-please{border-bottom:none!important}.sfsi-premium-version-text{color:#5489D0!important;text-decoration:none;font-weight:700}.sfsi-just-deactivate-it{text-align:center}.sfsi-just-deactivate-it a{text-decoration:none!important;font-size:13.73px;color:#000;border-bottom:1px solid #000}.show{display:block}.hide{display:none}.marginbottom{margin-bottom:15px}
3
-
4
- </style>
5
-
6
- <div class="sfsi-deactivation-popup" data-popup="popup-1">
7
-
8
- <div class="sfsi-deactivation-popup-content">
9
-
10
- <div class="sfsi-popup-header sfsi-top-header">
11
- <h2>Oh! You don\'t like our plugin?</h2>
12
- <div class="sfsi-sad-image">
13
- <img src="<?php echo SFSI_PLUGURL; ?>images/sad_image.png" alt="error">
14
- </div>
15
- </div>
16
-
17
- <div class="sfsi-popup-content">
18
- <div class="sfsi-text">
19
- <p class="sfsi-please">PLEASE</p>
20
- <p class="sfsi-please-other-text">let us know in the Support Forum what was the issue, <br>so that we can fix it. We‘ll respond quickly!</p>
21
- </div>
22
- <div class="sfsi-go-to-support">
23
- <a target="_blank" href="<?php echo SFSI_SUPPORT_FORM; ?>" class="go-to-support-forum">Go to Support Forum></a>
24
- </div>
25
- <div class="sfsi-info-text">
26
- <p>If you're not a Wordpress user yet, please sign up – it's quick! Once logged in you‘ll see a section at the bottom where you can ask your question.</p>
27
- </div>
28
- </div>
29
- <div class="sfsi-popup-footer">
30
- <div class="sfsi-deactivation-reason-link">
31
- <a href="javascript:void(0)">No, don't worry, there was a different reason, I want to de-activate it</a>
32
- </div>
33
- </div>
34
-
35
- <a href="javascript:void(0)" class="sfsi-deactivation-popup-close" data-popup-close="popup-1">&times;</a>
36
-
37
- </div>
38
-
39
- </div>
40
-
41
- <div class="sfsi-deactivation-popup" data-popup="popup-2">
42
-
43
- <div class="sfsi-deactivation-popup-content">
44
-
45
- <!-- Radio buttons START-->
46
- <div class="sfsi-radio-button-content">
47
-
48
- <form>
49
-
50
- <div class="sfsi-reason-container">
51
-
52
- <input type="radio" class="sfsi-deactivate-radio" name="reason" value="0">
53
- <p class="sfsi-deactivate-radio-text">The plugin <span class="sfsi-bold-text">doesn't work for me</span></p>
54
-
55
- <div class="sfsi-reason-section hide">
56
- <div class="sfsi-popup-content">
57
- <div class="sfsi-text">
58
- <p class="sfsi-please">PLEASE</p>
59
- <p class="sfsi-please-other-text">let us know in the Support Forum what didn't work, <br>so that we can fix it. We‘ll respond quickly! <img src="<?php echo SFSI_PLUGURL; ?>images/smile.png" alt="error"></p>
60
- </div>
61
- <div class="sfsi-go-to-support">
62
- <a target="_blank" href="<?php echo SFSI_SUPPORT_FORM; ?>" class="go-to-support-forum">Go to Support Forum ></a>
63
- </div>
64
- <div class="sfsi-info-text">
65
- <p>If you‘re not a Wordpress user yet, please sign up – it‘s quick! Once logged in you‘ll see a section at the bottom where you can ask your question. </p>
66
- </div>
67
- </div>
68
- </div>
69
-
70
- </div>
71
-
72
- <div class="sfsi-reason-container">
73
-
74
- <input type="radio" class="sfsi-deactivate-radio" name="reason" value="1">
75
- <p class="sfsi-deactivate-radio-text">I got the <a target="_blank" href="https://www.ultimatelysocial.com/usm-premium" class="sfsi-premium-version-text">premium version</a>!</p>
76
-
77
- <div class="sfsi-reason-section hide">
78
- <div class="sfsi-popup-content">
79
- <div class="sfsi-text">
80
- <p class="sfsi-please-other-text">Thumbs up to that one! <img src="<?php echo SFSI_PLUGURL; ?>images/smile.png" alt="error"></p>
81
- </div>
82
- <div class="sfsi-go-to-support">
83
- <a href="javascript:void(0)" class="sfsi-deactive-plugin go-to-support-forum">De-activate plugin now</a>
84
- </div>
85
- </div>
86
- </div>
87
-
88
- </div>
89
- <div class="sfsi-reason-container">
90
-
91
- <input type="radio" class="sfsi-deactivate-radio" name="reason" value="2">
92
- <p class="sfsi-deactivate-radio-text"><span class="sfsi-bold-text">Other</span></p>
93
-
94
- <div class="sfsi-reason-section hide">
95
- <div class="sfsi-popup-content marginbottom">
96
- <div class="sfsi-text">
97
- <p class="sfsi-please-other-text">Cool - if it was a reason we colud learn from, please let us know in the Support Forum.</p>
98
- </div>
99
- <div class="sfsi-go-to-support">
100
- <a target="_blank" href="<?php echo SFSI_SUPPORT_FORM; ?>" class="go-to-support-forum">Go to Support Forum ></a>
101
- </div>
102
- </div>
103
- </div>
104
- </div>
105
-
106
- <div class="sfsi-reason-container">
107
-
108
- <div class="sfsi-just-deactivate-it">
109
- <a href="javascript:void(0)" class="sfsi-deactive-plugin">Just de-activate it</a>
110
- </div>
111
-
112
- </div>
113
-
114
- </form>
115
-
116
- </div>
117
- <!-- Radio buttons END-->
118
-
119
- <a href="javascript:void(0)" class="sfsi-deactivation-popup-close" data-popup-close="popup-2">&times;</a>
120
-
121
- </div>
122
  </div>
1
+ <style>
2
+ .sfsi-top-header .sfsi-sad-image,.sfsi-top-header h2{vertical-align:middle;display:inline-block}.banner_support_forum{margin:50px auto;text-align:center;width:80%}.banner_support_forum .banner-1 img{width:100%}.sfsi-deactivation-popup{width:100%;height:100%;display:none;position:fixed;top:0;left:0;background:rgba(0,0,0,.75)}.sfsi-deactivation-popup-content{max-width:540px;width:90%;position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);box-shadow:0 2px 6px rgba(0,0,0,1);border-radius:3px;background:#fff}.sfsi-deactivation-popup-close{padding:0 5px 3px;display:inline-block;position:absolute;top:25px;right:25px;transition:ease .25s all;-webkit-transform:translate(50%,-50%);transform:translate(50%,-50%);border-radius:100%;background:#FEFEFE;font-size:20px;text-align:center;line-height:100%;color:#acacac;border:1px solid #acacac;text-decoration:none}.sfsi-deactivation-popup-close:active,.sfsi-deactivation-popup-close:focus,.sfsi-deactivation-popup-close:hover{color:#acacac;border:1px solid #acacac}.sfsi-deactivation-popup-close:focus{box-shadow:none!important}.sfsi-top-header{text-align:center;padding:30px 30px 0}.sfsi-top-header h2{font-size:22.92px;margin-right:12px}.sfsi-popup-content{padding:0 30px}.sfsi-text{text-align:center;padding-bottom:14px}.sfsi-text .sfsi-please{font-size:16.92px;font-weight:900;display:inline;text-decoration:none!important;border-bottom:1px solid #000!important}.sfsi-text .sfsi-please-other-text{font-size:14.92px;display:inline}.sfsi-go-to-support{text-align:center}.sfsi-go-to-support .go-to-support-forum{display:inline-block;background:#26B654;padding:14px 35px;font-size:19.34px;color:#fff;text-decoration:none;font-weight:700}.sfsi-info-text{text-align:center;margin-left:auto;width:70%;margin-right:auto;padding-top:10px;padding-bottom:23px}.sfsi-info-text p{font-size:9.31px!important}.sfsi-popup-footer{border-top:2px solid #f2f2f2}.sfsi-popup-footer .sfsi-deactivation-reason-link{text-align:center;padding:28px}.sfsi-popup-footer .sfsi-deactivation-reason-link a{text-decoration:none!important;font-size:12.73px;color:#000;border-bottom:1px Solid #000}.sfsi-radio-button-content{padding:23px 30px}.sfsi-deactivate-radio-text{font-size:16.92px!important;display:inline-block;margin:10px 0;padding-top:5px;cursor:pointer}.sfsi-reason-1-section .sfsi-popup-content .sfsi-text .sfsi-please-other-text img,.sfsi-reason-2-section .sfsi-popup-content .sfsi-text .sfsi-please-other-text img{vertical-align:middle!important;width:16px!important;margin-bottom:3px!important}.sfsi-deactivate-radio-text .sfsi-bold-text{font-weight:700!important}.sfsi-reason-1-section .sfsi-popup-content .sfsi-text,.sfsi-reason-3-section .sfsi-popup-content .sfsi-text{text-align:left;padding-top:10px;padding-bottom:14px;padding-left:23px}.sfsi-reason-1-section .sfsi-popup-content,.sfsi-reason-2-section .sfsi-popup-content,.sfsi-reason-3-section .sfsi-popup-content{padding:0!important}.sfsi-reason-1-section .sfsi-popup-content .sfsi-text .sfsi-please{border-bottom:none!important}.sfsi-premium-version-text{color:#5489D0!important;text-decoration:none;font-weight:700}.sfsi-just-deactivate-it{text-align:center}.sfsi-just-deactivate-it a{text-decoration:none!important;font-size:13.73px;color:#000;border-bottom:1px solid #000}.show{display:block}.hide{display:none}.marginbottom{margin-bottom:15px}
3
+
4
+ </style>
5
+
6
+ <div class="sfsi-deactivation-popup" data-popup="popup-1">
7
+
8
+ <div class="sfsi-deactivation-popup-content">
9
+
10
+ <div class="sfsi-popup-header sfsi-top-header">
11
+ <h2>Oh! You don\'t like our plugin?</h2>
12
+ <div class="sfsi-sad-image">
13
+ <img src="<?php echo SFSI_PLUGURL; ?>images/sad_image.png" alt="error">
14
+ </div>
15
+ </div>
16
+
17
+ <div class="sfsi-popup-content">
18
+ <div class="sfsi-text">
19
+ <p class="sfsi-please">PLEASE</p>
20
+ <p class="sfsi-please-other-text">let us know in the Support Forum what was the issue, <br>so that we can fix it. We‘ll respond quickly!</p>
21
+ </div>
22
+ <div class="sfsi-go-to-support">
23
+ <a target="_blank" href="<?php echo SFSI_SUPPORT_FORM; ?>" class="go-to-support-forum">Go to Support Forum></a>
24
+ </div>
25
+ <div class="sfsi-info-text">
26
+ <p>If you're not a Wordpress user yet, please sign up – it's quick! Once logged in you‘ll see a section at the bottom where you can ask your question.</p>
27
+ </div>
28
+ </div>
29
+ <div class="sfsi-popup-footer">
30
+ <div class="sfsi-deactivation-reason-link">
31
+ <a href="javascript:void(0)">No, don't worry, there was a different reason, I want to de-activate it</a>
32
+ </div>
33
+ </div>
34
+
35
+ <a href="javascript:void(0)" class="sfsi-deactivation-popup-close" data-popup-close="popup-1">&times;</a>
36
+
37
+ </div>
38
+
39
+ </div>
40
+
41
+ <div class="sfsi-deactivation-popup" data-popup="popup-2">
42
+
43
+ <div class="sfsi-deactivation-popup-content">
44
+
45
+ <!-- Radio buttons START-->
46
+ <div class="sfsi-radio-button-content">
47
+
48
+ <form>
49
+
50
+ <div class="sfsi-reason-container">
51
+
52
+ <input type="radio" class="sfsi-deactivate-radio" name="reason" value="0">
53
+ <p class="sfsi-deactivate-radio-text">The plugin <span class="sfsi-bold-text">doesn't work for me</span></p>
54
+
55
+ <div class="sfsi-reason-section hide">
56
+ <div class="sfsi-popup-content">
57
+ <div class="sfsi-text">
58
+ <p class="sfsi-please">PLEASE</p>
59
+ <p class="sfsi-please-other-text">let us know in the Support Forum what didn't work, <br>so that we can fix it. We‘ll respond quickly! <img src="<?php echo SFSI_PLUGURL; ?>images/smile.png" alt="error"></p>
60
+ </div>
61
+ <div class="sfsi-go-to-support">
62
+ <a target="_blank" href="<?php echo SFSI_SUPPORT_FORM; ?>" class="go-to-support-forum">Go to Support Forum ></a>
63
+ </div>
64
+ <div class="sfsi-info-text">
65
+ <p>If you‘re not a Wordpress user yet, please sign up – it‘s quick! Once logged in you‘ll see a section at the bottom where you can ask your question. </p>
66
+ </div>
67
+ </div>
68
+ </div>
69
+
70
+ </div>
71
+
72
+ <div class="sfsi-reason-container">
73
+
74
+ <input type="radio" class="sfsi-deactivate-radio" name="reason" value="1">
75
+ <p class="sfsi-deactivate-radio-text">I got the <a target="_blank" href="https://www.ultimatelysocial.com/usm-premium" class="sfsi-premium-version-text">premium version</a>!</p>
76
+
77
+ <div class="sfsi-reason-section hide">
78
+ <div class="sfsi-popup-content">
79
+ <div class="sfsi-text">
80
+ <p class="sfsi-please-other-text">Thumbs up to that one! <img src="<?php echo SFSI_PLUGURL; ?>images/smile.png" alt="error"></p>
81
+ </div>
82
+ <div class="sfsi-go-to-support">
83
+ <a href="javascript:void(0)" class="sfsi-deactive-plugin go-to-support-forum">De-activate plugin now</a>
84
+ </div>
85
+ </div>
86
+ </div>
87
+
88
+ </div>
89
+ <div class="sfsi-reason-container">
90
+
91
+ <input type="radio" class="sfsi-deactivate-radio" name="reason" value="2">
92
+ <p class="sfsi-deactivate-radio-text"><span class="sfsi-bold-text">Other</span></p>
93
+
94
+ <div class="sfsi-reason-section hide">
95
+ <div class="sfsi-popup-content marginbottom">
96
+ <div class="sfsi-text">
97
+ <p class="sfsi-please-other-text">Cool - if it was a reason we colud learn from, please let us know in the Support Forum.</p>
98
+ </div>
99
+ <div class="sfsi-go-to-support">
100
+ <a target="_blank" href="<?php echo SFSI_SUPPORT_FORM; ?>" class="go-to-support-forum">Go to Support Forum ></a>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </div>
105
+
106
+ <div class="sfsi-reason-container">
107
+
108
+ <div class="sfsi-just-deactivate-it">
109
+ <a href="javascript:void(0)" class="sfsi-deactive-plugin">Just de-activate it</a>
110
+ </div>
111
+
112
+ </div>
113
+
114
+ </form>
115
+
116
+ </div>
117
+ <!-- Radio buttons END-->
118
+
119
+ <a href="javascript:void(0)" class="sfsi-deactivation-popup-close" data-popup-close="popup-2">&times;</a>
120
+
121
+ </div>
122
  </div>
views/sfsi_chat_on_admin_pannel.php CHANGED
@@ -1,117 +1,117 @@
1
- <?php
2
- global $current_user;
3
- $current_user=wp_get_current_user();
4
-
5
- $email = $current_user->user_email;
6
- ?>
7
- <div id="sfsi_jivo_offline_chat" style="display:none">
8
- <a href="" style="float:right;font-size:20px;margin-right:5px;color:#888;text-decoration: none;" onclick="sfsi_close_offline_chat(event)">X</a>
9
- <p style="text-align:center" class="heading-text">No chat agent are available, However <span style="text-decoration: underline">we'll still respond quickly</span>.
10
- <!-- <a target="_blank" href="https://goo.gl/MU6pTN#no-topic-0" >we'll still respond quickly</a> -->
11
- </p>
12
- <ul class="tab-changer">
13
- <li class="tab-link active"><p style="text-align:center"><a href="#sfsi_technical"></a>Technical question<br><span>(for the free plugin)</span></p></li>
14
- <li class="tab-link"><p style="text-align:center"><a href="#sfsi_sales"></a>Pre-sales question<br><span>(for the Premium plugin)</span></p></li>
15
- </ul>
16
- <div class="clear"></div>
17
- <div class="tabs">
18
- <div id="sfsi_technical" class="tab-content" style="text-align:center;display:block">
19
- <h5>Please ask your question in the...</h5>
20
- <div class="support-forum-green-div">
21
- <!-- <span style="width: 25%"> </span> -->
22
- <a target="_blank" href="https://goo.gl/auxJ9C#no-topic-0" class="support-forum-green-bg" >
23
- <img src="<?php echo SFSI_PLUGURL ?>images/support.png">
24
- <p class="support-forum">Support Forum</p>
25
- </a>
26
- <span class="sfsi-button-right-side" ><span class="sfsi-button-right-side-icon"></span>Click here</span>
27
- </div>
28
- <!-- <p class="sfsi-button-right-side" ><span class="sfsi-button-right-side-icon"></span>Click here</p> -->
29
- <h5>We‘ll respond <span style="text-decoration: underline;"><b>quickly!</b></span></h5>
30
- </div>
31
- <div id="sfsi_sales" class="tab-content" style="display:none">
32
-
33
- <div style="display:block" class="before_message_sent">
34
-
35
- <!-- <p class="right-message" style="display:none">Please also check the <a href="">FAQ</a></p> -->
36
- <form action="#" method="POST" >
37
- <?php wp_nonce_field( 'OfflineChatMessage','nonce' ) ?>
38
- <div>
39
- <div for="question" class="label">
40
- Your question:
41
- <!-- <span class="right-message">Please also check the <a href=""><i>FAQ</i></a></span> -->
42
- </div>
43
- <textarea id="question" name="question" placeholder="Your question..."></textarea>
44
- </div>
45
- <div>
46
- <div>
47
- <div for="email" class="label email">Your email: </div>
48
- <div>
49
- <input type="email" name="email" value="<?php echo $email; ?>" placeholder="your@email.com" style="width:60%;float:left">
50
- <input type="submit" value="Send message" class="submit" style="width:37%;float:right">
51
- </div>
52
- </div>
53
- <div class="clear"></div>
54
- </div>
55
- </form>
56
-
57
- </div>
58
- <div style="display:none" class="after_message_sent">
59
- <h2>Thank you!</h2>
60
- <h3>We‘ll get back to you ASAP.</h3>
61
- <button class="chat_btn" onclick="sfsi_close_offline_chat(event)">Close window</button>
62
- </div>
63
- </div>
64
- </div>
65
-
66
- </div>
67
- <!-- Start jivo chat code -->
68
-
69
- <script type='text/javascript'>
70
- var sfsi_jivo_init=function(){ var widget_id =window.sfsi_plus_jivo_widget_id= 'heGfAHWfsn';var d=document;var w=window;function l(){var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true;s.src = '//code.jivosite.com/script/widget/'+widget_id; var ss = document.getElementsByTagName('script')[0]; ss.parentNode.insertBefore(s, ss);}if(d.readyState=='complete'){l();}else{if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}};
71
- var sfsi_dummy_chat_icon={};
72
- sfsi_dummy_chat_icon.element=document.createElement('div');
73
- sfsi_dummy_chat_icon.element.id="sfsi_dummy_chat_icon";
74
- sfsi_dummy_chat_icon.element.style="position:fixed; bottom:0;right:10px;width:350px;height:74px;cursor:pointer;background-image:url('<?php echo SFSI_PLUGURL.'images/Chat_with_us_bar_light_green.png' ?>');background-position: -12.5px -11.5px;background-size: 374px 101px;border-top-left-radius: 8px;border-top-right-radius: 8px;";
75
- function sfsi_open_chat(){
76
- if(window.jivo_api){
77
- if( window.jivo_api.chatMode()==='online'){
78
- sfsi_jivo_init();
79
- }else{
80
- jQuery('#jivo-iframe-container').remove();
81
- jQuery('script[src="//code.jivosite.com/script/widget/'+sfsi_plus_jivo_widget_id+'"]').remove();
82
- jQuery('#sfsi_jivo_offline_chat').show();
83
- }
84
- }else{
85
- sfsi_jivo_init();
86
- }
87
- // jQuery(sfsi_dummy_chat_icon.element).html("<p style='text-align: center;font-size: 18px;'>Loading...</p>");
88
- jQuery(sfsi_dummy_chat_icon.element).hide();
89
- }
90
- sfsi_dummy_chat_icon.element.onclick=sfsi_open_chat;
91
- var jivo_onLoadCallback = function(){
92
- if(jivo_api.chatMode()==='online'){
93
- jivo_api.showProactiveInvitation('How can I help you?');
94
- }else{
95
- jQuery('#jivo-iframe-container').remove();
96
- jQuery('script[src="//code.jivosite.com/script/widget/'+sfsi_plus_jivo_widget_id+'"]').remove();
97
- jQuery('#sfsi_jivo_offline_chat').show();
98
- }
99
- // jQuery(sfsi_dummy_chat_icon.element).hide();
100
- };
101
- // sfsi_dummy_chat_icon.heading= document.createElement('p');
102
- // sfsi_dummy_chat_icon.warning= document.createElement('p');
103
- // sfsi_dummy_chat_icon.heading.style="margin: 0;text-align: center;font-size: 18px;margin-top: 5px;"
104
- // sfsi_dummy_chat_icon.warning.style="font-size:11px;text-align: center;margin-bottom: 0;margin-top: 4px;"
105
- // sfsi_dummy_chat_icon.heading.appendChild(document.createTextNode("Questions? Chat with us!"));
106
- // sfsi_dummy_chat_icon.warning.appendChild(document.createTextNode("This will establish connection to the chat servers."));
107
- // sfsi_dummy_chat_icon.element.appendChild(sfsi_dummy_chat_icon.heading);
108
- // sfsi_dummy_chat_icon.element.appendChild(sfsi_dummy_chat_icon.warning);
109
- sfsi_dummy_chat_icon.body=document.getElementsByTagName('body');
110
- if(sfsi_dummy_chat_icon.body.length>0){
111
- sfsi_dummy_chat_icon.body[0].appendChild(sfsi_dummy_chat_icon.element);
112
- }else{
113
- document.appendChild(sfsi_dummy_chat_icon.element);
114
- }
115
- </script>
116
-
117
- <!-- End jivo chat code -->
1
+ <?php
2
+ global $current_user;
3
+ $current_user=wp_get_current_user();
4
+
5
+ $email = $current_user->user_email;
6
+ ?>
7
+ <div id="sfsi_jivo_offline_chat" style="display:none">
8
+ <a href="" style="float:right;font-size:20px;margin-right:5px;color:#888;text-decoration: none;" onclick="sfsi_close_offline_chat(event)">X</a>
9
+ <p style="text-align:center" class="heading-text">No chat agent are available, However <span style="text-decoration: underline">we'll still respond quickly</span>.
10
+ <!-- <a target="_blank" href="https://goo.gl/MU6pTN#no-topic-0" >we'll still respond quickly</a> -->
11
+ </p>
12
+ <ul class="tab-changer">
13
+ <li class="tab-link active"><p style="text-align:center"><a href="#sfsi_technical"></a>Technical question<br><span>(for the free plugin)</span></p></li>
14
+ <li class="tab-link"><p style="text-align:center"><a href="#sfsi_sales"></a>Pre-sales question<br><span>(for the Premium plugin)</span></p></li>
15
+ </ul>
16
+ <div class="clear"></div>
17
+ <div class="tabs">
18
+ <div id="sfsi_technical" class="tab-content" style="text-align:center;display:block">
19
+ <h5>Please ask your question in the...</h5>
20
+ <div class="support-forum-green-div">
21
+ <!-- <span style="width: 25%"> </span> -->
22
+ <a target="_blank" href="https://goo.gl/auxJ9C#no-topic-0" class="support-forum-green-bg" >
23
+ <img src="<?php echo SFSI_PLUGURL ?>images/support.png">
24
+ <p class="support-forum">Support Forum</p>
25
+ </a>
26
+ <span class="sfsi-button-right-side" ><span class="sfsi-button-right-side-icon"></span>Click here</span>
27
+ </div>
28
+ <!-- <p class="sfsi-button-right-side" ><span class="sfsi-button-right-side-icon"></span>Click here</p> -->
29
+ <h5>We‘ll respond <span style="text-decoration: underline;"><b>quickly!</b></span></h5>
30
+ </div>
31
+ <div id="sfsi_sales" class="tab-content" style="display:none">
32
+
33
+ <div style="display:block" class="before_message_sent">
34
+
35
+ <!-- <p class="right-message" style="display:none">Please also check the <a href="">FAQ</a></p> -->
36
+ <form action="#" method="POST" >
37
+ <?php wp_nonce_field( 'OfflineChatMessage','nonce' ) ?>
38
+ <div>
39
+ <div for="question" class="label">
40
+ Your question:
41
+ <!-- <span class="right-message">Please also check the <a href=""><i>FAQ</i></a></span> -->
42
+ </div>
43
+ <textarea id="question" name="question" placeholder="Your question..."></textarea>
44
+ </div>
45
+ <div>
46
+ <div>
47
+ <div for="email" class="label email">Your email: </div>
48
+ <div>
49
+ <input type="email" name="email" value="<?php echo $email; ?>" placeholder="your@email.com" style="width:60%;float:left">
50
+ <input type="submit" value="Send message" class="submit" style="width:37%;float:right">
51
+ </div>
52
+ </div>
53
+ <div class="clear"></div>
54
+ </div>
55
+ </form>
56
+
57
+ </div>
58
+ <div style="display:none" class="after_message_sent">
59
+ <h2>Thank you!</h2>
60
+ <h3>We‘ll get back to you ASAP.</h3>
61
+ <button class="chat_btn" onclick="sfsi_close_offline_chat(event)">Close window</button>
62
+ </div>
63
+ </div>
64
+ </div>
65
+
66
+ </div>
67
+ <!-- Start jivo chat code -->
68
+
69
+ <script type='text/javascript'>
70
+ var sfsi_jivo_init=function(){ var widget_id =window.sfsi_plus_jivo_widget_id= 'heGfAHWfsn';var d=document;var w=window;function l(){var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true;s.src = '//code.jivosite.com/script/widget/'+widget_id; var ss = document.getElementsByTagName('script')[0]; ss.parentNode.insertBefore(s, ss);}if(d.readyState=='complete'){l();}else{if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}};
71
+ var sfsi_dummy_chat_icon={};
72
+ sfsi_dummy_chat_icon.element=document.createElement('div');
73
+ sfsi_dummy_chat_icon.element.id="sfsi_dummy_chat_icon";
74
+ sfsi_dummy_chat_icon.element.style="position:fixed; bottom:0;right:10px;width:350px;height:74px;cursor:pointer;background-image:url('<?php echo SFSI_PLUGURL.'images/Chat_with_us_bar_light_green.png' ?>');background-position: -12.5px -11.5px;background-size: 374px 101px;border-top-left-radius: 8px;border-top-right-radius: 8px;";
75
+ function sfsi_open_chat(){
76
+ if(window.jivo_api){
77
+ if( window.jivo_api.chatMode()==='online'){
78
+ sfsi_jivo_init();
79
+ }else{
80
+ jQuery('#jivo-iframe-container').remove();
81
+ jQuery('script[src="//code.jivosite.com/script/widget/'+sfsi_plus_jivo_widget_id+'"]').remove();
82
+ jQuery('#sfsi_jivo_offline_chat').show();
83
+ }
84
+ }else{
85
+ sfsi_jivo_init();
86
+ }
87
+ // jQuery(sfsi_dummy_chat_icon.element).html("<p style='text-align: center;font-size: 18px;'>Loading...</p>");
88
+ jQuery(sfsi_dummy_chat_icon.element).hide();
89
+ }
90
+ sfsi_dummy_chat_icon.element.onclick=sfsi_open_chat;
91
+ var jivo_onLoadCallback = function(){
92
+ if(jivo_api.chatMode()==='online'){
93
+ jivo_api.showProactiveInvitation('How can I help you?');
94
+ }else{
95
+ jQuery('#jivo-iframe-container').remove();
96
+ jQuery('script[src="//code.jivosite.com/script/widget/'+sfsi_plus_jivo_widget_id+'"]').remove();
97
+ jQuery('#sfsi_jivo_offline_chat').show();
98
+ }
99
+ // jQuery(sfsi_dummy_chat_icon.element).hide();
100
+ };
101
+ // sfsi_dummy_chat_icon.heading= document.createElement('p');
102
+ // sfsi_dummy_chat_icon.warning= document.createElement('p');
103
+ // sfsi_dummy_chat_icon.heading.style="margin: 0;text-align: center;font-size: 18px;margin-top: 5px;"
104
+ // sfsi_dummy_chat_icon.warning.style="font-size:11px;text-align: center;margin-bottom: 0;margin-top: 4px;"
105
+ // sfsi_dummy_chat_icon.heading.appendChild(document.createTextNode("Questions? Chat with us!"));
106
+ // sfsi_dummy_chat_icon.warning.appendChild(document.createTextNode("This will establish connection to the chat servers."));
107
+ // sfsi_dummy_chat_icon.element.appendChild(sfsi_dummy_chat_icon.heading);
108
+ // sfsi_dummy_chat_icon.element.appendChild(sfsi_dummy_chat_icon.warning);
109
+ sfsi_dummy_chat_icon.body=document.getElementsByTagName('body');
110
+ if(sfsi_dummy_chat_icon.body.length>0){
111
+ sfsi_dummy_chat_icon.body[0].appendChild(sfsi_dummy_chat_icon.element);
112
+ }else{
113
+ document.appendChild(sfsi_dummy_chat_icon.element);
114
+ }
115
+ </script>
116
+
117
+ <!-- End jivo chat code -->
views/sfsi_option_view3.php CHANGED
@@ -1,401 +1,401 @@
1
- <?php
2
-
3
- /* unserialize all saved option for second section options */
4
-
5
- $option3 = unserialize(get_option('sfsi_section3_options', false));
6
-
7
- $option1 = unserialize(get_option('sfsi_section1_options', false));
8
-
9
- /*
10
-
11
- * Sanitize, escape and validate values
12
-
13
- */
14
-
15
- $option3['sfsi_actvite_theme'] = (isset($option3['sfsi_actvite_theme'])) ? sanitize_text_field($option3['sfsi_actvite_theme']) : '';
16
-
17
- $option3['sfsi_mouseOver'] = (isset($option3['sfsi_mouseOver'])) ? sanitize_text_field($option3['sfsi_mouseOver']) : '';
18
-
19
- $option3['sfsi_mouseOver_effect'] = (isset($option3['sfsi_mouseOver_effect'])) ? sanitize_text_field($option3['sfsi_mouseOver_effect']) : '';
20
-
21
- $option3['sfsi_shuffle_icons'] = (isset($option3['sfsi_shuffle_icons'])) ? sanitize_text_field($option3['sfsi_shuffle_icons']) : '';
22
-
23
- $option3['sfsi_shuffle_Firstload'] = (isset($option3['sfsi_shuffle_Firstload'])) ? sanitize_text_field($option3['sfsi_shuffle_Firstload']) : '';
24
-
25
- $option3['sfsi_shuffle_interval'] = (isset($option3['sfsi_shuffle_interval'])) ? sanitize_text_field($option3['sfsi_shuffle_interval']) : '';
26
-
27
- $option3['sfsi_shuffle_intervalTime'] = (isset($option3['sfsi_shuffle_intervalTime'])) ? intval($option3['sfsi_shuffle_intervalTime']) : '';
28
-
29
- $option3['sfsi_mouseOver_effect_type'] = (isset($option3['sfsi_mouseOver_effect_type'])) ? sanitize_text_field($option3['sfsi_mouseOver_effect_type']) : 'same_icons';
30
-
31
- $mouseover_other_icons_transition_effect = (isset($option3['mouseover_other_icons_transition_effect'])) ? sanitize_text_field($option3['mouseover_other_icons_transition_effect']) : 'flip';
32
-
33
- ?>
34
-
35
- <!-- Section 3 "What design & animation do you want to give your icons?" main div Start -->
36
-
37
- <div class="tab3">
38
-
39
- <p>
40
-
41
- A good & well-fitting design is not only nice to look at, but it increases chances that people will subscribe and/or share your site with friends:
42
-
43
- </p>
44
-
45
- <ul class="tab_3_list">
46
-
47
- <li>It comes across as <span>more professional</span> and gives your site <span>more “credit”</span></li>
48
-
49
- <li>A smart automatic animation can <span>make your visitors aware of your icons</span> in an unintrusive manner</li>
50
-
51
- </ul>
52
-
53
- <p style="padding:0px;">
54
-
55
- The icons have been compressed by <a href="https://goo.gl/IV5Q3z" target="_blank">Shortpixel.com</a> for faster loading of your site. Thank you Shortpixel!
56
-
57
- </p>
58
-
59
- <div class="row">
60
-
61
- <!--<h3>Theme options</h3>-->
62
- <h4>Theme options</h4>
63
- <!--icon themes section start -->
64
-
65
- <ul class="tab_3_icns">
66
-
67
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'default') ? 'checked="true"' : ''; ?> type="radio" value="default" class="styled" /><label>Default</label>
68
- <div class="icns_tab_3"><span class="row_1_1 rss_section"></span><span class="row_1_2 email_section"></span><span class="row_1_3 facebook_section"></span><span class="row_1_5 twitter_section"></span><span class="row_1_7 youtube_section"></span><span class="row_1_8 pinterest_section"></span><span class="row_1_9 linkedin_section"></span> <span class="row_1_10 instagram_section"></span><span class="row_1_14 telegram_section"></span><span class="row_1_15 vk_section"></span><span class="row_1_16 ok_section"></span><span class="row_1_17 weibo_section"></span><span class="row_1_18 wechat_section"></span>
69
- <!--<span class="row_1_11 sf_section"></span>-->
70
- </div>
71
- </li>
72
-
73
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'flat') ? 'checked="true"' : ''; ?> type="radio" value="flat" class="styled" /><label>Flat</label>
74
- <div class="icns_tab_3"><span class="row_2_1 rss_section"></span><span class="row_2_2 email_section"></span><span class="row_2_3 facebook_section"></span><span class="row_2_5 twitter_section"></span><span class="row_2_7 youtube_section"></span><span class="row_2_8 pinterest_section"></span><span class="row_2_9 linkedin_section"></span><span class="row_2_10 instagram_section"></span><span class="row_2_14 telegram_section"></span><span class="row_2_15 vk_section"></span><span class="row_2_16 ok_section"></span><span class="row_2_17 weibo_section"></span><span class="row_2_18 wechat_section"></span>
75
- <!--<span class="row_2_11 sf_section"></span>-->
76
- </div>
77
- </li>
78
-
79
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'thin') ? 'checked="true"' : ''; ?> type="radio" value="thin" class="styled" /><label>Thin</label>
80
- <div class="icns_tab_3"><span class="row_3_1 rss_section"></span><span class="row_3_2 email_section"></span><span class="row_3_3 facebook_section"></span><span class="row_3_5 twitter_section"></span><span class="row_3_7 youtube_section"></span><span class="row_3_8 pinterest_section"></span><span class="row_3_9 linkedin_section"></span><span class="row_3_10 instagram_section"></span><span class="row_3_14 telegram_section"></span><span class="row_3_15 vk_section"></span><span class="row_3_16 ok_section"></span><span class="row_3_17 weibo_section"></span><span class="row_3_18 wechat_section"></span>
81
- <!--<span class="row_3_11 sf_section"></span>-->
82
- </div>
83
- </li>
84
-
85
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'cute') ? 'checked="true"' : ''; ?> type="radio" value="cute" class="styled" /><label>Cute</label>
86
- <div class="icns_tab_3"><span class="row_4_1 rss_section"></span><span class="row_4_2 email_section"></span><span class="row_4_3 facebook_section"></span><span class="row_4_5 twitter_section"></span><span class="row_4_7 youtube_section"></span><span class="row_4_8 pinterest_section"></span><span class="row_4_9 linkedin_section"></span><span class="row_4_10 instagram_section"></span><span class="row_4_14 telegram_section"></span><span class="row_4_15 vk_section"></span><span class="row_4_16 ok_section"></span><span class="row_4_17 weibo_section"></span><span class="row_4_18 wechat_section"></span>
87
- <!--<span class="row_4_11 sf_section"></span>-->
88
- </div>
89
- </li>
90
-
91
- <!--start next four-->
92
-
93
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'cubes') ? 'checked="true"' : ''; ?> type="radio" value="cubes" class="styled" /><label>Cubes</label>
94
- <div class="icns_tab_3"><span class="row_5_1 rss_section"></span><span class="row_5_2 email_section"></span><span class="row_5_3 facebook_section"></span><span class="row_5_5 twitter_section"></span><span class="row_5_7 youtube_section"></span><span class="row_5_8 pinterest_section"></span><span class="row_5_9 linkedin_section"></span><span class="row_5_10 instagram_section"></span><span class="row_5_14 telegram_section"></span><span class="row_5_15 vk_section"></span><span class="row_5_16 ok_section"></span><span class="row_5_17 weibo_section"></span><span class="row_5_18 wechat_section"></span>
95
- <!--<span class="row_5_11 sf_section"></span>-->
96
- </div>
97
- </li>
98
-
99
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'chrome_blue') ? 'checked="true"' : ''; ?> type="radio" value="chrome_blue" class="styled" /><label>Chrome Blue</label>
100
- <div class="icns_tab_3"><span class="row_6_1 rss_section"></span><span class="row_6_2 email_section"></span><span class="row_6_3 facebook_section"></span><span class="row_6_5 twitter_section"></span><span class="row_6_7 youtube_section"></span><span class="row_6_8 pinterest_section"></span><span class="row_6_9 linkedin_section"></span><span class="row_6_10 instagram_section"></span><span class="row_6_14 telegram_section"></span><span class="row_6_15 vk_section"></span><span class="row_6_16 ok_section"></span><span class="row_6_17 weibo_section"></span><span class="row_6_18 wechat_section"></span>
101
- <!--<span class="row_6_11 sf_section"></span>-->
102
- </div>
103
- </li>
104
-
105
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'chrome_grey') ? 'checked="true"' : ''; ?> type="radio" value="chrome_grey" class="styled" /><label>Chrome Grey</label>
106
- <div class="icns_tab_3"><span class="row_7_1 rss_section"></span><span class="row_7_2 email_section"></span><span class="row_7_3 facebook_section"></span><span class="row_7_5 twitter_section"></span><span class="row_7_7 youtube_section"></span><span class="row_7_8 pinterest_section"></span><span class="row_7_9 linkedin_section"></span><span class="row_7_10 instagram_section"></span><span class="row_7_14 telegram_section"></span><span class="row_7_15 vk_section"></span><span class="row_7_16 ok_section"></span><span class="row_7_17 weibo_section"></span><span class="row_7_18 wechat_section"></span>
107
- <!--<span class="row_7_11 sf_section"></span>-->
108
- </div>
109
- </li>
110
-
111
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'splash') ? 'checked="true"' : ''; ?> type="radio" value="splash" class="styled" /><label>Splash</label>
112
- <div class="icns_tab_3"><span class="row_8_1 rss_section"></span><span class="row_8_2 email_section"></span><span class="row_8_3 facebook_section"></span><span class="row_8_5 twitter_section"></span><span class="row_8_7 youtube_section"></span><span class="row_8_8 pinterest_section"></span><span class="row_8_9 linkedin_section"></span><span class="row_8_10 instagram_section"></span><span class="row_8_14 telegram_section"></span><span class="row_8_15 vk_section"></span><span class="row_8_16 ok_section"></span><span class="row_8_17 weibo_section"></span><span class="row_8_18 wechat_section"></span>
113
- <!--<span class="row_8_11 sf_section"></span>-->
114
- </div>
115
- </li>
116
-
117
- <!--start second four-->
118
-
119
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'orange') ? 'checked="true"' : ''; ?> type="radio" value="orange" class="styled" /><label>Orange</label>
120
- <div class="icns_tab_3"><span class="row_9_1 rss_section"></span><span class="row_9_2 email_section"></span><span class="row_9_3 facebook_section"></span><span class="row_9_5 twitter_section"></span><span class="row_9_7 youtube_section"></span><span class="row_9_8 pinterest_section"></span><span class="row_9_9 linkedin_section"></span><span class="row_9_10 instagram_section"></span><span class="row_9_14 telegram_section"></span><span class="row_9_15 vk_section"></span><span class="row_9_16 ok_section"></span><span class="row_9_17 weibo_section"></span><span class="row_9_18 wechat_section"></span>
121
- <!--<span class="row_9_11 sf_section"></span>-->
122
- </div>
123
- </li>
124
-
125
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'crystal') ? 'checked="true"' : ''; ?> type="radio" value="crystal" class="styled" /><label>Crystal</label>
126
- <div class="icns_tab_3"><span class="row_10_1 rss_section"></span><span class="row_10_2 email_section"></span><span class="row_10_3 facebook_section"></span><span class="row_10_5 twitter_section"></span><span class="row_10_7 youtube_section"></span><span class="row_10_8 pinterest_section"></span><span class="row_10_9 linkedin_section"></span><span class="row_10_10 instagram_section"></span><span class="row_10_14 telegram_section"></span><span class="row_10_15 vk_section"></span><span class="row_10_16 ok_section"></span><span class="row_10_17 weibo_section"></span><span class="row_10_18 wechat_section"></span>
127
- <!--<span class="row_10_11 sf_section"></span>-->
128
- </div>
129
- </li>
130
-
131
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'glossy') ? 'checked="true"' : ''; ?> type="radio" value="glossy" class="styled" /><label>Glossy</label>
132
- <div class="icns_tab_3"><span class="row_11_1 rss_section"></span><span class="row_11_2 email_section"></span><span class="row_11_3 facebook_section"></span><span class="row_11_5 twitter_section"></span><span class="row_11_7 youtube_section"></span><span class="row_11_8 pinterest_section"></span><span class="row_11_9 linkedin_section"></span><span class="row_11_10 instagram_section"></span><span class="row_11_14 telegram_section"></span><span class="row_11_15 vk_section"></span><span class="row_11_16 ok_section"></span><span class="row_11_17 weibo_section"></span><span class="row_11_18 wechat_section"></span>
133
- <!--<span class="row_11_11 sf_section"></span>-->
134
- </div>
135
- </li>
136
-
137
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'black') ? 'checked="true"' : ''; ?> type="radio" value="black" class="styled" /><label>Black</label>
138
- <div class="icns_tab_3"><span class="row_12_1 rss_section"></span><span class="row_12_2 email_section"></span><span class="row_12_3 facebook_section"></span><span class="row_12_5 twitter_section"></span><span class="row_12_7 youtube_section"></span><span class="row_12_8 pinterest_section"></span><span class="row_12_9 linkedin_section"></span><span class="row_12_10 instagram_section"></span><span class="row_12_14 telegram_section"></span><span class="row_12_15 vk_section"></span><span class="row_12_16 ok_section"></span><span class="row_12_17 weibo_section"></span><span class="row_12_18 wechat_section"></span>
139
- <!--<span class="row_12_11 sf_section"></span>-->
140
- </div>
141
- </li>
142
-
143
- <!--start last four-->
144
-
145
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'silver') ? 'checked="true"' : ''; ?> type="radio" value="silver" class="styled" /><label>Silver</label>
146
- <div class="icns_tab_3"><span class="row_13_1 rss_section"></span><span class="row_13_2 email_section"></span><span class="row_13_3 facebook_section"></span><span class="row_13_5 twitter_section"></span><span class="row_13_7 youtube_section"></span><span class="row_13_8 pinterest_section"></span><span class="row_13_9 linkedin_section"></span><span class="row_13_10 instagram_section"></span><span class="row_13_14 telegram_section"></span><span class="row_13_15 vk_section"></span><span class="row_13_16 ok_section"></span><span class="row_13_17 weibo_section"></span><span class="row_13_18 wechat_section"></span>
147
- <!--<span class="row_13_11 sf_section"></span>-->
148
- </div>
149
- </li>
150
-
151
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'shaded_dark') ? 'checked="true"' : ''; ?> type="radio" value="shaded_dark" class="styled" /><label>Shaded Dark</label>
152
- <div class="icns_tab_3"><span class="row_14_1 rss_section"></span><span class="row_14_2 email_section"></span><span class="row_14_3 facebook_section"></span><span class="row_14_5 twitter_section"></span><span class="row_14_7 youtube_section"></span><span class="row_14_8 pinterest_section"></span><span class="row_14_9 linkedin_section"></span><span class="row_14_10 instagram_section"></span><span class="row_14_14 telegram_section"></span><span class="row_14_15 vk_section"></span><span class="row_14_16 ok_section"></span><span class="row_14_17 weibo_section"></span><span class="row_14_18 wechat_section"></span>
153
- <!--<span class="row_14_11 sf_section"></span>-->
154
- </div>
155
- </li>
156
-
157
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'shaded_light') ? 'checked="true"' : ''; ?> type="radio" value="shaded_light" class="styled" /><label>Shaded Light</label>
158
- <div class="icns_tab_3"><span class="row_15_1 rss_section"></span><span class="row_15_2 email_section"></span><span class="row_15_3 facebook_section"></span><span class="row_15_5 twitter_section"></span><span class="row_15_7 youtube_section"></span><span class="row_15_8 pinterest_section"></span><span class="row_15_9 linkedin_section"></span><span class="row_15_10 instagram_section"></span><span class="row_15_14 telegram_section"></span><span class="row_15_15 vk_section"></span><span class="row_15_16 ok_section"></span><span class="row_15_17 weibo_section"></span><span class="row_15_18 wechat_section"></span>
159
- <!--<span class="row_15_11 sf_section"></span>-->
160
- </div>
161
- </li>
162
-
163
- <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'transparent') ? 'checked="true"' : ''; ?> type="radio" value="transparent" class="styled" /><label style="line-height:20px !important;margin-top:15px; ">Transparent <br /><span style="font-size: 9px;">(for dark backgrounds)</span></label>
164
- <div class="icns_tab_3 trans_bg" style="padding-left: 6px;"><span class="row_16_1 rss_section"></span><span class="row_16_2 email_section"></span><span class="row_16_3 facebook_section"></span><span class="row_16_5 twitter_section"></span><span class="row_16_7 youtube_section"></span><span class="row_16_8 pinterest_section"></span><span class="row_16_9 linkedin_section"></span><span class="row_16_10 instagram_section"></span><span class="row_16_14 telegram_section"></span><span class="row_16_15 vk_section"></span><span class="row_16_16 ok_section"></span><span class="row_16_17 weibo_section"></span><span class="row_16_18 wechat_section"></span>
165
- <!--<span class="row_16_11 sf_section"></span>-->
166
- </div>
167
- </li>
168
-
169
- <!--Custom Icon Support {Monad}-->
170
- <?php if (get_option('sfsi_custom_icons') == 'yes') { ?>
171
-
172
- <li class="cstomskins_upload">
173
-
174
- <input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'custom_support') ? 'checked="true"' : ''; ?> type="radio" value="custom_support" class="styled" />
175
-
176
- <label style="line-height:20px !important;margin-top:15px; ">Custom Icons <br /></label>
177
-
178
- <div class="icns_tab_3" style="padding-left: 6px;">
179
-
180
- <?php
181
-
182
- if (get_option("rss_skin")) {
183
-
184
- $icon = get_option("rss_skin");
185
-
186
- echo '<span class="row_17_1 rss_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
187
- } else {
188
-
189
- echo '<span class="row_17_1 rss_section" style="background-position:-1px 0;"></span>';
190
- }
191
-
192
- if (get_option("email_skin")) {
193
-
194
- $icon = get_option("email_skin");
195
-
196
- echo '<span class="row_17_2 email_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
197
- } else {
198
-
199
- echo '<span class="row_17_2 email_section" style="background-position:-58px 0;"></span>';
200
- }
201
-
202
- if (get_option("facebook_skin")) {
203
-
204
- $icon = get_option("facebook_skin");
205
-
206
- echo '<span class="row_17_3 facebook_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
207
- } else {
208
-
209
- echo '<span class="row_17_3 facebook_section" style="background-position:-118px 0;"></span>';
210
- }
211
- if (get_option("twitter_skin")) {
212
-
213
- $icon = get_option("twitter_skin");
214
-
215
- echo '<span class="row_17_5 twitter_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
216
- } else {
217
-
218
- echo '<span class="row_17_5 twitter_section" style="background-position:-235px 0;"></span>';
219
- }
220
-
221
- if (get_option("youtube_skin")) {
222
-
223
- $icon = get_option("youtube_skin");
224
-
225
- echo '<span class="row_17_7 youtube_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
226
- } else {
227
-
228
- echo '<span class="row_17_7 youtube_section" style="background-position:-350px 0;"></span>';
229
- }
230
-
231
- if (get_option("pintrest_skin")) {
232
-
233
- $icon = get_option("pintrest_skin");
234
-
235
- echo '<span class="row_17_8 pinterest_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
236
- } else {
237
-
238
- echo '<span class="row_17_8 pinterest_section" style="background-position:-409px 0;"></span>';
239
- }
240
-
241
- if (get_option("linkedin_skin")) {
242
-
243
- $icon = get_option("linkedin_skin");
244
-
245
- echo '<span class="row_17_9 linkedin_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
246
- } else {
247
-
248
- echo '<span class="row_17_9 linkedin_section" style="background-position:-467px 0;"></span>';
249
- }
250
-
251
- if (get_option("instagram_skin")) {
252
-
253
- $icon = get_option("instagram_skin");
254
-
255
- echo '<span class="row_17_10 instagram_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
256
- } else {
257
-
258
- echo '<span class="row_17_10 instagram_section" style="background-position:-526px 0;"></span>';
259
- }
260
-
261
- if (get_option("telegram_skin")) {
262
-
263
- $icon = get_option("telegram_skin");
264
-
265
- echo '<span class="row_17_10 telegram_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
266
- } else {
267
-
268
- echo '<span class="row_17_10 telegram_section" style="background-position:-773px 0;"></span>';
269
- }
270
-
271
- if (get_option("vk_skin")) {
272
-
273
- $icon = get_option("vk_skin");
274
-
275
- echo '<span class="row_17_10 vk_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
276
- } else {
277
-
278
- echo '<span class="row_17_10 vk_section" style="background-position:-838px 0;"></span>';
279
- }
280
-
281
- if (get_option("ok_skin")) {
282
-
283
- $icon = get_option("ok_skin");
284
-
285
- echo '<span class="row_17_10 ok_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
286
- } else {
287
-
288
- echo '<span class="row_17_10 ok_section" style="background-position:-909px 0;"></span>';
289
- }
290
-
291
- if (get_option("weibo_skin")) {
292
-
293
- $icon = get_option("weibo_skin");
294
-
295
- echo '<span class="row_17_10 weibo_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
296
- } else {
297
-
298
- echo '<span class="row_17_10 weibo_section" style="background-position:-977px 0;"></span>';
299
- }
300
-
301
- if (get_option("wechat_skin")) {
302
-
303
- $icon = get_option("wechat_skin");
304
-
305
- echo '<span class="row_17_10 wechat_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
306
- } else {
307
-
308
- echo '<span class="row_1_18 wechat_section"></span>';
309
- }
310
-
311
- ?>
312
-
313
- </div>
314
- </li>
315
- <?php
316
- }
317
- ?><?php if (get_option('sfsi_custom_icons') == 'no') { ?>
318
-
319
- <li class="sfsi_custom_icons_q4">
320
- <div style="float: left;">
321
- <a class="pop-up" data-id="sfsi_quickpay-overlay" onclick="sfsi_open_quick_checkout(event)" target="_blank" style="display: flex;">
322
-
323
- <input type="radio" class="styled" />
324
-
325
- <label style="line-height:20px !important;margin-top:15px;opacity:0.5">Custom Icons -</label>
326
- </a>
327
- </div>
328
- <div>
329
- <p style="margin-top: 3px;">
330
- <a style="color: #12a252 !important;font-weight: bold; border-bottom:none;text-decoration: none;">
331
- Premium Feature:
332
- </a>
333
- <span>Upload a custom design for the social media platforms implemented in the plugin under question number 1 - </span>
334
- <a class="pop-up" style="cursor:pointer; color: #12a252 !important;border-bottom: 1px solid #12a252;text-decoration: none;font-weight: bold;" data-id="sfsi_quickpay-overlay" onclick="sfsi_open_quick_checkout(event)" target="_blank">
335
- Get it now.
336
- </a>
337
- </p>
338
- </div>
339
- </li>
340
- <?php
341
- }
342
- ?>
343
- <li>
344
-
345
- <?php include_once(SFSI_DOCROOT . '/views/subviews/que4/banner.php'); ?>
346
-
347
- </li>
348
-
349
- <li>
350
-
351
- <p style="font-weight: bold; margin: 12px 0 0;">
352
-
353
- Need icons for another theme? Let us know in the
354
-
355
- <a target="_blank" href="https://wordpress.org/support/plugin/ultimate-social-media-icons/#new-topic-0" style="color:#8E81BD; text-decoration:underline;">
356
-
357
- Support Forum
358
-
359
- </a>
360
-
361
- </p>
362
-
363
- </li>
364
-
365
- </ul>
366
-
367
- <!--icon themes section start -->
368
-
369
- <?php include_once(SFSI_DOCROOT . '/views/subviews/que4/animatethem.php'); ?>
370
-
371
- </div>
372
-
373
- <?php sfsi_ask_for_help(3); ?>
374
-
375
- <!-- SAVE BUTTON SECTION -->
376
-
377
- <div class="save_button tab_3_sav">
378
-
379
- <img src="<?php echo SFSI_PLUGURL ?>images/ajax-loader.gif" class="loader-img" alt="error" />
380
-
381
- <?php $nonce = wp_create_nonce("update_step3"); ?>
382
-
383
- <a href="javascript:;" id="sfsi_save3" title="Save" data-nonce="<?php echo $nonce; ?>">Save</a>
384
-
385
- </div>
386
-
387
- <!-- END SAVE BUTTON SECTION -->
388
-
389
- <a class="sfsiColbtn closeSec" href="javascript:;">Collapse area</a>
390
-
391
- <label class="closeSec"></label>
392
-
393
- <!-- ERROR AND SUCCESS MESSAGE AREA-->
394
-
395
- <p class="red_txt errorMsg" style="display:none"> </p>
396
-
397
- <p class="green_txt sucMsg" style="display:none"> </p>
398
-
399
- </div>
400
-
401
  <!-- END Section 3 "What design & animation do you want to give your icons?" main div -->
1
+ <?php
2
+
3
+ /* unserialize all saved option for second section options */
4
+
5
+ $option3 = unserialize(get_option('sfsi_section3_options', false));
6
+
7
+ $option1 = unserialize(get_option('sfsi_section1_options', false));
8
+
9
+ /*
10
+
11
+ * Sanitize, escape and validate values
12
+
13
+ */
14
+
15
+ $option3['sfsi_actvite_theme'] = (isset($option3['sfsi_actvite_theme'])) ? sanitize_text_field($option3['sfsi_actvite_theme']) : '';
16
+
17
+ $option3['sfsi_mouseOver'] = (isset($option3['sfsi_mouseOver'])) ? sanitize_text_field($option3['sfsi_mouseOver']) : '';
18
+
19
+ $option3['sfsi_mouseOver_effect'] = (isset($option3['sfsi_mouseOver_effect'])) ? sanitize_text_field($option3['sfsi_mouseOver_effect']) : '';
20
+
21
+ $option3['sfsi_shuffle_icons'] = (isset($option3['sfsi_shuffle_icons'])) ? sanitize_text_field($option3['sfsi_shuffle_icons']) : '';
22
+
23
+ $option3['sfsi_shuffle_Firstload'] = (isset($option3['sfsi_shuffle_Firstload'])) ? sanitize_text_field($option3['sfsi_shuffle_Firstload']) : '';
24
+
25
+ $option3['sfsi_shuffle_interval'] = (isset($option3['sfsi_shuffle_interval'])) ? sanitize_text_field($option3['sfsi_shuffle_interval']) : '';
26
+
27
+ $option3['sfsi_shuffle_intervalTime'] = (isset($option3['sfsi_shuffle_intervalTime'])) ? intval($option3['sfsi_shuffle_intervalTime']) : '';
28
+
29
+ $option3['sfsi_mouseOver_effect_type'] = (isset($option3['sfsi_mouseOver_effect_type'])) ? sanitize_text_field($option3['sfsi_mouseOver_effect_type']) : 'same_icons';
30
+
31
+ $mouseover_other_icons_transition_effect = (isset($option3['mouseover_other_icons_transition_effect'])) ? sanitize_text_field($option3['mouseover_other_icons_transition_effect']) : 'flip';
32
+
33
+ ?>
34
+
35
+ <!-- Section 3 "What design & animation do you want to give your icons?" main div Start -->
36
+
37
+ <div class="tab3">
38
+
39
+ <p>
40
+
41
+ A good & well-fitting design is not only nice to look at, but it increases chances that people will subscribe and/or share your site with friends:
42
+
43
+ </p>
44
+
45
+ <ul class="tab_3_list">
46
+
47
+ <li>It comes across as <span>more professional</span> and gives your site <span>more “credit”</span></li>
48
+
49
+ <li>A smart automatic animation can <span>make your visitors aware of your icons</span> in an unintrusive manner</li>
50
+
51
+ </ul>
52
+
53
+ <p style="padding:0px;">
54
+
55
+ The icons have been compressed by <a href="https://goo.gl/IV5Q3z" target="_blank">Shortpixel.com</a> for faster loading of your site. Thank you Shortpixel!
56
+
57
+ </p>
58
+
59
+ <div class="row">
60
+
61
+ <!--<h3>Theme options</h3>-->
62
+ <h4>Theme options</h4>
63
+ <!--icon themes section start -->
64
+
65
+ <ul class="tab_3_icns">
66
+
67
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'default') ? 'checked="true"' : ''; ?> type="radio" value="default" class="styled" /><label>Default</label>
68
+ <div class="icns_tab_3"><span class="row_1_1 rss_section"></span><span class="row_1_2 email_section"></span><span class="row_1_3 facebook_section"></span><span class="row_1_5 twitter_section"></span><span class="row_1_7 youtube_section"></span><span class="row_1_8 pinterest_section"></span><span class="row_1_9 linkedin_section"></span> <span class="row_1_10 instagram_section"></span><span class="row_1_14 telegram_section"></span><span class="row_1_15 vk_section"></span><span class="row_1_16 ok_section"></span><span class="row_1_17 weibo_section"></span><span class="row_1_18 wechat_section"></span>
69
+ <!--<span class="row_1_11 sf_section"></span>-->
70
+ </div>
71
+ </li>
72
+
73
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'flat') ? 'checked="true"' : ''; ?> type="radio" value="flat" class="styled" /><label>Flat</label>
74
+ <div class="icns_tab_3"><span class="row_2_1 rss_section"></span><span class="row_2_2 email_section"></span><span class="row_2_3 facebook_section"></span><span class="row_2_5 twitter_section"></span><span class="row_2_7 youtube_section"></span><span class="row_2_8 pinterest_section"></span><span class="row_2_9 linkedin_section"></span><span class="row_2_10 instagram_section"></span><span class="row_2_14 telegram_section"></span><span class="row_2_15 vk_section"></span><span class="row_2_16 ok_section"></span><span class="row_2_17 weibo_section"></span><span class="row_2_18 wechat_section"></span>
75
+ <!--<span class="row_2_11 sf_section"></span>-->
76
+ </div>
77
+ </li>
78
+
79
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'thin') ? 'checked="true"' : ''; ?> type="radio" value="thin" class="styled" /><label>Thin</label>
80
+ <div class="icns_tab_3"><span class="row_3_1 rss_section"></span><span class="row_3_2 email_section"></span><span class="row_3_3 facebook_section"></span><span class="row_3_5 twitter_section"></span><span class="row_3_7 youtube_section"></span><span class="row_3_8 pinterest_section"></span><span class="row_3_9 linkedin_section"></span><span class="row_3_10 instagram_section"></span><span class="row_3_14 telegram_section"></span><span class="row_3_15 vk_section"></span><span class="row_3_16 ok_section"></span><span class="row_3_17 weibo_section"></span><span class="row_3_18 wechat_section"></span>
81
+ <!--<span class="row_3_11 sf_section"></span>-->
82
+ </div>
83
+ </li>
84
+
85
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'cute') ? 'checked="true"' : ''; ?> type="radio" value="cute" class="styled" /><label>Cute</label>
86
+ <div class="icns_tab_3"><span class="row_4_1 rss_section"></span><span class="row_4_2 email_section"></span><span class="row_4_3 facebook_section"></span><span class="row_4_5 twitter_section"></span><span class="row_4_7 youtube_section"></span><span class="row_4_8 pinterest_section"></span><span class="row_4_9 linkedin_section"></span><span class="row_4_10 instagram_section"></span><span class="row_4_14 telegram_section"></span><span class="row_4_15 vk_section"></span><span class="row_4_16 ok_section"></span><span class="row_4_17 weibo_section"></span><span class="row_4_18 wechat_section"></span>
87
+ <!--<span class="row_4_11 sf_section"></span>-->
88
+ </div>
89
+ </li>
90
+
91
+ <!--start next four-->
92
+
93
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'cubes') ? 'checked="true"' : ''; ?> type="radio" value="cubes" class="styled" /><label>Cubes</label>
94
+ <div class="icns_tab_3"><span class="row_5_1 rss_section"></span><span class="row_5_2 email_section"></span><span class="row_5_3 facebook_section"></span><span class="row_5_5 twitter_section"></span><span class="row_5_7 youtube_section"></span><span class="row_5_8 pinterest_section"></span><span class="row_5_9 linkedin_section"></span><span class="row_5_10 instagram_section"></span><span class="row_5_14 telegram_section"></span><span class="row_5_15 vk_section"></span><span class="row_5_16 ok_section"></span><span class="row_5_17 weibo_section"></span><span class="row_5_18 wechat_section"></span>
95
+ <!--<span class="row_5_11 sf_section"></span>-->
96
+ </div>
97
+ </li>
98
+
99
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'chrome_blue') ? 'checked="true"' : ''; ?> type="radio" value="chrome_blue" class="styled" /><label>Chrome Blue</label>
100
+ <div class="icns_tab_3"><span class="row_6_1 rss_section"></span><span class="row_6_2 email_section"></span><span class="row_6_3 facebook_section"></span><span class="row_6_5 twitter_section"></span><span class="row_6_7 youtube_section"></span><span class="row_6_8 pinterest_section"></span><span class="row_6_9 linkedin_section"></span><span class="row_6_10 instagram_section"></span><span class="row_6_14 telegram_section"></span><span class="row_6_15 vk_section"></span><span class="row_6_16 ok_section"></span><span class="row_6_17 weibo_section"></span><span class="row_6_18 wechat_section"></span>
101
+ <!--<span class="row_6_11 sf_section"></span>-->
102
+ </div>
103
+ </li>
104
+
105
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'chrome_grey') ? 'checked="true"' : ''; ?> type="radio" value="chrome_grey" class="styled" /><label>Chrome Grey</label>
106
+ <div class="icns_tab_3"><span class="row_7_1 rss_section"></span><span class="row_7_2 email_section"></span><span class="row_7_3 facebook_section"></span><span class="row_7_5 twitter_section"></span><span class="row_7_7 youtube_section"></span><span class="row_7_8 pinterest_section"></span><span class="row_7_9 linkedin_section"></span><span class="row_7_10 instagram_section"></span><span class="row_7_14 telegram_section"></span><span class="row_7_15 vk_section"></span><span class="row_7_16 ok_section"></span><span class="row_7_17 weibo_section"></span><span class="row_7_18 wechat_section"></span>
107
+ <!--<span class="row_7_11 sf_section"></span>-->
108
+ </div>
109
+ </li>
110
+
111
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'splash') ? 'checked="true"' : ''; ?> type="radio" value="splash" class="styled" /><label>Splash</label>
112
+ <div class="icns_tab_3"><span class="row_8_1 rss_section"></span><span class="row_8_2 email_section"></span><span class="row_8_3 facebook_section"></span><span class="row_8_5 twitter_section"></span><span class="row_8_7 youtube_section"></span><span class="row_8_8 pinterest_section"></span><span class="row_8_9 linkedin_section"></span><span class="row_8_10 instagram_section"></span><span class="row_8_14 telegram_section"></span><span class="row_8_15 vk_section"></span><span class="row_8_16 ok_section"></span><span class="row_8_17 weibo_section"></span><span class="row_8_18 wechat_section"></span>
113
+ <!--<span class="row_8_11 sf_section"></span>-->
114
+ </div>
115
+ </li>
116
+
117
+ <!--start second four-->
118
+
119
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'orange') ? 'checked="true"' : ''; ?> type="radio" value="orange" class="styled" /><label>Orange</label>
120
+ <div class="icns_tab_3"><span class="row_9_1 rss_section"></span><span class="row_9_2 email_section"></span><span class="row_9_3 facebook_section"></span><span class="row_9_5 twitter_section"></span><span class="row_9_7 youtube_section"></span><span class="row_9_8 pinterest_section"></span><span class="row_9_9 linkedin_section"></span><span class="row_9_10 instagram_section"></span><span class="row_9_14 telegram_section"></span><span class="row_9_15 vk_section"></span><span class="row_9_16 ok_section"></span><span class="row_9_17 weibo_section"></span><span class="row_9_18 wechat_section"></span>
121
+ <!--<span class="row_9_11 sf_section"></span>-->
122
+ </div>
123
+ </li>
124
+
125
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'crystal') ? 'checked="true"' : ''; ?> type="radio" value="crystal" class="styled" /><label>Crystal</label>
126
+ <div class="icns_tab_3"><span class="row_10_1 rss_section"></span><span class="row_10_2 email_section"></span><span class="row_10_3 facebook_section"></span><span class="row_10_5 twitter_section"></span><span class="row_10_7 youtube_section"></span><span class="row_10_8 pinterest_section"></span><span class="row_10_9 linkedin_section"></span><span class="row_10_10 instagram_section"></span><span class="row_10_14 telegram_section"></span><span class="row_10_15 vk_section"></span><span class="row_10_16 ok_section"></span><span class="row_10_17 weibo_section"></span><span class="row_10_18 wechat_section"></span>
127
+ <!--<span class="row_10_11 sf_section"></span>-->
128
+ </div>
129
+ </li>
130
+
131
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'glossy') ? 'checked="true"' : ''; ?> type="radio" value="glossy" class="styled" /><label>Glossy</label>
132
+ <div class="icns_tab_3"><span class="row_11_1 rss_section"></span><span class="row_11_2 email_section"></span><span class="row_11_3 facebook_section"></span><span class="row_11_5 twitter_section"></span><span class="row_11_7 youtube_section"></span><span class="row_11_8 pinterest_section"></span><span class="row_11_9 linkedin_section"></span><span class="row_11_10 instagram_section"></span><span class="row_11_14 telegram_section"></span><span class="row_11_15 vk_section"></span><span class="row_11_16 ok_section"></span><span class="row_11_17 weibo_section"></span><span class="row_11_18 wechat_section"></span>
133
+ <!--<span class="row_11_11 sf_section"></span>-->
134
+ </div>
135
+ </li>
136
+
137
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'black') ? 'checked="true"' : ''; ?> type="radio" value="black" class="styled" /><label>Black</label>
138
+ <div class="icns_tab_3"><span class="row_12_1 rss_section"></span><span class="row_12_2 email_section"></span><span class="row_12_3 facebook_section"></span><span class="row_12_5 twitter_section"></span><span class="row_12_7 youtube_section"></span><span class="row_12_8 pinterest_section"></span><span class="row_12_9 linkedin_section"></span><span class="row_12_10 instagram_section"></span><span class="row_12_14 telegram_section"></span><span class="row_12_15 vk_section"></span><span class="row_12_16 ok_section"></span><span class="row_12_17 weibo_section"></span><span class="row_12_18 wechat_section"></span>
139
+ <!--<span class="row_12_11 sf_section"></span>-->
140
+ </div>
141
+ </li>
142
+
143
+ <!--start last four-->
144
+
145
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'silver') ? 'checked="true"' : ''; ?> type="radio" value="silver" class="styled" /><label>Silver</label>
146
+ <div class="icns_tab_3"><span class="row_13_1 rss_section"></span><span class="row_13_2 email_section"></span><span class="row_13_3 facebook_section"></span><span class="row_13_5 twitter_section"></span><span class="row_13_7 youtube_section"></span><span class="row_13_8 pinterest_section"></span><span class="row_13_9 linkedin_section"></span><span class="row_13_10 instagram_section"></span><span class="row_13_14 telegram_section"></span><span class="row_13_15 vk_section"></span><span class="row_13_16 ok_section"></span><span class="row_13_17 weibo_section"></span><span class="row_13_18 wechat_section"></span>
147
+ <!--<span class="row_13_11 sf_section"></span>-->
148
+ </div>
149
+ </li>
150
+
151
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'shaded_dark') ? 'checked="true"' : ''; ?> type="radio" value="shaded_dark" class="styled" /><label>Shaded Dark</label>
152
+ <div class="icns_tab_3"><span class="row_14_1 rss_section"></span><span class="row_14_2 email_section"></span><span class="row_14_3 facebook_section"></span><span class="row_14_5 twitter_section"></span><span class="row_14_7 youtube_section"></span><span class="row_14_8 pinterest_section"></span><span class="row_14_9 linkedin_section"></span><span class="row_14_10 instagram_section"></span><span class="row_14_14 telegram_section"></span><span class="row_14_15 vk_section"></span><span class="row_14_16 ok_section"></span><span class="row_14_17 weibo_section"></span><span class="row_14_18 wechat_section"></span>
153
+ <!--<span class="row_14_11 sf_section"></span>-->
154
+ </div>
155
+ </li>
156
+
157
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'shaded_light') ? 'checked="true"' : ''; ?> type="radio" value="shaded_light" class="styled" /><label>Shaded Light</label>
158
+ <div class="icns_tab_3"><span class="row_15_1 rss_section"></span><span class="row_15_2 email_section"></span><span class="row_15_3 facebook_section"></span><span class="row_15_5 twitter_section"></span><span class="row_15_7 youtube_section"></span><span class="row_15_8 pinterest_section"></span><span class="row_15_9 linkedin_section"></span><span class="row_15_10 instagram_section"></span><span class="row_15_14 telegram_section"></span><span class="row_15_15 vk_section"></span><span class="row_15_16 ok_section"></span><span class="row_15_17 weibo_section"></span><span class="row_15_18 wechat_section"></span>
159
+ <!--<span class="row_15_11 sf_section"></span>-->
160
+ </div>
161
+ </li>
162
+
163
+ <li><input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'transparent') ? 'checked="true"' : ''; ?> type="radio" value="transparent" class="styled" /><label style="line-height:20px !important;margin-top:15px; ">Transparent <br /><span style="font-size: 9px;">(for dark backgrounds)</span></label>
164
+ <div class="icns_tab_3 trans_bg" style="padding-left: 6px;"><span class="row_16_1 rss_section"></span><span class="row_16_2 email_section"></span><span class="row_16_3 facebook_section"></span><span class="row_16_5 twitter_section"></span><span class="row_16_7 youtube_section"></span><span class="row_16_8 pinterest_section"></span><span class="row_16_9 linkedin_section"></span><span class="row_16_10 instagram_section"></span><span class="row_16_14 telegram_section"></span><span class="row_16_15 vk_section"></span><span class="row_16_16 ok_section"></span><span class="row_16_17 weibo_section"></span><span class="row_16_18 wechat_section"></span>
165
+ <!--<span class="row_16_11 sf_section"></span>-->
166
+ </div>
167
+ </li>
168
+
169
+ <!--Custom Icon Support {Monad}-->
170
+ <?php if (get_option('sfsi_custom_icons') == 'yes') { ?>
171
+
172
+ <li class="cstomskins_upload">
173
+
174
+ <input name="sfsi_actvite_theme" <?php echo ($option3['sfsi_actvite_theme'] == 'custom_support') ? 'checked="true"' : ''; ?> type="radio" value="custom_support" class="styled" />
175
+
176
+ <label style="line-height:20px !important;margin-top:15px; ">Custom Icons <br /></label>
177
+
178
+ <div class="icns_tab_3" style="padding-left: 6px;">
179
+
180
+ <?php
181
+
182
+ if (get_option("rss_skin")) {
183
+
184
+ $icon = get_option("rss_skin");
185
+
186
+ echo '<span class="row_17_1 rss_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
187
+ } else {
188
+
189
+ echo '<span class="row_17_1 rss_section" style="background-position:-1px 0;"></span>';
190
+ }
191
+
192
+ if (get_option("email_skin")) {
193
+
194
+ $icon = get_option("email_skin");
195
+
196
+ echo '<span class="row_17_2 email_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
197
+ } else {
198
+
199
+ echo '<span class="row_17_2 email_section" style="background-position:-58px 0;"></span>';
200
+ }
201
+
202
+ if (get_option("facebook_skin")) {
203
+
204
+ $icon = get_option("facebook_skin");
205
+
206
+ echo '<span class="row_17_3 facebook_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
207
+ } else {
208
+
209
+ echo '<span class="row_17_3 facebook_section" style="background-position:-118px 0;"></span>';
210
+ }
211
+ if (get_option("twitter_skin")) {
212
+
213
+ $icon = get_option("twitter_skin");
214
+
215
+ echo '<span class="row_17_5 twitter_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
216
+ } else {
217
+
218
+ echo '<span class="row_17_5 twitter_section" style="background-position:-235px 0;"></span>';
219
+ }
220
+
221
+ if (get_option("youtube_skin")) {
222
+
223
+ $icon = get_option("youtube_skin");
224
+
225
+ echo '<span class="row_17_7 youtube_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
226
+ } else {
227
+
228
+ echo '<span class="row_17_7 youtube_section" style="background-position:-350px 0;"></span>';
229
+ }
230
+
231
+ if (get_option("pintrest_skin")) {
232
+
233
+ $icon = get_option("pintrest_skin");
234
+
235
+ echo '<span class="row_17_8 pinterest_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
236
+ } else {
237
+
238
+ echo '<span class="row_17_8 pinterest_section" style="background-position:-409px 0;"></span>';
239
+ }
240
+
241
+ if (get_option("linkedin_skin")) {
242
+
243
+ $icon = get_option("linkedin_skin");
244
+
245
+ echo '<span class="row_17_9 linkedin_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
246
+ } else {
247
+
248
+ echo '<span class="row_17_9 linkedin_section" style="background-position:-467px 0;"></span>';
249
+ }
250
+
251
+ if (get_option("instagram_skin")) {
252
+
253
+ $icon = get_option("instagram_skin");
254
+
255
+ echo '<span class="row_17_10 instagram_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
256
+ } else {
257
+
258
+ echo '<span class="row_17_10 instagram_section" style="background-position:-526px 0;"></span>';
259
+ }
260
+
261
+ if (get_option("telegram_skin")) {
262
+
263
+ $icon = get_option("telegram_skin");
264
+
265
+ echo '<span class="row_17_10 telegram_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
266
+ } else {
267
+
268
+ echo '<span class="row_17_10 telegram_section" style="background-position:-773px 0;"></span>';
269
+ }
270
+
271
+ if (get_option("vk_skin")) {
272
+
273
+ $icon = get_option("vk_skin");
274
+
275
+ echo '<span class="row_17_10 vk_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
276
+ } else {
277
+
278
+ echo '<span class="row_17_10 vk_section" style="background-position:-838px 0;"></span>';
279
+ }
280
+
281
+ if (get_option("ok_skin")) {
282
+
283
+ $icon = get_option("ok_skin");
284
+
285
+ echo '<span class="row_17_10 ok_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
286
+ } else {
287
+
288
+ echo '<span class="row_17_10 ok_section" style="background-position:-909px 0;"></span>';
289
+ }
290
+
291
+ if (get_option("weibo_skin")) {
292
+
293
+ $icon = get_option("weibo_skin");
294
+
295
+ echo '<span class="row_17_10 weibo_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
296
+ } else {
297
+
298
+ echo '<span class="row_17_10 weibo_section" style="background-position:-977px 0;"></span>';
299
+ }
300
+
301
+ if (get_option("wechat_skin")) {
302
+
303
+ $icon = get_option("wechat_skin");
304
+
305
+ echo '<span class="row_17_10 wechat_section sfsi-bgimage" style="background: url(' . $icon . ') no-repeat;"></span>';
306
+ } else {
307
+
308
+ echo '<span class="row_1_18 wechat_section"></span>';
309
+ }
310
+
311
+ ?>
312
+
313
+ </div>
314
+ </li>
315
+ <?php
316
+ }
317
+ ?><?php if (get_option('sfsi_custom_icons') == 'no') { ?>
318
+
319
+ <li class="sfsi_custom_icons_q4">
320
+ <div style="float: left;">
321
+ <a class="pop-up" data-id="sfsi_quickpay-overlay" onclick="sfsi_open_quick_checkout(event)" target="_blank" style="display: flex;">
322
+
323
+ <input type="radio" class="styled" />
324
+
325
+ <label style="line-height:20px !important;margin-top:15px;opacity:0.5">Custom Icons -</label>
326
+ </a>
327
+ </div>
328
+ <div>
329
+ <p style="margin-top: 3px;">
330
+ <a style="color: #12a252 !important;font-weight: bold; border-bottom:none;text-decoration: none;">
331
+ Premium Feature:
332
+ </a>
333
+ <span>Upload a custom design for the social media platforms implemented in the plugin under question number 1 - </span>
334
+ <a class="pop-up" style="cursor:pointer; color: #12a252 !important;border-bottom: 1px solid #12a252;text-decoration: none;font-weight: bold;" data-id="sfsi_quickpay-overlay" onclick="sfsi_open_quick_checkout(event)" target="_blank">
335
+ Get it now.
336
+ </a>
337
+ </p>
338
+ </div>
339
+ </li>
340
+ <?php
341
+ }
342
+ ?>
343
+ <li>
344
+
345
+ <?php include_once(SFSI_DOCROOT . '/views/subviews/que4/banner.php'); ?>
346
+
347
+ </li>
348
+
349
+ <li>
350
+
351
+ <p style="font-weight: bold; margin: 12px 0 0;">
352
+
353
+ Need icons for another theme? Let us know in the
354
+
355
+ <a target="_blank" href="https://wordpress.org/support/plugin/ultimate-social-media-icons/#new-topic-0" style="color:#8E81BD; text-decoration:underline;">
356
+
357
+ Support Forum
358
+
359
+ </a>
360
+
361
+ </p>
362
+
363
+ </li>
364
+
365
+ </ul>
366
+
367
+ <!--icon themes section start -->
368
+
369
+ <?php include_once(SFSI_DOCROOT . '/views/subviews/que4/animatethem.php'); ?>
370
+
371
+ </div>
372
+
373
+ <?php sfsi_ask_for_help(3); ?>
374
+
375
+ <!-- SAVE BUTTON SECTION -->
376
+
377
+ <div class="save_button tab_3_sav">
378
+
379
+ <img src="<?php echo SFSI_PLUGURL ?>images/ajax-loader.gif" class="loader-img" alt="error" />
380
+
381
+ <?php $nonce = wp_create_nonce("update_step3"); ?>
382
+
383
+ <a href="javascript:;" id="sfsi_save3" title="Save" data-nonce="<?php echo $nonce; ?>">Save</a>
384
+
385
+ </div>
386
+
387
+ <!-- END SAVE BUTTON SECTION -->
388
+
389
+ <a class="sfsiColbtn closeSec" href="javascript:;">Collapse area</a>
390
+
391
+ <label class="closeSec"></label>
392
+
393
+ <!-- ERROR AND SUCCESS MESSAGE AREA-->
394
+
395
+ <p class="red_txt errorMsg" style="display:none"> </p>
396
+
397
+ <p class="green_txt sucMsg" style="display:none"> </p>
398
+
399
+ </div>
400
+
401
  <!-- END Section 3 "What design & animation do you want to give your icons?" main div -->
views/sfsi_option_view6.php CHANGED
@@ -170,8 +170,7 @@ if (!isset($option6['sfsi_rectfbshare'])) {
170
  <div class="sfsi_new_prmium_follw" style="width: 91%;">
171
  <p style="font-size:20px !important">
172
  <b>New: </b>In the Premium Plugin, we also added: Pinterest, Linkedin, WhatsApp, VK,
173
- OK, Telegram, Weibo, WeChat, Xing and the option to add custom icons. There are more
174
- important options to add custom icons. There are more placement options too, e.g.
175
  place the responsive icons before/after posts/pages, show them only on
176
  desktop/mobile, insert them manually (via shortcode).<a href="https://www.ultimatelysocial.com/usm-premium/?utm_source=usmi_settings_page&utm_campaign=responsive_icons&utm_medium=banner" class="sfsi_font_inherit" target="_blank"> See all features</a>
177
  </p>
@@ -457,6 +456,22 @@ if (!isset($option6['sfsi_rectfbshare'])) {
457
  </div>
458
  </div>
459
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
  <div class="options sfsi_margin_top_0">
461
  <label class="first">
462
  Text on icons:
170
  <div class="sfsi_new_prmium_follw" style="width: 91%;">
171
  <p style="font-size:20px !important">
172
  <b>New: </b>In the Premium Plugin, we also added: Pinterest, Linkedin, WhatsApp, VK,
173
+ OK, Telegram, Weibo, WeChat, Xing and the option to add custom icons. There are more placement options too, e.g.
 
174
  place the responsive icons before/after posts/pages, show them only on
175
  desktop/mobile, insert them manually (via shortcode).<a href="https://www.ultimatelysocial.com/usm-premium/?utm_source=usmi_settings_page&utm_campaign=responsive_icons&utm_medium=banner" class="sfsi_font_inherit" target="_blank"> See all features</a>
176
  </p>
456
  </div>
457
  </div>
458
 
459
+ <div class="options sfsi_margin_top_0 sfsi_inputSec">
460
+ <label class="first">
461
+ Margins:
462
+ </label>
463
+ <div class="field" style="float: none;">
464
+ <span class="span_before_input" style="width: 120px;">Above Icon</span>
465
+ <input type="number" value="<?php echo isset($sfsi_responsive_icons["settings"]) && isset($sfsi_responsive_icons["settings"]["margin_above"]) ? $sfsi_responsive_icons["settings"]["margin_above"] : 0; ?>" name="sfsi_responsive_icons_settings_margin_above" style="float:none" />
466
+ <span class="span_after_input">px</span>
467
+ </div>
468
+ <div class="field" style="float: none;">
469
+ <span class="span_before_input" style="width: 120px;">Below Icon</span>
470
+ <input type="number" value="<?php echo isset($sfsi_responsive_icons["settings"]) && isset($sfsi_responsive_icons["settings"]["margin_below"]) ? $sfsi_responsive_icons["settings"]["margin_below"] : 0; ?>" name="sfsi_responsive_icons_settings_margin_below" style="float:none" />
471
+ <span class="span_after_input">px</span>
472
+ </div>
473
+ </div>
474
+
475
  <div class="options sfsi_margin_top_0">
476
  <label class="first">
477
  Text on icons: