Completed
Push — master ( 5c3df7...e73e89 )
by Ankit
02:03
created

dynamic-featured-image.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/***
4
 * Plugin Name: Dynamic Featured Image
5
 * Plugin URI: http://wordpress.org/plugins/dynamic-featured-image/
6
 * Description: Dynamically adds multiple featured image or post thumbnail functionality to your posts, pages and custom post types.
7
 * Version: 3.5.2
8
 * Author: Ankit Pokhrel
9
 * Author URI: http://ankitpokhrel.com.np
10
 * License: GPL2 or later
11
 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 * Text Domain: dynamic-featured-image
13
 * Domain Path: /languages
14
 * GitHub Plugin URI: https://github.com/ankitpokhrel/Dynamic-Featured-Image
15
 *
16
 * Copyright (C) 2013 Ankit Pokhrel <[email protected], http://ankitpokhrel.com.np>,
17
 *
18
 * This program is free software; you can redistribute it and/or modify
19
 * it under the terms of the GNU General Public License as published by
20
 * the Free Software Foundation; either version 3 of the License, or
21
 * (at your option) any later version.
22
 *
23
 * This program is distributed in the hope that it will be useful,
24
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
 * GNU General Public License for more details.
27
 *
28
 * You should have received a copy of the GNU General Public License
29
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
30
 */
31
32
// Avoid direct calls to this file
33
if ( ! defined( 'ABSPATH' ) ) {
34
    header( 'Status: 403 Forbidden' );
35
    header( 'HTTP/1.1 403 Forbidden' );
36
    exit();
37
}
38
39
/**
40
 * Dynamic Featured Image plugin main class
41
 *
42
 * @package dynamic-featured-image
43
 * @author Ankit Pokhrel <[email protected]>
44
 * @version 3.0.1
45
 */
46
class Dynamic_Featured_Image
47
{
48
    /**
49
     * Current version of the plugin.
50
     *
51
     * @since 3.0.0
52
     */
53
    const VERSION = '3.5.2';
54
55
    /* Image upload directory */
56
    private $__upload_dir;
57
58
    /* Image upload URL */
59
    private $__upload_url;
60
61
    /* Database object */
62
    private $__db;
63
64
    /* Plugin text domain */
65
    protected $_textDomain;
66
67
    /* Title for dfi metabox */
68
    protected $_metabox_title;
69
70
    /* Users post type filter for dfi metabox */
71
    protected $_userFilter;
72
73
    /**
74
     * Constructor. Hooks all interactions to initialize the class.
75
     *
76
     * @since 1.0.0
77
     * @access public
78
     * @global object $wpdb
79
     *
80
     * @see     add_action()
81
     */
82
    public function __construct()
83
    {
84
        $this->_textDomain = 'dynamic-featured-image';
85
86
        //plugin update warning
87
        add_action( 'in_plugin_update_message-' . plugin_basename( __FILE__ ), array( $this, 'update_notice' ) );
88
89
        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
90
        add_action( 'add_meta_boxes', array( $this, 'initialize_featured_box' ) );
91
        add_action( 'save_post', array( $this, 'save_meta' ) );
92
        add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
93
94
        //handle ajax request
95
        add_action( 'wp_ajax_dfiMetaBox_callback', array( $this, 'ajax_callback' ) );
96
97
        //add action links
98
        add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'dfi_action_links' ) );
99
100
        //media uploader custom fields
101
        add_filter( 'attachment_fields_to_edit', array( $this, 'media_attachment_custom_fields' ), 10, 2 );
102
        add_filter( 'attachment_fields_to_save', array( $this, 'media_attachment_custom_fields_save' ), 10, 2 );
103
104
        //get the site protocol
105
        $protocol = $this->__get_protocol();
106
107
        $this->__upload_dir = wp_upload_dir();
108
        $this->__upload_url = preg_replace( '#^https?://#', '', $this->__upload_dir['baseurl'] );
109
110
        //add protocol to the upload url
111
        $this->__upload_url = $protocol . $this->__upload_url;
112
113
        //post type filter added by user
114
        $this->_userFilter = array();
115
116
        global $wpdb;
117
        $this->__db = $wpdb;
118
119
    } // END __construct()
120
121
    /**
122
     * Return site protocol
123
     *
124
     * @since 3.5.1
125
     * @access public
126
     *
127
     * @return string
128
     */
129
    private function __get_protocol()
0 ignored issues
show
__get_protocol uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
130
    {
131
        return ( ( ! empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] != 'off' ) ||
132
                 ( ! empty( $_SERVER['SERVER_PORT'] ) && $_SERVER['SERVER_PORT'] == 443 ) ) ? "https://" : "http://";
133
    }
134
135
    /**
136
     * Add required admin scripts
137
     *
138
     * @since 1.0.0
139
     * @access public
140
     *
141
     * @see  wp_enque_style()
142
     * @see  wp_register_script()
143
     * @see  wp_enqueue_script()
144
     *
145
     * @return Void
146
     */
147
    public function enqueue_admin_scripts()
148
    {
149
        //enqueue styles
150
        wp_enqueue_style( 'style-dfi', plugins_url( '/css/style-dfi.css', __FILE__ ), array(), self::VERSION );
151
        wp_enqueue_style( 'dashicons', plugins_url( '/css/dashicons.css', __FILE__ ), array(), self::VERSION );
152
153
        //register script
154
        wp_register_script( 'scripts-dfi', plugins_url( '/js/script-dfi.js', __FILE__ ), array( 'jquery' ),
155
                self::VERSION );
156
157
        //localize the script with required data
158
        wp_localize_script(
159
                'scripts-dfi',
160
                'WP_SPECIFIC',
161
                array(
162
                        'upload_url'               => $this->__upload_url,
163
                        'metabox_title'            => __( $this->_metabox_title, $this->_textDomain ),
164
                        'mediaSelector_title'      => __( 'Dynamic Featured Image - Media Selector',
165
                                $this->_textDomain ),
166
                        'mediaSelector_buttonText' => __( 'Set Featured Image', $this->_textDomain )
167
                )
168
        );
169
170
        //enqueue scripts
171
        wp_enqueue_script( 'scripts-dfi' );
172
173
    } // END initialize_components()
174
175
    /**
176
     * Add upgrade link
177
     *
178
     * @access public
179
     * @since  3.5.1
180
     * @action plugin_action_links
181
     *
182
     * @codeCoverageIgnore
183
     *
184
     * @param  array $links Action links
185
     *
186
     * @return array
187
     */
188
    public function dfi_action_links( $links )
189
    {
190
        $upgrade_link = array(
191
                '<a href="http://ankitpokhrel.com.np/blog/downloads/dynamic-featured-image-pro/" target="_blank">Upgrade to Premium</a>'
192
        );
193
194
        return array_merge( $links, $upgrade_link );
195
196
    } // END dfi_action_links()
197
198
    /**
199
     * Add featured meta boxes dynamically
200
     *
201
     * @since 1.0.0
202
     * @access public
203
     * @global object $post
204
     *
205
     * @see  get_post_meta()
206
     * @see  get_post_types()
207
     * @see  add_meta_box()
208
     * @see  add_filter()
209
     *
210
     * @return Void
211
     */
212
    public function initialize_featured_box()
213
    {
214
        global $post;
215
216
        if ( ! is_object( $post ) ) {
217
            return;
218
        }
219
220
        //make metabox title dynamic
221
        $this->_metabox_title = apply_filters( 'dfi_set_metabox_title', __( "Featured Image" ) );
222
223
        $featuredData  = get_post_meta( $post->ID, 'dfiFeatured', true );
224
        $totalFeatured = count( $featuredData );
225
226
        $defaultFilter     = array( 'attachment', 'revision', 'nav_menu_item' );
227
        $this->_userFilter = apply_filters( 'dfi_post_type_user_filter', $this->_userFilter );
228
        $filter            = array_merge( $defaultFilter, $this->_userFilter );
229
230
        $postTypes = get_post_types();
231
        $postTypes = array_diff( $postTypes, $filter );
232
233
        $postTypes = apply_filters( 'dfi_post_types', $postTypes );
234
235
        if ( ! empty( $featuredData ) && $totalFeatured >= 1 ) {
236
            $i = 2;
237
            foreach ( $featuredData as $featured ) {
238
                self::_dfi_add_meta_box( $postTypes, $featured, $i );
239
                $i ++;
240
            }
241
        } else {
242
            self::_dfi_add_meta_box( $postTypes );
243
        }
244
    } // END initialize_featured_box()
245
246
    /**
247
     * Translates more than one digit number digit by digit.
248
     *
249
     * @param  Integer $number Integer to be translated
250
     *
251
     * @return String         Translated number
252
     */
253
    protected function _get_number_translation( $number )
254
    {
255
        if ( $number <= 9 ) {
256
            return __( $number, $this->_textDomain );
257
        } else {
258
            $pieces = str_split( $number, 1 );
259
            $buffer = '';
260
            foreach ( $pieces as $piece ) {
261
                $buffer .= __( $piece, $this->_textDomain );
262
            }
263
264
            return $buffer;
265
        }
266
    }
267
268
    /**
269
     * adds meta boxes
270
     *
271
     * @param  Array $postTypes post types to show featured image box
272
     * @param  Object $featured callback arguments
273
     * @param  Integer $i index of the featured image
274
     *
275
     * @return Void
276
     */
277
    private function _dfi_add_meta_box( $postTypes, $featured = null, $i = null )
278
    {
279
        if ( ! is_null( $i ) ) {
280
            foreach ( $postTypes as $type ) {
281
                add_meta_box(
282
                        'dfiFeaturedMetaBox-' . $i,
283
                        __( $this->_metabox_title, $this->_textDomain ) . " " . self::_get_number_translation( $i ),
284
                        array( $this, 'featured_meta_box' ),
285
                        $type,
286
                        'side',
287
                        'low',
288
                        array( $featured, $i + 1 )
289
                );
290
                add_filter( "postbox_classes_{$type}_dfiFeaturedMetaBox-" . $i, array( $this, 'add_metabox_classes' ) );
291
            }
292
293
        } else {
294
            foreach ( $postTypes as $type ) {
295
                add_meta_box(
296
                        'dfiFeaturedMetaBox',
297
                        __( $this->_metabox_title, $this->_textDomain ) . " " . __( 2, $this->_textDomain ),
298
                        array( $this, 'featured_meta_box' ),
299
                        $type,
300
                        'side',
301
                        'low',
302
                        array( null, null )
303
                );
304
                add_filter( "postbox_classes_{$type}_dfiFeaturedMetaBox", array( $this, 'add_metabox_classes' ) );
305
            }
306
        }
307
308
    }
309
310
    /**
311
     * Separate thumb and full image url from given URL string
312
     *
313
     * @since  3.3.1
314
     *
315
     * @param  string $urlString [description]
316
     * @param  string $state Thumb or full
317
     *
318
     * @return string|null
319
     */
320
    private function _separate( $urlString, $state = 'thumb' )
321
    {
322
        $imagePiece = explode( ',', $urlString );
323
324
        if ( $state == 'thumb' ) {
325
            return isset( $imagePiece[0] ) ? $imagePiece[0] : null;
326
        }
327
328
        return isset( $imagePiece[1] ) ? $imagePiece[1] : null;
329
    }
330
331
    /**
332
     * Create a nonce field
333
     *
334
     * @since  3.5.0
335
     *
336
     * @see  wp_nonce_field()
337
     * @see  plugin_basename()
338
     *
339
     * @codeCoverageIgnore
340
     *
341
     * @param  string $key Nonce key
342
     *
343
     * @return string
344
     */
345
    protected function _nonce_field( $key )
346
    {
347
        return wp_nonce_field( plugin_basename( __FILE__ ), $key, true, false );
348
    }
349
350
    /**
351
     * Featured meta box as seen in the admin
352
     *
353
     * @since 1.0.0
354
     * @access public
355
     *
356
     * @param  Object $post global post object
357
     * @param  Array $featured array containing featured image count
358
     *
359
     * @return Void
360
     */
361
    public function featured_meta_box( $post, $featured )
362
    {
363
        $featuredImg = $featured['args'][0];
364
        $featuredId  = is_null( $featured['args'][1] ) ? 2 : -- $featured['args'][1];
365
366
        $featuredImgTrimmed = $featuredImgFull = $featuredImg;
367
        if ( ! is_null( $featuredImg ) ) {
368
            $featuredImgTrimmed = self::_separate( $featuredImg );
369
            $featuredImgFull    = self::_separate( $featuredImg, 'full' );
370
        }
371
372
        try {
373
374
            $thumbnail = $this->get_image_thumb( $this->__upload_url . $featuredImgFull, 'medium' );
375
            if ( is_null( $thumbnail ) ) {
376
377
                //medium sized thumbnail image is missing
378
                throw new Exception( "Medium size image not found", 1 );
379
380
            }
381
382
        } catch ( Exception $e ) {
383
384
            //since medium sized thumbnail image was not found,
385
            //let's set full image url as thumbnail
386
            $thumbnail = $featuredImgFull;
387
388
        }
389
390
        //Add a nonce field
391
        echo $this->_nonce_field( 'dfi_fimageplug-' . $featuredId );
392
        echo self::_get_featured_box( $featuredImgTrimmed, $featuredImg, $featuredId, $thumbnail, $post->ID );
393
394
    } // END featured_meta_box()
395
396
    /**
397
     * Returns featured box html content
398
     * @since  3.1.0
399
     * @access private
400
     *
401
     * @param  String $featuredImgTrimmed Medium sized image
402
     * @param  String $featuredImg Full sized image
403
     * @param  String $featuredId Attachment Id
404
     * @param  String $thumbnail Thumb sized image
405
     *
406
     * @return String                     Html content
407
     */
408
    private function _get_featured_box( $featuredImgTrimmed, $featuredImg, $featuredId, $thumbnail, $postId )
409
    {
410
        $hasFeaturedImage = ! empty( $featuredImgTrimmed ) ? 'hasFeaturedImage' : '';
411
        $thumbnail        = ! is_null( $thumbnail ) ? $thumbnail : '';
412
        $dfiEmpty         = is_null( $featuredImgTrimmed ) ? 'dfiImgEmpty' : '';
413
414
        return "<a href='javascript:void(0)' class='dfiFeaturedImage {$hasFeaturedImage}' title='" . __( 'Set Featured Image',
415
                $this->_textDomain ) . "' data-post-id='" . $postId . "'><span class='dashicons dashicons-camera'></span></a><br/>
416
			<img src='" . $thumbnail . "' class='dfiImg {$dfiEmpty}'/>
417
			<div class='dfiLinks'>
418
				<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',
419
                $this->_textDomain ) . "'></a>
420
				<a href='javascript:void(0)' class='dfiRemove dashicons dashicons-minus' title='" . __( 'Remove',
421
                $this->_textDomain ) . "'></a>
422
			</div>
423
			<div class='dfiClearFloat'></div>
424
			<input type='hidden' name='dfiFeatured[]' value='{$featuredImg}'  class='dfiImageHolder' />";
425
    }
426
427
    /**
428
     * Load new featured meta box via ajax
429
     *
430
     * @since 1.0.0
431
     * @access public
432
     *
433
     * @return Void
434
     */
435
    public function ajax_callback()
436
    {
437
        $featuredId = isset( $_POST['id'] ) ? (int) strip_tags( trim( $_POST['id'] ) ) : null;
438
439
        if ( is_null( $featuredId ) ) {
440
            return;
441
        }
442
443
        echo $this->_nonce_field( 'dfi_fimageplug-' . $featuredId );
444
        ?>
445
        <a href="javascript:void(0)" class="dfiFeaturedImage"
446
           title="<?php echo __( 'Set Featured Image', $this->_textDomain ) ?>"><span
447
                    class="dashicons dashicons-camera"></span></a><br/>
448
        <img src="" class="dfiImg dfiImgEmpty"/>
449
        <div class="dfiLinks">
450
            <a href="javascript:void(0)" data-id="<?php echo $featuredId ?>"
451
               data-id-local="<?php echo self::_get_number_translation( ( $featuredId + 1 ) ) ?>"
452
               class="dfiAddNew dashicons dashicons-plus" title="<?php echo __( 'Add New', $this->_textDomain ) ?>"></a>
453
            <a href="javascript:void(0)" class="dfiRemove dashicons dashicons-minus"
454
               title="<?php echo __( 'Remove', $this->_textDomain ) ?>"></a>
455
        </div>
456
        <div class="dfiClearFloat"></div>
457
        <input type="hidden" name="dfiFeatured[]" value="" class="dfiImageHolder"/>
458
        <?php
459
        wp_die( '' );
460
461
    } // END ajax_callback())
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
462
463
    /**
464
     * Add custom class 'featured-meta-box' to meta box
465
     *
466
     * @since 1.0.0
467
     * @access public
468
     *
469
     * @see  add_metabox_classes
470
     *
471
     * @param  $classes classes to add in the meta box
472
     *
473
     * @return string
474
     */
475
    public function add_metabox_classes( $classes )
476
    {
477
        array_push( $classes, 'featured-meta-box' );
478
479
        return $classes;
480
481
    } // END add_metabox_classes()
482
483
    /**
484
     * Add custom fields in media uploader
485
     *
486
     * @since  3.4.0
487
     *
488
     * @param $form_fields Array Fields to include in media attachment form
489
     * @param $post Array Post data
490
     *
491
     * @return Array
492
     */
493
    public function media_attachment_custom_fields( $form_fields, $post )
494
    {
495
        $form_fields['dfi-link-to-image'] = array(
496
                'label' => _( 'Link to Image' ),
497
                'input' => 'text',
498
                'value' => get_post_meta( $post->ID, '_dfi_link_to_image', true )
499
        );
500
501
        return $form_fields;
502
503
    } // END media_attachment_custom_fields()
504
505
    /**
506
     * Save values of media uploader custom fields
507
     *
508
     * @since 3.4.0
509
     *
510
     * @param $post Array The post data for database
511
     * @param $attachment Array Attachment fields from $_POST form
512
     *
513
     * @return Array
514
     */
515
    public function media_attachment_custom_fields_save( $post, $attachment )
516
    {
517
        if ( isset( $attachment['dfi-link-to-image'] ) ) {
518
            update_post_meta( $post['ID'], '_dfi_link_to_image', $attachment['dfi-link-to-image'] );
519
        }
520
521
        return $post;
522
523
    } // END media_attachment_custom_fields_save()
524
525
    /**
526
     * Update featured images in the database
527
     *
528
     * @since 1.0.0
529
     * @access public
530
     *
531
     * @see  plugin_basename()
532
     * @see  update_post_meta()
533
     * @see  current_user_can()
534
     *
535
     * @param  Integer $post_id current post id
536
     *
537
     * @return Void
538
     */
539
    public function save_meta( $post_id )
540
    {
541
        //Check autosave
542
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
543
            return false;
544
        }
545
546
        if ( $this->_verify_nonces() ) {
547
            //Check permission before saving data
548
            if ( current_user_can( 'edit_posts', $post_id ) && isset( $_POST['dfiFeatured'] ) ) {
549
                update_post_meta( $post_id, 'dfiFeatured', $_POST['dfiFeatured'] );
550
            }
551
        }
552
553
        return false;
554
555
    } // END save_meta()
556
557
    /**
558
     * Verify metabox nonces
559
     *
560
     * @access protected
561
     * @see  wp_verify_nonce()
562
     *
563
     * @return boolean
564
     */
565
    protected function _verify_nonces()
566
    {
567
        $keys = array_keys( $_POST );
568
        foreach ( $keys as $key ) {
569
            if ( preg_match( '/dfi_fimageplug-\d+$/', $key ) ) {
570
                //Verify nonce
571
                if ( ! wp_verify_nonce( $_POST[ $key ], plugin_basename( __FILE__ ) ) ) {
572
                    return false;
573
                }
574
            }
575
        }
576
577
        return true;
578
579
    } // END _verify_nonces()
580
581
    /**
582
     * Add update notice. Displayed in plugin update page.
583
     *
584
     * @since 2.0.0
585
     * @access public
586
     *
587
     * @return Void
588
     */
589
    public function update_notice()
590
    {
591
        $info = __( 'ATTENTION! Please read the <a href="https://github.com/ankitpokhrel/Dynamic-Featured-Image/wiki" target="_blank">DOCUMENTATION</a> properly before update.',
592
                $this->_textDomain );
593
        echo '<div style="color:red; padding:7px 0;">' . strip_tags( $info, '<a><b><i><span>' ) . '</div>';
594
595
    } // END update_notice()
596
597
    /** Helper functions */
598
599
    private function execute_query( $query )
600
    {
601
        return $this->__db->get_var( $query );
602
    }
603
604
    /**
605
     * Get attachment id of the image by image url
606
     *
607
     * @since 3.1.7
608
     * @access protected
609
     * @global object $wpdb
610
     *
611
     * @param  String $image_url url of the image
612
     *
613
     * @return string
614
     */
615
    protected function _get_attachment_id( $image_url )
616
    {
617
        return self::execute_query( $this->__db->prepare( "SELECT ID FROM " . $this->__db->posts . " WHERE guid = %s",
618
                $image_url ) );
619
620
    } // END _get_attachment_id()
621
622
    /**
623
     * Get image url of the image by attachment id
624
     *
625
     * @since 2.0.0
626
     * @access public
627
     *
628
     * @see  wp_get_attachment_image_src()
629
     *
630
     * @param  Integer $attachment_id attachment id of an image
631
     * @param  String $size size of the image to fetch (thumbnail, medium, full)
632
     *
633
     * @return String
634
     */
635
    public function get_image_url( $attachment_id, $size = 'full' )
636
    {
637
        $image_thumb = wp_get_attachment_image_src( $attachment_id, $size );
638
639
        return empty( $image_thumb ) ? null : $image_thumb[0];
640
641
    } // END get_image_url()
642
643
    /**
644
     * Get image thumbnail url of specific size by image url
645
     *
646
     * @since 2.0.0
647
     * @access public
648
     *
649
     * @see  get_image_id()
650
     * @see  wp_get_attachment_image_src()
651
     *
652
     * @param  String $image_url url of an image
653
     * @param  String $size size of the image to fetch (thumbnail, medium, full)
654
     *
655
     * @return String
656
     */
657
    public function get_image_thumb( $image_url, $size = 'thumbnail' )
658
    {
659
        $attachment_id = $this->get_image_id( $image_url );
660
        $image_thumb   = wp_get_attachment_image_src( $attachment_id, $size );
661
662
        return empty( $image_thumb ) ? null : $image_thumb[0];
663
664
    } // END get_image_thumb()
665
666
    /**
667
     * Gets attachment id from given image url
668
     *
669
     * @param  String $image_url url of an image
670
     *
671
     * @return Integer|Null            attachment id of an image
672
     *
673
     * @since  2.0.0
674
     * @access public
675
     */
676
    public function get_image_id( $image_url )
677
    {
678
        $attachment_id = $this->_get_attachment_id( $image_url );
679
        if ( is_null( $attachment_id ) ) {
680
            //check if the image is edited image
681
            //and try to get the attachment id
682
            $image_url = str_replace( $this->__upload_url . "/", '', $image_url );
683
            $row       = self::execute_query( $this->__db->prepare( "SELECT post_id FROM " . $this->__db->postmeta . " WHERE meta_value = %s",
684
                    $image_url ) );
685
            if ( ! is_null( $row ) ) {
686
                $attachment_id = $row;
687
            }
688
        }
689
690
        return $attachment_id;
691
    }
692
693
    /**
694
     * Get image title
695
     *
696
     * @since 2.0.0
697
     * @access public
698
     *
699
     * @param  String $image_url url of an image
700
     *
701
     * @return String
702
     */
703
    public function get_image_title( $image_url )
704
    {
705
        return self::execute_query( $this->__db->prepare( "SELECT post_title FROM " . $this->__db->posts . " WHERE guid = %s",
706
                $image_url ) );
707
708
    } // END get_image_title()
709
710
    /**
711
     * Get image title by id
712
     *
713
     * @since 2.0.0
714
     * @access public
715
     *
716
     * @param  Integer $attachment_id attachment id of an image
717
     *
718
     * @return String
719
     */
720
    public function get_image_title_by_id( $attachment_id )
721
    {
722
        return self::execute_query( $this->__db->prepare( "SELECT post_title FROM " . $this->__db->posts . " WHERE ID = %d",
723
                $attachment_id ) );
724
725
    } // END get_image_title_by_id()
726
727
    /**
728
     * Get image caption
729
     *
730
     * @since 2.0.0
731
     * @access public
732
     *
733
     * @param  String $image_url url of an image
734
     *
735
     * @return String
736
     */
737
    public function get_image_caption( $image_url )
738
    {
739
        return self::execute_query( $this->__db->prepare( "SELECT post_excerpt FROM " . $this->__db->posts . " WHERE guid = %s",
740
                $image_url ) );
741
742
    } // END get_image_caption()
743
744
    /**
745
     * Get image caption by id
746
     *
747
     * @since 2.0.0
748
     * @access public
749
     *
750
     * @param  Integer $attachment_id attachment id of an image
751
     *
752
     * @return String
753
     */
754
    public function get_image_caption_by_id( $attachment_id )
755
    {
756
        return self::execute_query( $this->__db->prepare( "SELECT post_excerpt FROM " . $this->__db->posts . " WHERE ID = %d",
757
                $attachment_id ) );
758
759
    } // END get_image_caption_by_id()
760
761
    /**
762
     * Get image alternate text
763
     *
764
     * @since 2.0.0
765
     * @access public
766
     *
767
     * @see  get_post_meta()
768
     *
769
     * @param  String $image_url url of an image
770
     *
771
     * @return String
772
     */
773
    public function get_image_alt( $image_url )
774
    {
775
        $attachment = $this->__db->get_col( $this->__db->prepare( "SELECT ID FROM " . $this->__db->posts . " WHERE guid = %s",
776
                $image_url ) );
777
778
        $alt = null;
779
        if ( ! empty( $attachment ) ) {
780
            $alt = get_post_meta( $attachment[0], '_wp_attachment_image_alt' );
781
        }
782
783
        return ( is_null( $alt ) || empty( $alt ) ) ? null : $alt[0];
784
785
    } // END get_image_alt()
786
787
    /**
788
     * Get image alternate text by attachment id
789
     *
790
     * @since 2.0.0
791
     * @access public
792
     *
793
     * @see  get_post_meta()
794
     *
795
     * @param  Integer $attachment_id attachment id of an image
796
     *
797
     * @return String
798
     */
799
    public function get_image_alt_by_id( $attachment_id )
800
    {
801
        $alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt' );
802
803
        return empty( $alt ) ? null : $alt[0];
804
805
    } // END get_image_alt_by_id()
806
807
    /**
808
     * Get image description
809
     *
810
     * @since 3.0.0
811
     * @access public
812
     *
813
     * @param  String $image_url url of an image
814
     *
815
     * @return String
816
     */
817
    public function get_image_description( $image_url )
818
    {
819
        return self::execute_query( $this->__db->prepare( "SELECT post_content FROM " . $this->__db->posts . " WHERE guid = %s",
820
                $image_url ) );
821
822
    } // END get_image_description()
823
824
    /**
825
     * Get image description by id
826
     *
827
     * @since 3.0.0
828
     * @access public
829
     *
830
     * @param  Integer $attachment_id attachment id of an image
831
     *
832
     * @return String
833
     */
834
    public function get_image_description_by_id( $attachment_id )
835
    {
836
        return self::execute_query( $this->__db->prepare( "SELECT post_content FROM " . $this->__db->posts . " WHERE ID = %d",
837
                $attachment_id ) );
838
839
    } // END get_image_description_by_id()
840
841
    /**
842
     * Get link to image
843
     *
844
     * @since 3.4.0
845
     * @access public
846
     *
847
     * @param  Integer $attachment_id attachment id of an image
848
     *
849
     * @return string|null
850
     */
851
    public function get_link_to_image( $attachment_id )
852
    {
853
        return get_post_meta( $attachment_id, '_dfi_link_to_image', true );
854
855
    } // END get_link_to_image()
856
857
    /**
858
     * Get all attachment ids of the post
859
     *
860
     * @since 2.0.0
861
     * @access public
862
     *
863
     * @see  get_post_meta()
864
     *
865
     * @param  Integer $post_id id of the current post
866
     *
867
     * @return Array
868
     */
869
    public function get_post_attachment_ids( $post_id )
870
    {
871
        $dfiImages = get_post_meta( $post_id, 'dfiFeatured', true );
872
873
        $retVal = array();
874
        if ( ! empty( $dfiImages ) && is_array( $dfiImages ) ) {
875
            foreach ( $dfiImages as $dfiImage ) {
876
                $dfiImageFull = self::_separate( $dfiImage, 'full' );
877
                $retVal[]     = $this->get_image_id( $this->__upload_url . $dfiImageFull );
878
            }
879
        }
880
881
        return $retVal;
882
883
    } // END get_post_attachment_ids()
884
885
    /**
886
     * Fetches featured image data of nth position
887
     *
888
     * @since  3.0.0
889
     * @access  public
890
     *
891
     * @see  get_featured_images()
892
     *
893
     * @param  Integer $position position of the featured image
894
     * @param  Integer $post_id id of the current post
895
     *
896
     * @return Array if found, null otherwise
897
     */
898
    public function get_nth_featured_image( $position, $post_id = null )
899
    {
900
        if ( is_null( $post_id ) ) {
901
            global $post;
902
            $post_id = $post->ID;
903
        }
904
905
        $featured_images = $this->get_featured_images( $post_id );
906
907
        return isset( $featured_images[ $position - 2 ] ) ? $featured_images[ $position - 2 ] : null;
908
909
    } // END get_nth_featured_image()
910
911
    /**
912
     * Check if the image is attached with the particular post
913
     *
914
     * @since 2.0.0
915
     * @access public
916
     *
917
     * @see  get_post_attachment_ids()
918
     *
919
     * @param  $attachment_id attachment id of an image
920
     * @param  $post_id id of the current post
921
     *
922
     * @return boolean
923
     */
924
    public function is_attached( $attachment_id, $post_id )
925
    {
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 : false;
933
934
    } // END is_attached()
935
936
    /**
937
     * Retrieve featured images for specific post(s)
938
     *
939
     * @since 2.0.0
940
     * @access public
941
     *
942
     * @see  get_post_meta()
943
     *
944
     * @param  Integer $post_id id of the current post
945
     *
946
     * @return Array
947
     */
948
    public function get_featured_images( $post_id = null )
949
    {
950
        if ( is_null( $post_id ) ) {
951
            global $post;
952
            $post_id = $post->ID;
953
        }
954
955
        $dfiImages = get_post_meta( $post_id, 'dfiFeatured', true );
956
957
        $retImages = array();
958
        if ( ! empty( $dfiImages ) && is_array( $dfiImages ) ) {
959
            $dfiImages = array_filter( $dfiImages );
960
961
            $count = 0;
962
            foreach ( $dfiImages as $dfiImage ) {
963
                $dfiImageTrimmed = self::_separate( $dfiImage );
964
                $dfiImageFull    = self::_separate( $dfiImage, 'full' );
965
966
                try {
967
968
                    $retImages[ $count ]['thumb']         = $this->_get_real_upload_path( $dfiImageTrimmed );
969
                    $retImages[ $count ]['full']          = $this->_get_real_upload_path( $dfiImageFull );
970
                    $retImages[ $count ]['attachment_id'] = $this->get_image_id( $retImages[ $count ]['full'] );
971
972
                } catch ( Exception $e ) { /* Ignore the exception and continue with other featured images */
973
                }
974
975
                $count ++;
976
            }
977
        }
978
979
        return $retImages;
980
981
    } // END get_featured_images()
982
983
    /**
984
     * Check to see if the upload url is already available in path.
985
     *
986
     * @since  3.1.14
987
     * @access protected
988
     *
989
     * @param  string $img
990
     *
991
     * @return string
992
     */
993
    protected function _get_real_upload_path( $img )
994
    {
995
        //check if upload path is already attached
996
        if ( strpos( $img, $this->__upload_url ) !== false || preg_match( '/https?:\/\//', $img ) ) {
997
            return $img;
998
        }
999
1000
        return $this->__upload_url . $img;
1001
    } // END _get_real_upload_path()
1002
1003
    /**
1004
     * Retrieve featured images for specific post(s) including the default Featured Image
1005
     *
1006
     * @since 3.1.7
1007
     * @access public
1008
     *
1009
     * @see  $this->get_featured_images()
1010
     *
1011
     * @param Integer $post_id id of the current post
1012
     *
1013
     * @return Array An array of images or an empty array on failure
1014
     */
1015
    public function get_all_featured_images( $post_id = null )
1016
    {
1017
        if ( is_null( $post_id ) ) {
1018
            global $post;
1019
            $post_id = $post->ID;
1020
        }
1021
1022
        $thumbnail_id = get_post_thumbnail_id( $post_id );
1023
1024
        $featured_image_array = array();
1025
        if ( ! empty( $thumbnail_id ) ) {
1026
            $featured_image         = array(
1027
                    'thumb'         => wp_get_attachment_thumb_url( $thumbnail_id ),
1028
                    'full'          => wp_get_attachment_url( $thumbnail_id ),
1029
                    'attachment_id' => $thumbnail_id
1030
            );
1031
            $featured_image_array[] = $featured_image;
1032
        }
1033
1034
        $dfiImages = $this->get_featured_images( $post_id );
1035
1036
        $all_featured_images = array_merge( $featured_image_array, $dfiImages );
1037
1038
        return $all_featured_images;
1039
1040
    }
1041
1042
    /**
1043
     * Load the plugin's textdomain hooked to 'plugins_loaded'.
1044
     *
1045
     * @since 1.0.0
1046
     * @access public
1047
     *
1048
     * @see    load_plugin_textdomain()
1049
     * @see    plugin_basename()
1050
     * @action    plugins_loaded
1051
     *
1052
     * @codeCoverageIgnore
1053
     *
1054
     * @return    void
1055
     */
1056
    public function load_plugin_textdomain()
1057
    {
1058
        load_plugin_textdomain(
1059
                $this->_textDomain,
1060
                false,
1061
                dirname( plugin_basename( __FILE__ ) ) . '/languages/'
1062
        );
1063
1064
    } // END load_plugin_textdomain()
1065
1066
} // END class Dynamic_Featured_Image
1067
1068
1069
/**
1070
 * Instantiate the main class
1071
 *
1072
 * @since 1.0.0
1073
 * @access public
1074
 *
1075
 * @var    object $dynamic_featured_image holds the instantiated class {@uses Dynamic_Featured_Image}
1076
 */
1077
global $dynamic_featured_image;
1078
$dynamic_featured_image = new Dynamic_Featured_Image();
1079