Completed
Push — master ( 6020f8...c4ee7b )
by Ankit
01:48
created

Dynamic_Featured_Image::get_featured_box()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 8
nop 5
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: https://ankitpokhrel.com
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
 * @package dynamic-featured-image
17
 *
18
 * Copyright (C) 2013 Ankit Pokhrel <[email protected], https://ankitpokhrel.com>
19
 *
20
 * This program is free software; you can redistribute it and/or modify
21
 * it under the terms of the GNU General Public License as published by
22
 * the Free Software Foundation; either version 3 of the License, or
23
 * (at your option) any later version.
24
 *
25
 * This program is distributed in the hope that it will be useful,
26
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28
 * GNU General Public License for more details.
29
 *
30
 * You should have received a copy of the GNU General Public License
31
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
32
 */
33
34
// Avoid direct calls to this file.
35
if ( ! defined( 'ABSPATH' ) ) {
36
    header( 'Status: 403 Forbidden' );
37
    header( 'HTTP/1.1 403 Forbidden' );
38
    exit();
39
}
40
41
/**
42
 * Dynamic Featured Image plugin main class.
43
 *
44
 * @package dynamic-featured-image
45
 * @author Ankit Pokhrel <[email protected]>
46
 * @version 3.0.1
47
 */
48
class Dynamic_Featured_Image {
49
    /**
50
     * Current version of the plugin.
51
     *
52
     * @since 3.0.0
53
     */
54
    const VERSION = '3.5.2';
55
56
    /**
57
     * Text domain.
58
     *
59
     * @since 3.6.0
60
     */
61
    const TEXT_DOMAIN = 'dynamic-featured-image';
62
63
    /**
64
     * Image upload directory.
65
     *
66
     * @var $upload_dir string
67
     */
68
    private $upload_dir;
69
70
    /**
71
     * Image upload URL.
72
     *
73
     * @var $upload_url string
74
     */
75
    private $upload_url;
76
77
    /**
78
     * Database object.
79
     *
80
     * @var $db wpdb
81
     */
82
    private $db;
83
84
    /**
85
     * Title for dfi metabox.
86
     *
87
     * @var $metabox_title string
88
     */
89
    protected $metabox_title;
90
91
    /**
92
     * Users post type filter for dfi metabox.
93
     *
94
     * @var $user_filter array
95
     */
96
    protected $user_filter;
97
98
    /**
99
     * Constructor. Hooks all interactions to initialize the class.
100
     *
101
     * @since 1.0.0
102
     * @access public
103
     * @global object $wpdb
104
     *
105
     * @see     add_action()
106
     */
107
    public function __construct() {
108
        // plugin update warning.
109
        add_action( 'in_plugin_update_message-' . plugin_basename( __FILE__ ), array( $this, 'update_notice' ) );
110
111
        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
112
        add_action( 'add_meta_boxes', array( $this, 'initialize_featured_box' ) );
113
        add_action( 'save_post', array( $this, 'save_meta' ) );
114
        add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
115
116
        // handle ajax request.
117
        add_action( 'wp_ajax_dfiMetaBox_callback', array( $this, 'ajax_callback' ) );
118
119
        // add action links.
120
        add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'dfi_action_links' ) );
121
122
        // media uploader custom fields.
123
        add_filter( 'attachment_fields_to_edit', array( $this, 'media_attachment_custom_fields' ), 10, 2 );
124
        add_filter( 'attachment_fields_to_save', array( $this, 'media_attachment_custom_fields_save' ), 10, 2 );
125
126
        // get the site protocol.
127
        $protocol = $this->get_protocol();
128
129
        $this->upload_dir = wp_upload_dir();
130
        $this->upload_url = preg_replace( '#^https?://#', '', $this->upload_dir['baseurl'] );
131
132
        // add protocol to the upload url.
133
        $this->upload_url = $protocol . $this->upload_url;
134
135
        // post type filter added by user.
136
        $this->user_filter = array();
137
138
        global $wpdb;
139
        $this->db = $wpdb;
140
    }
141
142
    /**
143
     * Return site protocol.
144
     *
145
     * @since 3.5.1
146
     * @access public
147
     *
148
     * @return string
149
     */
150
    private function get_protocol() {
0 ignored issues
show
Coding Style introduced by
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...
151
        return ( ( ! empty( $_SERVER['HTTPS'] ) && 'off' !== $_SERVER['HTTPS'] ) ||
152
                 ( ! empty( $_SERVER['SERVER_PORT'] ) && 443 === $_SERVER['SERVER_PORT'] ) ) ? 'https://' : 'http://';
153
    }
154
155
    /**
156
     * Add required admin scripts.
157
     *
158
     * @since 1.0.0
159
     * @access public
160
     *
161
     * @see  wp_enque_style()
162
     * @see  wp_register_script()
163
     * @see  wp_enqueue_script()
164
     *
165
     * @return void
166
     */
167
    public function enqueue_admin_scripts() {
168
        // enqueue styles.
169
        wp_enqueue_style( 'style-dfi', plugins_url( '/css/style-dfi.css', __FILE__ ), array(), self::VERSION );
170
        wp_enqueue_style( 'dashicons', plugins_url( '/css/dashicons.css', __FILE__ ), array(), self::VERSION );
171
172
        // register script.
173
        wp_register_script( 'scripts-dfi', plugins_url( '/js/script-dfi.js', __FILE__ ), array( 'jquery' ), self::VERSION );
174
175
        // localize the script with required data.
176
        wp_localize_script(
177
            'scripts-dfi',
178
            'WP_SPECIFIC',
179
            array(
180
                'upload_url'               => $this->upload_url,
181
                'metabox_title'            => __( $this->metabox_title, self::TEXT_DOMAIN ),
182
                'mediaSelector_title'      => __( 'Dynamic Featured Image - Media Selector', self::TEXT_DOMAIN ),
183
                'mediaSelector_buttonText' => __( 'Set Featured Image', self::TEXT_DOMAIN ),
184
            )
185
        );
186
187
        // enqueue scripts.
188
        wp_enqueue_script( 'scripts-dfi' );
189
    }
190
191
    /**
192
     * Add upgrade link.
193
     *
194
     * @access public
195
     * @since  3.5.1
196
     * @action plugin_action_links
197
     *
198
     * @codeCoverageIgnore
199
     *
200
     * @param  array $links Action links.
201
     *
202
     * @return array
203
     */
204
    public function dfi_action_links( $links ) {
205
        $upgrade_link = array(
206
            '<a href="https://ankitpokhrel.com/explore/downloads/dynamic-featured-image-pro/" target="_blank">Upgrade to Premium</a>'
207
        );
208
209
        return array_merge( $links, $upgrade_link );
210
    }
211
212
    /**
213
     * Add featured meta boxes dynamically.
214
     *
215
     * @since 1.0.0
216
     * @access public
217
     * @global object $post
218
     *
219
     * @see  get_post_meta()
220
     * @see  get_post_types()
221
     * @see  add_meta_box()
222
     * @see  add_filter()
223
     *
224
     * @return void
225
     */
226
    public function initialize_featured_box() {
227
        global $post;
228
229
        // make metabox title dynamic.
230
        $this->metabox_title = apply_filters( 'dfi_set_metabox_title', __( 'Featured Image', self::TEXT_DOMAIN ) );
231
232
        $featured_data  = get_post_meta( $post->ID, 'dfiFeatured', true );
233
        $total_featured = count( $featured_data );
234
235
        $default_filter    = array( 'attachment', 'revision', 'nav_menu_item' );
236
        $this->user_filter = apply_filters( 'dfi_post_type_user_filter', $this->user_filter );
237
        $filter            = array_merge( $default_filter, $this->user_filter );
238
239
        $post_types = get_post_types();
240
        $post_types = array_diff( $post_types, $filter );
241
242
        $post_types = apply_filters( 'dfi_post_types', $post_types );
243
244
        if ( ! empty( $featured_data ) && $total_featured >= 1 ) {
245
            $i = 2;
246
            foreach ( $featured_data as $featured ) {
247
                $this->dfi_add_meta_box( $post_types, $featured, $i );
248
                $i ++;
249
            }
250
        } else {
251
            $this->dfi_add_meta_box( $post_types );
252
        }
253
    }
254
255
    /**
256
     * Translates more than one digit number digit by digit.
257
     *
258
     * @param  int $number Integer to be translated.
259
     *
260
     * @return string Translated number
261
     */
262
    protected function get_number_translation( $number ) {
263
        if ( $number <= 9 ) {
264
            return __( $number, self::TEXT_DOMAIN );
265
        } else {
266
            $pieces = str_split( $number, 1 );
267
            $buffer = '';
268
            foreach ( $pieces as $piece ) {
269
                $buffer .= __( $piece, self::TEXT_DOMAIN );
270
            }
271
272
            return $buffer;
273
        }
274
    }
275
276
    /**
277
     * Adds meta boxes.
278
     *
279
     * @param  array  $post_types Post types to show featured image box.
280
     * @param  object $featured Callback arguments.
281
     * @param  int    $i Index of the featured image.
282
     *
283
     * @return void
284
     */
285
    private function dfi_add_meta_box( $post_types, $featured = null, $i = null ) {
286
        if ( ! is_null( $i ) ) {
287
            foreach ( $post_types as $type ) {
288
                add_meta_box(
289
                    'dfiFeaturedMetaBox-' . $i,
290
                    __( $this->metabox_title, self::TEXT_DOMAIN ) . ' ' . $this->get_number_translation( $i ),
291
                    array( $this, 'featured_meta_box' ),
292
                    $type,
293
                    'side',
294
                    'low',
295
                    array( $featured, $i + 1 )
296
                );
297
298
                add_filter( "postbox_classes_{$type}_dfiFeaturedMetaBox-" . $i, array( $this, 'add_metabox_classes' ) );
299
            }
300
        } else {
301
            foreach ( $post_types as $type ) {
302
                add_meta_box(
303
                    'dfiFeaturedMetaBox',
304
                    __( $this->metabox_title, self::TEXT_DOMAIN ) . ' ' . __( 2, self::TEXT_DOMAIN ),
305
                    array( $this, 'featured_meta_box' ),
306
                    $type,
307
                    'side',
308
                    'low',
309
                    array( null, null )
310
                );
311
312
                add_filter( "postbox_classes_{$type}_dfiFeaturedMetaBox", array( $this, 'add_metabox_classes' ) );
313
            }
314
        }
315
    }
316
317
    /**
318
     * Separate thumb and full image url from given URL string.
319
     *
320
     * @since  3.3.1
321
     *
322
     * @param  string $url_string Url string.
323
     * @param  string $state Thumb or full.
324
     *
325
     * @return string|null
326
     */
327
    private function separate( $url_string, $state = 'thumb' ) {
328
        $image_piece = explode( ',', $url_string );
329
330
        if ( 'thumb' === $state ) {
331
            return isset( $image_piece[0] ) ? $image_piece[0] : null;
332
        }
333
334
        return isset( $image_piece[1] ) ? $image_piece[1] : null;
335
    }
336
337
    /**
338
     * Create a nonce field
339
     *
340
     * @since  3.5.0
341
     *
342
     * @see  wp_nonce_field()
343
     * @see  plugin_basename()
344
     *
345
     * @codeCoverageIgnore
346
     *
347
     * @param  string $key Nonce key.
348
     *
349
     * @return string
350
     */
351
    protected function nonce_field( $key ) {
352
        return wp_nonce_field( plugin_basename( __FILE__ ), $key, true, false );
353
    }
354
355
    /**
356
     * Featured meta box as seen in the admin
357
     *
358
     * @since 1.0.0
359
     * @access public
360
     *
361
     * @param  object $post Global post object.
362
     * @param  array  $featured Array containing featured image count.
363
     *
364
     * @throws Exception Medium size image not found.
365
     * @return void
366
     */
367
    public function featured_meta_box( $post, $featured ) {
368
        $featured_img         = $featured['args'][0];
369
        $featured_id          = is_null( $featured['args'][1] ) ? 2 : --$featured['args'][1];
370
        $featured_img_full    = $featured_img;
371
        $featured_img_trimmed = $featured_img;
372
373
        if ( ! is_null( $featured_img ) ) {
374
            $featured_img_trimmed = $this->separate( $featured_img );
375
            $featured_img_full    = $this->separate( $featured_img, 'full' );
376
        }
377
378
        try {
379
            $thumbnail = $this->get_image_thumb( $this->upload_url . $featured_img_full, 'medium' );
380
            if ( is_null( $thumbnail ) ) {
381
                // medium sized thumbnail image is missing.
382
                throw new Exception( 'Medium size image not found', 1 );
383
            }
384
        } catch ( Exception $e ) {
385
            // since medium sized thumbnail image was not found,
386
            // let's set full image url as thumbnail.
387
            $thumbnail = $featured_img_full;
388
        }
389
390
        // Add a nonce field.
391
        echo $this->nonce_field( 'dfi_fimageplug-' . $featured_id );
392
        echo $this->get_featured_box( $featured_img_trimmed, $featured_img, $featured_id, $thumbnail, $post->ID );
393
    }
394
395
    /**
396
     * Returns featured box html content.
397
     *
398
     * @since  3.1.0
399
     * @access private
400
     *
401
     * @param string $featured_img_trimmed Medium sized image.
402
     * @param string $featured_img Full sized image.
403
     * @param string $featured_id Attachment Id.
404
     * @param string $thumbnail Thumb sized image.
405
     * @param int    $post_id Post id.
406
     *
407
     * @return string Html content
408
     */
409
    private function get_featured_box( $featured_img_trimmed, $featured_img, $featured_id, $thumbnail, $post_id ) {
410
        $has_featured_image = ! empty( $featured_img_trimmed ) ? 'hasFeaturedImage' : '';
411
        $thumbnail          = ! is_null( $thumbnail ) ? $thumbnail : '';
412
        $dfi_empty          = is_null( $featured_img_trimmed ) ? 'dfiImgEmpty' : '';
413
414
        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/>
415
            <img src='" . $thumbnail . "' class='dfiImg {$dfi_empty}'/>
416
            <div class='dfiLinks'>
417
                <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>
418
                <a href='javascript:void(0)' class='dfiRemove dashicons dashicons-minus' title='" . __( 'Remove', self::TEXT_DOMAIN ) . "'></a>
419
            </div>
420
            <div class='dfiClearFloat'></div>
421
            <input type='hidden' name='dfiFeatured[]' value='{$featured_img}'  class='dfiImageHolder' />";
422
    }
423
424
    /**
425
     * Load new featured meta box via ajax
426
     *
427
     * @since 1.0.0
428
     * @access public
429
     *
430
     * @return void
431
     */
432
    public function ajax_callback() {
433
        $featured_id = isset( $_POST['id'] ) ? (int) strip_tags( trim( $_POST['id'] ) ) : null;
434
435
        if ( is_null( $featured_id ) ) {
436
            return;
437
        }
438
439
        echo $this->nonce_field( 'dfi_fimageplug-' . $featured_id );
440
        ?>
441
        <a href="javascript:void(0)" class="dfiFeaturedImage"
442
           title="<?php echo __( 'Set Featured Image', self::TEXT_DOMAIN ) ?>"><span
443
                    class="dashicons dashicons-camera"></span></a><br/>
444
        <img src="" class="dfiImg dfiImgEmpty"/>
445
        <div class="dfiLinks">
446
            <a href="javascript:void(0)" data-id="<?php echo $featured_id ?>"
447
               data-id-local="<?php echo $this->get_number_translation( $featured_id + 1 ) ?>"
448
               class="dfiAddNew dashicons dashicons-plus" title="<?php echo __( 'Add New', self::TEXT_DOMAIN ) ?>"></a>
449
            <a href="javascript:void(0)" class="dfiRemove dashicons dashicons-minus"
450
               title="<?php echo __( 'Remove', self::TEXT_DOMAIN ) ?>"></a>
451
        </div>
452
        <div class="dfiClearFloat"></div>
453
        <input type="hidden" name="dfiFeatured[]" value="" class="dfiImageHolder"/>
454
        <?php
455
        wp_die( '' );
456
    }
457
458
    /**
459
     * Add custom class 'featured-meta-box' to meta box.
460
     *
461
     * @since 1.0.0
462
     * @access public
463
     *
464
     * @see  add_metabox_classes
465
     *
466
     * @param array $classes Classes to add in the meta box.
467
     *
468
     * @return array
469
     */
470
    public function add_metabox_classes( $classes ) {
471
        array_push( $classes, 'featured-meta-box' );
472
473
        return $classes;
474
    }
475
476
    /**
477
     * Add custom fields in media uploader.
478
     *
479
     * @since  3.4.0
480
     *
481
     * @param array $form_fields Fields to include in media attachment form.
482
     * @param array $post Post data.
483
     *
484
     * @return array
485
     */
486
    public function media_attachment_custom_fields( $form_fields, $post ) {
487
        $form_fields['dfi-link-to-image'] = array(
488
            'label' => __( 'Link to Image', self::TEXT_DOMAIN ),
489
            'input' => 'text',
490
            'value' => get_post_meta( $post->ID, '_dfi_link_to_image', true ),
491
        );
492
493
        return $form_fields;
494
    }
495
496
    /**
497
     * Save values of media uploader custom fields.
498
     *
499
     * @since 3.4.0
500
     *
501
     * @param array $post Post data for database.
502
     * @param array $attachment Attachment fields from $_POST form.
503
     *
504
     * @return array
505
     */
506
    public function media_attachment_custom_fields_save( $post, $attachment ) {
507
        if ( isset( $attachment['dfi-link-to-image'] ) ) {
508
            update_post_meta( $post['ID'], '_dfi_link_to_image', $attachment['dfi-link-to-image'] );
509
        }
510
511
        return $post;
512
    }
513
514
    /**
515
     * Update featured images in the database.
516
     *
517
     * @since 1.0.0
518
     * @access public
519
     *
520
     * @see  plugin_basename()
521
     * @see  update_post_meta()
522
     * @see  current_user_can()
523
     *
524
     * @param  int $post_id Current post id.
525
     *
526
     * @return bool
527
     */
528
    public function save_meta( $post_id ) {
529
        // Check auto save.
530
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
531
            return false;
532
        }
533
534
        if ( $this->verify_nonces() ) {
535
            // Check permission before saving data.
536
            if ( current_user_can( 'edit_posts', $post_id ) && isset( $_POST['dfiFeatured'] ) ) {
537
                update_post_meta( $post_id, 'dfiFeatured', $_POST['dfiFeatured'] );
538
            }
539
        }
540
541
        return false;
542
    }
543
544
    /**
545
     * Verify metabox nonces.
546
     *
547
     * @access protected
548
     * @see  wp_verify_nonce()
549
     *
550
     * @return bool
551
     */
552
    protected function verify_nonces() {
0 ignored issues
show
Coding Style introduced by
verify_nonces uses the super-global variable $_POST 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...
553
        $keys = array_keys( $_POST );
554
        foreach ( $keys as $key ) {
555
            if ( preg_match( '/dfi_fimageplug-\d+$/', $key ) ) {
556
                // Verify nonce.
557
                if ( ! wp_verify_nonce( $_POST[ $key ], plugin_basename( __FILE__ ) ) ) {
558
                    return false;
559
                }
560
            }
561
        }
562
563
        return true;
564
    }
565
566
    /**
567
     * Add update notice. Displayed in plugin update page.
568
     *
569
     * @since 2.0.0
570
     * @access public
571
     *
572
     * @return void
573
     */
574
    public function update_notice() {
575
        $info = __( 'ATTENTION! Please read the <a href="https://github.com/ankitpokhrel/Dynamic-Featured-Image/wiki" target="_blank">DOCUMENTATION</a> properly before update.', self::TEXT_DOMAIN );
576
        echo '<div style="color:red; padding:7px 0;">' . strip_tags( $info, '<a><b><i><span>' ) . '</div>';
577
    }
578
579
    /**
580
     * Execute query.
581
     *
582
     * @param string $query Query to execute.
583
     *
584
     * @return null|string
585
     */
586
    private function execute_query( $query ) {
587
        return $this->db->get_var( $query );
588
    }
589
590
    /**
591
     * Get attachment id of the image by image url.
592
     *
593
     * @since 3.1.7
594
     * @access protected
595
     * @global object $wpdb
596
     *
597
     * @param  string $image_url URL of an image.
598
     *
599
     * @return string
600
     */
601
    protected function get_attachment_id( $image_url ) {
602
        return self::execute_query( $this->db->prepare( 'SELECT ID FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
603
    }
604
605
    /**
606
     * Get image url of the image by attachment id.
607
     *
608
     * @since 2.0.0
609
     * @access public
610
     *
611
     * @see  wp_get_attachment_image_src()
612
     *
613
     * @param  int    $attachment_id attachment id of an image.
614
     * @param  string $size size of the image to fetch (thumbnail, medium, full).
615
     *
616
     * @return string
617
     */
618
    public function get_image_url( $attachment_id, $size = 'full' ) {
619
        $image_thumb = wp_get_attachment_image_src( $attachment_id, $size );
620
621
        return empty( $image_thumb ) ? null : $image_thumb[0];
622
    }
623
624
    /**
625
     * Get image thumbnail url of specific size by image url.
626
     *
627
     * @since 2.0.0
628
     * @access public
629
     *
630
     * @see  get_image_id()
631
     * @see  wp_get_attachment_image_src()
632
     *
633
     * @param  string $image_url url of an image.
634
     * @param  string $size size of the image to fetch (thumbnail, medium, full).
635
     *
636
     * @return string
637
     */
638
    public function get_image_thumb( $image_url, $size = 'thumbnail' ) {
639
        $attachment_id = $this->get_image_id( $image_url );
640
        $image_thumb   = wp_get_attachment_image_src( $attachment_id, $size );
641
642
        return empty( $image_thumb ) ? null : $image_thumb[0];
643
    }
644
645
    /**
646
     * Gets attachment id from given image url.
647
     *
648
     * @param  string $image_url url of an image.
649
     *
650
     * @since  2.0.0
651
     * @access public
652
     *
653
     * @return int|null attachment id of an image
654
     */
655
    public function get_image_id( $image_url ) {
656
        $attachment_id = $this->get_attachment_id( $image_url );
657
658
        if ( is_null( $attachment_id ) ) {
659
            // check if the image is edited image.
660
            // and try to get the attachment id.
661
            $image_url = str_replace( $this->upload_url . '/', '', $image_url );
662
            $row       = self::execute_query( $this->db->prepare( 'SELECT post_id FROM ' . $this->db->postmeta . ' WHERE meta_value = %s', $image_url ) );
663
            if ( ! is_null( $row ) ) {
664
                $attachment_id = $row;
665
            }
666
        }
667
668
        return $attachment_id;
669
    }
670
671
    /**
672
     * Get image title.
673
     *
674
     * @since 2.0.0
675
     * @access public
676
     *
677
     * @param string $image_url URL of an image.
678
     *
679
     * @return string
680
     */
681
    public function get_image_title( $image_url ) {
682
        return self::execute_query( $this->db->prepare( 'SELECT post_title FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
683
    }
684
685
    /**
686
     * Get image title by id.
687
     *
688
     * @since 2.0.0
689
     * @access public
690
     *
691
     * @param  int $attachment_id Attachment id of an image.
692
     *
693
     * @return string
694
     */
695
    public function get_image_title_by_id( $attachment_id ) {
696
        return self::execute_query( $this->db->prepare( 'SELECT post_title FROM ' . $this->db->posts . ' WHERE ID = %d', $attachment_id ) );
697
    }
698
699
    /**
700
     * Get image caption.
701
     *
702
     * @since 2.0.0
703
     * @access public
704
     *
705
     * @param  string $image_url URL of an image.
706
     *
707
     * @return string
708
     */
709
    public function get_image_caption( $image_url ) {
710
        return self::execute_query( $this->db->prepare( 'SELECT post_excerpt FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
711
    }
712
713
    /**
714
     * Get image caption by id.
715
     *
716
     * @since 2.0.0
717
     * @access public
718
     *
719
     * @param  int $attachment_id Attachment id of an image.
720
     *
721
     * @return string
722
     */
723
    public function get_image_caption_by_id( $attachment_id ) {
724
        return self::execute_query( $this->db->prepare( 'SELECT post_excerpt FROM ' . $this->db->posts . ' WHERE ID = %d', $attachment_id ) );
725
    }
726
727
    /**
728
     * Get image alternate text.
729
     *
730
     * @since 2.0.0
731
     * @access public
732
     *
733
     * @see  get_post_meta()
734
     *
735
     * @param  string $image_url URL of an image.
736
     *
737
     * @return string
738
     */
739
    public function get_image_alt( $image_url ) {
740
        $attachment = $this->db->get_col( $this->db->prepare( 'SELECT ID FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
741
742
        $alt = null;
743
        if ( ! empty( $attachment ) ) {
744
            $alt = get_post_meta( $attachment[0], '_wp_attachment_image_alt' );
745
        }
746
747
        return ( is_null( $alt ) || empty( $alt ) ) ? null : $alt[0];
748
    }
749
750
    /**
751
     * Get image alternate text by attachment id.
752
     *
753
     * @since 2.0.0
754
     * @access public
755
     *
756
     * @see  get_post_meta()
757
     *
758
     * @param  int $attachment_id Attachment id of an image.
759
     *
760
     * @return string
761
     */
762
    public function get_image_alt_by_id( $attachment_id ) {
763
        $alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt' );
764
765
        return empty( $alt ) ? null : $alt[0];
766
    }
767
768
    /**
769
     * Get image description.
770
     *
771
     * @since 3.0.0
772
     * @access public
773
     *
774
     * @param  string $image_url URL of an image.
775
     *
776
     * @return string
777
     */
778
    public function get_image_description( $image_url ) {
779
        return self::execute_query( $this->db->prepare( 'SELECT post_content FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
780
    }
781
782
    /**
783
     * Get image description by id.
784
     *
785
     * @since 3.0.0
786
     * @access public
787
     *
788
     * @param  int $attachment_id attachment id of an image.
789
     *
790
     * @return string
791
     */
792
    public function get_image_description_by_id( $attachment_id ) {
793
        return self::execute_query( $this->db->prepare( 'SELECT post_content FROM ' . $this->db->posts . ' WHERE ID = %d', $attachment_id ) );
794
    }
795
796
    /**
797
     * Get link to image.
798
     *
799
     * @since 3.4.0
800
     * @access public
801
     *
802
     * @param  int $attachment_id Attachment id of an image.
803
     *
804
     * @return string|null
805
     */
806
    public function get_link_to_image( $attachment_id ) {
807
        return get_post_meta( $attachment_id, '_dfi_link_to_image', true );
808
    }
809
810
    /**
811
     * Get all attachment ids of the post.
812
     *
813
     * @since 2.0.0
814
     * @access public
815
     *
816
     * @see  get_post_meta()
817
     *
818
     * @param  int $post_id id of the current post.
819
     *
820
     * @return array
821
     */
822
    public function get_post_attachment_ids( $post_id ) {
823
        $dfi_images = get_post_meta( $post_id, 'dfiFeatured', true );
824
        $ret_val    = array();
825
826
        if ( ! empty( $dfi_images ) && is_array( $dfi_images ) ) {
827
            foreach ( $dfi_images as $dfi_image ) {
828
                $dfi_image_full = $this->separate( $dfi_image, 'full' );
829
                $ret_val[]     = $this->get_image_id( $this->upload_url . $dfi_image_full );
830
            }
831
        }
832
833
        return $ret_val;
834
    }
835
836
    /**
837
     * Fetches featured image data of nth position.
838
     *
839
     * @since  3.0.0
840
     * @access  public
841
     *
842
     * @see  get_featured_images()
843
     *
844
     * @param  int $position Position of the featured image.
845
     * @param  int $post_id Current post id.
846
     *
847
     * @return array if found, null otherwise.
848
     */
849
    public function get_nth_featured_image( $position, $post_id = null ) {
850
        if ( is_null( $post_id ) ) {
851
            global $post;
852
            $post_id = $post->ID;
853
        }
854
855
        $featured_images = $this->get_featured_images( $post_id );
856
857
        return isset( $featured_images[ $position - 2 ] ) ? $featured_images[ $position - 2 ] : null;
858
    }
859
860
    /**
861
     * Check if the image is attached with the particular post.
862
     *
863
     * @since 2.0.0
864
     * @access public
865
     *
866
     * @see  get_post_attachment_ids()
867
     *
868
     * @param  int $attachment_id Attachment id of an image.
869
     * @param  int $post_id Current post id.
870
     *
871
     * @return bool
872
     */
873
    public function is_attached( $attachment_id, $post_id ) {
874
        if ( empty( $attachment_id ) ) {
875
            return false;
876
        }
877
878
        $attachment_ids = $this->get_post_attachment_ids( $post_id );
879
880
        return in_array( $attachment_id, $attachment_ids, true ) ? true : false;
881
    }
882
883
    /**
884
     * Retrieve featured images for specific post(s).
885
     *
886
     * @since 2.0.0
887
     * @access public
888
     *
889
     * @see get_post_meta()
890
     *
891
     * @param  integer $post_id id of the current post.
892
     *
893
     * @return array
894
     */
895
    public function get_featured_images( $post_id = null ) {
896
        if ( is_null( $post_id ) ) {
897
            global $post;
898
899
            $post_id = $post->ID;
900
        }
901
902
        $dfi_images = get_post_meta( $post_id, 'dfiFeatured', true );
903
        $ret_images = array();
904
905
        if ( ! empty( $dfi_images ) && is_array( $dfi_images ) ) {
906
            $dfi_images = array_filter( $dfi_images );
907
908
            $count = 0;
909
            foreach ( $dfi_images as $dfi_image ) {
910
                $dfi_image_trimmed = $this->separate( $dfi_image );
911
                $dfi_image_full    = $this->separate( $dfi_image, 'full' );
912
913
                try {
914
                    $ret_images[ $count ]['thumb']         = $this->get_real_upload_path( $dfi_image_trimmed );
915
                    $ret_images[ $count ]['full']          = $this->get_real_upload_path( $dfi_image_full );
916
                    $ret_images[ $count ]['attachment_id'] = $this->get_image_id( $ret_images[ $count ]['full'] );
917
918
                } catch ( Exception $e ) {
919
                    /* Ignore the exception and continue with other featured images */
920
                }
921
922
                $count ++;
923
            }
924
        }
925
926
        return $ret_images;
927
    }
928
929
    /**
930
     * Check to see if the upload url is already available in path.
931
     *
932
     * @since  3.1.14
933
     * @access protected
934
     *
935
     * @param  string $img Uploaded image.
936
     *
937
     * @return string
938
     */
939
    protected function get_real_upload_path( $img ) {
940
        // check if upload path is already attached.
941
        if ( false !== strpos( $img, $this->upload_url ) || preg_match( '/https?:\/\//', $img ) ) {
942
            return $img;
943
        }
944
945
        return $this->upload_url . $img;
946
    }
947
948
    /**
949
     * Retrieve featured images for specific post(s) including the default Featured Image.
950
     *
951
     * @since 3.1.7
952
     * @access public
953
     *
954
     * @see  $this->get_featured_images()
955
     *
956
     * @param int $post_id Current post id.
957
     *
958
     * @return array An array of images or an empty array on failure
959
     */
960
    public function get_all_featured_images( $post_id = null ) {
961
        if ( is_null( $post_id ) ) {
962
            global $post;
963
964
            $post_id = $post->ID;
965
        }
966
967
        $thumbnail_id         = get_post_thumbnail_id( $post_id );
968
        $featured_image_array = array();
969
970
        if ( ! empty( $thumbnail_id ) ) {
971
            $featured_image         = array(
972
                'thumb'         => wp_get_attachment_thumb_url( $thumbnail_id ),
973
                'full'          => wp_get_attachment_url( $thumbnail_id ),
974
                'attachment_id' => $thumbnail_id,
975
            );
976
977
            $featured_image_array[] = $featured_image;
978
        }
979
980
        return array_merge( $featured_image_array, $this->get_featured_images( $post_id ) );
981
    }
982
983
    /**
984
     * Load the plugin's textdomain hooked to 'plugins_loaded'.
985
     *
986
     * @since 1.0.0
987
     * @access public
988
     *
989
     * @see    load_plugin_textdomain()
990
     * @see    plugin_basename()
991
     * @action plugins_loaded
992
     *
993
     * @codeCoverageIgnore
994
     *
995
     * @return void
996
     */
997
    public function load_plugin_textdomain() {
998
        load_plugin_textdomain(
999
            self::TEXT_DOMAIN,
1000
            false,
1001
            dirname( plugin_basename( __FILE__ ) ) . '/languages/'
1002
        );
1003
    }
1004
}
1005
1006
/**
1007
 * Instantiate the main class.
1008
 *
1009
 * @since 1.0.0
1010
 * @access public
1011
 *
1012
 * @var object $dynamic_featured_image holds the instantiated class {@uses Dynamic_Featured_Image}
1013
 */
1014
global $dynamic_featured_image;
1015
$dynamic_featured_image = new Dynamic_Featured_Image();
1016