Dynamic Featured Image - Version 3.6.0

Version Description

  • Various security fixes.
  • Missing text domains fixes.
  • Dashicons css removed as it is no longer needed.
  • Numerous WordPress coding standard improvements.
Download this release

Release Info

Developer ankitpokhrel
Plugin Icon wp plugin Dynamic Featured Image
Version 3.6.0
Comparing to
See all releases

Code changes from version 3.5.2 to 3.6.0

css/dashicons.css DELETED
@@ -1,760 +0,0 @@
1
- @font-face {
2
- font-family: "dashicons";
3
- src: url("fonts/dashicons.eot");
4
- }
5
-
6
- @font-face {
7
- font-family: "dashicons";
8
- src: url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff'),
9
- url("fonts/dashicons.ttf") format("truetype"),
10
- url("fonts/dashicons.svg#dashicons") format("svg");
11
- font-weight: normal;
12
- font-style: normal;
13
- }
14
-
15
- .dashicons {
16
- display: inline-block;
17
- width: 20px;
18
- height: 20px;
19
- -webkit-font-smoothing: antialiased;
20
- font-size: 20px;
21
- line-height: 1;
22
- font-family: "dashicons";
23
- text-decoration: inherit;
24
- font-weight: normal;
25
- font-style: normal;
26
- vertical-align: top;
27
- -moz-transition: color .1s ease-in 0;
28
- -webkit-transition: color .1s ease-in 0;
29
- text-align: center;
30
- }
31
-
32
-
33
- /* Admin Menu Icons */
34
-
35
- .dashicons-menu:before {
36
- content:"\f333";
37
- }
38
-
39
- .dashicons-admin-site:before {
40
- content:"\f319";
41
- }
42
-
43
- .dashicons-dashboard:before {
44
- content:"\f226";
45
- }
46
-
47
- .dashicons-admin-media:before {
48
- content: "\f104";
49
- }
50
-
51
- .dashicons-admin-page:before {
52
- content: "\f105";
53
- }
54
-
55
- .dashicons-admin-comments:before {
56
- content: "\f101";
57
- }
58
-
59
- .dashicons-admin-appearance:before {
60
- content: "\f100";
61
- }
62
-
63
- .dashicons-admin-plugins:before {
64
- content: "\f106";
65
- }
66
-
67
- .dashicons-admin-users:before {
68
- content: "\f110";
69
- }
70
-
71
- .dashicons-admin-tools:before {
72
- content: "\f107";
73
- }
74
-
75
- .dashicons-admin-settings:before {
76
- content: "\f108";
77
- }
78
-
79
- .dashicons-admin-network:before {
80
- content: "\f112";
81
- }
82
-
83
- .dashicons-admin-generic:before {
84
- content: "\f111";
85
- }
86
-
87
- .dashicons-admin-home:before {
88
- content: "\f102";
89
- }
90
-
91
- .dashicons-admin-collapse:before {
92
- content:"\f148";
93
- }
94
-
95
-
96
- /* Both Admin Menu and Post Formats */
97
-
98
- .dashicons-admin-links:before,
99
- .dashicons-format-links:before {
100
- content: "\f103";
101
- }
102
-
103
- .dashicons-admin-post:before,
104
- .dashicons-format-standard:before {
105
- content: "\f109";
106
- }
107
-
108
-
109
- /* Post Format Icons */
110
-
111
- .dashicons-format-image:before {
112
- content: "\f128";
113
- }
114
-
115
- .dashicons-format-gallery:before {
116
- content: "\f161";
117
- }
118
-
119
- .dashicons-format-audio:before {
120
- content: "\f127";
121
- }
122
-
123
- .dashicons-format-video:before {
124
- content: "\f126";
125
- }
126
-
127
- .dashicons-format-chat:before {
128
- content: "\f125";
129
- }
130
-
131
- .dashicons-format-status:before {
132
- content: "\f130";
133
- }
134
-
135
- .dashicons-format-aside:before {
136
- content: "\f123";
137
- }
138
-
139
- .dashicons-format-quote:before {
140
- content: "\f122";
141
- }
142
-
143
-
144
- /* Welcome Screen Icons */
145
-
146
- .dashicons-welcome-write-blog:before,
147
- .dashicons-welcome-edit-page:before {
148
- content:"\f119";
149
- }
150
-
151
- .dashicons-welcome-add-page:before {
152
- content:"\f133";
153
- }
154
-
155
- .dashicons-welcome-view-site:before {
156
- content:"\f115";
157
- }
158
-
159
- .dashicons-welcome-widgets-menus:before {
160
- content:"\f116";
161
- }
162
-
163
- .dashicons-welcome-comments:before {
164
- content:"\f117";
165
- }
166
-
167
- .dashicons-welcome-learn-more:before {
168
- content:"\f118";
169
- }
170
-
171
-
172
- /* Image Editing Icons */
173
-
174
- .dashicons-image-crop:before {
175
- content:"\f165";
176
- }
177
-
178
- .dashicons-image-rotate-left:before {
179
- content:"\f166";
180
- }
181
-
182
- .dashicons-image-rotate-right:before {
183
- content:"\f167";
184
- }
185
-
186
- .dashicons-image-flip-vertical:before {
187
- content:"\f168";
188
- }
189
-
190
- .dashicons-image-flip-horizontal:before {
191
- content:"\f169";
192
- }
193
-
194
-
195
- /* Both Image Editing and TinyMCE */
196
-
197
- .dashicons-undo:before {
198
- content:"\f171";
199
- }
200
-
201
- .dashicons-redo:before {
202
- content:"\f172";
203
- }
204
-
205
- /* TinyMCE Icons */
206
-
207
- .dashicons-editor-bold:before {
208
- content:"\f200";
209
- }
210
-
211
- .dashicons-editor-italic:before {
212
- content:"\f201";
213
- }
214
-
215
- .dashicons-editor-ul:before {
216
- content:"\f203";
217
- }
218
-
219
- .dashicons-editor-ol:before {
220
- content:"\f204";
221
- }
222
-
223
- .dashicons-editor-quote:before {
224
- content:"\f205";
225
- }
226
-
227
- .dashicons-editor-alignleft:before {
228
- content:"\f206";
229
- }
230
-
231
- .dashicons-editor-aligncenter:before {
232
- content:"\f207";
233
- }
234
-
235
- .dashicons-editor-alignright:before {
236
- content:"\f208";
237
- }
238
-
239
- .dashicons-editor-insertmore:before {
240
- content:"\f209";
241
- }
242
-
243
- .dashicons-editor-spellcheck:before {
244
- content:"\f210";
245
- }
246
-
247
- .dashicons-editor-distractionfree:before {
248
- content:"\f211";
249
- }
250
-
251
- .dashicons-editor-kitchensink:before {
252
- content:"\f212";
253
- }
254
-
255
- .dashicons-editor-underline:before {
256
- content:"\f213";
257
- }
258
-
259
- .dashicons-editor-justify:before {
260
- content:"\f214";
261
- }
262
-
263
- .dashicons-editor-textcolor:before {
264
- content:"\f215";
265
- }
266
-
267
- .dashicons-editor-paste-word:before {
268
- content:"\f216";
269
- }
270
-
271
- .dashicons-editor-paste-text:before {
272
- content:"\f217";
273
- }
274
-
275
- .dashicons-editor-removeformatting:before {
276
- content:"\f218";
277
- }
278
-
279
- .dashicons-editor-video:before {
280
- content:"\f219";
281
- }
282
-
283
- .dashicons-editor-customchar:before {
284
- content:"\f220";
285
- }
286
-
287
- .dashicons-editor-outdent:before {
288
- content:"\f221";
289
- }
290
-
291
- .dashicons-editor-indent:before {
292
- content:"\f222";
293
- }
294
-
295
- .dashicons-editor-help:before {
296
- content:"\f223";
297
- }
298
-
299
- .dashicons-editor-strikethrough:before {
300
- content:"\f224";
301
- }
302
-
303
- .dashicons-editor-unlink:before {
304
- content:"\f225";
305
- }
306
-
307
- .dashicons-editor-rtl:before {
308
- content:"\f320";
309
- }
310
-
311
- .dashicons-editor-break:before {
312
- content:"\f474";
313
- }
314
-
315
- .dashicons-editor-code:before {
316
- content:"\f475";
317
- }
318
-
319
- .dashicons-editor-paragraph:before {
320
- content:"\f476";
321
- }
322
-
323
- /* Post Icons */
324
-
325
- .dashicons-align-left:before {
326
- content:"\f135";
327
- }
328
-
329
- .dashicons-align-right:before {
330
- content:"\f136";
331
- }
332
-
333
- .dashicons-align-center:before {
334
- content:"\f134";
335
- }
336
-
337
- .dashicons-align-none:before {
338
- content:"\f138";
339
- }
340
-
341
- .dashicons-lock:before {
342
- content:"\f160";
343
- }
344
-
345
- .dashicons-calendar:before {
346
- content:"\f145";
347
- }
348
-
349
- .dashicons-visibility:before {
350
- content:"\f177";
351
- }
352
-
353
- .dashicons-post-status:before {
354
- content:"\f173";
355
- }
356
-
357
- .dashicons-edit:before {
358
- content:"\f464";
359
- }
360
-
361
- .dashicons-trash:before {
362
- content:"\f182";
363
- }
364
-
365
-
366
- /* Sorting */
367
-
368
- .dashicons-arrow-up:before {
369
- content:"\f142";
370
- }
371
-
372
- .dashicons-arrow-down:before {
373
- content:"\f140";
374
- }
375
-
376
- .dashicons-arrow-left:before {
377
- content:"\f141";
378
- }
379
-
380
- .dashicons-arrow-right:before {
381
- content:"\f139";
382
- }
383
-
384
- .dashicons-arrow-up-alt:before {
385
- content:"\f342";
386
- }
387
-
388
- .dashicons-arrow-down-alt:before {
389
- content:"\f346";
390
- }
391
-
392
- .dashicons-arrow-left-alt:before {
393
- content:"\f340";
394
- }
395
-
396
- .dashicons-arrow-right-alt:before {
397
- content:"\f344";
398
- }
399
-
400
- .dashicons-arrow-up-alt2:before {
401
- content:"\f343";
402
- }
403
-
404
- .dashicons-arrow-down-alt2:before {
405
- content:"\f347";
406
- }
407
-
408
- .dashicons-arrow-left-alt2:before {
409
- content:"\f341";
410
- }
411
-
412
- .dashicons-arrow-right-alt2:before {
413
- content:"\f345";
414
- }
415
-
416
- .dashicons-leftright:before {
417
- content:"\f229";
418
- }
419
-
420
- .dashicons-sort:before {
421
- content:"\f156";
422
- }
423
-
424
- .dashicons-list-view:before {
425
- content:"\f163";
426
- }
427
-
428
- .dashicons-exerpt-view:before {
429
- content:"\f164";
430
- }
431
-
432
-
433
- /* Social Icons */
434
-
435
- .dashicons-share:before {
436
- content:"\f237";
437
- }
438
-
439
- .dashicons-share1:before {
440
- content:"\f237";
441
- }
442
-
443
- .dashicons-share-alt:before {
444
- content:"\f240";
445
- }
446
-
447
- .dashicons-share-alt2:before {
448
- content:"\f242";
449
- }
450
-
451
- .dashicons-twitter:before {
452
- content:"\f301";
453
- }
454
-
455
- .dashicons-rss:before {
456
- content:"\f303";
457
- }
458
-
459
- .dashicons-email:before {
460
- content:"\f465";
461
- }
462
-
463
- .dashicons-email-alt:before {
464
- content:"\f466";
465
- }
466
-
467
- .dashicons-facebook:before {
468
- content:"\f304";
469
- }
470
-
471
- .dashicons-facebook-alt:before {
472
- content:"\f305";
473
- }
474
-
475
- .dashicons-networking:before {
476
- content:"\f325";
477
- }
478
-
479
- .dashicons-googleplus:before {
480
- content:"\f462";
481
- }
482
-
483
-
484
- /* Jobs Icons */
485
-
486
- .dashicons-hammer:before {
487
- content:"\f308";
488
- }
489
-
490
- .dashicons-art:before {
491
- content:"\f309";
492
- }
493
-
494
- .dashicons-migrate:before {
495
- content:"\f310";
496
- }
497
-
498
- .dashicons-performance:before {
499
- content:"\f311";
500
- }
501
-
502
-
503
- /* Internal/Products */
504
-
505
- .dashicons-wordpress:before {
506
- content:"\f120";
507
- }
508
-
509
- .dashicons-wordpress-alt:before {
510
- content:"\f324";
511
- }
512
-
513
- .dashicons-pressthis:before {
514
- content:"\f157";
515
- }
516
-
517
- .dashicons-update:before {
518
- content:"\f463";
519
- }
520
-
521
- .dashicons-screenoptions:before {
522
- content:"\f180";
523
- }
524
-
525
- .dashicons-info:before {
526
- content:"\f348";
527
- }
528
-
529
- .dashicons-cart:before {
530
- content:"\f174";
531
- }
532
-
533
- .dashicons-feedback:before {
534
- content:"\f175";
535
- }
536
-
537
- .dashicons-cloud:before {
538
- content:"\f176";
539
- }
540
-
541
- .dashicons-translation:before {
542
- content:"\f326";
543
- }
544
-
545
-
546
- /* Taxonomies */
547
-
548
- .dashicons-tag:before {
549
- content:"\f323";
550
- }
551
-
552
- .dashicons-category:before {
553
- content:"\f318";
554
- }
555
-
556
-
557
- /* Alerts/Notifications/Flags */
558
-
559
- .dashicons-yes:before {
560
- content:"\f147";
561
- }
562
-
563
- .dashicons-no:before {
564
- content:"\f158";
565
- }
566
-
567
- .dashicons-no-alt:before {
568
- content:"\f335";
569
- }
570
-
571
- .dashicons-plus:before {
572
- content:"\f132";
573
- }
574
-
575
- .dashicons-minus:before {
576
- content:"\f460";
577
- }
578
-
579
- .dashicons-dismiss:before {
580
- content:"\f153";
581
- }
582
-
583
- .dashicons-marker:before {
584
- content:"\f159";
585
- }
586
-
587
- .dashicons-star-filled:before {
588
- content:"\f155";
589
- }
590
-
591
- .dashicons-star-half:before {
592
- content:"\f459";
593
- }
594
-
595
- .dashicons-star-empty:before {
596
- content:"\f154";
597
- }
598
-
599
- .dashicons-flag:before {
600
- content:"\f227";
601
- }
602
-
603
-
604
- /* Misc/CPT */
605
-
606
- .dashicons-location:before {
607
- content:"\f230";
608
- }
609
-
610
- .dashicons-location-alt:before {
611
- content:"\f231";
612
- }
613
-
614
- .dashicons-camera:before {
615
- content:"\f306";
616
- }
617
-
618
- .dashicons-images-alt:before {
619
- content:"\f232";
620
- }
621
-
622
- .dashicons-images-alt2:before {
623
- content:"\f233";
624
- }
625
-
626
- .dashicons-video-alt:before {
627
- content:"\f234";
628
- }
629
-
630
- .dashicons-video-alt2:before {
631
- content:"\f235";
632
- }
633
-
634
- .dashicons-video-alt3:before {
635
- content:"\f236";
636
- }
637
-
638
- .dashicons-vault:before {
639
- content:"\f178";
640
- }
641
-
642
- .dashicons-shield:before {
643
- content:"\f332";
644
- }
645
-
646
- .dashicons-shield-alt:before {
647
- content:"\f334";
648
- }
649
-
650
- .dashicons-sos:before {
651
- content:"\f468";
652
- }
653
-
654
- .dashicons-search:before {
655
- content:"\f179";
656
- }
657
-
658
- .dashicons-slides:before {
659
- content:"\f181";
660
- }
661
-
662
- .dashicons-analytics:before {
663
- content:"\f183";
664
- }
665
-
666
- .dashicons-chart-pie:before {
667
- content:"\f184";
668
- }
669
-
670
- .dashicons-chart-bar:before {
671
- content:"\f185";
672
- }
673
-
674
- .dashicons-chart-line:before {
675
- content:"\f238";
676
- }
677
-
678
- .dashicons-chart-area:before {
679
- content:"\f239";
680
- }
681
-
682
- .dashicons-groups:before {
683
- content:"\f307";
684
- }
685
-
686
- .dashicons-businessman:before {
687
- content:"\f338";
688
- }
689
-
690
- .dashicons-id:before {
691
- content:"\f336";
692
- }
693
-
694
- .dashicons-id-alt:before {
695
- content:"\f337";
696
- }
697
-
698
- .dashicons-products:before {
699
- content:"\f312";
700
- }
701
-
702
- .dashicons-awards:before {
703
- content:"\f313";
704
- }
705
-
706
- .dashicons-forms:before {
707
- content:"\f314";
708
- }
709
-
710
- .dashicons-testimonial:before {
711
- content:"\f473";
712
- }
713
-
714
- .dashicons-portfolio:before {
715
- content:"\f322";
716
- }
717
-
718
- .dashicons-book:before {
719
- content:"\f330";
720
- }
721
-
722
- .dashicons-book-alt:before {
723
- content:"\f331";
724
- }
725
-
726
- .dashicons-download:before {
727
- content:"\f316";
728
- }
729
-
730
- .dashicons-upload:before {
731
- content:"\f317";
732
- }
733
-
734
- .dashicons-backup:before {
735
- content:"\f321";
736
- }
737
-
738
- .dashicons-clock:before {
739
- content:"\f469";
740
- }
741
-
742
- .dashicons-lightbulb:before {
743
- content:"\f339";
744
- }
745
-
746
- .dashicons-desktop:before {
747
- content:"\f472";
748
- }
749
-
750
- .dashicons-tablet:before {
751
- content:"\f471";
752
- }
753
-
754
- .dashicons-smartphone:before {
755
- content:"\f470";
756
- }
757
-
758
- .dashicons-smiley:before {
759
- content:"\f328";
760
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/style-dfi.css CHANGED
@@ -2,17 +2,17 @@
2
  * @file style-dfi.css
3
  *
4
  * Style for dynamic featured image plugin
5
- *
6
  * Copyright (c) 2013, Ankit Pokhrel <ankitpokhrel@gmail.com, http://ankitpokhrel.com.np>
7
  */
8
 
9
  .dfiAddNew {
10
- float: left;
11
  margin-top: 3px;
12
  }
13
 
14
- .dfiRemove {
15
- float: right;
16
  }
17
 
18
  .dfiLinks{
@@ -29,7 +29,7 @@
29
  }
30
 
31
  img.dfiImg {
32
- max-width: 258px;
33
  }
34
 
35
  img.dfiImg[src=""]{
@@ -37,7 +37,7 @@ img.dfiImg[src=""]{
37
  }
38
 
39
  img.dfiImgEmpty {
40
- display: none;
41
  }
42
 
43
  .dfiLoading {
@@ -74,7 +74,7 @@ img.dfiImgEmpty {
74
  border: none;
75
  width: auto;
76
  height: auto;
77
- margin: 0 !important;
78
  position: absolute;
79
  top: 30%;
80
  left: 37%;
@@ -88,4 +88,4 @@ img.dfiImgEmpty {
88
 
89
  .dashicons:hover, .dfiFeaturedImage:hover {
90
  color: #2ea2cc !important;
91
- }
2
  * @file style-dfi.css
3
  *
4
  * Style for dynamic featured image plugin
5
+ *
6
  * Copyright (c) 2013, Ankit Pokhrel <ankitpokhrel@gmail.com, http://ankitpokhrel.com.np>
7
  */
8
 
9
  .dfiAddNew {
10
+ float: left;
11
  margin-top: 3px;
12
  }
13
 
14
+ .dfiRemove {
15
+ float: right;
16
  }
17
 
18
  .dfiLinks{
29
  }
30
 
31
  img.dfiImg {
32
+ max-width: 258px;
33
  }
34
 
35
  img.dfiImg[src=""]{
37
  }
38
 
39
  img.dfiImgEmpty {
40
+ display: none;
41
  }
42
 
43
  .dfiLoading {
74
  border: none;
75
  width: auto;
76
  height: auto;
77
+ margin: 0 !important;
78
  position: absolute;
79
  top: 30%;
80
  left: 37%;
88
 
89
  .dashicons:hover, .dfiFeaturedImage:hover {
90
  color: #2ea2cc !important;
91
+ }
dynamic-featured-image.php CHANGED
@@ -1,18 +1,20 @@
1
  <?php
2
- /***
3
  * Plugin Name: Dynamic Featured Image
4
  * Plugin URI: http://wordpress.org/plugins/dynamic-featured-image/
5
  * Description: Dynamically adds multiple featured image or post thumbnail functionality to your posts, pages and custom post types.
6
- * Version: 3.5.2
7
  * Author: Ankit Pokhrel
8
- * Author URI: http://ankitpokhrel.com.np
9
  * License: GPL2 or later
10
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
  * Text Domain: dynamic-featured-image
12
  * Domain Path: /languages
13
  * GitHub Plugin URI: https://github.com/ankitpokhrel/Dynamic-Featured-Image
14
  *
15
- * Copyright (C) 2013 Ankit Pokhrel <ankitpokhrel@gmail.com, http://ankitpokhrel.com.np>,
 
 
16
  *
17
  * This program is free software; you can redistribute it and/or modify
18
  * it under the terms of the GNU General Public License as published by
@@ -28,992 +30,1027 @@
28
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
29
  */
30
 
31
- // Avoid direct calls to this file
32
  if ( ! defined( 'ABSPATH' ) ) {
33
- header( 'Status: 403 Forbidden' );
34
- header( 'HTTP/1.1 403 Forbidden' );
35
- exit();
36
  }
37
 
38
  /**
39
- * Dynamic Featured Image plugin main class
40
  *
41
- * @package dynamic-featured-image
42
- * @author Ankit Pokhrel <ankitpokhrel@gmail.com>
43
  * @version 3.0.1
44
  */
45
  class Dynamic_Featured_Image {
46
- /**
47
- * Current version of the plugin.
48
- *
49
- * @since 3.0.0
50
- */
51
- const VERSION = '3.5.2';
52
-
53
- /* Image upload directory */
54
- private $__upload_dir;
55
-
56
- /* Image upload URL */
57
- private $__upload_url;
58
-
59
- /* Database object */
60
- private $__db;
61
-
62
- /* Plugin text domain */
63
- protected $_textDomain;
64
-
65
- /* Title for dfi metabox */
66
- protected $_metabox_title;
67
-
68
- /* Users post type filter for dfi metabox */
69
- protected $_userFilter;
70
-
71
- /**
72
- * Constructor. Hooks all interactions to initialize the class.
73
- *
74
- * @since 1.0.0
75
- * @access public
76
- * @global object $wpdb
77
- *
78
- * @see add_action()
79
- */
80
- public function __construct() {
81
- $this->_textDomain = 'dynamic-featured-image';
82
-
83
- //plugin update warning
84
- add_action( 'in_plugin_update_message-' . plugin_basename( __FILE__ ), array( $this, 'update_notice' ) );
85
-
86
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
87
- add_action( 'add_meta_boxes', array( $this, 'initialize_featured_box' ) );
88
- add_action( 'save_post', array( $this, 'save_meta' ) );
89
- add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
90
-
91
- //handle ajax request
92
- add_action( 'wp_ajax_dfiMetaBox_callback', array( $this, 'ajax_callback' ) );
93
-
94
- //add action links
95
- add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'dfi_action_links' ) );
96
-
97
- //media uploader custom fields
98
- add_filter( 'attachment_fields_to_edit', array( $this, 'media_attachment_custom_fields' ), 10, 2 );
99
- add_filter( 'attachment_fields_to_save', array( $this, 'media_attachment_custom_fields_save' ), 10, 2 );
100
-
101
- //get the site protocol
102
- $protocol = $this->__get_protocol();
103
-
104
- $this->__upload_dir = wp_upload_dir();
105
- $this->__upload_url = preg_replace( '#^https?://#', '', $this->__upload_dir['baseurl'] );
106
-
107
- //add protocol to the upload url
108
- $this->__upload_url = $protocol . $this->__upload_url;
109
-
110
- //post type filter added by user
111
- $this->_userFilter = array();
112
-
113
- global $wpdb;
114
- $this->__db = $wpdb;
115
-
116
- } // END __construct()
117
-
118
- /**
119
- * Return site protocol
120
- *
121
- * @since 3.5.1
122
- * @access public
123
- *
124
- * @return string
125
- */
126
- private function __get_protocol() {
127
- return ( ( ! empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] != 'off' ) ||
128
- ( ! empty( $_SERVER['SERVER_PORT'] ) && $_SERVER['SERVER_PORT'] == 443 ) ) ? "https://" : "http://";
129
- }
130
-
131
- /**
132
- * Add required admin scripts
133
- *
134
- * @since 1.0.0
135
- * @access public
136
- *
137
- * @see wp_enque_style()
138
- * @see wp_register_script()
139
- * @see wp_enqueue_script()
140
- *
141
- * @return Void
142
- */
143
- public function enqueue_admin_scripts() {
144
- //enqueue styles
145
- wp_enqueue_style( 'style-dfi', plugins_url( '/css/style-dfi.css', __FILE__ ), array(), self::VERSION );
146
- wp_enqueue_style( 'dashicons', plugins_url( '/css/dashicons.css', __FILE__ ), array(), self::VERSION );
147
-
148
- //register script
149
- wp_register_script( 'scripts-dfi', plugins_url( '/js/script-dfi.js', __FILE__ ), array( 'jquery' ), self::VERSION );
150
-
151
- //localize the script with required data
152
- wp_localize_script(
153
- 'scripts-dfi',
154
- 'WP_SPECIFIC',
155
- array(
156
- 'upload_url' => $this->__upload_url,
157
- 'metabox_title' => __( $this->_metabox_title, $this->_textDomain ),
158
- 'mediaSelector_title' => __( 'Dynamic Featured Image - Media Selector', $this->_textDomain ),
159
- 'mediaSelector_buttonText' => __( 'Set Featured Image', $this->_textDomain )
160
- )
161
- );
162
-
163
- //enqueue scripts
164
- wp_enqueue_script( 'scripts-dfi' );
165
-
166
- } // END initialize_components()
167
-
168
- /**
169
- * Add upgrade link
170
- *
171
- * @access public
172
- * @since 3.5.1
173
- * @action plugin_action_links
174
- *
175
- * @codeCoverageIgnore
176
- *
177
- * @param array $links Action links
178
- *
179
- * @return array
180
- */
181
- public function dfi_action_links( $links ) {
182
- $upgrade_link = array(
183
- '<a href="http://ankitpokhrel.com.np/blog/downloads/dynamic-featured-image-pro/" target="_blank">Upgrade to Premium</a>'
184
- );
185
-
186
- return array_merge( $links, $upgrade_link );
187
-
188
- } // END dfi_action_links()
189
-
190
- /**
191
- * Add featured meta boxes dynamically
192
- *
193
- * @since 1.0.0
194
- * @access public
195
- * @global object $post
196
- *
197
- * @see get_post_meta()
198
- * @see get_post_types()
199
- * @see add_meta_box()
200
- * @see add_filter()
201
- *
202
- * @return Void
203
- */
204
- public function initialize_featured_box() {
205
- global $post;
206
-
207
- //make metabox title dynamic
208
- $this->_metabox_title = apply_filters( 'dfi_set_metabox_title', __( "Featured Image" ) );
209
-
210
- $featuredData = get_post_meta( $post->ID, 'dfiFeatured', true );
211
- $totalFeatured = count( $featuredData );
212
-
213
- $defaultFilter = array( 'attachment', 'revision', 'nav_menu_item' );
214
- $this->_userFilter = apply_filters( 'dfi_post_type_user_filter', $this->_userFilter );
215
- $filter = array_merge( $defaultFilter, $this->_userFilter );
216
-
217
- $postTypes = get_post_types();
218
- $postTypes = array_diff( $postTypes, $filter );
219
-
220
- $postTypes = apply_filters( 'dfi_post_types', $postTypes );
221
-
222
- if ( ! empty( $featuredData ) && $totalFeatured >= 1 ) {
223
- $i = 2;
224
- foreach ( $featuredData as $featured ) {
225
- self::_dfi_add_meta_box( $postTypes, $featured, $i );
226
- $i ++;
227
- }
228
- } else {
229
- self::_dfi_add_meta_box( $postTypes );
230
- }
231
-
232
- } // END initialize_featured_box()
233
-
234
- /**
235
- * Translates more than one digit number digit by digit.
236
- *
237
- * @param Integer $number Integer to be translated
238
- *
239
- * @return String Translated number
240
- */
241
- protected function _get_number_translation( $number ) {
242
- if ( $number <= 9 ) {
243
- return __( $number, $this->_textDomain );
244
- } else {
245
- $pieces = str_split( $number, 1 );
246
- $buffer = '';
247
- foreach ( $pieces as $piece ) {
248
- $buffer .= __( $piece, $this->_textDomain );
249
- }
250
-
251
- return $buffer;
252
- }
253
- }
254
-
255
- /**
256
- * adds meta boxes
257
- *
258
- * @param Array $postTypes post types to show featured image box
259
- * @param Object $featured callback arguments
260
- * @param Integer $i index of the featured image
261
- *
262
- * @return Void
263
- */
264
- private function _dfi_add_meta_box( $postTypes, $featured = null, $i = null ) {
265
- if ( ! is_null( $i ) ) {
266
- foreach ( $postTypes as $type ) {
267
- add_meta_box(
268
- 'dfiFeaturedMetaBox-' . $i,
269
- __( $this->_metabox_title, $this->_textDomain ) . " " . self::_get_number_translation( $i ),
270
- array( $this, 'featured_meta_box' ),
271
- $type,
272
- 'side',
273
- 'low',
274
- array( $featured, $i + 1 )
275
- );
276
- add_filter( "postbox_classes_{$type}_dfiFeaturedMetaBox-" . $i, array( $this, 'add_metabox_classes' ) );
277
- }
278
-
279
- } else {
280
- foreach ( $postTypes as $type ) {
281
- add_meta_box(
282
- 'dfiFeaturedMetaBox',
283
- __( $this->_metabox_title, $this->_textDomain ) . " " . __( 2, $this->_textDomain ),
284
- array( $this, 'featured_meta_box' ),
285
- $type,
286
- 'side',
287
- 'low',
288
- array( null, null )
289
- );
290
- add_filter( "postbox_classes_{$type}_dfiFeaturedMetaBox", array( $this, 'add_metabox_classes' ) );
291
- }
292
- }
293
-
294
- }
295
-
296
- /**
297
- * Separate thumb and full image url from given URL string
298
- *
299
- * @since 3.3.1
300
- *
301
- * @param string $urlString [description]
302
- * @param string $state Thumb or full
303
- *
304
- * @return string|null
305
- */
306
- private function _separate( $urlString, $state = 'thumb' ) {
307
- $imagePiece = explode( ',', $urlString );
308
-
309
- if ( $state == 'thumb' ) {
310
- return isset( $imagePiece[0] ) ? $imagePiece[0] : null;
311
- }
312
-
313
- return isset( $imagePiece[1] ) ? $imagePiece[1] : null;
314
- }
315
-
316
- /**
317
- * Create a nonce field
318
- *
319
- * @since 3.5.0
320
- *
321
- * @see wp_nonce_field()
322
- * @see plugin_basename()
323
- *
324
- * @codeCoverageIgnore
325
- *
326
- * @param string $key Nonce key
327
- *
328
- * @return string
329
- */
330
- protected function _nonce_field( $key ) {
331
- return wp_nonce_field( plugin_basename( __FILE__ ), $key, true, false );
332
- }
333
-
334
- /**
335
- * Featured meta box as seen in the admin
336
- *
337
- * @since 1.0.0
338
- * @access public
339
- *
340
- * @param Object $post global post object
341
- * @param Array $featured array containing featured image count
342
- *
343
- * @return Void
344
- */
345
- public function featured_meta_box( $post, $featured ) {
346
- $featuredImg = $featured['args'][0];
347
- $featuredId = is_null( $featured['args'][1] ) ? 2 : -- $featured['args'][1];
348
-
349
- $featuredImgTrimmed = $featuredImgFull = $featuredImg;
350
- if ( ! is_null( $featuredImg ) ) {
351
- $featuredImgTrimmed = self::_separate( $featuredImg );
352
- $featuredImgFull = self::_separate( $featuredImg, 'full' );
353
- }
354
-
355
- try {
356
-
357
- $thumbnail = $this->get_image_thumb( $this->__upload_url . $featuredImgFull, 'medium' );
358
- if ( is_null( $thumbnail ) ) {
359
-
360
- //medium sized thumbnail image is missing
361
- throw new Exception( "Medium size image not found", 1 );
362
-
363
- }
364
-
365
- } catch ( Exception $e ) {
366
-
367
- //since medium sized thumbnail image was not found,
368
- //let's set full image url as thumbnail
369
- $thumbnail = $featuredImgFull;
370
-
371
- }
372
-
373
- //Add a nonce field
374
- echo $this->_nonce_field( 'dfi_fimageplug-' . $featuredId );
375
- echo self::_get_featured_box( $featuredImgTrimmed, $featuredImg, $featuredId, $thumbnail, $post->ID );
376
-
377
- } // END featured_meta_box()
378
-
379
- /**
380
- * Returns featured box html content
381
- * @since 3.1.0
382
- * @access private
383
- *
384
- * @param String $featuredImgTrimmed Medium sized image
385
- * @param String $featuredImg Full sized image
386
- * @param String $featuredId Attachment Id
387
- * @param String $thumbnail Thumb sized image
388
- *
389
- * @return String Html content
390
- */
391
- private function _get_featured_box( $featuredImgTrimmed, $featuredImg, $featuredId, $thumbnail, $postId ) {
392
- $hasFeaturedImage = ! empty( $featuredImgTrimmed ) ? 'hasFeaturedImage' : '';
393
- $thumbnail = ! is_null( $thumbnail ) ? $thumbnail : '';
394
- $dfiEmpty = is_null( $featuredImgTrimmed ) ? 'dfiImgEmpty' : '';
395
-
396
- return "<a href='javascript:void(0)' class='dfiFeaturedImage {$hasFeaturedImage}' title='" . __( 'Set Featured Image', $this->_textDomain ) . "' data-post-id='" . $postId . "'><span class='dashicons dashicons-camera'></span></a><br/>
397
- <img src='" . $thumbnail . "' class='dfiImg {$dfiEmpty}'/>
398
- <div class='dfiLinks'>
399
- <a href='javascript:void(0)' data-id='{$featuredId}' data-id-local='" . $this->_get_number_translation( ( $featuredId + 1 ) ) . "' class='dfiAddNew dashicons dashicons-plus' title='" . __( 'Add New', $this->_textDomain ) . "'></a>
400
- <a href='javascript:void(0)' class='dfiRemove dashicons dashicons-minus' title='" . __( 'Remove', $this->_textDomain ) . "'></a>
401
- </div>
402
- <div class='dfiClearFloat'></div>
403
- <input type='hidden' name='dfiFeatured[]' value='{$featuredImg}' class='dfiImageHolder' />";
404
- }
405
-
406
- /**
407
- * Load new featured meta box via ajax
408
- *
409
- * @since 1.0.0
410
- * @access public
411
- *
412
- * @return Void
413
- */
414
- public function ajax_callback() {
415
- $featuredId = isset( $_POST['id'] ) ? (int) strip_tags( trim( $_POST['id'] ) ) : null;
416
-
417
- if ( is_null( $featuredId ) ) {
418
- return;
419
- }
420
-
421
- echo $this->_nonce_field( 'dfi_fimageplug-' . $featuredId );
422
- ?>
423
- <a href="javascript:void(0)" class="dfiFeaturedImage"
424
- title="<?php echo __( 'Set Featured Image', $this->_textDomain ) ?>"><span
425
- class="dashicons dashicons-camera"></span></a><br/>
426
- <img src="" class="dfiImg dfiImgEmpty"/>
427
- <div class="dfiLinks">
428
- <a href="javascript:void(0)" data-id="<?php echo $featuredId ?>"
429
- data-id-local="<?php echo self::_get_number_translation( ( $featuredId + 1 ) ) ?>"
430
- class="dfiAddNew dashicons dashicons-plus" title="<?php echo __( 'Add New', $this->_textDomain ) ?>"></a>
431
- <a href="javascript:void(0)" class="dfiRemove dashicons dashicons-minus"
432
- title="<?php echo __( 'Remove', $this->_textDomain ) ?>"></a>
433
- </div>
434
- <div class="dfiClearFloat"></div>
435
- <input type="hidden" name="dfiFeatured[]" value="" class="dfiImageHolder"/>
436
- <?php
437
- wp_die( '' );
438
-
439
- } // END ajax_callback())
440
-
441
- /**
442
- * Add custom class 'featured-meta-box' to meta box
443
- *
444
- * @since 1.0.0
445
- * @access public
446
- *
447
- * @see add_metabox_classes
448
- *
449
- * @param $classes classes to add in the meta box
450
- *
451
- * @return string
452
- */
453
- public function add_metabox_classes( $classes ) {
454
- array_push( $classes, 'featured-meta-box' );
455
-
456
- return $classes;
457
-
458
- } // END add_metabox_classes()
459
-
460
- /**
461
- * Add custom fields in media uploader
462
- *
463
- * @since 3.4.0
464
- *
465
- * @param $form_fields Array Fields to include in media attachment form
466
- * @param $post Array Post data
467
- *
468
- * @return Array
469
- */
470
- public function media_attachment_custom_fields( $form_fields, $post ) {
471
- $form_fields['dfi-link-to-image'] = array(
472
- 'label' => _( 'Link to Image' ),
473
- 'input' => 'text',
474
- 'value' => get_post_meta( $post->ID, '_dfi_link_to_image', true )
475
- );
476
-
477
- return $form_fields;
478
-
479
- } // END media_attachment_custom_fields()
480
-
481
- /**
482
- * Save values of media uploader custom fields
483
- *
484
- * @since 3.4.0
485
- *
486
- * @param $post Array The post data for database
487
- * @param $attachment Array Attachment fields from $_POST form
488
- *
489
- * @return Array
490
- */
491
- public function media_attachment_custom_fields_save( $post, $attachment ) {
492
- if ( isset( $attachment['dfi-link-to-image'] ) ) {
493
- update_post_meta( $post['ID'], '_dfi_link_to_image', $attachment['dfi-link-to-image'] );
494
- }
495
-
496
- return $post;
497
-
498
- } // END media_attachment_custom_fields_save()
499
-
500
- /**
501
- * Update featured images in the database
502
- *
503
- * @since 1.0.0
504
- * @access public
505
- *
506
- * @see plugin_basename()
507
- * @see update_post_meta()
508
- * @see current_user_can()
509
- *
510
- * @param Integer $post_id current post id
511
- *
512
- * @return Void
513
- */
514
- public function save_meta( $post_id ) {
515
- //Check autosave
516
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
517
- return false;
518
- }
519
-
520
- if ( $this->_verify_nonces() ) {
521
- //Check permission before saving data
522
- if ( current_user_can( 'edit_posts', $post_id ) && isset( $_POST['dfiFeatured'] ) ) {
523
- update_post_meta( $post_id, 'dfiFeatured', $_POST['dfiFeatured'] );
524
- }
525
- }
526
-
527
- return false;
528
-
529
- } // END save_meta()
530
-
531
- /**
532
- * Verify metabox nonces
533
- *
534
- * @access protected
535
- * @see wp_verify_nonce()
536
- *
537
- * @return boolean
538
- */
539
- protected function _verify_nonces() {
540
- $keys = array_keys( $_POST );
541
- foreach ( $keys as $key ) {
542
- if ( preg_match( '/dfi_fimageplug-\d+$/', $key ) ) {
543
- //Verify nonce
544
- if ( ! wp_verify_nonce( $_POST[ $key ], plugin_basename( __FILE__ ) ) ) {
545
- return false;
546
- }
547
- }
548
- }
549
-
550
- return true;
551
-
552
- } // END _verify_nonces()
553
-
554
- /**
555
- * Add update notice. Displayed in plugin update page.
556
- *
557
- * @since 2.0.0
558
- * @access public
559
- *
560
- * @return Void
561
- */
562
- public function update_notice() {
563
- $info = __( 'ATTENTION! Please read the <a href="https://github.com/ankitpokhrel/Dynamic-Featured-Image/wiki" target="_blank">DOCUMENTATION</a> properly before update.', $this->_textDomain );
564
- echo '<div style="color:red; padding:7px 0;">' . strip_tags( $info, '<a><b><i><span>' ) . '</div>';
565
-
566
- } // END update_notice()
567
-
568
- /** Helper functions */
569
-
570
- private function execute_query( $query ) {
571
- return $this->__db->get_var( $query );
572
- }
573
-
574
- /**
575
- * Get attachment id of the image by image url
576
- *
577
- * @since 3.1.7
578
- * @access protected
579
- * @global object $wpdb
580
- *
581
- * @param String $image_url url of the image
582
- *
583
- * @return string
584
- */
585
- protected function _get_attachment_id( $image_url ) {
586
- return self::execute_query( $this->__db->prepare( "SELECT ID FROM " . $this->__db->posts . " WHERE guid = %s", $image_url ) );
587
-
588
- } // END _get_attachment_id()
589
-
590
- /**
591
- * Get image url of the image by attachment id
592
- *
593
- * @since 2.0.0
594
- * @access public
595
- *
596
- * @see wp_get_attachment_image_src()
597
- *
598
- * @param Integer $attachment_id attachment id of an image
599
- * @param String $size size of the image to fetch (thumbnail, medium, full)
600
- *
601
- * @return String
602
- */
603
- public function get_image_url( $attachment_id, $size = 'full' ) {
604
- $image_thumb = wp_get_attachment_image_src( $attachment_id, $size );
605
-
606
- return empty( $image_thumb ) ? null : $image_thumb[0];
607
-
608
- } // END get_image_url()
609
-
610
- /**
611
- * Get image thumbnail url of specific size by image url
612
- *
613
- * @since 2.0.0
614
- * @access public
615
- *
616
- * @see get_image_id()
617
- * @see wp_get_attachment_image_src()
618
- *
619
- * @param String $image_url url of an image
620
- * @param String $size size of the image to fetch (thumbnail, medium, full)
621
- *
622
- * @return String
623
- */
624
- public function get_image_thumb( $image_url, $size = 'thumbnail' ) {
625
- $attachment_id = $this->get_image_id( $image_url );
626
- $image_thumb = wp_get_attachment_image_src( $attachment_id, $size );
627
-
628
- return empty( $image_thumb ) ? null : $image_thumb[0];
629
-
630
- } // END get_image_thumb()
631
-
632
- /**
633
- * Gets attachment id from given image url
634
- *
635
- * @param String $image_url url of an image
636
- *
637
- * @return Integer|Null attachment id of an image
638
- *
639
- * @since 2.0.0
640
- * @access public
641
- */
642
- public function get_image_id( $image_url ) {
643
- $attachment_id = $this->_get_attachment_id( $image_url );
644
- if ( is_null( $attachment_id ) ) {
645
- //check if the image is edited image
646
- //and try to get the attachment id
647
- $image_url = str_replace( $this->__upload_url . "/", '', $image_url );
648
- $row = self::execute_query( $this->__db->prepare( "SELECT post_id FROM " . $this->__db->postmeta . " WHERE meta_value = %s", $image_url ) );
649
- if ( ! is_null( $row ) ) {
650
- $attachment_id = $row;
651
- }
652
- }
653
-
654
- return $attachment_id;
655
- }
656
-
657
- /**
658
- * Get image title
659
- *
660
- * @since 2.0.0
661
- * @access public
662
- *
663
- * @param String $image_url url of an image
664
- *
665
- * @return String
666
- */
667
- public function get_image_title( $image_url ) {
668
- return self::execute_query( $this->__db->prepare( "SELECT post_title FROM " . $this->__db->posts . " WHERE guid = %s", $image_url ) );
669
-
670
- } // END get_image_title()
671
-
672
- /**
673
- * Get image title by id
674
- *
675
- * @since 2.0.0
676
- * @access public
677
- *
678
- * @param Integer $attachment_id attachment id of an image
679
- *
680
- * @return String
681
- */
682
- public function get_image_title_by_id( $attachment_id ) {
683
- return self::execute_query( $this->__db->prepare( "SELECT post_title FROM " . $this->__db->posts . " WHERE ID = %d", $attachment_id ) );
684
-
685
- } // END get_image_title_by_id()
686
-
687
- /**
688
- * Get image caption
689
- *
690
- * @since 2.0.0
691
- * @access public
692
- *
693
- * @param String $image_url url of an image
694
- *
695
- * @return String
696
- */
697
- public function get_image_caption( $image_url ) {
698
- return self::execute_query( $this->__db->prepare( "SELECT post_excerpt FROM " . $this->__db->posts . " WHERE guid = %s", $image_url ) );
699
-
700
- } // END get_image_caption()
701
-
702
- /**
703
- * Get image caption by id
704
- *
705
- * @since 2.0.0
706
- * @access public
707
- *
708
- * @param Integer $attachment_id attachment id of an image
709
- *
710
- * @return String
711
- */
712
- public function get_image_caption_by_id( $attachment_id ) {
713
- return self::execute_query( $this->__db->prepare( "SELECT post_excerpt FROM " . $this->__db->posts . " WHERE ID = %d", $attachment_id ) );
714
-
715
- } // END get_image_caption_by_id()
716
-
717
- /**
718
- * Get image alternate text
719
- *
720
- * @since 2.0.0
721
- * @access public
722
- *
723
- * @see get_post_meta()
724
- *
725
- * @param String $image_url url of an image
726
- *
727
- * @return String
728
- */
729
- public function get_image_alt( $image_url ) {
730
- $attachment = $this->__db->get_col( $this->__db->prepare( "SELECT ID FROM " . $this->__db->posts . " WHERE guid = %s", $image_url ) );
731
-
732
- $alt = null;
733
- if ( ! empty( $attachment ) ) {
734
- $alt = get_post_meta( $attachment[0], '_wp_attachment_image_alt' );
735
- }
736
-
737
- return ( is_null( $alt ) || empty( $alt ) ) ? null : $alt[0];
738
-
739
- } // END get_image_alt()
740
-
741
- /**
742
- * Get image alternate text by attachment id
743
- *
744
- * @since 2.0.0
745
- * @access public
746
- *
747
- * @see get_post_meta()
748
- *
749
- * @param Integer $attachment_id attachment id of an image
750
- *
751
- * @return String
752
- */
753
- public function get_image_alt_by_id( $attachment_id ) {
754
- $alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt' );
755
-
756
- return empty( $alt ) ? null : $alt[0];
757
-
758
- } // END get_image_alt_by_id()
759
-
760
- /**
761
- * Get image description
762
- *
763
- * @since 3.0.0
764
- * @access public
765
- *
766
- * @param String $image_url url of an image
767
- *
768
- * @return String
769
- */
770
- public function get_image_description( $image_url ) {
771
- return self::execute_query( $this->__db->prepare( "SELECT post_content FROM " . $this->__db->posts . " WHERE guid = %s", $image_url ) );
772
-
773
- } // END get_image_description()
774
-
775
- /**
776
- * Get image description by id
777
- *
778
- * @since 3.0.0
779
- * @access public
780
- *
781
- * @param Integer $attachment_id attachment id of an image
782
- *
783
- * @return String
784
- */
785
- public function get_image_description_by_id( $attachment_id ) {
786
- return self::execute_query( $this->__db->prepare( "SELECT post_content FROM " . $this->__db->posts . " WHERE ID = %d", $attachment_id ) );
787
-
788
- } // END get_image_description_by_id()
789
-
790
- /**
791
- * Get link to image
792
- *
793
- * @since 3.4.0
794
- * @access public
795
- *
796
- * @param Integer $attachment_id attachment id of an image
797
- *
798
- * @return string|null
799
- */
800
- public function get_link_to_image( $attachment_id ) {
801
- return get_post_meta( $attachment_id, '_dfi_link_to_image', true );
802
-
803
- } // END get_link_to_image()
804
-
805
- /**
806
- * Get all attachment ids of the post
807
- *
808
- * @since 2.0.0
809
- * @access public
810
- *
811
- * @see get_post_meta()
812
- *
813
- * @param Integer $post_id id of the current post
814
- *
815
- * @return Array
816
- */
817
- public function get_post_attachment_ids( $post_id ) {
818
- $dfiImages = get_post_meta( $post_id, 'dfiFeatured', true );
819
-
820
- $retVal = array();
821
- if ( ! empty( $dfiImages ) && is_array( $dfiImages ) ) {
822
- foreach ( $dfiImages as $dfiImage ) {
823
- $dfiImageFull = self::_separate( $dfiImage, 'full' );
824
- $retVal[] = $this->get_image_id( $this->__upload_url . $dfiImageFull );
825
- }
826
- }
827
-
828
- return $retVal;
829
-
830
- } // END get_post_attachment_ids()
831
-
832
- /**
833
- * Fetches featured image data of nth position
834
- *
835
- * @since 3.0.0
836
- * @access public
837
- *
838
- * @see get_featured_images()
839
- *
840
- * @param Integer $position position of the featured image
841
- * @param Integer $post_id id of the current post
842
- *
843
- * @return Array if found, null otherwise
844
- */
845
- public function get_nth_featured_image( $position, $post_id = null ) {
846
- if ( is_null( $post_id ) ) {
847
- global $post;
848
- $post_id = $post->ID;
849
- }
850
-
851
- $featured_images = $this->get_featured_images( $post_id );
852
-
853
- return isset( $featured_images[ $position - 2 ] ) ? $featured_images[ $position - 2 ] : null;
854
-
855
- } // END get_nth_featured_image()
856
-
857
- /**
858
- * Check if the image is attached with the particular post
859
- *
860
- * @since 2.0.0
861
- * @access public
862
- *
863
- * @see get_post_attachment_ids()
864
- *
865
- * @param $attachment_id attachment id of an image
866
- * @param $post_id id of the current post
867
- *
868
- * @return boolean
869
- */
870
- public function is_attached( $attachment_id, $post_id ) {
871
- if ( empty( $attachment_id ) ) {
872
- return false;
873
- }
874
-
875
- $attachment_ids = $this->get_post_attachment_ids( $post_id );
876
-
877
- return in_array( $attachment_id, $attachment_ids ) ? true : false;
878
-
879
- } // END is_attached()
880
-
881
- /**
882
- * Retrieve featured images for specific post(s)
883
- *
884
- * @since 2.0.0
885
- * @access public
886
- *
887
- * @see get_post_meta()
888
- *
889
- * @param Integer $post_id id of the current post
890
- *
891
- * @return Array
892
- */
893
- public function get_featured_images( $post_id = null ) {
894
- if ( is_null( $post_id ) ) {
895
- global $post;
896
- $post_id = $post->ID;
897
- }
898
-
899
- $dfiImages = get_post_meta( $post_id, 'dfiFeatured', true );
900
-
901
- $retImages = array();
902
- if ( ! empty( $dfiImages ) && is_array( $dfiImages ) ) {
903
- $dfiImages = array_filter( $dfiImages );
904
-
905
- $count = 0;
906
- foreach ( $dfiImages as $dfiImage ) {
907
- $dfiImageTrimmed = self::_separate( $dfiImage );
908
- $dfiImageFull = self::_separate( $dfiImage, 'full' );
909
-
910
- try {
911
-
912
- $retImages[ $count ]['thumb'] = $this->_get_real_upload_path( $dfiImageTrimmed );
913
- $retImages[ $count ]['full'] = $this->_get_real_upload_path( $dfiImageFull );
914
- $retImages[ $count ]['attachment_id'] = $this->get_image_id( $retImages[ $count ]['full'] );
915
-
916
- } catch ( Exception $e ) { /* Ignore the exception and continue with other featured images */
917
- }
918
-
919
- $count ++;
920
- }
921
- }
922
-
923
- return $retImages;
924
-
925
- } // END get_featured_images()
926
-
927
- /**
928
- * Check to see if the upload url is already available in path.
929
- *
930
- * @since 3.1.14
931
- * @access protected
932
- *
933
- * @param string $img
934
- *
935
- * @return string
936
- */
937
- protected function _get_real_upload_path( $img ) {
938
- //check if upload path is already attached
939
- if ( strpos( $img, $this->__upload_url ) !== false || preg_match('/https?:\/\//', $img) ) {
940
- return $img;
941
- }
942
-
943
- return $this->__upload_url . $img;
944
- } // END _get_real_upload_path()
945
-
946
- /**
947
- * Retrieve featured images for specific post(s) including the default Featured Image
948
- *
949
- * @since 3.1.7
950
- * @access public
951
- *
952
- * @see $this->get_featured_images()
953
- *
954
- * @param Integer $post_id id of the current post
955
- *
956
- * @return Array An array of images or an empty array on failure
957
- */
958
- public function get_all_featured_images( $post_id = null ) {
959
- if ( is_null( $post_id ) ) {
960
- global $post;
961
- $post_id = $post->ID;
962
- }
963
-
964
- $thumbnail_id = get_post_thumbnail_id( $post_id );
965
-
966
- $featured_image_array = array();
967
- if ( ! empty( $thumbnail_id ) ) {
968
- $featured_image = array(
969
- 'thumb' => wp_get_attachment_thumb_url( $thumbnail_id ),
970
- 'full' => wp_get_attachment_url( $thumbnail_id ),
971
- 'attachment_id' => $thumbnail_id
972
- );
973
- $featured_image_array[] = $featured_image;
974
- }
975
-
976
- $dfiImages = $this->get_featured_images( $post_id );
977
-
978
- $all_featured_images = array_merge( $featured_image_array, $dfiImages );
979
-
980
- return $all_featured_images;
981
-
982
- }
983
-
984
- /**
985
- * Load the plugin's textdomain hooked to 'plugins_loaded'.
986
- *
987
- * @since 1.0.0
988
- * @access public
989
- *
990
- * @see load_plugin_textdomain()
991
- * @see plugin_basename()
992
- * @action plugins_loaded
993
- *
994
- * @codeCoverageIgnore
995
- *
996
- * @return void
997
- */
998
- public function load_plugin_textdomain() {
999
- load_plugin_textdomain(
1000
- $this->_textDomain,
1001
- false,
1002
- dirname( plugin_basename( __FILE__ ) ) . '/languages/'
1003
- );
1004
-
1005
- } // END load_plugin_textdomain()
1006
-
1007
- } // END class Dynamic_Featured_Image
1008
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1009
 
1010
  /**
1011
- * Instantiate the main class
1012
  *
1013
  * @since 1.0.0
1014
  * @access public
1015
  *
1016
- * @var object $dynamic_featured_image holds the instantiated class {@uses Dynamic_Featured_Image}
1017
  */
1018
  global $dynamic_featured_image;
1019
  $dynamic_featured_image = new Dynamic_Featured_Image();
1
  <?php
2
+ /**
3
  * Plugin Name: Dynamic Featured Image
4
  * Plugin URI: http://wordpress.org/plugins/dynamic-featured-image/
5
  * Description: Dynamically adds multiple featured image or post thumbnail functionality to your posts, pages and custom post types.
6
+ * Version: 3.6.0
7
  * Author: Ankit Pokhrel
8
+ * Author URI: https://ankitpokhrel.com
9
  * License: GPL2 or later
10
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
  * Text Domain: dynamic-featured-image
12
  * Domain Path: /languages
13
  * GitHub Plugin URI: https://github.com/ankitpokhrel/Dynamic-Featured-Image
14
  *
15
+ * @package dynamic-featured-image
16
+ *
17
+ * Copyright (C) 2013 Ankit Pokhrel <info@ankitpokhrel.com, https://ankitpokhrel.com>
18
  *
19
  * This program is free software; you can redistribute it and/or modify
20
  * it under the terms of the GNU General Public License as published by
30
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31
  */
32
 
33
+ // Avoid direct calls to this file.
34
  if ( ! defined( 'ABSPATH' ) ) {
35
+ header( 'Status: 403 Forbidden' );
36
+ header( 'HTTP/1.1 403 Forbidden' );
37
+ exit();
38
  }
39
 
40
  /**
41
+ * Dynamic Featured Image plugin main class.
42
  *
43
+ * @author Ankit Pokhrel <info@ankitpokhrel.com>
 
44
  * @version 3.0.1
45
  */
46
  class Dynamic_Featured_Image {
47
+ /**
48
+ * Current version of the plugin.
49
+ *
50
+ * @since 3.0.0
51
+ */
52
+ const VERSION = '3.6.0';
53
+
54
+ /**
55
+ * Text domain.
56
+ *
57
+ * @since 3.6.0
58
+ */
59
+ const TEXT_DOMAIN = 'dynamic-featured-image';
60
+
61
+ /**
62
+ * Documentation Link.
63
+ *
64
+ * @since 3.6.0
65
+ */
66
+ const WIKI_LINK = 'https://github.com/ankitpokhrel/Dynamic-Featured-Image/wiki/';
67
+
68
+ /**
69
+ * Upgrade Link.
70
+ *
71
+ * @since 3.6.0
72
+ */
73
+ const UPGRADE_LINK = 'https://ankitpokhrel.com/explore/dynamic-featured-image-pro/';
74
+
75
+ /**
76
+ * Image upload directory.
77
+ *
78
+ * @var $upload_dir string
79
+ */
80
+ private $upload_dir;
81
+
82
+ /**
83
+ * Image upload URL.
84
+ *
85
+ * @var $upload_url string
86
+ */
87
+ private $upload_url;
88
+
89
+ /**
90
+ * Database object.
91
+ *
92
+ * @var $db wpdb
93
+ */
94
+ private $db;
95
+
96
+ /**
97
+ * Title for dfi metabox.
98
+ *
99
+ * @var $metabox_title string
100
+ */
101
+ protected $metabox_title;
102
+
103
+ /**
104
+ * Users post type filter for dfi metabox.
105
+ *
106
+ * @var $user_filter array
107
+ */
108
+ protected $user_filter;
109
+
110
+ /**
111
+ * Constructor. Hooks all interactions to initialize the class.
112
+ *
113
+ * @since 1.0.0
114
+ * @access public
115
+ * @global object $wpdb
116
+ *
117
+ * @see add_action()
118
+ */
119
+ public function __construct() {
120
+ // plugin update warning.
121
+ add_action( 'in_plugin_update_message-' . plugin_basename( __FILE__ ), array( $this, 'update_notice' ) );
122
+
123
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
124
+ add_action( 'add_meta_boxes', array( $this, 'initialize_featured_box' ) );
125
+ add_action( 'save_post', array( $this, 'save_meta' ) );
126
+ add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
127
+
128
+ // handle ajax request.
129
+ add_action( 'wp_ajax_dfiMetaBox_callback', array( $this, 'ajax_callback' ) );
130
+
131
+ // add action links.
132
+ add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'dfi_action_links' ) );
133
+
134
+ // media uploader custom fields.
135
+ add_filter( 'attachment_fields_to_edit', array( $this, 'media_attachment_custom_fields' ), 10, 2 );
136
+ add_filter( 'attachment_fields_to_save', array( $this, 'media_attachment_custom_fields_save' ), 10, 2 );
137
+
138
+ // get the site protocol.
139
+ $protocol = $this->get_protocol();
140
+
141
+ $this->upload_dir = wp_upload_dir();
142
+ $this->upload_url = preg_replace( '#^https?://#', '', $this->upload_dir['baseurl'] );
143
+
144
+ // add protocol to the upload url.
145
+ $this->upload_url = $protocol . $this->upload_url;
146
+
147
+ // post type filter added by user.
148
+ $this->user_filter = array();
149
+
150
+ global $wpdb;
151
+ $this->db = $wpdb;
152
+ }
153
+
154
+ /**
155
+ * Return site protocol.
156
+ *
157
+ * @since 3.5.1
158
+ * @access public
159
+ *
160
+ * @return string
161
+ */
162
+ private function get_protocol() {
163
+ return is_ssl() ? 'https://' : 'http://';
164
+ }
165
+
166
+ /**
167
+ * Add required admin scripts.
168
+ *
169
+ * @since 1.0.0
170
+ * @access public
171
+ *
172
+ * @see wp_enque_style()
173
+ * @see wp_register_script()
174
+ * @see wp_enqueue_script()
175
+ *
176
+ * @return void
177
+ */
178
+ public function enqueue_admin_scripts() {
179
+ // enqueue styles.
180
+ wp_enqueue_style( 'style-dfi', plugins_url( '/css/style-dfi.css', __FILE__ ), array(), self::VERSION );
181
+
182
+ // register script.
183
+ wp_register_script( 'scripts-dfi', plugins_url( '/js/script-dfi.js', __FILE__ ), array( 'jquery' ), self::VERSION );
184
+
185
+ // localize the script with required data.
186
+ wp_localize_script(
187
+ 'scripts-dfi',
188
+ 'DFI_SPECIFIC',
189
+ array(
190
+ 'upload_url' => $this->upload_url,
191
+ 'metabox_title' => __( $this->metabox_title, self::TEXT_DOMAIN ),
192
+ 'mediaSelector_title' => __( 'Dynamic Featured Image - Media Selector', self::TEXT_DOMAIN ),
193
+ 'mediaSelector_buttonText' => __( 'Set Featured Image', self::TEXT_DOMAIN ),
194
+ 'ajax_nonce' => wp_create_nonce( plugin_basename( __FILE__ ) ),
195
+ )
196
+ );
197
+
198
+ // enqueue scripts.
199
+ wp_enqueue_script( 'scripts-dfi' );
200
+ }
201
+
202
+ /**
203
+ * Add upgrade link.
204
+ *
205
+ * @access public
206
+ * @since 3.5.1
207
+ * @action plugin_action_links
208
+ *
209
+ * @codeCoverageIgnore
210
+ *
211
+ * @param array $links Action links.
212
+ *
213
+ * @return array
214
+ */
215
+ public function dfi_action_links( $links ) {
216
+ $upgrade_link = array(
217
+ '<a href="' . self::UPGRADE_LINK . '" target="_blank">Upgrade to Premium</a>'
218
+ );
219
+
220
+ return array_merge( $links, $upgrade_link );
221
+ }
222
+
223
+ /**
224
+ * Add featured meta boxes dynamically.
225
+ *
226
+ * @since 1.0.0
227
+ * @access public
228
+ * @global object $post
229
+ *
230
+ * @see get_post_meta()
231
+ * @see get_post_types()
232
+ * @see add_meta_box()
233
+ * @see add_filter()
234
+ *
235
+ * @return void
236
+ */
237
+ public function initialize_featured_box() {
238
+ global $post;
239
+
240
+ // make metabox title dynamic.
241
+ $this->metabox_title = apply_filters( 'dfi_set_metabox_title', __( 'Featured Image', self::TEXT_DOMAIN ) );
242
+
243
+ $featured_data = get_post_meta( $post->ID, 'dfiFeatured', true );
244
+ $total_featured = count( $featured_data );
245
+
246
+ $default_filter = array( 'attachment', 'revision', 'nav_menu_item' );
247
+ $this->user_filter = apply_filters( 'dfi_post_type_user_filter', $this->user_filter );
248
+
249
+ $post_types = array_diff( get_post_types(), array_merge( $default_filter, $this->user_filter ) );
250
+ $post_types = apply_filters( 'dfi_post_types', $post_types );
251
+
252
+ if ( ! empty( $featured_data ) && $total_featured >= 1 ) {
253
+ $i = 2;
254
+ foreach ( $featured_data as $featured ) {
255
+ $this->dfi_add_meta_box( $post_types, $featured, $i++ );
256
+ }
257
+ } else {
258
+ $this->dfi_add_meta_box( $post_types );
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Translates more than one digit number digit by digit.
264
+ *
265
+ * @param int $number Integer to be translated.
266
+ *
267
+ * @return string Translated number
268
+ */
269
+ protected function get_number_translation( $number ) {
270
+ if ( $number <= 9 ) {
271
+ return __( $number, self::TEXT_DOMAIN );
272
+ } else {
273
+ $pieces = str_split( $number, 1 );
274
+ $buffer = '';
275
+ foreach ( $pieces as $piece ) {
276
+ $buffer .= __( $piece, self::TEXT_DOMAIN );
277
+ }
278
+
279
+ return $buffer;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Adds meta boxes.
285
+ *
286
+ * @param array $post_types Post types to show featured image box.
287
+ * @param object $featured Callback arguments.
288
+ * @param int $i Index of the featured image.
289
+ *
290
+ * @return void
291
+ */
292
+ private function dfi_add_meta_box( $post_types, $featured = null, $i = null ) {
293
+ if ( ! is_null( $i ) ) {
294
+ foreach ( $post_types as $type ) {
295
+ add_meta_box(
296
+ 'dfiFeaturedMetaBox-' . $i,
297
+ __( $this->metabox_title, self::TEXT_DOMAIN ) . ' ' . $this->get_number_translation( $i ),
298
+ array( $this, 'featured_meta_box' ),
299
+ $type,
300
+ 'side',
301
+ 'low',
302
+ array( $featured, $i + 1 )
303
+ );
304
+
305
+ add_filter( "postbox_classes_{$type}_dfiFeaturedMetaBox-" . $i, array( $this, 'add_metabox_classes' ) );
306
+ }
307
+ } else {
308
+ foreach ( $post_types as $type ) {
309
+ add_meta_box(
310
+ 'dfiFeaturedMetaBox',
311
+ __( $this->metabox_title, self::TEXT_DOMAIN ) . ' ' . __( 2, self::TEXT_DOMAIN ),
312
+ array( $this, 'featured_meta_box' ),
313
+ $type,
314
+ 'side',
315
+ 'low',
316
+ array( null, null )
317
+ );
318
+
319
+ add_filter( "postbox_classes_{$type}_dfiFeaturedMetaBox", array( $this, 'add_metabox_classes' ) );
320
+ }
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Separate thumb and full image url from given URL string.
326
+ *
327
+ * @since 3.3.1
328
+ *
329
+ * @param string $url_string Url string.
330
+ * @param string $state Thumb or full.
331
+ *
332
+ * @return string|null
333
+ */
334
+ private function separate( $url_string, $state = 'thumb' ) {
335
+ $image_piece = explode( ',', $url_string );
336
+
337
+ if ( 'thumb' === $state ) {
338
+ return isset( $image_piece[0] ) ? $image_piece[0] : null;
339
+ }
340
+
341
+ return isset( $image_piece[1] ) ? $image_piece[1] : null;
342
+ }
343
+
344
+ /**
345
+ * Create a nonce field.
346
+ *
347
+ * @since 3.5.0
348
+ *
349
+ * @see wp_nonce_field()
350
+ * @see plugin_basename()
351
+ *
352
+ * @codeCoverageIgnore
353
+ *
354
+ * @param string $key Nonce key.
355
+ *
356
+ * @return string
357
+ */
358
+ protected function nonce_field( $key ) {
359
+ return wp_nonce_field( plugin_basename( __FILE__ ), $key, true, false );
360
+ }
361
+
362
+ /**
363
+ * Featured meta box as seen in the admin.
364
+ *
365
+ * @since 1.0.0
366
+ * @access public
367
+ *
368
+ * @param object $post Global post object.
369
+ * @param array $featured Array containing featured image count.
370
+ *
371
+ * @throws Exception Medium size image not found.
372
+ * @return void
373
+ */
374
+ public function featured_meta_box( $post, $featured ) {
375
+ $featured_img = $featured['args'][0];
376
+ $featured_id = is_null( $featured['args'][1] ) ? 2 : --$featured['args'][1];
377
+ $featured_img_full = $featured_img;
378
+ $featured_img_trimmed = $featured_img;
379
+
380
+ if ( ! is_null( $featured_img ) ) {
381
+ $featured_img_trimmed = $this->separate( $featured_img );
382
+ $featured_img_full = $this->separate( $featured_img, 'full' );
383
+ }
384
+
385
+ $thumbnail = $this->get_image_thumb( $this->upload_url . $featured_img_full, 'medium' );
386
+ if ( empty( $thumbnail ) ) {
387
+ // since medium sized thumbnail image is missing,
388
+ // let's set full image url as thumbnail.
389
+ $thumbnail = $featured_img_full;
390
+ }
391
+
392
+ // Add a nonce field.
393
+ echo $this->nonce_field( 'dfi_fimageplug-' . $featured_id ); // WPCS: XSS ok.
394
+ echo $this->get_featured_box( $featured_img_trimmed, $featured_img, $featured_id, $thumbnail, $post->ID ); // WPCS: XSS ok.
395
+ }
396
+
397
+ /**
398
+ * Returns featured box html content.
399
+ *
400
+ * @since 3.1.0
401
+ * @access private
402
+ *
403
+ * @param string $featured_img_trimmed Medium sized image.
404
+ * @param string $featured_img Full sized image.
405
+ * @param string $featured_id Attachment Id.
406
+ * @param string $thumbnail Thumb sized image.
407
+ * @param int $post_id Post id.
408
+ *
409
+ * @return string Html content
410
+ */
411
+ private function get_featured_box( $featured_img_trimmed, $featured_img, $featured_id, $thumbnail, $post_id ) {
412
+ $has_featured_image = ! empty( $featured_img_trimmed ) ? 'hasFeaturedImage' : '';
413
+ $thumbnail = ! is_null( $thumbnail ) ? $thumbnail : '';
414
+ $dfi_empty = is_null( $featured_img_trimmed ) ? 'dfiImgEmpty' : '';
415
+
416
+ return "<a href='javascript:void(0)' class='dfiFeaturedImage {$has_featured_image}' title='" . __( 'Set Featured Image', self::TEXT_DOMAIN ) . "' data-post-id='" . $post_id . "'><span class='dashicons dashicons-camera'></span></a><br/>
417
+ <img src='" . $thumbnail . "' class='dfiImg {$dfi_empty}'/>
418
+ <div class='dfiLinks'>
419
+ <a href='javascript:void(0)' data-id='{$featured_id}' data-id-local='" . $this->get_number_translation( $featured_id + 1 ) . "' class='dfiAddNew dashicons dashicons-plus' title='" . __( 'Add New', self::TEXT_DOMAIN ) . "'></a>
420
+ <a href='javascript:void(0)' class='dfiRemove dashicons dashicons-minus' title='" . __( 'Remove', self::TEXT_DOMAIN ) . "'></a>
421
+ </div>
422
+ <div class='dfiClearFloat'></div>
423
+ <input type='hidden' name='dfiFeatured[]' value='{$featured_img}' class='dfiImageHolder' />";
424
+ }
425
+
426
+ /**
427
+ * Load new featured meta box via ajax.
428
+ *
429
+ * @since 1.0.0
430
+ * @access public
431
+ *
432
+ * @return void
433
+ */
434
+ public function ajax_callback() {
435
+ check_ajax_referer( plugin_basename( __FILE__ ), 'security' );
436
+
437
+ $featured_id = isset( $_POST['id'] ) ? intval( wp_unslash( $_POST['id'] ) ) : null;
438
+
439
+ if ( ! is_numeric( $featured_id ) ) {
440
+ return;
441
+ }
442
+
443
+ // @codingStandardsIgnoreStart
444
+ echo $this->nonce_field( 'dfi_fimageplug-' . $featured_id );
445
+ ?>
446
+ <a href="javascript:void(0)" class="dfiFeaturedImage"
447
+ title="<?php echo __( 'Set Featured Image', self::TEXT_DOMAIN ) ?>"><span
448
+ class="dashicons dashicons-camera"></span></a><br/>
449
+ <img src="" class="dfiImg dfiImgEmpty"/>
450
+ <div class="dfiLinks">
451
+ <a href="javascript:void(0)" data-id="<?php echo $featured_id ?>"
452
+ data-id-local="<?php echo $this->get_number_translation( $featured_id + 1 ) ?>"
453
+ class="dfiAddNew dashicons dashicons-plus" title="<?php echo __( 'Add New', self::TEXT_DOMAIN ) ?>"></a>
454
+ <a href="javascript:void(0)" class="dfiRemove dashicons dashicons-minus"
455
+ title="<?php echo __( 'Remove', self::TEXT_DOMAIN ) ?>"></a>
456
+ </div>
457
+ <div class="dfiClearFloat"></div>
458
+ <input type="hidden" name="dfiFeatured[]" value="" class="dfiImageHolder"/>
459
+ <?php
460
+ // @codingStandardsIgnoreEnd
461
+ wp_die( '' );
462
+ }
463
+
464
+ /**
465
+ * Add custom class 'featured-meta-box' to meta box.
466
+ *
467
+ * @since 1.0.0
468
+ * @access public
469
+ *
470
+ * @see add_metabox_classes
471
+ *
472
+ * @param array $classes Classes to add in the meta box.
473
+ *
474
+ * @return array
475
+ */
476
+ public function add_metabox_classes( $classes ) {
477
+ array_push( $classes, 'featured-meta-box' );
478
+
479
+ return $classes;
480
+ }
481
+
482
+ /**
483
+ * Add custom fields in media uploader.
484
+ *
485
+ * @since 3.4.0
486
+ *
487
+ * @param array $form_fields Fields to include in media attachment form.
488
+ * @param array $post Post data.
489
+ *
490
+ * @return array
491
+ */
492
+ public function media_attachment_custom_fields( $form_fields, $post ) {
493
+ $form_fields['dfi-link-to-image'] = array(
494
+ 'label' => __( 'Link to Image', self::TEXT_DOMAIN ),
495
+ 'input' => 'text',
496
+ 'value' => get_post_meta( $post->ID, '_dfi_link_to_image', true ),
497
+ );
498
+
499
+ return $form_fields;
500
+ }
501
+
502
+ /**
503
+ * Save values of media uploader custom fields.
504
+ *
505
+ * @since 3.4.0
506
+ *
507
+ * @param array $post Post data for database.
508
+ * @param array $attachment Attachment fields from $_POST form.
509
+ *
510
+ * @return array
511
+ */
512
+ public function media_attachment_custom_fields_save( $post, $attachment ) {
513
+ if ( isset( $attachment['dfi-link-to-image'] ) ) {
514
+ update_post_meta( $post['ID'], '_dfi_link_to_image', $attachment['dfi-link-to-image'] );
515
+ }
516
+
517
+ return $post;
518
+ }
519
+
520
+ /**
521
+ * Update featured images in the database.
522
+ *
523
+ * @since 1.0.0
524
+ * @access public
525
+ *
526
+ * @see plugin_basename()
527
+ * @see update_post_meta()
528
+ * @see current_user_can()
529
+ *
530
+ * @param int $post_id Current post id.
531
+ *
532
+ * @return bool|null
533
+ */
534
+ public function save_meta( $post_id ) {
535
+ // Check auto save.
536
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
537
+ return false;
538
+ }
539
+
540
+ if ( ! $this->verify_nonces() ) {
541
+ return false;
542
+ }
543
+
544
+ // Check permission before saving data.
545
+ if ( current_user_can( 'edit_posts', $post_id ) && isset( $_POST['dfiFeatured'] ) ) { // WPCS: CSRF ok.
546
+ $featured_images = is_array( $_POST['dfiFeatured'] ) ? $_POST['dfiFeatured'] : []; // WPCS: sanitization ok, CSRF ok.
547
+
548
+ update_post_meta( $post_id, 'dfiFeatured', $this->sanitize_array( $featured_images ) );
549
+ }
550
+ }
551
+
552
+ /**
553
+ * Sanitize array.
554
+ *
555
+ * @since 3.6.0
556
+ * @access protected
557
+ *
558
+ * @param array $input_array Input array.
559
+ *
560
+ * @return array
561
+ */
562
+ protected function sanitize_array( $input_array ) {
563
+ $sanitized = [];
564
+
565
+ foreach ( $input_array as $value ) {
566
+ $sanitized[] = sanitize_text_field( wp_unslash( $value ) );
567
+ }
568
+
569
+ return $sanitized;
570
+ }
571
+
572
+ /**
573
+ * Verify metabox nonces.
574
+ *
575
+ * @access protected
576
+ * @see wp_verify_nonce()
577
+ *
578
+ * @return bool
579
+ */
580
+ protected function verify_nonces() {
581
+ $keys = preg_grep( '/dfi_fimageplug-\d+$/', array_keys( $_POST ) ); // WPCS: CSRF ok.
582
+
583
+ if ( empty( $keys ) ) {
584
+ return false;
585
+ }
586
+
587
+ foreach ( $keys as $key ) {
588
+ // Verify nonce.
589
+ if ( ! isset( $_POST[ $key ] ) ||
590
+ ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[ $key ] ) ), plugin_basename( __FILE__ ) )
591
+ ) {
592
+ return false;
593
+ }
594
+ }
595
+
596
+ return true;
597
+ }
598
+
599
+ /**
600
+ * Add update notice. Displayed in plugin update page.
601
+ *
602
+ * @since 2.0.0
603
+ * @access public
604
+ *
605
+ * @return void
606
+ */
607
+ public function update_notice() {
608
+ $info = __( 'ATTENTION! Please read the <a href="' . self::WIKI_LINK . '" target="_blank">DOCUMENTATION</a> properly before update.',
609
+ self::TEXT_DOMAIN );
610
+
611
+ echo '<span style="color: red; padding: 7px 0; display: block">' . strip_tags( $info, '<a><b><i><span>' ) . '</span>'; // WPCS: XSS ok.
612
+ }
613
+
614
+ /**
615
+ * Execute query.
616
+ *
617
+ * @param string $query Query to execute.
618
+ *
619
+ * @return null|string
620
+ */
621
+ private function execute_query( $query ) {
622
+ return $this->db->get_var( $query );
623
+ }
624
+
625
+ /**
626
+ * Get attachment id of the image by image url.
627
+ *
628
+ * @since 3.1.7
629
+ * @access protected
630
+ * @global object $wpdb
631
+ *
632
+ * @param string $image_url URL of an image.
633
+ *
634
+ * @return string
635
+ */
636
+ protected function get_attachment_id( $image_url ) {
637
+ return $this->execute_query( $this->db->prepare( 'SELECT ID FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
638
+ }
639
+
640
+ /**
641
+ * Get image url of the image by attachment id.
642
+ *
643
+ * @since 2.0.0
644
+ * @access public
645
+ *
646
+ * @see wp_get_attachment_image_src()
647
+ *
648
+ * @param int $attachment_id attachment id of an image.
649
+ * @param string $size size of the image to fetch (thumbnail, medium, full).
650
+ *
651
+ * @return string
652
+ */
653
+ public function get_image_url( $attachment_id, $size = 'full' ) {
654
+ $image_thumb = wp_get_attachment_image_src( $attachment_id, $size );
655
+
656
+ return empty( $image_thumb ) ? null : $image_thumb[0];
657
+ }
658
+
659
+ /**
660
+ * Get image thumbnail url of specific size by image url.
661
+ *
662
+ * @since 2.0.0
663
+ * @access public
664
+ *
665
+ * @see get_image_id()
666
+ * @see wp_get_attachment_image_src()
667
+ *
668
+ * @param string $image_url url of an image.
669
+ * @param string $size size of the image to fetch (thumbnail, medium, full).
670
+ *
671
+ * @return string
672
+ */
673
+ public function get_image_thumb( $image_url, $size = 'thumbnail' ) {
674
+ $attachment_id = $this->get_image_id( $image_url );
675
+ $image_thumb = wp_get_attachment_image_src( $attachment_id, $size );
676
+
677
+ return empty( $image_thumb ) ? null : $image_thumb[0];
678
+ }
679
+
680
+ /**
681
+ * Gets attachment id from given image url.
682
+ *
683
+ * @param string $image_url url of an image.
684
+ *
685
+ * @since 2.0.0
686
+ * @access public
687
+ *
688
+ * @return int|null attachment id of an image
689
+ */
690
+ public function get_image_id( $image_url ) {
691
+ $attachment_id = $this->get_attachment_id( $image_url );
692
+
693
+ if ( is_null( $attachment_id ) ) {
694
+ // check if the image is edited image.
695
+ // and try to get the attachment id.
696
+ $image_url = str_replace( $this->upload_url . '/', '', $image_url );
697
+ $row = $this->execute_query( $this->db->prepare( 'SELECT post_id FROM ' . $this->db->postmeta . ' WHERE meta_value = %s', $image_url ) );
698
+ if ( ! is_null( $row ) ) {
699
+ $attachment_id = $row;
700
+ }
701
+ }
702
+
703
+ return $attachment_id;
704
+ }
705
+
706
+ /**
707
+ * Get image title.
708
+ *
709
+ * @since 2.0.0
710
+ * @access public
711
+ *
712
+ * @param string $image_url URL of an image.
713
+ *
714
+ * @return string
715
+ */
716
+ public function get_image_title( $image_url ) {
717
+ return $this->execute_query( $this->db->prepare( 'SELECT post_title FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
718
+ }
719
+
720
+ /**
721
+ * Get image title by id.
722
+ *
723
+ * @since 2.0.0
724
+ * @access public
725
+ *
726
+ * @param int $attachment_id Attachment id of an image.
727
+ *
728
+ * @return string
729
+ */
730
+ public function get_image_title_by_id( $attachment_id ) {
731
+ return $this->execute_query( $this->db->prepare( 'SELECT post_title FROM ' . $this->db->posts . ' WHERE ID = %d', $attachment_id ) );
732
+ }
733
+
734
+ /**
735
+ * Get image caption.
736
+ *
737
+ * @since 2.0.0
738
+ * @access public
739
+ *
740
+ * @param string $image_url URL of an image.
741
+ *
742
+ * @return string
743
+ */
744
+ public function get_image_caption( $image_url ) {
745
+ return $this->execute_query( $this->db->prepare( 'SELECT post_excerpt FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
746
+ }
747
+
748
+ /**
749
+ * Get image caption by id.
750
+ *
751
+ * @since 2.0.0
752
+ * @access public
753
+ *
754
+ * @param int $attachment_id Attachment id of an image.
755
+ *
756
+ * @return string
757
+ */
758
+ public function get_image_caption_by_id( $attachment_id ) {
759
+ return $this->execute_query( $this->db->prepare( 'SELECT post_excerpt FROM ' . $this->db->posts . ' WHERE ID = %d', $attachment_id ) );
760
+ }
761
+
762
+ /**
763
+ * Get image alternate text.
764
+ *
765
+ * @since 2.0.0
766
+ * @access public
767
+ *
768
+ * @see get_post_meta()
769
+ *
770
+ * @param string $image_url URL of an image.
771
+ *
772
+ * @return string
773
+ */
774
+ public function get_image_alt( $image_url ) {
775
+ $attachment = $this->db->get_col( $this->db->prepare( 'SELECT ID FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
776
+
777
+ $alt = null;
778
+ if ( ! empty( $attachment ) ) {
779
+ $alt = get_post_meta( $attachment[0], '_wp_attachment_image_alt' );
780
+ }
781
+
782
+ return ( is_null( $alt ) || empty( $alt ) ) ? null : $alt[0];
783
+ }
784
+
785
+ /**
786
+ * Get image alternate text by attachment id.
787
+ *
788
+ * @since 2.0.0
789
+ * @access public
790
+ *
791
+ * @see get_post_meta()
792
+ *
793
+ * @param int $attachment_id Attachment id of an image.
794
+ *
795
+ * @return string
796
+ */
797
+ public function get_image_alt_by_id( $attachment_id ) {
798
+ $alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt' );
799
+
800
+ return empty( $alt ) ? null : $alt[0];
801
+ }
802
+
803
+ /**
804
+ * Get image description.
805
+ *
806
+ * @since 3.0.0
807
+ * @access public
808
+ *
809
+ * @param string $image_url URL of an image.
810
+ *
811
+ * @return string
812
+ */
813
+ public function get_image_description( $image_url ) {
814
+ return $this->execute_query( $this->db->prepare( 'SELECT post_content FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
815
+ }
816
+
817
+ /**
818
+ * Get image description by id.
819
+ *
820
+ * @since 3.0.0
821
+ * @access public
822
+ *
823
+ * @param int $attachment_id attachment id of an image.
824
+ *
825
+ * @return string
826
+ */
827
+ public function get_image_description_by_id( $attachment_id ) {
828
+ return $this->execute_query( $this->db->prepare( 'SELECT post_content FROM ' . $this->db->posts . ' WHERE ID = %d', $attachment_id ) );
829
+ }
830
+
831
+ /**
832
+ * Get link to image.
833
+ *
834
+ * @since 3.4.0
835
+ * @access public
836
+ *
837
+ * @param int $attachment_id Attachment id of an image.
838
+ *
839
+ * @return string|null
840
+ */
841
+ public function get_link_to_image( $attachment_id ) {
842
+ return get_post_meta( $attachment_id, '_dfi_link_to_image', true );
843
+ }
844
+
845
+ /**
846
+ * Get all attachment ids of the post.
847
+ *
848
+ * @since 2.0.0
849
+ * @access public
850
+ *
851
+ * @see get_post_meta()
852
+ *
853
+ * @param int $post_id id of the current post.
854
+ *
855
+ * @return array
856
+ */
857
+ public function get_post_attachment_ids( $post_id ) {
858
+ $dfi_images = get_post_meta( $post_id, 'dfiFeatured', true );
859
+ $ret_val = array();
860
+
861
+ if ( ! empty( $dfi_images ) && is_array( $dfi_images ) ) {
862
+ foreach ( $dfi_images as $dfi_image ) {
863
+ $dfi_image_full = $this->separate( $dfi_image, 'full' );
864
+ $ret_val[] = (int) $this->get_image_id( $this->upload_url . $dfi_image_full );
865
+ }
866
+ }
867
+
868
+ return $ret_val;
869
+ }
870
+
871
+ /**
872
+ * Get real post id.
873
+ *
874
+ * @since 3.6.0
875
+ * @access protected
876
+ *
877
+ * @param int|null $post_id Post id.
878
+ *
879
+ * @return int|null
880
+ */
881
+ protected function get_real_post_id( $post_id = null ) {
882
+ if ( ! is_null( $post_id ) && is_numeric( $post_id ) ) {
883
+ return $post_id;
884
+ }
885
+
886
+ global $post;
887
+
888
+ return $post->ID;
889
+ }
890
+
891
+ /**
892
+ * Fetches featured image data of nth position.
893
+ *
894
+ * @since 3.0.0
895
+ * @access public
896
+ *
897
+ * @see get_featured_images()
898
+ *
899
+ * @param int $position Position of the featured image.
900
+ * @param int $post_id Current post id.
901
+ *
902
+ * @return array if found, null otherwise.
903
+ */
904
+ public function get_nth_featured_image( $position, $post_id = null ) {
905
+ $post_id = $this->get_real_post_id( ( $post_id ) );
906
+
907
+ $featured_images = $this->get_featured_images( $post_id );
908
+
909
+ return isset( $featured_images[ $position - 2 ] ) ? $featured_images[ $position - 2 ] : null;
910
+ }
911
+
912
+ /**
913
+ * Check if the image is attached with the particular post.
914
+ *
915
+ * @since 2.0.0
916
+ * @access public
917
+ *
918
+ * @see get_post_attachment_ids()
919
+ *
920
+ * @param int $attachment_id Attachment id of an image.
921
+ * @param int $post_id Current post id.
922
+ *
923
+ * @return bool
924
+ */
925
+ public function is_attached( $attachment_id, $post_id ) {
926
+ if ( empty( $attachment_id ) ) {
927
+ return false;
928
+ }
929
+
930
+ $attachment_ids = $this->get_post_attachment_ids( $post_id );
931
+
932
+ return in_array( $attachment_id, $attachment_ids, true ) ? true : false;
933
+ }
934
+
935
+ /**
936
+ * Retrieve featured images for specific post(s).
937
+ *
938
+ * @since 2.0.0
939
+ * @access public
940
+ *
941
+ * @see get_post_meta()
942
+ *
943
+ * @param int $post_id id of the current post.
944
+ *
945
+ * @return array
946
+ */
947
+ public function get_featured_images( $post_id = null ) {
948
+ $post_id = $this->get_real_post_id( $post_id );
949
+ $dfi_images = get_post_meta( $post_id, 'dfiFeatured', true );
950
+ $ret_images = array();
951
+
952
+ if ( ! empty( $dfi_images ) && is_array( $dfi_images ) ) {
953
+ $dfi_images = array_filter( $dfi_images );
954
+
955
+ $count = 0;
956
+ foreach ( $dfi_images as $dfi_image ) {
957
+ $dfi_image_trimmed = $this->separate( $dfi_image );
958
+ $dfi_image_full = $this->separate( $dfi_image, 'full' );
959
+
960
+ try {
961
+ $ret_images[ $count ]['thumb'] = $this->get_real_upload_path( $dfi_image_trimmed );
962
+ $ret_images[ $count ]['full'] = $this->get_real_upload_path( $dfi_image_full );
963
+ $ret_images[ $count ]['attachment_id'] = $this->get_image_id( $ret_images[ $count ]['full'] );
964
+ } catch ( Exception $e ) {
965
+ /* Ignore the exception and continue with other featured images */
966
+ }
967
+
968
+ $count ++;
969
+ }
970
+ }
971
+
972
+ return $ret_images;
973
+ }
974
+
975
+ /**
976
+ * Check to see if the upload url is already available in path.
977
+ *
978
+ * @since 3.1.14
979
+ * @access protected
980
+ *
981
+ * @param string $img Uploaded image.
982
+ *
983
+ * @return string
984
+ */
985
+ protected function get_real_upload_path( $img ) {
986
+ // check if upload path is already attached.
987
+ if ( false !== strpos( $img, $this->upload_url ) || preg_match( '/https?:\/\//', $img ) ) {
988
+ return $img;
989
+ }
990
+
991
+ return $this->upload_url . $img;
992
+ }
993
+
994
+ /**
995
+ * Retrieve featured images for specific post(s) including the default Featured Image.
996
+ *
997
+ * @since 3.1.7
998
+ * @access public
999
+ *
1000
+ * @see $this->get_featured_images()
1001
+ *
1002
+ * @param int $post_id Current post id.
1003
+ *
1004
+ * @return array An array of images or an empty array on failure
1005
+ */
1006
+ public function get_all_featured_images( $post_id = null ) {
1007
+ $post_id = $this->get_real_post_id( $post_id );
1008
+ $thumbnail_id = get_post_thumbnail_id( $post_id );
1009
+ $all_images = array();
1010
+
1011
+ if ( ! empty( $thumbnail_id ) ) {
1012
+ $featured_image = array(
1013
+ 'thumb' => wp_get_attachment_thumb_url( $thumbnail_id ),
1014
+ 'full' => wp_get_attachment_url( $thumbnail_id ),
1015
+ 'attachment_id' => $thumbnail_id,
1016
+ );
1017
+
1018
+ $all_images[] = $featured_image;
1019
+ }
1020
+
1021
+ return array_merge( $all_images, $this->get_featured_images( $post_id ) );
1022
+ }
1023
+
1024
+ /**
1025
+ * Load the plugin's textdomain hooked to 'plugins_loaded'.
1026
+ *
1027
+ * @since 1.0.0
1028
+ * @access public
1029
+ *
1030
+ * @see load_plugin_textdomain()
1031
+ * @see plugin_basename()
1032
+ * @action plugins_loaded
1033
+ *
1034
+ * @codeCoverageIgnore
1035
+ *
1036
+ * @return void
1037
+ */
1038
+ public function load_plugin_textdomain() {
1039
+ load_plugin_textdomain(
1040
+ self::TEXT_DOMAIN,
1041
+ false,
1042
+ dirname( plugin_basename( __FILE__ ) ) . '/languages/'
1043
+ );
1044
+ }
1045
+ }
1046
 
1047
  /**
1048
+ * Instantiate the main class.
1049
  *
1050
  * @since 1.0.0
1051
  * @access public
1052
  *
1053
+ * @var object $dynamic_featured_image holds the instantiated class {@uses Dynamic_Featured_Image}
1054
  */
1055
  global $dynamic_featured_image;
1056
  $dynamic_featured_image = new Dynamic_Featured_Image();
js/script-dfi.js CHANGED
@@ -1,163 +1,155 @@
1
- /**
2
- * @file script-dfi.js
3
- *
4
- * Script for dynamic featured image plugin.
5
- *
6
- * Copyright (c) 2013, Ankit Pokhrel <ankitpokhrel@gmail.com, http://ankitpokhrel.com.np>
7
- */
8
-
9
- jQuery(document).ready(function($) {
10
- var current = null;
11
-
12
- /**
13
- * Add new meta box
14
- */
15
- $(document).on('click', '.dfiAddNew', function() {
16
-
17
- var obj = $(this),
18
- id = parseInt( $('.featured-meta-box:last').find('.dfiAddNew').data('id'), 10 ),
19
- idLocal = $('.featured-meta-box:last').find('.dfiAddNew').attr('data-id-local'),
20
- newMetaBox = obj.closest('.featured-meta-box').clone();
21
-
22
- newMetaBox.find('.hndle span').html( WP_SPECIFIC.metabox_title + " " + idLocal );
23
- newMetaBox.attr('id', 'dfiFeaturedMetaBox' + "-" + (++id) );
24
- newMetaBox.find('.handlediv').addClass('dfiDynamicBox');
25
-
26
- var metaBoxContentObj = newMetaBox.find('.inside');
27
- metaBoxContentObj.html('');
28
- obj.hide();
29
- obj.parent().append('<span class="dfiLoading"></span>').hide().fadeIn(200);
30
-
31
- $.ajax({
32
- type: 'POST',
33
- url: 'admin-ajax.php',
34
- data: { action: 'dfiMetaBox_callback', id: id },
35
- success: function(response){
36
- metaBoxContentObj.append(response);
37
- newMetaBox.appendTo( obj.closest('.featured-meta-box').parent() );
38
-
39
- //Add post id
40
- newMetaBox.find('.dfiFeaturedImage').attr('data-post-id', obj.parent().parent().find('.dfiFeaturedImage').attr('data-post-id') );
41
-
42
- var alias = obj;
43
- obj.parent().find('.dfiLoading').fadeOut(300, function(){ $(this).remove(); alias.fadeIn(200); });
44
- }
45
- });
46
-
47
- });
48
-
49
- /**
50
- * Remove featured image meta box
51
- */
52
- $(document).on('click', '.dfiRemove', function() {
53
-
54
- if( confirm('Are you sure?') ) {
55
-
56
- var dfiMetaBox = $(this).closest('.featured-meta-box'),
57
- totalMetaBox = $('.featured-meta-box').length;
58
-
59
- if( totalMetaBox === 1 ) {
60
-
61
- dfiMetaBox.find('.dfiImg').attr('src', '');
62
- dfiMetaBox.find('.dfiImageHolder').val('');
63
- dfiMetaBox.find('.dfiFeaturedImage')
64
- .removeClass('hasFeaturedImage')
65
- .show()
66
- .animate({ opacity: 1, display: 'inline-block' }, 600);
67
-
68
- } else {
69
-
70
- dfiMetaBox.fadeOut(500, function(){
71
- $(this).remove();
72
- });
73
-
74
- }
75
-
76
- }
77
-
78
- });
79
-
80
- /**
81
- * Display custom media uploader and allow to
82
- * select featured image from the media library
83
- */
84
- $(document).on('click', '.dfiFeaturedImage', function() {
85
-
86
- current = $(this);
87
-
88
- if( null !== current) {
89
-
90
- var dfi_uploader = wp.media({
91
-
92
- title: WP_SPECIFIC.mediaSelector_title,
93
- button: {
94
- text: WP_SPECIFIC.mediaSelector_buttonText
95
- },
96
- multiple: false,
97
-
98
- }).on('select', function() {
99
-
100
- var attachment = dfi_uploader.state().get('selection').first().toJSON(),
101
- fullSize = attachment.url,
102
- imgUrl = (typeof attachment.sizes.thumbnail === "undefined") ? fullSize : attachment.sizes.thumbnail.url,
103
- imgUrlTrimmed, fullUrlTrimmed;
104
-
105
- imgUrlTrimmed = imgUrl.replace(WP_SPECIFIC.upload_url, "");
106
- fullUrlTrimmed = fullSize.replace(WP_SPECIFIC.upload_url, "");
107
-
108
- var featuredBox = current.parent();
109
-
110
- featuredBox.find('.fImg').attr({
111
- 'src': imgUrl,
112
- 'data-src': fullSize
113
- });
114
-
115
- featuredBox.find('.dfiFeaturedImage').addClass('hasFeaturedImage');
116
-
117
- var dfiFeaturedImages = [imgUrlTrimmed, fullUrlTrimmed];
118
-
119
- /**
120
- * Check if medium sized image exists
121
- * @type object
122
- */
123
- var medium = attachment.url;
124
- if( typeof attachment.sizes.medium !== "undefined" ) {
125
- medium = attachment.sizes.medium.url;
126
- }
127
-
128
- featuredBox.find('img').attr('src', medium).fadeIn(200);
129
- featuredBox.find('input.dfiImageHolder').val(dfiFeaturedImages);
130
-
131
- }).open();
132
- }
133
-
134
- return false;
135
-
136
- });
137
-
138
- /**
139
- * Enable toggle of dynamically generated featured box
140
- */
141
- $(document).on('click', '.dfiDynamicBox', function() {
142
- $(this).parent().toggleClass('closed');
143
- });
144
-
145
- /**
146
- * Add a hover animation in image
147
- */
148
- $(document).on({
149
- mouseenter: function(){
150
- var obj = $(this).closest('.featured-meta-box');
151
- obj.find('.dfiImg').stop(true, true).animate({ opacity: 0.3 }, 300 );
152
- obj.find('.hasFeaturedImage').fadeIn(200);
153
- },
154
- mouseleave: function(){
155
- var obj = $(this);
156
- obj.find('.dfiImg').stop(true, true).animate({ opacity: 1 }, 300 );
157
- obj.find('.hasFeaturedImage').fadeOut(100);
158
- }
159
- }, '.featured-meta-box .inside');
160
-
161
- });
162
-
163
- //END
1
+ /**
2
+ * Script for dynamic featured image plugin.
3
+ *
4
+ * @package dynamic-featured-image
5
+ * @subpackage js
6
+ *
7
+ * Copyright (c) 2013, Ankit Pokhrel <info@ankitpokhrel.com, https://ankitpokhrel.com>
8
+ */
9
+
10
+ jQuery( document ).ready( function ( $ ) {
11
+ var current = null;
12
+
13
+ // Add new meta box.
14
+ $( document ).on( 'click', '.dfiAddNew', function () {
15
+
16
+ var obj = $( this ),
17
+ lastFeaturedMetaBox = $( '.featured-meta-box:last' ),
18
+ id = parseInt( lastFeaturedMetaBox.find( '.dfiAddNew' ).data( 'id' ), 10 ),
19
+ idLocal = lastFeaturedMetaBox.find( '.dfiAddNew' ).attr( 'data-id-local' ),
20
+ newMetaBox = obj.closest( '.featured-meta-box' ).clone();
21
+
22
+ newMetaBox.find( '.hndle span' ).html( DFI_SPECIFIC.metabox_title + " " + idLocal );
23
+ newMetaBox.attr( 'id', 'dfiFeaturedMetaBox' + "-" + (++ id) );
24
+ newMetaBox.find( '.handlediv' ).addClass( 'dfiDynamicBox' );
25
+
26
+ var metaBoxContentObj = newMetaBox.find( '.inside' );
27
+ metaBoxContentObj.html( '' );
28
+ obj.hide();
29
+ obj.parent().append( '<span class="dfiLoading"></span>' ).hide().fadeIn( 200 );
30
+
31
+ $.ajax( {
32
+ type: 'POST',
33
+ url: 'admin-ajax.php',
34
+ data: {
35
+ action: 'dfiMetaBox_callback',
36
+ security: DFI_SPECIFIC.ajax_nonce,
37
+ id: id
38
+ },
39
+ success: function ( response ) {
40
+ metaBoxContentObj.append( response );
41
+ newMetaBox.appendTo( obj.closest( '.featured-meta-box' ).parent() );
42
+
43
+ // Add post id.
44
+ newMetaBox.find( '.dfiFeaturedImage' ).attr( 'data-post-id',
45
+ obj.parent().parent().find( '.dfiFeaturedImage' ).attr( 'data-post-id' ) );
46
+
47
+ var alias = obj;
48
+ obj.parent().find( '.dfiLoading' ).fadeOut( 300, function () {
49
+ $( this ).remove();
50
+ alias.fadeIn( 200 );
51
+ } );
52
+ }
53
+ } );
54
+
55
+ } );
56
+
57
+ // Remove featured image meta box.
58
+ $( document ).on( 'click', '.dfiRemove', function () {
59
+
60
+ if ( confirm( 'Are you sure?' ) ) {
61
+
62
+ var dfiMetaBox = $( this ).closest( '.featured-meta-box' ),
63
+ totalMetaBox = $( '.featured-meta-box' ).length;
64
+
65
+ if ( 1 === totalMetaBox ) {
66
+
67
+ dfiMetaBox.find( '.dfiImg' ).attr( 'src', '' );
68
+ dfiMetaBox.find( '.dfiImageHolder' ).val( '' );
69
+ dfiMetaBox.find( '.dfiFeaturedImage' )
70
+ .removeClass( 'hasFeaturedImage' )
71
+ .show()
72
+ .animate( { opacity: 1, display: 'inline-block' }, 600 );
73
+
74
+ } else {
75
+ dfiMetaBox.fadeOut( 500, function () {
76
+ $( this ).remove();
77
+ } );
78
+ }
79
+ }
80
+ } );
81
+
82
+ // Display custom media uploader and allow to select featured image from the media library.
83
+ $( document ).on( 'click', '.dfiFeaturedImage', function () {
84
+
85
+ current = $( this );
86
+
87
+ if ( null !== current ) {
88
+ var dfi_uploader = wp.media( {
89
+ title: DFI_SPECIFIC.mediaSelector_title,
90
+ button: {
91
+ text: DFI_SPECIFIC.mediaSelector_buttonText
92
+ },
93
+ multiple: false,
94
+ } ).on( 'select', function () {
95
+ var attachment = dfi_uploader.state().get( 'selection' ).first().toJSON(),
96
+ fullSize = attachment.url,
97
+ imgUrl = (typeof attachment.sizes.thumbnail === "undefined") ? fullSize : attachment.sizes.thumbnail.url,
98
+ imgUrlTrimmed,
99
+ fullUrlTrimmed;
100
+
101
+ imgUrlTrimmed = imgUrl.replace( DFI_SPECIFIC.upload_url, "" );
102
+ fullUrlTrimmed = fullSize.replace( DFI_SPECIFIC.upload_url, "" );
103
+
104
+ var featuredBox = current.parent();
105
+
106
+ featuredBox.find( '.fImg' ).attr( {
107
+ 'src': imgUrl,
108
+ 'data-src': fullSize
109
+ } );
110
+
111
+ featuredBox.find( '.dfiFeaturedImage' ).addClass( 'hasFeaturedImage' );
112
+
113
+ var dfiFeaturedImages = [imgUrlTrimmed, fullUrlTrimmed];
114
+
115
+ /**
116
+ * Check if medium sized image exists.
117
+ *
118
+ * @type object
119
+ */
120
+ var medium = attachment.url;
121
+
122
+ if ( typeof attachment.sizes.medium !== "undefined" ) {
123
+ medium = attachment.sizes.medium.url;
124
+ }
125
+
126
+ featuredBox.find( 'img' ).attr( 'src', medium ).fadeIn( 200 );
127
+ featuredBox.find( 'input.dfiImageHolder' ).val( dfiFeaturedImages );
128
+ } ).open();
129
+ } // End if().
130
+
131
+ return false;
132
+ } );
133
+
134
+ // Enable toggle of dynamically generated featured box.
135
+ $( document ).on( 'click', '.dfiDynamicBox', function () {
136
+ $( this ).parent().toggleClass( 'closed' );
137
+ } );
138
+
139
+ // Add a hover animation in image.
140
+ $( document ).on( {
141
+ mouseenter: function () {
142
+ var obj = $( this ).closest( '.featured-meta-box' );
143
+
144
+ obj.find( '.dfiImg' ).stop( true, true ).animate( { opacity: 0.3 }, 300 );
145
+ obj.find( '.hasFeaturedImage' ).fadeIn( 200 );
146
+ },
147
+ mouseleave: function () {
148
+ var obj = $( this );
149
+
150
+ obj.find( '.dfiImg' ).stop( true, true ).animate( { opacity: 1 }, 300 );
151
+ obj.find( '.hasFeaturedImage' ).fadeOut( 100 );
152
+ }
153
+ }, '.featured-meta-box .inside' );
154
+
155
+ } );
 
 
 
 
 
 
 
 
languages/dynamic-featured-image-bs_BA.mo CHANGED
File without changes
languages/dynamic-featured-image-bs_BA.po CHANGED
File without changes
languages/dynamic-featured-image-he_IL.mo CHANGED
File without changes
languages/dynamic-featured-image-he_IL.po CHANGED
File without changes
languages/dynamic-featured-image-hr_HR.mo CHANGED
File without changes
languages/dynamic-featured-image-hr_HR.po CHANGED
File without changes
languages/dynamic-featured-image-it_IT.mo CHANGED
File without changes
languages/dynamic-featured-image-it_IT.po CHANGED
File without changes
languages/dynamic-featured-image-ne_NP.mo CHANGED
File without changes
languages/dynamic-featured-image-ne_NP.po CHANGED
File without changes
languages/dynamic-featured-image-sr_RS.mo CHANGED
File without changes
languages/dynamic-featured-image-sr_RS.po CHANGED
File without changes
languages/dynamic-featured-image-sv_SE.mo CHANGED
File without changes
languages/dynamic-featured-image-sv_SE.po CHANGED
File without changes
readme.txt CHANGED
@@ -2,11 +2,11 @@
2
  Contributors: ankitpokhrel, cfoellmann
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=J9FVY3ESPPD58
4
  Tags: dynamic featured image, featured image, post thumbnail, dynamic post thumbnail, multiple featured image, multiple post thumbnail
5
- Requires at least: 3.5
6
- Tested up to: 4.7
7
- Stable tag: 3.5.2
8
  License: GPLv2 or later
9
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
  Dynamically adds multiple featured image (post thumbnail) functionality to posts, pages and custom post types.
12
 
@@ -21,9 +21,9 @@ This is especially helpful when you use other plugins, post thumbnails or slider
21
  Why limit yourself to only one featured image if you can do some awesome stuffs with multiple featured image?
22
  DFI allows you to add different number of featured images to each post and page that can be collected by the various theme functions.
23
 
24
- > **A NOTE ABOUT SUPPORT:** We’re here to help troubleshoot bugs, but please don't set expectations early as the support forums at WordPress.org are only checked once a week. All the support of the Dynamic Featured Image plugin will now be provided from within [this support forum](http://ankitpokhrel.com/explore/forums/forum/dynamic-featured-image-free-version/ "Dynamic Featured Image Support Forum").
25
 
26
- > Users looking for more timely/in-depth support and extended features are encouraged to check out [Dynamic Featured Image PRO](http://ankitpokhrel.com/explore/dynamic-featured-image-pro/ "Dynamic Featured Image PRO").
27
 
28
  > **FEATURES OF PRO VERSION**
29
  – Settings Page to control the visibility of DFI metabox.
@@ -34,7 +34,7 @@ DFI allows you to add different number of featured images to each post and page
34
  – Dedicated email and chat support.
35
  – Access to more advance features and future updates for free.
36
 
37
- > [Learn more &raquo;](http://ankitpokhrel.com.np/blog/downloads/dynamic-featured-image-pro/ "Dynamic Featured Image PRO")
38
 
39
  **How it works?**
40
  1. After successfull plugin activation go to `add` or `edit` page of posts or pages and you will notice a box for second featured image.
@@ -59,8 +59,8 @@ array
59
 
60
  **Resources**
61
  1. [Detail Documentation](https://github.com/ankitpokhrel/Dynamic-Featured-Image/wiki "Documentation for current ver.").
62
- 2. [DFI Blog](http://ankitpokhrel.com/explore/category/dynamic-featured-image/ "DFI Blog").
63
- 3. [StackOverflow Tag](http://stackoverflow.com/questions/tagged/dynamic-featured-image "StackOverflow Tag").
64
 
65
  **MultiSite Info**
66
  You can use `Network Activate` to activate plugin for all sites on a single install. It is only available on the Network admin site not anywhere else.
@@ -85,7 +85,7 @@ The problem is usually due to the conflicts with other plugin or theme functions
85
  i. Switch to the default wordpress theme to rule out any theme-specific problems.
86
  ii. Try the plugin in a fresh new WordPress installation.
87
  iii. If it works, deactivate all plugins from your current wordpress installation to see if this resolves the problem. If this works, re-activate the plugins one by one until you find the problematic plugin(s).
88
- iv. [Resetting the plugins folder](http://www.google.com/url?q=http%3A%2F%2Fcodex.wordpress.org%2FFAQ_Troubleshooting%23How_to_deactivate_all_plugins_when_not_able_to_access_the_administrative_menus.3F&sa=D&sntz=1&usg=AFQjCNFaei9nyiMZe2yZQUBBA_MghJ-Wxw) by FTP or PhpMyAdmin. Sometimes, an apparently inactive plugin can still cause problems.
89
 
90
  = 2. There is no additional image on the page when I save it or publish it? =
91
  This happens when there is any problem in saving you post or page properly. For example, if you try to save or publish the post without the post title the featured images may not be saved properly.
@@ -100,13 +100,13 @@ Alt, caption and title attribute for these images cannot be retrieved using help
100
  This usually happens because of cache. Clear all your cache and try again if you are having this problem. If you still have such problem you can get help through support forum.
101
 
102
  = 5. Is it possible to make DFI work only for certain post types? =
103
- Yes! It is easily possible from version 3.1.13. A filter is added in the recent version for this purpose. Refer [this thread](http://ankitpokhrel.com.np/blog/is-it-possible-to-make-dfi-work-only-for-certain-post-types/) for mor info.
104
 
105
  = 6. Other problems or questions? =
106
- Other problems? Don't forget to check the [blog](http://ankitpokhrel.com/explore/category/dynamic-featured-image/) and learn to create some exciting things using DFI.
107
 
108
- Please use [support forum](http://wordpress.org/support/plugin/dynamic-featured-image) first if you have any question or queries about the project.
109
- If you don't receive any help in support forum then you can directly contact me at `info [at] ankitpokhrel.com.np`. Please atleast wait for 48hrs before sending another request.
110
 
111
  Please feel free to report any bug found at https://github.com/ankitpokhrel/Dynamic-Featured-Image/ or `info [at] ankitpokhrel.com`.
112
 
@@ -116,6 +116,12 @@ Please feel free to report any bug found at https://github.com/ankitpokhrel/Dyna
116
  3. Add new featured image box.
117
 
118
  == Changelog ==
 
 
 
 
 
 
119
  = 3.5.2 =
120
  * Fix image url if image already points to CDN. PR #50
121
  * Internal refactorings
@@ -212,6 +218,9 @@ Please feel free to report any bug found at https://github.com/ankitpokhrel/Dyna
212
  * Fixed some minor issues.
213
 
214
  == Upgrade Notice ==
 
 
 
215
  = 3.5.2 =
216
  * Some refactorings and bug fixes.
217
 
2
  Contributors: ankitpokhrel, cfoellmann
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=J9FVY3ESPPD58
4
  Tags: dynamic featured image, featured image, post thumbnail, dynamic post thumbnail, multiple featured image, multiple post thumbnail
5
+ Requires at least: 3.8
6
+ Tested up to: 4.8.1
7
+ Stable tag: 3.6.0
8
  License: GPLv2 or later
9
+ License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
11
  Dynamically adds multiple featured image (post thumbnail) functionality to posts, pages and custom post types.
12
 
21
  Why limit yourself to only one featured image if you can do some awesome stuffs with multiple featured image?
22
  DFI allows you to add different number of featured images to each post and page that can be collected by the various theme functions.
23
 
24
+ > **A NOTE ABOUT SUPPORT:** We’re here to help troubleshoot bugs, but please don't set expectations early as the support forums at WordPress.org are only checked once a week. All the support of the Dynamic Featured Image plugin will now be provided from within [this support forum](https://ankitpokhrel.com/explore/forums/forum/dynamic-featured-image-free-version/ "Dynamic Featured Image Support Forum").
25
 
26
+ > Users looking for more timely/in-depth support and extended features are encouraged to check out [Dynamic Featured Image PRO](https://ankitpokhrel.com/explore/dynamic-featured-image-pro/ "Dynamic Featured Image PRO").
27
 
28
  > **FEATURES OF PRO VERSION**
29
  – Settings Page to control the visibility of DFI metabox.
34
  – Dedicated email and chat support.
35
  – Access to more advance features and future updates for free.
36
 
37
+ > [Learn more &raquo;](https://ankitpokhrel.com/explore/dynamic-featured-image-pro/ "Dynamic Featured Image PRO")
38
 
39
  **How it works?**
40
  1. After successfull plugin activation go to `add` or `edit` page of posts or pages and you will notice a box for second featured image.
59
 
60
  **Resources**
61
  1. [Detail Documentation](https://github.com/ankitpokhrel/Dynamic-Featured-Image/wiki "Documentation for current ver.").
62
+ 2. [DFI Blog](https://ankitpokhrel.com/explore/category/dynamic-featured-image/ "DFI Blog").
63
+ 3. [StackOverflow Tag](https://stackoverflow.com/questions/tagged/dynamic-featured-image "StackOverflow Tag").
64
 
65
  **MultiSite Info**
66
  You can use `Network Activate` to activate plugin for all sites on a single install. It is only available on the Network admin site not anywhere else.
85
  i. Switch to the default wordpress theme to rule out any theme-specific problems.
86
  ii. Try the plugin in a fresh new WordPress installation.
87
  iii. If it works, deactivate all plugins from your current wordpress installation to see if this resolves the problem. If this works, re-activate the plugins one by one until you find the problematic plugin(s).
88
+ iv. [Resetting the plugins folder](https://codex.wordpress.org/FAQ_Troubleshooting#How_to_deactivate_all_plugins_when_not_able_to_access_the_administrative_menus.3F) by FTP or PhpMyAdmin. Sometimes, an apparently inactive plugin can still cause problems.
89
 
90
  = 2. There is no additional image on the page when I save it or publish it? =
91
  This happens when there is any problem in saving you post or page properly. For example, if you try to save or publish the post without the post title the featured images may not be saved properly.
100
  This usually happens because of cache. Clear all your cache and try again if you are having this problem. If you still have such problem you can get help through support forum.
101
 
102
  = 5. Is it possible to make DFI work only for certain post types? =
103
+ Yes! It is easily possible from version 3.1.13. A filter is added in the recent version for this purpose. Refer [this thread](https://ankitpokhrel.com/explore/is-it-possible-to-make-dfi-work-only-for-certain-post-types/) for mor info.
104
 
105
  = 6. Other problems or questions? =
106
+ Other problems? Don't forget to check the [blog](https://ankitpokhrel.com/explore/category/dynamic-featured-image/) and learn to create some exciting things using DFI.
107
 
108
+ Please use [support forum](https://wordpress.org/support/plugin/dynamic-featured-image) first if you have any question or queries about the project.
109
+ If you don't receive any help in support forum then you can directly contact me at `info [at] ankitpokhrel.com`. Please atleast wait for 48hrs before sending another request.
110
 
111
  Please feel free to report any bug found at https://github.com/ankitpokhrel/Dynamic-Featured-Image/ or `info [at] ankitpokhrel.com`.
112
 
116
  3. Add new featured image box.
117
 
118
  == Changelog ==
119
+ = 3.6.0 =
120
+ * Various security fixes.
121
+ * Missing text domains fixes.
122
+ * Dashicons css removed as it is no longer needed.
123
+ * Numerous WordPress coding standard improvements.
124
+
125
  = 3.5.2 =
126
  * Fix image url if image already points to CDN. PR #50
127
  * Internal refactorings
218
  * Fixed some minor issues.
219
 
220
  == Upgrade Notice ==
221
+ = 3.6.0 =
222
+ * Various security fixes.
223
+
224
  = 3.5.2 =
225
  * Some refactorings and bug fixes.
226
 
uninstall.php CHANGED
@@ -1,8 +1,16 @@
1
  <?php
2
- if( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
3
- exit();
4
- }
 
 
 
 
5
 
6
- //cleanup plugin data
7
- delete_post_meta_by_key('dfiFeatured');
8
- delete_post_meta_by_key('_dfi_link_to_image');
 
 
 
 
1
  <?php
2
+ /**
3
+ * Uninstall script.
4
+ *
5
+ * @since 0.0.0
6
+ * @package dynamic-featured-image
7
+ * @author Ankit Pokhrel <info@ankitpokhrel.com, https://ankitpokhrel.com>
8
+ */
9
 
10
+ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
11
+ exit();
12
+ }
13
+
14
+ // cleanup plugin data.
15
+ delete_post_meta_by_key( 'dfiFeatured' );
16
+ delete_post_meta_by_key( '_dfi_link_to_image' );