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 | 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
- analyst/assets/css/customize.css +280 -280
- analyst/assets/index.php +2 -2
- analyst/assets/js/customize.js +29 -29
- analyst/autoload.php +40 -40
- analyst/index.php +2 -2
- analyst/main.php +36 -36
- analyst/sdk_resolver.php +79 -79
- analyst/src/Account/AccountData.php +176 -176
- analyst/src/Account/AccountDataFactory.php +125 -125
- analyst/src/Analyst.php +167 -167
- analyst/src/ApiRequestor.php +257 -257
- analyst/src/ApiResponse.php +44 -44
- analyst/src/Cache/DatabaseCache.php +127 -127
- analyst/src/Collector.php +217 -217
- analyst/src/Contracts/AnalystContract.php +12 -12
- analyst/src/Contracts/CacheContract.php +47 -47
- analyst/src/Contracts/HttpClientContract.php +25 -25
- analyst/src/Contracts/RequestContract.php +22 -22
- analyst/src/Contracts/RequestorContract.php +44 -44
- analyst/src/Contracts/TrackerContract.php +69 -69
- analyst/src/Core/AbstractFactory.php +27 -27
- analyst/src/Http/CurlHttpClient.php +102 -102
- analyst/src/Http/DummyHttpClient.php +33 -33
- analyst/src/Http/Requests/AbstractLoggerRequest.php +64 -64
- analyst/src/Http/Requests/ActivateRequest.php +42 -42
- analyst/src/Http/Requests/DeactivateRequest.php +64 -64
- analyst/src/Http/Requests/InstallRequest.php +38 -38
- analyst/src/Http/Requests/OptInRequest.php +42 -42
- analyst/src/Http/Requests/OptOutRequest.php +40 -40
- analyst/src/Http/Requests/UninstallRequest.php +36 -36
- analyst/src/Http/WordPressHttpClient.php +61 -61
- analyst/src/Mutator.php +103 -103
- analyst/src/Notices/Notice.php +121 -121
- analyst/src/Notices/NoticeFactory.php +130 -130
- analyst/templates/forms/deactivate.php +156 -156
- analyst/templates/forms/install.php +113 -113
- analyst/templates/notice.php +10 -10
- analyst/templates/optin.php +60 -60
- analyst/templates/optout.php +109 -109
- css/jquery-ui-1.10.4/jquery-ui.css +1177 -1177
- css/sfsi-style.css +28 -3
- helpers/common_helper.php +202 -202
- helpers/linkedin-api/linkedin-api.php +136 -136
- helpers/sfsi_OAuth.php +910 -910
- helpers/twitteroauth/src/TwitterOAuth.php +506 -506
- images/responsive-icon/Twitter.svg +3 -3
- images/responsive-icon/facebook.svg +3 -3
- images/visit_icons/en_US_Follow.svg +16 -0
- images/visit_icons/en_US_Tweet.svg +18 -0
- images/visit_icons/en_US_save.svg +23 -0
- js/custom-admin.js +3 -0
- js/custom-form.js +148 -148
- js/index.php +3 -3
- js/shuffle/jquery.shuffle.js +1267 -1267
- libs/controllers/sfsi_buttons_controller.php +3 -1
- libs/controllers/sfsi_iconsUpload_contoller.php +529 -529
- libs/controllers/sfsi_socialhelper.php +63 -24
- libs/controllers/sfsiocns_OnPosts.php +164 -125
- libs/sfsi_Init_JqueryCss.php +132 -132
- libs/sfsi_ajax_social_sharing_settings_updater.php +15 -15
- libs/sfsi_install_uninstall.php +1 -1
- libs/sfsi_widget.php +3 -4
- readme.txt +7 -2
- ultimate_social_media_icons.php +2 -2
- views/deactivation/sfsi_deactivation_popup.php +121 -121
- views/sfsi_chat_on_admin_pannel.php +117 -117
- views/sfsi_option_view3.php +400 -400
- 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 |
-
|
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:
|
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 |
-
|
263 |
-
|
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).'"
|
|
|
|
|
|
|
|
|
280 |
return $twitter_html;
|
281 |
}
|
282 |
|
283 |
/* create on page twitter share icon */
|
284 |
public function sfsi_twitterShare($permalink,$tweettext)
|
285 |
{
|
286 |
-
|
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=" " ></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 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
}
|
306 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
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 |
-
|
63 |
-
|
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 (
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
if ($
|
81 |
-
if ($
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
$
|
90 |
-
|
91 |
-
|
|
|
|
|
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 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
}
|
108 |
|
109 |
if (($sfsi_section6['sfsi_show_Onposts'] == "yes") && $sfsi_section6['sfsi_rectpinit'] == 'yes') {
|
110 |
-
$
|
111 |
-
|
112 |
-
$
|
113 |
-
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
}
|
116 |
-
$icons .= "<div class='sf_pinit' style='text-align:left;vertical-align: middle;float:left;line-height: 20px;width:
|
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 = '
|
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 |
-
|
|
|
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 . '"
|
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"
|
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 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
|
|
|
|
|
|
|
|
|
|
288 |
}
|
|
|
289 |
|
290 |
-
|
291 |
-
|
|
|
292 |
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
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.
|
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;
|
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="
|
294 |
} else {
|
295 |
-
$icons_main = '<div class="norm_row sfsi_wDiv " style="
|
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.
|
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.
|
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.
|
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.
|
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">×</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">×</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">×</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">×</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:
|