WP Force SSL - Version 1.60

Version Description

Download this release

Release Info

Developer WebFactory
Plugin Icon 128x128 WP Force SSL
Version 1.60
Comparing to
See all releases

Code changes from version 1.57 to 1.60

css/wpfs-style.css CHANGED
@@ -1,147 +1,1105 @@
1
  /*
2
  * WP Force SSL
3
- * (c) WebFactory Ltd 2019 - 2021
4
  */
5
 
6
- .settings_page_wpfs-settings .button {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  box-shadow: none;
8
- text-shadow: none;
9
- border-radius: 0;
10
- margin-right: 15px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  }
12
 
13
  .settings_page_wpfs-settings h1 {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  font-weight: 600;
15
  }
16
 
17
- .settings_page_wpfs-settings,
18
- .settings_page_wpfs-settings p {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  font-size: 14px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
21
 
22
- .settings_page_wpfs-settings .swal2-container {
23
- z-index: 99999;
24
  }
25
 
26
- .settings_page_wpfs-settings .box {
27
- padding: 30px 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  display: inline-block;
29
- border: thin solid black;
30
- background: white;
31
- margin: 15px 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
 
34
  .settings_page_wpfs-settings .form-table th {
35
- font-weight: 400;
36
  }
37
 
38
- .rotating {
39
- -webkit-animation: spin 1.5s linear infinite;
40
- -moz-animation: spin 1.5s linear infinite;
41
- animation: spin 1.5s linear infinite;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
43
 
44
  @-moz-keyframes spin {
45
  100% {
46
- -moz-transform: rotate(-360deg);
47
  }
48
  }
49
 
50
  @-webkit-keyframes spin {
51
  100% {
52
- -webkit-transform: rotate(-360deg);
53
  }
54
  }
55
 
56
  @keyframes spin {
57
  100% {
58
- -webkit-transform: rotate(-360deg);
59
- transform: rotate(-360deg);
60
  }
61
  }
62
 
63
- .swal2-popup .swal2-title {
64
- line-height: 100%;
 
 
 
65
  }
66
 
67
- .toggle-wrapper {
68
- position: relative;
69
- overflow: hidden;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  display: inline-block;
71
- border: 1px solid #dcdada;
72
- background-color: #ffffff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
74
 
75
- .toggle-wrapper input {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  position: absolute;
77
- left: -99em;
 
 
 
 
 
78
  }
79
 
80
- .toggle-wrapper .toggle {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  display: inline-block;
83
- position: relative;
84
- width: 121px;
85
- height: 30px;
86
- font-weight: 600;
87
- background: transparent;
88
- border: 2px solid #f1f1f1;
89
- -webkit-transition: all 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
90
- transition: all 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
 
 
 
 
 
 
91
  }
92
 
93
- .toggle-wrapper .toggle:before,
94
- .toggle-wrapper .toggle:after {
95
- position: absolute;
96
- line-height: 30px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  font-size: 14px;
98
- z-index: 2;
99
- -webkit-transition: all 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
100
- transition: all 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
101
  }
102
 
103
- .toggle-wrapper .toggle:before {
104
- content: 'OFF';
105
- left: 18px;
106
- color: #ffffff;
 
 
 
 
 
 
 
 
 
 
 
107
  }
108
 
109
- .toggle-wrapper .toggle:after {
110
- content: 'ON';
111
- right: 20px;
112
- color: #23282d;
113
  }
114
 
115
- .toggle-wrapper .toggle_handler {
 
 
 
 
116
  display: inline-block;
117
- position: relative;
118
- z-index: 1;
119
- background: #ea1919;
120
- width: 55px;
121
- height: 24px;
122
- top: 3px;
123
- left: 3px;
124
- -webkit-transition: all 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
125
- transition: all 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
126
- -webkit-transform: translateX(0px);
127
- transform: translateX(0px);
128
  }
129
 
130
- .toggle-wrapper input:checked + .toggle {
131
- background: transparent;
 
 
 
 
132
  }
133
 
134
- .toggle-wrapper input:checked + .toggle:before {
135
- color: #23282d;
136
  }
137
 
138
- .toggle-wrapper input:checked + .toggle:after {
139
- color: #fff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  }
141
 
142
- .toggle-wrapper input:checked + .toggle .toggle_handler {
143
- width: 55px;
144
- -webkit-transform: translateX(60px);
145
- transform: translateX(60px);
146
- background: #66b317;
 
 
 
 
 
 
 
 
 
 
147
  }
1
  /*
2
  * WP Force SSL
3
+ * (c) WebFactory Ltd 2019 - 2022
4
  */
5
 
6
+ #wpbody {
7
+ font-family: 'Inter', sans-serif !important;
8
+ font-size: 14px !important;
9
+ font-weight: 400 !important;
10
+ color: #1d2328 !important;
11
+ }
12
+
13
+ .d-none {
14
+ display: none;
15
+ }
16
+
17
+ .settings_page_wpfs-settings #wpcontent,
18
+ .settings_page_wpfs-settings .auto-fold #wpcontent {
19
+ padding-left: 0;
20
+ }
21
+
22
+ .settings_page_wpfs-settings {
23
+ overflow-y: scroll;
24
+ }
25
+
26
+ body.settings_page_wp-force-ssl.swal2-height-auto {
27
+ height: 100% !important;
28
+ }
29
+
30
+ .settings_page_wpfs-settings .swal2-styled.swal2-confirm {
31
+ background-color: #42972d;
32
+ border: none;
33
+ }
34
+
35
+ .settings_page_wpfs-settings .swal2-styled:focus {
36
  box-shadow: none;
37
+ border: none;
38
+ }
39
+
40
+ .swal2-popup .swal2-title {
41
+ line-height: 1.2;
42
+ }
43
+
44
+ .settings_page_wpfs-settings .wrap {
45
+ margin: 0;
46
+ background: #f9fbfd;
47
+ min-height: calc(100vh - 100px);
48
+ font-size: 14px;
49
+ padding: 0;
50
+ }
51
+
52
+ .settings_page_wpfs-settings .disabled {
53
+ pointer-events: none;
54
+ opacity: 0.8;
55
+ cursor: not-allowed;
56
+ }
57
+
58
+ .settings_page_wpfs-settings .loading-wrapper {
59
+ padding-top: 80px;
60
+ text-align: center;
61
+ }
62
+
63
+ .settings_page_wpfs-settings .loading-wrapper img {
64
+ width: 100px;
65
+ height: auto;
66
+ opacity: 0.4;
67
+ }
68
+
69
+ .settings_page_wpfs-settings .mb0 {
70
+ margin-bottom: 0;
71
+ }
72
+
73
+ .wpmu-error {
74
+ padding: 10px;
75
+ border: 1px solid #dd3036;
76
+ }
77
+
78
+ .ssl_cert_error,
79
+ .ssl_cert_info {
80
+ margin-top: 10px;
81
+ clear: both;
82
+ }
83
+
84
+ .ssl_cert_error {
85
+ color: #fe725f;
86
+ font-weight: bold;
87
+ }
88
+
89
+ #ssl_cert_details {
90
+ position: relative;
91
+ }
92
+
93
+ #ssl_cert_details .dashicons {
94
+ font-size: 80px;
95
+ position: absolute;
96
+ top: -40px;
97
+ right: -40px;
98
+ background: #fff;
99
+ width: 80px;
100
+ height: 80px;
101
+ border-radius: 80px;
102
+ }
103
+
104
+ .wfssl-container {
105
+ margin: 0 auto;
106
+ max-width: 100%;
107
+ width: 1427px;
108
+ }
109
+
110
+ .wfssl-container-left {
111
+ max-width: calc(65% - 40px);
112
+ margin: 0px 20px;
113
+ float: left;
114
+ }
115
+
116
+ .wfssl-container-right {
117
+ max-width: calc(35% - 40px);
118
+ margin: 0px 20px;
119
+ float: left;
120
+ }
121
+
122
+ @media screen and (max-width: 1055px) {
123
+ .wfssl-container-left {
124
+ width: 100%;
125
+ }
126
+
127
+ .wfssl-container-right {
128
+ display: none;
129
+ }
130
+ }
131
+ .sidebar-box {
132
+ box-shadow: 0 1px 1px rgb(0 0 0 / 4%);
133
+ background: white;
134
+ margin-top: 76px;
135
+ padding: 15px;
136
+ font-size: 14px;
137
+ line-height: 1.5;
138
+ max-width: 450px;
139
+ }
140
+
141
+ .sidebar-box.pro-ad-box {
142
+ border: 2px solid #42982e;
143
+ }
144
+
145
+ .text-center {
146
+ text-align: center;
147
+ }
148
+
149
+ .plain-list {
150
+ margin-top: 5px;
151
+ list-style-type: circle;
152
+ list-style-position: inside;
153
+ }
154
+
155
+ .plain-list li {
156
+ text-indent: -18px;
157
+ padding-left: 23px;
158
+ line-height: 23px;
159
+ margin: 0;
160
+ }
161
+
162
+ .wfssl-tab-content {
163
+ background: #ffffff;
164
+ padding: 20px 40px;
165
+ border-bottom-left-radius: 4px;
166
+ border-bottom-right-radius: 4px;
167
+ border-top-right-radius: 4px;
168
+ font-size: 16px;
169
+ }
170
+
171
+ .wfssl-tab-content p {
172
+ font-size: 14px;
173
+ color: #6f7376;
174
+ }
175
+
176
+ .settings_page_wpfs-settings header {
177
+ padding: 20px 20px;
178
+ background: #ffffff;
179
+ }
180
+
181
+ .settings_page_wpfs-settings #logo-icon {
182
+ max-height: 42px;
183
+ width: auto;
184
+ padding: 0;
185
+ margin: 0;
186
+ display: inline;
187
+ vertical-align: bottom;
188
+ margin-right: 4px;
189
+ image-rendering: -moz-crisp-edges;
190
+ image-rendering: -o-crisp-edges;
191
+ image-rendering: -webkit-optimize-contrast;
192
+ image-rendering: crisp-edges;
193
+ -ms-interpolation-mode: nearest-neighbor;
194
  }
195
 
196
  .settings_page_wpfs-settings h1 {
197
+ font-size: 22px;
198
+ display: inline-block;
199
+ line-height: 44px;
200
+ margin: 0;
201
+ padding: 0;
202
+ margin-block-end: 0;
203
+ margin-block-start: 0;
204
+ }
205
+
206
+ .settings_page_wpfs-settings nav {
207
+ padding: 0;
208
+ margin: 25px 0 0 0;
209
+ }
210
+
211
+ .settings_page_wpfs-settings #wfssl-content {
212
+ padding: 0 0 35px 0;
213
+ }
214
+
215
+ /* tabs */
216
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li.wfssl-tab-pro a {
217
+ background-color: #42972d;
218
+ color: white;
219
+ font-weight: 600;
220
+ }
221
+
222
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li.wfssl-tab-pro a:hover {
223
+ background-color: #42972d90;
224
+ color: white;
225
  font-weight: 600;
226
  }
227
 
228
+ .settings_page_wpfs-settings .ui-tabs {
229
+ max-width: 1050px;
230
+ position: relative;
231
+ padding: 0px;
232
+ zoom: 1;
233
+ margin: 0;
234
+ margin-bottom: 20px;
235
+ }
236
+
237
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav {
238
+ margin: 0;
239
+ padding: 0;
240
+ }
241
+
242
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li {
243
+ list-style: none;
244
+ position: relative;
245
+ top: 1px;
246
+ margin: 0 0.2em 1px 0;
247
+ padding: 0;
248
+ white-space: nowrap;
249
+ }
250
+
251
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li a {
252
+ text-decoration: none;
253
+ }
254
+
255
+ .settings_page_wpfs-settings ul.ui-tabs-nav.wfssl-main-tab li.ui-state-active {
256
+ border-bottom: 2px solid #ffffff;
257
+ transition: all 0.4s ease-out;
258
+ }
259
+
260
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li.ui-tabs-selected a,
261
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li.ui-state-disabled a,
262
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li.ui-state-processing a {
263
+ cursor: text;
264
+ }
265
+
266
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li a,
267
+ .settings_page_wpfs-settings .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a {
268
+ cursor: pointer;
269
+ }
270
+
271
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-panel {
272
+ display: block;
273
+ border: none;
274
+ overflow: hidden;
275
+ }
276
+
277
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-hide {
278
+ display: none !important;
279
+ }
280
+
281
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li a {
282
+ font-size: 16px;
283
+ font-weight: 500;
284
+ line-height: 32px;
285
+ color: #616161;
286
+ padding: 5px 0;
287
+ display: block;
288
+ padding: 8px 14px;
289
+ }
290
+
291
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li a:hover {
292
+ color: #222222;
293
+ }
294
+
295
+ .settings_page_wpfs-settings .ui-tabs ul.ui-tabs-nav li.ui-state-active .icon {
296
+ color: #666666;
297
+ }
298
+
299
+ .settings_page_wpfs-settings .ui-tabs-nav:after {
300
+ content: '';
301
+ clear: both;
302
+ display: block;
303
+ }
304
+
305
+ .settings_page_wpfs-settings .ui-tabs-anchor,
306
+ .nav-tab {
307
+ outline: none !important;
308
+ }
309
+
310
+ .settings_page_wpfs-settings .ui-tabs ul.ui-tabs-nav li {
311
+ color: #aaaaaa;
312
+ display: inline-block;
313
+ font-size: 12px;
314
+ line-height: 16px;
315
+ text-decoration: none;
316
+ text-shadow: none;
317
+ padding: 0;
318
+ text-align: center;
319
+ border-bottom: 2px solid #f0f0f1;
320
+ background: #fff;
321
+ margin: 0px 5px 1px 5px;
322
+ border-top-left-radius: 4px;
323
+ border-top-right-radius: 4px;
324
+ }
325
+
326
+ @media screen and (max-width: 880px) {
327
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav {
328
+ padding: 0 25px;
329
+ }
330
+ .settings_page_wpfs-settings .ui-tabs ul.ui-tabs-nav li {
331
+ margin: 0px 10px 0px 5px;
332
+ }
333
+ }
334
+
335
+ .settings_page_wpfs-settings .ui-tabs ul.ui-tabs-nav li .label {
336
+ display: block;
337
+ margin-top: -10px;
338
+ }
339
+
340
+ .settings_page_wpfs-settings .ui-tabs ul.ui-tabs-nav li:first-child {
341
+ margin-left: 0;
342
+ }
343
+
344
+ .settings_page_wpfs-settings ul.ui-tabs-nav.wfssl-main-tab {
345
+ padding-bottom: 0;
346
+ width: 100%;
347
+ box-sizing: border-box;
348
+ }
349
+
350
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav .ui-state-hover a,
351
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav .ui-state-active a,
352
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li.ui-state-hover,
353
+ .settings_page_wpfs-settings .ui-tabs .ui-tabs-nav li.ui-state-hover a {
354
+ color: #42972d;
355
+ }
356
+
357
+ .settings_page_wpfs-settings .ui-tabs ul.ui-tabs-nav li.ui-state-hover {
358
+ background-color: #fafafa !important;
359
+ border-bottom: 2px solid #fafafa;
360
+ }
361
+
362
+ .settings_page_wpfs-settings .ui-tabs-nav a:focus {
363
+ box-shadow: none;
364
+ -webkit-box-shadow: none;
365
+ }
366
+ /* tabs */
367
+
368
+ .wfssl-tab-title {
369
+ margin: 0 0 25px;
370
+ font-size: 26px;
371
+ font-weight: 400;
372
+ }
373
+
374
+ .wfssl-progress .bar {
375
+ height: 25px;
376
+ background-color: #42972d;
377
+ border-radius: 8px;
378
+ position: relative;
379
+ }
380
+
381
+ .wfssl-progress {
382
+ height: 25px;
383
+ margin-bottom: 15px;
384
+ border-radius: 8px;
385
+ position: relative;
386
+ background-color: #e7e7e7;
387
+ }
388
+
389
+ .wfssl-progress-text {
390
+ position: absolute;
391
+ right: 10px;
392
+ margin-left: -10px;
393
  font-size: 14px;
394
+ color: #fff;
395
+ top: 3px;
396
+ }
397
+
398
+ .wfssl-labels {
399
+ font-size: 16px;
400
+ font-weight: 400;
401
+ color: #222222;
402
+ margin-bottom: 25px;
403
+ }
404
+
405
+ .wfssl-badge {
406
+ display: block;
407
+ text-align: center;
408
+ width: 110px;
409
+ height: 27px;
410
+ line-height: 27px;
411
+ color: #ffffff;
412
+ text-transform: capitalize;
413
+ border-radius: 100px;
414
  }
415
 
416
+ .wfssl-badge-red {
417
+ background-color: #fe725f;
418
  }
419
 
420
+ .wfssl-badge-green {
421
+ background-color: #42972d;
422
+ }
423
+
424
+ .wfssl-badge-yellow {
425
+ background-color: #ffaa39;
426
+ }
427
+
428
+ .wfssl-badge-gray {
429
+ background-color: #d6d6d6;
430
+ }
431
+
432
+ .wfssl-badge-empty {
433
+ background-color: transparent;
434
+ }
435
+
436
+ #test-results tr td {
437
+ padding: 4px;
438
+ }
439
+
440
+ .wfssl-switch {
441
+ position: relative;
442
  display: inline-block;
443
+ width: 50px;
444
+ height: 26px;
445
+ }
446
+
447
+ .wfssl-slider {
448
+ position: absolute;
449
+ cursor: pointer;
450
+ top: 0;
451
+ left: 0;
452
+ right: 0;
453
+ bottom: 0;
454
+ background-color: #ccc;
455
+ -webkit-transition: 0.4s;
456
+ transition: 0.4s;
457
+ }
458
+
459
+ .wfssl-slider:before {
460
+ position: absolute;
461
+ content: '';
462
+ height: 22px;
463
+ width: 22px;
464
+ left: 3px;
465
+ bottom: 2px;
466
+ background-color: white;
467
+ -webkit-transition: 0.4s;
468
+ transition: 0.4s;
469
+ }
470
+
471
+ .wfssl-slider.wfssl-round {
472
+ border-radius: 20px;
473
+ }
474
+
475
+ .wfssl-slider.wfssl-round:before {
476
+ border-radius: 50%;
477
+ }
478
+
479
+ input:checked + .wfssl-slider {
480
+ background-color: #42972d;
481
+ }
482
+
483
+ .disabled input:checked + .wfssl-slider {
484
+ background-color: #ccc;
485
+ }
486
+
487
+ input:checked + .wfssl-slider:before {
488
+ -webkit-transform: translateX(23px);
489
+ -ms-transform: translateX(23px);
490
+ transform: translateX(23px);
491
+ }
492
+
493
+ .wfssl-switch input[type='checkbox'] {
494
+ position: absolute;
495
+ opacity: 0;
496
+ z-index: -1;
497
+ }
498
+
499
+ #settings-table tr td:first-child {
500
+ width: 60%;
501
+ margin-right: 20px;
502
+ }
503
+
504
+ #settings-table tr td:last-child label {
505
+ margin-left: 15px;
506
+ }
507
+
508
+ #settings-table tr td {
509
+ padding: 4px;
510
+ }
511
+
512
+ .wfssl-adminbar-icon {
513
+ display: inline-block;
514
+ }
515
+
516
+ .settings_page_wpfs-settings tbody th,
517
+ .settings_page_wpfs-settings table.dataTable tbody td,
518
+ .settings_page_wpfs-settings .form-table td {
519
+ padding: 10px 4px !important;
520
  }
521
 
522
  .settings_page_wpfs-settings .form-table th {
523
+ width: 120px;
524
  }
525
 
526
+ .settings_page_wpfs-settings thead th,
527
+ table.dataTable thead td {
528
+ border: none !important;
529
+ }
530
+
531
+ .dataTables_length {
532
+ display: none;
533
+ }
534
+
535
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current,
536
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
537
+ background: none !important;
538
+ border: none !important;
539
+ }
540
+
541
+ .dataTables_wrapper tr.even td {
542
+ background: #f5f5f5;
543
+ }
544
+
545
+ .scanner-stats {
546
+ padding: 10px 0 20px;
547
+ float: right;
548
+ }
549
+
550
+ .scanner-stats span {
551
+ font-weight: 500;
552
+ }
553
+
554
+ .settings_page_wpfs-settings .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
555
+ color: #368cd3 !important;
556
+ background: transparent;
557
+ border-color: transparent;
558
+ }
559
+
560
+ .settings_page_wpfs-settings table.dataTable thead th,
561
+ .settings_page_wpfs-settings table.dataTable thead td {
562
+ padding: 10px 8px;
563
+ }
564
+
565
+ .wfssl-submit-icon {
566
+ min-width: 32px;
567
+ max-width: 32px;
568
+ width: 32px;
569
+ max-height: 32px;
570
+ min-height: 32px;
571
+ height: 32px;
572
+ display: flex;
573
+ align-items: center;
574
+ justify-content: center;
575
+ position: relative;
576
+ }
577
+
578
+ .wfssl-refresh-icon {
579
+ position: absolute;
580
+ max-width: 100%;
581
+ }
582
+
583
+ .wfssl-refresh-icon:focus,
584
+ .wfssl-refresh-icon:active {
585
+ outline: 0;
586
+ box-shadow: none;
587
+ border: 0;
588
+ }
589
+
590
+ .wfssl_rotating {
591
+ -webkit-animation: spin 2.5s linear infinite;
592
+ -moz-animation: spin 2.5s linear infinite;
593
+ animation: spin 2.5s linear infinite;
594
  }
595
 
596
  @-moz-keyframes spin {
597
  100% {
598
+ -moz-transform: rotate(360deg);
599
  }
600
  }
601
 
602
  @-webkit-keyframes spin {
603
  100% {
604
+ -webkit-transform: rotate(360deg);
605
  }
606
  }
607
 
608
  @keyframes spin {
609
  100% {
610
+ -webkit-transform: rotate(360deg);
611
+ transform: rotate(360deg);
612
  }
613
  }
614
 
615
+ .wfssl_flicker {
616
+ -webkit-animation: flickerAnimation 2s infinite;
617
+ -moz-animation: flickerAnimation 2s infinite;
618
+ -o-animation: flickerAnimation 2s infinite;
619
+ animation: flickerAnimation 2s infinite;
620
  }
621
 
622
+ @keyframes flickerAnimation {
623
+ 0% {
624
+ opacity: 1;
625
+ }
626
+ 50% {
627
+ opacity: 0.55;
628
+ }
629
+ 100% {
630
+ opacity: 1;
631
+ }
632
+ }
633
+
634
+ @-o-keyframes flickerAnimation {
635
+ 0% {
636
+ opacity: 1;
637
+ }
638
+ 50% {
639
+ opacity: 0.55;
640
+ }
641
+ 100% {
642
+ opacity: 1;
643
+ }
644
+ }
645
+
646
+ @-moz-keyframes flickerAnimation {
647
+ 0% {
648
+ opacity: 1;
649
+ }
650
+ 50% {
651
+ opacity: 0.55;
652
+ }
653
+ 100% {
654
+ opacity: 1;
655
+ }
656
+ }
657
+
658
+ @-webkit-keyframes flickerAnimation {
659
+ 0% {
660
+ opacity: 1;
661
+ }
662
+ 50% {
663
+ opacity: 0.55;
664
+ }
665
+ 100% {
666
+ opacity: 1;
667
+ }
668
+ }
669
+
670
+ .wfssl-box {
671
+ background-color: #f5f5f5;
672
+ padding: 27px 31px 47px 31px;
673
+ width: 100%;
674
+ border-radius: 4px;
675
+ font-size: 14px;
676
+ box-sizing: border-box;
677
+ float: left;
678
+ margin-bottom: 20px;
679
+ }
680
+
681
+ .settings_page_wpfs-settings .button {
682
  display: inline-block;
683
+ padding: 4px 11px;
684
+ border-radius: 4px;
685
+ margin-right: 10px;
686
+ cursor: pointer;
687
+ width: auto;
688
+ max-width: fit-content;
689
+ text-align: center;
690
+ height: 32px;
691
+ line-height: 32px;
692
+ font-size: 14px;
693
+ transition: background-color 0.5s ease;
694
+ background-color: #f2f2f2;
695
+ border: none;
696
+ line-height: 23px;
697
+ color: #1d2328;
698
+ box-shadow: none;
699
+ }
700
+
701
+ .settings_page_wpfs-settings .button-primary {
702
+ background-color: #42972d;
703
+ color: #ffffff;
704
+ }
705
+
706
+ .settings_page_wpfs-settings .button:hover,
707
+ .settings_page_wpfs-settings .button:focus,
708
+ .settings_page_wpfs-settings .button.active,
709
+ .settings_page_wpfs-settings .button.active:focus,
710
+ .settings_page_wpfs-settings .button.active:hover,
711
+ .settings_page_wpfs-settings .button:active {
712
+ background-color: #dedddd;
713
+ color: #222222;
714
+ box-shadow: none;
715
+ }
716
+
717
+ .settings_page_wpfs-settings .button-primary:hover,
718
+ .settings_page_wpfs-settings .button-primary:focus,
719
+ .settings_page_wpfs-settings .button-primary.active,
720
+ .settings_page_wpfs-settings .button-primary.active:focus,
721
+ .settings_page_wpfs-settings .button-primary.active:hover,
722
+ .settings_page_wpfs-settings .button-primary:active {
723
+ background-color: #3b8828;
724
+ color: #ffffff;
725
+ box-shadow: none;
726
+ }
727
+
728
+ .settings_page_wpfs-settings input[type='text'],
729
+ .settings_page_wpfs-settings select {
730
+ background-color: #f5f5f5;
731
+ color: #1d2328;
732
+ min-width: 220px;
733
+ border-color: #f5f5f5 !important;
734
+ box-shadow: none !important;
735
+ outline: 0 !important;
736
+ padding: 8px;
737
+ }
738
+
739
+ .settings_page_wpfs-settings input:hover,
740
+ .settings_page_wpfs-settings input:focus,
741
+ .settings_page_wpfs-settings input:active {
742
+ background-color: #f5f5f5;
743
+ color: #333333;
744
+ border-color: #f5f5f5 !important;
745
+ box-shadow: none !important;
746
+ outline: 0 !important;
747
+ padding: 8px;
748
  }
749
 
750
+ .settings_page_wpfs-settings input[type='readonly'] {
751
+ background-color: #f5f5f5;
752
+ color: #dbd7d5;
753
+ }
754
+
755
+ .wfssl-red {
756
+ color: #fe725f;
757
+ }
758
+
759
+ .wfssl-green {
760
+ color: #42972d;
761
+ }
762
+
763
+ .test-details-title {
764
+ text-align: left;
765
+ font-size: 20px;
766
+ margin: 10px 0;
767
+ }
768
+
769
+ .test-details-body {
770
+ text-align: left;
771
+ padding: 20px 0;
772
+ }
773
+
774
+ .status-tasks {
775
+ display: inline-block;
776
+ color: #a0a3a5;
777
+ margin-right: 10px;
778
+ cursor: pointer;
779
+ }
780
+
781
+ .status-tasks-selected,
782
+ .status-tasks:hover {
783
+ color: #1d2328;
784
+ }
785
+
786
+ #scanner-results {
787
+ width: 100% !important;
788
+ border-bottom: none;
789
+ }
790
+
791
+ #scanner-results-none {
792
+ text-align: center;
793
+ }
794
+
795
+ #scanner-results-none .dashicons {
796
+ font-size: 100px;
797
+ width: 100px;
798
+ height: 100px;
799
+ }
800
+
801
+ #scanner-results thead th {
802
+ background-color: #f5f5f5;
803
+ font-size: 14px;
804
+ font-weight: 500;
805
+ }
806
+
807
+ /* Accordion styles */
808
+ input[type='checkbox'] {
809
  position: absolute;
810
+ opacity: 0;
811
+ z-index: -1;
812
+ }
813
+
814
+ .wfssl-accordion-col {
815
+ width: 950px;
816
  }
817
 
818
+ .wfssl-accordion-tabs {
819
+ border-radius: 8px;
820
+ overflow: hidden;
821
+ box-shadow: 0 4px 4px -2px rgba(0, 0, 0, 0.5);
822
+ }
823
+
824
+ .wfssl-accordion-tab {
825
+ width: 100%;
826
+ color: white;
827
+ overflow: hidden;
828
+ margin-bottom: 15px;
829
+ }
830
+
831
+ .wfssl-accordion-tab-label {
832
+ display: flex;
833
+ justify-content: space-between;
834
+ padding: 1em;
835
+ background: #f5f5f5;
836
  cursor: pointer;
837
+ color: #1d2328cc;
838
+ }
839
+
840
+ .wfssl-accordion-tab-label:hover {
841
+ background: darken(#f5f5f5, 10%);
842
+ }
843
+
844
+ .wfssl-accordion-tab-label::after {
845
+ content: '\276F';
846
+ width: 1em;
847
+ height: 1em;
848
+ text-align: center;
849
+ transition: all 0.35s;
850
+ }
851
+
852
+ .wfssl-accordion-tab-content {
853
+ max-height: 0;
854
+ padding: 0 1em;
855
+ color: #f5f5f5;
856
+ background: white;
857
+ transition: all 0.35s;
858
+ color: #1d2328cc;
859
+ line-height: 1.5;
860
+ }
861
+
862
+ .wfssl-accordion-tab-close {
863
+ display: flex;
864
+ justify-content: flex-end;
865
+ padding: 1em;
866
+ font-size: 0.75em;
867
+ background: #f5f5f5;
868
+ cursor: pointer;
869
+ color: #1d2328cc;
870
+ }
871
+
872
+ .wfssl-accordion-tab-close:hover {
873
+ background: darken(#f5f5f5, 10%);
874
+ }
875
+
876
+ input:checked + .wfssl-accordion-tab-label {
877
+ background: darken(#f5f5f5, 10%);
878
+ }
879
+
880
+ input:checked + .wfssl-accordion-tab-label::after {
881
+ transform: rotate(90deg);
882
+ }
883
+
884
+ input:checked ~ .wfssl-accordion-tab-content {
885
+ max-height: 100vh;
886
+ padding: 1em;
887
+ }
888
+
889
+ .wfssl-support-icon {
890
+ font-size: 40px;
891
+ width: 40px;
892
+ height: 40px;
893
+ }
894
+
895
+ #wfssl-cert-email {
896
+ box-sizing: border-box;
897
+ width: 100%;
898
+ display: block;
899
+ clear: both;
900
+ padding-top: 30px;
901
+ padding: 20px;
902
+ border: 1px solid #eee;
903
+ border-radius: 4px;
904
+ }
905
+
906
+ #wfssl-cert-expiration-email-box {
907
+ padding-top: 20px;
908
+ }
909
+
910
+ .settings_page_wpfs-settings #wpfooter {
911
+ padding: 20px;
912
+ border-top: 1px solid #e5e5e5;
913
+ background-color: #ffffff;
914
+ }
915
+
916
+ .settings_page_wpfs-settings #wpfooter .wfssl-footer a {
917
+ text-decoration: none;
918
+ }
919
+
920
+ .settings_page_wpfs-settings #wpfooter .wfssl-footer span {
921
+ color: #ffb900;
922
+ }
923
+
924
+ #settings-table small,
925
+ #test-results-wrapper small {
926
+ display: block;
927
+ color: #666666;
928
+ font-size: 13px;
929
+ line-height: 1.5;
930
+ margin-top: 3px;
931
+ }
932
+
933
+ #test-results-wrapper td {
934
+ padding-right: 15px !important;
935
+ }
936
+
937
+ #wpadminbar .wfssl-failed-tests {
938
  display: inline-block;
939
+ vertical-align: top;
940
+ box-sizing: border-box;
941
+ margin: 1px 0 -1px 2px;
942
+ padding: 0 5px;
943
+ min-width: 18px;
944
+ height: 18px;
945
+ border-radius: 9px;
946
+ background-color: #d63638;
947
+ color: #fff;
948
+ font-size: 11px;
949
+ line-height: 1.6;
950
+ text-align: center;
951
+ z-index: 26;
952
+ vertical-align: text-bottom;
953
  }
954
 
955
+ .scanner-preview {
956
+ filter: blur(2px);
957
+ max-width: 100%;
958
+ }
959
+
960
+ .wpfssl-pro-dialog .ui-dialog-titlebar {
961
+ display: none;
962
+ }
963
+
964
+ .wpfssl-pro-dialog .logo img {
965
+ max-height: 55px;
966
+ }
967
+
968
+ .wpfssl-pro-dialog .logo {
969
+ text-align: center;
970
+ background: #f8f8f8;
971
+ margin: -16px -16px 0 -16px;
972
+ padding: 15px;
973
+ }
974
+
975
+ .wpfssl-pro-dialog .footer {
976
+ text-align: center;
977
+ background: #f8f8f8;
978
+ margin: 0 -16px -16px -16px;
979
+ padding: 15px;
980
+ }
981
+
982
+ .wpfssl-pro-dialog .logo span {
983
+ display: block;
984
+ font-size: 18px;
985
+ margin: 10px;
986
+ }
987
+
988
+ .wpfssl-pro-dialog .logo span b {
989
+ border-bottom: 3px solid #42982e;
990
+ }
991
+
992
+ #wpfssl-pro-table {
993
+ width: 100%;
994
+ margin: 10px auto 0 auto;
995
+ border-collapse: collapse;
996
+ }
997
+
998
+ #wpfssl-pro-table td {
999
+ padding: 4px 10px 4px 34px;
1000
+ border: none;
1001
  font-size: 14px;
 
 
 
1002
  }
1003
 
1004
+ #wpfssl-pro-table tr:last-child td {
1005
+ text-align: center;
1006
+ }
1007
+
1008
+ #wpfssl-pro-table .dashicons-yes {
1009
+ color: #42982e;
1010
+ }
1011
+
1012
+ #wpfssl-pro-table .dashicons {
1013
+ padding-right: 8px;
1014
+ margin-left: -27px;
1015
+ }
1016
+
1017
+ .center {
1018
+ text-align: center;
1019
  }
1020
 
1021
+ .prices del {
1022
+ color: #00000099;
 
 
1023
  }
1024
 
1025
+ .prices span {
1026
+ font-weight: 700;
1027
+ font-size: 40px;
1028
+ color: #42982e;
1029
+ line-height: 1;
1030
  display: inline-block;
1031
+ padding-bottom: 15px;
 
 
 
 
 
 
 
 
 
 
1032
  }
1033
 
1034
+ #wpfssl-pro-table tr:first-child td {
1035
+ color: #000;
1036
+ font-size: 18px;
1037
+ font-weight: 800 !important;
1038
+ padding: 10px 0;
1039
+ text-align: center;
1040
  }
1041
 
1042
+ .pro-ad-box p b {
1043
+ border-bottom: 3px solid #42982e;
1044
  }
1045
 
1046
+ .pro-ad-box img {
1047
+ max-height: 50px;
1048
+ padding: 0 0 10px 0;
1049
+ }
1050
+
1051
+ #wpfssl-pro-table tr:last-child td {
1052
+ padding: 20px 0 20px 0;
1053
+ vertical-align: top;
1054
+ }
1055
+
1056
+ #wpfssl-pro-table tr:last-child td span {
1057
+ display: block;
1058
+ padding: 0 0 5px 0;
1059
+ }
1060
+
1061
+ #wpfssl-features {
1062
+ width: 100%;
1063
+ padding: 20px 0 0 0;
1064
+ }
1065
+
1066
+ #wpfssl-features td {
1067
+ padding: 10px 20px;
1068
+ }
1069
+
1070
+ a.button.button-buy {
1071
+ padding: 11px 40px;
1072
+ color: white;
1073
+ background: #42982e;
1074
+ font-weight: 600;
1075
+ border: none;
1076
+ line-height: 1.5;
1077
+ height: auto;
1078
+ margin-bottom: 10px;
1079
+ }
1080
+
1081
+ a.button.button-buy:hover,
1082
+ a.button.button-buy:active,
1083
+ a.button.button-buy:focus {
1084
+ box-shadow: 0px 0px 10px 0px rgb(50 138 210 / 52%);
1085
+ background: #42982e;
1086
+ color: white;
1087
+ border: none;
1088
  }
1089
 
1090
+ .wp-dialog.ui-widget-content {
1091
+ background: #fff !important;
1092
+ }
1093
+
1094
+ #wpfssl-pro-dialog {
1095
+ overflow: hidden;
1096
+ }
1097
+
1098
+ .pro-feature {
1099
+ vertical-align: super;
1100
+ color: #42982e;
1101
+ font-weight: 600;
1102
+ font-size: 12px;
1103
+ margin-left: 4px;
1104
+ font-style: italic;
1105
  }
img/content-scanner.jpg ADDED
Binary file
img/loading-icon.png DELETED
Binary file
img/wp-force-ssl-icon.png ADDED
Binary file
img/wp-force-ssl-logo.png ADDED
Binary file
img/wp-ssl.png ADDED
Binary file
inc/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ //Silence is golden.
inc/wp-force-ssl-status-tests.php ADDED
@@ -0,0 +1,686 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WP Force SSL
4
+ * https://wpforcessl.com/
5
+ * (c) WebFactory Ltd, 2019 - 2022
6
+ */
7
+
8
+ // include only file
9
+ if (!defined('ABSPATH')) {
10
+ die('Do not open this file directly.');
11
+ }
12
+
13
+ class wpForceSSL_status_tests
14
+ {
15
+ var $tests_cache_hours = 12;
16
+ var $ssl_status_cache_hours = 24;
17
+ var $ssl_expiry_days_limit = 26;
18
+
19
+ function get_tests()
20
+ {
21
+ $tests = array();
22
+
23
+ $tests['localhost'] = array(
24
+ 'callback' => 'localhost',
25
+ 'description' => '',
26
+ 'output' => array(
27
+ 'pass' => array(
28
+ 'title' => 'The site is publicly available (not on a localhost)',
29
+ 'description' => 'In order to issue a properly signed SSL certificate the site needs to be publicly available.',
30
+ ),
31
+ 'warning' => array(
32
+ 'title' => 'The site is NOT publicly available. It\'s on a localhost.',
33
+ 'description' => 'There is nothing wrong with running a site on localhost. However, some WP Force SSL functions are not available for localhost. It\'s also not possible to issue SSL certificates for localhosts except self-signed ones.'
34
+ ),
35
+ )
36
+ );
37
+
38
+ $tests['checkssl'] = array(
39
+ 'callback' => 'checkssl',
40
+ 'description' => '',
41
+ 'output' => array(
42
+ 'pass' => array(
43
+ 'title' => 'Your SSL certificate is valid',
44
+ 'description' => 'Having a valid certificate is the first and most important step to having a secure site.',
45
+ ),
46
+ 'fail' => array(
47
+ 'title' => 'Your SSL certificate is NOT valid',
48
+ 'description' => 'While testing your SSL certificate the following error occurred: %1$s'
49
+ ),
50
+ )
51
+ );
52
+
53
+ $tests['pluginver'] = array(
54
+ 'callback' => 'pluginver',
55
+ 'description' => '',
56
+ 'output' => array(
57
+ 'pass' => array(
58
+ 'title' => 'You\'re using the latest version of WP Force SSL',
59
+ 'description' => 'Using the latest version of any plugin ensures you have the newest features and bug fixes.'
60
+ ),
61
+ 'fail' => array(
62
+ 'title' => 'You\'re NOT using the latest version of WP Force SSL',
63
+ 'description' => 'Please <a href="' . admin_url('update-core.php') . '">update</a> to the latest version to enjoy the benefits of new features and bug fixes.'
64
+ ),
65
+ )
66
+ );
67
+
68
+ $tests['conflictingplugins'] = array(
69
+ 'callback' => 'conflictingplugins',
70
+ 'description' => '',
71
+ 'output' => array(
72
+ 'pass' => array(
73
+ 'title' => 'You\'re not using any plugins that conflict with WP Force SSL',
74
+ 'description' => 'It\'s always a good idea to use only one plugin to solve a problem. Not multiple ones that will cause conflicts.'
75
+ ),
76
+ 'fail' => array(
77
+ 'title' => 'You\'re using %1$s plugin(s) that conflict with WP Force SSL',
78
+ 'description' => 'Please <a href="' . admin_url('plugins.php?plugin_status=active') . '">disable</a> the following plugin(s) to ensure there are no conflicts: %2$s.'
79
+ ),
80
+ )
81
+ );
82
+
83
+ $tests['wpurl'] = array(
84
+ 'callback' => 'wpurl',
85
+ 'description' => '',
86
+ 'output' => array(
87
+ 'pass' => array(
88
+ 'title' => 'WordPress address URL is properly configured for HTTPS',
89
+ 'description' => 'Prefix for the WordPress address URL should be <i>https://</i>'
90
+ ),
91
+ 'fail' => array(
92
+ 'title' => 'WordPress address URL is NOT properly configured',
93
+ 'description' => 'WordPress address URL is configured with HTTP instead of HTTPS. Please change the URL in <a href="' . admin_url('options-general.php') . '">Settings - General</a>.'
94
+ ),
95
+ )
96
+ );
97
+
98
+ $tests['url'] = array(
99
+ 'callback' => 'url',
100
+ 'description' => '',
101
+ 'output' => array(
102
+ 'pass' => array(
103
+ 'title' => 'Site address URL is properly configured for HTTPS',
104
+ 'description' => 'Prefix for the site address URL should be <i>https://</i>'
105
+ ),
106
+ 'fail' => array(
107
+ 'title' => 'Site address URL is NOT properly configured',
108
+ 'description' => 'Site address URL is configured with HTTP instead of HTTPS. Please change the URL in <a href="' . admin_url('options-general.php') . '">Settings - General</a>.'
109
+ ),
110
+ )
111
+ );
112
+
113
+ $tests['sslexpiry'] = array(
114
+ 'callback' => 'sslexpiry',
115
+ 'description' => '',
116
+ 'output' => array(
117
+ 'pass' => array(
118
+ 'title' => 'Your SSL certificate will expire in %1$s days. No need to renew it yet.',
119
+ 'description' => 'Having a valid certificate is the first and most important step to having a secure site.',
120
+ ),
121
+ 'warning' => array(
122
+ 'title' => 'Your SSL certificate will expire in %1$s days. Renew it as soon as possible.',
123
+ 'description' => 'It\'s not smart to renew the certificate at the last minute. We recommend renewing it at least 15 days before it expires.',
124
+ ),
125
+ 'fail' => array(
126
+ 'title' => '%1$s',
127
+ 'description' => 'Check your certificate manually immediately.',
128
+ ),
129
+ )
130
+ );
131
+
132
+ $tests['sslmonitoring'] = array(
133
+ 'callback' => 'sslmonitoring',
134
+ 'description' => '',
135
+ 'output' => array(
136
+ 'warning' => array(
137
+ 'title' => 'Realtime SSL monitoring is disabled',
138
+ 'description' => 'Real-time site and SSL certificate monitoring is a <a href="#" data-pro-feature="status-sslmonitoring-1" class="open-pro-dialog">PRO</a> feature that will help you and your clients sleep better. It monitors over 20 common errors related to SSL that can happen at any time. Forgot to renew your certificate? No problem, you\'ll get notified on time.<br><a href="#" data-pro-feature="status-sslmonitoring-2" class="open-pro-dialog">Enable real-time SSL monitoring</a>'
139
+ ),
140
+ )
141
+ );
142
+
143
+ $tests['httpsredirectwp'] = array(
144
+ 'callback' => 'httpsredirectwp',
145
+ 'description' => '',
146
+ 'output' => array(
147
+ 'pass' => array(
148
+ 'title' => 'WordPress URLs\' are properly redirected from HTTP to HTTPS',
149
+ 'description' => 'URLs like <code>http://site.com/page/</code> are automatically redirected to <code>https://site.com/test/</code>.',
150
+ ),
151
+ 'fail' => array(
152
+ 'title' => 'WordPress URLs\' are NOT properly redirected from HTTP to HTTPS',
153
+ 'description' => 'While testing the redirect the following error occurred: %1$s'
154
+ ),
155
+ )
156
+ );
157
+
158
+ $tests['httpsredirectfile'] = array(
159
+ 'callback' => 'httpsredirectfile',
160
+ 'description' => '',
161
+ 'output' => array(
162
+ 'warning' => array(
163
+ 'title' => 'Non-WordPress URLs\' may not be properly redirected from HTTP to HTTPS',
164
+ 'description' => 'Redirecting non-WP URLs requires a special <code>.htaccess</code> rule to be in place and is a <a href="#" data-pro-feature="status-httpsredirectfile-1" class="open-pro-dialog">PRO</a> feature. If you have files outside WP such as PDFs or images, and you can\'t modify links to them to be HTTPS, then you need this feature.<br><a href="#" data-pro-feature="status-httpsredirectfile-2" class="open-pro-dialog">Enable redirecting for non-WP URLs</a>'
165
+ ),
166
+ )
167
+ );
168
+
169
+ $tests['hsts'] = array(
170
+ 'callback' => 'hsts',
171
+ 'description' => '',
172
+ 'output' => array(
173
+ 'pass' => array(
174
+ 'title' => 'HTTP Strict Transport Security (HSTS) is enabled',
175
+ 'description' => 'HSTS is a policy mechanism that helps protect websites against man-in-the-middle attacks such as protocol downgrade attacks and cookie hijacking. It allows web servers to declare that web browsers should automatically interact with it using only HTTPS connections.',
176
+ ),
177
+ 'fail' => array(
178
+ 'title' => 'HTTP Strict Transport Security (HSTS) is NOT enabled',
179
+ 'description' => 'HSTS is a policy mechanism that helps protect websites against man-in-the-middle attacks such as protocol downgrade attacks and cookie hijacking. It allows web servers to declare that web browsers should automatically interact with it using only HTTPS connections. <a href="#" class="change-tab" data-tab="1">Enable HSTS</a> in Settings.',
180
+ ),
181
+ )
182
+ );
183
+
184
+ $tests['contentscanner'] = array(
185
+ 'callback' => 'contentscanner',
186
+ 'description' => '',
187
+ 'output' => array(
188
+ 'warning' => array(
189
+ 'title' => 'Content scanner was never run, mixed-content issues might be present',
190
+ 'description' => 'Content scanner is a <a href="#" data-pro-feature="status-contentscanner-1" class="open-pro-dialog">PRO</a> feature powered by our SaaS that ensures your site doesn\'t have any mixed content issues. It scans every page, post and custom post type and checks every link, image, CSS and JS file to verify everything is loaded via HTTPS. What it does in minutes is impossible to do manually.<br><a href="#" data-pro-feature="status-contentscanner-2" class="open-pro-dialog">Scan your content for mixed-content issues</a>'
191
+ ),
192
+ )
193
+ );
194
+
195
+ $tests['htaccess'] = array(
196
+ 'callback' => 'htaccess',
197
+ 'description' => '',
198
+ 'output' => array(
199
+ 'pass' => array(
200
+ 'title' => 'Your server uses .htaccess and it\'s writable',
201
+ 'description' => 'If needed the plugin will add redirect rules to the <code>.htaccess</code> file.',
202
+ ),
203
+ 'warning' => array(
204
+ 'title' => 'Your server uses .htaccess but it\'s NOT writable',
205
+ 'description' => 'This is not a problem and it\'s a good idea to have <code>.htaccess</code> write-protected. However, the plugin won\'t be able to automatically add redirect rules to it.',
206
+ ),
207
+ 'fail' => array(
208
+ 'title' => 'Your server doesn\'t use htaccess',
209
+ 'description' => 'There\'s nothing wrong with running a server setup that does\'t use <code>.htaccess</code>. However, the plugin won\'t be able to add redirect rules which might be required.',
210
+ ),
211
+ )
212
+ );
213
+
214
+ $tests['404home'] = array(
215
+ 'callback' => '404home',
216
+ 'description' => '',
217
+ 'output' => array(
218
+ 'warning' => array(
219
+ 'title' => 'Could not test if your 404 errors are redirected to the home page',
220
+ 'description' => 'This is a <a href="#" data-pro-feature="status-404home-1" class="open-pro-dialog">PRO</a> feature that checks if your 404 errors (pages) are redirected to the home page. It is not recommended by search engines to redirect all 404 pages to a single page. Instead, a 404 response code should be returned.<br><a href="#" data-pro-feature="status-404home-2" class="open-pro-dialog">Check 404 errors redirect</a>'
221
+ ),
222
+ )
223
+ );
224
+
225
+ return $tests;
226
+ } // get_tests
227
+
228
+
229
+ private function process_tests()
230
+ {
231
+ $results = array();
232
+
233
+ wpForceSSL_Utility::clear_3rd_party_cache();
234
+
235
+ $tests = $this->get_tests();
236
+
237
+ foreach ($tests as $test_name => $test_details) {
238
+ if ($test_name[0] == '_') {
239
+ continue;
240
+ }
241
+
242
+ $result = call_user_func(array($this, 'test_' . $test_details['callback']));
243
+ if (is_bool($result)) {
244
+ if ($result === true) {
245
+ $result = array('status' => 'pass', 'data' => array());
246
+ } else {
247
+ $result = array('status' => 'fail', 'data' => array());
248
+ }
249
+ }
250
+ if (!isset($result['data'])) {
251
+ $result['data'] = array();
252
+ }
253
+ if (isset($result['data']) && !is_array($result['data'])) {
254
+ $result['data'] = array($result['data']);
255
+ }
256
+
257
+ $result['status'] = strtolower($result['status']);
258
+ if ($result['status'] != 'pass' && $result['status'] != 'warning' && $result['status'] != 'fail') {
259
+ user_error('Unknown test status result (' . esc_attr($result['status']) . ') for ' . esc_attr($test_name), E_USER_ERROR);
260
+ die();
261
+ }
262
+
263
+ $tmp = $test_details['output'][$result['status']];
264
+ $tmp = array_merge(array('title' => '', 'description' => ''), $tmp);
265
+
266
+ $results[] = array(
267
+ 'test' => $test_name,
268
+ 'status' => $result['status'],
269
+ 'title' => $this->sprintfn($tmp['title'], $result['data']),
270
+ 'description' => $this->sprintfn($tmp['description'], $result['data']),
271
+ );
272
+ } // foreach $tests
273
+
274
+ usort($results, function ($a, $b) {
275
+ $values = array('pass' => 1, 'warning' => 2, 'fail' => 3);
276
+
277
+ if ($values[$a['status']] == $values[$b['status']]) {
278
+ return 0;
279
+ }
280
+ return ($values[$a['status']] < $values[$b['status']]) ? 1 : -1;
281
+ });
282
+
283
+ set_transient('wpssl_tests_results', $results, $this->tests_cache_hours * HOUR_IN_SECONDS);
284
+ return $results;
285
+ } // process_tests
286
+
287
+
288
+ function count_statuses()
289
+ {
290
+ $out = array('pass' => 0, 'warning' => 0, 'fail' => 0);
291
+ $results = $this->get_tests_results();
292
+
293
+ foreach ($results as $result) {
294
+ $out[$result['status']]++;
295
+ } // foreach $results
296
+
297
+ return $out;
298
+ } // count_statuses
299
+
300
+
301
+ /**
302
+ * Version of sprintf with named arguments
303
+ *
304
+ * with sprintf: sprintf('second: %2$s ; first: %1$s', '1st', '2nd');
305
+ *
306
+ * with sprintfn: sprintfn('second: %second$s ; first: %first$s', array(
307
+ * 'first' => '1st',
308
+ * 'second'=> '2nd'
309
+ * ));
310
+ *
311
+ * @param string $format sprintf format string, with any number of named arguments
312
+ * @param array $args array of [ 'arg_name' => 'arg value', ... ] replacements to be made
313
+ * @return string|false result of sprintf call, or bool false on error
314
+ */
315
+ function sprintfn($format, array $args = array())
316
+ {
317
+ // map of argument names to their corresponding sprintf numeric argument value
318
+ $arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);
319
+
320
+ // find the next named argument. each search starts at the end of the previous replacement.
321
+ for ($pos = 0; preg_match('/(?<=%)([a-zA-Z_]\w*)(?=\$)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
322
+ $arg_pos = $match[0][1];
323
+ $arg_len = strlen($match[0][0]);
324
+ $arg_key = $match[1][0];
325
+
326
+ // no value named argument
327
+ if (!array_key_exists($arg_key, $arg_nums)) {
328
+ user_error("sprintfn(): Missing argument '" . esc_attr($arg_key) . "'", E_USER_WARNING);
329
+ return false;
330
+ }
331
+
332
+ // replace the named argument with the corresponding numeric one
333
+ $format = substr_replace($format, $replace = $arg_nums[$arg_key], $arg_pos, $arg_len);
334
+ $pos = $arg_pos + strlen($replace); // skip to end of replacement for next iteration
335
+ }
336
+
337
+ return vsprintf($format, array_values($args));
338
+ } // sprintfn
339
+
340
+
341
+ function get_tests_results($skip_cache = false)
342
+ {
343
+ if ($skip_cache || !($results = get_transient('wpssl_tests_results'))) {
344
+ $results = $this->process_tests();
345
+ }
346
+
347
+ return $results;
348
+ } // get_tests_results
349
+
350
+ function is_localhost()
351
+ {
352
+ if (
353
+ substr($_SERVER['SERVER_ADDR'], 0, 6) == '127.0.'
354
+ || substr($_SERVER['SERVER_ADDR'], 0, 8) == '192.168.'
355
+ || @$_SERVER['HTTP_HOST'] == 'localhost'
356
+ || $_SERVER['SERVER_ADDR'] == '::1'
357
+ ) {
358
+ return true;
359
+ }
360
+
361
+ $ssl_status = $this->get_ssl_status(false);
362
+ if ($ssl_status['error']) {
363
+ if (stripos($ssl_status['data'], 'unable to retrieve') !== false || stripos($ssl_status['data'], 'unable to resolve') !== false) {
364
+ return true;
365
+ }
366
+ }
367
+
368
+ return false;
369
+ } // is_localhost
370
+
371
+ function get_ssl_status($skip_cache = false)
372
+ {
373
+ if ($skip_cache || !($status = get_transient('wpfs_ssl_status'))) {
374
+ $domain = get_bloginfo('url');
375
+
376
+ $result = array('error' => true, 'data' => '', 'domain' => '');
377
+
378
+ if (strpos($domain, ':') !== false) {
379
+ $domain = parse_url($domain, PHP_URL_HOST);
380
+ }
381
+
382
+ if (empty($domain)) {
383
+ $result = array('error' => true, 'domain' => $domain, 'data' => 'Invalid domain name.');
384
+ }
385
+
386
+ if (gethostbyname($domain) == $domain) {
387
+ $result = array('error' => true, 'domain' => $domain, 'data' => 'Unable to resolve domain name.');
388
+ }
389
+
390
+ $response = $this->do_request('https://' . $domain);
391
+ if (!$response || !is_array($response)) {
392
+ $result = array('domain' => $domain, 'error' => true, 'data' => 'Unable to test SSL certificate. Assume it\'s NOT valid.');
393
+ } elseif (!empty($response['error'])) {
394
+ $err = $response['error'];
395
+ $err = trim(substr($err, strpos($err, ':') + 1));
396
+ $err = trim(str_replace(array('SSL:', 'SSL certificate problem:'), '', $err));
397
+
398
+ $result = array('domain' => $domain, 'error' => true, 'data' => $err);
399
+ } elseif ($response['code'] == 200) {
400
+ $g = stream_context_create(['ssl' => ['capture_peer_cert' => true]]);
401
+ $r = stream_socket_client("ssl://{$domain}:443", $errno, $errstr, 10, STREAM_CLIENT_CONNECT, $g);
402
+ if (!$r) {
403
+ $result = array('domain' => $domain, 'error' => true, 'data' => 'Unknown error while fetching SSL certificate. Assuming it\'s NOT valid.');
404
+ } else {
405
+ $cont = stream_context_get_params($r);
406
+ $tmp = openssl_x509_parse($cont['options']['ssl']['peer_certificate']);
407
+ $data = array();
408
+
409
+ $data['valid_from'] = date('Y-m-d', (int) $tmp['validFrom_time_t']);
410
+ $data['valid_to'] = date('Y-m-d', (int) $tmp['validTo_time_t']);
411
+ $data['issuer'] = implode(', ', array_reverse($tmp['issuer']));
412
+ $data['issued_to'] = implode(', ', array_reverse($tmp['subject']));
413
+
414
+ $d = str_ireplace('dns:', '', $tmp['extensions']['subjectAltName']);
415
+ $d = explode(',', $d);
416
+ $d = array_map('trim', $d);
417
+
418
+ $data['issued_to_hosts'] = $d;
419
+
420
+ $result = array('domain' => $domain, 'error' => false, 'data' => $data);
421
+ }
422
+ } else {
423
+ $result = array('domain' => $domain, 'error' => true, 'data' => 'A valid SSL certificate was NOT found.');
424
+ }
425
+
426
+ $status = array('error' => $result['error'], 'data' => $result['data']);
427
+ set_transient('wpfs_ssl_status', $status, $this->ssl_status_cache_hours * HOUR_IN_SECONDS);
428
+ }
429
+
430
+ return $status;
431
+ } // get_ssl_status
432
+
433
+ function do_request($url)
434
+ {
435
+ $args = array(
436
+ 'timeout' => 10,
437
+ 'httpversion' => '1.1',
438
+ 'sslverify' => true
439
+ );
440
+
441
+ $response = wp_remote_get($url, $args);
442
+
443
+ $error = '';
444
+ if (is_wp_error($response)) {
445
+ $error = $response->get_error_message();
446
+ }
447
+
448
+ $out = array(
449
+ 'code' => wp_remote_retrieve_response_code($response),
450
+ 'body' => wp_remote_retrieve_body($response),
451
+ 'error' => $error
452
+ );
453
+
454
+ return $out;
455
+ } // make_request
456
+
457
+ function test_rand()
458
+ {
459
+ $rand = rand(0, 100);
460
+
461
+ if ($rand > 66) {
462
+ return array('status' => 'pass', 'data' => $rand);
463
+ } elseif ($rand > 33) {
464
+ return array('status' => 'warning', 'data' => $rand);
465
+ } else {
466
+ return array('status' => 'fail', 'data' => $rand);
467
+ }
468
+ } // test_rand
469
+
470
+
471
+ function test_wpurl()
472
+ {
473
+ $tmp = get_bloginfo('wpurl');
474
+ if (stripos($tmp, 'https://') === 0) {
475
+ return true;
476
+ } else {
477
+ return false;
478
+ }
479
+ } // test_wpurl
480
+
481
+
482
+ function test_url()
483
+ {
484
+ $tmp = get_bloginfo('url');
485
+ if (stripos($tmp, 'https://') === 0) {
486
+ return true;
487
+ } else {
488
+ return false;
489
+ }
490
+ } // test_url
491
+
492
+
493
+ function test_checkssl()
494
+ {
495
+ $ssl_status = $this->get_ssl_status();
496
+ if ($ssl_status['error']) {
497
+ return array('status' => 'fail', 'data' => $ssl_status['data']);
498
+ } else {
499
+ return true;
500
+ }
501
+ } // test_checkssl
502
+
503
+
504
+ function test_localhost()
505
+ {
506
+ if ($this->is_localhost()) {
507
+ return array('status' => 'warning', 'data' => '');
508
+ } else {
509
+ return true;
510
+ }
511
+ } // test_localhost
512
+
513
+
514
+ function test_pluginver()
515
+ {
516
+ global $wpfs;
517
+ $updates = get_site_transient('update_plugins');
518
+
519
+ if (isset($updates->response['wp-force-ssl/wp-force-ssl.php']) && version_compare($wpfs->version, $updates->response['wp-force-ssl/wp-force-ssl.php']->new_version, '<')) {
520
+ return false;
521
+ } else {
522
+ return true;
523
+ }
524
+ } // test_pluginver
525
+
526
+ function test_conflictingplugins()
527
+ {
528
+ $plugins = array();
529
+
530
+ if (defined('WPLE_BASE')) {
531
+ $plugins[] = 'WP Encryption';
532
+ }
533
+ if (defined('WPSSL_VER')) {
534
+ $plugins[] = 'WP Free SSL';
535
+ }
536
+ if (defined('SSL_ZEN_PLUGIN_VERSION')) {
537
+ $plugins[] = 'SSL Zen';
538
+ }
539
+ if (defined('WPSSL_VER')) {
540
+ $plugins[] = 'WP Free SSL';
541
+ }
542
+ if (defined('SSLFIX_PLUGIN_VERSION')) {
543
+ $plugins[] = 'SSL Insecure Content Fixer';
544
+ }
545
+ if (class_exists('OCSSL', false)) {
546
+ $plugins[] = 'One Click SSL';
547
+ }
548
+ if (class_exists('JSM_Force_SSL', false)) {
549
+ $plugins[] = 'JSM\'s Force HTTP to HTTPS (SSL)';
550
+ }
551
+ if (function_exists('httpsrdrctn_plugin_init')) {
552
+ $plugins[] = 'Easy HTTPS (SSL) Redirection';
553
+ }
554
+ if (defined('WPSSL_VER')) {
555
+ $plugins[] = 'WP Free SSL';
556
+ }
557
+ if (class_exists('REALLY_SIMPLE_SSL')) {
558
+ $plugins[] = 'Really Simple SSL';
559
+ }
560
+ if (defined('ESSL_REQUIRED_PHP_VERSION')) {
561
+ $plugins[] = 'EasySSL';
562
+ }
563
+ if (class_exists('ICWP_Cloudflare_Flexible_SSL')) {
564
+ $plugins[] = 'Flexible SSL for CloudFlare';
565
+ }
566
+
567
+ if ($plugins) {
568
+ return array('status' => 'fail', 'data' => array(sizeof($plugins), implode(', ', $plugins)));
569
+ } else {
570
+ return true;
571
+ }
572
+ } // test_conflictingplugins
573
+
574
+
575
+ function test_sslexpiry()
576
+ {
577
+ $ssl_status = $this->get_ssl_status();
578
+
579
+ if ($ssl_status['error']) {
580
+ return array('status' => 'fail', 'data' => 'Unable to test your SSL certificate\'s expiry date');
581
+ } else {
582
+ $days_valid = round((strtotime($ssl_status['data']['valid_to']) - time()) / DAY_IN_SECONDS);
583
+ if ($days_valid <= 1) {
584
+ return array('status' => 'fail', 'data' => 'Your SSL certificate has expired! Please renew it immediately.');
585
+ } elseif ($days_valid <= $this->ssl_expiry_days_limit) {
586
+ return array('status' => 'warning', 'data' => $days_valid);
587
+ } else {
588
+ return array('status' => 'pass', 'data' => $days_valid);
589
+ }
590
+ }
591
+ } // test_sslexpiry
592
+
593
+
594
+ function test_sslmonitoring()
595
+ {
596
+ return array('status' => 'warning', 'data' => '');
597
+ } // test_sslmonitoring
598
+
599
+
600
+ function test_httpsredirectwp()
601
+ {
602
+ $query = new WP_Query(array('orderby' => 'rand', 'post_status' => 'publish', 'posts_per_page' => '1'));
603
+ if (!$query->posts) {
604
+ $query = new WP_Query(array('orderby' => 'rand', 'post_type' => 'page', 'post_status' => 'publish', 'posts_per_page' => '1'));
605
+ }
606
+ $query->the_post();
607
+ $url = get_the_permalink();
608
+ wp_reset_postdata();
609
+
610
+ if (!$url) {
611
+ $url = get_bloginfo('url');
612
+ }
613
+ $url = str_replace('https://', 'http://', $url);
614
+
615
+ $ch = curl_init($url);
616
+ curl_setopt($ch, CURLOPT_NOBODY, 1);
617
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
618
+ curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
619
+ curl_setopt($ch, CURLOPT_FAILONERROR, true);
620
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
621
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
622
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
623
+
624
+ curl_exec($ch);
625
+
626
+ if (curl_errno($ch)) {
627
+ $error_msg = curl_error($ch);
628
+ return array('status' => 'fail', 'data' => $error_msg);
629
+ }
630
+ $target = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
631
+ curl_close($ch);
632
+
633
+ if (substr($target, 0, 8) == 'https://') {
634
+ return true;
635
+ } else {
636
+ return array('status' => 'fail', 'data' => 'URL was not redirected to an HTTPS URL. ' . $url . ' -&gt; ' . $target);
637
+ }
638
+ } // test_httpsredirectwp
639
+
640
+
641
+ function test_httpsredirectfile()
642
+ {
643
+ return array('status' => 'warning', 'data' => '');
644
+ } // test_httpsredirectfile
645
+
646
+
647
+ function test_hsts()
648
+ {
649
+ global $wpfs;
650
+ if ($wpfs->options['wpfs_hsts'] == 'yes') {
651
+ return true;
652
+ } else {
653
+ return false;
654
+ }
655
+ } // test_hsts
656
+
657
+ function test_contentscanner()
658
+ {
659
+ return array('status' => 'warning', 'data' => '');
660
+ } // test_contentscanner
661
+
662
+
663
+ function test_htaccess()
664
+ {
665
+ $server = strtolower(filter_var($_SERVER['SERVER_SOFTWARE'], FILTER_SANITIZE_STRING));
666
+
667
+ if (stripos($server, 'apache') === false && stripos($server, 'litespeed') === false) {
668
+ return false;
669
+ }
670
+
671
+ if (!is_writable(get_home_path() . '.htaccess')) {
672
+ return array('status' => 'warning');
673
+ }
674
+
675
+ return true;
676
+ } // test_htaccess
677
+
678
+
679
+ function test_404home()
680
+ {
681
+ return array('status' => 'warning', 'data' => '');
682
+ } // test_404home
683
+ } // class wpForceSSL_status_tests
684
+
685
+ global $wp_force_ssl_tests;
686
+ $wp_force_ssl_tests = new wpForceSSL_status_tests();
inc/wp-force-ssl-utility.php ADDED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * WP Force SSL
4
+ * Utility & Helper functions
5
+ * (c) WebFactory Ltd, 2019 - 2022
6
+ */
7
+
8
+ // include only file
9
+ if (!defined('ABSPATH')) {
10
+ die('Do not open this file directly.');
11
+ }
12
+
13
+ class wpForceSSL_Utility
14
+ {
15
+ /**
16
+ * Creates a fancy, iOS alike toggle switch
17
+ *
18
+ * @param string $name ID used for checkbox.
19
+ * @param array $options Various options: value, saved_value, option_key, class
20
+ * @param boolean $echo Default: true.
21
+ * @return void
22
+ */
23
+ static function create_toogle_switch($name, $options = array(), $echo = true)
24
+ {
25
+ $default_options = array('value' => '1', 'saved_value' => '', 'option_key' => $name, 'class' => '');
26
+ $options = array_merge($default_options, $options);
27
+
28
+ $extra = '';
29
+ if (strpos($options['class'], 'open-pro-dialog') !== false) {
30
+ $extra = 'data-pro-feature="' . $name . '" ';
31
+ }
32
+
33
+ $out = '<label ' . $extra . 'for="' . $name . '" class="wfssl-switch tooltip ' . $options['class'] . '">';
34
+ $out .= '<input type="checkbox" id="' . $name . '" ' . self::checked($options['value'], $options['saved_value']) . ' type="checkbox" value="' . $options['value'] . '" name="' . $options['option_key'] . '">';
35
+ $out .= '<span class="wfssl-slider wfssl-round"></span>';
36
+ $out .= '</label>';
37
+
38
+ if ($echo) {
39
+ wpForceSSL_Utility::wp_kses_wf($out);
40
+ } else {
41
+ return $out;
42
+ }
43
+ } // create_toggle_switch
44
+
45
+
46
+ /**
47
+ * Helper for creating checkboxes.
48
+ *
49
+ * @param string $value Checkbox value, in HTML.
50
+ * @param array $current Current, saved value of checkbox.
51
+ * @param boolean $echo Default: false.
52
+ *
53
+ * @return void|string
54
+ */
55
+ static function checked($value, $current, $echo = false)
56
+ {
57
+ $out = '';
58
+
59
+ if (!is_array($current)) {
60
+ $current = (array) $current;
61
+ }
62
+
63
+ if (in_array($value, $current)) {
64
+ $out = ' checked="checked" ';
65
+ }
66
+
67
+ if ($echo) {
68
+ wpForceSSL_Utility::wp_kses_wf($out);
69
+ } else {
70
+ return $out;
71
+ }
72
+ } // checked
73
+
74
+ static function wp_kses_wf($html)
75
+ {
76
+ add_filter('safe_style_css', function ($styles) {
77
+ $styles_wf = array(
78
+ 'text-align',
79
+ 'margin',
80
+ 'color',
81
+ 'float',
82
+ 'border',
83
+ 'background',
84
+ 'background-color',
85
+ 'border-bottom',
86
+ 'border-bottom-color',
87
+ 'border-bottom-style',
88
+ 'border-bottom-width',
89
+ 'border-collapse',
90
+ 'border-color',
91
+ 'border-left',
92
+ 'border-left-color',
93
+ 'border-left-style',
94
+ 'border-left-width',
95
+ 'border-right',
96
+ 'border-right-color',
97
+ 'border-right-style',
98
+ 'border-right-width',
99
+ 'border-spacing',
100
+ 'border-style',
101
+ 'border-top',
102
+ 'border-top-color',
103
+ 'border-top-style',
104
+ 'border-top-width',
105
+ 'border-width',
106
+ 'caption-side',
107
+ 'clear',
108
+ 'cursor',
109
+ 'direction',
110
+ 'font',
111
+ 'font-family',
112
+ 'font-size',
113
+ 'font-style',
114
+ 'font-variant',
115
+ 'font-weight',
116
+ 'height',
117
+ 'letter-spacing',
118
+ 'line-height',
119
+ 'margin-bottom',
120
+ 'margin-left',
121
+ 'margin-right',
122
+ 'margin-top',
123
+ 'overflow',
124
+ 'padding',
125
+ 'padding-bottom',
126
+ 'padding-left',
127
+ 'padding-right',
128
+ 'padding-top',
129
+ 'text-decoration',
130
+ 'text-indent',
131
+ 'vertical-align',
132
+ 'width',
133
+ 'display',
134
+ );
135
+
136
+ foreach ($styles_wf as $style_wf) {
137
+ $styles[] = $style_wf;
138
+ }
139
+ return $styles;
140
+ });
141
+
142
+ $allowed_tags = wp_kses_allowed_html('post');
143
+ $allowed_tags['input'] = array(
144
+ 'type' => true,
145
+ 'style' => true,
146
+ 'class' => true,
147
+ 'id' => true,
148
+ 'checked' => true,
149
+ 'disabled' => true,
150
+ 'name' => true,
151
+ 'size' => true,
152
+ 'placeholder' => true,
153
+ 'value' => true,
154
+ 'data-*' => true,
155
+ 'size' => true,
156
+ 'disabled' => true
157
+ );
158
+
159
+ $allowed_tags['textarea'] = array(
160
+ 'type' => true,
161
+ 'style' => true,
162
+ 'class' => true,
163
+ 'id' => true,
164
+ 'checked' => true,
165
+ 'disabled' => true,
166
+ 'name' => true,
167
+ 'size' => true,
168
+ 'placeholder' => true,
169
+ 'value' => true,
170
+ 'data-*' => true,
171
+ 'cols' => true,
172
+ 'rows' => true,
173
+ 'disabled' => true
174
+ );
175
+
176
+ $allowed_tags['select'] = array(
177
+ 'type' => true,
178
+ 'style' => true,
179
+ 'class' => true,
180
+ 'id' => true,
181
+ 'checked' => true,
182
+ 'disabled' => true,
183
+ 'name' => true,
184
+ 'size' => true,
185
+ 'placeholder' => true,
186
+ 'value' => true,
187
+ 'data-*' => true,
188
+ 'multiple' => true,
189
+ 'disabled' => true
190
+ );
191
+
192
+ $allowed_tags['option'] = array(
193
+ 'type' => true,
194
+ 'style' => true,
195
+ 'class' => true,
196
+ 'id' => true,
197
+ 'checked' => true,
198
+ 'disabled' => true,
199
+ 'name' => true,
200
+ 'size' => true,
201
+ 'placeholder' => true,
202
+ 'value' => true,
203
+ 'selected' => true,
204
+ 'data-*' => true
205
+ );
206
+ $allowed_tags['optgroup'] = array(
207
+ 'type' => true,
208
+ 'style' => true,
209
+ 'class' => true,
210
+ 'id' => true,
211
+ 'checked' => true,
212
+ 'disabled' => true,
213
+ 'name' => true,
214
+ 'size' => true,
215
+ 'placeholder' => true,
216
+ 'value' => true,
217
+ 'selected' => true,
218
+ 'data-*' => true,
219
+ 'label' => true
220
+ );
221
+
222
+ $allowed_tags['a'] = array(
223
+ 'href' => true,
224
+ 'data-*' => true,
225
+ 'class' => true,
226
+ 'style' => true,
227
+ 'id' => true,
228
+ 'target' => true,
229
+ 'data-*' => true,
230
+ 'role' => true,
231
+ 'aria-controls' => true,
232
+ 'aria-selected' => true,
233
+ 'disabled' => true
234
+ );
235
+
236
+ $allowed_tags['div'] = array(
237
+ 'style' => true,
238
+ 'class' => true,
239
+ 'id' => true,
240
+ 'data-*' => true,
241
+ 'role' => true,
242
+ 'aria-labelledby' => true,
243
+ 'value' => true,
244
+ 'aria-modal' => true,
245
+ 'tabindex' => true
246
+ );
247
+
248
+ $allowed_tags['li'] = array(
249
+ 'style' => true,
250
+ 'class' => true,
251
+ 'id' => true,
252
+ 'data-*' => true,
253
+ 'role' => true,
254
+ 'aria-labelledby' => true,
255
+ 'value' => true,
256
+ 'aria-modal' => true,
257
+ 'tabindex' => true
258
+ );
259
+
260
+ $allowed_tags['span'] = array(
261
+ 'style' => true,
262
+ 'class' => true,
263
+ 'id' => true,
264
+ 'data-*' => true,
265
+ 'aria-hidden' => true
266
+ );
267
+
268
+ $allowed_tags['style'] = array(
269
+ 'class' => true,
270
+ 'id' => true,
271
+ 'type' => true
272
+ );
273
+
274
+ $allowed_tags['form'] = array(
275
+ 'style' => true,
276
+ 'class' => true,
277
+ 'id' => true,
278
+ 'method' => true,
279
+ 'action' => true,
280
+ 'data-*' => true
281
+ );
282
+
283
+ echo wp_kses($html, $allowed_tags);
284
+
285
+ add_filter('safe_style_css', function ($styles) {
286
+ $styles_wf = array(
287
+ 'text-align',
288
+ 'margin',
289
+ 'color',
290
+ 'float',
291
+ 'border',
292
+ 'background',
293
+ 'background-color',
294
+ 'border-bottom',
295
+ 'border-bottom-color',
296
+ 'border-bottom-style',
297
+ 'border-bottom-width',
298
+ 'border-collapse',
299
+ 'border-color',
300
+ 'border-left',
301
+ 'border-left-color',
302
+ 'border-left-style',
303
+ 'border-left-width',
304
+ 'border-right',
305
+ 'border-right-color',
306
+ 'border-right-style',
307
+ 'border-right-width',
308
+ 'border-spacing',
309
+ 'border-style',
310
+ 'border-top',
311
+ 'border-top-color',
312
+ 'border-top-style',
313
+ 'border-top-width',
314
+ 'border-width',
315
+ 'caption-side',
316
+ 'clear',
317
+ 'cursor',
318
+ 'direction',
319
+ 'font',
320
+ 'font-family',
321
+ 'font-size',
322
+ 'font-style',
323
+ 'font-variant',
324
+ 'font-weight',
325
+ 'height',
326
+ 'letter-spacing',
327
+ 'line-height',
328
+ 'margin-bottom',
329
+ 'margin-left',
330
+ 'margin-right',
331
+ 'margin-top',
332
+ 'overflow',
333
+ 'padding',
334
+ 'padding-bottom',
335
+ 'padding-left',
336
+ 'padding-right',
337
+ 'padding-top',
338
+ 'text-decoration',
339
+ 'text-indent',
340
+ 'vertical-align',
341
+ 'width'
342
+ );
343
+
344
+ foreach ($styles_wf as $style_wf) {
345
+ if (($key = array_search($style_wf, $styles)) !== false) {
346
+ unset($styles[$key]);
347
+ }
348
+ }
349
+ return $styles;
350
+ });
351
+ }
352
+
353
+
354
+ static function clear_3rd_party_cache()
355
+ {
356
+ wp_cache_flush();
357
+
358
+ if (function_exists('rocket_clean_domain')) {
359
+ rocket_clean_domain();
360
+ }
361
+
362
+ if (function_exists('w3tc_pgcache_flush')) {
363
+ w3tc_pgcache_flush();
364
+ }
365
+
366
+ if (function_exists('wpfc_clear_all_cache')) {
367
+ wpfc_clear_all_cache();
368
+ }
369
+ if (function_exists('w3tc_flush_all')) {
370
+ w3tc_flush_all();
371
+ }
372
+ if (function_exists('wp_cache_clear_cache')) {
373
+ wp_cache_clear_cache();
374
+ }
375
+ if (method_exists('LiteSpeed_Cache_API', 'purge_all')) {
376
+ LiteSpeed_Cache_API::purge_all();
377
+ }
378
+ if (class_exists('Endurance_Page_Cache')) {
379
+ $epc = new Endurance_Page_Cache;
380
+ $epc->purge_all();
381
+ }
382
+ if (class_exists('SG_CachePress_Supercacher') && method_exists('SG_CachePress_Supercacher', 'purge_cache')) {
383
+ SG_CachePress_Supercacher::purge_cache(true);
384
+ }
385
+ if (class_exists('SiteGround_Optimizer\Supercacher\Supercacher')) {
386
+ SiteGround_Optimizer\Supercacher\Supercacher::purge_cache();
387
+ }
388
+ if (isset($GLOBALS['wp_fastest_cache']) && method_exists($GLOBALS['wp_fastest_cache'], 'deleteCache')) {
389
+ $GLOBALS['wp_fastest_cache']->deleteCache(true);
390
+ }
391
+ if (is_callable(array('Swift_Performance_Cache', 'clear_all_cache'))) {
392
+ Swift_Performance_Cache::clear_all_cache();
393
+ }
394
+ if (is_callable(array('Hummingbird\WP_Hummingbird', 'flush_cache'))) {
395
+ Hummingbird\WP_Hummingbird::flush_cache(true, false);
396
+ }
397
+ }
398
+ } // wpForceSSL_Utility
js/wpfs-pointers.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * WP Force SSL
3
+ * Backend GUI pointers
4
+ * (c) WebFactory Ltd, 2017 - 2022
5
+ */
6
+
7
+ jQuery(document).ready(function($){
8
+ if (typeof wp_force_ssl_pointers == 'undefined') {
9
+ return;
10
+ }
11
+
12
+ $.each(wp_force_ssl_pointers, function(index, pointer) {
13
+ if (index.charAt(0) == '_') {
14
+ return true;
15
+ }
16
+ $(pointer.target).pointer({
17
+ content: '<h3>WP Force SSL</h3><p>' + pointer.content + '</p>',
18
+ pointerWidth: 380,
19
+ position: {
20
+ edge: pointer.edge,
21
+ align: pointer.align
22
+ },
23
+ close: function() {
24
+ $.get(ajaxurl, {
25
+ notice_name: index,
26
+ _ajax_nonce: wp_force_ssl_pointers._nonce_dismiss_pointer,
27
+ action: 'wpfs_dismiss_notice'
28
+ });
29
+ }
30
+ }).pointer('open');
31
+ });
32
+ });
js/wpfs-script.js CHANGED
@@ -1,9 +1,74 @@
1
  /*
2
  * WP Force SSL
3
- * (c) WebFactory Ltd 2019 - 2021
4
  */
5
 
6
- (function($) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  // display a loading message while an action is performed
8
  function block_ui(message) {
9
  tmp = swal({
@@ -11,7 +76,7 @@
11
  type: false,
12
  imageUrl: wpfs.loading_icon_url,
13
  onOpen: () => {
14
- $(swal.getImage()).addClass('rotating');
15
  },
16
  heightAuto: false,
17
  imageWidth: 100,
@@ -21,45 +86,44 @@
21
  allowEscapeKey: false,
22
  allowEnterKey: false,
23
  showConfirmButton: false,
24
- width: 600
25
  });
26
 
27
  return tmp;
28
  } // block_ui
29
 
30
  // test SSL certificate
31
- $('.wpfs_test_ssl').on('click', function(e) {
32
  e.preventDefault();
33
 
34
  var _ajax_nonce = wpfs.nonce_test_ssl;
35
- var action = 'test_ssl_nonce_action';
36
  var form_data = '_ajax_nonce=' + _ajax_nonce + '&action=' + action;
37
 
38
  block_ui(wpfs.testing);
39
 
40
  $.post({
41
  url: wpfs.ajaxurl,
42
- data: form_data
43
  })
44
 
45
- .always(function(data) {
46
  swal.close();
47
  })
48
 
49
- .done(function(result) {
50
  if (typeof result.success != 'undefined' && result.success) {
51
- jQuery.get(wpfs.home_url).always(function(data, text, xhr) {
52
- status = xhr.status;
53
  wphe_changed = false;
54
 
55
- if (status.substr(0, 1) != '2') {
56
  swal({ type: 'error', heightAuto: false, title: wpfs.undocumented_error });
57
  } else {
58
  swal({
59
  type: 'success',
60
  heightAuto: false,
61
  title: wpfs.test_success,
62
- html: result.data
63
  });
64
  }
65
  });
@@ -70,12 +134,12 @@
70
  }
71
  })
72
 
73
- .fail(function(data) {
74
  if (data.data) {
75
  swal({
76
  type: 'error',
77
  heightAuto: false,
78
- title: wpfs.documented_error + ' ' + data.data
79
  });
80
  } else {
81
  swal({ heightAuto: false, type: 'error', title: wpfs.undocumented_error });
@@ -86,38 +150,31 @@
86
  }); // test SSL certificate
87
 
88
  // save settings
89
- $('#wpfs_save_settings').on('click', function(e) {
90
  e.preventDefault();
91
 
92
  var _ajax_nonce = wpfs.nonce_save_settings;
93
- var action = 'save_settting_nonce_action';
94
  var form_data = $('#wpfs_form').serialize() + '&_ajax_nonce=' + _ajax_nonce + '&action=' + action;
95
 
96
  block_ui(wpfs.saving);
97
 
98
  $.post({
99
  url: wpfs.ajaxurl,
100
- data: form_data
101
  })
102
- .always(function(data) {
103
  swal.close();
104
  })
105
- .done(function(result) {
106
  if (typeof result.success != 'undefined' && result.success) {
107
- jQuery.get(window.location.href).always(function(data, text, xhr) {
108
- status = xhr.status;
109
- if (status.substr(0, 1) != '2') {
110
- swal({ heightAuto: false, type: 'error', title: wpfs.undocumented_error });
111
- } else {
112
- $('#review-notification').show();
113
- swal({
114
- type: 'success',
115
- heightAuto: false,
116
- title: wpfs.save_success,
117
- showConfirmButton: false,
118
- timer: 1400
119
- });
120
- }
121
  });
122
  } else if (typeof result.success != 'undefined' && !result.success) {
123
  swal({ heightAuto: false, type: 'error', title: result.data });
@@ -125,12 +182,12 @@
125
  swal({ heightAuto: false, type: 'error', title: wpfs.undocumented_error });
126
  }
127
  })
128
- .fail(function(data) {
129
  if (data.data) {
130
  swal({
131
  type: 'error',
132
  heightAuto: false,
133
- title: wpfs.documented_error + ' ' + data.data
134
  });
135
  } else {
136
  swal({ heightAuto: false, type: 'error', title: wpfs.undocumented_error });
@@ -139,4 +196,260 @@
139
 
140
  return false;
141
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  })(jQuery);
 
 
 
 
 
 
1
  /*
2
  * WP Force SSL
3
+ * (c) WebFactory Ltd 2019 - 2022
4
  */
5
 
6
+ (function ($) {
7
+ $('#wfssl-tabs')
8
+ .tabs({
9
+ create: function () {
10
+ if (window.location.hash && window.location.hash != '#' && window.location.hash != '#open-pro-dialog') {
11
+ $('#wfssl-tabs').tabs(
12
+ 'option',
13
+ 'active',
14
+ $('a[href="' + location.hash + '"]')
15
+ .parent()
16
+ .index()
17
+ );
18
+ window.location.hash = '';
19
+ }
20
+ },
21
+ beforeActivate: function (event, ui) {
22
+ if (ui.newTab.hasClass('wfssl-tab-pro')) {
23
+ return false;
24
+ }
25
+ },
26
+ activate: function (event, ui) {
27
+ localStorage.setItem('wfssl-tabs', $('#wfssl-tabs').tabs('option', 'active'));
28
+ },
29
+ active: localStorage.getItem('wfssl-tabs') || 0,
30
+ })
31
+ .show();
32
+
33
+ $(window).on('hashchange', function () {
34
+ $('#wfssl-tabs').tabs(
35
+ 'option',
36
+ 'active',
37
+ $('a[href="' + location.hash + '"]')
38
+ .parent()
39
+ .index()
40
+ );
41
+ });
42
+
43
+ // helper for switching tabs & linking anchors in different tabs
44
+ $('.settings_page_wpfs-settings').on('click', '.change-tab', function (e) {
45
+ e.preventDefault();
46
+ $('#wfssl-tabs').tabs('option', 'active', $(this).data('tab'));
47
+
48
+ // get the link anchor and scroll to it
49
+ target = this.href.split('#')[1];
50
+ if (target) {
51
+ $.scrollTo('#' + target, 500, { offset: { top: -50, left: 0 } });
52
+ }
53
+
54
+ $(this).blur();
55
+ return false;
56
+ }); // jump to tab/anchor helper
57
+
58
+ // helper for scrolling to anchor
59
+ $('.settings_page_wpfs-settings').on('click', '.scrollto', function (e) {
60
+ e.preventDefault();
61
+
62
+ // get the link anchor and scroll to it
63
+ target = this.href.split('#')[1];
64
+ if (target) {
65
+ $.scrollTo('#' + target, 500, { offset: { top: -50, left: 0 } });
66
+ }
67
+
68
+ $(this).blur();
69
+ return false;
70
+ }); // scroll to anchor helper
71
+
72
  // display a loading message while an action is performed
73
  function block_ui(message) {
74
  tmp = swal({
76
  type: false,
77
  imageUrl: wpfs.loading_icon_url,
78
  onOpen: () => {
79
+ $(swal.getImage()).addClass('wfssl_flicker');
80
  },
81
  heightAuto: false,
82
  imageWidth: 100,
86
  allowEscapeKey: false,
87
  allowEnterKey: false,
88
  showConfirmButton: false,
89
+ width: 600,
90
  });
91
 
92
  return tmp;
93
  } // block_ui
94
 
95
  // test SSL certificate
96
+ $('.wpfs_test_ssl').on('click', function (e) {
97
  e.preventDefault();
98
 
99
  var _ajax_nonce = wpfs.nonce_test_ssl;
100
+ var action = 'wpfs_test_ssl';
101
  var form_data = '_ajax_nonce=' + _ajax_nonce + '&action=' + action;
102
 
103
  block_ui(wpfs.testing);
104
 
105
  $.post({
106
  url: wpfs.ajaxurl,
107
+ data: form_data,
108
  })
109
 
110
+ .always(function (data) {
111
  swal.close();
112
  })
113
 
114
+ .done(function (result) {
115
  if (typeof result.success != 'undefined' && result.success) {
116
+ jQuery.get(wpfs.home_url).always(function (data, text, xhr) {
 
117
  wphe_changed = false;
118
 
119
+ if (xhr.status.substr(0, 1) != '2') {
120
  swal({ type: 'error', heightAuto: false, title: wpfs.undocumented_error });
121
  } else {
122
  swal({
123
  type: 'success',
124
  heightAuto: false,
125
  title: wpfs.test_success,
126
+ html: result.data,
127
  });
128
  }
129
  });
134
  }
135
  })
136
 
137
+ .fail(function (data) {
138
  if (data.data) {
139
  swal({
140
  type: 'error',
141
  heightAuto: false,
142
+ title: wpfs.documented_error + ' ' + data.data,
143
  });
144
  } else {
145
  swal({ heightAuto: false, type: 'error', title: wpfs.undocumented_error });
150
  }); // test SSL certificate
151
 
152
  // save settings
153
+ $('.settings_page_wpfs-settings').on('click', '.save-ssl-options', function (e) {
154
  e.preventDefault();
155
 
156
  var _ajax_nonce = wpfs.nonce_save_settings;
157
+ var action = 'wpfs_save_settting';
158
  var form_data = $('#wpfs_form').serialize() + '&_ajax_nonce=' + _ajax_nonce + '&action=' + action;
159
 
160
  block_ui(wpfs.saving);
161
 
162
  $.post({
163
  url: wpfs.ajaxurl,
164
+ data: form_data,
165
  })
166
+ .always(function (data) {
167
  swal.close();
168
  })
169
+ .done(function (result) {
170
  if (typeof result.success != 'undefined' && result.success) {
171
+ load_test_results(true);
172
+ swal({
173
+ type: 'success',
174
+ heightAuto: false,
175
+ title: wpfs.save_success,
176
+ showConfirmButton: false,
177
+ timer: 1400,
 
 
 
 
 
 
 
178
  });
179
  } else if (typeof result.success != 'undefined' && !result.success) {
180
  swal({ heightAuto: false, type: 'error', title: result.data });
182
  swal({ heightAuto: false, type: 'error', title: wpfs.undocumented_error });
183
  }
184
  })
185
+ .fail(function (data) {
186
  if (data.data) {
187
  swal({
188
  type: 'error',
189
  heightAuto: false,
190
+ title: wpfs.documented_error + ' ' + data.data,
191
  });
192
  } else {
193
  swal({ heightAuto: false, type: 'error', title: wpfs.undocumented_error });
196
 
197
  return false;
198
  });
199
+
200
+ load_test_results(false);
201
+
202
+ $('.settings_page_wpfs-settings').on('click', '.run-tests', function () {
203
+ load_test_results(true);
204
+ });
205
+
206
+ function load_test_results(force) {
207
+ $('#status_progress_wrapper').hide();
208
+ $('.run-tests').hide();
209
+ $('#status_tasks').hide();
210
+ $('#test-results-wrapper').html(
211
+ '<div class="loading-wrapper"><img class="wfssl_flicker" src="' +
212
+ wpfs.loading_icon_url +
213
+ '" alt="Loading. Please wait." title="Loading. Please wait."><p>Loading. Please wait.</p></div>'
214
+ );
215
+
216
+ $.ajax({
217
+ url: ajaxurl,
218
+ data: {
219
+ action: 'wpfs_run_tests',
220
+ _ajax_nonce: wpfs.nonce_run_tests,
221
+ force: force,
222
+ },
223
+ })
224
+ .done(function (data) {
225
+ if (data.success) {
226
+ tests_total = 0;
227
+ tests_pass = 0;
228
+ tests_fail = 0;
229
+ tests_warning = 0;
230
+ tests_results = data.data;
231
+ tests_results_html = '<table class="form-table">';
232
+ for (test in tests_results) {
233
+ tests_total++;
234
+
235
+ tests_results_html += '<tr data-status="' + tests_results[test].status + '"><td>';
236
+
237
+ switch (tests_results[test].status) {
238
+ case 'fail':
239
+ tests_results_html += '<div class="wfssl-badge wfssl-badge-red" title="Test failed">failed</div>';
240
+ tests_fail++;
241
+ break;
242
+ case 'warning':
243
+ tests_results_html += '<div class="wfssl-badge wfssl-badge-yellow" title="Test warning">warning</div>';
244
+ tests_warning++;
245
+ break;
246
+ case 'pass':
247
+ tests_results_html += '<div class="wfssl-badge wfssl-badge-green" title="Test passed">passed</div>';
248
+ tests_pass++;
249
+ break;
250
+ }
251
+ tests_results_html += '</td>';
252
+ tests_results_html +=
253
+ '<td>' + tests_results[test].title + '<br /><small>' + tests_results[test].description + '</small></td>';
254
+ tests_results_html += '</tr>';
255
+ }
256
+
257
+ tests_results_html += '</table>';
258
+ var progress = Math.floor(((tests_warning + tests_pass) / tests_total) * 100);
259
+ $('#status_progress').css('width', progress + '%');
260
+ $('#status_progress_text').html(progress + '%');
261
+ $('#wfssl-failed-tests').html(tests_fail);
262
+ $('#status_progress_wrapper').show();
263
+ $('#status_tasks').html(
264
+ '<div class="status-tasks status-tasks-selected" data-tasks="all">All Tests (' +
265
+ tests_total +
266
+ ')</div><div class="status-tasks" data-tasks="pass">Passed (' +
267
+ tests_pass +
268
+ ')</div><div class="status-tasks" data-tasks="warning">Need Attention (' +
269
+ tests_warning +
270
+ ')</div><div class="status-tasks" data-tasks="fail">Failed (' +
271
+ tests_fail +
272
+ ')</div>'
273
+ );
274
+ $('#status_tasks').show();
275
+ $('#test-results-wrapper').html(tests_results_html);
276
+ $('.run-tests').show();
277
+ } else {
278
+ swal.fire({
279
+ type: 'error',
280
+ title: wpfs.undocumented_error,
281
+ });
282
+ }
283
+ })
284
+ .fail(function (data) {
285
+ swal.fire({
286
+ type: 'error',
287
+ title: wpfs.undocumented_error,
288
+ });
289
+ });
290
+ }
291
+
292
+ $('.settings_page_wpfs-settings').on('click', '.status-tasks', function (e) {
293
+ $('.status-tasks').removeClass('status-tasks-selected');
294
+ $(this).addClass('status-tasks-selected');
295
+ var test_status = $(this).data('tasks');
296
+ if (test_status == 'all') {
297
+ $('tr[data-status="pass"]').show();
298
+ $('tr[data-status="warning"]').show();
299
+ $('tr[data-status="fail"]').show();
300
+ } else if (test_status == 'pass') {
301
+ $('tr[data-status="pass"]').show();
302
+ $('tr[data-status="warning"]').hide();
303
+ $('tr[data-status="fail"]').hide();
304
+ } else if (test_status == 'warning') {
305
+ $('tr[data-status="pass"]').hide();
306
+ $('tr[data-status="warning"]').show();
307
+ $('tr[data-status="fail"]').hide();
308
+ } else if (test_status == 'fail') {
309
+ $('tr[data-status="pass"]').hide();
310
+ $('tr[data-status="warning"]').hide();
311
+ $('tr[data-status="fail"]').show();
312
+ }
313
+ });
314
+
315
+ // load SSL Certificate info
316
+ load_ssl_cert_info();
317
+
318
+ $('.settings_page_wpfs-settings').on('click', '.refresh-certificate-info', function () {
319
+ $('#ssl_cert_details').html(
320
+ 'Loading certificate information ... <span class="wfssl-green wfssl_rotating dashicons dashicons-update"></span>'
321
+ );
322
+ load_ssl_cert_info(true);
323
+ });
324
+
325
+ function load_ssl_cert_info(force) {
326
+ $.ajax({
327
+ url: ajaxurl,
328
+ data: {
329
+ action: 'wpfs_test_ssl',
330
+ _ajax_nonce: wpfs.nonce_test_ssl,
331
+ force: force,
332
+ },
333
+ })
334
+ .always(function (data) {})
335
+ .done(function (data) {
336
+ if (data.success) {
337
+ ssl_cert_info = data.data;
338
+ ssl_cert_info_html = '';
339
+
340
+ if (ssl_cert_info.error == true) {
341
+ ssl_cert_info_html += 'Your SSL certificate is <strong class="wfssl-red">NOT</strong> valid.';
342
+ ssl_cert_info_html += '<div class="ssl_cert_error">' + ssl_cert_info.data + '</div>';
343
+ if (wpfs.is_localhost) {
344
+ ssl_cert_info_html +=
345
+ '<div class="clear"><br /><strong>The site is not publicly available. It\'s on a localhost.</strong></div>';
346
+ }
347
+ ssl_cert_info_html += '<span class="wfssl-red dashicons dashicons-dismiss"></span>';
348
+ } else {
349
+ ssl_cert_info_html += 'Your SSL certificate is <strong class="wfssl-green">VALID</strong>.';
350
+ ssl_cert_info_html +=
351
+ '<div class="ssl_cert_info"><strong>Issued To:</strong> ' + ssl_cert_info.data.issued_to + '</div>';
352
+ ssl_cert_info_html +=
353
+ '<div class="ssl_cert_info"><strong>Issuer:</strong> ' + ssl_cert_info.data.issuer + '</div>';
354
+ ssl_cert_info_html +=
355
+ '<div class="ssl_cert_info"><strong>Valid From:</strong> ' + ssl_cert_info.data.valid_from + '</div>';
356
+ ssl_cert_info_html +=
357
+ '<div class="ssl_cert_info"><strong>Valid To:</strong> ' + ssl_cert_info.data.valid_to + '</div>';
358
+ ssl_cert_info_html += '<span class="wfssl-green dashicons dashicons-yes-alt"></span>';
359
+ }
360
+
361
+ ssl_cert_info_html +=
362
+ '<div class="button button-primary refresh-certificate-info" style="margin-top: 20px;">Refresh Certificate Info</div>';
363
+ $('#ssl_cert_details').html(ssl_cert_info_html);
364
+ } else {
365
+ swal.fire({
366
+ type: 'error',
367
+ title: wpfs.undocumented_error,
368
+ });
369
+ }
370
+ })
371
+ .fail(function (data) {
372
+ swal.fire({
373
+ type: 'error',
374
+ title: wpfs.undocumented_error,
375
+ });
376
+ });
377
+ }
378
+
379
+ // PRO related stuff
380
+ $('li.wfssl-tab-pro').on('click', function (e) {
381
+ e.preventDefault();
382
+
383
+ open_upsell('tab');
384
+
385
+ return false;
386
+ });
387
+
388
+ $('#wpwrap').on('click', '.open-pro-dialog', function (e) {
389
+ e.preventDefault();
390
+ $(this).blur();
391
+
392
+ pro_feature = $(this).data('pro-feature');
393
+ if (!pro_feature) {
394
+ pro_feature = $(this).parent('label').attr('for');
395
+ }
396
+ open_upsell(pro_feature);
397
+
398
+ return false;
399
+ });
400
+
401
+ $('#wpfssl-pro-dialog').dialog({
402
+ dialogClass: 'wp-dialog wpfssl-pro-dialog',
403
+ modal: true,
404
+ resizable: false,
405
+ width: 850,
406
+ height: 'auto',
407
+ show: 'fade',
408
+ hide: 'fade',
409
+ close: function (event, ui) {},
410
+ open: function (event, ui) {
411
+ $(this).siblings().find('span.ui-dialog-title').html('WP Force SSL PRO is here!');
412
+ wpfssl_fix_dialog_close(event, ui);
413
+ },
414
+ autoOpen: false,
415
+ closeOnEscape: true,
416
+ });
417
+
418
+ function clean_feature(feature) {
419
+ feature = feature || 'free-plugin-unknown';
420
+ feature = feature.toLowerCase();
421
+ feature = feature.replace(' ', '-');
422
+
423
+ return feature;
424
+ }
425
+
426
+ function open_upsell(feature) {
427
+ feature = clean_feature(feature);
428
+
429
+ $('#wpfssl-pro-dialog').dialog('open');
430
+
431
+ $('#wpfssl-pro-table .button-buy').each(function (ind, el) {
432
+ tmp = $(el).data('href-org');
433
+ tmp = tmp.replace('pricing-table', feature);
434
+ $(el).attr('href', tmp);
435
+ });
436
+ } // open_upsell
437
+
438
+ if (window.localStorage.getItem('wpfssl_upsell_shown') != 'true') {
439
+ open_upsell('welcome');
440
+
441
+ window.localStorage.setItem('wpfssl_upsell_shown', 'true');
442
+ window.localStorage.setItem('wpfssl_upsell_shown_timestamp', new Date().getTime());
443
+ }
444
+
445
+ if (window.location.hash == '#open-pro-dialog') {
446
+ open_upsell('url-hash');
447
+ window.location.hash = '';
448
+ }
449
  })(jQuery);
450
+
451
+ function wpfssl_fix_dialog_close(event, ui) {
452
+ jQuery('.ui-widget-overlay').bind('click', function () {
453
+ jQuery('#' + event.target.id).dialog('close');
454
+ });
455
+ } // wpfssl_fix_dialog_close
readme.txt CHANGED
@@ -1,41 +1,57 @@
1
  === WP Force SSL & HTTPS Redirect ===
2
  Contributors: WebFactory
3
- Tags: ssl, force ssl, add ssl, enable ssl, https, ssl certificate, ssl redirect, redirect, mixed content, hsts, lets encrypt
4
  Requires at least: 4.6
5
  Tested up to: 5.8
6
  Requires PHP: 5.2
7
- Stable Tag: 1.57
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
- Enable SSL & HTTPS redirect with 1 click! Add an SSL certificate & WP Force SSL to redirect site from HTTP to HTTPS.
12
 
13
  == Description ==
14
 
15
- WP Force SSL helps you redirect insecure HTTP traffic to secure HTTPS one **without touching any code**. Just activate Force SSL and everything will be configured for you and SSL enabled. The entire site will move to HTTPS using your SSL certificate. It works with any SSL certificate. It can be free SSL certificate from Let's Encrypt or a paid SSL certificate.
16
 
17
- How to add SSL & enable SSL? Most hosting companies support the free SSL certificate from Let's Encrypt, so just login to your hosting panel and add SSL certificate for free. You'll probably see a button labeled "Add SSL Certificate" or "Add Let's Encrypt Certificate" and after that it's 1 click to have the SSL enabled on your site.
18
 
19
- To keep things fast & simple WP Force SSL is very lightweight - there are only two settings.
20
- Access options via main Settings menu - Force SSL.
21
 
22
- = Three fast steps to get you started: =
23
- * Get an SSL certificate (yea, you need one, sorry).
24
- * Activate WP Force SSL.
25
- * Test certificate & you're done!
26
-
27
- = SSL certificate testing tool =
28
- WP Force SSL comes with an SSL certificate testing tool. Simply click "Test SSL certificate" and it'll test if the certificate is valid, properly installed, up-to date, and generally in good shape to be used on your site so you can force SSL.
 
 
 
 
 
 
 
 
29
 
30
  = Settings =
31
- * Force SSL - automatically redirect all traffic from HTTP to HTTPS
32
- * Enable HTTP Strict Transport Security (HSTS) - HSTS is a web security policy mechanism that helps to protect your site against protocol downgrade attacks and cookie hijacking. It allows web servers to declare that web browsers should interact with it using only HTTPS connections. HSTS adds additional security to your site.
 
 
 
 
 
 
 
 
 
33
 
34
  = Need support? =
35
  We're here for you! Things get frustrating when they don't work so make sure you <a href="https://wordpress.org/support/plugin/wp-force-ssl/">open a support topic</a> in the official Force SSL forum. We answer all questions within a few hours!
36
 
37
- = Wanna say "thank you"? =
38
- WP Force SSL is 100% free so the best way to say "thank you" is to <a href="https://wordpress.org/support/plugin/wp-force-ssl/reviews/#new-post">leave a review</a>. Reviews are what keeps the plugin going. Thank you!
39
 
40
 
41
  == Frequently Asked Questions ==
@@ -44,30 +60,32 @@ WP Force SSL is 100% free so the best way to say "thank you" is to <a href="http
44
  For anyone who has an SSL certificate installed on their site and wants to be sure all content is accessed (and redirected if needed) via a secure connection.
45
 
46
  = Do I need an SSL certificate for this to work? =
47
- Yes, you do need an SSL certificate regardless of the plugin you're using. If you don't have one try switching to a <a href="https://wordpress.org/hosting/">quality hosting provider</a> that provides and installs free certificates.
48
-
49
- = Where and how can I get an SSL certificate? =
50
- You can buy an SSL certificate but we recommend getting one for free from Let's Encrypt. The easiest way to get a free SSL certificate is to use a <a href="https://wordpress.org/hosting/">good hosting provider</a> that will automatically get an SSL certificate for you and install it. There's nothing to configure, it's just one click - they do everything for you.
51
 
52
- = After activating WP Force SSL plugin, do I need to do anything else? =
53
- No, nothing. After activating WP Force SSL, the main option "redirect SSL" will already be active. What you can do is use our tool to test your SSL certificate, to make sure it works properly.
54
 
55
  == Screenshots ==
56
 
57
- 1. After activation, all traffic is redirected from HTTP to HTTPS.
58
- 2. Test your SSL certificate with our built-in tool.
 
59
 
60
  == Installation ==
61
 
62
  1. Open Plugins - Add New in WP admin and search for "WP Force SSL"
63
  2. Install and activate the plugin
64
- 3. Plugin settings will open automatically (you can also access them via Settings - Force SSL)
65
- 4. Test you SSL certificate using our tool
66
- 5. Make sure WP Address and Site Address in Settings - General have an "https" prefix
67
 
68
 
69
  == Changelog ==
70
 
 
 
 
 
 
71
  = v1.57 =
72
  - 2021/01/30
73
  - added flyout menu
1
  === WP Force SSL & HTTPS Redirect ===
2
  Contributors: WebFactory
3
+ Tags: ssl, force ssl, add ssl, install ssl, https, ssl certificate, ssl redirect, mixed content, hsts, lets encrypt
4
  Requires at least: 4.6
5
  Tested up to: 5.8
6
  Requires PHP: 5.2
7
+ Stable Tag: 1.60
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
+ Enable SSL & HTTPS redirect with 1 click! Add SSL certificate & WP Force SSL to redirect site from HTTP to HTTPS.
12
 
13
  == Description ==
14
 
15
+ <a href="https://wpforcessl.com/?ref=wporg">WP Force SSL</a> helps you redirect insecure HTTP traffic to secure HTTPS and fix SSL errors **without touching any code**. Activate Force SSL and everything will be set and SSL enabled. The entire site will move to HTTPS using your SSL certificate. It works with any SSL certificate. It can be free SSL certificate from Let's Encrypt or a paid SSL certificate.
16
 
17
+ How to add SSL & enable SSL? Most hosting companies support the free SSL certificate from Let's Encrypt, so login to your hosting panel and add SSL certificate. You'll see a button labeled "Add SSL Certificate" or "Add Let's Encrypt Certificate" and after that it's 1 click to have the SSL enabled on your site with WP Force SSL. If that doesn't work get <a href="https://wpforcessl.com/">WP Force SSL PRO</a> and it'll generate a free SSL certificate for your site.
18
 
19
+ Access WP Force SSL settings via the main Settings menu -> WP Force SSL.
 
20
 
21
+ = SSL Tests available in the plugin =
22
+ * is site on localhost?
23
+ * check SSL certificate
24
+ * check SSL certificate expiry date
25
+ * is latest version of Force SSL used?
26
+ * are known incompatible SSL plugins active?
27
+ * is WP address URL set for SSL?
28
+ * is WP home URL set for SSL?
29
+ * is SSL monitoring enabled (pro feature)
30
+ * is HTTPS redirection working?
31
+ * is file redirection working (pro feature)
32
+ * is HSTS enabled?
33
+ * check mixed-content issue (pro feature)
34
+ * is htaccess available & writable?
35
+ * is 404 redirection enabled (pro feature)
36
 
37
  = Settings =
38
+ * redirect HTTP to HTTPS
39
+ * fix mixed-content (pro)
40
+ * enable HSTS
41
+ * force secure cookies (pro)
42
+ * cross-site scripting protection (pro)
43
+ * expect CT header
44
+ * X-Frame options
45
+ * show WP Force SSL menu in admin bar
46
+
47
+ = SSL certificate testing tool =
48
+ WP Force SSL comes with an SSL certificate testing tool. It tests if the SSL certificate is valid, properly installed & up-to date.
49
 
50
  = Need support? =
51
  We're here for you! Things get frustrating when they don't work so make sure you <a href="https://wordpress.org/support/plugin/wp-force-ssl/">open a support topic</a> in the official Force SSL forum. We answer all questions within a few hours!
52
 
53
+ = External Assets =
54
+ A big thank you to <a href="https://sweetalert2.github.io/">SweetAlert2</a> authors which we use to make alerts nicer. And to <a href="https://depositphotos.com/248496280/stock-illustration-online-payment-protection-system-concept.html">DepositPhotos</a> for the lovely header image.
55
 
56
 
57
  == Frequently Asked Questions ==
60
  For anyone who has an SSL certificate installed on their site and wants to be sure all content is accessed (and redirected if needed) via a secure connection.
61
 
62
  = Do I need an SSL certificate for this to work? =
63
+ Yes, you do need an SSL certificate. If you don't have one you can buy <a href="https://wpforcessl.com/">WP Force SSL PRO</a> which will generate an SSL certificate for free.
 
 
 
64
 
65
+ = After activating WP Force SSL, do I need to do anything else? =
66
+ No, nothing. After activating WP Force SSL, the main option "redirect SSL" will already be active. What you can do is use our tests to make sure everything related to SSL is working.
67
 
68
  == Screenshots ==
69
 
70
+ 1. Built-in tests verify your SSL configuration
71
+ 2. SSL settings
72
+ 3. SSL certificate tester
73
 
74
  == Installation ==
75
 
76
  1. Open Plugins - Add New in WP admin and search for "WP Force SSL"
77
  2. Install and activate the plugin
78
+ 3. Open plugin settings via Settings - WP Force SSL
79
+ 4. Check provided tests and settings
 
80
 
81
 
82
  == Changelog ==
83
 
84
+ = v1.60 =
85
+ - 2021/12/28
86
+ - new GUI & features
87
+ - PRO version available
88
+
89
  = v1.57 =
90
  - 2021/01/30
91
  - added flyout menu
wf-flyout/config.php CHANGED
@@ -6,12 +6,13 @@ $config['icon_border'] = '1px solid #00000099';
6
  $config['icon_right'] = '35px';
7
  $config['icon_bottom'] = '35px';
8
  $config['icon_image'] = 'wp-ssl.png';
9
- $config['icon_padding'] = '4px';
10
  $config['icon_size'] = '55px';
11
  $config['menu_accent_color'] = '#dd3036';
12
  $config['custom_css'] = '#wf-flyout .wff-menu-item .dashicons.dashicons-universal-access { font-size: 30px; padding: 0px 10px 0px 0; } #wf-flyout .ucp-icon .wff-icon img { max-width: 70%; } #wf-flyout .ucp-icon .wff-icon { line-height: 57px; }';
13
 
14
  $config['menu_items'] = array(
 
15
  array('href' => 'https://wpreset.com/?ref=wff-ssl', 'target' => '_blank', 'label' => 'Get WP Reset PRO with 50% off', 'icon' => 'wp-reset.png'),
16
  array('href' => 'https://underconstructionpage.com/?ref=wff-ssl&coupon=welcome', 'target' => '_blank', 'label' => 'Create the perfect Under Construction Page', 'icon' => 'ucp.png', 'class' => 'ucp-icon'),
17
  array('href' => 'https://wpsticky.com/?ref=wff-ssl', 'target' => '_blank', 'label' => 'Make a menu sticky with WP Sticky', 'icon' => 'dashicons-admin-post'),
6
  $config['icon_right'] = '35px';
7
  $config['icon_bottom'] = '35px';
8
  $config['icon_image'] = 'wp-ssl.png';
9
+ $config['icon_padding'] = '10px 7px 4px 7px';
10
  $config['icon_size'] = '55px';
11
  $config['menu_accent_color'] = '#dd3036';
12
  $config['custom_css'] = '#wf-flyout .wff-menu-item .dashicons.dashicons-universal-access { font-size: 30px; padding: 0px 10px 0px 0; } #wf-flyout .ucp-icon .wff-icon img { max-width: 70%; } #wf-flyout .ucp-icon .wff-icon { line-height: 57px; }';
13
 
14
  $config['menu_items'] = array(
15
+ array('href' => 'https://wp301redirects.com/?ref=wff-ssl&coupon=50off', 'label' => 'Get WP 301 Redirects PRO with 50% off', 'icon' => '301-logo.png', 'class' => 'wp301-icon'),
16
  array('href' => 'https://wpreset.com/?ref=wff-ssl', 'target' => '_blank', 'label' => 'Get WP Reset PRO with 50% off', 'icon' => 'wp-reset.png'),
17
  array('href' => 'https://underconstructionpage.com/?ref=wff-ssl&coupon=welcome', 'target' => '_blank', 'label' => 'Create the perfect Under Construction Page', 'icon' => 'ucp.png', 'class' => 'ucp-icon'),
18
  array('href' => 'https://wpsticky.com/?ref=wff-ssl', 'target' => '_blank', 'label' => 'Make a menu sticky with WP Sticky', 'icon' => 'dashicons-admin-post'),
wf-flyout/icons/301-logo.png ADDED
Binary file
wf-flyout/icons/wp-ssl.png CHANGED
Binary file
wf-flyout/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ //Silence is golden.
wf-flyout/wf-flyout.css CHANGED
@@ -1,6 +1,6 @@
1
  /**
2
  * Universal fly-out menu for WebFactory plugins
3
- * (c) WebFactory Ltd, 2021
4
  */
5
 
6
  #wf-flyout {
1
  /**
2
  * Universal fly-out menu for WebFactory plugins
3
+ * (c) WebFactory Ltd, 2022
4
  */
5
 
6
  #wf-flyout {
wf-flyout/wf-flyout.js CHANGED
@@ -1,6 +1,6 @@
1
  /**
2
  * Universal fly-out menu for WebFactory plugins
3
- * (c) WebFactory Ltd, 2021
4
  */
5
 
6
  jQuery(document).ready(function ($) {
1
  /**
2
  * Universal fly-out menu for WebFactory plugins
3
+ * (c) WebFactory Ltd, 2022
4
  */
5
 
6
  jQuery(document).ready(function ($) {
wf-flyout/wf-flyout.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  /**
4
  * Universal fly-out menu for WebFactory plugins
5
- * (c) WebFactory Ltd, 2021
6
  */
7
 
8
 
@@ -112,7 +112,7 @@ if (false == class_exists('wf_flyout')) {
112
  $out .= $this->config['custom_css'];
113
  $out .= '</style>';
114
 
115
- echo $out;
116
  } // admin_head
117
 
118
 
@@ -161,7 +161,7 @@ if (false == class_exists('wf_flyout')) {
161
 
162
  $out .= '</div>'; // #wf-flyout
163
 
164
- echo $out;
165
  } // admin_footer
166
  } // wf_flyout
167
  } // if class exists
2
 
3
  /**
4
  * Universal fly-out menu for WebFactory plugins
5
+ * (c) WebFactory Ltd, 2022
6
  */
7
 
8
 
112
  $out .= $this->config['custom_css'];
113
  $out .= '</style>';
114
 
115
+ wpForceSSL_Utility::wp_kses_wf($out);
116
  } // admin_head
117
 
118
 
161
 
162
  $out .= '</div>'; // #wf-flyout
163
 
164
+ wpForceSSL_Utility::wp_kses_wf($out);
165
  } // admin_footer
166
  } // wf_flyout
167
  } // if class exists
wp-force-ssl.php CHANGED
@@ -2,13 +2,16 @@
2
  /*
3
  Plugin Name: WP Force SSL
4
  Plugin URI: https://wpforcessl.com/
5
- Description: Redirect all traffic from HTTP to HTTPS for your entire site.
6
  Author: WebFactory Ltd
7
  Author URI: https://www.webfactoryltd.com/
8
- Version: 1.57
9
  Text Domain: wp-force-ssl
 
 
 
10
 
11
- Copyright 2019 - 2021 WebFactory Ltd (email: support@webfactoryltd.com)
12
 
13
  This program is free software; you can redistribute it and/or modify
14
  it under the terms of the GNU General Public License, version 2, as
@@ -16,7 +19,7 @@
16
 
17
  This program is distributed in the hope that it will be useful,
18
  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
  GNU General Public License for more details.
21
 
22
  You should have received a copy of the GNU General Public License
@@ -30,6 +33,8 @@ if (!defined('ABSPATH')) {
30
  exit('You are not allowed to access this file directly.');
31
  }
32
 
 
 
33
  require_once dirname(__FILE__) . '/wf-flyout/wf-flyout.php';
34
  new wf_flyout(__FILE__);
35
 
@@ -40,20 +45,21 @@ define('WPFSSL_META_KEY', 'wpfssl_meta');
40
  // start up the engine
41
  class wpForceSSL
42
  {
43
- static $instance = false;
44
- private $wpfs_settings = array();
45
  public $version = 0;
46
  public $plugin_url = '';
 
47
  public $meta = array();
48
 
49
 
50
  /**
51
- * Check if minimum WP and PHP versions are installed
52
  * Register all hooks for the plugin
53
  *
54
  * @since 1.5
55
  *
56
- * @return array plugin meta
57
  *
58
  */
59
  private function __construct()
@@ -64,32 +70,44 @@ class wpForceSSL
64
  return false;
65
  }
66
 
67
- $this->wpfs_settings = get_option(WPFSSL_OPTIONS_KEY, array());
68
-
69
- if (!is_array($this->wpfs_settings) || empty($this->wpfs_settings)) {
70
- $this->wpfs_settings['wpfs_ssl'] = 'yes';
71
- $this->wpfs_settings['wpfs_hsts'] = 'no';
72
- update_option(WPFSSL_OPTIONS_KEY, $this->wpfs_settings);
73
- }
 
74
 
75
  $this->plugin_url = plugin_dir_url(__FILE__);
 
76
  $this->meta = $this->get_meta();
77
 
78
- if ($this->wpfs_settings['wpfs_ssl'] == 'yes') {
79
  add_action('template_redirect', array($this, 'wpfs_core'));
80
  }
81
- if ($this->wpfs_settings['wpfs_hsts'] == 'yes') {
82
  add_action('send_headers', array($this, 'to_strict_transport_security'));
83
  }
 
 
 
84
 
85
  add_action('admin_menu', array($this, 'add_settings_page'));
 
 
86
  add_filter('admin_footer_text', array($this, 'admin_footer_text'));
 
87
  add_action('admin_enqueue_scripts', array($this, 'admin_scripts'));
88
- add_action('admin_action_wpfs_dismiss_review_notice', array($this, 'action_dismiss_review_notice'));
 
 
89
 
90
  // ajax hooks for the settings, and SSL certificate test
91
- add_action('wp_ajax_save_settting_nonce_action', array($this, 'ajax_save_setting'));
92
- add_action('wp_ajax_test_ssl_nonce_action', array($this, 'ajax_check_ssl'));
 
 
93
  } // __construct
94
 
95
 
@@ -108,7 +126,7 @@ class wpForceSSL
108
  if (!is_array($meta) || empty($meta)) {
109
  $meta['first_version'] = $this->get_plugin_version();
110
  $meta['first_install'] = time();
111
- $meta['hide_review_notification'] = false;
112
  update_option(WPFSSL_META_KEY, $meta);
113
  }
114
 
@@ -116,6 +134,31 @@ class wpForceSSL
116
  } // get_meta
117
 
118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  /**
120
  * Get plugin version
121
  *
@@ -141,14 +184,43 @@ class wpForceSSL
141
  * @return object wpForceSLL instance
142
  *
143
  */
144
- public static function getInstance()
145
  {
146
  if (false == is_a(self::$instance, 'wpForceSSL')) {
147
  self::$instance = new self;
148
  }
149
 
150
  return self::$instance;
151
- } // getInstance
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
 
154
  /**
@@ -161,35 +233,58 @@ class wpForceSSL
161
  */
162
  public function admin_scripts($hook)
163
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  if (false == $this->is_plugin_page()) {
165
  return;
166
  }
167
 
168
  wp_enqueue_style('wpfs-style', $this->plugin_url . 'css/wpfs-style.css', null, $this->version);
169
  wp_enqueue_style('wpfs-sweetalert2-style', $this->plugin_url . 'css/sweetalert2.min.css', null, $this->version);
 
 
 
 
 
 
170
 
171
  wp_enqueue_script('wpfs-sweetalert2', $this->plugin_url . 'js/sweetalert2.min.js', array('jquery'), $this->version, true);
172
  wp_enqueue_script('wpfs-script', $this->plugin_url . 'js/wpfs-script.js', array('jquery'), $this->version, true);
173
 
174
  wp_localize_script('wpfs-script', 'wpfs', array(
175
  'ajaxurl' => admin_url('admin-ajax.php'),
176
- 'loading_icon_url' => plugins_url('img/loading-icon.png', __FILE__),
177
  'testing' => __('Testing. Please wait ...', 'wp-force-ssl'),
178
  'saving' => __('Saving. Please wait ...', 'wp-force-ssl'),
179
  'test_success' => __('Test Completed Successfully', 'wp-force-ssl'),
180
  'test_failed' => __('Test Failed', 'wp-force-ssl'),
181
  'home_url' => get_home_url(),
182
- 'save_success' => __('Settings saved.', 'wp-force-ssl'),
183
  'undocumented_error' => __('An undocumented error has occurred. Please refresh the page and try again.', 'wp-force-ssl'),
184
  'documented_error' => __('An error has occurred.', 'wp-force-ssl'),
185
  'nonce_save_settings' => wp_create_nonce('save_settting_nonce_action'),
186
- 'nonce_test_ssl' => wp_create_nonce('test_ssl_nonce_action')
 
187
  ));
 
 
188
  } // admin_scripts
189
 
190
 
191
  /**
192
- * Load text domain and plugin version
193
  *
194
  * @since 1.5
195
  *
@@ -212,10 +307,13 @@ class wpForceSSL
212
  */
213
  public function add_settings_page()
214
  {
 
 
 
215
  add_options_page(
216
  __('WP Force SSL', 'wp-force-ssl'),
217
- __('WP Force SSL', 'wp-force-ssl'),
218
- 'manage_options',
219
  'wpfs-settings',
220
  array($this, 'settings_page_content')
221
  );
@@ -223,105 +321,485 @@ class wpForceSSL
223
 
224
 
225
  /**
226
- * Dismiss review notification
227
  *
228
- * @since 1.55
229
  *
230
  * @return null
231
  *
232
  */
233
- public function action_dismiss_review_notice() {
234
- if (false == wp_verify_nonce(@$_GET['_wpnonce'], 'wpfs_dismiss_review_notice')) {
235
- wp_die('Please reload the page and try again.');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  }
237
 
238
- $this->meta['hide_review_notification'] = true;
239
- update_option(WPFSSL_META_KEY, $this->meta);
 
 
 
240
 
241
- wp_safe_redirect('options-general.php?page=wpfs-settings');
242
- } // action_dismiss_review_notice
243
 
244
 
245
  /**
246
- * Echo plugin settings page
247
  *
248
- * @since 1.5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  *
250
  * @return null
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  *
 
252
  */
253
- public function settings_page_content()
254
- {
255
- ?>
256
- <div class="wrap">
257
- <h1>
258
- <?php _e('WP Force SSL', 'wp-force-ssl'); ?>
259
- </h1>
260
- <hr>
261
- <p>WP Force SSL is a one-click solution that helps redirect visitors from unsecure HTTP connection to a secure HTTPS one without the need to edit any code.<br>There's nothing to configure, just by activating the plugin everything is enabled and configured.</p>
262
-
263
- <p>If you run into any problems <a href="https://wordpress.org/support/plugin/wp-force-ssl/" target="_blank">open a new topic</a> in the official support forum. We answer all questions within a few hours.</p>
264
-
265
- <h2><br>Requirements for running a site on SSL</h2>
266
- <ul class="ul-disc">
267
- <li>If you already have an SSL certificate installed <a href="#" class="wpfs_test_ssl">test it</a> to make sure it works.
268
- If you don't have one get <a href="https://wordpress.org/hosting/" target="_blank">quality hosting</a> that offers free certificates and installation.</li>
269
- <li>Make sure "Force SSL" option below is enabled (green).</li>
270
- <li>Check that <a href="<?php echo admin_url('options-general.php'); ?>" target="_blank">WP Address &amp; Site Address</a> settings have an <code>https://</code> prefix set.</li>
271
- </ul>
272
- <?php
273
- if (!isset($this->meta['hide_review_notification']) ||
274
- empty($this->meta['hide_review_notification'])) {
275
-
276
- $dismiss_url = add_query_arg(array('action' => 'wpfs_dismiss_review_notice', 'redirect' => urlencode($_SERVER['REQUEST_URI'])), admin_url('admin.php'));
277
- $dismiss_url = wp_nonce_url($dismiss_url, 'wpfs_dismiss_review_notice');
278
- ?>
279
- <p id="review-notification" class="box"<?php if ($this->wpfs_settings['wpfs_ssl'] == 'no') echo ' style="display: none;"'; ?>><b>Your site is now more secure! Please help others learn about this free plugin.</b><br><br>Please help other users learn about WP Force SSL by leaving a review.<br>It only takes a minute but it helps a lot and it keeps the plugin updated, maintained and free. <b>Thank you!</b><br><br>
280
- <a class="button button-primary" href="https://wordpress.org/support/plugin/wp-force-ssl/reviews/?filter=5" target="_blank">Help other users - leave a review</a><a href="<?php echo $dismiss_url; ?>">I already left a review</a>
281
- </p>
282
- <?php
283
- }
284
- ?>
285
- <h2><br><?php _e('Settings', 'wp-force-ssl'); ?></h2>
286
- <form id="wpfs_form">
287
- <table class="form-table">
288
- <tbody>
289
- <tr>
290
- <th scope="row">
291
- <label for="enable_ssl"><?php _e('Force SSL', 'wp-force-ssl'); ?></label>
292
- </th>
293
- <td>
294
- <div class="toggle-wrapper">
295
- <input type="checkbox" id="enable_ssl" <?php if ($this->wpfs_settings['wpfs_ssl'] == 'yes') echo 'checked'; ?> name="wpfs_ssl" value="yes">
296
- <label for="enable_ssl" class="toggle"><span class="toggle_handler"></span></label>
297
- </div>
298
- <p class="description">Visitors will be automatically redirected from HTTP to HTTPS for all pages, posts and other WP content.</p>
299
- </td>
300
- </tr>
301
- <tr>
302
- <th scope="row">
303
- <label for="enable_hsts"><?php _e('Enable HTTP Strict Transport Security (HSTS)', 'wp-force-ssl'); ?></label>
304
- </th>
305
- <td>
306
- <div class="toggle-wrapper">
307
- <input type="checkbox" id="enable_hsts" <?php if ($this->wpfs_settings['wpfs_hsts'] == 'yes') echo 'checked'; ?> name="wpfs_hsts" value="yes">
308
- <label for="enable_hsts" class="toggle"><span class="toggle_handler"></span></label>
309
- </div>
310
- <p class="description">HSTS is a web security policy mechanism that helps to protect your site against protocol downgrade attacks and cookie hijacking.<br>It allows web servers to declare that web browsers should interact with it using only HTTPS connections.</p>
311
- </td>
312
- </tr>
313
- </tbody>
314
- </table>
315
- <p>
316
- <a id="wpfs_save_settings" name="submit" title="Save Changes" class="button button-primary" href="#">Save Changes</a>
317
- <a href="#" class="button button-secondary wpfs_test_ssl">Test site's SSL certificate</a>
318
- </p>
319
- </form>
320
- </div>
321
- <?php
 
 
 
322
  } // settings_page_content
323
 
324
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  /**
326
  * Perform the redirect to HTTPS if loaded over HTTP
327
  *
@@ -333,14 +811,14 @@ class wpForceSSL
333
  public function wpfs_core()
334
  {
335
  if (!is_ssl()) {
336
- wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301);
337
  exit();
338
  }
339
  } // wpfs_core
340
 
341
 
342
  /**
343
- * Check if user has the minimal WP version required by WP Force SSL
344
  *
345
  * @since 1.5
346
  *
@@ -385,6 +863,19 @@ class wpForceSSL
385
  } // to_strict_transport_security
386
 
387
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
  /**
389
  * Save plugin settings received via AJAX
390
  *
@@ -398,10 +889,14 @@ class wpForceSSL
398
 
399
  $wpfs_ssl = isset($_POST['wpfs_ssl']) ? 'yes' : 'no';
400
  $wpfs_hsts = isset($_POST['wpfs_hsts']) ? 'yes' : 'no';
 
 
401
 
402
  $wpfs_settings = array(
403
  'wpfs_ssl' => $wpfs_ssl,
404
- 'wpfs_hsts' => $wpfs_hsts
 
 
405
  );
406
  update_option(WPFSSL_OPTIONS_KEY, $wpfs_settings);
407
 
@@ -418,64 +913,19 @@ class wpForceSSL
418
  */
419
  public function ajax_check_ssl()
420
  {
421
- check_ajax_referer('test_ssl_nonce_action');
422
 
423
- if (!version_compare(PHP_VERSION, '5.6', '>=')) {
424
- wp_send_json_error(sprintf(__('WP Force SSL plugin <b>requires PHP version 5.6.20</b> or higher to function properly. You are using PHP version %s. Please <a href="%s" target="_blank">update it</a>.', 'wp-force-ssl'), PHP_VERSION, 'https://wordpress.org/support/update-php/'));
425
- }
426
-
427
- $url = home_url(false, 'https');
428
- $response = $this->make_request($url);
429
 
430
- if (!$response || !is_array($response)) {
431
- wp_send_json_error(__('Unable to test SSL certificate. Assume it\'s NOT valid.', 'wp-force-ssl'));
432
- } elseif (!empty($response['error'])) {
433
- wp_send_json_error($response['error']);
434
- } elseif ($response['code'] == 200 && !empty($response['body'])) {
435
- wp_send_json_success(__('Valid SSL certificate found!', 'wp-force-ssl'));
436
  } else {
437
- wp_send_json_error(__('Valid SSL certificate was NOT found.', 'wp-force-ssl'));
438
- }
439
- } // check_ssl
440
-
441
-
442
- /**
443
- * Perform a POST request
444
- *
445
- * @since 1.5
446
- *
447
- * @param string $url
448
- *
449
- * @return array $response
450
- */
451
- public function make_request($url = null)
452
- {
453
- if (empty($url)) {
454
- $url = home_url(false, 'https');
455
  }
 
456
 
457
- $args = array(
458
- 'timeout' => 5,
459
- 'httpversion' => '1.1',
460
- 'sslverify' => true
461
- );
462
-
463
- $response = wp_remote_post($url, $args);
464
-
465
- $error = '';
466
- if (is_wp_error($response)) {
467
- $error = $response->get_error_message();
468
- }
469
-
470
- $out = array(
471
- 'code' => wp_remote_retrieve_response_code($response),
472
- 'body' => wp_remote_retrieve_body($response),
473
- 'error' => $error
474
- );
475
-
476
- return $out;
477
- } // make_request
478
-
479
 
480
  /**
481
  * Check if currently on WP Force SSL settings page
@@ -510,91 +960,130 @@ class wpForceSSL
510
  return $text_org;
511
  }
512
 
513
- $text = '<i><a target="_blank" href="' . $this->generate_web_link('admin_footer') . '">WP Force SSL</a> v' . $this->version . ' by <a href="https://www.webfactoryltd.com/" title="' . __('Visit our site to get more great plugins', 'wp-force-ssl') . '" target="_blank">WebFactory Ltd</a>.';
514
  $text .= ' Please <a target="_blank" href="https://wordpress.org/support/plugin/wp-force-ssl/reviews/#new-post" title="' . __('Rate the plugin', 'wp-force-ssl') . '">' . __('Rate the plugin ★★★★★', 'wp-force-ssl') . '</a>.</i> ';
515
  return $text;
516
  } // admin_footer_text
517
 
518
 
519
- /**
520
- * Generate web link
521
- *
522
- * @since 1.5
523
- *
524
- * @return string link html
525
- */
526
- public function generate_web_link($placement = '', $page = '/', $params = array(), $anchor = '')
527
  {
528
- $base_url = 'https://wpforcessl.com';
529
- if ('/' != $page) {
530
- $page = '/' . trim($page, '/') . '/';
531
- }
532
- if ($page == '//') {
533
- $page = '/';
534
- }
535
-
536
- $parts = array_merge(array('utm_source' => 'wp-force-ssl', 'utm_medium' => 'plugin', 'utm_content' => $placement, 'utm_campaign' => 'wp-force-ssl' . $this->version), $params);
537
- if (!empty($anchor)) {
538
- $anchor = '#' . trim($anchor, '#');
539
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
 
541
- $out = $base_url . $page . '?' . http_build_query($parts, '', '&amp;') . $anchor;
542
  return $out;
543
- } // generate_web_link
544
 
545
 
546
  /**
547
- * Activation hook, check if trying to activate on WP Network and exit if that's the case
548
  *
549
  * @since 1.5
550
  *
551
  * @return null
552
  */
553
- public static function activate()
554
  {
555
- // Bail if activating from network, or bulk
556
- if (is_network_admin() || isset($_GET['activate-multi'])) {
557
- wp_die(__('Sorry, WP Force SSL is currently not compatible with WPMU.', 'wp-force-ssl'));
558
- }
559
- } // activate
560
-
561
-
562
- /**
563
- * Redirect to WP Force SSL settings page on activation
564
- *
565
- * @since 1.5
566
- *
567
- * @return null
568
- *
569
- */
570
- public function redirect_to_settings_page($plugin)
571
- {
572
- if ($plugin == plugin_basename(__FILE__)) {
573
- wp_safe_redirect(
574
- add_query_arg(
575
- array(
576
- 'page' => 'wpfs-settings'
577
- ),
578
- admin_url('options-general.php')
579
- )
580
- );
581
- exit();
582
- }
583
- } // redirect_to_settings_page
584
 
585
 
586
  /**
587
- * Clean-up on uninstall
588
- *
589
- * @since 1.5
590
  *
591
  * @return null
592
  */
593
- public static function uninstall()
594
  {
595
- delete_option(WPFSSL_OPTIONS_KEY);
596
- delete_option(WPFSSL_META_KEY);
597
- } // uninstall
 
598
 
599
 
600
  /**
@@ -605,7 +1094,8 @@ class wpForceSSL
605
  * @return null
606
  */
607
  private function __clone()
608
- { }
 
609
 
610
 
611
  /**
@@ -616,7 +1106,8 @@ class wpForceSSL
616
  * @return null
617
  */
618
  public function __sleep()
619
- { }
 
620
 
621
 
622
  /**
@@ -627,13 +1118,13 @@ class wpForceSSL
627
  * @return null
628
  */
629
  public function __wakeup()
630
- { }
 
631
  // end class
632
  }
633
 
634
 
635
- $wpfs = wpForceSSL::getInstance();
636
  add_action('plugins_loaded', array($wpfs, 'plugins_loaded'));
637
- add_action('activated_plugin', array($wpfs, 'redirect_to_settings_page'));
638
- register_activation_hook(__FILE__, array('wpForceSSL', 'activate'));
639
  register_uninstall_hook(__FILE__, array('wpForceSSL', 'uninstall'));
2
  /*
3
  Plugin Name: WP Force SSL
4
  Plugin URI: https://wpforcessl.com/
5
+ Description: Redirect all traffic from HTTP to HTTPS and fix other SSL issues.
6
  Author: WebFactory Ltd
7
  Author URI: https://www.webfactoryltd.com/
8
+ Version: 1.60
9
  Text Domain: wp-force-ssl
10
+ Requires at least: 4.6
11
+ Requires PHP: 5.2
12
+ Tested up to: 5.8
13
 
14
+ Copyright 2019 - 2022 WebFactory Ltd (email: support@webfactoryltd.com)
15
 
16
  This program is free software; you can redistribute it and/or modify
17
  it under the terms of the GNU General Public License, version 2, as
19
 
20
  This program is distributed in the hope that it will be useful,
21
  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
  GNU General Public License for more details.
24
 
25
  You should have received a copy of the GNU General Public License
33
  exit('You are not allowed to access this file directly.');
34
  }
35
 
36
+ require_once dirname(__FILE__) . '/inc/wp-force-ssl-status-tests.php';
37
+ require_once dirname(__FILE__) . '/inc/wp-force-ssl-utility.php';
38
  require_once dirname(__FILE__) . '/wf-flyout/wf-flyout.php';
39
  new wf_flyout(__FILE__);
40
 
45
  // start up the engine
46
  class wpForceSSL
47
  {
48
+ protected static $instance = false;
49
+ public $options = array();
50
  public $version = 0;
51
  public $plugin_url = '';
52
+ public $plugin_dir = '';
53
  public $meta = array();
54
 
55
 
56
  /**
57
+ * Check if minimum WP and PHP versions are available
58
  * Register all hooks for the plugin
59
  *
60
  * @since 1.5
61
  *
62
+ * @return null
63
  *
64
  */
65
  private function __construct()
70
  return false;
71
  }
72
 
73
+ $this->options = get_option(WPFSSL_OPTIONS_KEY, array());
74
+ $default = array(
75
+ 'wpfs_ssl' => 'yes',
76
+ 'wpfs_hsts' => 'no',
77
+ 'wpfs_expect_ct' => 'no',
78
+ 'wpfs_adminbar_menu' => 'no'
79
+ );
80
+ $this->options = array_merge($default, $this->options);
81
 
82
  $this->plugin_url = plugin_dir_url(__FILE__);
83
+ $this->plugin_dir = plugin_dir_path(__FILE__);
84
  $this->meta = $this->get_meta();
85
 
86
+ if ($this->options['wpfs_ssl'] == 'yes') {
87
  add_action('template_redirect', array($this, 'wpfs_core'));
88
  }
89
+ if ($this->options['wpfs_hsts'] == 'yes') {
90
  add_action('send_headers', array($this, 'to_strict_transport_security'));
91
  }
92
+ if ($this->options['wpfs_expect_ct'] == 'yes') {
93
+ add_action('send_headers', array($this, 'enable_expect_ct'));
94
+ }
95
 
96
  add_action('admin_menu', array($this, 'add_settings_page'));
97
+ add_action('admin_head', array($this, 'cleanup_enqueues'), 99999);
98
+ add_action('wp_before_admin_bar_render', array($this, 'admin_bar'));
99
  add_filter('admin_footer_text', array($this, 'admin_footer_text'));
100
+ add_action('admin_print_scripts', array($this, 'remove_admin_notices'));
101
  add_action('admin_enqueue_scripts', array($this, 'admin_scripts'));
102
+
103
+ add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'plugin_action_links'));
104
+ add_filter('plugin_row_meta', array($this, 'plugin_meta_links'), 10, 2);
105
 
106
  // ajax hooks for the settings, and SSL certificate test
107
+ add_action('wp_ajax_wpfs_save_settting', array($this, 'ajax_save_setting'));
108
+ add_action('wp_ajax_wpfs_test_ssl', array($this, 'ajax_check_ssl'));
109
+ add_action('wp_ajax_wpfs_run_tests', array($this, 'ajax_run_tests'));
110
+ add_action('wp_ajax_wpfs_dismiss_notice', array($this, 'ajax_dismiss_notice'));
111
  } // __construct
112
 
113
 
126
  if (!is_array($meta) || empty($meta)) {
127
  $meta['first_version'] = $this->get_plugin_version();
128
  $meta['first_install'] = time();
129
+ $meta['hide_welcome_pointer'] = false;
130
  update_option(WPFSSL_META_KEY, $meta);
131
  }
132
 
134
  } // get_meta
135
 
136
 
137
+ /**
138
+ * Dismiss notice via AJAX call
139
+ *
140
+ * @return null
141
+ */
142
+ function ajax_dismiss_notice()
143
+ {
144
+ check_ajax_referer('wpfs_dismiss_notice');
145
+
146
+ if (!current_user_can('administrator')) {
147
+ wp_send_json_error('You are not allowed to run this action.');
148
+ }
149
+
150
+ $notice_name = trim(sanitize_text_field(@$_GET['notice_name']));
151
+
152
+ if ($notice_name != 'welcome') {
153
+ wp_send_json_error('Unknown notice');
154
+ } else {
155
+ $this->meta['hide_welcome_pointer'] = true;
156
+ update_option(WPFSSL_META_KEY, $this->meta);
157
+ wp_send_json_success();
158
+ }
159
+ } // ajax_dismiss_notice
160
+
161
+
162
  /**
163
  * Get plugin version
164
  *
184
  * @return object wpForceSLL instance
185
  *
186
  */
187
+ public static function get_instance()
188
  {
189
  if (false == is_a(self::$instance, 'wpForceSSL')) {
190
  self::$instance = new self;
191
  }
192
 
193
  return self::$instance;
194
+ } // get_instance
195
+
196
+
197
+ /**
198
+ * Run websites tests
199
+ *
200
+ * @return null
201
+ */
202
+ function ajax_run_tests()
203
+ {
204
+ global $wp_force_ssl_tests;
205
+
206
+ check_ajax_referer('run_tests_nonce_action');
207
+ if (!current_user_can('administrator')) {
208
+ wp_send_json_error('You are not allowed to run this action.');
209
+ }
210
+
211
+ if (isset($_REQUEST['force']) && (bool) $_REQUEST['force'] === true) {
212
+ $nocache = true;
213
+ } else {
214
+ $nocache = false;
215
+ }
216
+
217
+ $res = $wp_force_ssl_tests->get_tests_results($nocache);
218
+ if (is_wp_error($res)) {
219
+ wp_send_json_error($res->get_error_message());
220
+ } else {
221
+ wp_send_json_success($res);
222
+ }
223
+ } // ajax_run_tool
224
 
225
 
226
  /**
233
  */
234
  public function admin_scripts($hook)
235
  {
236
+ $meta = $this->get_meta();
237
+ $pointers = array();
238
+
239
+ if (empty($meta['hide_welcome_pointer']) && !$this->is_plugin_page() && current_user_can('administrator')) {
240
+ $pointers['_nonce_dismiss_pointer'] = wp_create_nonce('wpfs_dismiss_notice');
241
+ $pointers['welcome'] = array('target' => '#menu-settings', 'edge' => 'left', 'align' => 'right', 'content' => 'Thank you for installing the <b style="font-weight: 800;">WP Force SSL</b> plugin!<br>Open <a href="' . admin_url('options-general.php?page=wpfs-settings') . '">Settings - WP Force SSL</a> to access SSL settings.');
242
+
243
+ wp_enqueue_style('wp-pointer');
244
+
245
+ wp_enqueue_script('wp-force-ssl-pointers', $this->plugin_url . 'js/wpfs-pointers.js', array('jquery'), $this->version, true);
246
+ wp_enqueue_script('wp-pointer');
247
+ wp_localize_script('wp-pointer', 'wp_force_ssl_pointers', $pointers);
248
+ }
249
+
250
  if (false == $this->is_plugin_page()) {
251
  return;
252
  }
253
 
254
  wp_enqueue_style('wpfs-style', $this->plugin_url . 'css/wpfs-style.css', null, $this->version);
255
  wp_enqueue_style('wpfs-sweetalert2-style', $this->plugin_url . 'css/sweetalert2.min.css', null, $this->version);
256
+ wp_enqueue_style('wp-jquery-ui-dialog');
257
+
258
+ wp_enqueue_script('jquery-ui-tabs');
259
+ wp_enqueue_script('jquery-ui-core');
260
+ wp_enqueue_script('jquery-ui-position');
261
+ wp_enqueue_script('jquery-ui-dialog');
262
 
263
  wp_enqueue_script('wpfs-sweetalert2', $this->plugin_url . 'js/sweetalert2.min.js', array('jquery'), $this->version, true);
264
  wp_enqueue_script('wpfs-script', $this->plugin_url . 'js/wpfs-script.js', array('jquery'), $this->version, true);
265
 
266
  wp_localize_script('wpfs-script', 'wpfs', array(
267
  'ajaxurl' => admin_url('admin-ajax.php'),
268
+ 'loading_icon_url' => plugins_url('img/wp-ssl.png', __FILE__),
269
  'testing' => __('Testing. Please wait ...', 'wp-force-ssl'),
270
  'saving' => __('Saving. Please wait ...', 'wp-force-ssl'),
271
  'test_success' => __('Test Completed Successfully', 'wp-force-ssl'),
272
  'test_failed' => __('Test Failed', 'wp-force-ssl'),
273
  'home_url' => get_home_url(),
274
+ 'save_success' => __('Settings saved', 'wp-force-ssl'),
275
  'undocumented_error' => __('An undocumented error has occurred. Please refresh the page and try again.', 'wp-force-ssl'),
276
  'documented_error' => __('An error has occurred.', 'wp-force-ssl'),
277
  'nonce_save_settings' => wp_create_nonce('save_settting_nonce_action'),
278
+ 'nonce_test_ssl' => wp_create_nonce('test_ssl_nonce_action'),
279
+ 'nonce_run_tests' => wp_create_nonce('run_tests_nonce_action')
280
  ));
281
+
282
+ $this->cleanup_enqueues();
283
  } // admin_scripts
284
 
285
 
286
  /**
287
+ * Load text domain
288
  *
289
  * @since 1.5
290
  *
307
  */
308
  public function add_settings_page()
309
  {
310
+ global $wp_force_ssl_tests;
311
+ $test_results = $wp_force_ssl_tests->count_statuses();
312
+
313
  add_options_page(
314
  __('WP Force SSL', 'wp-force-ssl'),
315
+ __('WP Force SSL', 'wp-force-ssl') . ($test_results['fail'] ? sprintf(' <span class="wfssl-failed-tests awaiting-mod">%d</span>', $test_results['fail']) : ''),
316
+ 'administrator',
317
  'wpfs-settings',
318
  array($this, 'settings_page_content')
319
  );
321
 
322
 
323
  /**
324
+ * Shows admin top menu entry
325
  *
326
+ * @since 1.6
327
  *
328
  * @return null
329
  *
330
  */
331
+ function admin_bar()
332
+ {
333
+ if (!is_admin()) {
334
+ return;
335
+ }
336
+
337
+ global $wp_admin_bar, $wp_force_ssl_tests;
338
+
339
+ $test_results = $wp_force_ssl_tests->count_statuses();
340
+ $plugin_name = __('WP Force SSL', 'wp-force-ssl');
341
+ $plugin_logo = esc_url($this->plugin_url) . 'img/wp-force-ssl-icon.png';
342
+
343
+ if (
344
+ 'yes' != $this->options['wpfs_adminbar_menu'] ||
345
+ false === current_user_can('administrator') ||
346
+ false === apply_filters('wp_force_ssl_show_admin_bar', true)
347
+ ) {
348
+ return;
349
+ }
350
+
351
+ $title = '<div class="wfssl-adminbar-icon" style="display:inline-block;"><img style="height: 22px; padding: 4px; margin-bottom: -10px; filter: invert(1) brightness(1.2) grayscale(1);" src="' . $plugin_logo . '" alt="' . $plugin_name . '" title="' . $plugin_name . '"></div> <span class="ab-label">' . $plugin_name . '</span>';
352
+ if ($test_results['fail']) {
353
+ $title .= sprintf(' <span class="wfssl-failed-tests awaiting-mod" style="display: inline-block;vertical-align: top;box-sizing: border-box;margin: 1px 0 -1px 2px; padding: 0 5px; min-width: 18px;height: 18px; border-radius: 9px;background-color: #d63638; color: #fff; font-size: 11px; line-height: 1.6; text-align: center; z-index: 26;vertical-align: text-bottom;">%d</span>', $test_results['fail']);
354
+ }
355
+
356
+ $wp_admin_bar->add_node(array(
357
+ 'id' => 'wfssl-ab',
358
+ 'title' => $title,
359
+ 'href' => '#',
360
+ 'parent' => '',
361
+ ));
362
+
363
+ $wp_admin_bar->add_node(array(
364
+ 'id' => 'wfssl-status',
365
+ 'title' => 'Status',
366
+ 'href' => admin_url('options-general.php?page=wpfs-settings#tab_status'),
367
+ 'parent' => 'wfssl-ab'
368
+ ));
369
+
370
+ $wp_admin_bar->add_node(array(
371
+ 'id' => 'wfssl-settings',
372
+ 'title' => 'Settings',
373
+ 'href' => admin_url('options-general.php?page=wpfs-settings#tab_settings'),
374
+ 'parent' => 'wfssl-ab'
375
+ ));
376
+
377
+ $wp_admin_bar->add_node(array(
378
+ 'id' => 'wfssl-scanner',
379
+ 'title' => 'Content Scanner',
380
+ 'href' => admin_url('options-general.php?page=wpfs-settings#tab_scanner'),
381
+ 'parent' => 'wfssl-ab'
382
+ ));
383
+
384
+ $wp_admin_bar->add_node(array(
385
+ 'id' => 'wfssl-snapshots',
386
+ 'title' => 'SSL Certificate',
387
+ 'href' => admin_url('options-general.php?page=wpfs-settings#tab_ssl'),
388
+ 'parent' => 'wfssl-ab'
389
+ ));
390
+ } // admin_bar
391
+
392
+
393
+ // fix for aggressive plugins that include their CSS on all pages
394
+ function cleanup_enqueues()
395
+ {
396
+ if (!$this->is_plugin_page()) {
397
+ return;
398
+ }
399
+
400
+ wp_dequeue_style('uiStyleSheet');
401
+ wp_dequeue_style('wpcufpnAdmin');
402
+ wp_dequeue_style('unifStyleSheet');
403
+ wp_dequeue_style('wpcufpn_codemirror');
404
+ wp_dequeue_style('wpcufpn_codemirrorTheme');
405
+ wp_dequeue_style('collapse-admin-css');
406
+ wp_dequeue_style('jquery-ui-css');
407
+ wp_dequeue_style('tribe-common-admin');
408
+ wp_dequeue_style('file-manager__jquery-ui-css');
409
+ wp_dequeue_style('file-manager__jquery-ui-css-theme');
410
+ wp_dequeue_style('wpmegmaps-jqueryui');
411
+ wp_dequeue_style('wp-botwatch-css');
412
+ wp_dequeue_style('njt-filebird-admin');
413
+ wp_dequeue_style('ihc_jquery-ui.min.css');
414
+ wp_dequeue_style('badgeos-juqery-autocomplete-css');
415
+ wp_dequeue_style('mainwp');
416
+ wp_dequeue_style('mainwp-responsive-layouts');
417
+ wp_dequeue_style('jquery-ui-style');
418
+ wp_dequeue_style('additional_style');
419
+ wp_dequeue_style('wobd-jqueryui-style');
420
+ wp_dequeue_style('wpdp-style3');
421
+ wp_dequeue_style('jquery_smoothness_ui');
422
+ wp_dequeue_style('uap_main_admin_style');
423
+ wp_dequeue_style('uap_font_awesome');
424
+ wp_dequeue_style('uap_jquery-ui.min.css');
425
+ } // cleanup_enqueues
426
+
427
+
428
+ /**
429
+ * Add links to plugin's description in plugins table
430
+ *
431
+ * @param array $links Initial list of links.
432
+ * @param string $file Basename of current plugin.
433
+ *
434
+ * @return array
435
+ */
436
+ function plugin_meta_links($links, $file)
437
+ {
438
+ if ($file !== plugin_basename(__FILE__)) {
439
+ return $links;
440
  }
441
 
442
+ $support_link = '<a target="_blank" href="https://wordpress.org/support/plugin/wp-force-ssl/" title="Get help">Support</a>';
443
+ $home_link = '<a target="_blank" href="https://wpforcessl.com/?ref=wpfssl-free" title="Plugin Homepage">Plugin Homepage</a>';
444
+
445
+ $links[] = $support_link;
446
+ $links[] = $home_link;
447
 
448
+ return $links;
449
+ } // plugin_meta_links
450
 
451
 
452
  /**
453
+ * Add action links to plugins table, left part
454
  *
455
+ * @param array $links Initial list of links.
456
+ *
457
+ * @return array
458
+ */
459
+ function plugin_action_links($links)
460
+ {
461
+ $settings_link = '<a href="' . admin_url('options-general.php?page=wpfs-settings') . '" title="Configure SSL settings">Configure SSL</a>';
462
+ $buy_link = '<a href="' . admin_url('options-general.php?page=wpfs-settings#open-pro-dialog') . '" title="Buy the PRO version"><b>Buy PRO</b></a>';
463
+
464
+ array_unshift($links, $buy_link);
465
+ array_unshift($links, $settings_link);
466
+
467
+ return $links;
468
+ } // plugin_action_links
469
+
470
+
471
+ /**
472
+ * Remove all WP notices on WPSSL page
473
  *
474
  * @return null
475
+ */
476
+ function remove_admin_notices()
477
+ {
478
+ if (!$this->is_plugin_page()) {
479
+ return false;
480
+ }
481
+
482
+ global $wp_filter;
483
+ unset($wp_filter['user_admin_notices'], $wp_filter['admin_notices']);
484
+ } // remove_admin_notices
485
+
486
+
487
+ /**
488
+ * Main function for displaying plugin's admin page
489
  *
490
+ * @return null
491
  */
492
+ function settings_page_content()
493
+ {
494
+ // double check for admin privileges
495
+ if (!current_user_can('administrator')) {
496
+ wp_die('Sorry, you are not allowed to access this page.');
497
+ }
498
+
499
+ echo '<header>';
500
+ echo '<img id="logo-icon" src="' . esc_url($this->plugin_url) . 'img/wp-force-ssl-logo.png" title="WP Force SSL" alt="WP Force SSL" />';
501
+ echo '</header>';
502
+
503
+ echo '<div id="wfssl-notifications">';
504
+ echo '</div>';
505
+
506
+ echo '<div class="wfssl-container-left">';
507
+ echo '<div id="wfssl-tabs" class="ui-tabs" style="display: none;">';
508
+ $tabs = array();
509
+
510
+ $tabs[] = array('id' => 'tab_status', 'class' => 'wfssl-tab', 'label' => 'Status', 'callback' => 'tab_status');
511
+ $tabs[] = array('id' => 'tab_settings', 'class' => 'wfssl-tab', 'label' => 'Settings', 'callback' => 'tab_settings');
512
+ $tabs[] = array('id' => 'tab_scanner', 'class' => 'wfssl-tab', 'label' => 'Content Scanner', 'callback' => 'tab_scanner');
513
+ $tabs[] = array('id' => 'tab_ssl', 'class' => 'wfssl-tab', 'label' => 'SSL Certificate', 'callback' => 'tab_ssl');
514
+ $tabs[] = array('id' => 'tab_support', 'class' => 'wfssl-tab', 'label' => 'Support', 'callback' => 'tab_support');
515
+ $tabs[] = array('id' => 'tab_pro', 'class' => 'wfssl-tab wfssl-tab-pro', 'label' => 'PRO', 'callback' => '');
516
+
517
+ echo '<nav>';
518
+ echo '<div class="wfssl-container">';
519
+ echo '<ul class="wfssl-main-tab">';
520
+ foreach ($tabs as $tab) {
521
+ echo '<li id="button-' . esc_attr($tab['id']) . '" class="' . esc_attr($tab['class']) . '"><a href="#' . esc_attr($tab['id']) . '">' . esc_attr($tab['label']) . '</a></li>';
522
+ }
523
+ echo '</ul>';
524
+ echo '</div>'; // container
525
+ echo '</nav>';
526
+
527
+ // tabs
528
+ echo '<div class="wfssl-container">';
529
+
530
+ foreach ($tabs as $tab) {
531
+ if (is_callable(array($this, $tab['callback']))) {
532
+ echo '<div id="' . esc_attr($tab['id']) . '" class="wfssl-tab-content">';
533
+ call_user_func(array($this, $tab['callback']));
534
+ echo '</div>';
535
+ }
536
+ }
537
+
538
+ echo '</div>'; // wfssl-container
539
+ echo '</div>';
540
+ echo '</div>'; // wfssl-container-left
541
+
542
+ echo '<div class="wfssl-container wfssl-container-right">';
543
+ echo '<div class="sidebar-box pro-ad-box">
544
+ <p class="text-center"><a href="https://wpforcessl.com/?ref=wpfssl-free-sidebar-box" target="_blank">
545
+ <img src="' . esc_url($this->plugin_url) . 'img/wp-force-ssl-logo.png" alt="WP Force SSL PRO" title="WP Force SSL PRO"></a><br><b>PRO version</b> is here! Grab the launch discount - <b>all prices are LIFETIME!</b></p>
546
+ <ul class="plain-list">
547
+ <li>15+ Options to Fine-Tune Your SSL</li>
548
+ <li>Mixed Content Scanner + Fixer</li>
549
+ <li>Real-Time SSL &amp; Site monitoring (via our SaaS)</li>
550
+ <li>Generate &amp; Install Free SSL Certificate</li>
551
+ <li>Licenses &amp; Sites Manager (remote SaaS dashboard)</li>
552
+ <li>White-label Mode + Complete Codeless Plugin Rebranding</li>
553
+ <li>Email support from plugin developers</li>
554
+ </ul>
555
+
556
+ <p class="text-center"><a href="#" class="open-pro-dialog button button-buy" data-pro-feature="sidebar-box">Get PRO Now</a></p>
557
+ </div>';
558
+ echo '<div class="sidebar-box" style="margin-top: 35px;">
559
+ <p>Please <a href="https://wordpress.org/support/plugin/wp-force-ssl/reviews/#new-post" target="_blank">rate the plugin ★★★★★</a> to <b>keep it up-to-date &amp; maintained</b>. It only takes a second to rate. Thank you! 👋</p>
560
+ </div>';
561
+ echo '</div>'; // wfssl-container-right
562
+
563
+ wpForceSSL_Utility::wp_kses_wf($this->pro_dialog());
564
  } // settings_page_content
565
 
566
 
567
+ function tab_support()
568
+ {
569
+ echo '<div style="overflow: auto;">
570
+ <div class="wfssl-box">
571
+ <h3>Support</h3>
572
+ <p>Support for the free version is available only via the <a href="https://wordpress.org/support/plugin/wp-force-ssl/" target="_blank">WP repo support forum</a>. If you need email support please <a href="#" class="open-pro-dialog" data-pro-feature="support">upgrade to PRO</a>.</p>';
573
+ echo '</div>';
574
+ echo '</div>';
575
+ echo '<h3>FAQ</h3>
576
+ <div class="wfssl-accordion-wfssl-accordion-tabs">
577
+ <div class="wfssl-accordion-tab">
578
+ <input type="checkbox" id="faq1">
579
+ <label class="wfssl-accordion-tab-label wfssl-fs-18 wfssl-font" for="faq1">Will WP Force SSL slow down my site?</label>
580
+ <div class="wfssl-accordion-tab-content">
581
+ Absolutely not. Everything the plugin does happens in the admin. Nothing is loaded, added, or processed on the front-end so you can rest assured there is no impact on the performance of your site.
582
+ </div>
583
+ </div>
584
+
585
+ <div class="wfssl-accordion-tab">
586
+ <input type="checkbox" id="faq8">
587
+ <label class="wfssl-accordion-tab-label wfssl-fs-18 wfssl-font" for="faq8">I just moved my site to another address, will WP Force SSL help?</label>
588
+ <div class="wfssl-accordion-tab-content">
589
+ Definitely! Especially if you moved from HTTP to HTTPS. The plugin will make sure to properly redirect all your content, check your SSL certificate, and add other security features.
590
+ </div>
591
+ </div>
592
+
593
+ <div class="wfssl-accordion-tab d-none">
594
+ <input type="checkbox" id="faq2">
595
+ <label class="wfssl-accordion-tab-label wfssl-fs-18 wfssl-font" for="faq2">Can you install an SSL certificate for me?</label>
596
+ <div class="wfssl-accordion-tab-content">
597
+ Sorry, at the moment we can\'t. The automatic SSL certificate installation feature is on our to-do and will be available in one of the future versions.
598
+ </div>
599
+ </div>
600
+
601
+ <div class="wfssl-accordion-tab">
602
+ <input type="checkbox" id="faq11">
603
+ <label class="wfssl-accordion-tab-label wfssl-fs-18 wfssl-font" for="faq11">What are the requirements for running SSL on a site?</label>
604
+ <div class="wfssl-accordion-tab-content">There are many but a short answer is "A valid SSL certificate". Please head over to the <a href="#" data-tab="0" class="change-tab">Status</a> tab and see the results. The tests were made specifically to see if a site is ready for SSL.
605
+ </div>
606
+ </div>
607
+
608
+ <div class="wfssl-accordion-tab">
609
+ <input type="checkbox" id="faq4">
610
+ <label class="wfssl-accordion-tab-label wfssl-fs-18 wfssl-font" for="faq4">Is WP Force SSL dangerous for my site?</label>
611
+ <div class="wfssl-accordion-tab-content">
612
+ No, definitely not! The plugin does not make any permanent changes to your site so even if it comes to a worst-case scenario you can just disable the plugin and that will undo all changes.
613
+ </div>
614
+ </div>
615
+
616
+ <div class="wfssl-accordion-tab d-none">
617
+ <input type="checkbox" id="faq5">
618
+ <label class="wfssl-accordion-tab-label wfssl-fs-18 wfssl-font" for="faq5">Can you generate/get an SSL certificate for me?</label>
619
+ <div class="wfssl-accordion-tab-content">
620
+ At the moment no. Sorry. We are already working on a feature that will automatically get a certificate from Let\'s Encrypt and install it on your site but it\'s not ready yet.
621
+ </div>
622
+ </div>
623
+
624
+ <div class="wfssl-accordion-tab">
625
+ <input type="checkbox" id="faq7">
626
+ <label class="wfssl-accordion-tab-label wfssl-fs-18 wfssl-font" for="faq7">Will WP Force SSL modify my files, database or any content?</label>
627
+ <div class="wfssl-accordion-tab-content">
628
+ It will not automatically modify anything. If anything needs permanent changes you\'ll be prompted to double-confirm the change. However, on 90% of sites, all changes are done on the fly so they are not permanent. Disabling the plugin undoes all changes.
629
+ </div>
630
+ </div>
631
+
632
+ <div class="wfssl-accordion-tab">
633
+ <input type="checkbox" id="faq6">
634
+ <label class="wfssl-accordion-tab-label wfssl-fs-18 wfssl-font" for="faq6">When I buy PRO can I manage my licenses and change sites?</label>
635
+ <div class="wfssl-accordion-tab-content">
636
+ Certainly! Purchases, sites, licenses & SSL monitors are managed in the <a href="https://dashboard.wpforcessl.com/" target="_blank">WP Force SSL Dashboard</a>. It\'s a central place to manage all your sites. You can move the licenses (change sites/domains) as much as you need. There are no limits.
637
+ </div>
638
+ </div>
639
+ </div>';
640
+ } // tab_support
641
+
642
+
643
+ function tab_status()
644
+ {
645
+ echo '<div id="status_progress_wrapper" class="wfssl-progress" style="display:none;">
646
+ <div id="status_progress" class="bar orange" style="width:0%">
647
+ <div id="status_progress_text" class="wfssl-progress-text"></div>
648
+ </div>
649
+ </div>
650
+
651
+ <div id="status_tasks" class="wfssl-labels" style="display:none;">
652
+ <div class="status-tasks status-tasks-selected">All tasks</div>
653
+ <div class="status-tasks-remaining">Remaining tasks</div>
654
+ </div>
655
+
656
+ <div id="test-results-wrapper">
657
+ <div class="loading-wrapper">
658
+ <img class="wfssl_flicker" src="' . esc_url($this->plugin_url) . 'img/wp-force-ssl-icon.png' . '" alt="Loading. Please wait." title="Loading. Please wait.">
659
+ <p>Loading. Please wait.</p>
660
+ </div>
661
+ </div>';
662
+ echo '<div class="button button-primary run-tests" style="float: right; display:none;">Run Tests Again</div>';
663
+ } // tab_status
664
+
665
+
666
+ function tab_settings()
667
+ {
668
+ echo '<form id="wpfs_form"><table class="form-table" id="settings-table">';
669
+
670
+ echo '<tr><td>
671
+ <label for="wpfs_ssl">Redirect HTTP requests to HTTPS</label>
672
+ <small>Visitors will be automatically redirected from HTTP to HTTPS for all pages, posts and other WP content. The 301 redirect status is used. Files that are outside of WP, or accessed directly will still be served via HTTP.</small>
673
+ </td><td>';
674
+ wpForceSSL_Utility::create_toogle_switch('wpfs_ssl', array('saved_value' => ($this->options['wpfs_ssl'] == 'yes' ? true : false)));
675
+ echo '</td></tr>';
676
+
677
+ echo '<tr><td>
678
+ <label for="fix_frontend_mixed_content_fixer">Fix mixed content on frontend<span class="pro-feature open-pro-dialog">PRO</span></label>
679
+ <small>Fix mixed content on the frontend on the fly (files and/or database is not changed) by replacing <code>http://</code> with <code>https://</code> for linked resources.</small>
680
+ </td><td>';
681
+ wpForceSSL_Utility::create_toogle_switch('fix_frontend_mixed_content_fixer', array('class' => 'open-pro-dialog', 'saved_value' => false));
682
+ echo '</td></tr>';
683
+
684
+ echo '<tr><td>
685
+ <label for="fix_backend_mixed_content_fixer">Fix mixed content on backend (in WP admin)<span class="pro-feature open-pro-dialog">PRO</span></label>
686
+ <small>Fix mixed content in the backend (WP admin) on the fly (files and/or database is not changed) by replacing <code>http://</code> with <code>https://</code> for linked resources</small>
687
+ </td><td>';
688
+ wpForceSSL_Utility::create_toogle_switch('fix_backend_mixed_content_fixer', array('class' => 'open-pro-dialog', 'saved_value' => false));
689
+ echo '</td></tr>';
690
+
691
+ echo '<tr><td>
692
+ <label for="wpfs_hsts">Enable HSTS</label>
693
+ <small>HSTS (HTTP Strict Transport Security) is a header sent by your website to your visitors\' browser telling it to only use HTTPS to connect to the website. If someone tried to perform a man-in-the-middle attack and redirect the visitor to their own malicious version of the domain the browser will refuse to load the website via HTTP and force them to show a valid SSL certificate for the domain, which they will not have and thus the attack will fail.</small>
694
+ </td><td>';
695
+ wpForceSSL_Utility::create_toogle_switch('wpfs_hsts', array('saved_value' => ($this->options['wpfs_hsts'] == 'yes' ? true : false)));
696
+ echo '</td></tr>';
697
+
698
+ echo '<tr><td>
699
+ <label for="force_secure_cookies">Force Secure Cookies<span class="pro-feature open-pro-dialog">PRO</span></label>
700
+ <small>Cookies are small packets of data stored on your computer by the websites you visit so it remembers information like your logged in state. Most times this information is sensitive, so you should enable this option to harden the way cookies are exchanged with by your browser and to prevent anyone else from reading them.</small>
701
+ </td><td>';
702
+ wpForceSSL_Utility::create_toogle_switch('force_secure_cookies', array('class' => 'open-pro-dialog', 'saved_value' => false));
703
+ echo '</td></tr>';
704
+
705
+ echo '<tr><td>
706
+ <label for="htaccess_301_redirect">Redirect HTTP to HTTPS requests via .htaccess<span class="pro-feature open-pro-dialog">PRO</span></label>
707
+ <small>Redirect all <code>http://</code> requests to <code>https://</code> via .htaccess as soon as the request is received. This is slighly faster than PHP redirect but if your server does not use .htaccess you can use the PHP redirect option too.</small>
708
+ </td><td>';
709
+ wpForceSSL_Utility::create_toogle_switch('htaccess_301_redirect', array('class' => 'open-pro-dialog', 'saved_value' => false));
710
+ echo '</td></tr>';
711
+
712
+ echo '<tr><td>
713
+ <label for="xss_protection">Cross-site scripting (X-XSS) protection<span class="pro-feature open-pro-dialog">PRO</span></label>
714
+ <small>Protects your site from cross-site scripting attacks. If a cross-site scripting attack is detected, the browser will automatically block those requests.</small>
715
+ </td><td>';
716
+ wpForceSSL_Utility::create_toogle_switch('xss_protection', array('class' => 'open-pro-dialog', 'saved_value' => false));
717
+ echo '</td></tr>';
718
+
719
+ echo '<tr><td>
720
+ <label for="x_content_options">X-Content-Type Options<span class="pro-feature open-pro-dialog">PRO</span></label>
721
+ <small>This header prevents MIME-sniffing, which is used to disguise the content type of malicious files being uploaded to the website.</small>
722
+ </td><td>';
723
+ wpForceSSL_Utility::create_toogle_switch('x_content_options', array('class' => 'open-pro-dialog', 'saved_value' => false));
724
+ echo '</td></tr>';
725
+
726
+ echo '<tr><td>
727
+ <label for="referrer_policy">Referrer Policy<span class="pro-feature open-pro-dialog">PRO</span></label>
728
+ <small>To prevent data leakage, only send referrer information when navigating to the same protocol (HTTPS -&gt; HTTPS) and not when downgrading (HTTPS -&gt; HTTP).</small>
729
+ </td><td>';
730
+ wpForceSSL_Utility::create_toogle_switch('referrer_policy', array('class' => 'open-pro-dialog', 'saved_value' => false));
731
+ echo '</td></tr>';
732
+
733
+ echo '<tr><td>
734
+ <label for="wpfs_expect_ct">Expect CT</label>
735
+ <small>Enables the Expect-CT header, requesting that the browser check that the certificate for that site appears in public CT logs.</small>
736
+ </td><td>';
737
+ wpForceSSL_Utility::create_toogle_switch('wpfs_expect_ct', array('saved_value' => ($this->options['wpfs_expect_ct'] == 'yes' ? true : false)));
738
+ echo '</td></tr>';
739
+
740
+ echo '<tr><td>
741
+ <label for="x_frame_options">X-Frame Options<span class="pro-feature open-pro-dialog">PRO</span></label>
742
+ <small>This header prevents your site from being loaded in an iFrame on other domains. This is used to prevent clickjacking attacks. Be sure to enable this option!</small>
743
+ </td><td>';
744
+ wpForceSSL_Utility::create_toogle_switch('x_frame_options', array('class' => 'open-pro-dialog', 'saved_value' => false));
745
+ echo '</td></tr>';
746
+
747
+ echo '<tr><td>
748
+ <label for="permissions_policy">Permissions Policy<span class="pro-feature open-pro-dialog">PRO</span></label>
749
+ <small>The Permissions Policy allows you to specify which browser resources to allow on your site (i.e. microphone, webcam, etc.).</small>
750
+ </td><td>';
751
+ wpForceSSL_Utility::create_toogle_switch('permissions_policy', array('class' => 'open-pro-dialog', 'saved_value' => false));
752
+ echo '</td></tr>';
753
+
754
+ echo '<tr><td>
755
+ <label for="wpfs_adminbar_menu">Show WP Force SSL menu to administrators in admin bar</label>
756
+ <small>When enabled an extra menu will be shown to admins in the admin topbar. Don\'t forget to reload the page after saving to see the change.</small>
757
+ </td><td>';
758
+ wpForceSSL_Utility::create_toogle_switch('wpfs_adminbar_menu', array('saved_value' => ($this->options['wpfs_adminbar_menu'] == 'yes' ? true : false)));
759
+ echo '</td></tr>';
760
+
761
+ echo '</table></form>';
762
+
763
+ echo '<p><a href="#" class="button button-primary save-ssl-options">' . __('Save Settings', 'wp-force-ssl') . '</a></p>';
764
+ } //tab_settings
765
+
766
+
767
+ function tab_scanner()
768
+ {
769
+ echo '<div id="scanner_progress_wrapper" class="wfssl-progress" style="display:none;">
770
+ <div id="scanner_progress" class="bar">
771
+ <div id="scanner_progress_text" class="wfssl-progress-text"></div>
772
+ </div>
773
+ </div>';
774
+ $posts = get_posts(array('post_type' => get_post_types(array('public' => true)), 'numberposts' => 1000));
775
+ echo '<div class="scanner-stats">Total pages to scan: ' . esc_html(number_format(count($posts))) . '</div>';
776
+ echo '<a href="#" class="open-pro-dialog" data-pro-feature="content-scanner"><img class="scanner-preview" src="' . esc_url($this->plugin_url . 'img/content-scanner.jpg') . '" /></a>';
777
+
778
+ echo '<div id="start-scanner" data-pro-feature="start-scanning" class="button button-primary open-pro-dialog">Start Scanning</div>';
779
+ } //tab_scanner
780
+
781
+
782
+ function tab_ssl()
783
+ {
784
+ echo '<h2>SSL Certificate Information</h2>';
785
+ echo '<div id="ssl_cert_details" class="wfssl-box">';
786
+ echo 'Loading certificate information ...<span class="wfssl-green wfssl_rotating dashicons dashicons-update"></span>';
787
+ echo '</div>';
788
+ echo '<div class="clear"></div>';
789
+
790
+ echo '<h2>Real-Time SSL &amp; Site Monitoring<span class="pro-feature">PRO</span></h2>';
791
+ echo '<div id="wfssl-cert-email" class="wfssl-box">';
792
+ echo '<p>Real-time site &amp; SSL certificate monitoring is a <a href="#" data-pro-feature="ssl-monitor-text" class="open-pro-dialog">PRO</a> feature powered by our SaaS that will help you and your clients sleep better. It monitors over 20 common errors related to SSL that can happen at any time. Forgot to renew your certificate? No problem, you\'ll get notified on time. Forgot to change certificate after switching the domain or server? Again, not a problem. You\'ll get notified.</p>';
793
+ echo '<label for="ssl-monitor-toggle">Enable Monitoring</label> &nbsp; ';
794
+ wpForceSSL_Utility::create_toogle_switch('ssl-monitor-toggle', array('class' => 'open-pro-dialog', 'saved_value' => false));
795
+ echo '<div id="wfssl-cert-expiration-email-box">';
796
+ echo '<input id="cert_expiration_email" name="cert_expiration_email" class="wfssl-cert-expiration-email-input open-pro-dialog" data-pro-feature="ssl-monitor-email" type="text" placeholder="Email for notifications" value="" style="height:32px; width:353px; background-color: #fff; margin-bottom: 20px;"><br>';
797
+ echo '<div class="button button-primary open-pro-dialog" data-pro-feature="ssl-monitor-save">Save &amp; Enable Monitoring</div>';
798
+ echo '</div>';
799
+ echo '</div>';
800
+ } // tab_ssl
801
+
802
+
803
  /**
804
  * Perform the redirect to HTTPS if loaded over HTTP
805
  *
811
  public function wpfs_core()
812
  {
813
  if (!is_ssl()) {
814
+ wp_safe_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301);
815
  exit();
816
  }
817
  } // wpfs_core
818
 
819
 
820
  /**
821
+ * Check if minimal WP version required by WP Force SSL is used
822
  *
823
  * @since 1.5
824
  *
863
  } // to_strict_transport_security
864
 
865
 
866
+ /**
867
+ * Send the Expect CT header.
868
+ *
869
+ * @since 1.5
870
+ *
871
+ * @return null
872
+ */
873
+ public function enable_expect_ct()
874
+ {
875
+ header('Expect-CT: max-age=5184000, enforce');
876
+ } // enable_expect_ct
877
+
878
+
879
  /**
880
  * Save plugin settings received via AJAX
881
  *
889
 
890
  $wpfs_ssl = isset($_POST['wpfs_ssl']) ? 'yes' : 'no';
891
  $wpfs_hsts = isset($_POST['wpfs_hsts']) ? 'yes' : 'no';
892
+ $wpfs_expect_ct = isset($_POST['wpfs_expect_ct']) ? 'yes' : 'no';
893
+ $wpfs_adminbar_menu = isset($_POST['wpfs_adminbar_menu']) ? 'yes' : 'no';
894
 
895
  $wpfs_settings = array(
896
  'wpfs_ssl' => $wpfs_ssl,
897
+ 'wpfs_hsts' => $wpfs_hsts,
898
+ 'wpfs_expect_ct' => $wpfs_expect_ct,
899
+ 'wpfs_adminbar_menu' => $wpfs_adminbar_menu
900
  );
901
  update_option(WPFSSL_OPTIONS_KEY, $wpfs_settings);
902
 
913
  */
914
  public function ajax_check_ssl()
915
  {
916
+ global $wp_force_ssl_tests;
917
 
918
+ check_ajax_referer('test_ssl_nonce_action');
 
 
 
 
 
919
 
920
+ if (isset($_REQUEST['force']) && (bool)$_REQUEST['force'] === true) {
921
+ $nocache = true;
 
 
 
 
922
  } else {
923
+ $nocache = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
924
  }
925
+ $status = $wp_force_ssl_tests->get_ssl_status($nocache);
926
 
927
+ wp_send_json_success($status);
928
+ } // check_ssl
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
929
 
930
  /**
931
  * Check if currently on WP Force SSL settings page
960
  return $text_org;
961
  }
962
 
963
+ $text = '<i><a target="_blank" href="https://wpforcessl.com/?ref=wpfssl-free">WP Force SSL</a> v' . $this->version . ' by <a href="https://www.webfactoryltd.com/" title="' . __('Visit our site to get more great plugins', 'wp-force-ssl') . '" target="_blank">WebFactory Ltd</a>.';
964
  $text .= ' Please <a target="_blank" href="https://wordpress.org/support/plugin/wp-force-ssl/reviews/#new-post" title="' . __('Rate the plugin', 'wp-force-ssl') . '">' . __('Rate the plugin ★★★★★', 'wp-force-ssl') . '</a>.</i> ';
965
  return $text;
966
  } // admin_footer_text
967
 
968
 
969
+ function pro_dialog()
 
 
 
 
 
 
 
970
  {
971
+ $out = '';
972
+
973
+ $out .= '<div id="wpfssl-pro-dialog" style="display: none;" title="WP Force SSL PRO is here!"><span class="ui-helper-hidden-accessible"><input type="text"/></span>';
974
+
975
+ $out .= '<div class="center logo"><a href="https://wpforcessl.com/?ref=wpfssl-free-pricing-table" target="_blank"><img src="' . $this->plugin_url . 'img/wp-force-ssl-logo.png' . '" alt="WP Force SSL PRO" title="WP Force SSL PRO"></a><br>';
976
+
977
+ $out .= '<span>Limited PRO Launch Discount - <b>all prices are LIFETIME</b>! Pay once &amp; use forever!</span>';
978
+ $out .= '</div>';
979
+
980
+ $out .= '<table id="wpfssl-pro-table">';
981
+ $out .= '<tr>';
982
+ $out .= '<td class="center">Lifetime Personal License</td>';
983
+ $out .= '<td class="center">Lifetime Team License</td>';
984
+ $out .= '<td class="center">Lifetime Agency License</td>';
985
+ $out .= '</tr>';
986
+
987
+ $out .= '<tr class="prices">';
988
+ $out .= '<td class="center"><del>$49 /year</del><br><span>$59</span> <b>/lifetime</b></td>';
989
+ $out .= '<td class="center"><del>$89 /year</del><br><span>$89</span> <b>/lifetime</b></td>';
990
+ $out .= '<td class="center"><del>$199 /year</del><br><span>$119</span> <b>/lifetime</b></td>';
991
+ $out .= '</tr>';
992
+
993
+ $out .= '<tr>';
994
+ $out .= '<td><span class="dashicons dashicons-yes"></span><b>1 Site License</b></td>';
995
+ $out .= '<td><span class="dashicons dashicons-yes"></span><b>5 Sites License</b></td>';
996
+ $out .= '<td><span class="dashicons dashicons-yes"></span><b>100 Sites License</b></td>';
997
+ $out .= '</tr>';
998
+
999
+ $out .= '<tr>';
1000
+ $out .= '<td><span class="dashicons dashicons-yes"></span>All Plugin Features</td>';
1001
+ $out .= '<td><span class="dashicons dashicons-yes"></span>All Plugin Features</td>';
1002
+ $out .= '<td><span class="dashicons dashicons-yes"></span>All Plugin Features</td>';
1003
+ $out .= '</tr>';
1004
+
1005
+ $out .= '<tr>';
1006
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Lifetime Updates &amp; Support</td>';
1007
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Lifetime Updates &amp; Support</td>';
1008
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Lifetime Updates &amp; Support</td>';
1009
+ $out .= '</tr>';
1010
+
1011
+ $out .= '<tr>';
1012
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Content Scanner</td>';
1013
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Content Scanner</td>';
1014
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Content Scanner</td>';
1015
+ $out .= '</tr>';
1016
+
1017
+ $out .= '<tr>';
1018
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Real-Time SSL &amp; Site Monitoring</td>';
1019
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Real-Time SSL &amp; Site Monitoring</td>';
1020
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Real-Time SSL &amp; Site Monitoring</td>';
1021
+ $out .= '</tr>';
1022
+
1023
+ $out .= '<tr>';
1024
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Free SSL Certificate Generating</td>';
1025
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Free SSL Certificate Generating</td>';
1026
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Free SSL Certificate Generating</td>';
1027
+ $out .= '</tr>';
1028
+
1029
+ $out .= '<tr>';
1030
+ $out .= '<td><span class="dashicons dashicons-no"></span>Licenses &amp; Sites Manager</td>';
1031
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Licenses &amp; Sites Manager</td>';
1032
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Licenses &amp; Sites Manager</td>';
1033
+ $out .= '</tr>';
1034
+
1035
+ $out .= '<tr>';
1036
+ $out .= '<td><span class="dashicons dashicons-no"></span>White-label Mode</td>';
1037
+ $out .= '<td><span class="dashicons dashicons-yes"></span>White-label Mode</td>';
1038
+ $out .= '<td><span class="dashicons dashicons-yes"></span>White-label Mode</td>';
1039
+ $out .= '</tr>';
1040
+
1041
+ $out .= '<tr>';
1042
+ $out .= '<td><span class="dashicons dashicons-no"></span>Full Plugin Rebranding</td>';
1043
+ $out .= '<td><span class="dashicons dashicons-no"></span>Full Plugin Rebranding</td>';
1044
+ $out .= '<td><span class="dashicons dashicons-yes"></span>Full Plugin Rebranding</td>';
1045
+ $out .= '</tr>';
1046
+
1047
+ $out .= '<tr>';
1048
+ $out .= '<td><a class="button button-buy" data-href-org="https://wpforcessl.com/buy/?product=personal-launch&ref=pricing-table" href="https://wpforcessl.com/buy/?product=personal-launch&ref=pricing-table" target="_blank">Lifetime License<br>$59 -&gt; BUY NOW</a>
1049
+ <br>or <a class="button-buy" data-href-org="https://wpforcessl.com/buy/?product=personal-monthly&ref=pricing-table" href="https://wpforcessl.com/buy/?product=personal-monthly&ref=pricing-table" target="_blank">only $6.99 <small>/month</small></a></td>';
1050
+ $out .= '<td><a class="button button-buy" data-href-org="https://wpforcessl.com/buy/?product=team-launch&ref=pricing-table" href="https://wpforcessl.com/buy/?product=team-launch&ref=pricing-table" target="_blank">Lifetime License<br>$69 -&gt; BUY NOW</a></td>';
1051
+ $out .= '<td><a class="button button-buy" data-href-org="https://wpforcessl.com/buy/?product=agency-launch&ref=pricing-table" href="https://wpforcessl.com/buy/?product=agency-launch&ref=pricing-table" target="_blank">Lifetime License<br>$99 -&gt; BUY NOW</a></td>';
1052
+ $out .= '</tr>';
1053
+
1054
+ $out .= '</table>';
1055
+
1056
+ $out .= '<div class="center footer"><b>100% No-Risk Money Back Guarantee!</b> If you don\'t like the plugin over the next 7 days, we will happily refund 100% of your money. No questions asked! Payments are processed by our merchant of records - <a href="https://paddle.com/" target="_blank">Paddle</a>.</div></div>';
1057
 
 
1058
  return $out;
1059
+ } // pro_dialog
1060
 
1061
 
1062
  /**
1063
+ * Clean-up on delete
1064
  *
1065
  * @since 1.5
1066
  *
1067
  * @return null
1068
  */
1069
+ public static function uninstall()
1070
  {
1071
+ delete_option(WPFSSL_OPTIONS_KEY);
1072
+ delete_option(WPFSSL_META_KEY);
1073
+ } // uninstall
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1074
 
1075
 
1076
  /**
1077
+ * Reset on deactivate
 
 
1078
  *
1079
  * @return null
1080
  */
1081
+ public static function deactivate()
1082
  {
1083
+ $meta = get_option(WPFSSL_META_KEY, array());
1084
+ $meta['hide_welcome_pointer'] = false;
1085
+ update_option(WPFSSL_META_KEY, $meta);
1086
+ } // deactivate
1087
 
1088
 
1089
  /**
1094
  * @return null
1095
  */
1096
  private function __clone()
1097
+ {
1098
+ }
1099
 
1100
 
1101
  /**
1106
  * @return null
1107
  */
1108
  public function __sleep()
1109
+ {
1110
+ }
1111
 
1112
 
1113
  /**
1118
  * @return null
1119
  */
1120
  public function __wakeup()
1121
+ {
1122
+ }
1123
  // end class
1124
  }
1125
 
1126
 
1127
+ $wpfs = wpForceSSL::get_instance();
1128
  add_action('plugins_loaded', array($wpfs, 'plugins_loaded'));
1129
+ register_deactivation_hook(__FILE__, array('wpForceSSL', 'deactivate'));
 
1130
  register_uninstall_hook(__FILE__, array('wpForceSSL', 'uninstall'));