Post Views Counter - Version 1.1.3

Version Description

  • Fix: Duplicated views count in custom post types
  • Fix: Exclude visitors checkboxes not working
Download this release

Release Info

Developer dfactory
Plugin Icon 128x128 Post Views Counter
Version 1.1.3
Comparing to
See all releases

Code changes from version 1.1.2 to 1.1.3

css/admin.css CHANGED
@@ -1,489 +1,489 @@
1
- /* Post Views Counter settings */
2
- .post-views-counter-settings {
3
- margin-right: 300px;
4
- }
5
-
6
- .post-views-counter-settings form {
7
- float: left;
8
- min-width: 463px;
9
- width: auto;
10
- }
11
-
12
- .post-views-counter-settings fieldset .description {
13
- font-size: 13px;
14
- margin-bottom: 8px;
15
- margin-top: 4px;
16
- display: block;
17
- }
18
-
19
- .post-views-counter-settings p.help, .post-views-counter-settings p.description, .post-views-counter-settings span.description {
20
- font-size: 13px;
21
- font-style: italic;
22
- }
23
-
24
- .post-views-counter-settings div.ip-box {
25
- margin-bottom: 3px;
26
- }
27
-
28
- .df-credits {
29
- float: right;
30
- width: 280px;
31
- background: #fff;
32
- margin: 20px -300px 20px 20px;
33
- position: relative;
34
- box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05);
35
- }
36
-
37
- .df-credits .inner {
38
- padding-left: 10px;
39
- padding-right: 10px;
40
- }
41
-
42
- .df-credits h3 {
43
- font-size: 14px;
44
- line-height: 1.4;
45
- margin: 0;
46
- padding: 8px 12px;
47
- border-bottom: 1px solid #eee;
48
- }
49
-
50
- .df-credits .df-link {
51
- font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif;
52
- font-style: italic;
53
- padding-bottom: 10px;
54
- margin: 0;
55
- }
56
-
57
- .df-credits .df-link a {
58
- vertical-align: middle;
59
- padding: 5px 0 0 4px;
60
- }
61
-
62
- .df-credits hr {
63
- border: solid #eee;
64
- border-width: 1px 0 0;
65
- clear: both;
66
- height: 0;
67
- }
68
-
69
- /* Single post edit screen */
70
- #misc-publishing-actions #post-views #post-views-display:before {
71
- display: inline-block;
72
- font: 400 20px/1 dashicons;
73
- left: -1px;
74
- padding: 0 2px 0 0;
75
- position: relative;
76
- text-decoration: none !important;
77
- vertical-align: top;
78
- color: #888;
79
- content: "\f185";
80
- top: -1px;
81
- }
82
-
83
- /* Listing edit screen */
84
- .edit-php .widefat th#post_views {
85
- width: 5.5em;
86
- }
87
- .edit-php .widefat th.column-post_views .dashicons,
88
- .edit-php .widefat th.column-post_views .dashicons:before {
89
- font-size: 1.1em;
90
- vertical-align: middle;
91
- }
92
- .edit-php .widefat th .dash-title {
93
- display:none;
94
- }
95
- .edit-php .metabox-prefs .dash-icon {
96
- display:none;
97
- }
98
- .edit-php .widefat td .dashicons,
99
- .edit-php .widefat td .dashicons:before {
100
- font-size: 1.1em;
101
- }
102
- .edit-php #inline-edit-post_views input {
103
- width: auto;
104
- }
105
-
106
- /*
107
- * checkBo lightweight jQuery plugin v0.1.4 by @ElmahdiMahmoud
108
- * Licensed under the MIT license - https://github.com/elmahdim/checkbo/blob/master/LICENSE
109
- *
110
- * Custom checkbox and radio
111
- * Author URL: elmahdim.com
112
- */
113
- .cb-checkbox .cb-inner, .cb-checkbox i {
114
- width:18px;
115
- height:18px;
116
- -moz-border-radius:3px;
117
- -webkit-border-radius:3px;
118
- border-radius:3px
119
- }
120
- .cb-checkbox.cb-sm i, .cb-checkbox.cb-sm .cb-inner {
121
- width:14px;
122
- height:14px
123
- }
124
- .cb-checkbox.cb-md i, .cb-checkbox.cb-md .cb-inner {
125
- width:24px;
126
- height:24px;
127
- -moz-border-radius:4px;
128
- -webkit-border-radius:4px;
129
- border-radius:4px
130
- }
131
- .cb-checkbox.cb-lg i, .cb-checkbox.cb-lg .cb-inner {
132
- width:30px;
133
- height:30px;
134
- -moz-border-radius:6px;
135
- -webkit-border-radius:6px;
136
- border-radius:6px
137
- }
138
- .cb-radio .cb-inner {
139
- width:18px;
140
- height:18px
141
- }
142
- .cb-radio.cb-sm .cb-inner {
143
- width:14px;
144
- height:14px
145
- }
146
- .cb-radio.cb-md .cb-inner {
147
- width:24px;
148
- height:24px
149
- }
150
- .cb-radio.cb-lg .cb-inner {
151
- width:30px;
152
- height:30px
153
- }
154
- .cb-checkbox, .cb-radio {
155
- color:inherit;
156
- cursor:pointer;
157
- overflow:hidden;
158
- font-size:inherit;
159
- font-weight:normal;
160
- display:inline-block;
161
- line-height:18px;
162
- margin-right: 8px;
163
- }
164
- .form-table td fieldset label.cb-checkbox,
165
- .form-table td fieldset label.cb-radio {
166
- margin-right: 8px !important;
167
- }
168
- .cb-checkbox.disabled, .cb-checkbox.disabled *, .cb-radio.disabled, .cb-radio.disabled * {
169
- cursor:default
170
- }
171
- .cb-checkbox input[type="checkbox"], .cb-radio input[type="radio"], .cb-switcher input[type="checkbox"], .cb-switcher input[type="radio"] {
172
- display:none
173
- }
174
- .cb-checkbox.disabled, .cb-checkbox.disabled *, .cb-radio.disabled, .cb-radio.disabled *, .cb-switcher.disabled, .cb-switcher.disabled * {
175
- cursor:default
176
- }
177
- .cb-checkbox.disabled {
178
- color:#ddd
179
- }
180
- .cb-checkbox.disabled .cb-inner {
181
- color:#ddd
182
- }
183
- .cb-checkbox.disabled:hover .cb-inner {
184
- border-color:#ddd
185
- }
186
- .cb-checkbox.disabled.checked .cb-inner {
187
- background-color:#ddd;
188
- border-color:#ddd
189
- }
190
- .cb-radio.disabled {
191
- color:#ddd
192
- }
193
- .cb-radio.disabled .cb-inner {
194
- border-color:#ddd
195
- }
196
- .cb-radio.disabled i {
197
- background-color:transparent
198
- }
199
- .cb-radio.disabled.checked .cb-inner {
200
- border-color:#ddd
201
- }
202
- .cb-radio.disabled.checked .cb-inner i {
203
- background-color:#ddd
204
- }
205
- .cb-radio.disabled:hover .cb-inner {
206
- border-color:#ddd
207
- }
208
- .cb-checkbox .cb-inner {
209
- float:left;
210
- overflow:hidden;
211
- margin:0 5px 0 0;
212
- position:relative;
213
- background:#f2f2f2;
214
- display:inline-block;
215
- border:1px solid #d6d6d6;
216
- -moz-transition:all 0.5s ease;
217
- -o-transition:all 0.5s ease;
218
- -webkit-transition:all 0.5s ease;
219
- transition:all 0.5s ease
220
- }
221
- .cb-checkbox i {
222
- top:1px;
223
- left:2px;
224
- display:block;
225
- position:absolute
226
- }
227
- .cb-checkbox i:before, .cb-checkbox i:after {
228
- height:0;
229
- width:2px;
230
- content:"";
231
- display:block;
232
- position:absolute;
233
- background-color:#fff;
234
- -moz-transition:all 0.2s ease;
235
- -o-transition:all 0.2s ease;
236
- -webkit-transition:all 0.2s ease;
237
- transition:all 0.2s ease
238
- }
239
- .cb-checkbox i:before {
240
- top:0;
241
- left:0;
242
- -moz-transform:rotate(-45deg);
243
- -ms-transform:rotate(-45deg);
244
- -webkit-transform:rotate(-45deg);
245
- transform:rotate(-45deg)
246
- }
247
- .cb-checkbox i:after {
248
- left:7px;
249
- bottom:5px;
250
- -moz-transition-delay:0.3s;
251
- -o-transition-delay:0.3s;
252
- -webkit-transition-delay:0.3s;
253
- transition-delay:0.3s;
254
- -moz-transform:rotate(30deg);
255
- -ms-transform:rotate(30deg);
256
- -webkit-transform:rotate(30deg);
257
- transform:rotate(30deg)
258
- }
259
- .cb-radio .cb-inner {
260
- float:left;
261
- overflow:hidden;
262
- margin:0 5px 0 0;
263
- position:relative;
264
- display:inline-block;
265
- border:1px solid #d7d7d7;
266
- background-color:#f2f2f2;
267
- -moz-border-radius:100%;
268
- -webkit-border-radius:100%;
269
- border-radius:100%;
270
- -moz-transition:all 0.1s ease;
271
- -o-transition:all 0.1s ease;
272
- -webkit-transition:all 0.1s ease;
273
- transition:all 0.1s ease
274
- }
275
- .cb-radio i {
276
- top:50%;
277
- left:50%;
278
- width:6px;
279
- height:6px;
280
- margin-top:-3px;
281
- margin-left:-3px;
282
- position:absolute;
283
- background-color:transparent;
284
- -moz-border-radius:100%;
285
- -webkit-border-radius:100%;
286
- border-radius:100%;
287
- -moz-transform:scale(0.05, 5);
288
- -ms-transform:scale(0.05, 5);
289
- -webkit-transform:scale(0.05, 5);
290
- transform:scale(0.05, 5);
291
- -moz-transition:all 0.2s ease;
292
- -o-transition:all 0.2s ease;
293
- -webkit-transition:all 0.2s ease;
294
- transition:all 0.2s ease
295
- }
296
- .cb-checkbox.cb-sm, .cb-radio.cb-sm {
297
- line-height:14px
298
- }
299
- .cb-checkbox.cb-md, .cb-radio.cb-md {
300
- line-height:24px
301
- }
302
- .cb-checkbox.cb-lg, .cb-radio.cb-lg {
303
- line-height:30px
304
- }
305
- .cb-checkbox.cb-sm i:before {
306
- top:4px;
307
- left:1px
308
- }
309
- .cb-checkbox.cb-sm i:after {
310
- left:5px
311
- }
312
- .cb-checkbox.cb-md i:before {
313
- top:10px;
314
- left:5px
315
- }
316
- .cb-checkbox.cb-md i:after {
317
- bottom:6px;
318
- left:11px
319
- }
320
- .cb-checkbox.checked .cb-inner {
321
- border-color:#0073aa;
322
- background-color:#00a0d2;
323
- box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15);
324
- }
325
- .cb-checkbox.checked:hover .cb-inner {
326
- background-color:#0091cd
327
- }
328
- .cb-checkbox.checked.cb-sm i:before {
329
- top:4px;
330
- left:1px
331
- }
332
- .cb-checkbox.checked.cb-sm i:after {
333
- height:9px
334
- }
335
- .cb-checkbox.checked.cb-md i:before {
336
- top:10px;
337
- left:4px;
338
- height:8px
339
- }
340
- .cb-checkbox.checked.cb-md i:after {
341
- bottom:6px;
342
- left:11px;
343
- height:16px
344
- }
345
- .cb-checkbox.checked.cb-lg i:before {
346
- top:11px;
347
- left:6px;
348
- height:12px
349
- }
350
- .cb-checkbox.checked.cb-lg i:after {
351
- left:14px;
352
- bottom:7px;
353
- height:20px
354
- }
355
- .cb-checkbox.checked i:before {
356
- top:6px;
357
- left:2px;
358
- height:6px
359
- }
360
- .cb-checkbox.checked i:after {
361
- height:12px
362
- }
363
- .cb-radio.checked .cb-inner {
364
- background:#fff;
365
- box-shadow:0 0 3px #efefef
366
- }
367
- .cb-radio.checked i {
368
- -moz-transform:scale(1.1, 1.1);
369
- -ms-transform:scale(1.1, 1.1);
370
- -webkit-transform:scale(1.1, 1.1);
371
- transform:scale(1.1, 1.1);
372
- background-color:#00a0d2
373
- }
374
- .cb-checkbox:hover .cb-inner, .cb-radio:hover .cb-inner {
375
- border-color:#0073aa
376
- }
377
- .cb-switcher {
378
- display:inline-block;
379
- border:1px solid #eee;
380
- background-color:#fff;
381
- width:95px;
382
- height:35px;
383
- position:relative;
384
- -moz-border-radius:20px;
385
- -webkit-border-radius:20px;
386
- border-radius:20px;
387
- -moz-transition:background 0.4s ease;
388
- -o-transition:background 0.4s ease;
389
- -webkit-transition:background 0.4s ease;
390
- transition:background 0.4s ease
391
- }
392
- .cb-switcher, .cb-switcher * {
393
- cursor:pointer
394
- }
395
- .cb-switcher ::-moz-selection {
396
- background-color:transparent
397
- }
398
- .cb-switcher ::selection {
399
- background-color:transparent
400
- }
401
- .cb-switcher .cb-state {
402
- z-index:1;
403
- text-align:center;
404
- font-size:12px
405
- }
406
- .cb-switcher .cb-state, .cb-switcher:before {
407
- width:34px;
408
- height:34px;
409
- line-height:34px;
410
- position:absolute;
411
- left:0;
412
- top:-1px;
413
- -moz-border-radius:100%;
414
- -webkit-border-radius:100%;
415
- border-radius:100%;
416
- -moz-transition:all 0.4s ease;
417
- -o-transition:all 0.4s ease;
418
- -webkit-transition:all 0.4s ease;
419
- transition:all 0.4s ease
420
- }
421
- .cb-switcher:before {
422
- content:"";
423
- background-color:#eee;
424
- -moz-box-shadow:1px 1px 1px rgba(0, 0, 0, 0.1);
425
- -webkit-box-shadow:1px 1px 1px rgba(0, 0, 0, 0.1);
426
- box-shadow:1px 1px 1px rgba(0, 0, 0, 0.1)
427
- }
428
- .cb-switcher.checked {
429
- background-color:#00a0d2
430
- }
431
- .cb-switcher.checked .cb-state, .cb-switcher.checked:before {
432
- left:60px;
433
- color:#00a0d2
434
- }
435
- .cb-switcher.checked:before {
436
- background-color:#fff;
437
- -moz-box-shadow:-1px 1px 1px rgba(0, 0, 0, 0.1);
438
- -webkit-box-shadow:-1px 1px 1px rgba(0, 0, 0, 0.1);
439
- box-shadow:-1px 1px 1px rgba(0, 0, 0, 0.1)
440
- }
441
- .cb-switcher.checked .inner-switcher:before {
442
- border-top-color:#0073aa
443
- }
444
- .cb-switcher.checked .inner-switcher:after {
445
- border-bottom-color:#0073aa
446
- }
447
- .cb-switcher .inner-switcher:before, .cb-switcher .inner-switcher:after {
448
- content:"";
449
- position:absolute;
450
- left:50%;
451
- width:0;
452
- height:0;
453
- z-index:2;
454
- margin-left:-20px;
455
- border-left:20px solid transparent;
456
- border-right:20px solid transparent;
457
- -moz-transition:border 0.4s ease;
458
- -o-transition:border 0.4s ease;
459
- -webkit-transition:border 0.4s ease;
460
- transition:border 0.4s ease
461
- }
462
- .cb-switcher .inner-switcher:before {
463
- border-top:17px solid #fff;
464
- top:0
465
- }
466
- .cb-switcher .inner-switcher:after {
467
- border-bottom:17px solid #fff;
468
- bottom:0
469
- }
470
- .cb-state {
471
- color:#ccc;
472
- display:inline-block
473
- }
474
- .cb-switcher-group .cb-state {
475
- position:relative;
476
- top:7px
477
- }
478
- .is-hidden {
479
- display:none !important;
480
- visibility:hidden !important
481
- }
482
- output {
483
- display: block;
484
- font-size: 30px;
485
- font-weight: bold;
486
- text-align: center;
487
- margin: 30px 0;
488
- width: 100%;
489
  }
1
+ /* Post Views Counter settings */
2
+ .post-views-counter-settings {
3
+ margin-right: 300px;
4
+ }
5
+
6
+ .post-views-counter-settings form {
7
+ float: left;
8
+ min-width: 463px;
9
+ width: auto;
10
+ }
11
+
12
+ .post-views-counter-settings fieldset .description {
13
+ font-size: 13px;
14
+ margin-bottom: 8px;
15
+ margin-top: 4px;
16
+ display: block;
17
+ }
18
+
19
+ .post-views-counter-settings p.help, .post-views-counter-settings p.description, .post-views-counter-settings span.description {
20
+ font-size: 13px;
21
+ font-style: italic;
22
+ }
23
+
24
+ .post-views-counter-settings div.ip-box {
25
+ margin-bottom: 3px;
26
+ }
27
+
28
+ .df-credits {
29
+ float: right;
30
+ width: 280px;
31
+ background: #fff;
32
+ margin: 20px -300px 20px 20px;
33
+ position: relative;
34
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05);
35
+ }
36
+
37
+ .df-credits .inner {
38
+ padding-left: 10px;
39
+ padding-right: 10px;
40
+ }
41
+
42
+ .df-credits h3 {
43
+ font-size: 14px;
44
+ line-height: 1.4;
45
+ margin: 0;
46
+ padding: 8px 12px;
47
+ border-bottom: 1px solid #eee;
48
+ }
49
+
50
+ .df-credits .df-link {
51
+ font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif;
52
+ font-style: italic;
53
+ padding-bottom: 10px;
54
+ margin: 0;
55
+ }
56
+
57
+ .df-credits .df-link a {
58
+ vertical-align: middle;
59
+ padding: 5px 0 0 4px;
60
+ }
61
+
62
+ .df-credits hr {
63
+ border: solid #eee;
64
+ border-width: 1px 0 0;
65
+ clear: both;
66
+ height: 0;
67
+ }
68
+
69
+ /* Single post edit screen */
70
+ #misc-publishing-actions #post-views #post-views-display:before {
71
+ display: inline-block;
72
+ font: 400 20px/1 dashicons;
73
+ left: -1px;
74
+ padding: 0 2px 0 0;
75
+ position: relative;
76
+ text-decoration: none !important;
77
+ vertical-align: top;
78
+ color: #888;
79
+ content: "\f185";
80
+ top: -1px;
81
+ }
82
+
83
+ /* Listing edit screen */
84
+ .edit-php .widefat th#post_views {
85
+ width: 5.5em;
86
+ }
87
+ .edit-php .widefat th.column-post_views .dashicons,
88
+ .edit-php .widefat th.column-post_views .dashicons:before {
89
+ font-size: 1.1em;
90
+ vertical-align: middle;
91
+ }
92
+ .edit-php .widefat th .dash-title {
93
+ display:none;
94
+ }
95
+ .edit-php .metabox-prefs .dash-icon {
96
+ display:none;
97
+ }
98
+ .edit-php .widefat td .dashicons,
99
+ .edit-php .widefat td .dashicons:before {
100
+ font-size: 1.1em;
101
+ }
102
+ .edit-php #inline-edit-post_views input {
103
+ width: auto;
104
+ }
105
+
106
+ /*
107
+ * checkBo lightweight jQuery plugin v0.1.4 by @ElmahdiMahmoud
108
+ * Licensed under the MIT license - https://github.com/elmahdim/checkbo/blob/master/LICENSE
109
+ *
110
+ * Custom checkbox and radio
111
+ * Author URL: elmahdim.com
112
+ */
113
+ .cb-checkbox .cb-inner, .cb-checkbox i {
114
+ width:18px;
115
+ height:18px;
116
+ -moz-border-radius:3px;
117
+ -webkit-border-radius:3px;
118
+ border-radius:3px
119
+ }
120
+ .cb-checkbox.cb-sm i, .cb-checkbox.cb-sm .cb-inner {
121
+ width:14px;
122
+ height:14px
123
+ }
124
+ .cb-checkbox.cb-md i, .cb-checkbox.cb-md .cb-inner {
125
+ width:24px;
126
+ height:24px;
127
+ -moz-border-radius:4px;
128
+ -webkit-border-radius:4px;
129
+ border-radius:4px
130
+ }
131
+ .cb-checkbox.cb-lg i, .cb-checkbox.cb-lg .cb-inner {
132
+ width:30px;
133
+ height:30px;
134
+ -moz-border-radius:6px;
135
+ -webkit-border-radius:6px;
136
+ border-radius:6px
137
+ }
138
+ .cb-radio .cb-inner {
139
+ width:18px;
140
+ height:18px
141
+ }
142
+ .cb-radio.cb-sm .cb-inner {
143
+ width:14px;
144
+ height:14px
145
+ }
146
+ .cb-radio.cb-md .cb-inner {
147
+ width:24px;
148
+ height:24px
149
+ }
150
+ .cb-radio.cb-lg .cb-inner {
151
+ width:30px;
152
+ height:30px
153
+ }
154
+ .cb-checkbox, .cb-radio {
155
+ color:inherit;
156
+ cursor:pointer;
157
+ overflow:hidden;
158
+ font-size:inherit;
159
+ font-weight:normal;
160
+ display:inline-block;
161
+ line-height:18px;
162
+ margin-right: 8px;
163
+ }
164
+ .form-table td fieldset label.cb-checkbox,
165
+ .form-table td fieldset label.cb-radio {
166
+ margin-right: 8px !important;
167
+ }
168
+ .cb-checkbox.disabled, .cb-checkbox.disabled *, .cb-radio.disabled, .cb-radio.disabled * {
169
+ cursor:default
170
+ }
171
+ .cb-checkbox input[type="checkbox"], .cb-radio input[type="radio"], .cb-switcher input[type="checkbox"], .cb-switcher input[type="radio"] {
172
+ display:none
173
+ }
174
+ .cb-checkbox.disabled, .cb-checkbox.disabled *, .cb-radio.disabled, .cb-radio.disabled *, .cb-switcher.disabled, .cb-switcher.disabled * {
175
+ cursor:default
176
+ }
177
+ .cb-checkbox.disabled {
178
+ color:#ddd
179
+ }
180
+ .cb-checkbox.disabled .cb-inner {
181
+ color:#ddd
182
+ }
183
+ .cb-checkbox.disabled:hover .cb-inner {
184
+ border-color:#ddd
185
+ }
186
+ .cb-checkbox.disabled.checked .cb-inner {
187
+ background-color:#ddd;
188
+ border-color:#ddd
189
+ }
190
+ .cb-radio.disabled {
191
+ color:#ddd
192
+ }
193
+ .cb-radio.disabled .cb-inner {
194
+ border-color:#ddd
195
+ }
196
+ .cb-radio.disabled i {
197
+ background-color:transparent
198
+ }
199
+ .cb-radio.disabled.checked .cb-inner {
200
+ border-color:#ddd
201
+ }
202
+ .cb-radio.disabled.checked .cb-inner i {
203
+ background-color:#ddd
204
+ }
205
+ .cb-radio.disabled:hover .cb-inner {
206
+ border-color:#ddd
207
+ }
208
+ .cb-checkbox .cb-inner {
209
+ float:left;
210
+ overflow:hidden;
211
+ margin:0 5px 0 0;
212
+ position:relative;
213
+ background:#f2f2f2;
214
+ display:inline-block;
215
+ border:1px solid #d6d6d6;
216
+ -moz-transition:all 0.5s ease;
217
+ -o-transition:all 0.5s ease;
218
+ -webkit-transition:all 0.5s ease;
219
+ transition:all 0.5s ease
220
+ }
221
+ .cb-checkbox i {
222
+ top:1px;
223
+ left:2px;
224
+ display:block;
225
+ position:absolute
226
+ }
227
+ .cb-checkbox i:before, .cb-checkbox i:after {
228
+ height:0;
229
+ width:2px;
230
+ content:"";
231
+ display:block;
232
+ position:absolute;
233
+ background-color:#fff;
234
+ -moz-transition:all 0.2s ease;
235
+ -o-transition:all 0.2s ease;
236
+ -webkit-transition:all 0.2s ease;
237
+ transition:all 0.2s ease
238
+ }
239
+ .cb-checkbox i:before {
240
+ top:0;
241
+ left:0;
242
+ -moz-transform:rotate(-45deg);
243
+ -ms-transform:rotate(-45deg);
244
+ -webkit-transform:rotate(-45deg);
245
+ transform:rotate(-45deg)
246
+ }
247
+ .cb-checkbox i:after {
248
+ left:7px;
249
+ bottom:5px;
250
+ -moz-transition-delay:0.3s;
251
+ -o-transition-delay:0.3s;
252
+ -webkit-transition-delay:0.3s;
253
+ transition-delay:0.3s;
254
+ -moz-transform:rotate(30deg);
255
+ -ms-transform:rotate(30deg);
256
+ -webkit-transform:rotate(30deg);
257
+ transform:rotate(30deg)
258
+ }
259
+ .cb-radio .cb-inner {
260
+ float:left;
261
+ overflow:hidden;
262
+ margin:0 5px 0 0;
263
+ position:relative;
264
+ display:inline-block;
265
+ border:1px solid #d7d7d7;
266
+ background-color:#f2f2f2;
267
+ -moz-border-radius:100%;
268
+ -webkit-border-radius:100%;
269
+ border-radius:100%;
270
+ -moz-transition:all 0.1s ease;
271
+ -o-transition:all 0.1s ease;
272
+ -webkit-transition:all 0.1s ease;
273
+ transition:all 0.1s ease
274
+ }
275
+ .cb-radio i {
276
+ top:50%;
277
+ left:50%;
278
+ width:6px;
279
+ height:6px;
280
+ margin-top:-3px;
281
+ margin-left:-3px;
282
+ position:absolute;
283
+ background-color:transparent;
284
+ -moz-border-radius:100%;
285
+ -webkit-border-radius:100%;
286
+ border-radius:100%;
287
+ -moz-transform:scale(0.05, 5);
288
+ -ms-transform:scale(0.05, 5);
289
+ -webkit-transform:scale(0.05, 5);
290
+ transform:scale(0.05, 5);
291
+ -moz-transition:all 0.2s ease;
292
+ -o-transition:all 0.2s ease;
293
+ -webkit-transition:all 0.2s ease;
294
+ transition:all 0.2s ease
295
+ }
296
+ .cb-checkbox.cb-sm, .cb-radio.cb-sm {
297
+ line-height:14px
298
+ }
299
+ .cb-checkbox.cb-md, .cb-radio.cb-md {
300
+ line-height:24px
301
+ }
302
+ .cb-checkbox.cb-lg, .cb-radio.cb-lg {
303
+ line-height:30px
304
+ }
305
+ .cb-checkbox.cb-sm i:before {
306
+ top:4px;
307
+ left:1px
308
+ }
309
+ .cb-checkbox.cb-sm i:after {
310
+ left:5px
311
+ }
312
+ .cb-checkbox.cb-md i:before {
313
+ top:10px;
314
+ left:5px
315
+ }
316
+ .cb-checkbox.cb-md i:after {
317
+ bottom:6px;
318
+ left:11px
319
+ }
320
+ .cb-checkbox.checked .cb-inner {
321
+ border-color:#0073aa;
322
+ background-color:#00a0d2;
323
+ box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15);
324
+ }
325
+ .cb-checkbox.checked:hover .cb-inner {
326
+ background-color:#0091cd
327
+ }
328
+ .cb-checkbox.checked.cb-sm i:before {
329
+ top:4px;
330
+ left:1px
331
+ }
332
+ .cb-checkbox.checked.cb-sm i:after {
333
+ height:9px
334
+ }
335
+ .cb-checkbox.checked.cb-md i:before {
336
+ top:10px;
337
+ left:4px;
338
+ height:8px
339
+ }
340
+ .cb-checkbox.checked.cb-md i:after {
341
+ bottom:6px;
342
+ left:11px;
343
+ height:16px
344
+ }
345
+ .cb-checkbox.checked.cb-lg i:before {
346
+ top:11px;
347
+ left:6px;
348
+ height:12px
349
+ }
350
+ .cb-checkbox.checked.cb-lg i:after {
351
+ left:14px;
352
+ bottom:7px;
353
+ height:20px
354
+ }
355
+ .cb-checkbox.checked i:before {
356
+ top:6px;
357
+ left:2px;
358
+ height:6px
359
+ }
360
+ .cb-checkbox.checked i:after {
361
+ height:12px
362
+ }
363
+ .cb-radio.checked .cb-inner {
364
+ background:#fff;
365
+ box-shadow:0 0 3px #efefef
366
+ }
367
+ .cb-radio.checked i {
368
+ -moz-transform:scale(1.1, 1.1);
369
+ -ms-transform:scale(1.1, 1.1);
370
+ -webkit-transform:scale(1.1, 1.1);
371
+ transform:scale(1.1, 1.1);
372
+ background-color:#00a0d2
373
+ }
374
+ .cb-checkbox:hover .cb-inner, .cb-radio:hover .cb-inner {
375
+ border-color:#0073aa
376
+ }
377
+ .cb-switcher {
378
+ display:inline-block;
379
+ border:1px solid #eee;
380
+ background-color:#fff;
381
+ width:95px;
382
+ height:35px;
383
+ position:relative;
384
+ -moz-border-radius:20px;
385
+ -webkit-border-radius:20px;
386
+ border-radius:20px;
387
+ -moz-transition:background 0.4s ease;
388
+ -o-transition:background 0.4s ease;
389
+ -webkit-transition:background 0.4s ease;
390
+ transition:background 0.4s ease
391
+ }
392
+ .cb-switcher, .cb-switcher * {
393
+ cursor:pointer
394
+ }
395
+ .cb-switcher ::-moz-selection {
396
+ background-color:transparent
397
+ }
398
+ .cb-switcher ::selection {
399
+ background-color:transparent
400
+ }
401
+ .cb-switcher .cb-state {
402
+ z-index:1;
403
+ text-align:center;
404
+ font-size:12px
405
+ }
406
+ .cb-switcher .cb-state, .cb-switcher:before {
407
+ width:34px;
408
+ height:34px;
409
+ line-height:34px;
410
+ position:absolute;
411
+ left:0;
412
+ top:-1px;
413
+ -moz-border-radius:100%;
414
+ -webkit-border-radius:100%;
415
+ border-radius:100%;
416
+ -moz-transition:all 0.4s ease;
417
+ -o-transition:all 0.4s ease;
418
+ -webkit-transition:all 0.4s ease;
419
+ transition:all 0.4s ease
420
+ }
421
+ .cb-switcher:before {
422
+ content:"";
423
+ background-color:#eee;
424
+ -moz-box-shadow:1px 1px 1px rgba(0, 0, 0, 0.1);
425
+ -webkit-box-shadow:1px 1px 1px rgba(0, 0, 0, 0.1);
426
+ box-shadow:1px 1px 1px rgba(0, 0, 0, 0.1)
427
+ }
428
+ .cb-switcher.checked {
429
+ background-color:#00a0d2
430
+ }
431
+ .cb-switcher.checked .cb-state, .cb-switcher.checked:before {
432
+ left:60px;
433
+ color:#00a0d2
434
+ }
435
+ .cb-switcher.checked:before {
436
+ background-color:#fff;
437
+ -moz-box-shadow:-1px 1px 1px rgba(0, 0, 0, 0.1);
438
+ -webkit-box-shadow:-1px 1px 1px rgba(0, 0, 0, 0.1);
439
+ box-shadow:-1px 1px 1px rgba(0, 0, 0, 0.1)
440
+ }
441
+ .cb-switcher.checked .inner-switcher:before {
442
+ border-top-color:#0073aa
443
+ }
444
+ .cb-switcher.checked .inner-switcher:after {
445
+ border-bottom-color:#0073aa
446
+ }
447
+ .cb-switcher .inner-switcher:before, .cb-switcher .inner-switcher:after {
448
+ content:"";
449
+ position:absolute;
450
+ left:50%;
451
+ width:0;
452
+ height:0;
453
+ z-index:2;
454
+ margin-left:-20px;
455
+ border-left:20px solid transparent;
456
+ border-right:20px solid transparent;
457
+ -moz-transition:border 0.4s ease;
458
+ -o-transition:border 0.4s ease;
459
+ -webkit-transition:border 0.4s ease;
460
+ transition:border 0.4s ease
461
+ }
462
+ .cb-switcher .inner-switcher:before {
463
+ border-top:17px solid #fff;
464
+ top:0
465
+ }
466
+ .cb-switcher .inner-switcher:after {
467
+ border-bottom:17px solid #fff;
468
+ bottom:0
469
+ }
470
+ .cb-state {
471
+ color:#ccc;
472
+ display:inline-block
473
+ }
474
+ .cb-switcher-group .cb-state {
475
+ position:relative;
476
+ top:7px
477
+ }
478
+ .is-hidden {
479
+ display:none !important;
480
+ visibility:hidden !important
481
+ }
482
+ output {
483
+ display: block;
484
+ font-size: 30px;
485
+ font-weight: bold;
486
+ text-align: center;
487
+ margin: 30px 0;
488
+ width: 100%;
489
  }
includes/columns.php CHANGED
@@ -1,334 +1,329 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) )
3
- exit;
4
-
5
- new Post_Views_Counter_Columns();
6
-
7
- class Post_Views_Counter_Columns {
8
-
9
- public function __construct() {
10
- // actions
11
- add_action( 'admin_init', array( &$this, 'register_new_column' ) );
12
- add_action( 'post_submitbox_misc_actions', array( &$this, 'submitbox_views' ) );
13
- add_action( 'save_post', array( &$this, 'save_post' ), 10, 2 );
14
- add_action( 'bulk_edit_custom_box', array( &$this, 'quick_edit_custom_box' ), 10, 2 );
15
- add_action( 'quick_edit_custom_box', array( &$this, 'quick_edit_custom_box') , 10, 2 );
16
- add_action( 'wp_ajax_save_bulk_post_views', array( &$this, 'save_bulk_post_views' ) );
17
- }
18
-
19
- /**
20
- * Output post views for single post.
21
- *
22
- * @global object $post
23
- * @global object $wpbd;
24
- * @return mixed
25
- */
26
- public function submitbox_views() {
27
- global $post;
28
-
29
- $post_types = Post_Views_Counter()->get_attribute( 'options', 'general', 'post_types_count' );
30
-
31
- if ( ! in_array( $post->post_type, (array) $post_types ) )
32
- return;
33
-
34
- // break if current user can't edit this post
35
- if ( ! current_user_can( 'edit_post', $post->ID ) )
36
- return;
37
-
38
- global $wpdb;
39
-
40
- // get total post views
41
- $count = $wpdb->get_var(
42
- $wpdb->prepare( "
43
- SELECT count
44
- FROM " . $wpdb->prefix . "post_views
45
- WHERE id = %d AND type = 4", absint( $post->ID )
46
- )
47
- );
48
- ?>
49
-
50
- <div class="misc-pub-section" id="post-views">
51
-
52
- <?php wp_nonce_field( 'post_views_count', 'pvc_nonce' ); ?>
53
-
54
- <span id="post-views-display">
55
-
56
- <?php echo __( 'Post Views', 'post-views-counter' ) . ': <b>' . number_format_i18n( (int) $count ) . '</b>'; ?>
57
-
58
- </span>
59
-
60
- <?php // restrict editing
61
- $restrict = (bool) Post_Views_Counter()->get_attribute( 'options', 'general', 'restrict_edit_views' );
62
-
63
- if ( $restrict === false || ( $restrict === true && current_user_can( apply_filters( 'pvc_restrict_edit_capability', 'manage_options' ) ) ) ) {
64
- ?>
65
- <a href="#post-views" class="edit-post-views hide-if-no-js"><?php _e( 'Edit', 'post-views-counter' ); ?></a>
66
-
67
- <div id="post-views-input-container" class="hide-if-js">
68
-
69
- <p><?php _e( 'Adjust the views count for this post.', 'post-views-counter' ); ?></p>
70
- <input type="hidden" name="current_post_views" id="post-views-current" value="<?php echo (int) $count; ?>" />
71
- <input type="text" name="post_views" id="post-views-input" value="<?php echo (int) $count; ?>"/><br />
72
- <p>
73
- <a href="#post-views" class="save-post-views hide-if-no-js button"><?php _e( 'OK', 'post-views-counter' ); ?></a>
74
- <a href="#post-views" class="cancel-post-views hide-if-no-js"><?php _e( 'Cancel', 'post-views-counter' ); ?></a>
75
- </p>
76
-
77
- </div>
78
- <?php
79
- }
80
- ?>
81
-
82
- </div>
83
- <?php
84
- }
85
-
86
- /**
87
- * Save post views data.
88
- *
89
- * @param int $post_id
90
- * @param object $post
91
- */
92
- public function save_post( $post_id, $post ) {
93
-
94
- // break if doing autosave
95
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
96
- return $post_id;
97
-
98
- // break if current user can't edit this post
99
- if ( ! current_user_can( 'edit_post', $post_id ) )
100
- return $post_id;
101
-
102
- // is post views set
103
- if ( ! isset( $_POST['post_views'] ) )
104
- return $post_id;
105
-
106
- // break if post views in not one of the selected
107
- $post_types = Post_Views_Counter()->get_attribute( 'options', 'general', 'post_types_count' );
108
-
109
- if ( ! in_array( $post->post_type, (array) $post_types ) )
110
- return $post_id;
111
-
112
- // break if views editing is restricted
113
- $restrict = (bool) Post_Views_Counter()->get_attribute( 'options', 'general', 'restrict_edit_views' );
114
-
115
- if ( $restrict === true && ! current_user_can( apply_filters( 'pvc_restrict_edit_capability', 'manage_options' ) ) )
116
- return $post_id;
117
-
118
- // validate data
119
- if ( ! isset( $_POST['pvc_nonce'] ) || ! wp_verify_nonce( $_POST['pvc_nonce'], 'post_views_count' ) )
120
- return $post_id;
121
-
122
- global $wpdb;
123
-
124
- $count = apply_filters( 'pvc_update_post_views_count', absint( $_POST['post_views'] ), $post_id );
125
-
126
- // insert or update db post views count
127
- $wpdb->query(
128
- $wpdb->prepare( "
129
- INSERT INTO " . $wpdb->prefix . "post_views (id, type, period, count)
130
- VALUES (%d, %d, %s, %d)
131
- ON DUPLICATE KEY UPDATE count = %d", $post_id, 4, 'total', $count, $count
132
- )
133
- );
134
-
135
- do_action( 'pvc_after_update_post_views_count', $post_id );
136
- }
137
-
138
- /**
139
- * Register post views column for specific post types
140
- */
141
- public function register_new_column() {
142
- $post_types = Post_Views_Counter()->get_attribute( 'options', 'general', 'post_types_count' );
143
-
144
- if ( ! empty( $post_types ) ) {
145
- foreach ( $post_types as $post_type ) {
146
-
147
- if ( $post_type === 'page' ) {
148
- // actions
149
- add_action( 'manage_pages_custom_column', array( &$this, 'add_new_column_content' ), 10, 2 );
150
-
151
- // filters
152
- add_filter( 'manage_pages_columns', array( &$this, 'add_new_column' ) );
153
- add_filter( 'manage_edit-page_sortable_columns', array( &$this, 'register_sortable_custom_column' ) );
154
- } elseif ( $post_type === 'post' ) {
155
- // actions
156
- add_action( 'manage_posts_custom_column', array( &$this, 'add_new_column_content' ), 10, 2 );
157
-
158
- // filters
159
- add_filter( 'manage_posts_columns', array( &$this, 'add_new_column' ) );
160
- add_filter( 'manage_edit-post_sortable_columns', array( &$this, 'register_sortable_custom_column' ) );
161
- } else{
162
- // actions
163
- add_action( 'manage_' . $post_type . '_posts_custom_column', array( &$this, 'add_new_column_content' ), 10, 2 );
164
-
165
- // filters
166
- add_filter( 'manage_' . $post_type . '_posts_columns', array( &$this, 'add_new_column' ) );
167
- add_filter( 'manage_edit-' . $post_type . '_sortable_columns', array( &$this, 'register_sortable_custom_column' ) );
168
- }
169
- }
170
- }
171
- }
172
-
173
- /**
174
- * Register sortable post views column.
175
- *
176
- * @param array $columns
177
- * @return array
178
- */
179
- public function register_sortable_custom_column( $columns ) {
180
- // add new sortable column
181
- $columns['post_views'] = 'post_views';
182
-
183
- return $columns;
184
- }
185
-
186
- /**
187
- * Add post views column.
188
- *
189
- * @param array $columns
190
- * @return array
191
- */
192
- public function add_new_column( $columns ) {
193
- $offset = 0;
194
-
195
- if ( isset( $columns['date'] ) )
196
- $offset ++;
197
-
198
- if ( isset( $columns['comments'] ) )
199
- $offset ++;
200
-
201
- if ( $offset > 0 ) {
202
- $date = array_slice( $columns, -$offset, $offset, true );
203
-
204
- foreach ( $date as $column => $name ) {
205
- unset( $columns[$column] );
206
- }
207
-
208
- $columns['post_views'] = '<span class="dash-icon dashicons dashicons-chart-bar" title="' . __( 'Post Views', 'post-views-counter' ) . '"></span><span class="dash-title">' . __( 'Post Views', 'post-views-counter' ) . '</span>';
209
-
210
- foreach ( $date as $column => $name ) {
211
- $columns[$column] = $name;
212
- }
213
- } else
214
- $columns['post_views'] = '<span class="dash-icon dashicons dashicons-chart-bar" title="' . __( 'Post Views', 'post-views-counter' ) . '"></span><span class="dash-title">' . __( 'Post Views', 'post-views-counter' ) . '</span>';
215
-
216
- return $columns;
217
- }
218
-
219
- /**
220
- * Add post views column content.
221
- *
222
- * @global object $wpdb
223
- * @param string $column_name
224
- * @param int $id
225
- * @return muxed
226
- */
227
- public function add_new_column_content( $column_name, $id ) {
228
-
229
- if ( $column_name === 'post_views' ) {
230
-
231
- global $wpdb;
232
-
233
- // get total post views
234
- $count = $wpdb->get_var(
235
- $wpdb->prepare( "
236
- SELECT count
237
- FROM " . $wpdb->prefix . "post_views
238
- WHERE id = %d AND type = 4", $id
239
- )
240
- );
241
-
242
- echo (int) $count;
243
- }
244
- }
245
-
246
- /**
247
- * Handle quick edit.
248
- *
249
- * @global string $pagenow
250
- * @global object $wpdb
251
- * @param string $column_name
252
- * @return mixed
253
- */
254
- function quick_edit_custom_box( $column_name, $post_type ) {
255
- global $pagenow, $post;
256
-
257
- if ( $pagenow !== 'edit.php' )
258
- return;
259
-
260
- if ( ! Post_Views_Counter()->get_attribute( 'options', 'general', 'post_views_column' ) || ! in_array( $post_type, Post_Views_Counter()->get_attribute( 'options', 'general', 'post_types_count' ) ) )
261
- return;
262
-
263
- // break if views editing is restricted
264
- $restrict = (bool) Post_Views_Counter()->get_attribute( 'options', 'general', 'restrict_edit_views' );
265
-
266
- if ( $restrict === true && ! current_user_can( apply_filters( 'pvc_restrict_edit_capability', 'manage_options' ) ) )
267
- return;
268
-
269
- if ( $column_name != 'post_views' )
270
- return;
271
-
272
- global $wpdb;
273
-
274
- // get total post views
275
- $count = $wpdb->get_var(
276
- $wpdb->prepare( "
277
- SELECT count
278
- FROM " . $wpdb->prefix . "post_views
279
- WHERE id = %d AND type = 4", $post->ID
280
- )
281
- );
282
- ?>
283
- <fieldset class="inline-edit-col-left">
284
- <div id="inline-edit-post_views" class="inline-edit-col">
285
- <label class="inline-edit-group">
286
- <span class="title"><?php _e( 'Post Views', 'post-views-counter' ); ?></span>
287
- <span class="input-text-wrap"><input type="text" name="post_views" class="title text" value="<?php echo absint( $count ); ?>"></span>
288
- <?php wp_nonce_field( 'post_views_count', 'pvc_nonce' ); ?>
289
- </label>
290
- </div>
291
- </fieldset>
292
- <?php
293
- }
294
-
295
- /**
296
- * Bulk save post views.
297
- *
298
- * @global object $wpdb;
299
- * @return type
300
- */
301
- function save_bulk_post_views() {
302
-
303
- $post_ids = ( ! empty( $_POST[ 'post_ids' ] ) && is_array( $post_ids ) ) ? array_map( 'absint', $_POST[ 'post_ids' ] ) : array();
304
- $count = ( ! empty( $_POST[ 'post_views' ] ) ) ? absint( $_POST[ 'post_views' ] ) : null;
305
-
306
- // break if views editing is restricted
307
- $restrict = (bool) Post_Views_Counter()->get_attribute( 'options', 'general', 'restrict_edit_views' );
308
-
309
- if ( $restrict === true && ! current_user_can( apply_filters( 'pvc_restrict_edit_capability', 'manage_options' ) ) )
310
- die();
311
-
312
- if ( ! empty( $post_ids ) ) {
313
- foreach ( $post_ids as $post_id ) {
314
-
315
- // break if current user can't edit this post
316
- if ( ! current_user_can( 'edit_post', $post_id ) )
317
- continue;
318
-
319
- global $wpdb;
320
-
321
- // insert or update db post views count
322
- $wpdb->query(
323
- $wpdb->prepare( "
324
- INSERT INTO " . $wpdb->prefix . "post_views (id, type, period, count)
325
- VALUES (%d, %d, %s, %d)
326
- ON DUPLICATE KEY UPDATE count = %d", $post_id, 4, 'total', $count, $count
327
- )
328
- );
329
- }
330
- }
331
- die();
332
- }
333
-
334
  }
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * Post_Views_Counter_Columns class.
8
+ */
9
+ class Post_Views_Counter_Columns {
10
+
11
+ public function __construct() {
12
+ // actions
13
+ add_action( 'admin_init', array( $this, 'register_new_column' ) );
14
+ add_action( 'post_submitbox_misc_actions', array( $this, 'submitbox_views' ) );
15
+ add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );
16
+ add_action( 'bulk_edit_custom_box', array( $this, 'quick_edit_custom_box' ), 10, 2 );
17
+ add_action( 'quick_edit_custom_box', array( $this, 'quick_edit_custom_box') , 10, 2 );
18
+ add_action( 'wp_ajax_save_bulk_post_views', array( $this, 'save_bulk_post_views' ) );
19
+ }
20
+
21
+ /**
22
+ * Output post views for single post.
23
+ *
24
+ * @global object $post
25
+ * @global object $wpbd
26
+ *
27
+ * @return mixed
28
+ */
29
+ public function submitbox_views() {
30
+ global $post;
31
+
32
+ $post_types = Post_Views_Counter()->options['general']['post_types_count'];
33
+
34
+ if ( ! in_array( $post->post_type, (array) $post_types ) )
35
+ return;
36
+
37
+ // break if current user can't edit this post
38
+ if ( ! current_user_can( 'edit_post', $post->ID ) )
39
+ return;
40
+
41
+ global $wpdb;
42
+
43
+ // get total post views
44
+ $count = $wpdb->get_var(
45
+ $wpdb->prepare( "
46
+ SELECT count
47
+ FROM " . $wpdb->prefix . "post_views
48
+ WHERE id = %d AND type = 4", absint( $post->ID )
49
+ )
50
+ );
51
+ ?>
52
+
53
+ <div class="misc-pub-section" id="post-views">
54
+
55
+ <?php wp_nonce_field( 'post_views_count', 'pvc_nonce' ); ?>
56
+
57
+ <span id="post-views-display">
58
+
59
+ <?php echo __( 'Post Views', 'post-views-counter' ) . ': <b>' . number_format_i18n( (int) $count ) . '</b>'; ?>
60
+
61
+ </span>
62
+
63
+ <?php // restrict editing
64
+ $restrict = (bool) Post_Views_Counter()->options['general']['restrict_edit_views'];
65
+
66
+ if ( $restrict === false || ( $restrict === true && current_user_can( apply_filters( 'pvc_restrict_edit_capability', 'manage_options' ) ) ) ) {
67
+ ?>
68
+ <a href="#post-views" class="edit-post-views hide-if-no-js"><?php _e( 'Edit', 'post-views-counter' ); ?></a>
69
+
70
+ <div id="post-views-input-container" class="hide-if-js">
71
+
72
+ <p><?php _e( 'Adjust the views count for this post.', 'post-views-counter' ); ?></p>
73
+ <input type="hidden" name="current_post_views" id="post-views-current" value="<?php echo (int) $count; ?>" />
74
+ <input type="text" name="post_views" id="post-views-input" value="<?php echo (int) $count; ?>"/><br />
75
+ <p>
76
+ <a href="#post-views" class="save-post-views hide-if-no-js button"><?php _e( 'OK', 'post-views-counter' ); ?></a>
77
+ <a href="#post-views" class="cancel-post-views hide-if-no-js"><?php _e( 'Cancel', 'post-views-counter' ); ?></a>
78
+ </p>
79
+
80
+ </div>
81
+ <?php
82
+ }
83
+ ?>
84
+
85
+ </div>
86
+ <?php
87
+ }
88
+
89
+ /**
90
+ * Save post views data.
91
+ *
92
+ * @param int $post_id
93
+ * @param object $post
94
+ */
95
+ public function save_post( $post_id, $post ) {
96
+
97
+ // break if doing autosave
98
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
99
+ return $post_id;
100
+
101
+ // break if current user can't edit this post
102
+ if ( ! current_user_can( 'edit_post', $post_id ) )
103
+ return $post_id;
104
+
105
+ // is post views set
106
+ if ( ! isset( $_POST['post_views'] ) )
107
+ return $post_id;
108
+
109
+ // break if post views in not one of the selected
110
+ $post_types = Post_Views_Counter()->options['general']['post_types_count'];
111
+
112
+ if ( ! in_array( $post->post_type, (array) $post_types ) )
113
+ return $post_id;
114
+
115
+ // break if views editing is restricted
116
+ $restrict = (bool) Post_Views_Counter()->options['general']['restrict_edit_views'];
117
+
118
+ if ( $restrict === true && ! current_user_can( apply_filters( 'pvc_restrict_edit_capability', 'manage_options' ) ) )
119
+ return $post_id;
120
+
121
+ // validate data
122
+ if ( ! isset( $_POST['pvc_nonce'] ) || ! wp_verify_nonce( $_POST['pvc_nonce'], 'post_views_count' ) )
123
+ return $post_id;
124
+
125
+ global $wpdb;
126
+
127
+ $count = apply_filters( 'pvc_update_post_views_count', absint( $_POST['post_views'] ), $post_id );
128
+
129
+ // insert or update db post views count
130
+ $wpdb->query(
131
+ $wpdb->prepare( "
132
+ INSERT INTO " . $wpdb->prefix . "post_views (id, type, period, count)
133
+ VALUES (%d, %d, %s, %d)
134
+ ON DUPLICATE KEY UPDATE count = %d", $post_id, 4, 'total', $count, $count
135
+ )
136
+ );
137
+
138
+ do_action( 'pvc_after_update_post_views_count', $post_id );
139
+ }
140
+
141
+ /**
142
+ * Register post views column for specific post types
143
+ */
144
+ public function register_new_column() {
145
+ $post_types = Post_Views_Counter()->options['general']['post_types_count'];
146
+
147
+ if ( ! empty( $post_types ) ) {
148
+ foreach ( $post_types as $post_type ) {
149
+ if ( $post_type === 'page' ) {
150
+ // actions
151
+ add_action( 'manage_pages_custom_column', array( $this, 'add_new_column_content' ), 10, 2 );
152
+
153
+ // filters
154
+ add_filter( 'manage_pages_columns', array( $this, 'add_new_column' ) );
155
+ add_filter( 'manage_edit-page_sortable_columns', array( $this, 'register_sortable_custom_column' ) );
156
+ } else {
157
+ // actions
158
+ add_action( 'manage_' . $post_type . '_posts_custom_column', array( $this, 'add_new_column_content' ), 10, 2 );
159
+
160
+ // filters
161
+ add_filter( 'manage_' . $post_type . '_posts_columns', array( $this, 'add_new_column' ) );
162
+ add_filter( 'manage_edit-' . $post_type . '_sortable_columns', array( $this, 'register_sortable_custom_column' ) );
163
+ }
164
+ }
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Register sortable post views column.
170
+ *
171
+ * @param array $columns
172
+ * @return array
173
+ */
174
+ public function register_sortable_custom_column( $columns ) {
175
+ // add new sortable column
176
+ $columns['post_views'] = 'post_views';
177
+
178
+ return $columns;
179
+ }
180
+
181
+ /**
182
+ * Add post views column.
183
+ *
184
+ * @param array $columns
185
+ * @return array
186
+ */
187
+ public function add_new_column( $columns ) {
188
+ $offset = 0;
189
+
190
+ if ( isset( $columns['date'] ) )
191
+ $offset ++;
192
+
193
+ if ( isset( $columns['comments'] ) )
194
+ $offset ++;
195
+
196
+ if ( $offset > 0 ) {
197
+ $date = array_slice( $columns, -$offset, $offset, true );
198
+
199
+ foreach ( $date as $column => $name ) {
200
+ unset( $columns[$column] );
201
+ }
202
+
203
+ $columns['post_views'] = '<span class="dash-icon dashicons dashicons-chart-bar" title="' . __( 'Post Views', 'post-views-counter' ) . '"></span><span class="dash-title">' . __( 'Post Views', 'post-views-counter' ) . '</span>';
204
+
205
+ foreach ( $date as $column => $name ) {
206
+ $columns[$column] = $name;
207
+ }
208
+ } else
209
+ $columns['post_views'] = '<span class="dash-icon dashicons dashicons-chart-bar" title="' . __( 'Post Views', 'post-views-counter' ) . '"></span><span class="dash-title">' . __( 'Post Views', 'post-views-counter' ) . '</span>';
210
+
211
+ return $columns;
212
+ }
213
+
214
+ /**
215
+ * Add post views column content.
216
+ *
217
+ * @global object $wpdb
218
+ * @param string $column_name
219
+ * @param int $id
220
+ * @return muxed
221
+ */
222
+ public function add_new_column_content( $column_name, $id ) {
223
+
224
+ if ( $column_name === 'post_views' ) {
225
+
226
+ global $wpdb;
227
+
228
+ // get total post views
229
+ $count = $wpdb->get_var(
230
+ $wpdb->prepare( "
231
+ SELECT count
232
+ FROM " . $wpdb->prefix . "post_views
233
+ WHERE id = %d AND type = 4", $id
234
+ )
235
+ );
236
+
237
+ echo (int) $count;
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Handle quick edit.
243
+ *
244
+ * @global string $pagenow
245
+ * @global object $wpdb
246
+ * @param string $column_name
247
+ * @return mixed
248
+ */
249
+ function quick_edit_custom_box( $column_name, $post_type ) {
250
+ global $pagenow, $post;
251
+
252
+ if ( $pagenow !== 'edit.php' )
253
+ return;
254
+
255
+ if ( ! Post_Views_Counter()->options['general']['post_views_column'] || ! in_array( $post_type, Post_Views_Counter()->options['general']['post_types_count'] ) )
256
+ return;
257
+
258
+ // break if views editing is restricted
259
+ $restrict = (bool) Post_Views_Counter()->options['general']['restrict_edit_views'];
260
+
261
+ if ( $restrict === true && ! current_user_can( apply_filters( 'pvc_restrict_edit_capability', 'manage_options' ) ) )
262
+ return;
263
+
264
+ if ( $column_name != 'post_views' )
265
+ return;
266
+
267
+ global $wpdb;
268
+
269
+ // get total post views
270
+ $count = $wpdb->get_var(
271
+ $wpdb->prepare( "
272
+ SELECT count
273
+ FROM " . $wpdb->prefix . "post_views
274
+ WHERE id = %d AND type = 4", $post->ID
275
+ )
276
+ );
277
+ ?>
278
+ <fieldset class="inline-edit-col-left">
279
+ <div id="inline-edit-post_views" class="inline-edit-col">
280
+ <label class="inline-edit-group">
281
+ <span class="title"><?php _e( 'Post Views', 'post-views-counter' ); ?></span>
282
+ <span class="input-text-wrap"><input type="text" name="post_views" class="title text" value="<?php echo absint( $count ); ?>"></span>
283
+ <?php wp_nonce_field( 'post_views_count', 'pvc_nonce' ); ?>
284
+ </label>
285
+ </div>
286
+ </fieldset>
287
+ <?php
288
+ }
289
+
290
+ /**
291
+ * Bulk save post views.
292
+ *
293
+ * @global object $wpdb;
294
+ * @return type
295
+ */
296
+ function save_bulk_post_views() {
297
+
298
+ $post_ids = ( ! empty( $_POST[ 'post_ids' ] ) && is_array( $post_ids ) ) ? array_map( 'absint', $_POST[ 'post_ids' ] ) : array();
299
+ $count = ( ! empty( $_POST[ 'post_views' ] ) ) ? absint( $_POST[ 'post_views' ] ) : null;
300
+
301
+ // break if views editing is restricted
302
+ $restrict = (bool) Post_Views_Counter()->options['general']['restrict_edit_views'];
303
+
304
+ if ( $restrict === true && ! current_user_can( apply_filters( 'pvc_restrict_edit_capability', 'manage_options' ) ) )
305
+ die();
306
+
307
+ if ( ! empty( $post_ids ) ) {
308
+ foreach ( $post_ids as $post_id ) {
309
+
310
+ // break if current user can't edit this post
311
+ if ( ! current_user_can( 'edit_post', $post_id ) )
312
+ continue;
313
+
314
+ global $wpdb;
315
+
316
+ // insert or update db post views count
317
+ $wpdb->query(
318
+ $wpdb->prepare( "
319
+ INSERT INTO " . $wpdb->prefix . "post_views (id, type, period, count)
320
+ VALUES (%d, %d, %s, %d)
321
+ ON DUPLICATE KEY UPDATE count = %d", $post_id, 4, 'total', $count, $count
322
+ )
323
+ );
324
+ }
325
+ }
326
+ die();
327
+ }
328
+
 
 
 
 
 
329
  }
includes/counter.php CHANGED
@@ -1,527 +1,526 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) )
3
- exit;
4
-
5
- new Post_Views_Counter_Counter();
6
-
7
- class Post_Views_Counter_Counter {
8
-
9
- const GROUP = 'pvc';
10
- const NAME_ALLKEYS = 'cached_key_names';
11
- const CACHE_KEY_SEPARATOR = '.';
12
-
13
- private $cookie = array(
14
- 'exists' => false,
15
- 'visited_posts' => array(),
16
- 'expiration' => 0
17
- );
18
-
19
- public function __construct() {
20
- // set instance
21
- Post_Views_Counter()->add_instance( 'counter', $this );
22
-
23
- // actions
24
- add_action( 'plugins_loaded', array( &$this, 'check_cookie' ), 1 );
25
- add_action( 'wp', array( &$this, 'check_post' ) );
26
- add_action( 'deleted_post', array( &$this, 'delete_post_views' ) );
27
- add_action( 'wp_ajax_pvc-check-post', array( &$this, 'check_post_ajax' ) );
28
- add_action( 'wp_ajax_nopriv_pvc-check-post', array( &$this, 'check_post_ajax' ) );
29
- }
30
-
31
- /**
32
- * Remove post views from database when post is deleted.
33
- *
34
- * @param int $post_id
35
- */
36
- public function delete_post_views( $post_id ) {
37
- global $wpdb;
38
-
39
- $wpdb->delete( $wpdb->prefix . 'post_views', array( 'id' => $post_id ), array( '%d' ) );
40
- }
41
-
42
- /**
43
- * Check whether user has excluded roles.
44
- *
45
- * @param string $option
46
- * @return bool
47
- */
48
- public function is_user_roles_excluded( $option ) {
49
- $user = wp_get_current_user();
50
-
51
- if ( empty( $user ) )
52
- return false;
53
-
54
- $roles = (array) $user->roles;
55
-
56
- if ( ! empty( $roles ) ) {
57
- foreach ( $roles as $role ) {
58
- if ( in_array( $role, $option, true ) )
59
- return true;
60
- }
61
- }
62
-
63
- return false;
64
- }
65
-
66
- /**
67
- *
68
- * Get timestamp convertion.
69
- *
70
- * @param string $type
71
- * @param int $number
72
- * @param int $timestamp
73
- * @return string
74
- */
75
- public function get_timestamp( $type, $number, $timestamp = true ) {
76
- $converter = array(
77
- 'minutes' => 60,
78
- 'hours' => 3600,
79
- 'days' => 86400,
80
- 'weeks' => 604800,
81
- 'months' => 2592000,
82
- 'years' => 946080000
83
- );
84
-
85
- return ($timestamp ? current_time( 'timestamp', true ) : 0) + $number * $converter[$type];
86
- }
87
-
88
- /**
89
- * Check whether to count visit via AJAX request.
90
- */
91
- public function check_post_ajax() {
92
- if ( isset( $_POST['action'], $_POST['post_id'], $_POST['pvc_nonce'], $_POST['post_type'] ) && $_POST['action'] === 'pvc-check-post' && ($post_id = (int) $_POST['post_id']) > 0 && wp_verify_nonce( $_POST['pvc_nonce'], 'pvc-check-post' ) !== false && Post_Views_Counter()->get_attribute( 'options', 'general', 'counter_mode' ) === 'js' ) {
93
- // get countable post types
94
- $post_types = Post_Views_Counter()->get_attribute( 'options', 'general', 'post_types_count' );
95
-
96
- // get post type
97
- $post_type = get_post_type( $post_id );
98
-
99
- // whether to count this post type or not
100
- if ( empty( $post_types ) || empty( $post_type ) || $post_type !== $_POST['post_type'] || ! in_array( $post_type, $post_types, true ) )
101
- exit;
102
-
103
- // get excluded ips
104
- $excluded_ips = Post_Views_Counter()->get_attribute( 'options', 'general', 'exclude_ips' );
105
-
106
- // whether to count this ip or not
107
- if ( ! empty( $excluded_ips ) && filter_var( preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] ), FILTER_VALIDATE_IP ) && in_array( $_SERVER['REMOTE_ADDR'], $excluded_ips, true ) )
108
- exit;
109
-
110
- // get groups to check them faster
111
- $groups = Post_Views_Counter()->get_attribute( 'options', 'general', 'exclude', 'groups' );
112
-
113
- // whether to count this user
114
- if ( is_user_logged_in() ) {
115
- // exclude logged in users?
116
- if ( in_array( 'users', $groups, true ) )
117
- exit;
118
- // exclude specific roles?
119
- elseif ( in_array( 'roles', $groups, true ) && $this->is_user_roles_excluded( Post_Views_Counter()->get_attribute( 'options', 'general', 'exclude', 'roles' ) ) )
120
- exit;
121
- }
122
- // exclude guests?
123
- elseif ( in_array( 'guests', $groups, true ) )
124
- exit;
125
-
126
- // whether to count robots
127
- if ( $this->is_robot() )
128
- exit;
129
-
130
- // cookie already existed?
131
- if ( $this->cookie['exists'] ) {
132
- // post already viewed but not expired?
133
- if ( in_array( $post_id, array_keys( $this->cookie['visited_posts'] ), true ) && current_time( 'timestamp', true ) < $this->cookie['visited_posts'][$post_id] ) {
134
- // updates cookie but do not count visit
135
- $this->save_cookie( $post_id, $this->cookie, false );
136
-
137
- exit;
138
- } else
139
- // updates cookie
140
- $this->save_cookie( $post_id, $this->cookie );
141
- } else {
142
- // set new cookie
143
- $this->save_cookie( $post_id );
144
- }
145
-
146
- // count visit
147
- $this->count_visit( $post_id );
148
- }
149
-
150
- exit;
151
- }
152
-
153
- /**
154
- * Check whether to count visit.
155
- */
156
- public function check_post() {
157
- // do not count admin entries
158
- if ( is_admin() )
159
- return;
160
-
161
- // do we use PHP as counter?
162
- if ( Post_Views_Counter()->get_attribute( 'options', 'general', 'counter_mode' ) === 'php' ) {
163
- $post_types = Post_Views_Counter()->get_attribute( 'options', 'general', 'post_types_count' );
164
-
165
- // whether to count this post type
166
- if ( empty( $post_types ) || ! is_singular( $post_types ) )
167
- return;
168
-
169
- $ips = Post_Views_Counter()->get_attribute( 'options', 'general', 'exclude_ips' );
170
-
171
- // whether to count this ip
172
- if ( ! empty( $ips ) && filter_var( preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] ), FILTER_VALIDATE_IP ) && in_array( $_SERVER['REMOTE_ADDR'], $ips, true ) )
173
- return;
174
-
175
- // get groups to check them faster
176
- $groups = Post_Views_Counter()->get_attribute( 'options', 'general', 'exclude', 'groups' );
177
-
178
- // whether to count this user
179
- if ( is_user_logged_in() ) {
180
- // exclude logged in users?
181
- if ( in_array( 'users', $groups, true ) )
182
- return;
183
- // exclude specific roles?
184
- elseif ( in_array( 'roles', $groups, true ) && $this->is_user_roles_excluded( Post_Views_Counter()->get_attribute( 'options', 'general', 'exclude', 'roles' ) ) )
185
- return;
186
- }
187
- // exclude guests?
188
- elseif ( in_array( 'guests', $groups, true ) )
189
- return;
190
-
191
- // whether to count robots
192
- if ( $this->is_robot() )
193
- return;
194
-
195
- // get post id
196
- $id = get_the_ID();
197
-
198
- // cookie already existed?
199
- if ( $this->cookie['exists'] ) {
200
- // post already viewed but not expired?
201
- if ( in_array( $id, array_keys( $this->cookie['visited_posts'] ), true ) && current_time( 'timestamp', true ) < $this->cookie['visited_posts'][$id] ) {
202
- // update cookie but do not count visit
203
- $this->save_cookie( $id, $this->cookie, false );
204
-
205
- return;
206
- } else
207
- // update cookie
208
- $this->save_cookie( $id, $this->cookie );
209
- } else
210
- // set new cookie
211
- $this->save_cookie( $id );
212
-
213
- // count visit
214
- $this->count_visit( $id );
215
- }
216
- }
217
-
218
- /**
219
- * Initialize cookie session.
220
- */
221
- public function check_cookie() {
222
- // do not run in admin except for ajax requests
223
- if ( is_admin() && ! (defined( 'DOING_AJAX' ) && DOING_AJAX) )
224
- return;
225
-
226
- // is cookie set?
227
- if ( isset( $_COOKIE['pvc_visits'] ) && ! empty( $_COOKIE['pvc_visits'] ) ) {
228
- $visited_posts = $expirations = array();
229
-
230
- foreach ( $_COOKIE['pvc_visits'] as $content ) {
231
- // is cookie valid?
232
- if ( preg_match( '/^(([0-9]+b[0-9]+a?)+)$/', $content ) === 1 ) {
233
- // get single id with expiration
234
- $expiration_ids = explode( 'a', $content );
235
-
236
- // check every expiration => id pair
237
- foreach ( $expiration_ids as $pair ) {
238
- $pair = explode( 'b', $pair );
239
- $expirations[] = (int) $pair[0];
240
- $visited_posts[(int) $pair[1]] = (int) $pair[0];
241
- }
242
- }
243
- }
244
-
245
- $this->cookie = array(
246
- 'exists' => true,
247
- 'visited_posts' => $visited_posts,
248
- 'expiration' => max( $expirations )
249
- );
250
- }
251
- }
252
-
253
- /**
254
- * Save cookie function.
255
- *
256
- * @param int $id
257
- * @param array $cookie
258
- * @param bool $expired
259
- */
260
- private function save_cookie( $id, $cookie = array(), $expired = true ) {
261
- $expiration = $this->get_timestamp( Post_Views_Counter()->get_attribute( 'options', 'general', 'time_between_counts', 'type' ), Post_Views_Counter()->get_attribute( 'options', 'general', 'time_between_counts', 'number' ) );
262
-
263
- // is this a new cookie?
264
- if ( empty( $cookie ) ) {
265
- // set cookie
266
- setcookie( 'pvc_visits[0]', $expiration . 'b' . $id, $expiration, COOKIEPATH, COOKIE_DOMAIN, (isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ? true : false ), true );
267
- } else {
268
- if ( $expired ) {
269
- // add new id or chang expiration date if id already exists
270
- $cookie['visited_posts'][$id] = $expiration;
271
- }
272
-
273
- // create copy for better foreach performance
274
- $visited_posts_expirations = $cookie['visited_posts'];
275
-
276
- // get current gmt time
277
- $time = current_time( 'timestamp', true );
278
-
279
- // check whether viewed id has expired - no need to keep it in cookie (less size)
280
- foreach ( $visited_posts_expirations as $post_id => $post_expiration ) {
281
- if ( $time > $post_expiration )
282
- unset( $cookie['visited_posts'][$post_id] );
283
- }
284
-
285
- // set new last expiration date if needed
286
- $cookie['expiration'] = max( $cookie['visited_posts'] );
287
-
288
- $cookies = $imploded = array();
289
-
290
- // create pairs
291
- foreach ( $cookie['visited_posts'] as $id => $exp ) {
292
- $imploded[] = $exp . 'b' . $id;
293
- }
294
-
295
- // split cookie into chunks (4000 bytes to make sure it is safe for every browser)
296
- $chunks = str_split( implode( 'a', $imploded ), 4000 );
297
-
298
- // more then one chunk?
299
- if ( count( $chunks ) > 1 ) {
300
- $last_id = '';
301
-
302
- foreach ( $chunks as $chunk_id => $chunk ) {
303
- // new chunk
304
- $chunk_c = $last_id . $chunk;
305
-
306
- // is it full-length chunk?
307
- if ( strlen( $chunk ) === 4000 ) {
308
- // get last part
309
- $last_part = strrchr( $chunk_c, 'a' );
310
-
311
- // get last id
312
- $last_id = substr( $last_part, 1 );
313
-
314
- // add new full-lenght chunk
315
- $cookies[$chunk_id] = substr( $chunk_c, 0, strlen( $chunk_c ) - strlen( $last_part ) );
316
- } else {
317
- // add last chunk
318
- $cookies[$chunk_id] = $chunk_c;
319
- }
320
- }
321
- } else {
322
- // only one chunk
323
- $cookies[] = $chunks[0];
324
- }
325
-
326
- foreach ( $cookies as $key => $value ) {
327
- // set cookie
328
- setcookie( 'pvc_visits[' . $key . ']', $value, $cookie['expiration'], COOKIEPATH, COOKIE_DOMAIN, (isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ? true : false ), true );
329
- }
330
- }
331
- }
332
-
333
- /**
334
- * Check if object cache is in use.
335
- *
336
- * @param bool $using
337
- * @return bool
338
- */
339
- public function using_object_cache( $using = null ) {
340
- $using = wp_using_ext_object_cache( $using );
341
-
342
- if ( $using ) {
343
- // check if explicitly disabled by flush_interval setting/option <= 0
344
- $flush_interval_number = Post_Views_Counter()->get_attribute( 'options', 'general', 'flush_interval', 'number' );
345
- $using = ( $flush_interval_number <= 0 ) ? false : true;
346
- }
347
-
348
- return $using;
349
- }
350
-
351
- /**
352
- * Count visit function.
353
- *
354
- * @global object $wpdb
355
- * @param int $id
356
- * @return bool
357
- */
358
- private function count_visit( $id ) {
359
- global $wpdb;
360
-
361
- $cache_key_names = array();
362
- $using_object_cache = $this->using_object_cache();
363
-
364
- // get day, week, month and year
365
- $date = explode( '-', date( 'W-d-m-Y', current_time( 'timestamp' ) ) );
366
-
367
- foreach ( array(
368
- 0 => $date[3] . $date[2] . $date[1], // day like 20140324
369
- 1 => $date[3] . $date[0], // week like 201439
370
- 2 => $date[3] . $date[2], // month like 201405
371
- 3 => $date[3], // year like 2014
372
- 4 => 'total' // total views
373
- ) as $type => $period ) {
374
- if ( $using_object_cache ) {
375
- $cache_key = $id . self::CACHE_KEY_SEPARATOR . $type . self::CACHE_KEY_SEPARATOR . $period;
376
- wp_cache_add( $cache_key, 0, self::GROUP );
377
- wp_cache_incr( $cache_key, 1, self::GROUP );
378
- $cache_key_names[] = $cache_key;
379
- } else {
380
- // hit the db directly
381
- // @TODO: investigate queueing these queries on the 'shutdown' hook instead instead of running them instantly?
382
- $this->db_insert( $id, $type, $period, 1 );
383
- }
384
- }
385
-
386
- // update the list of cache keys to be flushed
387
- if ( $using_object_cache && ! empty( $cache_key_names ) ) {
388
- $this->update_cached_keys_list_if_needed( $cache_key_names );
389
- }
390
-
391
- do_action( 'pvc_after_count_visit', $id );
392
-
393
- return true;
394
- }
395
-
396
- /**
397
- * Update the single cache key which holds a list of all the cache keys
398
- * that need to be flushed to the db.
399
- *
400
- * The value of that special cache key is a giant string containing key names separated with the `|` character.
401
- * Each such key name then consists of 3 elements: $id, $type, $period (separated by a `.` character).
402
- * Examples:
403
- * 62053.0.20150327|62053.1.201513|62053.2.201503|62053.3.2015|62053.4.total|62180.0.20150327|62180.1.201513|62180.2.201503|62180.3.2015|62180.4.total
404
- * A single key is `62053.0.20150327` and that key's data is: $id = 62053, $type = 0, $period = 20150327
405
- *
406
- * This data format proved more efficient (avoids the (un)serialization overhead completely + duplicates filtering is a string search now)
407
- *
408
- * @param array $key_names
409
- */
410
- private function update_cached_keys_list_if_needed( $key_names = array() ) {
411
- $existing_list = wp_cache_get( self::NAME_ALLKEYS, self::GROUP );
412
- if ( ! $existing_list ) {
413
- $existing_list = '';
414
- }
415
-
416
- $list_modified = false;
417
-
418
- // modify the list contents if/when needed
419
- if ( empty( $existing_list ) ) {
420
- // the simpler case of an empty initial list where we just
421
- // transform the specified key names into a string
422
- $existing_list = implode( '|', $key_names );
423
- $list_modified = true;
424
- } else {
425
- // search each specified key name and append it if it's not found
426
- foreach ( $key_names as $key_name ) {
427
- if ( false === strpos( $existing_list, $key_name ) ) {
428
- $existing_list .= '|' . $key_name;
429
- $list_modified = true;
430
- }
431
- }
432
- }
433
-
434
- // save modified list back in cache
435
- if ( $list_modified ) {
436
- wp_cache_set( self::NAME_ALLKEYS, $existing_list, self::GROUP );
437
- }
438
- }
439
-
440
- /**
441
- * Flush views data stored in the persistent object cache into
442
- * our custom table and clear the object cache keys when done
443
- *
444
- * @global object $wpdb
445
- * @return bool
446
- */
447
- public function flush_cache_to_db() {
448
- global $wpdb;
449
-
450
- $key_names = wp_cache_get( self::NAME_ALLKEYS, self::GROUP );
451
-
452
- if ( ! $key_names ) {
453
- $key_names = array();
454
- } else {
455
- // create an array out of a string that's stored in the cache
456
- $key_names = explode( '|', $key_names );
457
- }
458
-
459
- foreach ( $key_names as $key_name ) {
460
- // get values stored within the key name itself
461
- list( $id, $type, $period ) = explode( self::CACHE_KEY_SEPARATOR, $key_name );
462
- // get the cached count value
463
- $count = wp_cache_get( $key_name, self::GROUP );
464
-
465
- // store cached value in the db
466
- $this->db_insert( $id, $type, $period, $count );
467
-
468
- // clear the cache key we just flushed
469
- wp_cache_delete( $key_name, self::GROUP );
470
- }
471
-
472
- // delete the key holding the list itself after we've successfully flushed it
473
- if ( ! empty( $key_names ) ) {
474
- wp_cache_delete( self::NAME_ALLKEYS, self::GROUP );
475
- }
476
-
477
- return true;
478
- }
479
-
480
- /**
481
- * Insert or update views count.
482
- *
483
- * @global object $wpdb
484
- * @param int $id
485
- * @param string $type
486
- * @param string $period
487
- * @param int $count
488
- * @return bool
489
- */
490
- private function db_insert( $id, $type, $period, $count = 1 ) {
491
- global $wpdb;
492
-
493
- $count = (int) $count;
494
-
495
- if ( ! $count ) {
496
- $count = 1;
497
- }
498
-
499
- return $wpdb->query(
500
- $wpdb->prepare( "
501
- INSERT INTO " . $wpdb->prefix . "post_views (id, type, period, count)
502
- VALUES (%d, %d, %s, %d)
503
- ON DUPLICATE KEY UPDATE count = count + %d", $id, $type, $period, $count, $count
504
- )
505
- );
506
- }
507
-
508
- /**
509
- * Check whether visitor is a bot.
510
- */
511
- private function is_robot() {
512
- if ( ! isset( $_SERVER['HTTP_USER_AGENT'] ) || (isset( $_SERVER['HTTP_USER_AGENT'] ) && trim( $_SERVER['HTTP_USER_AGENT'] ) === '') )
513
- return false;
514
-
515
- $robots = array(
516
- 'bot', 'b0t', 'Acme.Spider', 'Ahoy! The Homepage Finder', 'Alkaline', 'Anthill', 'Walhello appie', 'Arachnophilia', 'Arale', 'Araneo', 'ArchitextSpider', 'Aretha', 'ARIADNE', 'arks', 'AskJeeves', 'ASpider (Associative Spider)', 'ATN Worldwide', 'AURESYS', 'BackRub', 'Bay Spider', 'Big Brother', 'Bjaaland', 'BlackWidow', 'Die Blinde Kuh', 'Bloodhound', 'BSpider', 'CACTVS Chemistry Spider', 'Calif', 'Cassandra', 'Digimarc Marcspider/CGI', 'ChristCrawler.com', 'churl', 'cIeNcIaFiCcIoN.nEt', 'CMC/0.01', 'Collective', 'Combine System', 'Web Core / Roots', 'Cusco', 'CyberSpyder Link Test', 'CydralSpider', 'Desert Realm Spider', 'DeWeb(c) Katalog/Index', 'DienstSpider', 'Digger', 'Direct Hit Grabber', 'DownLoad Express', 'DWCP (Dridus\' Web Cataloging Project)', 'e-collector', 'EbiNess', 'Emacs-w3 Search Engine', 'ananzi', 'esculapio', 'Esther', 'Evliya Celebi', 'FastCrawler', 'Felix IDE', 'Wild Ferret Web Hopper #1, #2, #3', 'FetchRover', 'fido', 'KIT-Fireball', 'Fish search', 'Fouineur', 'Freecrawl', 'FunnelWeb', 'gammaSpider, FocusedCrawler', 'gazz', 'GCreep', 'GetURL', 'Golem', 'Grapnel/0.01 Experiment', 'Griffon', 'Gromit', 'Northern Light Gulliver', 'Harvest', 'havIndex', 'HI (HTML Index) Search', 'Hometown Spider Pro', 'ht://Dig', 'HTMLgobble', 'Hyper-Decontextualizer', 'IBM_Planetwide', 'Popular Iconoclast', 'Ingrid', 'Imagelock', 'IncyWincy', 'Informant', 'Infoseek Sidewinder', 'InfoSpiders', 'Inspector Web', 'IntelliAgent', 'Iron33', 'Israeli-search', 'JavaBee', 'JCrawler', 'Jeeves', 'JumpStation', 'image.kapsi.net', 'Katipo', 'KDD-Explorer', 'Kilroy', 'LabelGrabber', 'larbin', 'legs', 'Link Validator', 'LinkScan', 'LinkWalker', 'Lockon', 'logo.gif Crawler', 'Lycos', 'Mac WWWWorm', 'Magpie', 'marvin/infoseek', 'Mattie', 'MediaFox', 'MerzScope', 'NEC-MeshExplorer', 'MindCrawler', 'mnoGoSearch search engine software', 'moget', 'MOMspider', 'Monster', 'Motor', 'Muncher', 'Muninn', 'Muscat Ferret', 'Mwd.Search', 'Internet Shinchakubin', 'NDSpider', 'Nederland.zoek', 'NetCarta WebMap Engine', 'NetMechanic', 'NetScoop', 'newscan-online', 'NHSE Web Forager', 'Nomad', 'nzexplorer', 'ObjectsSearch', 'Occam', 'HKU WWW Octopus', 'OntoSpider', 'Openfind data gatherer', 'Orb Search', 'Pack Rat', 'PageBoy', 'ParaSite', 'Patric', 'pegasus', 'The Peregrinator', 'PerlCrawler 1.0', 'Phantom', 'PhpDig', 'PiltdownMan', 'Pioneer', 'html_analyzer', 'Portal Juice Spider', 'PGP Key Agent', 'PlumtreeWebAccessor', 'Poppi', 'PortalB Spider', 'GetterroboPlus Puu', 'Raven Search', 'RBSE Spider', 'RoadHouse Crawling System', 'ComputingSite Robi/1.0', 'RoboCrawl Spider', 'RoboFox', 'Robozilla', 'RuLeS', 'Scooter', 'Sleek', 'Search.Aus-AU.COM', 'SearchProcess', 'Senrigan', 'SG-Scout', 'ShagSeeker', 'Shai\'Hulud', 'Sift', 'Site Valet', 'SiteTech-Rover', 'Skymob.com', 'SLCrawler', 'Inktomi Slurp', 'Smart Spider', 'Snooper', 'Spanner', 'Speedy Spider', 'spider_monkey', 'Spiderline Crawler', 'SpiderMan', 'SpiderView(tm)', 'Site Searcher', 'Suke', 'suntek search engine', 'Sven', 'Sygol', 'TACH Black Widow', 'Tarantula', 'tarspider', 'Templeton', 'TeomaTechnologies', 'TITAN', 'TitIn', 'TLSpider', 'UCSD Crawl', 'UdmSearch', 'URL Check', 'URL Spider Pro', 'Valkyrie', 'Verticrawl', 'Victoria', 'vision-search', 'Voyager', 'W3M2', 'WallPaper (alias crawlpaper)', 'the World Wide Web Wanderer', 'w@pSpider by wap4.com', 'WebBandit Web Spider', 'WebCatcher', 'WebCopy', 'webfetcher', 'Webinator', 'weblayers', 'WebLinker', 'WebMirror', 'The Web Moose', 'WebQuest', 'Digimarc MarcSpider', 'WebReaper', 'webs', 'Websnarf', 'WebSpider', 'WebVac', 'webwalk', 'WebWalker', 'WebWatch', 'Wget', 'whatUseek Winona', 'Wired Digital', 'Weblog Monitor', 'w3mir', 'WebStolperer', 'The Web Wombat', 'The World Wide Web Worm', 'WWWC Ver 0.2.5', 'WebZinger', 'XGET'
517
- );
518
-
519
- foreach ( $robots as $robot ) {
520
- if ( stripos( $_SERVER['HTTP_USER_AGENT'], $robot ) !== false )
521
- return true;
522
- }
523
-
524
- return false;
525
- }
526
-
527
- }
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * Post_Views_Counter_Counter class.
8
+ */
9
+ class Post_Views_Counter_Counter {
10
+
11
+ const GROUP = 'pvc';
12
+ const NAME_ALLKEYS = 'cached_key_names';
13
+ const CACHE_KEY_SEPARATOR = '.';
14
+
15
+ private $cookie = array(
16
+ 'exists' => false,
17
+ 'visited_posts' => array(),
18
+ 'expiration' => 0
19
+ );
20
+
21
+ public function __construct() {
22
+ // actions
23
+ add_action( 'plugins_loaded', array( $this, 'check_cookie' ), 1 );
24
+ add_action( 'wp', array( $this, 'check_post' ) );
25
+ add_action( 'deleted_post', array( $this, 'delete_post_views' ) );
26
+ add_action( 'wp_ajax_pvc-check-post', array( $this, 'check_post_ajax' ) );
27
+ add_action( 'wp_ajax_nopriv_pvc-check-post', array( $this, 'check_post_ajax' ) );
28
+ }
29
+
30
+ /**
31
+ * Remove post views from database when post is deleted.
32
+ *
33
+ * @param int $post_id
34
+ */
35
+ public function delete_post_views( $post_id ) {
36
+ global $wpdb;
37
+
38
+ $wpdb->delete( $wpdb->prefix . 'post_views', array( 'id' => $post_id ), array( '%d' ) );
39
+ }
40
+
41
+ /**
42
+ *
43
+ * Get timestamp convertion.
44
+ *
45
+ * @param string $type
46
+ * @param int $number
47
+ * @param int $timestamp
48
+ * @return string
49
+ */
50
+ public function get_timestamp( $type, $number, $timestamp = true ) {
51
+ $converter = array(
52
+ 'minutes' => 60,
53
+ 'hours' => 3600,
54
+ 'days' => 86400,
55
+ 'weeks' => 604800,
56
+ 'months' => 2592000,
57
+ 'years' => 946080000
58
+ );
59
+
60
+ return ($timestamp ? current_time( 'timestamp', true ) : 0) + $number * $converter[$type];
61
+ }
62
+
63
+ /**
64
+ * Check whether to count visit via AJAX request.
65
+ */
66
+ public function check_post_ajax() {
67
+ if ( isset( $_POST['action'], $_POST['post_id'], $_POST['pvc_nonce'], $_POST['post_type'] ) && $_POST['action'] === 'pvc-check-post' && ($post_id = (int) $_POST['post_id']) > 0 && wp_verify_nonce( $_POST['pvc_nonce'], 'pvc-check-post' ) !== false && Post_Views_Counter()->options['general']['counter_mode'] === 'js' ) {
68
+ // get countable post types
69
+ $post_types = Post_Views_Counter()->options['general']['post_types_count'];
70
+
71
+ // get post type
72
+ $post_type = get_post_type( $post_id );
73
+
74
+ // whether to count this post type or not
75
+ if ( empty( $post_types ) || empty( $post_type ) || $post_type !== $_POST['post_type'] || ! in_array( $post_type, $post_types, true ) )
76
+ exit;
77
+
78
+ // get excluded ips
79
+ $excluded_ips = Post_Views_Counter()->options['general']['exclude_ips'];
80
+
81
+ // whether to count this ip or not
82
+ if ( ! empty( $excluded_ips ) && filter_var( preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] ), FILTER_VALIDATE_IP ) && in_array( $_SERVER['REMOTE_ADDR'], $excluded_ips, true ) )
83
+ exit;
84
+
85
+ // get groups to check them faster
86
+ $groups = Post_Views_Counter()->options['general']['exclude']['groups'];
87
+
88
+ // whether to count this user
89
+ if ( is_user_logged_in() ) {
90
+ // exclude logged in users?
91
+ if ( in_array( 'users', $groups, true ) )
92
+ exit;
93
+ // exclude specific roles?
94
+ elseif ( in_array( 'roles', $groups, true ) && $this->is_user_role_excluded( Post_Views_Counter()->options['general']['exclude']['roles'] ) )
95
+ exit;
96
+ }
97
+ // exclude guests?
98
+ elseif ( in_array( 'guests', $groups, true ) )
99
+ exit;
100
+
101
+ // whether to count robots
102
+ if ( $this->is_robot() )
103
+ exit;
104
+
105
+ // cookie already existed?
106
+ if ( $this->cookie['exists'] ) {
107
+ // post already viewed but not expired?
108
+ if ( in_array( $post_id, array_keys( $this->cookie['visited_posts'] ), true ) && current_time( 'timestamp', true ) < $this->cookie['visited_posts'][$post_id] ) {
109
+ // updates cookie but do not count visit
110
+ $this->save_cookie( $post_id, $this->cookie, false );
111
+
112
+ exit;
113
+ } else
114
+ // updates cookie
115
+ $this->save_cookie( $post_id, $this->cookie );
116
+ } else {
117
+ // set new cookie
118
+ $this->save_cookie( $post_id );
119
+ }
120
+
121
+ // count visit
122
+ $this->count_visit( $post_id );
123
+ }
124
+
125
+ exit;
126
+ }
127
+
128
+ /**
129
+ * Check whether to count visit.
130
+ */
131
+ public function check_post() {
132
+ // do not count admin entries
133
+ if ( is_admin() )
134
+ return;
135
+
136
+ // do we use PHP as counter?
137
+ if ( Post_Views_Counter()->options['general']['counter_mode'] === 'php' ) {
138
+ $post_types = Post_Views_Counter()->options['general']['post_types_count'];
139
+
140
+ // whether to count this post type
141
+ if ( empty( $post_types ) || ! is_singular( $post_types ) )
142
+ return;
143
+
144
+ $ips = Post_Views_Counter()->options['general']['exclude_ips'];
145
+
146
+ // whether to count this ip
147
+ if ( ! empty( $ips ) && filter_var( preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] ), FILTER_VALIDATE_IP ) && in_array( $_SERVER['REMOTE_ADDR'], $ips, true ) )
148
+ return;
149
+
150
+ // get groups to check them faster
151
+ $groups = Post_Views_Counter()->options['general']['exclude']['groups'];
152
+
153
+ // whether to count this user
154
+ if ( is_user_logged_in() ) {
155
+ // exclude logged in users?
156
+ if ( in_array( 'users', $groups, true ) )
157
+ return;
158
+ // exclude specific roles?
159
+ elseif ( in_array( 'roles', $groups, true ) && $this->is_user_role_excluded( Post_Views_Counter()->options['general']['exclude']['roles'] ) )
160
+ return;
161
+ }
162
+ // exclude guests?
163
+ elseif ( in_array( 'guests', $groups, true ) )
164
+ return;
165
+
166
+ // whether to count robots
167
+ if ( $this->is_robot() )
168
+ return;
169
+
170
+ // get post id
171
+ $id = get_the_ID();
172
+
173
+ // cookie already existed?
174
+ if ( $this->cookie['exists'] ) {
175
+ // post already viewed but not expired?
176
+ if ( in_array( $id, array_keys( $this->cookie['visited_posts'] ), true ) && current_time( 'timestamp', true ) < $this->cookie['visited_posts'][$id] ) {
177
+ // update cookie but do not count visit
178
+ $this->save_cookie( $id, $this->cookie, false );
179
+
180
+ return;
181
+ } else
182
+ // update cookie
183
+ $this->save_cookie( $id, $this->cookie );
184
+ } else
185
+ // set new cookie
186
+ $this->save_cookie( $id );
187
+
188
+ // count visit
189
+ $this->count_visit( $id );
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Initialize cookie session.
195
+ */
196
+ public function check_cookie() {
197
+ // do not run in admin except for ajax requests
198
+ if ( is_admin() && ! (defined( 'DOING_AJAX' ) && DOING_AJAX) )
199
+ return;
200
+
201
+ // is cookie set?
202
+ if ( isset( $_COOKIE['pvc_visits'] ) && ! empty( $_COOKIE['pvc_visits'] ) ) {
203
+ $visited_posts = $expirations = array();
204
+
205
+ foreach ( $_COOKIE['pvc_visits'] as $content ) {
206
+ // is cookie valid?
207
+ if ( preg_match( '/^(([0-9]+b[0-9]+a?)+)$/', $content ) === 1 ) {
208
+ // get single id with expiration
209
+ $expiration_ids = explode( 'a', $content );
210
+
211
+ // check every expiration => id pair
212
+ foreach ( $expiration_ids as $pair ) {
213
+ $pair = explode( 'b', $pair );
214
+ $expirations[] = (int) $pair[0];
215
+ $visited_posts[(int) $pair[1]] = (int) $pair[0];
216
+ }
217
+ }
218
+ }
219
+
220
+ $this->cookie = array(
221
+ 'exists' => true,
222
+ 'visited_posts' => $visited_posts,
223
+ 'expiration' => max( $expirations )
224
+ );
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Save cookie function.
230
+ *
231
+ * @param int $id
232
+ * @param array $cookie
233
+ * @param bool $expired
234
+ */
235
+ private function save_cookie( $id, $cookie = array(), $expired = true ) {
236
+ $expiration = $this->get_timestamp( Post_Views_Counter()->options['general']['time_between_counts']['type'], Post_Views_Counter()->options['general']['time_between_counts']['number'] );
237
+
238
+ // is this a new cookie?
239
+ if ( empty( $cookie ) ) {
240
+ // set cookie
241
+ setcookie( 'pvc_visits[0]', $expiration . 'b' . $id, $expiration, COOKIEPATH, COOKIE_DOMAIN, (isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ? true : false ), true );
242
+ } else {
243
+ if ( $expired ) {
244
+ // add new id or chang expiration date if id already exists
245
+ $cookie['visited_posts'][$id] = $expiration;
246
+ }
247
+
248
+ // create copy for better foreach performance
249
+ $visited_posts_expirations = $cookie['visited_posts'];
250
+
251
+ // get current gmt time
252
+ $time = current_time( 'timestamp', true );
253
+
254
+ // check whether viewed id has expired - no need to keep it in cookie (less size)
255
+ foreach ( $visited_posts_expirations as $post_id => $post_expiration ) {
256
+ if ( $time > $post_expiration )
257
+ unset( $cookie['visited_posts'][$post_id] );
258
+ }
259
+
260
+ // set new last expiration date if needed
261
+ $cookie['expiration'] = max( $cookie['visited_posts'] );
262
+
263
+ $cookies = $imploded = array();
264
+
265
+ // create pairs
266
+ foreach ( $cookie['visited_posts'] as $id => $exp ) {
267
+ $imploded[] = $exp . 'b' . $id;
268
+ }
269
+
270
+ // split cookie into chunks (4000 bytes to make sure it is safe for every browser)
271
+ $chunks = str_split( implode( 'a', $imploded ), 4000 );
272
+
273
+ // more then one chunk?
274
+ if ( count( $chunks ) > 1 ) {
275
+ $last_id = '';
276
+
277
+ foreach ( $chunks as $chunk_id => $chunk ) {
278
+ // new chunk
279
+ $chunk_c = $last_id . $chunk;
280
+
281
+ // is it full-length chunk?
282
+ if ( strlen( $chunk ) === 4000 ) {
283
+ // get last part
284
+ $last_part = strrchr( $chunk_c, 'a' );
285
+
286
+ // get last id
287
+ $last_id = substr( $last_part, 1 );
288
+
289
+ // add new full-lenght chunk
290
+ $cookies[$chunk_id] = substr( $chunk_c, 0, strlen( $chunk_c ) - strlen( $last_part ) );
291
+ } else {
292
+ // add last chunk
293
+ $cookies[$chunk_id] = $chunk_c;
294
+ }
295
+ }
296
+ } else {
297
+ // only one chunk
298
+ $cookies[] = $chunks[0];
299
+ }
300
+
301
+ foreach ( $cookies as $key => $value ) {
302
+ // set cookie
303
+ setcookie( 'pvc_visits[' . $key . ']', $value, $cookie['expiration'], COOKIEPATH, COOKIE_DOMAIN, (isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ? true : false ), true );
304
+ }
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Check if object cache is in use.
310
+ *
311
+ * @param bool $using
312
+ * @return bool
313
+ */
314
+ public function using_object_cache( $using = null ) {
315
+ $using = wp_using_ext_object_cache( $using );
316
+
317
+ if ( $using ) {
318
+ // check if explicitly disabled by flush_interval setting/option <= 0
319
+ $flush_interval_number = Post_Views_Counter()->options['general']['flush_interval']['number'];
320
+ $using = ( $flush_interval_number <= 0 ) ? false : true;
321
+ }
322
+
323
+ return $using;
324
+ }
325
+
326
+ /**
327
+ * Count visit function.
328
+ *
329
+ * @global object $wpdb
330
+ * @param int $id
331
+ * @return bool
332
+ */
333
+ private function count_visit( $id ) {
334
+ global $wpdb;
335
+
336
+ $cache_key_names = array();
337
+ $using_object_cache = $this->using_object_cache();
338
+
339
+ // get day, week, month and year
340
+ $date = explode( '-', date( 'W-d-m-Y', current_time( 'timestamp' ) ) );
341
+
342
+ foreach( array(
343
+ 0 => $date[3] . $date[2] . $date[1], // day like 20140324
344
+ 1 => $date[3] . $date[0], // week like 201439
345
+ 2 => $date[3] . $date[2], // month like 201405
346
+ 3 => $date[3], // year like 2014
347
+ 4 => 'total' // total views
348
+ ) as $type => $period ) {
349
+ if ( $using_object_cache ) {
350
+ $cache_key = $id . self::CACHE_KEY_SEPARATOR . $type . self::CACHE_KEY_SEPARATOR . $period;
351
+ wp_cache_add( $cache_key, 0, self::GROUP );
352
+ wp_cache_incr( $cache_key, 1, self::GROUP );
353
+ $cache_key_names[] = $cache_key;
354
+ } else {
355
+ // hit the db directly
356
+ // @TODO: investigate queueing these queries on the 'shutdown' hook instead instead of running them instantly?
357
+ $this->db_insert( $id, $type, $period, 1 );
358
+ }
359
+ }
360
+
361
+ // update the list of cache keys to be flushed
362
+ if ( $using_object_cache && ! empty( $cache_key_names ) ) {
363
+ $this->update_cached_keys_list_if_needed( $cache_key_names );
364
+ }
365
+
366
+ do_action( 'pvc_after_count_visit', $id );
367
+
368
+ return true;
369
+ }
370
+
371
+ /**
372
+ * Update the single cache key which holds a list of all the cache keys
373
+ * that need to be flushed to the db.
374
+ *
375
+ * The value of that special cache key is a giant string containing key names separated with the `|` character.
376
+ * Each such key name then consists of 3 elements: $id, $type, $period (separated by a `.` character).
377
+ * Examples:
378
+ * 62053.0.20150327|62053.1.201513|62053.2.201503|62053.3.2015|62053.4.total|62180.0.20150327|62180.1.201513|62180.2.201503|62180.3.2015|62180.4.total
379
+ * A single key is `62053.0.20150327` and that key's data is: $id = 62053, $type = 0, $period = 20150327
380
+ *
381
+ * This data format proved more efficient (avoids the (un)serialization overhead completely + duplicates filtering is a string search now)
382
+ *
383
+ * @param array $key_names
384
+ */
385
+ private function update_cached_keys_list_if_needed( $key_names = array() ) {
386
+ $existing_list = wp_cache_get( self::NAME_ALLKEYS, self::GROUP );
387
+ if ( ! $existing_list ) {
388
+ $existing_list = '';
389
+ }
390
+
391
+ $list_modified = false;
392
+
393
+ // modify the list contents if/when needed
394
+ if ( empty( $existing_list ) ) {
395
+ // the simpler case of an empty initial list where we just
396
+ // transform the specified key names into a string
397
+ $existing_list = implode( '|', $key_names );
398
+ $list_modified = true;
399
+ } else {
400
+ // search each specified key name and append it if it's not found
401
+ foreach ( $key_names as $key_name ) {
402
+ if ( false === strpos( $existing_list, $key_name ) ) {
403
+ $existing_list .= '|' . $key_name;
404
+ $list_modified = true;
405
+ }
406
+ }
407
+ }
408
+
409
+ // save modified list back in cache
410
+ if ( $list_modified ) {
411
+ wp_cache_set( self::NAME_ALLKEYS, $existing_list, self::GROUP );
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Flush views data stored in the persistent object cache into
417
+ * our custom table and clear the object cache keys when done.
418
+ *
419
+ * @global object $wpdb
420
+ * @return bool
421
+ */
422
+ public function flush_cache_to_db() {
423
+ global $wpdb;
424
+
425
+ $key_names = wp_cache_get( self::NAME_ALLKEYS, self::GROUP );
426
+
427
+ if ( ! $key_names ) {
428
+ $key_names = array();
429
+ } else {
430
+ // create an array out of a string that's stored in the cache
431
+ $key_names = explode( '|', $key_names );
432
+ }
433
+
434
+ foreach( $key_names as $key_name ) {
435
+ // get values stored within the key name itself
436
+ list( $id, $type, $period ) = explode( self::CACHE_KEY_SEPARATOR, $key_name );
437
+ // get the cached count value
438
+ $count = wp_cache_get( $key_name, self::GROUP );
439
+
440
+ // store cached value in the db
441
+ $this->db_insert( $id, $type, $period, $count );
442
+
443
+ // clear the cache key we just flushed
444
+ wp_cache_delete( $key_name, self::GROUP );
445
+ }
446
+
447
+ // delete the key holding the list itself after we've successfully flushed it
448
+ if ( ! empty( $key_names ) ) {
449
+ wp_cache_delete( self::NAME_ALLKEYS, self::GROUP );
450
+ }
451
+
452
+ return true;
453
+ }
454
+
455
+ /**
456
+ * Insert or update views count.
457
+ *
458
+ * @global object $wpdb
459
+ * @param int $id
460
+ * @param string $type
461
+ * @param string $period
462
+ * @param int $count
463
+ * @return bool
464
+ */
465
+ private function db_insert( $id, $type, $period, $count = 1 ) {
466
+ global $wpdb;
467
+
468
+ $count = (int) $count;
469
+
470
+ if ( ! $count ) {
471
+ $count = 1;
472
+ }
473
+
474
+ return $wpdb->query(
475
+ $wpdb->prepare( "
476
+ INSERT INTO " . $wpdb->prefix . "post_views (id, type, period, count)
477
+ VALUES (%d, %d, %s, %d)
478
+ ON DUPLICATE KEY UPDATE count = count + %d", $id, $type, $period, $count, $count
479
+ )
480
+ );
481
+ }
482
+
483
+ /**
484
+ * Check whether user has excluded roles.
485
+ *
486
+ * @param string $option
487
+ * @return bool
488
+ */
489
+ public function is_user_role_excluded( $option ) {
490
+ $user = wp_get_current_user();
491
+
492
+ if ( empty( $user ) )
493
+ return false;
494
+
495
+ $roles = (array) $user->roles;
496
+
497
+ if ( ! empty( $roles ) ) {
498
+ foreach ( $roles as $role ) {
499
+ if ( in_array( $role, $option, true ) )
500
+ return true;
501
+ }
502
+ }
503
+
504
+ return false;
505
+ }
506
+
507
+ /**
508
+ * Check whether visitor is a bot.
509
+ */
510
+ private function is_robot() {
511
+ if ( ! isset( $_SERVER['HTTP_USER_AGENT'] ) || (isset( $_SERVER['HTTP_USER_AGENT'] ) && trim( $_SERVER['HTTP_USER_AGENT'] ) === '') )
512
+ return false;
513
+
514
+ $robots = array(
515
+ 'bot', 'b0t', 'Acme.Spider', 'Ahoy! The Homepage Finder', 'Alkaline', 'Anthill', 'Walhello appie', 'Arachnophilia', 'Arale', 'Araneo', 'ArchitextSpider', 'Aretha', 'ARIADNE', 'arks', 'AskJeeves', 'ASpider (Associative Spider)', 'ATN Worldwide', 'AURESYS', 'BackRub', 'Bay Spider', 'Big Brother', 'Bjaaland', 'BlackWidow', 'Die Blinde Kuh', 'Bloodhound', 'BSpider', 'CACTVS Chemistry Spider', 'Calif', 'Cassandra', 'Digimarc Marcspider/CGI', 'ChristCrawler.com', 'churl', 'cIeNcIaFiCcIoN.nEt', 'CMC/0.01', 'Collective', 'Combine System', 'Web Core / Roots', 'Cusco', 'CyberSpyder Link Test', 'CydralSpider', 'Desert Realm Spider', 'DeWeb(c) Katalog/Index', 'DienstSpider', 'Digger', 'Direct Hit Grabber', 'DownLoad Express', 'DWCP (Dridus\' Web Cataloging Project)', 'e-collector', 'EbiNess', 'Emacs-w3 Search Engine', 'ananzi', 'esculapio', 'Esther', 'Evliya Celebi', 'FastCrawler', 'Felix IDE', 'Wild Ferret Web Hopper #1, #2, #3', 'FetchRover', 'fido', 'KIT-Fireball', 'Fish search', 'Fouineur', 'Freecrawl', 'FunnelWeb', 'gammaSpider, FocusedCrawler', 'gazz', 'GCreep', 'GetURL', 'Golem', 'Grapnel/0.01 Experiment', 'Griffon', 'Gromit', 'Northern Light Gulliver', 'Harvest', 'havIndex', 'HI (HTML Index) Search', 'Hometown Spider Pro', 'ht://Dig', 'HTMLgobble', 'Hyper-Decontextualizer', 'IBM_Planetwide', 'Popular Iconoclast', 'Ingrid', 'Imagelock', 'IncyWincy', 'Informant', 'Infoseek Sidewinder', 'InfoSpiders', 'Inspector Web', 'IntelliAgent', 'Iron33', 'Israeli-search', 'JavaBee', 'JCrawler', 'Jeeves', 'JumpStation', 'image.kapsi.net', 'Katipo', 'KDD-Explorer', 'Kilroy', 'LabelGrabber', 'larbin', 'legs', 'Link Validator', 'LinkScan', 'LinkWalker', 'Lockon', 'logo.gif Crawler', 'Lycos', 'Mac WWWWorm', 'Magpie', 'marvin/infoseek', 'Mattie', 'MediaFox', 'MerzScope', 'NEC-MeshExplorer', 'MindCrawler', 'mnoGoSearch search engine software', 'moget', 'MOMspider', 'Monster', 'Motor', 'Muncher', 'Muninn', 'Muscat Ferret', 'Mwd.Search', 'Internet Shinchakubin', 'NDSpider', 'Nederland.zoek', 'NetCarta WebMap Engine', 'NetMechanic', 'NetScoop', 'newscan-online', 'NHSE Web Forager', 'Nomad', 'nzexplorer', 'ObjectsSearch', 'Occam', 'HKU WWW Octopus', 'OntoSpider', 'Openfind data gatherer', 'Orb Search', 'Pack Rat', 'PageBoy', 'ParaSite', 'Patric', 'pegasus', 'The Peregrinator', 'PerlCrawler 1.0', 'Phantom', 'PhpDig', 'PiltdownMan', 'Pioneer', 'html_analyzer', 'Portal Juice Spider', 'PGP Key Agent', 'PlumtreeWebAccessor', 'Poppi', 'PortalB Spider', 'GetterroboPlus Puu', 'Raven Search', 'RBSE Spider', 'RoadHouse Crawling System', 'ComputingSite Robi/1.0', 'RoboCrawl Spider', 'RoboFox', 'Robozilla', 'RuLeS', 'Scooter', 'Sleek', 'Search.Aus-AU.COM', 'SearchProcess', 'Senrigan', 'SG-Scout', 'ShagSeeker', 'Shai\'Hulud', 'Sift', 'Site Valet', 'SiteTech-Rover', 'Skymob.com', 'SLCrawler', 'Inktomi Slurp', 'Smart Spider', 'Snooper', 'Spanner', 'Speedy Spider', 'spider_monkey', 'Spiderline Crawler', 'SpiderMan', 'SpiderView(tm)', 'Site Searcher', 'Suke', 'suntek search engine', 'Sven', 'Sygol', 'TACH Black Widow', 'Tarantula', 'tarspider', 'Templeton', 'TeomaTechnologies', 'TITAN', 'TitIn', 'TLSpider', 'UCSD Crawl', 'UdmSearch', 'URL Check', 'URL Spider Pro', 'Valkyrie', 'Verticrawl', 'Victoria', 'vision-search', 'Voyager', 'W3M2', 'WallPaper (alias crawlpaper)', 'the World Wide Web Wanderer', 'w@pSpider by wap4.com', 'WebBandit Web Spider', 'WebCatcher', 'WebCopy', 'webfetcher', 'Webinator', 'weblayers', 'WebLinker', 'WebMirror', 'The Web Moose', 'WebQuest', 'Digimarc MarcSpider', 'WebReaper', 'webs', 'Websnarf', 'WebSpider', 'WebVac', 'webwalk', 'WebWalker', 'WebWatch', 'Wget', 'whatUseek Winona', 'Wired Digital', 'Weblog Monitor', 'w3mir', 'WebStolperer', 'The Web Wombat', 'The World Wide Web Worm', 'WWWC Ver 0.2.5', 'WebZinger', 'XGET'
516
+ );
517
+
518
+ foreach( $robots as $robot ) {
519
+ if ( stripos( $_SERVER['HTTP_USER_AGENT'], $robot ) !== false )
520
+ return true;
521
+ }
522
+
523
+ return false;
524
+ }
525
+
526
+ }
 
includes/cron.php CHANGED
@@ -1,101 +1,99 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) )
3
- exit;
4
-
5
- new Post_Views_Counter_Cron();
6
-
7
- class Post_Views_Counter_Cron {
8
-
9
- public function __construct() {
10
- // set instance
11
- Post_Views_Counter()->add_instance( 'cron', $this );
12
-
13
- // actions
14
- add_action( 'init', array( &$this, 'check_cron' ) );
15
- add_action( 'pvc_reset_counts', array( &$this, 'reset_counts' ) );
16
- add_action( 'pvc_flush_cached_counts', array( &$this, 'flush_cached_counts' ) );
17
-
18
- // filters
19
- add_filter( 'cron_schedules', array( &$this, 'cron_time_intervals' ) );
20
- }
21
-
22
- /**
23
- * Reset daily counts.
24
- *
25
- * @global object $wpdb
26
- */
27
- public function reset_counts() {
28
- global $wpdb;
29
-
30
- $wpdb->query( 'DELETE FROM ' . $wpdb->prefix . 'post_views WHERE type = 0' );
31
- }
32
-
33
- /**
34
- * Call Post_Views_Counter_Counter::flush_cache_to_db().
35
- * This is (un)scheduled on plugin activation/deactivation.
36
- */
37
- public function flush_cached_counts() {
38
- $counter = Post_Views_Counter()->get_instance( 'counter' );
39
-
40
- if ( $counter && $counter->using_object_cache() ) {
41
- $counter->flush_cache_to_db();
42
- }
43
- }
44
-
45
- /**
46
- * Add new cron interval from settings.
47
- *
48
- * @param array $schedules
49
- * @return array
50
- */
51
- public function cron_time_intervals( $schedules ) {
52
- $schedules['post_views_counter_interval'] = array(
53
- 'interval' => Post_Views_Counter()->get_instance( 'counter' )->get_timestamp( Post_Views_Counter()->get_attribute( 'options', 'general', 'reset_counts', 'type' ), Post_Views_Counter()->get_attribute( 'options', 'general', 'reset_counts', 'number' ), false ),
54
- 'display' => __( 'Post Views Counter reset daily counts interval', 'post-views-counter' )
55
- );
56
-
57
- $schedules['post_views_counter_flush_interval'] = array(
58
- 'interval' => Post_Views_Counter()->get_instance( 'counter' )->get_timestamp( Post_Views_Counter()->get_attribute( 'options', 'general', 'flush_interval', 'type' ), Post_Views_Counter()->get_attribute( 'options', 'general', 'flush_interval', 'number' ), false ),
59
- 'display' => __( 'Post Views Counter cache flush interval', 'post-views-counter' )
60
- );
61
-
62
- return $schedules;
63
- }
64
-
65
- /**
66
- * Check whether WP Cron needs to add new task.
67
- */
68
- public function check_cron() {
69
- if ( ! is_admin() )
70
- return;
71
-
72
- // set wp cron task
73
- if ( Post_Views_Counter()->get_attribute( 'options', 'general', 'cron_run' ) ) {
74
-
75
- // not set or need to be updated?
76
- if ( ! wp_next_scheduled( 'pvc_reset_counts' ) || Post_Views_Counter()->get_attribute( 'options', 'general', 'cron_update' ) ) {
77
-
78
- // task is added but need to be updated
79
- if ( Post_Views_Counter()->get_attribute( 'options', 'general', 'cron_update' ) ) {
80
- // remove old schedule
81
- wp_clear_scheduled_hook( 'pvc_reset_counts' );
82
-
83
- // set update to false
84
- $general = Post_Views_Counter()->get_attribute( 'options', 'general' );
85
- $general['cron_update'] = false;
86
-
87
- // update settings
88
- update_option( 'post_views_counter_settings_general', $general );
89
- }
90
-
91
- // set schedule
92
- wp_schedule_event( Post_Views_Counter()->get_instance( 'counter' )->get_timestamp( Post_Views_Counter()->get_attribute( 'options', 'general', 'reset_counts', 'type' ), Post_Views_Counter()->get_attribute( 'options', 'general', 'reset_counts', 'number' ) ), 'post_views_counter_interval', 'pvc_reset_counts' );
93
- }
94
- } else {
95
- // remove schedule
96
- wp_clear_scheduled_hook( 'pvc_reset_counts' );
97
- remove_action( 'pvc_reset_counts', array( &$this, 'reset_counts' ) );
98
- }
99
- }
100
-
101
- }
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * Post_Views_Counter_Cron class.
8
+ */
9
+ class Post_Views_Counter_Cron {
10
+
11
+ public function __construct() {
12
+ // actions
13
+ add_action( 'init', array( $this, 'check_cron' ) );
14
+ add_action( 'pvc_reset_counts', array( $this, 'reset_counts' ) );
15
+ add_action( 'pvc_flush_cached_counts', array( $this, 'flush_cached_counts' ) );
16
+
17
+ // filters
18
+ add_filter( 'cron_schedules', array( $this, 'cron_time_intervals' ) );
19
+ }
20
+
21
+ /**
22
+ * Reset daily counts.
23
+ *
24
+ * @global object $wpdb
25
+ */
26
+ public function reset_counts() {
27
+ global $wpdb;
28
+
29
+ $wpdb->query( 'DELETE FROM ' . $wpdb->prefix . 'post_views WHERE type = 0' );
30
+ }
31
+
32
+ /**
33
+ * Call Post_Views_Counter_Counter::flush_cache_to_db().
34
+ * This is (un)scheduled on plugin activation/deactivation.
35
+ */
36
+ public function flush_cached_counts() {
37
+ $counter = Post_Views_Counter()->counter;
38
+
39
+ if ( $counter && $counter->using_object_cache() )
40
+ $counter->flush_cache_to_db();
41
+ }
42
+
43
+ /**
44
+ * Add new cron interval from settings.
45
+ *
46
+ * @param array $schedules
47
+ * @return array
48
+ */
49
+ public function cron_time_intervals( $schedules ) {
50
+ $schedules['post_views_counter_interval'] = array(
51
+ 'interval' => Post_Views_Counter()->counter->get_timestamp( Post_Views_Counter()->options['general']['reset_counts']['type'], Post_Views_Counter()->options['general']['reset_counts']['number'], false ),
52
+ 'display' => __( 'Post Views Counter reset daily counts interval', 'post-views-counter' )
53
+ );
54
+
55
+ $schedules['post_views_counter_flush_interval'] = array(
56
+ 'interval' => Post_Views_Counter()->counter->get_timestamp( Post_Views_Counter()->options['general']['flush_interval']['type'], Post_Views_Counter()->options['general']['flush_interval']['number'], false ),
57
+ 'display' => __( 'Post Views Counter cache flush interval', 'post-views-counter' )
58
+ );
59
+
60
+ return $schedules;
61
+ }
62
+
63
+ /**
64
+ * Check whether WP Cron needs to add new task.
65
+ */
66
+ public function check_cron() {
67
+ if ( ! is_admin() )
68
+ return;
69
+
70
+ // set wp cron task
71
+ if ( Post_Views_Counter()->options['general']['cron_run'] ) {
72
+
73
+ // not set or need to be updated?
74
+ if ( ! wp_next_scheduled( 'pvc_reset_counts' ) || Post_Views_Counter()->options['general']['cron_update'] ) {
75
+
76
+ // task is added but need to be updated
77
+ if ( Post_Views_Counter()->options['general']['cron_update'] ) {
78
+ // remove old schedule
79
+ wp_clear_scheduled_hook( 'pvc_reset_counts' );
80
+
81
+ // set update to false
82
+ $general = Post_Views_Counter()->options['general'];
83
+ $general['cron_update'] = false;
84
+
85
+ // update settings
86
+ update_option( 'post_views_counter_settings_general', $general );
87
+ }
88
+
89
+ // set schedule
90
+ wp_schedule_event( Post_Views_Counter()->counter->get_timestamp( Post_Views_Counter()->options['general']['reset_counts']['type'], Post_Views_Counter()->options['general']['reset_counts']['number'] ), 'post_views_counter_interval', 'pvc_reset_counts' );
91
+ }
92
+ } else {
93
+ // remove schedule
94
+ wp_clear_scheduled_hook( 'pvc_reset_counts' );
95
+ remove_action( 'pvc_reset_counts', array( $this, 'reset_counts' ) );
96
+ }
97
+ }
98
+
99
+ }
 
 
includes/frontend.php CHANGED
@@ -1,134 +1,134 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) )
3
- exit;
4
-
5
- new Post_Views_Counter_Frontend();
6
-
7
- class Post_Views_Counter_Frontend {
8
-
9
- public function __construct() {
10
- // actions
11
- add_action( 'after_setup_theme', array( &$this, 'register_shortcode' ) );
12
- add_action( 'wp_enqueue_scripts', array( &$this, 'frontend_scripts_styles' ) );
13
-
14
- // filters
15
- add_filter( 'the_content', array( &$this, 'add_post_views_count' ) );
16
- add_filter( 'the_excerpt', array( &$this, 'remove_post_views_count' ) );
17
- }
18
-
19
- /**
20
- * Register post-views shortcode function.
21
- */
22
- public function register_shortcode() {
23
- add_shortcode( 'post-views', array( &$this, 'post_views_shortcode' ) );
24
- }
25
-
26
- /**
27
- * Post views shortcode function.
28
- *
29
- * @param array $args
30
- * @return mixed
31
- */
32
- public function post_views_shortcode( $args ) {
33
- $defaults = array(
34
- 'id' => get_the_ID()
35
- );
36
-
37
- $args = shortcode_atts( $defaults, $args );
38
-
39
- return pvc_post_views( $args['id'], false );
40
- }
41
-
42
- /**
43
- * Add post views counter to content.
44
- *
45
- * @param mixed $content
46
- * @return mixed
47
- */
48
- public function add_post_views_count( $content ) {
49
- if ( is_singular() && in_array( get_post_type(), Post_Views_Counter()->get_attribute( 'options', 'display', 'post_types_display' ), true ) ) {
50
-
51
- // get groups to check it faster
52
- $groups = Post_Views_Counter()->get_attribute( 'options', 'display', 'restrict_display', 'groups' );
53
-
54
- // whether to display views
55
- if ( is_user_logged_in() ) {
56
- // exclude logged in users?
57
- if ( in_array( 'users', $groups, true ) )
58
- return $content;
59
- // exclude specific roles?
60
- elseif ( in_array( 'roles', $groups, true ) && Post_Views_Counter()->get_instance( 'counter' )->is_user_roles_excluded( Post_Views_Counter()->get_attribute( 'options', 'display', 'restrict_display', 'roles' ) ) )
61
- return $content;
62
- }
63
- // exclude guests?
64
- elseif ( in_array( 'guests', $groups, true ) )
65
- return $content;
66
-
67
- switch ( Post_Views_Counter()->get_attribute( 'options', 'display', 'position' ) ) {
68
- case 'after':
69
- return $content . '[post-views]';
70
-
71
- case 'before':
72
- return '[post-views]' . $content;
73
-
74
- default:
75
- case 'manual':
76
- return $content;
77
- }
78
- }
79
-
80
- return $content;
81
- }
82
-
83
- /**
84
- * Remove post views shortcode from excerpt.
85
- *
86
- * @param mixed $excerpt
87
- * @return mixed
88
- */
89
- public function remove_post_views_count( $excerpt ) {
90
- remove_shortcode( 'post-views' );
91
- $excerpt = preg_replace( '/\[post-views[^\]]*\]/', '', $excerpt );
92
- return $excerpt;
93
- }
94
-
95
- /**
96
- * Enqueue frontend scripts and styles.
97
- */
98
- public function frontend_scripts_styles() {
99
- $post_types = Post_Views_Counter()->get_attribute( 'options', 'display', 'post_types_display' );
100
-
101
- // load dashicons
102
- wp_enqueue_style( 'dashicons' );
103
-
104
- wp_register_style(
105
- 'post-views-counter-frontend', POST_VIEWS_COUNTER_URL . '/css/frontend.css'
106
- );
107
-
108
- wp_enqueue_style( 'post-views-counter-frontend' );
109
-
110
- if ( Post_Views_Counter()->get_attribute( 'options', 'general', 'counter_mode' ) === 'js' ) {
111
- $post_types = Post_Views_Counter()->get_attribute( 'options', 'general', 'post_types_count' );
112
-
113
- // whether to count this post type or not
114
- if ( empty( $post_types ) || ! is_singular( $post_types ) )
115
- return;
116
-
117
- wp_register_script(
118
- 'post-views-counter-frontend', POST_VIEWS_COUNTER_URL . '/js/frontend.js', array( 'jquery' )
119
- );
120
-
121
- wp_enqueue_script( 'post-views-counter-frontend' );
122
-
123
- wp_localize_script(
124
- 'post-views-counter-frontend', 'pvcArgsFrontend', array(
125
- 'ajaxURL' => admin_url( 'admin-ajax.php' ),
126
- 'postID' => get_the_ID(),
127
- 'nonce' => wp_create_nonce( 'pvc-check-post' ),
128
- 'postType' => get_post_type()
129
- )
130
- );
131
- }
132
- }
133
-
134
- }
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * Post_Views_Counter_Frontend class.
8
+ */
9
+ class Post_Views_Counter_Frontend {
10
+
11
+ public function __construct() {
12
+ // actions
13
+ add_action( 'after_setup_theme', array( $this, 'register_shortcode' ) );
14
+ add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts_styles' ) );
15
+
16
+ // filters
17
+ add_filter( 'the_content', array( $this, 'add_post_views_count' ) );
18
+ add_filter( 'the_excerpt', array( $this, 'remove_post_views_count' ) );
19
+ }
20
+
21
+ /**
22
+ * Register post-views shortcode function.
23
+ */
24
+ public function register_shortcode() {
25
+ add_shortcode( 'post-views', array( $this, 'post_views_shortcode' ) );
26
+ }
27
+
28
+ /**
29
+ * Post views shortcode function.
30
+ *
31
+ * @param array $args
32
+ * @return mixed
33
+ */
34
+ public function post_views_shortcode( $args ) {
35
+ $defaults = array(
36
+ 'id' => get_the_ID()
37
+ );
38
+
39
+ $args = shortcode_atts( $defaults, $args );
40
+
41
+ return pvc_post_views( $args['id'], false );
42
+ }
43
+
44
+ /**
45
+ * Add post views counter to content.
46
+ *
47
+ * @param mixed $content
48
+ * @return mixed
49
+ */
50
+ public function add_post_views_count( $content ) {
51
+ if ( is_singular() && in_array( get_post_type(), Post_Views_Counter()->options['display']['post_types_display'], true ) ) {
52
+
53
+ // get groups to check it faster
54
+ $groups = Post_Views_Counter()->options['display']['restrict_display']['groups'];
55
+
56
+ // whether to display views
57
+ if ( is_user_logged_in() ) {
58
+ // exclude logged in users?
59
+ if ( in_array( 'users', $groups, true ) )
60
+ return $content;
61
+ // exclude specific roles?
62
+ elseif ( in_array( 'roles', $groups, true ) && Post_Views_Counter()->_counter->is_user_roles_excluded( Post_Views_Counter()->options['display']['restrict_display']['roles'] ) )
63
+ return $content;
64
+ }
65
+ // exclude guests?
66
+ elseif ( in_array( 'guests', $groups, true ) )
67
+ return $content;
68
+
69
+ switch ( Post_Views_Counter()->options['display']['position'] ) {
70
+ case 'after':
71
+ return $content . '[post-views]';
72
+
73
+ case 'before':
74
+ return '[post-views]' . $content;
75
+
76
+ default:
77
+ case 'manual':
78
+ return $content;
79
+ }
80
+ }
81
+
82
+ return $content;
83
+ }
84
+
85
+ /**
86
+ * Remove post views shortcode from excerpt.
87
+ *
88
+ * @param mixed $excerpt
89
+ * @return mixed
90
+ */
91
+ public function remove_post_views_count( $excerpt ) {
92
+ remove_shortcode( 'post-views' );
93
+ $excerpt = preg_replace( '/\[post-views[^\]]*\]/', '', $excerpt );
94
+ return $excerpt;
95
+ }
96
+
97
+ /**
98
+ * Enqueue frontend scripts and styles.
99
+ */
100
+ public function frontend_scripts_styles() {
101
+ $post_types = Post_Views_Counter()->options['display']['post_types_display'];
102
+
103
+ // load dashicons
104
+ wp_enqueue_style( 'dashicons' );
105
+
106
+ // load style
107
+ wp_enqueue_style( 'post-views-counter-frontend', POST_VIEWS_COUNTER_URL . '/css/frontend.css' );
108
+
109
+ if ( Post_Views_Counter()->options['general']['counter_mode'] === 'js' ) {
110
+ $post_types = Post_Views_Counter()->options['general']['post_types_count'];
111
+
112
+ // whether to count this post type or not
113
+ if ( empty( $post_types ) || ! is_singular( $post_types ) )
114
+ return;
115
+
116
+ wp_register_script(
117
+ 'post-views-counter-frontend', POST_VIEWS_COUNTER_URL . '/js/frontend.js', array( 'jquery' )
118
+ );
119
+
120
+ wp_enqueue_script( 'post-views-counter-frontend' );
121
+
122
+ wp_localize_script(
123
+ 'post-views-counter-frontend',
124
+ 'pvcArgsFrontend',
125
+ array(
126
+ 'ajaxURL' => admin_url( 'admin-ajax.php' ),
127
+ 'postID' => get_the_ID(),
128
+ 'nonce' => wp_create_nonce( 'pvc-check-post' ),
129
+ 'postType' => get_post_type()
130
+ )
131
+ );
132
+ }
133
+ }
134
+ }
includes/functions.php CHANGED
@@ -1,204 +1,204 @@
1
- <?php
2
- /**
3
- * Post Views Counter pluggable template functions
4
- *
5
- * Override any of those functions by copying it to your theme or replace it via plugin
6
- *
7
- * @author Digital Factory
8
- * @package Post Views Counter
9
- * @since 1.0.0
10
- */
11
-
12
- if ( ! defined( 'ABSPATH' ) )
13
- exit;
14
-
15
- /**
16
- * Get post views for a post or array of posts.
17
- *
18
- * @param int|array $post_id
19
- * @return int
20
- */
21
- if ( ! function_exists( 'pvc_get_post_views' ) ) {
22
-
23
- function pvc_get_post_views( $post_id = 0 ) {
24
- if ( empty( $post_id ) )
25
- $post_id = get_the_ID();
26
-
27
- if ( is_array( $post_id ) )
28
- $post_id = implode( ',', array_map( 'intval', $post_id ) );
29
- else
30
- $post_id = (int) $post_id;
31
-
32
- global $wpdb;
33
-
34
- $post_views = (int) $wpdb->get_var( "
35
- SELECT SUM(count) AS views
36
- FROM " . $wpdb->prefix . "post_views
37
- WHERE id IN (" . $post_id . ") AND type = 4"
38
- );
39
-
40
- return apply_filters( 'pvc_get_post_views', $post_views, $post_id );
41
- }
42
-
43
- }
44
-
45
- /**
46
- * Display post views for a given post.
47
- *
48
- * @param int|array $post_id
49
- * @param bool $display
50
- * @return mixed
51
- */
52
- if ( ! function_exists( 'pvc_post_views' ) ) {
53
-
54
- function pvc_post_views( $post_id = 0, $display = true ) {
55
- // get all data
56
- $post_id = (int) (empty( $post_id ) ? get_the_ID() : $post_id);
57
- $options = Post_Views_Counter()->get_attribute( 'options', 'display' );
58
- $views = pvc_get_post_views( $post_id );
59
-
60
- // prepares display
61
- $label = apply_filters( 'pvc_post_views_label', (function_exists( 'icl_t' ) ? icl_t( 'Post Views Counter', 'Post Views Label', $options['label'] ) : $options['label'] ), $post_id );
62
- $icon_class = ($options['icon_class'] !== '' ? ' ' . esc_attr( $options['icon_class'] ) : '');
63
- $icon = apply_filters( 'pvc_post_views_icon', '<span class="post-views-icon dashicons ' . $icon_class . '"></span>', $post_id );
64
-
65
- $html = apply_filters(
66
- 'pvc_post_views_html', '<div class="post-views post-' . $post_id . ' entry-meta">
67
- ' . ($options['display_style']['icon'] && $icon_class !== '' ? $icon : '') . '
68
- ' . ($options['display_style']['text'] ? '<span class="post-views-label">' . $label . ' </span>' : '') . '
69
- <span class="post-views-count">' . number_format_i18n( $views ) . '</span>
70
- </div>', $post_id, $views, $label, $icon
71
- );
72
-
73
- if ( $display )
74
- echo $html;
75
- else
76
- return $html;
77
- }
78
-
79
- }
80
-
81
- /**
82
- * Get most viewed posts.
83
- *
84
- * @param array $args
85
- * @return array
86
- */
87
- if ( ! function_exists( 'pvc_get_most_viewed_posts' ) ) {
88
-
89
- function pvc_get_most_viewed_posts( $args = array() ) {
90
- $args = array_merge(
91
- array(
92
- 'posts_per_page' => 10,
93
- 'order' => 'desc',
94
- 'post_type' => 'post'
95
- ), $args
96
- );
97
-
98
- $args = apply_filters( 'pvc_get_most_viewed_posts_args', $args );
99
-
100
- // force to use filters
101
- $args['suppress_filters'] = false;
102
-
103
- // force to use post views as order
104
- $args['orderby'] = 'post_views';
105
-
106
- // force to get all fields
107
- $args['fields'] = '';
108
-
109
- return apply_filters( 'pvc_get_most_viewed_posts', get_posts( $args ), $args );
110
- }
111
-
112
- }
113
-
114
- /**
115
- * Display a list of most viewed posts.
116
- *
117
- * @param array $post_id
118
- * @param bool $display
119
- * @return mixed
120
- */
121
- if ( ! function_exists( 'pvc_most_viewed_posts' ) ) {
122
-
123
- function pvc_most_viewed_posts( $args = array(), $display = true ) {
124
- $defaults = array(
125
- 'number_of_posts' => 5,
126
- 'post_types' => array( 'post' ),
127
- 'order' => 'desc',
128
- 'thumbnail_size' => 'thumbnail',
129
- 'show_post_views' => true,
130
- 'show_post_thumbnail' => false,
131
- 'show_post_excerpt' => false,
132
- 'no_posts_message' => __( 'No Posts', 'post-views-counter' )
133
- );
134
-
135
- $args = apply_filters( 'pvc_most_viewed_posts_args', wp_parse_args( $args, $defaults ) );
136
-
137
- $args['show_post_views'] = (bool) $args['show_post_views'];
138
- $args['show_post_thumbnail'] = (bool) $args['show_post_thumbnail'];
139
- $args['show_post_excerpt'] = (bool) $args['show_post_excerpt'];
140
-
141
- $posts = pvc_get_most_viewed_posts(
142
- array(
143
- 'posts_per_page' => (isset( $args['number_of_posts'] ) ? (int) $args['number_of_posts'] : $defaults['number_of_posts']),
144
- 'order' => (isset( $args['order'] ) ? $args['order'] : $defaults['order']),
145
- 'post_type' => (isset( $args['post_types'] ) ? $args['post_types'] : $defaults['post_types'])
146
- )
147
- );
148
-
149
- if ( ! empty( $posts ) ) {
150
- $html = '
151
- <ul>';
152
-
153
- foreach ( $posts as $post ) {
154
- setup_postdata( $post );
155
-
156
- $html .= '
157
- <li>';
158
-
159
- if ( $args['show_post_thumbnail'] && has_post_thumbnail( $post->ID ) ) {
160
- $html .= '
161
- <span class="post-thumbnail">
162
- ' . get_the_post_thumbnail( $post->ID, $args['thumbnail_size'] ) . '
163
- </span>';
164
- }
165
-
166
- $html .= '
167
- <a class="post-title" href="' . get_permalink( $post->ID ) . '">' . get_the_title( $post->ID ) . '</a>' . ($args['show_post_views'] ? ' <span class="count">(' . number_format_i18n( pvc_get_post_views( $post->ID ) ) . ')</span>' : '');
168
-
169
- $excerpt = '';
170
-
171
- if ( $args['show_post_excerpt'] ) {
172
- if ( empty( $post->post_excerpt ) )
173
- $text = $post->post_content;
174
- else
175
- $text = $post->post_excerpt;
176
-
177
- if ( ! empty( $text ) )
178
- $excerpt = wp_trim_words( str_replace( ']]>', ']]&gt;', strip_shortcodes( $text ) ), apply_filters( 'excerpt_length', 55 ), apply_filters( 'excerpt_more', ' ' . '[&hellip;]' ) );
179
- }
180
-
181
- if ( ! empty( $excerpt ) )
182
- $html .= '
183
- <div class="post-excerpt">' . esc_html( $excerpt ) . '</div>';
184
-
185
- $html .= '
186
- </li>';
187
- }
188
-
189
- wp_reset_postdata();
190
-
191
- $html .= '
192
- </ul>';
193
- } else
194
- $html = $args['no_posts_message'];
195
-
196
- $html = apply_filters( 'pvc_most_viewed_posts_html', $html, $args );
197
-
198
- if ( $display )
199
- echo $html;
200
- else
201
- return $html;
202
- }
203
-
204
- }
1
+ <?php
2
+ /**
3
+ * Post Views Counter pluggable template functions
4
+ *
5
+ * Override any of those functions by copying it to your theme or replace it via plugin
6
+ *
7
+ * @author Digital Factory
8
+ * @package Post Views Counter
9
+ * @since 1.0.0
10
+ */
11
+
12
+ if ( ! defined( 'ABSPATH' ) )
13
+ exit;
14
+
15
+ /**
16
+ * Get post views for a post or array of posts.
17
+ *
18
+ * @param int|array $post_id
19
+ * @return int
20
+ */
21
+ if ( ! function_exists( 'pvc_get_post_views' ) ) {
22
+
23
+ function pvc_get_post_views( $post_id = 0 ) {
24
+ if ( empty( $post_id ) )
25
+ $post_id = get_the_ID();
26
+
27
+ if ( is_array( $post_id ) )
28
+ $post_id = implode( ',', array_map( 'intval', $post_id ) );
29
+ else
30
+ $post_id = (int) $post_id;
31
+
32
+ global $wpdb;
33
+
34
+ $post_views = (int) $wpdb->get_var( "
35
+ SELECT SUM(count) AS views
36
+ FROM " . $wpdb->prefix . "post_views
37
+ WHERE id IN (" . $post_id . ") AND type = 4"
38
+ );
39
+
40
+ return apply_filters( 'pvc_get_post_views', $post_views, $post_id );
41
+ }
42
+
43
+ }
44
+
45
+ /**
46
+ * Display post views for a given post.
47
+ *
48
+ * @param int|array $post_id
49
+ * @param bool $display
50
+ * @return mixed
51
+ */
52
+ if ( ! function_exists( 'pvc_post_views' ) ) {
53
+
54
+ function pvc_post_views( $post_id = 0, $display = true ) {
55
+ // get all data
56
+ $post_id = (int) (empty( $post_id ) ? get_the_ID() : $post_id);
57
+ $options = Post_Views_Counter()->options['display'];
58
+ $views = pvc_get_post_views( $post_id );
59
+
60
+ // prepares display
61
+ $label = apply_filters( 'pvc_post_views_label', (function_exists( 'icl_t' ) ? icl_t( 'Post Views Counter', 'Post Views Label', $options['label'] ) : $options['label'] ), $post_id );
62
+ $icon_class = ($options['icon_class'] !== '' ? ' ' . esc_attr( $options['icon_class'] ) : '');
63
+ $icon = apply_filters( 'pvc_post_views_icon', '<span class="post-views-icon dashicons ' . $icon_class . '"></span>', $post_id );
64
+
65
+ $html = apply_filters(
66
+ 'pvc_post_views_html', '<div class="post-views post-' . $post_id . ' entry-meta">
67
+ ' . ($options['display_style']['icon'] && $icon_class !== '' ? $icon : '') . '
68
+ ' . ($options['display_style']['text'] ? '<span class="post-views-label">' . $label . ' </span>' : '') . '
69
+ <span class="post-views-count">' . number_format_i18n( $views ) . '</span>
70
+ </div>', $post_id, $views, $label, $icon
71
+ );
72
+
73
+ if ( $display )
74
+ echo $html;
75
+ else
76
+ return $html;
77
+ }
78
+
79
+ }
80
+
81
+ /**
82
+ * Get most viewed posts.
83
+ *
84
+ * @param array $args
85
+ * @return array
86
+ */
87
+ if ( ! function_exists( 'pvc_get_most_viewed_posts' ) ) {
88
+
89
+ function pvc_get_most_viewed_posts( $args = array() ) {
90
+ $args = array_merge(
91
+ array(
92
+ 'posts_per_page' => 10,
93
+ 'order' => 'desc',
94
+ 'post_type' => 'post'
95
+ ), $args
96
+ );
97
+
98
+ $args = apply_filters( 'pvc_get_most_viewed_posts_args', $args );
99
+
100
+ // force to use filters
101
+ $args['suppress_filters'] = false;
102
+
103
+ // force to use post views as order
104
+ $args['orderby'] = 'post_views';
105
+
106
+ // force to get all fields
107
+ $args['fields'] = '';
108
+
109
+ return apply_filters( 'pvc_get_most_viewed_posts', get_posts( $args ), $args );
110
+ }
111
+
112
+ }
113
+
114
+ /**
115
+ * Display a list of most viewed posts.
116
+ *
117
+ * @param array $post_id
118
+ * @param bool $display
119
+ * @return mixed
120
+ */
121
+ if ( ! function_exists( 'pvc_most_viewed_posts' ) ) {
122
+
123
+ function pvc_most_viewed_posts( $args = array(), $display = true ) {
124
+ $defaults = array(
125
+ 'number_of_posts' => 5,
126
+ 'post_types' => array( 'post' ),
127
+ 'order' => 'desc',
128
+ 'thumbnail_size' => 'thumbnail',
129
+ 'show_post_views' => true,
130
+ 'show_post_thumbnail' => false,
131
+ 'show_post_excerpt' => false,
132
+ 'no_posts_message' => __( 'No Posts', 'post-views-counter' )
133
+ );
134
+
135
+ $args = apply_filters( 'pvc_most_viewed_posts_args', wp_parse_args( $args, $defaults ) );
136
+
137
+ $args['show_post_views'] = (bool) $args['show_post_views'];
138
+ $args['show_post_thumbnail'] = (bool) $args['show_post_thumbnail'];
139
+ $args['show_post_excerpt'] = (bool) $args['show_post_excerpt'];
140
+
141
+ $posts = pvc_get_most_viewed_posts(
142
+ array(
143
+ 'posts_per_page' => (isset( $args['number_of_posts'] ) ? (int) $args['number_of_posts'] : $defaults['number_of_posts']),
144
+ 'order' => (isset( $args['order'] ) ? $args['order'] : $defaults['order']),
145
+ 'post_type' => (isset( $args['post_types'] ) ? $args['post_types'] : $defaults['post_types'])
146
+ )
147
+ );
148
+
149
+ if ( ! empty( $posts ) ) {
150
+ $html = '
151
+ <ul>';
152
+
153
+ foreach ( $posts as $post ) {
154
+ setup_postdata( $post );
155
+
156
+ $html .= '
157
+ <li>';
158
+
159
+ if ( $args['show_post_thumbnail'] && has_post_thumbnail( $post->ID ) ) {
160
+ $html .= '
161
+ <span class="post-thumbnail">
162
+ ' . get_the_post_thumbnail( $post->ID, $args['thumbnail_size'] ) . '
163
+ </span>';
164
+ }
165
+
166
+ $html .= '
167
+ <a class="post-title" href="' . get_permalink( $post->ID ) . '">' . get_the_title( $post->ID ) . '</a>' . ($args['show_post_views'] ? ' <span class="count">(' . number_format_i18n( pvc_get_post_views( $post->ID ) ) . ')</span>' : '');
168
+
169
+ $excerpt = '';
170
+
171
+ if ( $args['show_post_excerpt'] ) {
172
+ if ( empty( $post->post_excerpt ) )
173
+ $text = $post->post_content;
174
+ else
175
+ $text = $post->post_excerpt;
176
+
177
+ if ( ! empty( $text ) )
178
+ $excerpt = wp_trim_words( str_replace( ']]>', ']]&gt;', strip_shortcodes( $text ) ), apply_filters( 'excerpt_length', 55 ), apply_filters( 'excerpt_more', ' ' . '[&hellip;]' ) );
179
+ }
180
+
181
+ if ( ! empty( $excerpt ) )
182
+ $html .= '
183
+ <div class="post-excerpt">' . esc_html( $excerpt ) . '</div>';
184
+
185
+ $html .= '
186
+ </li>';
187
+ }
188
+
189
+ wp_reset_postdata();
190
+
191
+ $html .= '
192
+ </ul>';
193
+ } else
194
+ $html = $args['no_posts_message'];
195
+
196
+ $html = apply_filters( 'pvc_most_viewed_posts_html', $html, $args );
197
+
198
+ if ( $display )
199
+ echo $html;
200
+ else
201
+ return $html;
202
+ }
203
+
204
+ }
includes/query.php CHANGED
@@ -1,112 +1,225 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) )
3
- exit;
4
-
5
- new Post_Views_Counter_Query();
6
-
7
- class Post_Views_Counter_Query {
8
-
9
- public function __construct() {
10
- // actions
11
- add_action( 'pre_get_posts', array( $this, 'extend_pre_query' ), 9 );
12
-
13
- // filters
14
- add_filter( 'posts_join', array( $this, 'posts_join' ), 10, 2 );
15
- add_filter( 'posts_groupby', array( $this, 'posts_groupby' ), 10, 2 );
16
- add_filter( 'posts_orderby', array( $this, 'posts_orderby' ), 10, 2 );
17
- add_filter( 'posts_fields', array( $this, 'posts_fields' ), 10, 2 );
18
- }
19
-
20
- /**
21
- * Extend query with post_views orderby parameter.
22
- *
23
- * @param object $query
24
- */
25
- public function extend_pre_query( $query ) {
26
- if ( isset( $query->query_vars['orderby'] ) && $query->query_vars['orderby'] === 'post_views' )
27
- $query->order_by_post_views = true;
28
- }
29
-
30
- /**
31
- * Modify the db query to use post_views parameter.
32
- *
33
- * @global object $wpdb
34
- * @param string $join
35
- * @param object $query
36
- * @return string
37
- */
38
- public function posts_join( $join, $query ) {
39
- // is it sorted by post views?
40
- if ( ( isset( $query->order_by_post_views ) && $query->order_by_post_views ) || apply_filters( 'pvc_extend_post_object', false, $query ) === true ) {
41
- global $wpdb;
42
-
43
- $join .= " LEFT JOIN " . $wpdb->prefix . "post_views pvc ON pvc.id = " . $wpdb->prefix . "posts.ID AND pvc.type = 4";
44
- }
45
-
46
- return $join;
47
- }
48
-
49
- /**
50
- * Group posts using the post ID.
51
- *
52
- * @global object $wpdb
53
- * @param string $groupby
54
- * @param object $query
55
- * @return string
56
- */
57
- public function posts_groupby( $groupby, $query ) {
58
- // is it sorted by post views?
59
- if ( ( isset( $query->order_by_post_views ) && $query->order_by_post_views ) || apply_filters( 'pvc_extend_post_object', false, $query ) === true ) {
60
- global $wpdb;
61
-
62
- $groupby = trim( $groupby );
63
-
64
- if ( strpos( $groupby, $wpdb->prefix . 'posts.ID' ) === false )
65
- $groupby = ( $groupby !== '' ? $groupby . ', ' : '') . $wpdb->prefix . 'posts.ID';
66
- }
67
-
68
- return $groupby;
69
- }
70
-
71
- /**
72
- * Order posts by post views.
73
- *
74
- * @global object $wpdb
75
- * @param string $orderby
76
- * @param object $query
77
- * @return string
78
- */
79
- public function posts_orderby( $orderby, $query ) {
80
- // is it sorted by post views?
81
- if ( isset( $query->order_by_post_views ) && $query->order_by_post_views ) {
82
- global $wpdb;
83
-
84
- $order = $query->get( 'order' );
85
- $orderby = 'pvc.count ' . $order . ', ' . $wpdb->prefix . 'posts.ID ' . $order;
86
- }
87
-
88
- return $orderby;
89
- }
90
-
91
- /**
92
- * Return post views in queried post objects.
93
- *
94
- * @global object $wpdb
95
- * @param string $fields
96
- * @param object $query
97
- * @return string
98
- */
99
- public function posts_fields( $fields, $query ) {
100
-
101
- if ( isset( $query->query['fields'] ) && ( $query->query['fields'] === '' || $query->query['fields'] === 'all' ) ) {
102
- // is it sorted by post views?
103
- if ( ( isset( $query->order_by_post_views ) && $query->order_by_post_views ) || apply_filters( 'pvc_extend_post_object', false, $query ) === true ) {
104
- global $wpdb;
105
-
106
- $fields = $fields . ', IFNULL( pvc.count, 0 ) AS post_views';
107
- }
108
- }
109
-
110
- return $fields;
111
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  }
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * Post_Views_Counter_Query class.
8
+ */
9
+ class Post_Views_Counter_Query {
10
+
11
+ public function __construct() {
12
+ // actions
13
+ add_action( 'pre_get_posts', array( $this, 'extend_pre_query' ), 1 );
14
+
15
+ // filters
16
+ add_filter( 'query_vars', array( $this, 'query_vars' ) );
17
+ add_filter( 'posts_join', array( $this, 'posts_join' ), 10, 2 );
18
+ add_filter( 'posts_groupby', array( $this, 'posts_groupby' ), 10, 2 );
19
+ add_filter( 'posts_orderby', array( $this, 'posts_orderby' ), 10, 2 );
20
+ add_filter( 'posts_fields', array( $this, 'posts_fields' ), 10, 2 );
21
+ }
22
+
23
+ /**
24
+ * Regiseter views_query var.
25
+ *
26
+ * @param array $query_vars
27
+ * @return array
28
+ */
29
+ public function query_vars( $query_vars ) {
30
+ $query_vars[] = 'views_query';
31
+
32
+ return $query_vars;
33
+ }
34
+
35
+ /**
36
+ * Extend query with post_views orderby parameter.
37
+ *
38
+ * @param object $query
39
+ */
40
+ public function extend_pre_query( $query ) {
41
+ if ( isset( $query->query_vars['orderby'] ) && $query->query_vars['orderby'] === 'post_views' )
42
+ $query->pvc_orderby = true;
43
+ }
44
+
45
+ /**
46
+ * Modify the db query to use post_views parameter.
47
+ *
48
+ * @global object $wpdb
49
+ * @param string $join
50
+ * @param object $query
51
+ * @return string
52
+ */
53
+ public function posts_join( $join, $query ) {
54
+ $sql = '';
55
+
56
+ if ( ! empty( $query->query['views_query'] ) ) {
57
+ if ( isset( $query->query['views_query']['year'] ) )
58
+ $year = (int)$query->query['views_query']['year'];
59
+
60
+ if ( isset( $query->query['views_query']['month'] ) )
61
+ $month = (int)$query->query['views_query']['month'];
62
+
63
+ if ( isset( $query->query['views_query']['week'] ) )
64
+ $week = (int)$query->query['views_query']['week'];
65
+
66
+ if ( isset( $query->query['views_query']['day'] ) )
67
+ $day = (int)$query->query['views_query']['day'];
68
+
69
+ // year
70
+ if ( isset( $year ) ) {
71
+ // year, week
72
+ if ( isset( $week ) && $this->is_valid_date( 'yw', $year, 0, 0, $week ) ) {
73
+ $sql = " AND pvc.type = 1 AND pvc.period = '" . str_pad( $year, 4, 0, STR_PAD_LEFT ) . str_pad( $week, 2, 0, STR_PAD_LEFT ) . "'";
74
+ // year, month
75
+ } elseif ( isset( $month ) ) {
76
+ // year, month, day
77
+ if ( isset( $day ) && $this->is_valid_date( 'ymd', $year, $month, $day ) ) {
78
+ $sql = " AND pvc.type = 0 AND pvc.period = '" . str_pad( $year, 4, 0, STR_PAD_LEFT ) . str_pad( $month, 2, 0, STR_PAD_LEFT ) . str_pad( $day, 2, 0, STR_PAD_LEFT ) . "'";
79
+ // year, month
80
+ } elseif ( $this->is_valid_date( 'ym', $year, $month ) ) {
81
+ $sql = " AND pvc.type = 2 AND pvc.period = '" . str_pad( $year, 4, 0, STR_PAD_LEFT ) . str_pad( $month, 2, 0, STR_PAD_LEFT ) . "'";
82
+ }
83
+ // year
84
+ } elseif ( $this->is_valid_date( 'y', $year ) ) {
85
+ $sql = " AND pvc.type = 3 AND pvc.period = '" . str_pad( $year, 4, 0, STR_PAD_LEFT ) . "'";
86
+ }
87
+ // month
88
+ } elseif ( isset( $month ) ) {
89
+ // month, day
90
+ if ( isset( $day ) && $this->is_valid_date( 'md', 0, $month, $day ) ) {
91
+ $sql = " AND pvc.type = 0 AND RIGHT( pvc.period, 4 ) = '" . str_pad( $month, 2, 0, STR_PAD_LEFT ) . str_pad( $day, 2, 0, STR_PAD_LEFT ) . "'";
92
+ // month
93
+ } elseif ( $this->is_valid_date( 'm', 0, $month ) ) {
94
+ $sql = " AND pvc.type = 2 AND RIGHT( pvc.period, 2 ) = '" . str_pad( $month, 2, 0, STR_PAD_LEFT ) . "'";
95
+ }
96
+ // week
97
+ } elseif ( isset( $week ) && $this->is_valid_date( 'w', 0, 0, 0, $week ) ) {
98
+ $sql = " AND pvc.type = 1 AND RIGHT( pvc.period, 2 ) = '" . str_pad( $week, 2, 0, STR_PAD_LEFT ) . "'";
99
+ // day
100
+ } elseif ( isset( $day ) && $this->is_valid_date( 'd', 0, 0, $day ) ) {
101
+ $sql = " AND pvc.type = 0 AND RIGHT( pvc.period, 2 ) = '" . str_pad( $day, 2, 0, STR_PAD_LEFT ) . "'";
102
+ }
103
+
104
+ if ( $sql !== '' )
105
+ $query->pvc_query = true;
106
+ }
107
+
108
+ // is it sorted by post views?
109
+ if ( ( $sql === '' && isset( $query->pvc_orderby ) && $query->pvc_orderby ) || apply_filters( 'pvc_extend_post_object', false, $query ) === true )
110
+ $sql = ' AND pvc.type = 4';
111
+
112
+ // add date range
113
+ if ( $sql !== '' ) {
114
+ global $wpdb;
115
+
116
+ $join .= " LEFT JOIN " . $wpdb->prefix . "post_views pvc ON pvc.id = " . $wpdb->prefix . "posts.ID" . $sql;
117
+ }
118
+
119
+ return $join;
120
+ }
121
+
122
+ /**
123
+ * Group posts using the post ID.
124
+ *
125
+ * @global object $wpdb
126
+ * @param string $groupby
127
+ * @param object $query
128
+ * @return string
129
+ */
130
+ public function posts_groupby( $groupby, $query ) {
131
+ // is it sorted by post views or views_query is used?
132
+ if ( ( isset( $query->pvc_orderby ) && $query->pvc_orderby ) || ( isset( $query->pvc_query ) && $query->pvc_query ) || apply_filters( 'pvc_extend_post_object', false, $query ) === true ) {
133
+ global $wpdb;
134
+
135
+ $groupby = trim( $groupby );
136
+
137
+ if ( strpos( $groupby, $wpdb->prefix . 'posts.ID' ) === false )
138
+ $groupby = ( $groupby !== '' ? $groupby . ', ' : '') . $wpdb->prefix . 'posts.ID';
139
+ }
140
+
141
+ return $groupby;
142
+ }
143
+
144
+ /**
145
+ * Order posts by post views.
146
+ *
147
+ * @global object $wpdb
148
+ * @param string $orderby
149
+ * @param object $query
150
+ * @return string
151
+ */
152
+ public function posts_orderby( $orderby, $query ) {
153
+ // is it sorted by post views?
154
+ if ( ( isset( $query->pvc_orderby ) && $query->pvc_orderby ) ) {
155
+ global $wpdb;
156
+
157
+ $order = $query->get( 'order' );
158
+ $orderby = 'pvc.count ' . $order . ', ' . $wpdb->prefix . 'posts.ID ' . $order;
159
+ }
160
+
161
+ return $orderby;
162
+ }
163
+
164
+ /**
165
+ * Return post views in queried post objects.
166
+ *
167
+ * @param string $fields
168
+ * @param object $query
169
+ * @return string
170
+ */
171
+ public function posts_fields( $fields, $query ) {
172
+ if ( ( ! isset( $query->query['fields'] ) || $query->query['fields'] === '' ) && ( ( isset( $query->pvc_orderby ) && $query->pvc_orderby ) || ( isset( $query->pvc_query ) && $query->pvc_query ) || apply_filters( 'pvc_extend_post_object', false, $query ) === true ) )
173
+ $fields = $fields . ', IFNULL( pvc.count, 0 ) AS post_views';
174
+
175
+ return $fields;
176
+ }
177
+
178
+ /**
179
+ * Validate date helper function.
180
+ *
181
+ * @param string $type
182
+ * @param int $year
183
+ * @param int $month
184
+ * @param int $day
185
+ * @param int $week
186
+ * @return bool
187
+ */
188
+ private function is_valid_date( $type, $year = 0, $month = 0, $day = 0, $week = 0 ) {
189
+ switch( $type ) {
190
+ case 'y':
191
+ $bool = ( $year >= 1 && $year <= 32767 );
192
+ break;
193
+
194
+ case 'yw':
195
+ $bool = ( $year >= 1 && $year <= 32767 && $week >= 0 && $week <= 53 );
196
+ break;
197
+
198
+ case 'ym':
199
+ $bool = ( $year >= 1 && $year <= 32767 && $month >= 1 && $month <= 12 );
200
+ break;
201
+
202
+ case 'ymd':
203
+ $bool = checkdate( $month, $day, $year );
204
+ break;
205
+
206
+ case 'm':
207
+ $bool = ( $month >= 1 && $month <= 12 );
208
+ break;
209
+
210
+ case 'md':
211
+ $bool = ( $month >= 1 && $month <= 12 && $day >= 1 && $day <= 31 );
212
+ break;
213
+
214
+ case 'w':
215
+ $bool = ( $week >= 0 && $week <= 53 );
216
+ break;
217
+
218
+ case 'd':
219
+ $bool = ( $day >= 1 && $day <= 31 );
220
+ break;
221
+ }
222
+
223
+ return $bool;
224
+ }
225
  }
includes/settings.php CHANGED
@@ -1,719 +1,720 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) )
3
- exit;
4
-
5
- new Post_Views_Counter_Settings();
6
-
7
- class Post_Views_Counter_Settings {
8
-
9
- private $tabs;
10
- private $choices;
11
- private $modes;
12
- private $time_types;
13
- private $groups;
14
- private $user_roles;
15
- private $positions;
16
- private $display_styles;
17
- public $post_types;
18
-
19
- public function __construct() {
20
- // set instance
21
- Post_Views_Counter()->add_instance( 'settings', $this );
22
-
23
- // actions
24
- add_action( 'admin_init', array( &$this, 'register_settings' ) );
25
- add_action( 'admin_menu', array( &$this, 'admin_menu_options' ) );
26
- add_action( 'after_setup_theme', array( &$this, 'load_defaults' ) );
27
- add_action( 'wp_loaded', array( &$this, 'load_post_types' ) );
28
- }
29
-
30
- /**
31
- * Load default settings.
32
- */
33
- public function load_defaults() {
34
-
35
- $this->modes = array(
36
- 'php' => __( 'PHP', 'post-views-counter' ),
37
- 'js' => __( 'JavaScript', 'post-views-counter' )
38
- );
39
-
40
- $this->time_types = array(
41
- 'minutes' => __( 'minutes', 'post-views-counter' ),
42
- 'hours' => __( 'hours', 'post-views-counter' ),
43
- 'days' => __( 'days', 'post-views-counter' ),
44
- 'weeks' => __( 'weeks', 'post-views-counter' ),
45
- 'months' => __( 'months', 'post-views-counter' ),
46
- 'years' => __( 'years', 'post-views-counter' )
47
- );
48
-
49
- $this->groups = array(
50
- 'robots' => __( 'robots', 'post-views-counter' ),
51
- 'users' => __( 'logged in users', 'post-views-counter' ),
52
- 'guests' => __( 'guests', 'post-views-counter' ),
53
- 'roles' => __( 'selected user roles', 'post-views-counter' )
54
- );
55
-
56
- $this->positions = array(
57
- 'before' => __( 'before the content', 'post-views-counter' ),
58
- 'after' => __( 'after the content', 'post-views-counter' ),
59
- 'manual' => __( 'manual', 'post-views-counter' )
60
- );
61
-
62
- $this->display_styles = array(
63
- 'icon' => __( 'icon', 'post-views-counter' ),
64
- 'text' => __( 'label', 'post-views-counter' )
65
- );
66
-
67
- $this->tabs = array(
68
- 'general' => array(
69
- 'name' => __( 'General', 'post-views-counter' ),
70
- 'key' => 'post_views_counter_settings_general',
71
- 'submit' => 'save_pvc_general',
72
- 'reset' => 'reset_pvc_general'
73
- ),
74
- 'display' => array(
75
- 'name' => __( 'Display', 'post-views-counter' ),
76
- 'key' => 'post_views_counter_settings_display',
77
- 'submit' => 'save_pvc_display',
78
- 'reset' => 'reset_pvc_display'
79
- )
80
- );
81
-
82
- $this->user_roles = $this->get_user_roles();
83
- }
84
-
85
- /**
86
- * Get post types avaiable for counting.
87
- */
88
- public function load_post_types() {
89
- $post_types = array();
90
-
91
- // built in public post types
92
- foreach ( get_post_types( array( '_builtin' => true, 'public' => true ), 'objects', 'and' ) as $key => $post_type ) {
93
- if ( $key !== 'attachment' )
94
- $post_types[$key] = $post_type->labels->name;
95
- }
96
-
97
- // public custom post types
98
- foreach ( get_post_types( array( '_builtin' => false, 'public' => true ), 'objects', 'and' ) as $key => $post_type ) {
99
- $post_types[$key] = $post_type->labels->name;
100
- }
101
-
102
- // sort post types alphabetically with their keys
103
- asort( $post_types, SORT_STRING );
104
-
105
- $this->post_types = $post_types;
106
- }
107
-
108
- /**
109
- * Get all user roles.
110
- */
111
- public function get_user_roles() {
112
- global $wp_roles;
113
-
114
- $roles = array();
115
-
116
- foreach ( apply_filters( 'editable_roles', $wp_roles->roles ) as $role => $details ) {
117
- $roles[$role] = translate_user_role( $details['name'] );
118
- }
119
-
120
- asort( $roles, SORT_STRING );
121
-
122
- return $roles;
123
- }
124
-
125
- /**
126
- * Add options page.
127
- */
128
- public function admin_menu_options() {
129
- add_options_page(
130
- __( 'Post Views Counter', 'post-views-counter' ), __( 'Post Views Counter', 'post-views-counter' ), 'manage_options', 'post-views-counter', array( &$this, 'options_page' )
131
- );
132
- }
133
-
134
- /**
135
- * Options page callback.
136
- */
137
- public function options_page() {
138
- $tab_key = (isset( $_GET['tab'] ) ? $_GET['tab'] : 'general');
139
-
140
- echo '
141
- <div class="wrap">' . screen_icon() . '
142
- <h2>' . __( 'Post Views Counter', 'post-views-counter' ) . '</h2>
143
- <h2 class="nav-tab-wrapper">';
144
-
145
- foreach ( $this->tabs as $key => $name ) {
146
- echo '
147
- <a class="nav-tab ' . ($tab_key == $key ? 'nav-tab-active' : '') . '" href="' . esc_url( admin_url( 'options-general.php?page=post-views-counter&tab=' . $key ) ) . '">' . $name['name'] . '</a>';
148
- }
149
-
150
- echo '
151
- </h2>
152
- <div class="post-views-counter-settings">
153
- <div class="df-credits">
154
- <h3 class="hndle">' . __( 'Post Views Counter', 'post-views-counter' ) . ' ' . Post_Views_Counter()->get_attribute( 'defaults', 'version' ) . '</h3>
155
- <div class="inside">
156
- <h4 class="inner">' . __( 'Need support?', 'post-views-counter' ) . '</h4>
157
- <p class="inner">' . __( 'If you are having problems with this plugin, please talk about them in the', 'post-views-counter' ) . ' <a href="http://www.dfactory.eu/support/?utm_source=post-views-counter-settings&utm_medium=link&utm_campaign=support" target="_blank" title="' . __( 'Support forum', 'post-views-counter' ) . '">' . __( 'Support forum', 'post-views-counter' ) . '</a></p>
158
- <hr />
159
- <h4 class="inner">' . __( 'Do you like this plugin?', 'post-views-counter' ) . '</h4>
160
- <p class="inner"><a href="http://wordpress.org/support/view/plugin-reviews/post-views-counter" target="_blank" title="' . __( 'Rate it 5', 'post-views-counter' ) . '">' . __( 'Rate it 5', 'post-views-counter' ) . '</a> ' . __( 'on WordPress.org', 'post-views-counter' ) . '<br />' .
161
- __( 'Blog about it & link to the', 'post-views-counter' ) . ' <a href="http://www.dfactory.eu/plugins/post-views-counter/?utm_source=post-views-counter-settings&utm_medium=link&utm_campaign=blog-about" target="_blank" title="' . __( 'plugin page', 'post-views-counter' ) . '">' . __( 'plugin page', 'post-views-counter' ) . '</a><br/>' .
162
- __( 'Check out our other', 'post-views-counter' ) . ' <a href="http://www.dfactory.eu/plugins/?utm_source=post-views-counter-settings&utm_medium=link&utm_campaign=other-plugins" target="_blank" title="' . __( 'WordPress plugins', 'post-views-counter' ) . '">' . __( 'WordPress plugins', 'post-views-counter' ) . '</a>
163
- </p>
164
- <hr />
165
- <p class="df-link inner">' . __( 'Created by', 'post-views-counter' ) . ' <a href="http://www.dfactory.eu/?utm_source=post-views-counter-settings&utm_medium=link&utm_campaign=created-by" target="_blank" title="dFactory - Quality plugins for WordPress"><img src="' . POST_VIEWS_COUNTER_URL . '/images/logo-dfactory.png' . '" title="dFactory - Quality plugins for WordPress" alt="dFactory - Quality plugins for WordPress" /></a></p>
166
- </div>
167
- </div>
168
- <form action="options.php" method="post">';
169
-
170
- wp_nonce_field( 'update-options' );
171
- settings_fields( $this->tabs[$tab_key]['key'] );
172
- do_settings_sections( $this->tabs[$tab_key]['key'] );
173
-
174
- echo '
175
- <p class="submit">';
176
-
177
- submit_button( '', 'primary', $this->tabs[$tab_key]['submit'], false );
178
-
179
- echo ' ';
180
-
181
- submit_button( __( 'Reset to defaults', 'post-views-counter' ), 'secondary reset_pvc_settings', $this->tabs[$tab_key]['reset'], false );
182
-
183
- echo '
184
- </p>
185
- </form>
186
- </div>
187
- <div class="clear"></div>
188
- </div>';
189
- }
190
-
191
- /**
192
- * Register settings callback.
193
- */
194
- public function register_settings() {
195
- // general options
196
- register_setting( 'post_views_counter_settings_general', 'post_views_counter_settings_general', array( &$this, 'validate_settings' ) );
197
- add_settings_section( 'post_views_counter_settings_general', __( 'General settings', 'post-views-counter' ), '', 'post_views_counter_settings_general' );
198
- add_settings_field( 'pvc_post_types_count', __( 'Post Types Count', 'post-views-counter' ), array( &$this, 'post_types_count' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
199
- add_settings_field( 'pvc_counter_mode', __( 'Counter Mode', 'post-views-counter' ), array( &$this, 'counter_mode' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
200
- add_settings_field( 'pvc_post_views_column', __( 'Post Views Column', 'post-views-counter' ), array( &$this, 'post_views_column' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
201
- add_settings_field( 'pvc_restrict_edit_views', __( 'Restrict Edit', 'post-views-counter' ), array( &$this, 'restrict_edit_views' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
202
- add_settings_field( 'pvc_time_between_counts', __( 'Time Between Counts', 'post-views-counter' ), array( &$this, 'time_between_counts' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
203
- add_settings_field( 'pvc_reset_counts', __( 'Reset Data Interval', 'post-views-counter' ), array( &$this, 'reset_counts' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
204
- add_settings_field( 'pvc_flush_interval', __( 'Flush Object Cache Interval', 'post-views-counter' ), array( &$this, 'flush_interval' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
205
- add_settings_field( 'pvc_exclude', __( 'Exclude Visitors', 'post-views-counter' ), array( &$this, 'exclude' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
206
- add_settings_field( 'pvc_exclude_ips', __( 'Exclude IPs', 'post-views-counter' ), array( &$this, 'exclude_ips' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
207
- add_settings_field( 'pvc_wp_postviews', __( 'WP-PostViews', 'post-views-counter' ), array( &$this, 'wp_postviews' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
208
- add_settings_field( 'pvc_deactivation_delete', __( 'Deactivation', 'post-views-counter' ), array( &$this, 'deactivation_delete' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
209
-
210
- // display options
211
- register_setting( 'post_views_counter_settings_display', 'post_views_counter_settings_display', array( &$this, 'validate_settings' ) );
212
- add_settings_section( 'post_views_counter_settings_display', __( 'Display settings', 'post-views-counter' ), '', 'post_views_counter_settings_display' );
213
- add_settings_field( 'pvc_post_views_label', __( 'Post Views Label', 'post-views-counter' ), array( &$this, 'post_views_label' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
214
- add_settings_field( 'pvc_post_types_display', __( 'Post Types Display', 'post-views-counter' ), array( &$this, 'post_types_display' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
215
- add_settings_field( 'pvc_restrict_display', __( 'Restrict Display', 'post-views-counter' ), array( &$this, 'restrict_display' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
216
- add_settings_field( 'pvc_position', __( 'Position', 'post-views-counter' ), array( &$this, 'position' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
217
- add_settings_field( 'pvc_display_style', __( 'Display Style', 'post-views-counter' ), array( &$this, 'display_style' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
218
- add_settings_field( 'pvc_icon_class', __( 'Icon Class', 'post-views-counter' ), array( &$this, 'icon_class' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
219
- }
220
-
221
- /**
222
- * Post views label option.
223
- */
224
- public function post_views_label() {
225
- echo '
226
- <div id="pvc_post_views_label">
227
- <fieldset>
228
- <input type="text" class="large-text" name="post_views_counter_settings_display[label]" value="' . esc_attr( Post_Views_Counter()->get_attribute( 'options', 'display', 'label' ) ) . '" />
229
- <p class="description">' . esc_html__( 'Enter the label for the post views counter field.', 'post-views-counter' ) . '</p>
230
- </fieldset>
231
- </div>';
232
- }
233
-
234
- /**
235
- * Post types to count option.
236
- */
237
- public function post_types_count() {
238
- echo '
239
- <div id="pvc_post_types_count">';
240
-
241
- foreach ( $this->post_types as $post_type => $post_type_name ) {
242
- echo '
243
- <label class="cb-checkbox"><input id="pvc_post_types_count-' . esc_attr( $post_type ) . '" type="checkbox" name="post_views_counter_settings_general[post_types_count][' . esc_attr( $post_type ) . ']" value="1" ' . checked( in_array( $post_type, Post_Views_Counter()->get_attribute( 'options', 'general', 'post_types_count' ), true ), true, false ) . ' />' . esc_html( $post_type_name ) . ' </label>';
244
- }
245
-
246
- echo '
247
- <p class="description">' . esc_html__( 'Select post types for which post views will be counted.', 'post-views-counter' ) . '</p>
248
- </div>';
249
- }
250
-
251
- /**
252
- * Post types to display option.
253
- */
254
- public function post_types_display() {
255
- echo '
256
- <div id="pvc_post_types_display">';
257
-
258
- foreach ( $this->post_types as $post_type => $post_type_name ) {
259
- echo '
260
- <label class="cb-checkbox"><input id="pvc_post_types_display-' . esc_attr( $post_type ) . '" type="checkbox" name="post_views_counter_settings_display[post_types_display][' . esc_attr( $post_type ) . ']" value="1" ' . checked( in_array( $post_type, Post_Views_Counter()->get_attribute( 'options', 'display', 'post_types_display' ), true ), true, false ) . ' />' . esc_html( $post_type_name ) . '</label>';
261
- }
262
-
263
- echo '
264
- <p class="description">' . esc_html__( 'Select post types for which post views will be displayed.', 'post-views-counter' ) . '</p>
265
- </div>';
266
- }
267
-
268
- /**
269
- * Counter mode option.
270
- */
271
- public function counter_mode() {
272
- echo '
273
- <div id="pvc_counter_mode">';
274
-
275
- foreach ( $this->modes as $key => $value ) {
276
- $key = esc_attr( $key );
277
-
278
- echo '
279
- <label class="cb-radio"><input type="radio" name="post_views_counter_settings_general[counter_mode]" value="' . $key . '" ' . checked( $key, Post_Views_Counter()->get_attribute( 'options', 'general', 'counter_mode' ), false ) . ' />' . esc_html( $value ) . '</label>';
280
- }
281
-
282
- echo '
283
- <p class="description">' . esc_html__( 'Select the method of collecting post views data. If you are using any of the caching plugins select Javascript.', 'post-views-counter' ) . '</p>
284
- </div>';
285
- }
286
-
287
- /**
288
- * Post views column option.
289
- */
290
- public function post_views_column() {
291
- echo '
292
- <div id="pvc_post_views_column">
293
- <label class="cb-checkbox"><input id="pvc-post-views-column-enable" type="checkbox" name="post_views_counter_settings_general[post_views_column]" value="1" ' . checked( true, (bool) Post_Views_Counter()->get_attribute( 'options', 'general', 'post_views_column' ), false ) . ' />' . esc_html__( 'Enable to display post views count column for each of the selected post types.', 'post-views-counter' ) . '</label>
294
- </div>';
295
- }
296
-
297
- /**
298
- * Time between counts option.
299
- */
300
- public function time_between_counts() {
301
- echo '
302
- <div id="pvc_time_between_counts">
303
- <input size="4" type="text" name="post_views_counter_settings_general[time_between_counts][number]" value="' . esc_attr( Post_Views_Counter()->get_attribute( 'options', 'general', 'time_between_counts', 'number' ) ) . '" />
304
- <select class="pvc-chosen-short" name="post_views_counter_settings_general[time_between_counts][type]">';
305
-
306
- foreach ( $this->time_types as $type => $type_name ) {
307
- echo '
308
- <option value="' . esc_attr( $type ) . '" ' . selected( $type, Post_Views_Counter()->get_attribute( 'options', 'general', 'time_between_counts', 'type' ), false ) . '>' . esc_html( $type_name ) . '</option>';
309
- }
310
-
311
- echo '
312
- </select>
313
- <p class="description">' . esc_html__( 'Enter the time between single user visit count.', 'post-views-counter' ) . '</p>
314
- </div>';
315
- }
316
-
317
- /**
318
- * Reset counts option.
319
- */
320
- public function reset_counts() {
321
- echo '
322
- <div id="pvc_reset_counts">
323
- <input size="4" type="text" name="post_views_counter_settings_general[reset_counts][number]" value="' . esc_attr( Post_Views_Counter()->get_attribute( 'options', 'general', 'reset_counts', 'number' ) ) . '" />
324
- <select class="pvc-chosen-short" name="post_views_counter_settings_general[reset_counts][type]">';
325
-
326
- foreach ( $this->time_types as $type => $type_name ) {
327
- echo '
328
- <option value="' . esc_attr( $type ) . '" ' . selected( $type, Post_Views_Counter()->get_attribute( 'options', 'general', 'reset_counts', 'type' ), false ) . '>' . esc_html( $type_name ) . '</option>';
329
- }
330
-
331
- echo '
332
- </select>
333
- <p class="description">' . esc_html__( 'Delete single day post views data older than specified above. Enter 0 (number zero) if you want to preserve your data regardless of its age.', 'post-views-counter' ) . '</p>
334
- </div>';
335
- }
336
-
337
- /**
338
- * Flush interval option.
339
- */
340
- public function flush_interval() {
341
- echo '
342
- <div id="pvc_flush_interval">
343
- <input size="4" type="text" name="post_views_counter_settings_general[flush_interval][number]" value="' . esc_attr( Post_Views_Counter()->get_attribute( 'options', 'general', 'flush_interval', 'number' ) ) . '" />
344
- <select class="pvc-chosen-short" name="post_views_counter_settings_general[flush_interval][type]">';
345
-
346
- foreach ( $this->time_types as $type => $type_name ) {
347
- echo '
348
- <option value="' . esc_attr( $type ) . '" ' . selected( $type, Post_Views_Counter()->get_attribute( 'options', 'general', 'flush_interval', 'type' ), false ) . '>' . esc_html( $type_name ) . '</option>';
349
- }
350
-
351
- echo '
352
- </select>
353
- <p class="description">' . __( 'How often to flush cached view counts from the object cache into the database. This feature is used only if a persistent object cache is detected and the interval is greater than 0 (number zero)). When used, view counts will be collected and stored in the object cache instead of the database and will then be asynchronously flushed to the database according to the specified interval.<br /><strong>Notice:</strong> Potential data loss may occur if the object cache is cleared/unavailable for the duration of the interval.', 'post-views-counter' ) . '</p>
354
- </div>';
355
- }
356
-
357
- /**
358
- * Exlude user groups option.
359
- */
360
- public function exclude() {
361
- echo '
362
- <div id="pvc_exclude">
363
- <fieldset>';
364
-
365
- foreach ( $this->groups as $type => $type_name ) {
366
- echo '
367
- <label class="cb-checkbox"><input id="pvc_exclude-' . $type . '" type="checkbox" name="post_views_counter_settings_general[exclude][groups][' . $type . ']" value="1" ' . checked( in_array( $type, Post_Views_Counter()->get_attribute( 'options', 'general', 'exclude', 'groups' ), true ), true, false ) . ' />' . esc_html( $type_name ) . '</label>';
368
- }
369
-
370
- echo ' <p class="description">' . esc_html__( 'Use it to hide the post views counter from selected type of visitors.', 'post-views-counter' ) . '</p>
371
- <div class="pvc_user_roles"' . (in_array( 'roles', Post_Views_Counter()->get_attribute( 'options', 'general', 'exclude', 'groups' ), true ) ? '' : ' style="display: none;"') . '>';
372
-
373
- foreach ( $this->user_roles as $role => $role_name ) {
374
- echo ' <label class="cb-checkbox"><input type="checkbox" name="post_views_counter_settings_general[exclude][roles][' . $role . ']" value="1" ' . checked( in_array( $role, Post_Views_Counter()->get_attribute( 'options', 'general', 'exclude', 'roles' ), true ), true, false ) . '>' . esc_html( $role_name ) . '</label>';
375
- }
376
-
377
- echo ' <p class="description">' . esc_html__( 'Use it to hide the post views counter from selected user roles.', 'post-views-counter' ) . '</p>
378
- </div>
379
- </fieldset>
380
- </div>';
381
- }
382
-
383
- /**
384
- * Exclude IPs option.
385
- */
386
- public function exclude_ips() {
387
- // lovely php 5.2 limitations
388
- $ips = Post_Views_Counter()->get_attribute( 'options', 'general', 'exclude_ips' );
389
-
390
- echo '
391
- <div id="pvc_exclude_ips">';
392
-
393
- if ( ! empty( $ips ) ) {
394
- foreach ( $ips as $key => $ip ) {
395
- echo '
396
- <div class="ip-box">
397
- <input type="text" name="post_views_counter_settings_general[exclude_ips][]" value="' . esc_attr( $ip ) . '" /> <a href="#" class="remove-exclude-ip" title="' . esc_attr__( 'Remove', 'post-views-counter' ) . '">' . esc_attr__( 'Remove', 'post-views-counter' ) . '</a>
398
- </div>';
399
- }
400
- } else {
401
- echo '
402
- <div class="ip-box">
403
- <input type="text" name="post_views_counter_settings_general[exclude_ips][]" value="" /> <a href="#" class="remove-exclude-ip" title="' . esc_attr__( 'Remove', 'post-views-counter' ) . '">' . esc_attr__( 'Remove', 'post-views-counter' ) . '</a>
404
- </div>';
405
- }
406
-
407
- echo '
408
- <p><input type="button" class="button button-secondary add-exclude-ip" value="' . esc_attr__( 'Add new', 'post-views-counter' ) . '" /> <input type="button" class="button button-secondary add-current-ip" value="' . esc_attr__( 'Add my current IP', 'post-views-counter' ) . '" data-rel="' . esc_attr( $_SERVER['REMOTE_ADDR'] ) . '" /></p>
409
- <p class="description">' . esc_html__( 'Enter the IP addresses to be excluded from post views count.', 'post-views-counter' ) . '</p>
410
- </div>';
411
- }
412
-
413
- /**
414
- * WP-PostViews import option.
415
- */
416
- public function wp_postviews() {
417
- echo '
418
- <div id="pvc_wp_postviews">
419
- <fieldset>
420
- <input type="submit" class="button button-secondary" name="post_views_counter_import_wp_postviews" value="' . __( 'Import', 'post-views-counter' ) . '"/>
421
- <p class="description">' . esc_html__( 'Import post views data from WP-PostViews plugin.', 'post-views-counter' ) . '</p>
422
- <label class="cb-checkbox"><input id="pvc-wp-postviews" type="checkbox" name="post_views_counter_import_wp_postviews_override" value="1" />' . esc_html__( 'Override existing Post Views Counter data.', 'post-views-counter' ) . '</label>
423
- </fieldset>
424
- </div>';
425
- }
426
-
427
- /**
428
- * Limit views edit to admins.
429
- */
430
- public function restrict_edit_views() {
431
- echo '
432
- <div id="pvc_restrict_edit_views">
433
- <label class="cb-checkbox"><input type="checkbox" name="post_views_counter_settings_general[restrict_edit_views]" value="1" ' . checked( true, (bool) Post_Views_Counter()->get_attribute( 'options', 'general', 'restrict_edit_views' ), false ) . ' />' . esc_html__( 'Enable to restrict post views editing to admins only.', 'post-views-counter' ) . '</label>
434
- </div>';
435
- }
436
-
437
- /**
438
- * Plugin deactivation option.
439
- */
440
- public function deactivation_delete() {
441
- echo '
442
- <div id="pvc_deactivation_delete">
443
- <label class="cb-checkbox"><input type="checkbox" name="post_views_counter_settings_general[deactivation_delete]" value="1" ' . checked( true, (bool) Post_Views_Counter()->get_attribute( 'options', 'general', 'deactivation_delete' ), false ) . ' />' . esc_html__( 'Enable to delete all plugin data on deactivation.', 'post-views-counter' ) . '</label>
444
- </div>';
445
- }
446
-
447
- /**
448
- * Counter position option.
449
- */
450
- public function position() {
451
- echo '
452
- <div id="pvc_position">
453
- <select class="pvc-chosen-short" name="post_views_counter_settings_display[position]">';
454
-
455
- foreach ( $this->positions as $position => $position_name ) {
456
- echo '
457
- <option value="' . esc_attr( $position ) . '" ' . selected( $position, Post_Views_Counter()->get_attribute( 'options', 'display', 'position' ), false ) . '>' . esc_html( $position_name ) . '</option>';
458
- }
459
-
460
- echo '
461
- </select>
462
- <p class="description">' . esc_html__( 'Select where would you like to display the post views counter. Use [post-views] shortcode for manual display.', 'post-views-counter' ) . '</p>
463
- </div>';
464
- }
465
-
466
- /**
467
- * Counter style option.
468
- */
469
- public function display_style() {
470
- echo '
471
- <div id="pvc_display_style">';
472
-
473
- foreach ( $this->display_styles as $display => $style ) {
474
- $display = esc_attr( $display );
475
-
476
- echo '
477
- <label class="cb-checkbox"><input type="checkbox" name="post_views_counter_settings_display[display_style][' . $display . ']" value="1" ' . checked( true, Post_Views_Counter()->get_attribute( 'options', 'display', 'display_style', $display ), false ) . ' />' . esc_html( $style ) . '</label>';
478
- }
479
-
480
- echo '
481
- <p class="description">' . esc_html__( 'Choose how to display the post views counter.', 'post-views-counter' ) . '</p>
482
- </div>';
483
- }
484
-
485
- /**
486
- * Counter icon class option.
487
- */
488
- public function icon_class() {
489
- echo '
490
- <div id="pvc_icon_class">
491
- <input type="text" name="post_views_counter_settings_display[icon_class]" class="large-text" value="' . esc_attr( Post_Views_Counter()->get_attribute( 'options', 'display', 'icon_class' ) ) . '" />
492
- <p class="description">' . sprintf( __( 'Enter the post views icon class. Any of the <a href="%s" target="_blank">Dashicons</a> classes are available.', 'post-views-counter' ), 'http://melchoyce.github.io/dashicons/' ) . '</p>
493
- </div>';
494
- }
495
-
496
- /**
497
- * Restrict display option.
498
- */
499
- public function restrict_display() {
500
- echo '
501
- <div id="pvc_restrict_display">
502
- <fieldset>';
503
-
504
- foreach ( $this->groups as $type => $type_name ) {
505
-
506
- if ( $type === 'robots' )
507
- continue;
508
-
509
- echo '
510
- <label class="cb-checkbox"><input id="pvc_restrict_display-' . $type . '" type="checkbox" name="post_views_counter_settings_display[restrict_display][groups][' . esc_html( $type ) . ']" value="1" ' . checked( in_array( $type, Post_Views_Counter()->get_attribute( 'options', 'display', 'restrict_display', 'groups' ), true ), true, false ) . ' />' . esc_html( $type_name ) . '</label>';
511
- }
512
-
513
- echo ' <p class="description">' . esc_html__( 'Use it to hide the post views counter from selected type of visitors.', 'post-views-counter' ) . '</p>
514
- <div class="pvc_user_roles"' . (in_array( 'roles', Post_Views_Counter()->get_attribute( 'options', 'display', 'restrict_display', 'groups' ), true ) ? '' : ' style="display: none;"') . '>';
515
-
516
- foreach ( $this->user_roles as $role => $role_name ) {
517
- echo ' <label class="cb-checkbox"><input type="checkbox" name="post_views_counter_settings_display[restrict_display][roles][' . $role . ']" value="1" ' . checked( in_array( $role, Post_Views_Counter()->get_attribute( 'options', 'display', 'restrict_display', 'roles' ), true ), true, false ) . ' />' . esc_html( $role_name ) . '</label>';
518
- }
519
-
520
- echo ' <p class="description">' . esc_html__( 'Use it to hide the post views counter from selected user roles.', 'post-views-counter' ) . '</p>
521
- </div>
522
- </fieldset>
523
- </div>';
524
- }
525
-
526
- /**
527
- * Validate general settings.
528
- */
529
- public function validate_settings( $input ) {
530
- if ( isset( $_POST['post_views_counter_import_wp_postviews'] ) ) {
531
- global $wpdb;
532
-
533
- $meta_key = esc_attr( apply_filters( 'pvc_import_meta_key', 'views' ) );
534
-
535
- $views = $wpdb->get_results(
536
- "SELECT post_id, meta_value FROM " . $wpdb->postmeta . " WHERE meta_key = '" . $meta_key . "'", ARRAY_A, 0
537
- );
538
-
539
- if ( ! empty( $views ) ) {
540
- $input = Post_Views_Counter()->get_attribute( 'defaults', 'general' );
541
- $input['wp_postviews_import'] = true;
542
-
543
- $sql = '';
544
-
545
- foreach ( $views as $view ) {
546
- $sql[] = "(" . $view['post_id'] . ", 4, 'total', " . $view['meta_value'] . ")";
547
- }
548
-
549
- $wpdb->query( "INSERT INTO " . $wpdb->prefix . "post_views(id, type, period, count) VALUES " . implode( ',', $sql ) . " ON DUPLICATE KEY UPDATE count = " . (isset( $_POST['post_views_counter_import_wp_postviews_override'] ) ? '' : 'count + ') . "VALUES(count)" );
550
-
551
- add_settings_error( 'wp_postviews_import', 'wp_postviews_import', __( 'Post views data imported succesfully.', 'post-views-counter' ), 'updated' );
552
- } else {
553
- add_settings_error( 'wp_postviews_import', 'wp_postviews_import', __( 'There was no post views data to import.', 'post-views-counter' ), 'updated' );
554
- }
555
- } elseif ( isset( $_POST['save_pvc_general'] ) ) {
556
- // post types count
557
- if ( isset( $input['post_types_count'] ) ) {
558
- $post_types = array();
559
-
560
- foreach ( $input['post_types_count'] as $post_type => $set ) {
561
- if ( isset( $this->post_types[$post_type] ) )
562
- $post_types[] = $post_type;
563
- }
564
-
565
- $input['post_types_count'] = array_unique( $post_types );
566
- } else
567
- $input['post_types_count'] = array();
568
-
569
- // counter mode
570
- $input['counter_mode'] = (isset( $input['counter_mode'], $this->modes[$input['counter_mode']] ) ? $input['counter_mode'] : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'counter_mode' ));
571
-
572
- // post views column
573
- $input['post_views_column'] = (bool) $input['post_views_column'];
574
-
575
- // time between counts
576
- $input['time_between_counts']['number'] = (int) (isset( $input['time_between_counts']['number'] ) ? $input['time_between_counts']['number'] : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'time_between_counts', 'number' ));
577
- $input['time_between_counts']['type'] = (isset( $input['time_between_counts']['type'], $this->time_types[$input['time_between_counts']['type']] ) ? $input['time_between_counts']['type'] : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'time_between_counts', 'type' ));
578
-
579
- // flush interval
580
- $input['flush_interval']['number'] = (int) (isset( $input['flush_interval']['number'] ) ? $input['flush_interval']['number'] : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'flush_interval', 'number' ));
581
- $input['flush_interval']['type'] = (isset( $input['flush_interval']['type'], $this->time_types[$input['flush_interval']['type']] ) ? $input['flush_interval']['type'] : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'flush_interval', 'type' ));
582
-
583
- // Since the settings are about to be saved and cache flush interval could've changed,
584
- // we want to make sure that any changes done on the settings page are in effect immediately
585
- // (instead of having to wait for the previous schedule to occur).
586
- // We achieve that by making sure to clear any previous cache flush schedules and
587
- // schedule the new one if the specified interval is > 0
588
- Post_Views_Counter()->remove_cache_flush();
589
-
590
- if ( $input['flush_interval']['number'] > 0 ) {
591
- Post_Views_Counter()->schedule_cache_flush();
592
- }
593
-
594
- // reset counts
595
- $input['reset_counts']['number'] = (int) (isset( $input['reset_counts']['number'] ) ? $input['reset_counts']['number'] : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'reset_counts', 'number' ));
596
- $input['reset_counts']['type'] = (isset( $input['reset_counts']['type'], $this->time_types[$input['reset_counts']['type']] ) ? $input['reset_counts']['type'] : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'reset_counts', 'type' ));
597
-
598
- // run cron on next visit?
599
- $input['cron_run'] = ($input['reset_counts']['number'] > 0 ? true : false);
600
- $input['cron_update'] = ($input['cron_run'] && (Post_Views_Counter()->get_attribute( 'options', 'general', 'reset_counts', 'number' ) !== $input['reset_counts']['number'] || Post_Views_Counter()->get_attribute( 'options', 'general', 'reset_counts', 'type' ) !== $input['reset_counts']['type']) ? true : false);
601
-
602
- // exclude
603
- if ( isset( $input['exclude']['groups'] ) ) {
604
- $groups = array();
605
-
606
- foreach ( $input['exclude']['groups'] as $group => $set ) {
607
- if ( isset( $this->groups[$group] ) )
608
- $groups[] = $group;
609
- }
610
-
611
- $input['exclude']['groups'] = array_unique( $groups );
612
- } else
613
- $input['exclude']['groups'] = array();
614
-
615
- if ( in_array( 'roles', $input['exclude']['groups'], true ) && isset( $input['exclude']['roles'] ) ) {
616
- $roles = array();
617
-
618
- foreach ( $input['exclude']['roles'] as $role => $set ) {
619
- if ( isset( $this->user_roles[$role] ) )
620
- $roles[] = $role;
621
- }
622
-
623
- $input['exclude']['roles'] = array_unique( $roles );
624
- } else
625
- $input['exclude']['roles'] = array();
626
-
627
- // exclude ips
628
- if ( isset( $input['exclude_ips'] ) ) {
629
-
630
- $ips = array();
631
-
632
- foreach ( $input['exclude_ips'] as $ip ) {
633
- if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) )
634
- $ips[] = $ip;
635
- }
636
-
637
- $input['exclude_ips'] = array_unique( $ips );
638
- }
639
-
640
- // restrict edit viewa
641
- $input['restrict_edit_views'] = (isset( $input['restrict_edit_views'] ) ? (bool) $input['restrict_edit_views'] : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'restrict_edit_views' ));
642
-
643
- // deactivation delete
644
- $input['deactivation_delete'] = (bool) isset( $input['deactivation_delete'] );
645
- } elseif ( isset( $_POST['save_pvc_display'] ) ) {
646
-
647
- // post views label
648
- $input['label'] = (isset( $input['label'] ) ? $input['label'] : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'label' ));
649
-
650
- if ( function_exists( 'icl_register_string' ) )
651
- icl_register_string( 'Post Views Counter', 'Post Views Label', $input['label'] );
652
-
653
- // position
654
- $input['position'] = (isset( $input['position'], $this->positions[$input['position']] ) ? $input['position'] : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'position' ));
655
-
656
- // display style
657
- $input['display_style']['icon'] = (bool) isset( $input['display_style']['icon'] );
658
- $input['display_style']['text'] = (bool) isset( $input['display_style']['text'] );
659
-
660
- // link to post
661
- $input['link_to_post'] = (isset( $input['link_to_post'] ) ? (bool) $input['link_to_post'] : Post_Views_Counter()->get_attribute( 'defaults', 'display', 'link_to_post' ));
662
-
663
- // icon class
664
- $input['icon_class'] = (isset( $input['icon_class'] ) ? trim( $input['icon_class'] ) : Post_Views_Counter()->get_attribute( 'defaults', 'general', 'icon_class' ));
665
-
666
- // post types display
667
- if ( isset( $input['post_types_display'] ) ) {
668
- $post_types = array();
669
-
670
- foreach ( $input['post_types_display'] as $post_type => $set ) {
671
- if ( isset( $this->post_types[$post_type] ) )
672
- $post_types[] = $post_type;
673
- }
674
-
675
- $input['post_types_display'] = array_unique( $post_types );
676
- } else
677
- $input['post_types_display'] = array();
678
-
679
- // restrict display
680
- if ( isset( $input['restrict_display']['groups'] ) ) {
681
- $groups = array();
682
-
683
- foreach ( $input['restrict_display']['groups'] as $group => $set ) {
684
- if ( $group === 'robots' )
685
- continue;
686
-
687
- if ( isset( $this->groups[$group] ) )
688
- $groups[] = $group;
689
- }
690
-
691
- $input['restrict_display']['groups'] = array_unique( $groups );
692
- } else
693
- $input['restrict_display']['groups'] = array();
694
-
695
- if ( in_array( 'roles', $input['restrict_display']['groups'], true ) && isset( $input['restrict_display']['roles'] ) ) {
696
- $roles = array();
697
-
698
- foreach ( $input['restrict_display']['roles'] as $role => $set ) {
699
- if ( isset( $this->user_roles[$role] ) )
700
- $roles[] = $role;
701
- }
702
-
703
- $input['restrict_display']['roles'] = array_unique( $roles );
704
- } else
705
- $input['restrict_display']['roles'] = array();
706
- } elseif ( isset( $_POST['reset_pvc_general'] ) ) {
707
- $input = Post_Views_Counter()->get_attribute( 'defaults', 'general' );
708
-
709
- add_settings_error( 'reset_general_settings', 'settings_reset', __( 'General settings restored to defaults.', 'post-views-counter' ), 'updated' );
710
- } elseif ( isset( $_POST['reset_pvc_display'] ) ) {
711
- $input = Post_Views_Counter()->get_attribute( 'defaults', 'display' );
712
-
713
- add_settings_error( 'reset_general_settings', 'settings_reset', __( 'Display settings restored to defaults.', 'post-views-counter' ), 'updated' );
714
- }
715
-
716
- return $input;
717
- }
718
-
719
- }
 
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * Post_Views_Counter_Settings class.
8
+ */
9
+ class Post_Views_Counter_Settings {
10
+
11
+ private $tabs;
12
+ private $choices;
13
+ private $modes;
14
+ private $time_types;
15
+ private $groups;
16
+ private $user_roles;
17
+ private $positions;
18
+ private $display_styles;
19
+ public $post_types;
20
+
21
+ public function __construct() {
22
+ // actions
23
+ add_action( 'admin_init', array( $this, 'register_settings' ) );
24
+ add_action( 'admin_menu', array( $this, 'admin_menu_options' ) );
25
+ add_action( 'after_setup_theme', array( $this, 'load_defaults' ) );
26
+ add_action( 'wp_loaded', array( $this, 'load_post_types' ) );
27
+ }
28
+
29
+ /**
30
+ * Load default settings.
31
+ */
32
+ public function load_defaults() {
33
+
34
+ $this->modes = array(
35
+ 'php' => __( 'PHP', 'post-views-counter' ),
36
+ 'js' => __( 'JavaScript', 'post-views-counter' )
37
+ );
38
+
39
+ $this->time_types = array(
40
+ 'minutes' => __( 'minutes', 'post-views-counter' ),
41
+ 'hours' => __( 'hours', 'post-views-counter' ),
42
+ 'days' => __( 'days', 'post-views-counter' ),
43
+ 'weeks' => __( 'weeks', 'post-views-counter' ),
44
+ 'months' => __( 'months', 'post-views-counter' ),
45
+ 'years' => __( 'years', 'post-views-counter' )
46
+ );
47
+
48
+ $this->groups = array(
49
+ 'robots' => __( 'robots', 'post-views-counter' ),
50
+ 'users' => __( 'logged in users', 'post-views-counter' ),
51
+ 'guests' => __( 'guests', 'post-views-counter' ),
52
+ 'roles' => __( 'selected user roles', 'post-views-counter' )
53
+ );
54
+
55
+ $this->positions = array(
56
+ 'before' => __( 'before the content', 'post-views-counter' ),
57
+ 'after' => __( 'after the content', 'post-views-counter' ),
58
+ 'manual' => __( 'manual', 'post-views-counter' )
59
+ );
60
+
61
+ $this->display_styles = array(
62
+ 'icon' => __( 'icon', 'post-views-counter' ),
63
+ 'text' => __( 'label', 'post-views-counter' )
64
+ );
65
+
66
+ $this->tabs = array(
67
+ 'general' => array(
68
+ 'name' => __( 'General', 'post-views-counter' ),
69
+ 'key' => 'post_views_counter_settings_general',
70
+ 'submit' => 'save_pvc_general',
71
+ 'reset' => 'reset_pvc_general'
72
+ ),
73
+ 'display' => array(
74
+ 'name' => __( 'Display', 'post-views-counter' ),
75
+ 'key' => 'post_views_counter_settings_display',
76
+ 'submit' => 'save_pvc_display',
77
+ 'reset' => 'reset_pvc_display'
78
+ )
79
+ );
80
+
81
+ $this->user_roles = $this->get_user_roles();
82
+ }
83
+
84
+ /**
85
+ * Get post types avaiable for counting.
86
+ */
87
+ public function load_post_types() {
88
+ $post_types = array();
89
+
90
+ // built in public post types
91
+ foreach ( get_post_types( array( '_builtin' => true, 'public' => true ), 'objects', 'and' ) as $key => $post_type ) {
92
+ if ( $key !== 'attachment' )
93
+ $post_types[$key] = $post_type->labels->name;
94
+ }
95
+
96
+ // public custom post types
97
+ foreach ( get_post_types( array( '_builtin' => false, 'public' => true ), 'objects', 'and' ) as $key => $post_type ) {
98
+ $post_types[$key] = $post_type->labels->name;
99
+ }
100
+
101
+ // sort post types alphabetically with their keys
102
+ asort( $post_types, SORT_STRING );
103
+
104
+ $this->post_types = $post_types;
105
+ }
106
+
107
+ /**
108
+ * Get all user roles.
109
+ */
110
+ public function get_user_roles() {
111
+ global $wp_roles;
112
+
113
+ $roles = array();
114
+
115
+ foreach ( apply_filters( 'editable_roles', $wp_roles->roles ) as $role => $details ) {
116
+ $roles[$role] = translate_user_role( $details['name'] );
117
+ }
118
+
119
+ asort( $roles, SORT_STRING );
120
+
121
+ return $roles;
122
+ }
123
+
124
+ /**
125
+ * Add options page.
126
+ */
127
+ public function admin_menu_options() {
128
+ add_options_page(
129
+ __( 'Post Views Counter', 'post-views-counter' ), __( 'Post Views Counter', 'post-views-counter' ), 'manage_options', 'post-views-counter', array( $this, 'options_page' )
130
+ );
131
+ }
132
+
133
+ /**
134
+ * Options page callback.
135
+ */
136
+ public function options_page() {
137
+ $tab_key = (isset( $_GET['tab'] ) ? $_GET['tab'] : 'general');
138
+
139
+ echo '
140
+ <div class="wrap">' . screen_icon() . '
141
+ <h2>' . __( 'Post Views Counter', 'post-views-counter' ) . '</h2>
142
+ <h2 class="nav-tab-wrapper">';
143
+
144
+ foreach ( $this->tabs as $key => $name ) {
145
+ echo '
146
+ <a class="nav-tab ' . ($tab_key == $key ? 'nav-tab-active' : '') . '" href="' . esc_url( admin_url( 'options-general.php?page=post-views-counter&tab=' . $key ) ) . '">' . $name['name'] . '</a>';
147
+ }
148
+
149
+ echo '
150
+ </h2>
151
+ <div class="post-views-counter-settings">
152
+ <div class="df-credits">
153
+ <h3 class="hndle">' . __( 'Post Views Counter', 'post-views-counter' ) . ' ' . Post_Views_Counter()->defaults['version'] . '</h3>
154
+ <div class="inside">
155
+ <h4 class="inner">' . __( 'Need support?', 'post-views-counter' ) . '</h4>
156
+ <p class="inner">' . __( 'If you are having problems with this plugin, please talk about them in the', 'post-views-counter' ) . ' <a href="http://www.dfactory.eu/support/?utm_source=post-views-counter-settings&utm_medium=link&utm_campaign=support" target="_blank" title="' . __( 'Support forum', 'post-views-counter' ) . '">' . __( 'Support forum', 'post-views-counter' ) . '</a></p>
157
+ <hr />
158
+ <h4 class="inner">' . __( 'Do you like this plugin?', 'post-views-counter' ) . '</h4>
159
+ <p class="inner"><a href="http://wordpress.org/support/view/plugin-reviews/post-views-counter" target="_blank" title="' . __( 'Rate it 5', 'post-views-counter' ) . '">' . __( 'Rate it 5', 'post-views-counter' ) . '</a> ' . __( 'on WordPress.org', 'post-views-counter' ) . '<br />' .
160
+ __( 'Blog about it & link to the', 'post-views-counter' ) . ' <a href="http://www.dfactory.eu/plugins/post-views-counter/?utm_source=post-views-counter-settings&utm_medium=link&utm_campaign=blog-about" target="_blank" title="' . __( 'plugin page', 'post-views-counter' ) . '">' . __( 'plugin page', 'post-views-counter' ) . '</a><br/>' .
161
+ __( 'Check out our other', 'post-views-counter' ) . ' <a href="http://www.dfactory.eu/plugins/?utm_source=post-views-counter-settings&utm_medium=link&utm_campaign=other-plugins" target="_blank" title="' . __( 'WordPress plugins', 'post-views-counter' ) . '">' . __( 'WordPress plugins', 'post-views-counter' ) . '</a>
162
+ </p>
163
+ <hr />
164
+ <p class="df-link inner">' . __( 'Created by', 'post-views-counter' ) . ' <a href="http://www.dfactory.eu/?utm_source=post-views-counter-settings&utm_medium=link&utm_campaign=created-by" target="_blank" title="dFactory - Quality plugins for WordPress"><img src="' . POST_VIEWS_COUNTER_URL . '/images/logo-dfactory.png' . '" title="dFactory - Quality plugins for WordPress" alt="dFactory - Quality plugins for WordPress" /></a></p>
165
+ </div>
166
+ </div>
167
+ <form action="options.php" method="post">';
168
+
169
+ wp_nonce_field( 'update-options' );
170
+ settings_fields( $this->tabs[$tab_key]['key'] );
171
+ do_settings_sections( $this->tabs[$tab_key]['key'] );
172
+
173
+ echo '
174
+ <p class="submit">';
175
+
176
+ submit_button( '', 'primary', $this->tabs[$tab_key]['submit'], false );
177
+
178
+ echo ' ';
179
+
180
+ submit_button( __( 'Reset to defaults', 'post-views-counter' ), 'secondary reset_pvc_settings', $this->tabs[$tab_key]['reset'], false );
181
+
182
+ echo '
183
+ </p>
184
+ </form>
185
+ </div>
186
+ <div class="clear"></div>
187
+ </div>';
188
+ }
189
+
190
+ /**
191
+ * Register settings callback.
192
+ */
193
+ public function register_settings() {
194
+ // general options
195
+ register_setting( 'post_views_counter_settings_general', 'post_views_counter_settings_general', array( $this, 'validate_settings' ) );
196
+ add_settings_section( 'post_views_counter_settings_general', __( 'General settings', 'post-views-counter' ), '', 'post_views_counter_settings_general' );
197
+ add_settings_field( 'pvc_post_types_count', __( 'Post Types Count', 'post-views-counter' ), array( $this, 'post_types_count' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
198
+ add_settings_field( 'pvc_counter_mode', __( 'Counter Mode', 'post-views-counter' ), array( $this, 'counter_mode' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
199
+ add_settings_field( 'pvc_post_views_column', __( 'Post Views Column', 'post-views-counter' ), array( $this, 'post_views_column' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
200
+ add_settings_field( 'pvc_restrict_edit_views', __( 'Restrict Edit', 'post-views-counter' ), array( $this, 'restrict_edit_views' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
201
+ add_settings_field( 'pvc_time_between_counts', __( 'Time Between Counts', 'post-views-counter' ), array( $this, 'time_between_counts' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
202
+ add_settings_field( 'pvc_reset_counts', __( 'Reset Data Interval', 'post-views-counter' ), array( $this, 'reset_counts' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
203
+ add_settings_field( 'pvc_flush_interval', __( 'Flush Object Cache Interval', 'post-views-counter' ), array( $this, 'flush_interval' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
204
+ add_settings_field( 'pvc_exclude', __( 'Exclude Visitors', 'post-views-counter' ), array( $this, 'exclude' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
205
+ add_settings_field( 'pvc_exclude_ips', __( 'Exclude IPs', 'post-views-counter' ), array( $this, 'exclude_ips' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
206
+ add_settings_field( 'pvc_wp_postviews', __( 'WP-PostViews', 'post-views-counter' ), array( $this, 'wp_postviews' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
207
+ add_settings_field( 'pvc_deactivation_delete', __( 'Deactivation', 'post-views-counter' ), array( $this, 'deactivation_delete' ), 'post_views_counter_settings_general', 'post_views_counter_settings_general' );
208
+
209
+ // display options
210
+ register_setting( 'post_views_counter_settings_display', 'post_views_counter_settings_display', array( $this, 'validate_settings' ) );
211
+ add_settings_section( 'post_views_counter_settings_display', __( 'Display settings', 'post-views-counter' ), '', 'post_views_counter_settings_display' );
212
+ add_settings_field( 'pvc_post_views_label', __( 'Post Views Label', 'post-views-counter' ), array( $this, 'post_views_label' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
213
+ add_settings_field( 'pvc_post_types_display', __( 'Post Types Display', 'post-views-counter' ), array( $this, 'post_types_display' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
214
+ add_settings_field( 'pvc_restrict_display', __( 'Restrict Display', 'post-views-counter' ), array( $this, 'restrict_display' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
215
+ add_settings_field( 'pvc_position', __( 'Position', 'post-views-counter' ), array( $this, 'position' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
216
+ add_settings_field( 'pvc_display_style', __( 'Display Style', 'post-views-counter' ), array( $this, 'display_style' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
217
+ add_settings_field( 'pvc_icon_class', __( 'Icon Class', 'post-views-counter' ), array( $this, 'icon_class' ), 'post_views_counter_settings_display', 'post_views_counter_settings_display' );
218
+ }
219
+
220
+ /**
221
+ * Post views label option.
222
+ */
223
+ public function post_views_label() {
224
+ echo '
225
+ <div id="pvc_post_views_label">
226
+ <fieldset>
227
+ <input type="text" class="large-text" name="post_views_counter_settings_display[label]" value="' . esc_attr( Post_Views_Counter()->options['display']['label'] ) . '" />
228
+ <p class="description">' . esc_html__( 'Enter the label for the post views counter field.', 'post-views-counter' ) . '</p>
229
+ </fieldset>
230
+ </div>';
231
+ }
232
+
233
+ /**
234
+ * Post types to count option.
235
+ */
236
+ public function post_types_count() {
237
+ echo '
238
+ <div id="pvc_post_types_count">';
239
+
240
+ foreach ( $this->post_types as $post_type => $post_type_name ) {
241
+ echo '
242
+ <label class="cb-checkbox"><input id="pvc_post_types_count-' . esc_attr( $post_type ) . '" type="checkbox" name="post_views_counter_settings_general[post_types_count][' . esc_attr( $post_type ) . ']" value="1" ' . checked( in_array( $post_type, Post_Views_Counter()->options['general']['post_types_count'], true ), true, false ) . ' />' . esc_html( $post_type_name ) . ' </label>';
243
+ }
244
+
245
+ echo '
246
+ <p class="description">' . esc_html__( 'Select post types for which post views will be counted.', 'post-views-counter' ) . '</p>
247
+ </div>';
248
+ }
249
+
250
+ /**
251
+ * Post types to display option.
252
+ */
253
+ public function post_types_display() {
254
+ echo '
255
+ <div id="pvc_post_types_display">';
256
+
257
+ foreach ( $this->post_types as $post_type => $post_type_name ) {
258
+ echo '
259
+ <label class="cb-checkbox"><input id="pvc_post_types_display-' . esc_attr( $post_type ) . '" type="checkbox" name="post_views_counter_settings_display[post_types_display][' . esc_attr( $post_type ) . ']" value="1" ' . checked( in_array( $post_type, Post_Views_Counter()->options['display']['post_types_display'], true ), true, false ) . ' />' . esc_html( $post_type_name ) . '</label>';
260
+ }
261
+
262
+ echo '
263
+ <p class="description">' . esc_html__( 'Select post types for which post views will be displayed.', 'post-views-counter' ) . '</p>
264
+ </div>';
265
+ }
266
+
267
+ /**
268
+ * Counter mode option.
269
+ */
270
+ public function counter_mode() {
271
+ echo '
272
+ <div id="pvc_counter_mode">';
273
+
274
+ foreach ( $this->modes as $key => $value ) {
275
+ $key = esc_attr( $key );
276
+
277
+ echo '
278
+ <label class="cb-radio"><input type="radio" name="post_views_counter_settings_general[counter_mode]" value="' . $key . '" ' . checked( $key, Post_Views_Counter()->options['general']['counter_mode'], false ) . ' />' . esc_html( $value ) . '</label>';
279
+ }
280
+
281
+ echo '
282
+ <p class="description">' . esc_html__( 'Select the method of collecting post views data. If you are using any of the caching plugins select Javascript.', 'post-views-counter' ) . '</p>
283
+ </div>';
284
+ }
285
+
286
+ /**
287
+ * Post views column option.
288
+ */
289
+ public function post_views_column() {
290
+ echo '
291
+ <div id="pvc_post_views_column">
292
+ <label class="cb-checkbox"><input id="pvc-post-views-column-enable" type="checkbox" name="post_views_counter_settings_general[post_views_column]" value="1" ' . checked( true, Post_Views_Counter()->options['general']['post_views_column'], false ) . ' />' . esc_html__( 'Enable to display post views count column for each of the selected post types.', 'post-views-counter' ) . '</label>
293
+ </div>';
294
+ }
295
+
296
+ /**
297
+ * Time between counts option.
298
+ */
299
+ public function time_between_counts() {
300
+ echo '
301
+ <div id="pvc_time_between_counts">
302
+ <input size="4" type="text" name="post_views_counter_settings_general[time_between_counts][number]" value="' . esc_attr( Post_Views_Counter()->options['general']['time_between_counts']['number'] ) . '" />
303
+ <select class="pvc-chosen-short" name="post_views_counter_settings_general[time_between_counts][type]">';
304
+
305
+ foreach ( $this->time_types as $type => $type_name ) {
306
+ echo '
307
+ <option value="' . esc_attr( $type ) . '" ' . selected( $type, Post_Views_Counter()->options['general']['time_between_counts']['type'], false ) . '>' . esc_html( $type_name ) . '</option>';
308
+ }
309
+
310
+ echo '
311
+ </select>
312
+ <p class="description">' . esc_html__( 'Enter the time between single user visit count.', 'post-views-counter' ) . '</p>
313
+ </div>';
314
+ }
315
+
316
+ /**
317
+ * Reset counts option.
318
+ */
319
+ public function reset_counts() {
320
+ echo '
321
+ <div id="pvc_reset_counts">
322
+ <input size="4" type="text" name="post_views_counter_settings_general[reset_counts][number]" value="' . esc_attr( Post_Views_Counter()->options['general']['reset_counts']['number'] ) . '" />
323
+ <select class="pvc-chosen-short" name="post_views_counter_settings_general[reset_counts][type]">';
324
+
325
+ foreach ( $this->time_types as $type => $type_name ) {
326
+ echo '
327
+ <option value="' . esc_attr( $type ) . '" ' . selected( $type, Post_Views_Counter()->options['general']['reset_counts']['type'], false ) . '>' . esc_html( $type_name ) . '</option>';
328
+ }
329
+
330
+ echo '
331
+ </select>
332
+ <p class="description">' . esc_html__( 'Delete single day post views data older than specified above. Enter 0 (number zero) if you want to preserve your data regardless of its age.', 'post-views-counter' ) . '</p>
333
+ </div>';
334
+ }
335
+
336
+ /**
337
+ * Flush interval option.
338
+ */
339
+ public function flush_interval() {
340
+ echo '
341
+ <div id="pvc_flush_interval">
342
+ <input size="4" type="text" name="post_views_counter_settings_general[flush_interval][number]" value="' . esc_attr( Post_Views_Counter()->options['general']['flush_interval']['number'] ) . '" />
343
+ <select class="pvc-chosen-short" name="post_views_counter_settings_general[flush_interval][type]">';
344
+
345
+ foreach ( $this->time_types as $type => $type_name ) {
346
+ echo '
347
+ <option value="' . esc_attr( $type ) . '" ' . selected( $type, Post_Views_Counter()->options['general']['flush_interval']['type'], false ) . '>' . esc_html( $type_name ) . '</option>';
348
+ }
349
+
350
+ echo '
351
+ </select>
352
+ <p class="description">' . __( 'How often to flush cached view counts from the object cache into the database. This feature is used only if a persistent object cache is detected and the interval is greater than 0 (number zero)). When used, view counts will be collected and stored in the object cache instead of the database and will then be asynchronously flushed to the database according to the specified interval.<br /><strong>Notice:</strong> Potential data loss may occur if the object cache is cleared/unavailable for the duration of the interval.', 'post-views-counter' ) . '</p>
353
+ </div>';
354
+ }
355
+
356
+ /**
357
+ * Exlude user groups option.
358
+ */
359
+ public function exclude() {
360
+ echo '
361
+ <div id="pvc_exclude">
362
+ <fieldset>';
363
+
364
+ foreach ( $this->groups as $type => $type_name ) {
365
+ echo '
366
+ <label class="cb-checkbox"><input id="pvc_exclude-' . $type . '" type="checkbox" name="post_views_counter_settings_general[exclude][groups][' . $type . ']" value="1" ' . checked( in_array( $type, Post_Views_Counter()->options['general']['exclude']['groups'], true ), true, false ) . ' />' . esc_html( $type_name ) . '</label>';
367
+ }
368
+
369
+ echo ' <p class="description">' . esc_html__( 'Use it to hide the post views counter from selected type of visitors.', 'post-views-counter' ) . '</p>
370
+ <div class="pvc_user_roles"' . (in_array( 'roles', Post_Views_Counter()->options['general']['exclude']['groups'], true ) ? '' : ' style="display: none;"') . '>';
371
+
372
+ foreach ( $this->user_roles as $role => $role_name ) {
373
+ echo ' <label class="cb-checkbox"><input type="checkbox" name="post_views_counter_settings_general[exclude][roles][' . $role . ']" value="1" ' . checked( in_array( $role, Post_Views_Counter()->options['general']['exclude']['roles'], true ), true, false ) . '>' . esc_html( $role_name ) . '</label>';
374
+ }
375
+
376
+ echo ' <p class="description">' . esc_html__( 'Use it to hide the post views counter from selected user roles.', 'post-views-counter' ) . '</p>
377
+ </div>
378
+ </fieldset>
379
+ </div>';
380
+ }
381
+
382
+ /**
383
+ * Exclude IPs option.
384
+ */
385
+ public function exclude_ips() {
386
+ // lovely php 5.2 limitations
387
+ $ips = Post_Views_Counter()->options['general']['exclude_ips'];
388
+
389
+ echo '
390
+ <div id="pvc_exclude_ips">';
391
+
392
+ if ( ! empty( $ips ) ) {
393
+ foreach ( $ips as $key => $ip ) {
394
+ echo '
395
+ <div class="ip-box">
396
+ <input type="text" name="post_views_counter_settings_general[exclude_ips][]" value="' . esc_attr( $ip ) . '" /> <a href="#" class="remove-exclude-ip" title="' . esc_attr__( 'Remove', 'post-views-counter' ) . '">' . esc_attr__( 'Remove', 'post-views-counter' ) . '</a>
397
+ </div>';
398
+ }
399
+ } else {
400
+ echo '
401
+ <div class="ip-box">
402
+ <input type="text" name="post_views_counter_settings_general[exclude_ips][]" value="" /> <a href="#" class="remove-exclude-ip" title="' . esc_attr__( 'Remove', 'post-views-counter' ) . '">' . esc_attr__( 'Remove', 'post-views-counter' ) . '</a>
403
+ </div>';
404
+ }
405
+
406
+ echo '
407
+ <p><input type="button" class="button button-secondary add-exclude-ip" value="' . esc_attr__( 'Add new', 'post-views-counter' ) . '" /> <input type="button" class="button button-secondary add-current-ip" value="' . esc_attr__( 'Add my current IP', 'post-views-counter' ) . '" data-rel="' . esc_attr( $_SERVER['REMOTE_ADDR'] ) . '" /></p>
408
+ <p class="description">' . esc_html__( 'Enter the IP addresses to be excluded from post views count.', 'post-views-counter' ) . '</p>
409
+ </div>';
410
+ }
411
+
412
+ /**
413
+ * WP-PostViews import option.
414
+ */
415
+ public function wp_postviews() {
416
+ echo '
417
+ <div id="pvc_wp_postviews">
418
+ <fieldset>
419
+ <input type="submit" class="button button-secondary" name="post_views_counter_import_wp_postviews" value="' . __( 'Import', 'post-views-counter' ) . '"/>
420
+ <p class="description">' . esc_html__( 'Import post views data from WP-PostViews plugin.', 'post-views-counter' ) . '</p>
421
+ <label class="cb-checkbox"><input id="pvc-wp-postviews" type="checkbox" name="post_views_counter_import_wp_postviews_override" value="1" />' . esc_html__( 'Override existing Post Views Counter data.', 'post-views-counter' ) . '</label>
422
+ </fieldset>
423
+ </div>';
424
+ }
425
+
426
+ /**
427
+ * Limit views edit to admins.
428
+ */
429
+ public function restrict_edit_views() {
430
+ echo '
431
+ <div id="pvc_restrict_edit_views">
432
+ <label class="cb-checkbox"><input type="checkbox" name="post_views_counter_settings_general[restrict_edit_views]" value="1" ' . checked( true, Post_Views_Counter()->options['general']['restrict_edit_views'], false ) . ' />' . esc_html__( 'Enable to restrict post views editing to admins only.', 'post-views-counter' ) . '</label>
433
+ </div>';
434
+ }
435
+
436
+ /**
437
+ * Plugin deactivation option.
438
+ */
439
+ public function deactivation_delete() {
440
+ echo '
441
+ <div id="pvc_deactivation_delete">
442
+ <label class="cb-checkbox"><input type="checkbox" name="post_views_counter_settings_general[deactivation_delete]" value="1" ' . checked( true, Post_Views_Counter()->options['general']['deactivation_delete'], false ) . ' />' . esc_html__( 'Enable to delete all plugin data on deactivation.', 'post-views-counter' ) . '</label>
443
+ </div>';
444
+ }
445
+
446
+ /**
447
+ * Counter position option.
448
+ */
449
+ public function position() {
450
+ echo '
451
+ <div id="pvc_position">
452
+ <select class="pvc-chosen-short" name="post_views_counter_settings_display[position]">';
453
+
454
+ foreach ( $this->positions as $position => $position_name ) {
455
+ echo '
456
+ <option value="' . esc_attr( $position ) . '" ' . selected( $position, Post_Views_Counter()->options['display']['position'], false ) . '>' . esc_html( $position_name ) . '</option>';
457
+ }
458
+
459
+ echo '
460
+ </select>
461
+ <p class="description">' . esc_html__( 'Select where would you like to display the post views counter. Use [post-views] shortcode for manual display.', 'post-views-counter' ) . '</p>
462
+ </div>';
463
+ }
464
+
465
+ /**
466
+ * Counter style option.
467
+ */
468
+ public function display_style() {
469
+ echo '
470
+ <div id="pvc_display_style">';
471
+
472
+ foreach ( $this->display_styles as $display => $style ) {
473
+ $display = esc_attr( $display );
474
+
475
+ echo '
476
+ <label class="cb-checkbox"><input type="checkbox" name="post_views_counter_settings_display[display_style][' . $display . ']" value="1" ' . checked( true, Post_Views_Counter()->options['display']['display_style'][$display], false ) . ' />' . esc_html( $style ) . '</label>';
477
+ }
478
+
479
+ echo '
480
+ <p class="description">' . esc_html__( 'Choose how to display the post views counter.', 'post-views-counter' ) . '</p>
481
+ </div>';
482
+ }
483
+
484
+ /**
485
+ * Counter icon class option.
486
+ */
487
+ public function icon_class() {
488
+ echo '
489
+ <div id="pvc_icon_class">
490
+ <input type="text" name="post_views_counter_settings_display[icon_class]" class="large-text" value="' . esc_attr( Post_Views_Counter()->options['display']['icon_class'] ) . '" />
491
+ <p class="description">' . sprintf( __( 'Enter the post views icon class. Any of the <a href="%s" target="_blank">Dashicons</a> classes are available.', 'post-views-counter' ), 'http://melchoyce.github.io/dashicons/' ) . '</p>
492
+ </div>';
493
+ }
494
+
495
+ /**
496
+ * Restrict display option.
497
+ */
498
+ public function restrict_display() {
499
+ echo '
500
+ <div id="pvc_restrict_display">
501
+ <fieldset>';
502
+
503
+ foreach ( $this->groups as $type => $type_name ) {
504
+
505
+ if ( $type === 'robots' )
506
+ continue;
507
+
508
+ echo '
509
+ <label class="cb-checkbox"><input id="pvc_restrict_display-' . $type . '" type="checkbox" name="post_views_counter_settings_display[restrict_display][groups][' . esc_html( $type ) . ']" value="1" ' . checked( in_array( $type, Post_Views_Counter()->options['display']['restrict_display']['groups'], true ), true, false ) . ' />' . esc_html( $type_name ) . '</label>';
510
+ }
511
+
512
+ echo ' <p class="description">' . esc_html__( 'Use it to hide the post views counter from selected type of visitors.', 'post-views-counter' ) . '</p>
513
+ <div class="pvc_user_roles"' . (in_array( 'roles', Post_Views_Counter()->options['display']['restrict_display']['groups'], true ) ? '' : ' style="display: none;"') . '>';
514
+
515
+ foreach ( $this->user_roles as $role => $role_name ) {
516
+ echo ' <label class="cb-checkbox"><input type="checkbox" name="post_views_counter_settings_display[restrict_display][roles][' . $role . ']" value="1" ' . checked( in_array( $role, Post_Views_Counter()->options['display']['restrict_display']['roles'], true ), true, false ) . ' />' . esc_html( $role_name ) . '</label>';
517
+ }
518
+
519
+ echo ' <p class="description">' . esc_html__( 'Use it to hide the post views counter from selected user roles.', 'post-views-counter' ) . '</p>
520
+ </div>
521
+ </fieldset>
522
+ </div>';
523
+ }
524
+
525
+ /**
526
+ * Validate general settings.
527
+ */
528
+ public function validate_settings( $input ) {
529
+ if ( isset( $_POST['post_views_counter_import_wp_postviews'] ) ) {
530
+ global $wpdb;
531
+
532
+ $meta_key = esc_attr( apply_filters( 'pvc_import_meta_key', 'views' ) );
533
+
534
+ $views = $wpdb->get_results(
535
+ "SELECT post_id, meta_value FROM " . $wpdb->postmeta . " WHERE meta_key = '" . $meta_key . "'", ARRAY_A, 0
536
+ );
537
+
538
+ if ( ! empty( $views ) ) {
539
+ $input = Post_Views_Counter()->defaults['general'];
540
+ $input['wp_postviews_import'] = true;
541
+
542
+ $sql = '';
543
+
544
+ foreach ( $views as $view ) {
545
+ $sql[] = "(" . $view['post_id'] . ", 4, 'total', " . $view['meta_value'] . ")";
546
+ }
547
+
548
+ $wpdb->query( "INSERT INTO " . $wpdb->prefix . "post_views(id, type, period, count) VALUES " . implode( ',', $sql ) . " ON DUPLICATE KEY UPDATE count = " . (isset( $_POST['post_views_counter_import_wp_postviews_override'] ) ? '' : 'count + ') . "VALUES(count)" );
549
+
550
+ add_settings_error( 'wp_postviews_import', 'wp_postviews_import', __( 'Post views data imported succesfully.', 'post-views-counter' ), 'updated' );
551
+ } else {
552
+ add_settings_error( 'wp_postviews_import', 'wp_postviews_import', __( 'There was no post views data to import.', 'post-views-counter' ), 'updated' );
553
+ }
554
+ } elseif ( isset( $_POST['save_pvc_general'] ) ) {
555
+ // post types count
556
+ if ( isset( $input['post_types_count'] ) ) {
557
+ $post_types = array();
558
+
559
+ foreach ( $input['post_types_count'] as $post_type => $set ) {
560
+ if ( isset( $this->post_types[$post_type] ) )
561
+ $post_types[] = $post_type;
562
+ }
563
+
564
+ $input['post_types_count'] = array_unique( $post_types );
565
+ } else
566
+ $input['post_types_count'] = array();
567
+
568
+ // counter mode
569
+ $input['counter_mode'] = isset( $input['counter_mode'], $this->modes[$input['counter_mode']] ) ? $input['counter_mode'] : Post_Views_Counter()->defaults['general']['counter_mode'];
570
+
571
+ // post views column
572
+ $input['post_views_column'] = $input['post_views_column'];
573
+
574
+ // time between counts
575
+ $input['time_between_counts']['number'] = (int)( isset( $input['time_between_counts']['number'] ) ? $input['time_between_counts']['number'] : Post_Views_Counter()->defaults['general']['time_between_counts']['number'] );
576
+ $input['time_between_counts']['type'] = isset( $input['time_between_counts']['type'], $this->time_types[$input['time_between_counts']['type']] ) ? $input['time_between_counts']['type'] : Post_Views_Counter()->defaults['general']['time_between_counts']['type'];
577
+
578
+ // flush interval
579
+ $input['flush_interval']['number'] = (int) ( isset( $input['flush_interval']['number'] ) ? $input['flush_interval']['number'] : Post_Views_Counter()->defaults['general']['flush_interval']['number'] );
580
+ $input['flush_interval']['type'] = isset( $input['flush_interval']['type'], $this->time_types[$input['flush_interval']['type']] ) ? $input['flush_interval']['type'] : Post_Views_Counter()->defaults['general']['flush_interval']['type'];
581
+
582
+ // Since the settings are about to be saved and cache flush interval could've changed,
583
+ // we want to make sure that any changes done on the settings page are in effect immediately
584
+ // (instead of having to wait for the previous schedule to occur).
585
+ // We achieve that by making sure to clear any previous cache flush schedules and
586
+ // schedule the new one if the specified interval is > 0
587
+ Post_Views_Counter()->remove_cache_flush();
588
+
589
+ if ( $input['flush_interval']['number'] > 0 ) {
590
+ Post_Views_Counter()->schedule_cache_flush();
591
+ }
592
+
593
+ // reset counts
594
+ $input['reset_counts']['number'] = (int) ( isset( $input['reset_counts']['number'] ) ? $input['reset_counts']['number'] : Post_Views_Counter()->defaults['general']['reset_counts']['number'] );
595
+ $input['reset_counts']['type'] = isset( $input['reset_counts']['type'], $this->time_types[$input['reset_counts']['type']] ) ? $input['reset_counts']['type'] : Post_Views_Counter()->defaults['general']['reset_counts']['type'];
596
+
597
+ // run cron on next visit?
598
+ $input['cron_run'] = ($input['reset_counts']['number'] > 0 ? true : false);
599
+ $input['cron_update'] = ($input['cron_run'] && (Post_Views_Counter()->options['general']['reset_counts']['number'] !== $input['reset_counts']['number'] || Post_Views_Counter()->options['general']['reset_counts']['type'] !== $input['reset_counts']['type']) ? true : false);
600
+
601
+ // exclude
602
+ if ( isset( $input['exclude']['groups'] ) ) {
603
+ $groups = array();
604
+
605
+ foreach ( $input['exclude']['groups'] as $group => $set ) {
606
+ if ( isset( $this->groups[$group] ) )
607
+ $groups[] = $group;
608
+ }
609
+
610
+ $input['exclude']['groups'] = array_unique( $groups );
611
+
612
+ } else {
613
+ $input['exclude']['groups'] = array();
614
+ }
615
+
616
+ if ( in_array( 'roles', $input['exclude']['groups'], true ) && isset( $input['exclude']['roles'] ) ) {
617
+ $roles = array();
618
+
619
+ foreach ( $input['exclude']['roles'] as $role => $set ) {
620
+ if ( isset( $this->user_roles[$role] ) )
621
+ $roles[] = $role;
622
+ }
623
+
624
+ $input['exclude']['roles'] = array_unique( $roles );
625
+ } else
626
+ $input['exclude']['roles'] = array();
627
+
628
+ // exclude ips
629
+ if ( isset( $input['exclude_ips'] ) ) {
630
+
631
+ $ips = array();
632
+
633
+ foreach ( $input['exclude_ips'] as $ip ) {
634
+ if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) )
635
+ $ips[] = $ip;
636
+ }
637
+
638
+ $input['exclude_ips'] = array_unique( $ips );
639
+ }
640
+
641
+ // restrict edit viewa
642
+ $input['restrict_edit_views'] = isset( $input['restrict_edit_views'] ) ? $input['restrict_edit_views'] : Post_Views_Counter()->defaults['general']['restrict_edit_views'];
643
+
644
+ // deactivation delete
645
+ $input['deactivation_delete'] = isset( $input['deactivation_delete'] );
646
+ } elseif ( isset( $_POST['save_pvc_display'] ) ) {
647
+
648
+ // post views label
649
+ $input['label'] = isset( $input['label'] ) ? $input['label'] : Post_Views_Counter()->defaults['general']['label'];
650
+
651
+ if ( function_exists( 'icl_register_string' ) )
652
+ icl_register_string( 'Post Views Counter', 'Post Views Label', $input['label'] );
653
+
654
+ // position
655
+ $input['position'] = isset( $input['position'], $this->positions[$input['position']] ) ? $input['position'] : Post_Views_Counter()->defaults['general']['position'];
656
+
657
+ // display style
658
+ $input['display_style']['icon'] = isset( $input['display_style']['icon'] );
659
+ $input['display_style']['text'] = isset( $input['display_style']['text'] );
660
+
661
+ // link to post
662
+ $input['link_to_post'] = isset( $input['link_to_post'] ) ? $input['link_to_post'] : Post_Views_Counter()->defaults['display']['link_to_post'];
663
+
664
+ // icon class
665
+ $input['icon_class'] = isset( $input['icon_class'] ) ? trim( $input['icon_class'] ) : Post_Views_Counter()->defaults['general']['icon_class'];
666
+
667
+ // post types display
668
+ if ( isset( $input['post_types_display'] ) ) {
669
+ $post_types = array();
670
+
671
+ foreach ( $input['post_types_display'] as $post_type => $set ) {
672
+ if ( isset( $this->post_types[$post_type] ) )
673
+ $post_types[] = $post_type;
674
+ }
675
+
676
+ $input['post_types_display'] = array_unique( $post_types );
677
+ } else
678
+ $input['post_types_display'] = array();
679
+
680
+ // restrict display
681
+ if ( isset( $input['restrict_display']['groups'] ) ) {
682
+ $groups = array();
683
+
684
+ foreach ( $input['restrict_display']['groups'] as $group => $set ) {
685
+ if ( $group === 'robots' )
686
+ continue;
687
+
688
+ if ( isset( $this->groups[$group] ) )
689
+ $groups[] = $group;
690
+ }
691
+
692
+ $input['restrict_display']['groups'] = array_unique( $groups );
693
+ } else
694
+ $input['restrict_display']['groups'] = array();
695
+
696
+ if ( in_array( 'roles', $input['restrict_display']['groups'], true ) && isset( $input['restrict_display']['roles'] ) ) {
697
+ $roles = array();
698
+
699
+ foreach ( $input['restrict_display']['roles'] as $role => $set ) {
700
+ if ( isset( $this->user_roles[$role] ) )
701
+ $roles[] = $role;
702
+ }
703
+
704
+ $input['restrict_display']['roles'] = array_unique( $roles );
705
+ } else
706
+ $input['restrict_display']['roles'] = array();
707
+ } elseif ( isset( $_POST['reset_pvc_general'] ) ) {
708
+ $input = Post_Views_Counter()->defaults['general'];
709
+
710
+ add_settings_error( 'reset_general_settings', 'settings_reset', __( 'General settings restored to defaults.', 'post-views-counter' ), 'updated' );
711
+ } elseif ( isset( $_POST['reset_pvc_display'] ) ) {
712
+ $input = Post_Views_Counter()->defaults['display'];
713
+
714
+ add_settings_error( 'reset_general_settings', 'settings_reset', __( 'Display settings restored to defaults.', 'post-views-counter' ), 'updated' );
715
+ }
716
+
717
+ return $input;
718
+ }
719
+
720
+ }
includes/update.php CHANGED
@@ -1,31 +1,33 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) )
3
- exit;
4
-
5
- new Post_Views_Counter_Update();
6
-
7
- class Post_Views_Counter_Update {
8
-
9
- public function __construct() {
10
- // actions
11
- add_action( 'init', array( &$this, 'check_update' ) );
12
- }
13
-
14
- /**
15
- * Check if there's a db update required
16
- */
17
- public function check_update() {
18
- if ( ! current_user_can( 'manage_options' ) )
19
- return;
20
-
21
- // get current database version
22
- $current_db_version = get_option( 'post_views_counter_version', '1.0.0' );
23
-
24
- // new version?
25
- if ( version_compare( $current_db_version, Post_Views_Counter()->get_attribute( 'defaults', 'version' ), '<' ) ) {
26
- // update plugin version
27
- update_option( 'post_views_counter_version', Post_Views_Counter()->get_attribute( 'defaults', 'version' ) );
28
- }
29
- }
30
-
31
- }
 
 
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * Post_Views_Counter_Update class.
8
+ */
9
+ class Post_Views_Counter_Update {
10
+
11
+ public function __construct() {
12
+ // actions
13
+ add_action( 'init', array( $this, 'check_update' ) );
14
+ }
15
+
16
+ /**
17
+ * Check if there's a db update required
18
+ */
19
+ public function check_update() {
20
+ if ( ! current_user_can( 'manage_options' ) )
21
+ return;
22
+
23
+ // get current database version
24
+ $current_db_version = get_option( 'post_views_counter_version', '1.0.0' );
25
+
26
+ // new version?
27
+ if ( version_compare( $current_db_version, Post_Views_Counter()->defaults['version'], '<' ) ) {
28
+ // update plugin version
29
+ update_option( 'post_views_counter_version', Post_Views_Counter()->defaults['version'] );
30
+ }
31
+ }
32
+
33
+ }
includes/widgets.php CHANGED
@@ -1,192 +1,197 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) )
3
- exit;
4
-
5
- new Post_Views_Counter_Widgets();
6
-
7
- class Post_Views_Counter_Widgets {
8
-
9
- public function __construct() {
10
- // actions
11
- add_action( 'widgets_init', array( &$this, 'register_widgets' ) );
12
- }
13
-
14
- /**
15
- * Register PVC widget
16
- */
17
- public function register_widgets() {
18
- register_widget( 'Post_Views_Counter_List_Widget' );
19
- }
20
-
21
- }
22
-
23
- class Post_Views_Counter_List_Widget extends WP_Widget {
24
-
25
- private $pvc_options;
26
- private $pvc_defaults;
27
- private $pvc_post_types;
28
- private $pvc_order_types;
29
- private $pvc_image_sizes;
30
-
31
- public function __construct() {
32
- parent::__construct(
33
- 'Post_Views_Counter_List_Widget', __( 'Most Viewed Posts', 'post-views-counter' ), array(
34
- 'description' => __( 'Displays a list of the most viewed posts', 'post-views-counter' )
35
- )
36
- );
37
-
38
- $this->pvc_options = array_merge(
39
- array( 'general' => get_option( 'events_maker_general' ) )
40
- );
41
-
42
- $this->pvc_defaults = array(
43
- 'title' => __( 'Most Viewed Posts', 'post-views-counter' ),
44
- 'number_of_posts' => 5,
45
- 'thumbnail_size' => 'thumbnail',
46
- 'post_types' => array(),
47
- 'order' => 'desc',
48
- 'show_post_views' => true,
49
- 'show_post_thumbnail' => false,
50
- 'show_post_excerpt' => false,
51
- 'no_posts_message' => __( 'No Posts found', 'post-views-counter' )
52
- );
53
-
54
- $this->pvc_order_types = array(
55
- 'asc' => __( 'Ascending', 'post-views-counter' ),
56
- 'desc' => __( 'Descending', 'post-views-counter' )
57
- );
58
-
59
- $this->pvc_image_sizes = array_merge( array( 'full' ), get_intermediate_image_sizes() );
60
-
61
- // sort image sizes by name, ascending
62
- sort( $this->pvc_image_sizes, SORT_STRING );
63
-
64
- add_action( 'wp_loaded', array( &$this, 'load_post_types' ) );
65
- }
66
-
67
- /**
68
- * Get selected post types
69
- */
70
- public function load_post_types() {
71
- $this->pvc_post_types = Post_Views_Counter()->get_instance( 'settings' )->post_types;
72
- }
73
-
74
- /**
75
- * Display widget function
76
- */
77
- public function widget( $args, $instance ) {
78
- $instance['title'] = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
79
-
80
- $html = $args['before_widget'] . ( ! empty( $instance['title'] ) ? $args['before_title'] . $instance['title'] . $args['after_title'] : '');
81
- $html .= pvc_most_viewed_posts( $instance, false );
82
- $html .= $args['after_widget'];
83
-
84
- echo $html;
85
- }
86
-
87
- /**
88
- * Admin widget function
89
- */
90
- public function form( $instance ) {
91
- $html = '
92
- <p>
93
- <label for="' . $this->get_field_id( 'title' ) . '">' . __( 'Title', 'post-views-counter' ) . ':</label>
94
- <input id="' . $this->get_field_id( 'title' ) . '" class="widefat" name="' . $this->get_field_name( 'title' ) . '" type="text" value="' . esc_attr( isset( $instance['title'] ) ? $instance['title'] : $this->pvc_defaults['title'] ) . '" />
95
- </p>
96
- <p>
97
- <label>' . __( 'Post Types', 'post-views-counter' ) . ':</label><br />';
98
-
99
- foreach ( $this->pvc_post_types as $post_type => $post_type_name ) {
100
- $html .= '
101
- <input id="' . $this->get_field_id( 'post_types' ) . '-' . $post_type . '" type="checkbox" name="' . $this->get_field_name( 'post_types' ) . '[]" value="' . $post_type . '" ' . checked( ( ! isset( $instance['post_types'] ) ? true : in_array( $post_type, $instance['post_types'], true ) ), true, false ) . '><label for="' . $this->get_field_id( 'post_types' ) . '-' . $post_type . '">' . esc_html( $post_type_name ) . '</label>';
102
- }
103
-
104
- $show_post_thumbnail = (isset( $instance['show_post_thumbnail'] ) ? $instance['show_post_thumbnail'] : $this->pvc_defaults['show_post_thumbnail']);
105
-
106
- $html .= '
107
- </select>
108
- </p>
109
- <p>
110
- <label for="' . $this->get_field_id( 'number_of_posts' ) . '">' . __( 'Number of posts to show', 'post-views-counter' ) . ':</label>
111
- <input id="' . $this->get_field_id( 'number_of_posts' ) . '" name="' . $this->get_field_name( 'number_of_posts' ) . '" type="text" size="3" value="' . esc_attr( isset( $instance['number_of_posts'] ) ? $instance['number_of_posts'] : $this->pvc_defaults['number_of_posts'] ) . '" />
112
- </p>
113
- <p>
114
- <label for="' . $this->get_field_id( 'no_posts_message' ) . '">' . __( 'No posts message', 'post-views-counter' ) . ':</label>
115
- <input id="' . $this->get_field_id( 'no_posts_message' ) . '" class="widefat" type="text" name="' . $this->get_field_name( 'no_posts_message' ) . '" value="' . esc_attr( isset( $instance['no_posts_message'] ) ? $instance['no_posts_message'] : $this->pvc_defaults['no_posts_message'] ) . '" />
116
- </p>
117
- <p>
118
- <label for="' . $this->get_field_id( 'order' ) . '">' . __( 'Order', 'post-views-counter' ) . ':</label>
119
- <select id="' . $this->get_field_id( 'order' ) . '" name="' . $this->get_field_name( 'order' ) . '">';
120
-
121
- foreach ( $this->pvc_order_types as $id => $order ) {
122
- $html .= '
123
- <option value="' . esc_attr( $id ) . '" ' . selected( $id, (isset( $instance['order'] ) ? $instance['order'] : $this->pvc_defaults['order'] ), false ) . '>' . $order . '</option>';
124
- }
125
-
126
- $html .= '
127
- </select>
128
- </p>
129
- <p>
130
- <input id="' . $this->get_field_id( 'show_post_views' ) . '" type="checkbox" name="' . $this->get_field_name( 'show_post_views' ) . '" ' . checked( true, (isset( $instance['show_post_views'] ) ? $instance['show_post_views'] : $this->pvc_defaults['show_post_views'] ), false ) . ' /> <label for="' . $this->get_field_id( 'show_post_views' ) . '">' . __( 'Display post views?', 'post-views-counter' ) . '</label>
131
- <br />
132
- <input id="' . $this->get_field_id( 'show_post_excerpt' ) . '" type="checkbox" name="' . $this->get_field_name( 'show_post_excerpt' ) . '" ' . checked( true, (isset( $instance['show_post_excerpt'] ) ? $instance['show_post_excerpt'] : $this->pvc_defaults['show_post_excerpt'] ), false ) . ' /> <label for="' . $this->get_field_id( 'show_post_excerpt' ) . '">' . __( 'Display post excerpt?', 'post-views-counter' ) . '</label>
133
- <br />
134
- <input id="' . $this->get_field_id( 'show_post_thumbnail' ) . '" class="em-show-event-thumbnail" type="checkbox" name="' . $this->get_field_name( 'show_post_thumbnail' ) . '" ' . checked( true, $show_post_thumbnail, false ) . ' /> <label for="' . $this->get_field_id( 'show_post_thumbnail' ) . '">' . __( 'Display post thumbnail?', 'post-views-counter' ) . '</label>
135
- </p>
136
- <p class="em-event-thumbnail-size"' . ($show_post_thumbnail ? '' : ' style="display: none;"') . '>
137
- <label for="' . $this->get_field_id( 'thumbnail_size' ) . '">' . __( 'Thumbnail size', 'post-views-counter' ) . ':</label>
138
- <select id="' . $this->get_field_id( 'thumbnail_size' ) . '" name="' . $this->get_field_name( 'thumbnail_size' ) . '">';
139
-
140
- $size_type = (isset( $instance['thumbnail_size'] ) ? $instance['thumbnail_size'] : $this->pvc_defaults['thumbnail_size']);
141
-
142
- foreach ( $this->pvc_image_sizes as $size ) {
143
- $html .= '
144
- <option value="' . esc_attr( $size ) . '" ' . selected( $size, $size_type, false ) . '>' . $size . '</option>';
145
- }
146
-
147
- $html .= '
148
- </select>
149
- </p>';
150
-
151
- echo $html;
152
- }
153
-
154
- /**
155
- * Save widget function
156
- */
157
- public function update( $new_instance, $old_instance ) {
158
- // number of posts
159
- $old_instance['number_of_posts'] = (int) (isset( $new_instance['number_of_posts'] ) ? $new_instance['number_of_posts'] : $this->pvc_defaults['number_of_posts']);
160
-
161
- // order
162
- $old_instance['order'] = (isset( $new_instance['order'] ) && in_array( $new_instance['order'], array_keys( $this->pvc_order_types ), true ) ? $new_instance['order'] : $this->pvc_defaults['order']);
163
-
164
- // thumbnail size
165
- $old_instance['thumbnail_size'] = (isset( $new_instance['thumbnail_size'] ) && in_array( $new_instance['thumbnail_size'], $this->pvc_image_sizes, true ) ? $new_instance['thumbnail_size'] : $this->pvc_defaults['thumbnail_size']);
166
-
167
- // booleans
168
- $old_instance['show_post_views'] = (isset( $new_instance['show_post_views'] ) ? true : false);
169
- $old_instance['show_post_thumbnail'] = (isset( $new_instance['show_post_thumbnail'] ) ? true : false);
170
- $old_instance['show_post_excerpt'] = (isset( $new_instance['show_post_excerpt'] ) ? true : false);
171
-
172
- // texts
173
- $old_instance['title'] = sanitize_text_field( isset( $new_instance['title'] ) ? $new_instance['title'] : $this->pvc_defaults['title'] );
174
- $old_instance['no_posts_message'] = sanitize_text_field( isset( $new_instance['no_posts_message'] ) ? $new_instance['no_posts_message'] : $this->pvc_defaults['no_posts_message'] );
175
-
176
- // post types
177
- if ( isset( $new_instance['post_types'] ) ) {
178
- $post_types = array();
179
-
180
- foreach ( $new_instance['post_types'] as $post_type ) {
181
- if ( isset( $this->pvc_post_types[$post_type] ) )
182
- $post_types[] = $post_type;
183
- }
184
-
185
- $old_instance['post_types'] = array_unique( $post_types );
186
- } else
187
- $old_instance['post_types'] = array( 'post' );
188
-
189
- return $old_instance;
190
- }
191
-
192
- }
 
 
 
 
 
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * Post_Views_Counter_Widgets class.
8
+ */
9
+ class Post_Views_Counter_Widgets {
10
+
11
+ public function __construct() {
12
+ // actions
13
+ add_action( 'widgets_init', array( $this, 'register_widgets' ) );
14
+ }
15
+
16
+ /**
17
+ * Register widgets.
18
+ */
19
+ public function register_widgets() {
20
+ register_widget( 'Post_Views_Counter_List_Widget' );
21
+ }
22
+
23
+ }
24
+
25
+ /**
26
+ * Post_Views_Counter_List_Widget class.
27
+ */
28
+ class Post_Views_Counter_List_Widget extends WP_Widget {
29
+
30
+ private $pvc_options;
31
+ private $pvc_defaults;
32
+ private $pvc_post_types;
33
+ private $pvc_order_types;
34
+ private $pvc_image_sizes;
35
+
36
+ public function __construct() {
37
+ parent::__construct(
38
+ 'Post_Views_Counter_List_Widget', __( 'Most Viewed Posts', 'post-views-counter' ), array(
39
+ 'description' => __( 'Displays a list of the most viewed posts', 'post-views-counter' )
40
+ )
41
+ );
42
+
43
+ $this->pvc_options = array_merge(
44
+ array( 'general' => get_option( 'events_maker_general' ) )
45
+ );
46
+
47
+ $this->pvc_defaults = array(
48
+ 'title' => __( 'Most Viewed Posts', 'post-views-counter' ),
49
+ 'number_of_posts' => 5,
50
+ 'thumbnail_size' => 'thumbnail',
51
+ 'post_types' => array(),
52
+ 'order' => 'desc',
53
+ 'show_post_views' => true,
54
+ 'show_post_thumbnail' => false,
55
+ 'show_post_excerpt' => false,
56
+ 'no_posts_message' => __( 'No Posts found', 'post-views-counter' )
57
+ );
58
+
59
+ $this->pvc_order_types = array(
60
+ 'asc' => __( 'Ascending', 'post-views-counter' ),
61
+ 'desc' => __( 'Descending', 'post-views-counter' )
62
+ );
63
+
64
+ $this->pvc_image_sizes = array_merge( array( 'full' ), get_intermediate_image_sizes() );
65
+
66
+ // sort image sizes by name, ascending
67
+ sort( $this->pvc_image_sizes, SORT_STRING );
68
+
69
+ add_action( 'wp_loaded', array( $this, 'load_post_types' ) );
70
+ }
71
+
72
+ /**
73
+ * Get selected post types.
74
+ */
75
+ public function load_post_types() {
76
+ $this->pvc_post_types = Post_Views_Counter()->settings->post_types;
77
+ }
78
+
79
+ /**
80
+ * Display widget function.
81
+ */
82
+ public function widget( $args, $instance ) {
83
+ $instance['title'] = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
84
+
85
+ $html = $args['before_widget'] . ( ! empty( $instance['title'] ) ? $args['before_title'] . $instance['title'] . $args['after_title'] : '');
86
+ $html .= pvc_most_viewed_posts( $instance, false );
87
+ $html .= $args['after_widget'];
88
+
89
+ echo $html;
90
+ }
91
+
92
+ /**
93
+ * Admin widget function.
94
+ */
95
+ public function form( $instance ) {
96
+ $html = '
97
+ <p>
98
+ <label for="' . $this->get_field_id( 'title' ) . '">' . __( 'Title', 'post-views-counter' ) . ':</label>
99
+ <input id="' . $this->get_field_id( 'title' ) . '" class="widefat" name="' . $this->get_field_name( 'title' ) . '" type="text" value="' . esc_attr( isset( $instance['title'] ) ? $instance['title'] : $this->pvc_defaults['title'] ) . '" />
100
+ </p>
101
+ <p>
102
+ <label>' . __( 'Post Types', 'post-views-counter' ) . ':</label><br />';
103
+
104
+ foreach ( $this->pvc_post_types as $post_type => $post_type_name ) {
105
+ $html .= '
106
+ <input id="' . $this->get_field_id( 'post_types' ) . '-' . $post_type . '" type="checkbox" name="' . $this->get_field_name( 'post_types' ) . '[]" value="' . $post_type . '" ' . checked( ( ! isset( $instance['post_types'] ) ? true : in_array( $post_type, $instance['post_types'], true ) ), true, false ) . '><label for="' . $this->get_field_id( 'post_types' ) . '-' . $post_type . '">' . esc_html( $post_type_name ) . '</label>';
107
+ }
108
+
109
+ $show_post_thumbnail = isset( $instance['show_post_thumbnail'] ) ? $instance['show_post_thumbnail'] : $this->pvc_defaults['show_post_thumbnail'];
110
+
111
+ $html .= '
112
+ </select>
113
+ </p>
114
+ <p>
115
+ <label for="' . $this->get_field_id( 'number_of_posts' ) . '">' . __( 'Number of posts to show', 'post-views-counter' ) . ':</label>
116
+ <input id="' . $this->get_field_id( 'number_of_posts' ) . '" name="' . $this->get_field_name( 'number_of_posts' ) . '" type="text" size="3" value="' . esc_attr( isset( $instance['number_of_posts'] ) ? $instance['number_of_posts'] : $this->pvc_defaults['number_of_posts'] ) . '" />
117
+ </p>
118
+ <p>
119
+ <label for="' . $this->get_field_id( 'no_posts_message' ) . '">' . __( 'No posts message', 'post-views-counter' ) . ':</label>
120
+ <input id="' . $this->get_field_id( 'no_posts_message' ) . '" class="widefat" type="text" name="' . $this->get_field_name( 'no_posts_message' ) . '" value="' . esc_attr( isset( $instance['no_posts_message'] ) ? $instance['no_posts_message'] : $this->pvc_defaults['no_posts_message'] ) . '" />
121
+ </p>
122
+ <p>
123
+ <label for="' . $this->get_field_id( 'order' ) . '">' . __( 'Order', 'post-views-counter' ) . ':</label>
124
+ <select id="' . $this->get_field_id( 'order' ) . '" name="' . $this->get_field_name( 'order' ) . '">';
125
+
126
+ foreach ( $this->pvc_order_types as $id => $order ) {
127
+ $html .= '
128
+ <option value="' . esc_attr( $id ) . '" ' . selected( $id, ( isset( $instance['order'] ) ? $instance['order'] : $this->pvc_defaults['order'] ), false ) . '>' . $order . '</option>';
129
+ }
130
+
131
+ $html .= '
132
+ </select>
133
+ </p>
134
+ <p>
135
+ <input id="' . $this->get_field_id( 'show_post_views' ) . '" type="checkbox" name="' . $this->get_field_name( 'show_post_views' ) . '" ' . checked( true, (isset( $instance['show_post_views'] ) ? $instance['show_post_views'] : $this->pvc_defaults['show_post_views'] ), false ) . ' /> <label for="' . $this->get_field_id( 'show_post_views' ) . '">' . __( 'Display post views?', 'post-views-counter' ) . '</label>
136
+ <br />
137
+ <input id="' . $this->get_field_id( 'show_post_excerpt' ) . '" type="checkbox" name="' . $this->get_field_name( 'show_post_excerpt' ) . '" ' . checked( true, (isset( $instance['show_post_excerpt'] ) ? $instance['show_post_excerpt'] : $this->pvc_defaults['show_post_excerpt'] ), false ) . ' /> <label for="' . $this->get_field_id( 'show_post_excerpt' ) . '">' . __( 'Display post excerpt?', 'post-views-counter' ) . '</label>
138
+ <br />
139
+ <input id="' . $this->get_field_id( 'show_post_thumbnail' ) . '" class="em-show-event-thumbnail" type="checkbox" name="' . $this->get_field_name( 'show_post_thumbnail' ) . '" ' . checked( true, $show_post_thumbnail, false ) . ' /> <label for="' . $this->get_field_id( 'show_post_thumbnail' ) . '">' . __( 'Display post thumbnail?', 'post-views-counter' ) . '</label>
140
+ </p>
141
+ <p class="em-event-thumbnail-size"' . ($show_post_thumbnail ? '' : ' style="display: none;"') . '>
142
+ <label for="' . $this->get_field_id( 'thumbnail_size' ) . '">' . __( 'Thumbnail size', 'post-views-counter' ) . ':</label>
143
+ <select id="' . $this->get_field_id( 'thumbnail_size' ) . '" name="' . $this->get_field_name( 'thumbnail_size' ) . '">';
144
+
145
+ $size_type = isset( $instance['thumbnail_size'] ) ? $instance['thumbnail_size'] : $this->pvc_defaults['thumbnail_size'];
146
+
147
+ foreach ( $this->pvc_image_sizes as $size ) {
148
+ $html .= '
149
+ <option value="' . esc_attr( $size ) . '" ' . selected( $size, $size_type, false ) . '>' . $size . '</option>';
150
+ }
151
+
152
+ $html .= '
153
+ </select>
154
+ </p>';
155
+
156
+ echo $html;
157
+ }
158
+
159
+ /**
160
+ * Save widget function.
161
+ */
162
+ public function update( $new_instance, $old_instance ) {
163
+ // number of posts
164
+ $old_instance['number_of_posts'] = (int) (isset( $new_instance['number_of_posts'] ) ? $new_instance['number_of_posts'] : $this->pvc_defaults['number_of_posts']);
165
+
166
+ // order
167
+ $old_instance['order'] = isset( $new_instance['order'] ) && in_array( $new_instance['order'], array_keys( $this->pvc_order_types ), true ) ? $new_instance['order'] : $this->pvc_defaults['order'];
168
+
169
+ // thumbnail size
170
+ $old_instance['thumbnail_size'] = isset( $new_instance['thumbnail_size'] ) && in_array( $new_instance['thumbnail_size'], $this->pvc_image_sizes, true ) ? $new_instance['thumbnail_size'] : $this->pvc_defaults['thumbnail_size'];
171
+
172
+ // booleans
173
+ $old_instance['show_post_views'] = isset( $new_instance['show_post_views'] );
174
+ $old_instance['show_post_thumbnail'] = isset( $new_instance['show_post_thumbnail'] );
175
+ $old_instance['show_post_excerpt'] = isset( $new_instance['show_post_excerpt'] );
176
+
177
+ // texts
178
+ $old_instance['title'] = sanitize_text_field( isset( $new_instance['title'] ) ? $new_instance['title'] : $this->pvc_defaults['title'] );
179
+ $old_instance['no_posts_message'] = sanitize_text_field( isset( $new_instance['no_posts_message'] ) ? $new_instance['no_posts_message'] : $this->pvc_defaults['no_posts_message'] );
180
+
181
+ // post types
182
+ if ( isset( $new_instance['post_types'] ) ) {
183
+ $post_types = array();
184
+
185
+ foreach ( $new_instance['post_types'] as $post_type ) {
186
+ if ( isset( $this->pvc_post_types[$post_type] ) )
187
+ $post_types[] = $post_type;
188
+ }
189
+
190
+ $old_instance['post_types'] = array_unique( $post_types );
191
+ } else
192
+ $old_instance['post_types'] = array( 'post' );
193
+
194
+ return $old_instance;
195
+ }
196
+
197
+ }
index.php CHANGED
@@ -1,3 +1,3 @@
1
- <?php
2
- // Silence is golden.
3
  ?>
1
+ <?php
2
+ // Silence is golden.
3
  ?>
js/admin-settings.js CHANGED
@@ -1,74 +1,74 @@
1
- ( function ( $ ) {
2
-
3
- $( document ).ready( function () {
4
-
5
- $( '.post-views-counter-settings' ).checkBo();
6
-
7
- var ip_boxes = $( '#pvc_exclude_ips' ).find( '.ip-box' ).length;
8
-
9
- $( '#pvc_exclude_ips .ip-box:first' ).find( '.remove-exclude-ip' ).hide();
10
-
11
- // ask whether to reset options to defaults
12
- $( document ).on( 'click', '.reset_pvc_settings', function () {
13
- return confirm( pvcArgsSettings.resetToDefaults );
14
- } );
15
-
16
- // remove ip box
17
- $( document ).on( 'click', '.remove-exclude-ip', function ( e ) {
18
- e.preventDefault();
19
-
20
- ip_boxes--;
21
-
22
- var parent = $( this ).parent();
23
-
24
- // remove ip box
25
- parent.slideUp( 'fast', function() {
26
- $( this ).remove();
27
- } );
28
- } );
29
-
30
- // add ip box
31
- $( document ).on( 'click', '.add-exclude-ip', function () {
32
- ip_boxes++;
33
-
34
- var parent = $( this ).parents( '#pvc_exclude_ips' ),
35
- new_ip_box = parent.find( '.ip-box:last' ).clone().hide();
36
-
37
- // clear value
38
- new_ip_box.find( 'input' ).val( '' );
39
-
40
- if ( ip_boxes > 1 ) {
41
- new_ip_box.find( '.remove-exclude-ip' ).show();
42
- }
43
-
44
- // add and display new ip box
45
- parent.find( '.ip-box:last' ).after( new_ip_box ).next().slideDown( 'fast' );
46
- } );
47
-
48
- // add current ip
49
- $( document ).on( 'click', '.add-current-ip', function () {
50
- // fill input with user's current ip
51
- $( this ).parents( '#pvc_exclude_ips' ).find( '.ip-box' ).last().find( 'input' ).val( $( this ).attr( 'data-rel' ) );
52
- } );
53
-
54
- // toggle user roles
55
- $( '#pvc_exclude-roles, #pvc_restrict_display-roles' ).change( function () {
56
- if ( $( this ).is(':checked') ) {
57
- $( '.pvc_user_roles' ).slideDown( 'fast' );
58
- } else {
59
- $( '.pvc_user_roles' ).slideUp( 'fast' );
60
- }
61
- } );
62
-
63
- } );
64
-
65
- } )( jQuery );
66
-
67
- /*
68
- * checkBo lightweight jQuery plugin v0.1.4 by @ElmahdiMahmoud
69
- * Licensed under the MIT license - https://github.com/elmahdim/checkbo/blob/master/LICENSE
70
- *
71
- * Custom checkbox and radio
72
- * Author URL: elmahdim.com
73
- */
74
  !function(e){e.fn.checkBo=function(c){return c=e.extend({},{checkAllButton:null,checkAllTarget:null,checkAllTextDefault:null,checkAllTextToggle:null},c),this.each(function(){function t(e){this.input=e}function n(){var c=e(this).is(":checked");e(this).closest("label").toggleClass("checked",c)}function i(e,c,t){e.text(e.parent(a).hasClass("checked")?t:c)}function h(c){var t=c.attr("data-show");c=c.attr("data-hide"),e(t).removeClass("is-hidden"),e(c).addClass("is-hidden")}var l=e(this),a=l.find(".cb-checkbox"),d=l.find(".cb-radio"),o=l.find(".cb-switcher"),s=a.find("input:checkbox"),f=d.find("input:radio");s.wrap('<span class="cb-inner"><i></i></span>'),f.wrap('<span class="cb-inner"><i></i></span>');var k=new t("input:checkbox"),r=new t("input:radio");if(t.prototype.checkbox=function(e){var c=e.find(this.input).is(":checked");e.find(this.input).prop("checked",!c).trigger("change")},t.prototype.radiobtn=function(c,t){var n=e('input:radio[name="'+t+'"]');n.prop("checked",!1),n.closest(n.closest(d)).removeClass("checked"),c.addClass("checked"),c.find(this.input).get(0).checked=c.hasClass("checked"),c.find(this.input).change()},s.on("change",n),f.on("change",n),a.find("a").on("click",function(e){e.stopPropagation()}),a.on("click",function(c){c.preventDefault(),k.checkbox(e(this)),c=e(this).attr("data-toggle"),e(c).toggleClass("is-hidden"),h(e(this))}),d.on("click",function(c){c.preventDefault(),r.radiobtn(e(this),e(this).find("input:radio").attr("name")),h(e(this))}),e.fn.toggleCheckbox=function(){this.prop("checked",!this.is(":checked"))},e.fn.switcherChecker=function(){var c=e(this),t=c.find("input"),n=c.find(".cb-state");t.is(":checked")?(c.addClass("checked"),n.html(t.attr("data-state-on"))):(c.removeClass("checked"),n.html(t.attr("data-state-off")))},o.on("click",function(c){c.preventDefault(),c=e(this),c.find("input").toggleCheckbox(),c.switcherChecker(),e(c.attr("data-toggle")).toggleClass("is-hidden")}),o.each(function(){e(this).switcherChecker()}),c.checkAllButton&&c.checkAllTarget){var u=e(this);u.find(e(c.checkAllButton)).on("click",function(){u.find(c.checkAllTarget).find("input:checkbox").each(function(){u.find(e(c.checkAllButton)).hasClass("checked")?u.find(c.checkAllTarget).find("input:checkbox").prop("checked",!0).change():u.find(c.checkAllTarget).find("input:checkbox").prop("checked",!1).change()}),i(u.find(e(c.checkAllButton)).find(".toggle-text"),c.checkAllTextDefault,c.checkAllTextToggle)}),u.find(c.checkAllTarget).find(a).on("click",function(){u.find(c.checkAllButton).find("input:checkbox").prop("checked",!1).change().removeClass("checked"),i(u.find(e(c.checkAllButton)).find(".toggle-text"),c.checkAllTextDefault,c.checkAllTextToggle)})}l.find('[checked="checked"]').closest("label").addClass("checked"),l.find("input").is("input:disabled")&&l.find("input:disabled").closest("label").off().addClass("disabled")})}}(jQuery,window,document);
1
+ ( function ( $ ) {
2
+
3
+ $( document ).ready( function () {
4
+
5
+ $( '.post-views-counter-settings' ).checkBo();
6
+
7
+ var ip_boxes = $( '#pvc_exclude_ips' ).find( '.ip-box' ).length;
8
+
9
+ $( '#pvc_exclude_ips .ip-box:first' ).find( '.remove-exclude-ip' ).hide();
10
+
11
+ // ask whether to reset options to defaults
12
+ $( document ).on( 'click', '.reset_pvc_settings', function () {
13
+ return confirm( pvcArgsSettings.resetToDefaults );
14
+ } );
15
+
16
+ // remove ip box
17
+ $( document ).on( 'click', '.remove-exclude-ip', function ( e ) {
18
+ e.preventDefault();
19
+
20
+ ip_boxes--;
21
+
22
+ var parent = $( this ).parent();
23
+
24
+ // remove ip box
25
+ parent.slideUp( 'fast', function() {
26
+ $( this ).remove();
27
+ } );
28
+ } );
29
+
30
+ // add ip box
31
+ $( document ).on( 'click', '.add-exclude-ip', function () {
32
+ ip_boxes++;
33
+
34
+ var parent = $( this ).parents( '#pvc_exclude_ips' ),
35
+ new_ip_box = parent.find( '.ip-box:last' ).clone().hide();
36
+
37
+ // clear value
38
+ new_ip_box.find( 'input' ).val( '' );
39
+
40
+ if ( ip_boxes > 1 ) {
41
+ new_ip_box.find( '.remove-exclude-ip' ).show();
42
+ }
43
+
44
+ // add and display new ip box
45
+ parent.find( '.ip-box:last' ).after( new_ip_box ).next().slideDown( 'fast' );
46
+ } );
47
+
48
+ // add current ip
49
+ $( document ).on( 'click', '.add-current-ip', function () {
50
+ // fill input with user's current ip
51
+ $( this ).parents( '#pvc_exclude_ips' ).find( '.ip-box' ).last().find( 'input' ).val( $( this ).attr( 'data-rel' ) );
52
+ } );
53
+
54
+ // toggle user roles
55
+ $( '#pvc_exclude-roles, #pvc_restrict_display-roles' ).change( function () {
56
+ if ( $( this ).is(':checked') ) {
57
+ $( '.pvc_user_roles' ).slideDown( 'fast' );
58
+ } else {
59
+ $( '.pvc_user_roles' ).slideUp( 'fast' );
60
+ }
61
+ } );
62
+
63
+ } );
64
+
65
+ } )( jQuery );
66
+
67
+ /*
68
+ * checkBo lightweight jQuery plugin v0.1.4 by @ElmahdiMahmoud
69
+ * Licensed under the MIT license - https://github.com/elmahdim/checkbo/blob/master/LICENSE
70
+ *
71
+ * Custom checkbox and radio
72
+ * Author URL: elmahdim.com
73
+ */
74
  !function(e){e.fn.checkBo=function(c){return c=e.extend({},{checkAllButton:null,checkAllTarget:null,checkAllTextDefault:null,checkAllTextToggle:null},c),this.each(function(){function t(e){this.input=e}function n(){var c=e(this).is(":checked");e(this).closest("label").toggleClass("checked",c)}function i(e,c,t){e.text(e.parent(a).hasClass("checked")?t:c)}function h(c){var t=c.attr("data-show");c=c.attr("data-hide"),e(t).removeClass("is-hidden"),e(c).addClass("is-hidden")}var l=e(this),a=l.find(".cb-checkbox"),d=l.find(".cb-radio"),o=l.find(".cb-switcher"),s=a.find("input:checkbox"),f=d.find("input:radio");s.wrap('<span class="cb-inner"><i></i></span>'),f.wrap('<span class="cb-inner"><i></i></span>');var k=new t("input:checkbox"),r=new t("input:radio");if(t.prototype.checkbox=function(e){var c=e.find(this.input).is(":checked");e.find(this.input).prop("checked",!c).trigger("change")},t.prototype.radiobtn=function(c,t){var n=e('input:radio[name="'+t+'"]');n.prop("checked",!1),n.closest(n.closest(d)).removeClass("checked"),c.addClass("checked"),c.find(this.input).get(0).checked=c.hasClass("checked"),c.find(this.input).change()},s.on("change",n),f.on("change",n),a.find("a").on("click",function(e){e.stopPropagation()}),a.on("click",function(c){c.preventDefault(),k.checkbox(e(this)),c=e(this).attr("data-toggle"),e(c).toggleClass("is-hidden"),h(e(this))}),d.on("click",function(c){c.preventDefault(),r.radiobtn(e(this),e(this).find("input:radio").attr("name")),h(e(this))}),e.fn.toggleCheckbox=function(){this.prop("checked",!this.is(":checked"))},e.fn.switcherChecker=function(){var c=e(this),t=c.find("input"),n=c.find(".cb-state");t.is(":checked")?(c.addClass("checked"),n.html(t.attr("data-state-on"))):(c.removeClass("checked"),n.html(t.attr("data-state-off")))},o.on("click",function(c){c.preventDefault(),c=e(this),c.find("input").toggleCheckbox(),c.switcherChecker(),e(c.attr("data-toggle")).toggleClass("is-hidden")}),o.each(function(){e(this).switcherChecker()}),c.checkAllButton&&c.checkAllTarget){var u=e(this);u.find(e(c.checkAllButton)).on("click",function(){u.find(c.checkAllTarget).find("input:checkbox").each(function(){u.find(e(c.checkAllButton)).hasClass("checked")?u.find(c.checkAllTarget).find("input:checkbox").prop("checked",!0).change():u.find(c.checkAllTarget).find("input:checkbox").prop("checked",!1).change()}),i(u.find(e(c.checkAllButton)).find(".toggle-text"),c.checkAllTextDefault,c.checkAllTextToggle)}),u.find(c.checkAllTarget).find(a).on("click",function(){u.find(c.checkAllButton).find("input:checkbox").prop("checked",!1).change().removeClass("checked"),i(u.find(e(c.checkAllButton)).find(".toggle-text"),c.checkAllTextDefault,c.checkAllTextToggle)})}l.find('[checked="checked"]').closest("label").addClass("checked"),l.find("input").is("input:disabled")&&l.find("input:disabled").closest("label").off().addClass("disabled")})}}(jQuery,window,document);
js/frontend.js CHANGED
@@ -1,14 +1,14 @@
1
- ( function ( $ ) {
2
-
3
- $( document ).ready( function () {
4
-
5
- $.post( pvcArgsFrontend.ajaxURL, {
6
- action: 'pvc-check-post',
7
- pvc_nonce: pvcArgsFrontend.nonce,
8
- post_id: pvcArgsFrontend.postID,
9
- post_type: pvcArgsFrontend.postType
10
- } );
11
-
12
- } );
13
-
14
  } )( jQuery );
1
+ ( function ( $ ) {
2
+
3
+ $( document ).ready( function () {
4
+
5
+ $.post( pvcArgsFrontend.ajaxURL, {
6
+ action: 'pvc-check-post',
7
+ pvc_nonce: pvcArgsFrontend.nonce,
8
+ post_id: pvcArgsFrontend.postID,
9
+ post_type: pvcArgsFrontend.postType
10
+ } );
11
+
12
+ } );
13
+
14
  } )( jQuery );
languages/post-views-counter-hr.po CHANGED
@@ -1,579 +1,579 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: Post Views Counter v1.0.7\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: \n"
6
- "PO-Revision-Date: 2015-04-09 17:59+0100\n"
7
- "Last-Translator: zytzagoo\n"
8
- "Language-Team: \n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "Plural-Forms: nplurals=3; plural=n%100/10==1 ? 2 : n%10==1 ? 0 : (n+9)%10>3 ? 2 : 1;\n"
13
- "X-Generator: Poedit 1.7.5\n"
14
- "X-Poedit-SourceCharset: utf-8\n"
15
- "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
16
- "X-Poedit-Basepath: ../\n"
17
- "X-Textdomain-Support: yes\n"
18
- "Language: hr_HR\n"
19
- "X-Poedit-SearchPath-0: .\n"
20
-
21
- # @ post-views-counter
22
- #: includes/columns.php:45 includes/columns.php:183 includes/columns.php:190
23
- msgid "Post Views"
24
- msgstr "Pregledi"
25
-
26
- # @ post-views-counter
27
- #: includes/cron.php:51
28
- msgid "Post Views Counter reset daily counts interval"
29
- msgstr "Interval resetiranja dnevnih podataka o pregledima"
30
-
31
- # @ post-views-counter
32
- #: includes/cron.php:56
33
- msgid "Post Views Counter cache flush interval"
34
- msgstr "Interval spremanja broja pregleda iz privremene memorije u WordPress bazu"
35
-
36
- # @ post-views-counter
37
- #: includes/functions.php:125
38
- msgid "No Posts"
39
- msgstr "Nema rezultata"
40
-
41
- # @ post-views-counter
42
- #: includes/settings.php:36
43
- msgid "Enable"
44
- msgstr "Uključeno"
45
-
46
- # @ post-views-counter
47
- #: includes/settings.php:37
48
- msgid "Disable"
49
- msgstr "Isključeno"
50
-
51
- # @ post-views-counter
52
- #: includes/settings.php:41
53
- msgid "PHP"
54
- msgstr "PHP"
55
-
56
- # @ post-views-counter
57
- #: includes/settings.php:42
58
- msgid "JavaScript"
59
- msgstr "JavaScript"
60
-
61
- # @ post-views-counter
62
- #: includes/settings.php:46
63
- msgid "minutes"
64
- msgstr "minuta/minute"
65
-
66
- # @ post-views-counter
67
- #: includes/settings.php:47
68
- msgid "hours"
69
- msgstr "sat/sata/sati"
70
-
71
- # @ post-views-counter
72
- #: includes/settings.php:48
73
- msgid "days"
74
- msgstr "dan/dana"
75
-
76
- # @ post-views-counter
77
- #: includes/settings.php:49
78
- msgid "weeks"
79
- msgstr "tjedan/tjedana/tjedna"
80
-
81
- # @ post-views-counter
82
- #: includes/settings.php:50
83
- msgid "months"
84
- msgstr "mjesec/mjeseca/mjeseci"
85
-
86
- # @ post-views-counter
87
- #: includes/settings.php:51
88
- msgid "years"
89
- msgstr "godinu/godine/godina"
90
-
91
- # @ post-views-counter
92
- #: includes/settings.php:55
93
- msgid "robots"
94
- msgstr "roboti"
95
-
96
- # @ post-views-counter
97
- #: includes/settings.php:56
98
- msgid "logged in users"
99
- msgstr "prijavljeni korisnici"
100
-
101
- # @ post-views-counter
102
- #: includes/settings.php:57
103
- msgid "guests"
104
- msgstr "gosti"
105
-
106
- # @ post-views-counter
107
- #: includes/settings.php:58
108
- msgid "selected user roles"
109
- msgstr "odabrane korisničke role"
110
-
111
- # @ post-views-counter
112
- #: includes/settings.php:62
113
- msgid "before the content"
114
- msgstr "prije sadržaja"
115
-
116
- # @ post-views-counter
117
- #: includes/settings.php:63
118
- msgid "after the content"
119
- msgstr "nakon sadržaja"
120
-
121
- # @ post-views-counter
122
- #: includes/settings.php:64
123
- msgid "manual"
124
- msgstr "ručno"
125
-
126
- # @ post-views-counter
127
- #: includes/settings.php:68
128
- msgid "icon"
129
- msgstr "ikona"
130
-
131
- # @ post-views-counter
132
- #: includes/settings.php:69
133
- msgid "label"
134
- msgstr "oznaka"
135
-
136
- # @ post-views-counter
137
- #: includes/settings.php:74
138
- msgid "General"
139
- msgstr "Općenito"
140
-
141
- # @ post-views-counter
142
- #: includes/settings.php:80
143
- msgid "Display"
144
- msgstr "Prikaz"
145
-
146
- # @ post-views-counter
147
- #. translators: plugin header field 'Name'
148
- #: includes/settings.php:135 includes/settings.php:136
149
- #: includes/settings.php:151 includes/settings.php:163
150
- #: post-views-counter.php:0
151
- msgid "Post Views Counter"
152
- msgstr "Brojač pregleda"
153
-
154
- # @ post-views-counter
155
- #: includes/settings.php:165
156
- msgid "Need support?"
157
- msgstr "Trebate pomoć?"
158
-
159
- # @ post-views-counter
160
- #: includes/settings.php:166
161
- msgid "If you are having problems with this plugin, please talk about them in the"
162
- msgstr "Ako imate poteškoća s korištenjem ovog dodatka uključite se u raspravu na"
163
-
164
- # @ post-views-counter
165
- #: includes/settings.php:166
166
- msgid "Support forum"
167
- msgstr "forumima podrške"
168
-
169
- # @ post-views-counter
170
- #: includes/settings.php:168
171
- msgid "Do you like this plugin?"
172
- msgstr "Zadovoljni ste s ovim dodatkom?"
173
-
174
- # @ post-views-counter
175
- #: includes/settings.php:169
176
- msgid "Rate it 5"
177
- msgstr "Ocjenite ga 5-icom"
178
-
179
- # @ post-views-counter
180
- #: includes/settings.php:169
181
- msgid "on WordPress.org"
182
- msgstr "na WordPress.org"
183
-
184
- # @ post-views-counter
185
- #: includes/settings.php:170
186
- msgid "Blog about it & link to the"
187
- msgstr "Pišite o njemu i linkajte ga na"
188
-
189
- # @ post-views-counter
190
- #: includes/settings.php:170
191
- msgid "plugin page"
192
- msgstr "stranicu dodatka"
193
-
194
- # @ post-views-counter
195
- #: includes/settings.php:171
196
- msgid "Check out our other"
197
- msgstr "Provjerite naše ostale"
198
-
199
- # @ post-views-counter
200
- #: includes/settings.php:171
201
- msgid "WordPress plugins"
202
- msgstr "WordPress dodatke"
203
-
204
- # @ post-views-counter
205
- #: includes/settings.php:174
206
- msgid "Created by"
207
- msgstr "Autor"
208
-
209
- # @ post-views-counter
210
- #: includes/settings.php:190
211
- msgid "Reset to defaults"
212
- msgstr "Vrati na zadane postavke"
213
-
214
- # @ post-views-counter
215
- #: includes/settings.php:207
216
- msgid "General settings"
217
- msgstr "Općenite postavke"
218
-
219
- # @ post-views-counter
220
- #: includes/settings.php:208
221
- msgid "Post Types Count"
222
- msgstr "Vrste objava koje se broje"
223
-
224
- # @ post-views-counter
225
- #: includes/settings.php:209
226
- msgid "Counter Mode"
227
- msgstr "Način rada brojača"
228
-
229
- # @ post-views-counter
230
- #: includes/settings.php:210
231
- msgid "Post Views Column"
232
- msgstr "Pregledi stupac"
233
-
234
- # @ post-views-counter
235
- #: includes/settings.php:211
236
- msgid "Time Between Counts"
237
- msgstr "Vrijeme između posjeta"
238
-
239
- # @ post-views-counter
240
- #: includes/settings.php:214
241
- msgid "Exclude Visitors"
242
- msgstr "Isključi posjete"
243
-
244
- # @ post-views-counter
245
- #: includes/settings.php:215
246
- msgid "Exclude IPs"
247
- msgstr "Isključi IP adrese"
248
-
249
- # @ post-views-counter
250
- #: includes/settings.php:216
251
- msgid "WP-PostViews"
252
- msgstr "WP-PostViews"
253
-
254
- # @ post-views-counter
255
- #: includes/settings.php:217
256
- msgid "Deactivation"
257
- msgstr "Deaktivacija"
258
-
259
- # @ post-views-counter
260
- #: includes/settings.php:221
261
- msgid "Display settings"
262
- msgstr "Postavke prikaza"
263
-
264
- # @ post-views-counter
265
- #: includes/settings.php:222
266
- msgid "Post Views Label"
267
- msgstr "Oznaka brojača"
268
-
269
- # @ post-views-counter
270
- #: includes/settings.php:223
271
- msgid "Post Types Display"
272
- msgstr "Vrste objava uz koje se prikazuje brojač"
273
-
274
- # @ post-views-counter
275
- #: includes/settings.php:224
276
- msgid "Restrict Display"
277
- msgstr "Ograničenje prikaza"
278
-
279
- # @ post-views-counter
280
- #: includes/settings.php:225
281
- msgid "Position"
282
- msgstr "Pozicija brojača"
283
-
284
- # @ post-views-counter
285
- #: includes/settings.php:226
286
- msgid "Display Style"
287
- msgstr "Stil prikaza"
288
-
289
- # @ post-views-counter
290
- #: includes/settings.php:227
291
- msgid "Icon Class"
292
- msgstr "CSS klasa ikone"
293
-
294
- # @ post-views-counter
295
- #: includes/settings.php:240
296
- msgid "Enter the label for the post views counter field."
297
- msgstr "Upišite naziv/oznaku koja će se prikazivati prije vrijednosti brojača"
298
-
299
- # @ post-views-counter
300
- #: includes/settings.php:253
301
- msgid "Select post types"
302
- msgstr "Odaberite vrste objava"
303
-
304
- # @ post-views-counter
305
- #: includes/settings.php:263
306
- msgid "Select post types for which post views will be counted."
307
- msgstr "Odaberite vrste objava za koje će se brojati posjete."
308
-
309
- # @ post-views-counter
310
- #: includes/settings.php:276 includes/settings.php:412
311
- #: includes/settings.php:569
312
- msgid "Select groups"
313
- msgstr "Odaberite grupe"
314
-
315
- # @ post-views-counter
316
- #: includes/settings.php:286
317
- msgid "Select post types for which post views will be displayed."
318
- msgstr "Odaberite vrste objava na kojima će se prikazivati brojač posjeta."
319
-
320
- # @ post-views-counter
321
- #: includes/settings.php:308
322
- msgid "Select the method of collecting post views data. If you are using any of the caching plugins select Javascript."
323
- msgstr "Odaberite način rada brojača. Koristite li neki od dodataka za poboljšanje performansi putem spremanja podataka u privremenu memoriju (ili slično), odaberite JavaScript."
324
-
325
- # @ post-views-counter
326
- #: includes/settings.php:330
327
- msgid "Enable to display post views count column for each of the selected post types."
328
- msgstr "Uključite ako želite prikaz stupca s vrijednostima brojača za odabrane vrste objava u administraciji."
329
-
330
- # @ post-views-counter
331
- #: includes/settings.php:353
332
- msgid "Enter the time between single user visit count."
333
- msgstr "Upišite vrijeme koje mora proći između dvije posjete istog korisnika kako bi se brojač povećao."
334
-
335
- # @ post-views-counter
336
- #: includes/settings.php:377
337
- msgid "Delete single day post views data older than specified above. Enter 0 (number zero) if you want to preserve your data regardless of its age."
338
- msgstr "Automatsko brisanje podataka o dnevnim pregledima starijim od navedenog vremena. Upišite 0 (brojka nula) ako želite čuvati sve dnevne podatke bez obzira na starost."
339
-
340
- # @ post-views-counter
341
- #: includes/settings.php:423 includes/settings.php:584
342
- msgid "Select user roles"
343
- msgstr "Odaberite korisničke uloge"
344
-
345
- # @ post-views-counter
346
- #: includes/settings.php:434
347
- msgid "Select the type of visitors to be excluded from post views count."
348
- msgstr "Odaberite vrste posjeta koje ne želite brojati."
349
-
350
- # @ post-views-counter
351
- #: includes/settings.php:450 includes/settings.php:459
352
- msgid "Remove"
353
- msgstr "Ukloni"
354
-
355
- # @ post-views-counter
356
- #: includes/settings.php:459
357
- msgid "Add new"
358
- msgstr "Dodaj"
359
-
360
- # @ post-views-counter
361
- #: includes/settings.php:459
362
- msgid "Add my current IP"
363
- msgstr "Dodaj moju trenutnu IP adresu"
364
-
365
- # @ post-views-counter
366
- #: includes/settings.php:461
367
- msgid "Enter the IP addresses to be excluded from post views count."
368
- msgstr "Upišite IP adrese s kojih se posjete neće brojati."
369
-
370
- # @ post-views-counter
371
- #: includes/settings.php:473
372
- msgid "Import"
373
- msgstr "Uvoz"
374
-
375
- # @ post-views-counter
376
- #: includes/settings.php:475
377
- msgid "Import post views data from WP-PostViews plugin."
378
- msgstr "Uvezi podatke o brojačima iz WP-PostViews dodatka."
379
-
380
- # @ post-views-counter
381
- #: includes/settings.php:476
382
- msgid "Override existing Post Views Counter data."
383
- msgstr "Uredi postojeće podatke prilikom unosa."
384
-
385
- # @ post-views-counter
386
- #: includes/settings.php:498
387
- msgid "Enable to delete all plugin data on deactivation."
388
- msgstr "\"Uključeno\" znači da će se prilikom deaktivacije dodatka svi podaci nepovratno obrisati."
389
-
390
- # @ post-views-counter
391
- #: includes/settings.php:520
392
- msgid "Select where would you like to display the post views counter. Use [post-views] shortcode for manual display."
393
- msgstr "Odaberite gdje želite prikazati brojač. Možete koristiti [post-views] shortcode za ručno prikazivanje negdje u temi."
394
-
395
- # @ post-views-counter
396
- #: includes/settings.php:542
397
- msgid "Choose how to display the post views counter."
398
- msgstr "Odaberite kako želite prikazati brojač."
399
-
400
- # @ post-views-counter
401
- #: includes/settings.php:556
402
- #, php-format
403
- msgid "Enter the post views icon class. Any of the <a href=\"%s\" target=\"_blank\">Dashicons</a> classes are available."
404
- msgstr "Upišite CSS klasu ikone brojača (bilo koju od standardnih <a href=\"%s\" target=\"_blank\">Dashicons</a> klasa)."
405
-
406
- # @ post-views-counter
407
- #: includes/settings.php:595
408
- msgid "Use it to hide the post views counter from selected type of visitors."
409
- msgstr "Brojač pregleda neće se prikazivati ovim vrstama posjetitelja (biti će skriven)."
410
-
411
- # @ post-views-counter
412
- #: includes/settings.php:626
413
- msgid "WP-PostViews data imported succesfully."
414
- msgstr "WP-PostViews podaci uspješno uvezeni."
415
-
416
- # @ post-views-counter
417
- #: includes/settings.php:628
418
- msgid "There was no data to import."
419
- msgstr "Nisu pronađeni podaci za uvoz."
420
-
421
- # @ post-views-counter
422
- #: includes/settings.php:786
423
- msgid "General settings restored to defaults."
424
- msgstr "Općenite postavke vraćene su na zadane vrijednosti."
425
-
426
- # @ post-views-counter
427
- #: includes/settings.php:790
428
- msgid "Display settings restored to defaults."
429
- msgstr "Postavke prikaza vraćene su na zadane vrijednosti."
430
-
431
- # @ post-views-counter
432
- #: includes/settings.php:810
433
- msgid "Support"
434
- msgstr "Podrška"
435
-
436
- # @ post-views-counter
437
- #: includes/widgets.php:32 includes/widgets.php:43
438
- msgid "Most Viewed Posts"
439
- msgstr "Najčitanije objave"
440
-
441
- # @ post-views-counter
442
- #: includes/widgets.php:34
443
- msgid "Displays a list of the most viewed posts"
444
- msgstr "Prikazuje listu najčitanijih objava"
445
-
446
- # @ post-views-counter
447
- #: includes/widgets.php:51
448
- msgid "No Posts found"
449
- msgstr "Nema rezultata"
450
-
451
- # @ post-views-counter
452
- #: includes/widgets.php:55
453
- msgid "Ascending"
454
- msgstr "Rastući (A-Z)"
455
-
456
- # @ post-views-counter
457
- #: includes/widgets.php:56
458
- msgid "Descending"
459
- msgstr "Padajući (Z-A)"
460
-
461
- # @ post-views-counter
462
- #: includes/widgets.php:93
463
- msgid "Title"
464
- msgstr "Naslov"
465
-
466
- # @ post-views-counter
467
- #: includes/widgets.php:110
468
- msgid "Number of posts to show"
469
- msgstr "Broj objava koje želite prikazati"
470
-
471
- # @ post-views-counter
472
- #: includes/widgets.php:114
473
- msgid "No posts message"
474
- msgstr "Nema objava"
475
-
476
- # @ post-views-counter
477
- #: includes/widgets.php:118
478
- msgid "Order"
479
- msgstr "Poredak"
480
-
481
- # @ post-views-counter
482
- #: includes/widgets.php:130
483
- msgid "Display post views?"
484
- msgstr "Prikaži brojač?"
485
-
486
- # @ post-views-counter
487
- #: includes/widgets.php:132
488
- msgid "Display post excerpt?"
489
- msgstr "Prikaži sažetak objave?"
490
-
491
- # @ post-views-counter
492
- #: includes/widgets.php:134
493
- msgid "Display post thumbnail?"
494
- msgstr "Prikaži thumbnail objave?"
495
-
496
- # @ post-views-counter
497
- #: includes/widgets.php:137
498
- msgid "Thumbnail size"
499
- msgstr "Dimenzije thumbnaila"
500
-
501
- # @ post-views-counter
502
- #. translators: plugin header field 'PluginURI'
503
- #: post-views-counter.php:0
504
- msgid "http://www.dfactory.eu/plugins/post-views-counter/"
505
- msgstr "http://www.dfactory.eu/plugins/post-views-counter/"
506
-
507
- # @ post-views-counter
508
- #. translators: plugin header field 'Description'
509
- #: post-views-counter.php:0
510
- msgid "Forget WP-PostViews. Display how many times a post, page or custom post type had been viewed in a simple, fast and reliable way."
511
- msgstr "Zaboravite WP-PostViews. Prikažite broj pregleda pojedine objave, stranice ili bilo kojih drugih vrsta objava na jednostavan, brz i pouzdan način."
512
-
513
- # @ post-views-counter
514
- #. translators: plugin header field 'Author'
515
- #: post-views-counter.php:0
516
- msgid "dFactory"
517
- msgstr "dFactory"
518
-
519
- # @ post-views-counter
520
- #. translators: plugin header field 'AuthorURI'
521
- #: post-views-counter.php:0
522
- msgid "http://www.dfactory.eu/"
523
- msgstr "http://www.dfactory.eu/"
524
-
525
- # @ post-views-counter
526
- #: post-views-counter.php:297
527
- msgid "Are you sure you want to reset these settings to defaults?"
528
- msgstr "Jeste li sigurni da želite vratiti postavke na njihove zadane vrijednosti?"
529
-
530
- # @ post-views-counter
531
- #: post-views-counter.php:330
532
- msgid "Settings"
533
- msgstr "Postavke"
534
-
535
- # @ post-views-counter
536
- #: includes/columns.php:49
537
- msgid "Edit"
538
- msgstr "Uredi"
539
-
540
- # @ post-views-counter
541
- #: includes/columns.php:53
542
- msgid "Adjust the views count for this post."
543
- msgstr "Promijeni vrijednost broja pregleda ove objave"
544
-
545
- # @ post-views-counter
546
- #: includes/columns.php:57
547
- msgid "OK"
548
- msgstr "OK"
549
-
550
- # @ post-views-counter
551
- #: includes/columns.php:58
552
- msgid "Cancel"
553
- msgstr "Odustani"
554
-
555
- # @ post-views-counter
556
- #: includes/settings.php:212
557
- msgid "Reset Data Interval"
558
- msgstr "Interval resetiranja podataka brojača"
559
-
560
- # @ post-views-counter
561
- #: includes/settings.php:213
562
- msgid "Flush Object Cache Interval"
563
- msgstr "Interval spremanja privremene memorije"
564
-
565
- # @ post-views-counter
566
- #: includes/settings.php:400
567
- msgid "How often to flush cached view counts from the object cache into the database. This feature is used only if a persistent object cache is detected and the interval is greater than 0 (number zero)). When used, view counts will be collected and stored in the object cache instead of the database and will then be asynchronously flushed to the database according to the specified interval.<br /><strong>Notice:</strong> Potential data loss may occur if the object cache is cleared/unavailable for the duration of the interval."
568
- msgstr "Koliko često se podaci iz privremene memorije trajno pohranjuju u bazu. Ova mogućnost biti će upotrebljena samo ako je podržana i ako je vrijednost intervala veća od 0 (brojka nula). Tada će se podaci o posjetama spremati u privremenu memoriju umjesto direktno u bazu (čime se dobija na performansama) i tek periodički trajno pohranjivati u bazu. <br><strong>Napomena:</strong> Ako se privremena memorija iznenada očisti i/ili je nedostupna, podaci iz privremene memorije mogu biti bespovratno izgubljeni."
569
-
570
- # @ post-views-counter
571
- #: includes/widgets.php:97
572
- msgid "Post Types"
573
- msgstr "Vrste objava"
574
-
575
- # @ post-views-counter
576
- #. translators: plugin header field 'Version'
577
- #: post-views-counter.php:0
578
- msgid "1.0.7"
579
- msgstr "1.0.7"
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Post Views Counter v1.0.7\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: \n"
6
+ "PO-Revision-Date: 2015-04-09 17:59+0100\n"
7
+ "Last-Translator: zytzagoo\n"
8
+ "Language-Team: \n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "Plural-Forms: nplurals=3; plural=n%100/10==1 ? 2 : n%10==1 ? 0 : (n+9)%10>3 ? 2 : 1;\n"
13
+ "X-Generator: Poedit 1.7.5\n"
14
+ "X-Poedit-SourceCharset: utf-8\n"
15
+ "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
16
+ "X-Poedit-Basepath: ../\n"
17
+ "X-Textdomain-Support: yes\n"
18
+ "Language: hr_HR\n"
19
+ "X-Poedit-SearchPath-0: .\n"
20
+
21
+ # @ post-views-counter
22
+ #: includes/columns.php:45 includes/columns.php:183 includes/columns.php:190
23
+ msgid "Post Views"
24
+ msgstr "Pregledi"
25
+
26
+ # @ post-views-counter
27
+ #: includes/cron.php:51
28
+ msgid "Post Views Counter reset daily counts interval"
29
+ msgstr "Interval resetiranja dnevnih podataka o pregledima"
30
+
31
+ # @ post-views-counter
32
+ #: includes/cron.php:56
33
+ msgid "Post Views Counter cache flush interval"
34
+ msgstr "Interval spremanja broja pregleda iz privremene memorije u WordPress bazu"
35
+
36
+ # @ post-views-counter
37
+ #: includes/functions.php:125
38
+ msgid "No Posts"
39
+ msgstr "Nema rezultata"
40
+
41
+ # @ post-views-counter
42
+ #: includes/settings.php:36
43
+ msgid "Enable"
44
+ msgstr "Uključeno"
45
+
46
+ # @ post-views-counter
47
+ #: includes/settings.php:37
48
+ msgid "Disable"
49
+ msgstr "Isključeno"
50
+
51
+ # @ post-views-counter
52
+ #: includes/settings.php:41
53
+ msgid "PHP"
54
+ msgstr "PHP"
55
+
56
+ # @ post-views-counter
57
+ #: includes/settings.php:42
58
+ msgid "JavaScript"
59
+ msgstr "JavaScript"
60
+
61
+ # @ post-views-counter
62
+ #: includes/settings.php:46
63
+ msgid "minutes"
64
+ msgstr "minuta/minute"
65
+
66
+ # @ post-views-counter
67
+ #: includes/settings.php:47
68
+ msgid "hours"
69
+ msgstr "sat/sata/sati"
70
+
71
+ # @ post-views-counter
72
+ #: includes/settings.php:48
73
+ msgid "days"
74
+ msgstr "dan/dana"
75
+
76
+ # @ post-views-counter
77
+ #: includes/settings.php:49
78
+ msgid "weeks"
79
+ msgstr "tjedan/tjedana/tjedna"
80
+
81
+ # @ post-views-counter
82
+ #: includes/settings.php:50
83
+ msgid "months"
84
+ msgstr "mjesec/mjeseca/mjeseci"
85
+
86
+ # @ post-views-counter
87
+ #: includes/settings.php:51
88
+ msgid "years"
89
+ msgstr "godinu/godine/godina"
90
+
91
+ # @ post-views-counter
92
+ #: includes/settings.php:55
93
+ msgid "robots"
94
+ msgstr "roboti"
95
+
96
+ # @ post-views-counter
97
+ #: includes/settings.php:56
98
+ msgid "logged in users"
99
+ msgstr "prijavljeni korisnici"
100
+
101
+ # @ post-views-counter
102
+ #: includes/settings.php:57
103
+ msgid "guests"
104
+ msgstr "gosti"
105
+
106
+ # @ post-views-counter
107
+ #: includes/settings.php:58
108
+ msgid "selected user roles"
109
+ msgstr "odabrane korisničke role"
110
+
111
+ # @ post-views-counter
112
+ #: includes/settings.php:62
113
+ msgid "before the content"
114
+ msgstr "prije sadržaja"
115
+
116
+ # @ post-views-counter
117
+ #: includes/settings.php:63
118
+ msgid "after the content"
119
+ msgstr "nakon sadržaja"
120
+
121
+ # @ post-views-counter
122
+ #: includes/settings.php:64
123
+ msgid "manual"
124
+ msgstr "ručno"
125
+
126
+ # @ post-views-counter
127
+ #: includes/settings.php:68
128
+ msgid "icon"
129
+ msgstr "ikona"
130
+
131
+ # @ post-views-counter
132
+ #: includes/settings.php:69
133
+ msgid "label"
134
+ msgstr "oznaka"
135
+
136
+ # @ post-views-counter
137
+ #: includes/settings.php:74
138
+ msgid "General"
139
+ msgstr "Općenito"
140
+
141
+ # @ post-views-counter
142
+ #: includes/settings.php:80
143
+ msgid "Display"
144
+ msgstr "Prikaz"
145
+
146
+ # @ post-views-counter
147
+ #. translators: plugin header field 'Name'
148
+ #: includes/settings.php:135 includes/settings.php:136
149
+ #: includes/settings.php:151 includes/settings.php:163
150
+ #: post-views-counter.php:0
151
+ msgid "Post Views Counter"
152
+ msgstr "Brojač pregleda"
153
+
154
+ # @ post-views-counter
155
+ #: includes/settings.php:165
156
+ msgid "Need support?"
157
+ msgstr "Trebate pomoć?"
158
+
159
+ # @ post-views-counter
160
+ #: includes/settings.php:166
161
+ msgid "If you are having problems with this plugin, please talk about them in the"
162
+ msgstr "Ako imate poteškoća s korištenjem ovog dodatka uključite se u raspravu na"
163
+
164
+ # @ post-views-counter
165
+ #: includes/settings.php:166
166
+ msgid "Support forum"
167
+ msgstr "forumima podrške"
168
+
169
+ # @ post-views-counter
170
+ #: includes/settings.php:168
171
+ msgid "Do you like this plugin?"
172
+ msgstr "Zadovoljni ste s ovim dodatkom?"
173
+
174
+ # @ post-views-counter
175
+ #: includes/settings.php:169
176
+ msgid "Rate it 5"
177
+ msgstr "Ocjenite ga 5-icom"
178
+
179
+ # @ post-views-counter
180
+ #: includes/settings.php:169
181
+ msgid "on WordPress.org"
182
+ msgstr "na WordPress.org"
183
+
184
+ # @ post-views-counter
185
+ #: includes/settings.php:170
186
+ msgid "Blog about it & link to the"
187
+ msgstr "Pišite o njemu i linkajte ga na"
188
+
189
+ # @ post-views-counter
190
+ #: includes/settings.php:170
191
+ msgid "plugin page"
192
+ msgstr "stranicu dodatka"
193
+
194
+ # @ post-views-counter
195
+ #: includes/settings.php:171
196
+ msgid "Check out our other"
197
+ msgstr "Provjerite naše ostale"
198
+
199
+ # @ post-views-counter
200
+ #: includes/settings.php:171
201
+ msgid "WordPress plugins"
202
+ msgstr "WordPress dodatke"
203
+
204
+ # @ post-views-counter
205
+ #: includes/settings.php:174
206
+ msgid "Created by"
207
+ msgstr "Autor"
208
+
209
+ # @ post-views-counter
210
+ #: includes/settings.php:190
211
+ msgid "Reset to defaults"
212
+ msgstr "Vrati na zadane postavke"
213
+
214
+ # @ post-views-counter
215
+ #: includes/settings.php:207
216
+ msgid "General settings"
217
+ msgstr "Općenite postavke"
218
+
219
+ # @ post-views-counter
220
+ #: includes/settings.php:208
221
+ msgid "Post Types Count"
222
+ msgstr "Vrste objava koje se broje"
223
+
224
+ # @ post-views-counter
225
+ #: includes/settings.php:209
226
+ msgid "Counter Mode"
227
+ msgstr "Način rada brojača"
228
+
229
+ # @ post-views-counter
230
+ #: includes/settings.php:210
231
+ msgid "Post Views Column"
232
+ msgstr "Pregledi stupac"
233
+
234
+ # @ post-views-counter
235
+ #: includes/settings.php:211
236
+ msgid "Time Between Counts"
237
+ msgstr "Vrijeme između posjeta"
238
+
239
+ # @ post-views-counter
240
+ #: includes/settings.php:214
241
+ msgid "Exclude Visitors"
242
+ msgstr "Isključi posjete"
243
+
244
+ # @ post-views-counter
245
+ #: includes/settings.php:215
246
+ msgid "Exclude IPs"
247
+ msgstr "Isključi IP adrese"
248
+
249
+ # @ post-views-counter
250
+ #: includes/settings.php:216
251
+ msgid "WP-PostViews"
252
+ msgstr "WP-PostViews"
253
+
254
+ # @ post-views-counter
255
+ #: includes/settings.php:217
256
+ msgid "Deactivation"
257
+ msgstr "Deaktivacija"
258
+
259
+ # @ post-views-counter
260
+ #: includes/settings.php:221
261
+ msgid "Display settings"
262
+ msgstr "Postavke prikaza"
263
+
264
+ # @ post-views-counter
265
+ #: includes/settings.php:222
266
+ msgid "Post Views Label"
267
+ msgstr "Oznaka brojača"
268
+
269
+ # @ post-views-counter
270
+ #: includes/settings.php:223
271
+ msgid "Post Types Display"
272
+ msgstr "Vrste objava uz koje se prikazuje brojač"
273
+
274
+ # @ post-views-counter
275
+ #: includes/settings.php:224
276
+ msgid "Restrict Display"
277
+ msgstr "Ograničenje prikaza"
278
+
279
+ # @ post-views-counter
280
+ #: includes/settings.php:225
281
+ msgid "Position"
282
+ msgstr "Pozicija brojača"
283
+
284
+ # @ post-views-counter
285
+ #: includes/settings.php:226
286
+ msgid "Display Style"
287
+ msgstr "Stil prikaza"
288
+
289
+ # @ post-views-counter
290
+ #: includes/settings.php:227
291
+ msgid "Icon Class"
292
+ msgstr "CSS klasa ikone"
293
+
294
+ # @ post-views-counter
295
+ #: includes/settings.php:240
296
+ msgid "Enter the label for the post views counter field."
297
+ msgstr "Upišite naziv/oznaku koja će se prikazivati prije vrijednosti brojača"
298
+
299
+ # @ post-views-counter
300
+ #: includes/settings.php:253
301
+ msgid "Select post types"
302
+ msgstr "Odaberite vrste objava"
303
+
304
+ # @ post-views-counter
305
+ #: includes/settings.php:263
306
+ msgid "Select post types for which post views will be counted."
307
+ msgstr "Odaberite vrste objava za koje će se brojati posjete."
308
+
309
+ # @ post-views-counter
310
+ #: includes/settings.php:276 includes/settings.php:412
311
+ #: includes/settings.php:569
312
+ msgid "Select groups"
313
+ msgstr "Odaberite grupe"
314
+
315
+ # @ post-views-counter
316
+ #: includes/settings.php:286
317
+ msgid "Select post types for which post views will be displayed."
318
+ msgstr "Odaberite vrste objava na kojima će se prikazivati brojač posjeta."
319
+
320
+ # @ post-views-counter
321
+ #: includes/settings.php:308
322
+ msgid "Select the method of collecting post views data. If you are using any of the caching plugins select Javascript."
323
+ msgstr "Odaberite način rada brojača. Koristite li neki od dodataka za poboljšanje performansi putem spremanja podataka u privremenu memoriju (ili slično), odaberite JavaScript."
324
+
325
+ # @ post-views-counter
326
+ #: includes/settings.php:330
327
+ msgid "Enable to display post views count column for each of the selected post types."
328
+ msgstr "Uključite ako želite prikaz stupca s vrijednostima brojača za odabrane vrste objava u administraciji."
329
+
330
+ # @ post-views-counter
331
+ #: includes/settings.php:353
332
+ msgid "Enter the time between single user visit count."
333
+ msgstr "Upišite vrijeme koje mora proći između dvije posjete istog korisnika kako bi se brojač povećao."
334
+
335
+ # @ post-views-counter
336
+ #: includes/settings.php:377
337
+ msgid "Delete single day post views data older than specified above. Enter 0 (number zero) if you want to preserve your data regardless of its age."
338
+ msgstr "Automatsko brisanje podataka o dnevnim pregledima starijim od navedenog vremena. Upišite 0 (brojka nula) ako želite čuvati sve dnevne podatke bez obzira na starost."
339
+
340
+ # @ post-views-counter
341
+ #: includes/settings.php:423 includes/settings.php:584
342
+ msgid "Select user roles"
343
+ msgstr "Odaberite korisničke uloge"
344
+
345
+ # @ post-views-counter
346
+ #: includes/settings.php:434
347
+ msgid "Select the type of visitors to be excluded from post views count."
348
+ msgstr "Odaberite vrste posjeta koje ne želite brojati."
349
+
350
+ # @ post-views-counter
351
+ #: includes/settings.php:450 includes/settings.php:459
352
+ msgid "Remove"
353
+ msgstr "Ukloni"
354
+
355
+ # @ post-views-counter
356
+ #: includes/settings.php:459
357
+ msgid "Add new"
358
+ msgstr "Dodaj"
359
+
360
+ # @ post-views-counter
361
+ #: includes/settings.php:459
362
+ msgid "Add my current IP"
363
+ msgstr "Dodaj moju trenutnu IP adresu"
364
+
365
+ # @ post-views-counter
366
+ #: includes/settings.php:461
367
+ msgid "Enter the IP addresses to be excluded from post views count."
368
+ msgstr "Upišite IP adrese s kojih se posjete neće brojati."
369
+
370
+ # @ post-views-counter
371
+ #: includes/settings.php:473
372
+ msgid "Import"
373
+ msgstr "Uvoz"
374
+
375
+ # @ post-views-counter
376
+ #: includes/settings.php:475
377
+ msgid "Import post views data from WP-PostViews plugin."
378
+ msgstr "Uvezi podatke o brojačima iz WP-PostViews dodatka."
379
+
380
+ # @ post-views-counter
381
+ #: includes/settings.php:476
382
+ msgid "Override existing Post Views Counter data."
383
+ msgstr "Uredi postojeće podatke prilikom unosa."
384
+
385
+ # @ post-views-counter
386
+ #: includes/settings.php:498
387
+ msgid "Enable to delete all plugin data on deactivation."
388
+ msgstr "\"Uključeno\" znači da će se prilikom deaktivacije dodatka svi podaci nepovratno obrisati."
389
+
390
+ # @ post-views-counter
391
+ #: includes/settings.php:520
392
+ msgid "Select where would you like to display the post views counter. Use [post-views] shortcode for manual display."
393
+ msgstr "Odaberite gdje želite prikazati brojač. Možete koristiti [post-views] shortcode za ručno prikazivanje negdje u temi."
394
+
395
+ # @ post-views-counter
396
+ #: includes/settings.php:542
397
+ msgid "Choose how to display the post views counter."
398
+ msgstr "Odaberite kako želite prikazati brojač."
399
+
400
+ # @ post-views-counter
401
+ #: includes/settings.php:556
402
+ #, php-format
403
+ msgid "Enter the post views icon class. Any of the <a href=\"%s\" target=\"_blank\">Dashicons</a> classes are available."
404
+ msgstr "Upišite CSS klasu ikone brojača (bilo koju od standardnih <a href=\"%s\" target=\"_blank\">Dashicons</a> klasa)."
405
+
406
+ # @ post-views-counter
407
+ #: includes/settings.php:595
408
+ msgid "Use it to hide the post views counter from selected type of visitors."
409
+ msgstr "Brojač pregleda neće se prikazivati ovim vrstama posjetitelja (biti će skriven)."
410
+
411
+ # @ post-views-counter
412
+ #: includes/settings.php:626
413
+ msgid "WP-PostViews data imported succesfully."
414
+ msgstr "WP-PostViews podaci uspješno uvezeni."
415
+
416
+ # @ post-views-counter
417
+ #: includes/settings.php:628
418
+ msgid "There was no data to import."
419
+ msgstr "Nisu pronađeni podaci za uvoz."
420
+
421
+ # @ post-views-counter
422
+ #: includes/settings.php:786
423
+ msgid "General settings restored to defaults."
424
+ msgstr "Općenite postavke vraćene su na zadane vrijednosti."
425
+
426
+ # @ post-views-counter
427
+ #: includes/settings.php:790
428
+ msgid "Display settings restored to defaults."
429
+ msgstr "Postavke prikaza vraćene su na zadane vrijednosti."
430
+
431
+ # @ post-views-counter
432
+ #: includes/settings.php:810
433
+ msgid "Support"
434
+ msgstr "Podrška"
435
+
436
+ # @ post-views-counter
437
+ #: includes/widgets.php:32 includes/widgets.php:43
438
+ msgid "Most Viewed Posts"
439
+ msgstr "Najčitanije objave"
440
+
441
+ # @ post-views-counter
442
+ #: includes/widgets.php:34
443
+ msgid "Displays a list of the most viewed posts"
444
+ msgstr "Prikazuje listu najčitanijih objava"
445
+
446
+ # @ post-views-counter
447
+ #: includes/widgets.php:51
448
+ msgid "No Posts found"
449
+ msgstr "Nema rezultata"
450
+
451
+ # @ post-views-counter
452
+ #: includes/widgets.php:55
453
+ msgid "Ascending"
454
+ msgstr "Rastući (A-Z)"
455
+
456
+ # @ post-views-counter
457
+ #: includes/widgets.php:56
458
+ msgid "Descending"
459
+ msgstr "Padajući (Z-A)"
460
+
461
+ # @ post-views-counter
462
+ #: includes/widgets.php:93
463
+ msgid "Title"
464
+ msgstr "Naslov"
465
+
466
+ # @ post-views-counter
467
+ #: includes/widgets.php:110
468
+ msgid "Number of posts to show"
469
+ msgstr "Broj objava koje želite prikazati"
470
+
471
+ # @ post-views-counter
472
+ #: includes/widgets.php:114
473
+ msgid "No posts message"
474
+ msgstr "Nema objava"
475
+
476
+ # @ post-views-counter
477
+ #: includes/widgets.php:118
478
+ msgid "Order"
479
+ msgstr "Poredak"
480
+
481
+ # @ post-views-counter
482
+ #: includes/widgets.php:130
483
+ msgid "Display post views?"
484
+ msgstr "Prikaži brojač?"
485
+
486
+ # @ post-views-counter
487
+ #: includes/widgets.php:132
488
+ msgid "Display post excerpt?"
489
+ msgstr "Prikaži sažetak objave?"
490
+
491
+ # @ post-views-counter
492
+ #: includes/widgets.php:134
493
+ msgid "Display post thumbnail?"
494
+ msgstr "Prikaži thumbnail objave?"
495
+
496
+ # @ post-views-counter
497
+ #: includes/widgets.php:137
498
+ msgid "Thumbnail size"
499
+ msgstr "Dimenzije thumbnaila"
500
+
501
+ # @ post-views-counter
502
+ #. translators: plugin header field 'PluginURI'
503
+ #: post-views-counter.php:0
504
+ msgid "http://www.dfactory.eu/plugins/post-views-counter/"
505
+ msgstr "http://www.dfactory.eu/plugins/post-views-counter/"
506
+
507
+ # @ post-views-counter
508
+ #. translators: plugin header field 'Description'
509
+ #: post-views-counter.php:0
510
+ msgid "Forget WP-PostViews. Display how many times a post, page or custom post type had been viewed in a simple, fast and reliable way."
511
+ msgstr "Zaboravite WP-PostViews. Prikažite broj pregleda pojedine objave, stranice ili bilo kojih drugih vrsta objava na jednostavan, brz i pouzdan način."
512
+
513
+ # @ post-views-counter
514
+ #. translators: plugin header field 'Author'
515
+ #: post-views-counter.php:0
516
+ msgid "dFactory"
517
+ msgstr "dFactory"
518
+
519
+ # @ post-views-counter
520
+ #. translators: plugin header field 'AuthorURI'
521
+ #: post-views-counter.php:0
522
+ msgid "http://www.dfactory.eu/"
523
+ msgstr "http://www.dfactory.eu/"
524
+
525
+ # @ post-views-counter
526
+ #: post-views-counter.php:297
527
+ msgid "Are you sure you want to reset these settings to defaults?"
528
+ msgstr "Jeste li sigurni da želite vratiti postavke na njihove zadane vrijednosti?"
529
+
530
+ # @ post-views-counter
531
+ #: post-views-counter.php:330
532
+ msgid "Settings"
533
+ msgstr "Postavke"
534
+
535
+ # @ post-views-counter
536
+ #: includes/columns.php:49
537
+ msgid "Edit"
538
+ msgstr "Uredi"
539
+
540
+ # @ post-views-counter
541
+ #: includes/columns.php:53
542
+ msgid "Adjust the views count for this post."
543
+ msgstr "Promijeni vrijednost broja pregleda ove objave"
544
+
545
+ # @ post-views-counter
546
+ #: includes/columns.php:57
547
+ msgid "OK"
548
+ msgstr "OK"
549
+
550
+ # @ post-views-counter
551
+ #: includes/columns.php:58
552
+ msgid "Cancel"
553
+ msgstr "Odustani"
554
+
555
+ # @ post-views-counter
556
+ #: includes/settings.php:212
557
+ msgid "Reset Data Interval"
558
+ msgstr "Interval resetiranja podataka brojača"
559
+
560
+ # @ post-views-counter
561
+ #: includes/settings.php:213
562
+ msgid "Flush Object Cache Interval"
563
+ msgstr "Interval spremanja privremene memorije"
564
+
565
+ # @ post-views-counter
566
+ #: includes/settings.php:400
567
+ msgid "How often to flush cached view counts from the object cache into the database. This feature is used only if a persistent object cache is detected and the interval is greater than 0 (number zero)). When used, view counts will be collected and stored in the object cache instead of the database and will then be asynchronously flushed to the database according to the specified interval.<br /><strong>Notice:</strong> Potential data loss may occur if the object cache is cleared/unavailable for the duration of the interval."
568
+ msgstr "Koliko često se podaci iz privremene memorije trajno pohranjuju u bazu. Ova mogućnost biti će upotrebljena samo ako je podržana i ako je vrijednost intervala veća od 0 (brojka nula). Tada će se podaci o posjetama spremati u privremenu memoriju umjesto direktno u bazu (čime se dobija na performansama) i tek periodički trajno pohranjivati u bazu. <br><strong>Napomena:</strong> Ako se privremena memorija iznenada očisti i/ili je nedostupna, podaci iz privremene memorije mogu biti bespovratno izgubljeni."
569
+
570
+ # @ post-views-counter
571
+ #: includes/widgets.php:97
572
+ msgid "Post Types"
573
+ msgstr "Vrste objava"
574
+
575
+ # @ post-views-counter
576
+ #. translators: plugin header field 'Version'
577
+ #: post-views-counter.php:0
578
+ msgid "1.0.7"
579
+ msgstr "1.0.7"
post-views-counter.php CHANGED
@@ -1,360 +1,370 @@
1
- <?php
2
- /*
3
- Plugin Name: Post Views Counter
4
- Description: Forget WP-PostViews. Display how many times a post, page or custom post type had been viewed in a simple, fast and reliable way.
5
- Version: 1.1.2
6
- Author: dFactory
7
- Author URI: http://www.dfactory.eu/
8
- Plugin URI: http://www.dfactory.eu/plugins/post-views-counter/
9
- License: MIT License
10
- License URI: http://opensource.org/licenses/MIT
11
- Text Domain: post-views-counter
12
- Domain Path: /languages
13
-
14
- Post Views Counter
15
- Copyright (C) 2014-2015, Digital Factory - info@digitalfactory.pl
16
-
17
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
18
-
19
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
20
-
21
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- */
23
-
24
- // exit if accessed directly
25
- if ( ! defined( 'ABSPATH' ) )
26
- exit;
27
-
28
- define( 'POST_VIEWS_COUNTER_URL', plugins_url( '', __FILE__ ) );
29
- define( 'POST_VIEWS_COUNTER_PATH', plugin_dir_path( __FILE__ ) );
30
- define( 'POST_VIEWS_COUNTER_REL_PATH', dirname( plugin_basename( __FILE__ ) ) . '/' );
31
-
32
- include_once( POST_VIEWS_COUNTER_PATH . 'includes/update.php' );
33
- include_once( POST_VIEWS_COUNTER_PATH . 'includes/settings.php' );
34
- include_once( POST_VIEWS_COUNTER_PATH . 'includes/query.php' );
35
- include_once( POST_VIEWS_COUNTER_PATH . 'includes/cron.php' );
36
- include_once( POST_VIEWS_COUNTER_PATH . 'includes/counter.php' );
37
- include_once( POST_VIEWS_COUNTER_PATH . 'includes/columns.php' );
38
- include_once( POST_VIEWS_COUNTER_PATH . 'includes/frontend.php' );
39
- include_once( POST_VIEWS_COUNTER_PATH . 'includes/widgets.php' );
40
-
41
- /**
42
- * Post Views Counter class
43
- *
44
- * @class Post_Views_Counter
45
- * @version 1.1.2
46
- */
47
- class Post_Views_Counter {
48
-
49
- private static $_instance;
50
- private $instances;
51
- private $options;
52
- private $defaults = array(
53
- 'general' => array(
54
- 'post_types_count' => array( 'post' ),
55
- 'counter_mode' => 'php',
56
- 'post_views_column' => true,
57
- 'time_between_counts' => array(
58
- 'number' => 24,
59
- 'type' => 'hours'
60
- ),
61
- 'reset_counts' => array(
62
- 'number' => 30,
63
- 'type' => 'days'
64
- ),
65
- 'flush_interval' => array(
66
- 'number' => 0,
67
- 'type' => 'minutes'
68
- ),
69
- 'exclude' => array(
70
- 'groups' => array(),
71
- 'roles' => array()
72
- ),
73
- 'exclude_ips' => array(),
74
- 'restrict_edit_views' => false,
75
- 'deactivation_delete' => false,
76
- 'cron_run' => true,
77
- 'cron_update' => true
78
- ),
79
- 'display' => array(
80
- 'label' => 'Post Views:',
81
- 'post_types_display' => array( 'post' ),
82
- 'restrict_display' => array(
83
- 'groups' => array(),
84
- 'roles' => array()
85
- ),
86
- 'position' => 'after',
87
- 'display_style' => array(
88
- 'icon' => true,
89
- 'text' => true
90
- ),
91
- 'link_to_post' => true,
92
- 'icon_class' => 'dashicons-chart-bar'
93
- ),
94
- 'version' => '1.1.2'
95
- );
96
-
97
- public static function instance() {
98
- if ( self::$_instance === null )
99
- self::$_instance = new self();
100
-
101
- return self::$_instance;
102
- }
103
-
104
- private function __clone() {
105
-
106
- }
107
-
108
- private function __wakeup() {
109
-
110
- }
111
-
112
- private function __construct() {
113
- register_activation_hook( __FILE__, array( &$this, 'activation' ) );
114
- register_deactivation_hook( __FILE__, array( &$this, 'deactivation' ) );
115
-
116
- // settings
117
- $this->options = array(
118
- 'general' => array_merge( $this->defaults['general'], get_option( 'post_views_counter_settings_general', $this->defaults['general'] ) ),
119
- 'display' => array_merge( $this->defaults['display'], get_option( 'post_views_counter_settings_display', $this->defaults['display'] ) )
120
- );
121
-
122
- // actions
123
- add_action( 'plugins_loaded', array( &$this, 'load_textdomain' ) );
124
- add_action( 'admin_enqueue_scripts', array( &$this, 'admin_scripts_styles' ) );
125
- add_action( 'wp_loaded', array( &$this, 'load_pluggable_functions' ), 10 );
126
-
127
- // filters
128
- add_filter( 'plugin_row_meta', array( &$this, 'plugin_extend_links' ), 10, 2 );
129
- add_filter( 'plugin_action_links', array( &$this, 'plugin_settings_link' ), 10, 2 );
130
- }
131
-
132
- /**
133
- * Execution of plugin activation function
134
- */
135
- public function activation() {
136
- global $wpdb, $charset_collate;
137
-
138
- // required for dbdelta
139
- require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
140
-
141
- // create post views table
142
- dbDelta( '
143
- CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'post_views (
144
- id bigint unsigned NOT NULL,
145
- type tinyint(1) unsigned NOT NULL,
146
- period varchar(8) NOT NULL,
147
- count bigint unsigned NOT NULL,
148
- PRIMARY KEY (type, period, id),
149
- UNIQUE INDEX id_period (id, period) USING BTREE,
150
- INDEX type_period_count (type, period, count) USING BTREE
151
- ) ' . $charset_collate . ';'
152
- );
153
-
154
- // add default options
155
- add_option( 'post_views_counter_settings_general', $this->defaults['general'], '', 'no' );
156
- add_option( 'post_views_counter_settings_display', $this->defaults['display'], '', 'no' );
157
- add_option( 'post_views_counter_version', $this->defaults['version'], '', 'no' );
158
-
159
- // schedule cache flush
160
- $this->schedule_cache_flush();
161
- }
162
-
163
- /**
164
- * Execution of plugin deactivation function
165
- */
166
- public function deactivation() {
167
- // delete default options
168
- if ( $this->options['general']['deactivation_delete'] ) {
169
- delete_option( 'post_views_counter_settings_general' );
170
- delete_option( 'post_views_counter_settings_display' );
171
- }
172
-
173
- // remove schedule
174
- wp_clear_scheduled_hook( 'pvc_reset_counts' );
175
- remove_action( 'pvc_reset_counts', array( Post_Views_Counter()->get_instance( 'cron' ), 'reset_counts' ) );
176
-
177
- $this->remove_cache_flush();
178
- }
179
-
180
- /**
181
- * Schedule cache flushing if it's not already scheduled
182
- */
183
- public function schedule_cache_flush( $forced = true ) {
184
- if ( $forced || ! wp_next_scheduled( 'pvc_flush_cached_counts' ) ) {
185
- wp_schedule_event( time(), 'post_views_counter_flush_interval', 'pvc_flush_cached_counts' );
186
- }
187
- }
188
-
189
- /**
190
- * Remove scheduled cache flush and the corresponding action
191
- */
192
- public function remove_cache_flush() {
193
- wp_clear_scheduled_hook( 'pvc_flush_cached_counts' );
194
- remove_action( 'pvc_flush_cached_counts', array( Post_Views_Counter()->get_instance( 'cron' ), 'flush_cached_counts' ) );
195
- }
196
-
197
- /**
198
- * Load text domain
199
- */
200
- public function load_textdomain() {
201
- load_plugin_textdomain( 'post-views-counter', false, POST_VIEWS_COUNTER_REL_PATH . 'languages/' );
202
- }
203
-
204
- /**
205
- * Load pluggable template functions
206
- */
207
- public function load_pluggable_functions() {
208
- include_once(POST_VIEWS_COUNTER_PATH . 'includes/functions.php');
209
- }
210
-
211
- /**
212
- * Set instance of class
213
- */
214
- public function add_instance( $name, $instance ) {
215
- $this->instances[$name] = $instance;
216
- }
217
-
218
- /**
219
- * Get instance of a class
220
- */
221
- public function get_instance( $name ) {
222
- if ( in_array( $name, array( 'counter', 'settings', 'cron' ), true ) )
223
- return $this->instances[$name];
224
- }
225
-
226
- /**
227
- * Get allowed attribute
228
- */
229
- public function get_attribute( $attribute ) {
230
- if ( in_array( $attribute, array( 'options', 'defaults' ), true ) ) {
231
- switch ( func_num_args() ) {
232
- case 1:
233
- return $this->{$attribute};
234
-
235
- case 2:
236
- return $this->{$attribute}[func_get_arg( 1 )];
237
-
238
- case 3:
239
- return $this->{$attribute}[func_get_arg( 1 )][func_get_arg( 2 )];
240
-
241
- case 4:
242
- return $this->{$attribute}[func_get_arg( 1 )][func_get_arg( 2 )][func_get_arg( 3 )];
243
- }
244
- } else
245
- return false;
246
- }
247
-
248
- /**
249
- * Enqueue admin scripts and styles
250
- */
251
- public function admin_scripts_styles( $page ) {
252
- wp_register_style(
253
- 'pvc-admin', POST_VIEWS_COUNTER_URL . '/css/admin.css'
254
- );
255
-
256
- wp_register_script(
257
- 'pvc-admin-settings', POST_VIEWS_COUNTER_URL . '/js/admin-settings.js', array( 'jquery' ), $this->defaults['version']
258
- );
259
-
260
- wp_register_script(
261
- 'pvc-admin-post', POST_VIEWS_COUNTER_URL . '/js/admin-post.js', array( 'jquery' ), $this->defaults['version']
262
- );
263
-
264
- wp_register_script(
265
- 'pvc-admin-quick-edit', POST_VIEWS_COUNTER_URL . '/js/admin-quick-edit.js', array( 'jquery', 'inline-edit-post' ), $this->defaults['version']
266
- );
267
-
268
- // load on PVC settings page
269
- if ( $page === 'settings_page_post-views-counter' ) {
270
-
271
- wp_enqueue_script( 'pvc-admin-settings' );
272
-
273
- wp_localize_script(
274
- 'pvc-admin-settings', 'pvcArgsSettings', array(
275
- 'resetToDefaults' => __( 'Are you sure you want to reset these settings to defaults?', 'post-views-counter' )
276
- )
277
- );
278
-
279
- wp_enqueue_style( 'pvc-admin' );
280
-
281
- // load on single post page
282
- } elseif ( $page === 'post.php' || $page === 'post-new.php' ) {
283
-
284
- $post_types = Post_Views_Counter()->get_attribute( 'options', 'general', 'post_types_count' );
285
-
286
- global $post_type;
287
-
288
- if ( ! in_array( $post_type, (array) $post_types ) )
289
- return;
290
-
291
- wp_enqueue_style( 'pvc-admin' );
292
- wp_enqueue_script( 'pvc-admin-post' );
293
- } elseif ( $page === 'edit.php' ) {
294
- $post_types = Post_Views_Counter()->get_attribute( 'options', 'general', 'post_types_count' );
295
-
296
- global $post_type;
297
-
298
- if ( ! in_array( $post_type, (array) $post_types ) )
299
- return;
300
-
301
- wp_enqueue_style( 'pvc-admin' );
302
- wp_enqueue_script( 'pvc-admin-quick-edit' );
303
- }
304
- }
305
-
306
- /**
307
- * Add links to plugin support forum.
308
- */
309
- public function plugin_extend_links( $links, $file ) {
310
-
311
- if ( ! current_user_can( 'install_plugins' ) )
312
- return $links;
313
-
314
- $plugin = plugin_basename( __FILE__ );
315
-
316
- if ( $file == $plugin ) {
317
- return array_merge(
318
- $links, array( sprintf( '<a href="http://www.dfactory.eu/support/forum/post-views-counter/" target="_blank">%s</a>', __( 'Support', 'post-views-counter' ) ) )
319
- );
320
- }
321
-
322
- return $links;
323
- }
324
-
325
- /**
326
- * Add link to settings page
327
- */
328
- public function plugin_settings_link( $links, $file ) {
329
- if ( ! is_admin() || ! current_user_can( 'manage_options' ) )
330
- return $links;
331
-
332
- static $plugin;
333
-
334
- $plugin = plugin_basename( __FILE__ );
335
-
336
- if ( $file == $plugin ) {
337
- $settings_link = sprintf( '<a href="%s">%s</a>', admin_url( 'options-general.php' ) . '?page=post-views-counter', __( 'Settings', 'post-views-counter' ) );
338
-
339
- array_unshift( $links, $settings_link );
340
- }
341
-
342
- return $links;
343
- }
344
-
345
- }
346
-
347
- /**
348
- * Initialise Post Views Counter
349
- */
350
- function Post_Views_Counter() {
351
- static $instance;
352
-
353
- // first call to instance() initializes the plugin
354
- if ( $instance === null || ! ($instance instanceof Post_Views_Counter) )
355
- $instance = Post_Views_Counter::instance();
356
-
357
- return $instance;
358
- }
359
-
 
 
 
 
 
 
 
 
 
 
360
  Post_Views_Counter();
1
+ <?php
2
+ /*
3
+ Plugin Name: Post Views Counter
4
+ Description: Forget WP-PostViews. Display how many times a post, page or custom post type had been viewed in a simple, fast and reliable way.
5
+ Version: 1.1.3
6
+ Author: dFactory
7
+ Author URI: http://www.dfactory.eu/
8
+ Plugin URI: http://www.dfactory.eu/plugins/post-views-counter/
9
+ License: MIT License
10
+ License URI: http://opensource.org/licenses/MIT
11
+ Text Domain: post-views-counter
12
+ Domain Path: /languages
13
+
14
+ Post Views Counter
15
+ Copyright (C) 2014-2015, Digital Factory - info@digitalfactory.pl
16
+
17
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ */
23
+
24
+ // exit if accessed directly
25
+ if ( ! defined( 'ABSPATH' ) )
26
+ exit;
27
+
28
+ if ( ! class_exists( 'Post_Views_Counter' ) ) :
29
+
30
+ /**
31
+ * Post Views Counter final class.
32
+ *
33
+ * @class Post_Views_Counter
34
+ * @version 1.1.3
35
+ */
36
+ final class Post_Views_Counter {
37
+
38
+ private static $instance;
39
+ public $_cron;
40
+ public $_counter;
41
+ public $_settings;
42
+ public $options;
43
+ public $defaults = array(
44
+ 'general' => array(
45
+ 'post_types_count' => array( 'post' ),
46
+ 'counter_mode' => 'php',
47
+ 'post_views_column' => true,
48
+ 'time_between_counts' => array(
49
+ 'number' => 24,
50
+ 'type' => 'hours'
51
+ ),
52
+ 'reset_counts' => array(
53
+ 'number' => 30,
54
+ 'type' => 'days'
55
+ ),
56
+ 'flush_interval' => array(
57
+ 'number' => 0,
58
+ 'type' => 'minutes'
59
+ ),
60
+ 'exclude' => array(
61
+ 'groups' => array(),
62
+ 'roles' => array()
63
+ ),
64
+ 'exclude_ips' => array(),
65
+ 'restrict_edit_views' => false,
66
+ 'deactivation_delete' => false,
67
+ 'cron_run' => true,
68
+ 'cron_update' => true
69
+ ),
70
+ 'display' => array(
71
+ 'label' => 'Post Views:',
72
+ 'post_types_display' => array( 'post' ),
73
+ 'restrict_display' => array(
74
+ 'groups' => array(),
75
+ 'roles' => array()
76
+ ),
77
+ 'position' => 'after',
78
+ 'display_style' => array(
79
+ 'icon' => true,
80
+ 'text' => true
81
+ ),
82
+ 'link_to_post' => true,
83
+ 'icon_class' => 'dashicons-chart-bar'
84
+ ),
85
+ 'version' => '1.1.3'
86
+ );
87
+
88
+ /**
89
+ * Disable object clone.
90
+ */
91
+ private function __clone() {}
92
+
93
+ /**
94
+ * Disable unserializing of the class.
95
+ */
96
+ private function __wakeup() {}
97
+
98
+ /**
99
+ * Main Post_Views_Counter instance,
100
+ * Insures that only one instance of Post_Views_Counter exists in memory at one time.
101
+ *
102
+ * @return object
103
+ */
104
+ public static function instance() {
105
+ if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Post_Views_Counter ) ) {
106
+ self::$instance = new Post_Views_Counter;
107
+ self::$instance->define_constants();
108
+
109
+ add_action( 'plugins_loaded', array( self::$instance, 'load_textdomain' ) );
110
+
111
+ self::$instance->includes();
112
+ self::$instance->update = new Post_Views_Counter_Update();
113
+ self::$instance->settings = new Post_Views_Counter_Settings();
114
+ self::$instance->query = new Post_Views_Counter_Query();
115
+ self::$instance->cron = new Post_Views_Counter_Cron();
116
+ self::$instance->counter = new Post_Views_Counter_Counter();
117
+ self::$instance->columns = new Post_Views_Counter_Columns();
118
+ self::$instance->frontend = new Post_Views_Counter_Frontend();
119
+ self::$instance->widgets = new Post_Views_Counter_Widgets();
120
+ }
121
+ return self::$instance;
122
+ }
123
+
124
+ /**
125
+ * Setup plugin constants.
126
+ *
127
+ * @return void
128
+ */
129
+ private function define_constants() {
130
+ define( 'POST_VIEWS_COUNTER_URL', plugins_url( '', __FILE__ ) );
131
+ define( 'POST_VIEWS_COUNTER_PATH', plugin_dir_path( __FILE__ ) );
132
+ define( 'POST_VIEWS_COUNTER_REL_PATH', dirname( plugin_basename( __FILE__ ) ) . '/' );
133
+ }
134
+
135
+ /**
136
+ * Include required files
137
+ *
138
+ * @return void
139
+ */
140
+ private function includes() {
141
+ include_once( POST_VIEWS_COUNTER_PATH . 'includes/update.php' );
142
+ include_once( POST_VIEWS_COUNTER_PATH . 'includes/settings.php' );
143
+ include_once( POST_VIEWS_COUNTER_PATH . 'includes/columns.php' );
144
+ include_once( POST_VIEWS_COUNTER_PATH . 'includes/query.php' );
145
+ include_once( POST_VIEWS_COUNTER_PATH . 'includes/cron.php' );
146
+ include_once( POST_VIEWS_COUNTER_PATH . 'includes/counter.php' );
147
+ include_once( POST_VIEWS_COUNTER_PATH . 'includes/frontend.php' );
148
+ include_once( POST_VIEWS_COUNTER_PATH . 'includes/widgets.php' );
149
+ }
150
+
151
+ /**
152
+ * Class constructor.
153
+ *
154
+ * @return void
155
+ */
156
+ public function __construct() {
157
+ register_activation_hook( __FILE__, array( $this, 'activation' ) );
158
+ register_deactivation_hook( __FILE__, array( $this, 'deactivation' ) );
159
+
160
+ // settings
161
+ $this->options = array(
162
+ 'general' => array_merge( $this->defaults['general'], get_option( 'post_views_counter_settings_general', $this->defaults['general'] ) ),
163
+ 'display' => array_merge( $this->defaults['display'], get_option( 'post_views_counter_settings_display', $this->defaults['display'] ) )
164
+ );
165
+
166
+ // actions
167
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts_styles' ) );
168
+ add_action( 'wp_loaded', array( $this, 'load_pluggable_functions' ), 10 );
169
+
170
+ // filters
171
+ add_filter( 'plugin_row_meta', array( $this, 'plugin_extend_links' ), 10, 2 );
172
+ add_filter( 'plugin_action_links', array( $this, 'plugin_settings_link' ), 10, 2 );
173
+ }
174
+
175
+ /**
176
+ * Plugin activation function.
177
+ */
178
+ public function activation() {
179
+ global $wpdb, $charset_collate;
180
+
181
+ // required for dbdelta
182
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
183
+
184
+ // create post views table
185
+ dbDelta( '
186
+ CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'post_views (
187
+ id bigint unsigned NOT NULL,
188
+ type tinyint(1) unsigned NOT NULL,
189
+ period varchar(8) NOT NULL,
190
+ count bigint unsigned NOT NULL,
191
+ PRIMARY KEY (type, period, id),
192
+ UNIQUE INDEX id_period (id, period) USING BTREE,
193
+ INDEX type_period_count (type, period, count) USING BTREE
194
+ ) ' . $charset_collate . ';'
195
+ );
196
+
197
+ // add default options
198
+ add_option( 'post_views_counter_settings_general', $this->defaults['general'], '', 'no' );
199
+ add_option( 'post_views_counter_settings_display', $this->defaults['display'], '', 'no' );
200
+ add_option( 'post_views_counter_version', $this->defaults['version'], '', 'no' );
201
+
202
+ // schedule cache flush
203
+ $this->schedule_cache_flush();
204
+ }
205
+
206
+ /**
207
+ * Plugin deactivation function.
208
+ */
209
+ public function deactivation() {
210
+ // delete default options
211
+ if ( $this->options['general']['deactivation_delete'] ) {
212
+ delete_option( 'post_views_counter_settings_general' );
213
+ delete_option( 'post_views_counter_settings_display' );
214
+ }
215
+
216
+ // remove schedule
217
+ wp_clear_scheduled_hook( 'pvc_reset_counts' );
218
+ remove_action( 'pvc_reset_counts', array( Post_Views_Counter()->_cron, 'reset_counts' ) );
219
+
220
+ $this->remove_cache_flush();
221
+ }
222
+
223
+ /**
224
+ * Schedule cache flushing if it's not already scheduled.
225
+ */
226
+ public function schedule_cache_flush( $forced = true ) {
227
+ if ( $forced || ! wp_next_scheduled( 'pvc_flush_cached_counts' ) ) {
228
+ wp_schedule_event( time(), 'post_views_counter_flush_interval', 'pvc_flush_cached_counts' );
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Remove scheduled cache flush and the corresponding action.
234
+ */
235
+ public function remove_cache_flush() {
236
+ wp_clear_scheduled_hook( 'pvc_flush_cached_counts' );
237
+ remove_action( 'pvc_flush_cached_counts', array( Post_Views_Counter()->_cron, 'flush_cached_counts' ) );
238
+ }
239
+
240
+ /**
241
+ * Load text domain.
242
+ */
243
+ public function load_textdomain() {
244
+ load_plugin_textdomain( 'post-views-counter', false, POST_VIEWS_COUNTER_REL_PATH . 'languages/' );
245
+ }
246
+
247
+ /**
248
+ * Load pluggable template functions.
249
+ */
250
+ public function load_pluggable_functions() {
251
+ include_once( POST_VIEWS_COUNTER_PATH . 'includes/functions.php' );
252
+ }
253
+
254
+ /**
255
+ * Enqueue admin scripts and styles.
256
+ */
257
+ public function admin_scripts_styles( $page ) {
258
+ wp_register_style(
259
+ 'pvc-admin', POST_VIEWS_COUNTER_URL . '/css/admin.css'
260
+ );
261
+
262
+ wp_register_script(
263
+ 'pvc-admin-settings', POST_VIEWS_COUNTER_URL . '/js/admin-settings.js', array( 'jquery' ), $this->defaults['version']
264
+ );
265
+
266
+ wp_register_script(
267
+ 'pvc-admin-post', POST_VIEWS_COUNTER_URL . '/js/admin-post.js', array( 'jquery' ), $this->defaults['version']
268
+ );
269
+
270
+ wp_register_script(
271
+ 'pvc-admin-quick-edit', POST_VIEWS_COUNTER_URL . '/js/admin-quick-edit.js', array( 'jquery', 'inline-edit-post' ), $this->defaults['version']
272
+ );
273
+
274
+ // load on PVC settings page
275
+ if ( $page === 'settings_page_post-views-counter' ) {
276
+
277
+ wp_enqueue_script( 'pvc-admin-settings' );
278
+
279
+ wp_localize_script(
280
+ 'pvc-admin-settings', 'pvcArgsSettings', array(
281
+ 'resetToDefaults' => __( 'Are you sure you want to reset these settings to defaults?', 'post-views-counter' )
282
+ )
283
+ );
284
+
285
+ wp_enqueue_style( 'pvc-admin' );
286
+
287
+ // load on single post page
288
+ } elseif ( $page === 'post.php' || $page === 'post-new.php' ) {
289
+
290
+ $post_types = Post_Views_Counter()->options['general']['post_types_count'];
291
+
292
+ global $post_type;
293
+
294
+ if ( ! in_array( $post_type, (array) $post_types ) )
295
+ return;
296
+
297
+ wp_enqueue_style( 'pvc-admin' );
298
+ wp_enqueue_script( 'pvc-admin-post' );
299
+ } elseif ( $page === 'edit.php' ) {
300
+ $post_types = Post_Views_Counter()->options['general']['post_types_count'];
301
+
302
+ global $post_type;
303
+
304
+ if ( ! in_array( $post_type, (array) $post_types ) )
305
+ return;
306
+
307
+ wp_enqueue_style( 'pvc-admin' );
308
+ wp_enqueue_script( 'pvc-admin-quick-edit' );
309
+ }
310
+ }
311
+
312
+ /**
313
+ * Add links to plugin support forum.
314
+ */
315
+ public function plugin_extend_links( $links, $file ) {
316
+
317
+ if ( ! current_user_can( 'install_plugins' ) )
318
+ return $links;
319
+
320
+ $plugin = plugin_basename( __FILE__ );
321
+
322
+ if ( $file == $plugin ) {
323
+ return array_merge(
324
+ $links, array( sprintf( '<a href="http://www.dfactory.eu/support/forum/post-views-counter/" target="_blank">%s</a>', __( 'Support', 'post-views-counter' ) ) )
325
+ );
326
+ }
327
+
328
+ return $links;
329
+ }
330
+
331
+ /**
332
+ * Add link to settings page.
333
+ */
334
+ public function plugin_settings_link( $links, $file ) {
335
+ if ( ! is_admin() || ! current_user_can( 'manage_options' ) )
336
+ return $links;
337
+
338
+ static $plugin;
339
+
340
+ $plugin = plugin_basename( __FILE__ );
341
+
342
+ if ( $file == $plugin ) {
343
+ $settings_link = sprintf( '<a href="%s">%s</a>', admin_url( 'options-general.php' ) . '?page=post-views-counter', __( 'Settings', 'post-views-counter' ) );
344
+
345
+ array_unshift( $links, $settings_link );
346
+ }
347
+
348
+ return $links;
349
+ }
350
+
351
+ }
352
+
353
+ endif; // end if class_exists check
354
+
355
+ /**
356
+ * Initialise Post Views Counter.
357
+ *
358
+ * @return object
359
+ */
360
+ function Post_Views_Counter() {
361
+ static $instance;
362
+
363
+ // first call to instance() initializes the plugin
364
+ if ( $instance === null || ! ( $instance instanceof Post_Views_Counter ) )
365
+ $instance = Post_Views_Counter::instance();
366
+
367
+ return $instance;
368
+ }
369
+
370
  Post_Views_Counter();
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://www.dfactory.eu/
4
  Tags: counter, hits, postviews, post views, views, count
5
  Requires at least: 4.0.0
6
  Tested up to: 4.3.1
7
- Stable tag: 1.1.2
8
  License: MIT License
9
  License URI: http://opensource.org/licenses/MIT
10
 
@@ -67,6 +67,10 @@ No questions yet.
67
 
68
  == Changelog ==
69
 
 
 
 
 
70
  = 1.1.2 =
71
  * Fix: Most viewed posts widget broken
72
 
@@ -121,5 +125,6 @@ Initial release
121
 
122
  == Upgrade Notice ==
123
 
124
- = 1.1.2 =
125
- * Fix: Most viewed posts widget broken
 
4
  Tags: counter, hits, postviews, post views, views, count
5
  Requires at least: 4.0.0
6
  Tested up to: 4.3.1
7
+ Stable tag: 1.1.3
8
  License: MIT License
9
  License URI: http://opensource.org/licenses/MIT
10
 
67
 
68
  == Changelog ==
69
 
70
+ = 1.1.3 =
71
+ * Fix: Duplicated views count in custom post types
72
+ * Fix: Exclude visitors checkboxes not working
73
+
74
  = 1.1.2 =
75
  * Fix: Most viewed posts widget broken
76
 
125
 
126
  == Upgrade Notice ==
127
 
128
+ = 1.1.3 =
129
+ * Fix: Duplicated views count in custom post types
130
+ * Fix: Exclude visitors checkboxes not working