Completed
Pull Request — master (#86)
by
unknown
02:09
created

Dynamic_Featured_Image::get_link_to_image()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
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.7.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-2019 Ankit Pokhrel <[email protected], 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
21
 * the Free Software Foundation; either version 3 of the License, or
22
 * (at your option) any later version.
23
 *
24
 * This program is distributed in the hope that it will be useful,
25
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
 * GNU General Public License for more details.
28
 *
29
 * You should have received a copy of the GNU General Public License
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 <[email protected]>
44
 * @version 3.7.0
45
 */
46
class Dynamic_Featured_Image {
47
    /**
48
     * Current version of the plugin.
49
     *
50
     * @since 3.0.0
51
     */
52
    const VERSION = '3.7.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
     * Image upload directory.
70
     *
71
     * @var $upload_dir string
72
     */
73
    private $upload_dir;
74
75
    /**
76
     * Image upload URL.
77
     *
78
     * @var $upload_url string
79
     */
80
    private $upload_url;
81
82
    /**
83
     * Database object.
84
     *
85
     * @var $db wpdb
86
     */
87
    private $db;
88
89
    /**
90
     * Title for dfi metabox.
91
     *
92
     * @var $metabox_title string
93
     */
94
    protected $metabox_title;
95
96
    /**
97
     * Users post type filter for dfi metabox.
98
     *
99
     * @var $user_filter array
100
     */
101
    protected $user_filter;
102
103
    /**
104
     * Constructor. Hooks all interactions to initialize the class.
105
     *
106
     * @since 1.0.0
107
     * @access public
108
     * @global object $wpdb
109
     *
110
     * @see     add_action()
111
     */
112 1
    public function __construct() {
113
        // plugin update warning.
114 1
        add_action( 'in_plugin_update_message-' . plugin_basename( __FILE__ ), array( $this, 'update_notice' ) );
115
116 1
        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
117 1
        add_action( 'add_meta_boxes', array( $this, 'initialize_featured_box' ) );
118 1
        add_action( 'save_post', array( $this, 'save_meta' ) );
119 1
        add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
120
121
        // handle ajax request.
122 1
        add_action( 'wp_ajax_dfiMetaBox_callback', array( $this, 'ajax_callback' ) );
123
124
        // media uploader custom fields.
125 1
        add_filter( 'attachment_fields_to_edit', array( $this, 'media_attachment_custom_fields' ), 10, 2 );
126 1
        add_filter( 'attachment_fields_to_save', array( $this, 'media_attachment_custom_fields_save' ), 10, 2 );
127
128
        // plugin sponsors.
129 1
        new PluginSponsor();
130
131
        // get the site protocol.
132 1
        $protocol = $this->get_protocol();
133
134 1
        $this->upload_dir = wp_upload_dir();
135 1
        $this->upload_url = preg_replace( '#^https?://#', '', $this->upload_dir['baseurl'] );
136
137
        // add protocol to the upload url.
138 1
        $this->upload_url = $protocol . $this->upload_url;
139
140
        // post type filter added by user.
141 1
        $this->user_filter = array();
142
143 1
        global $wpdb;
144 1
        $this->db = $wpdb;
145 1
    }
146
147
    /**
148
     * Return site protocol.
149
     *
150
     * @since 3.5.1
151
     * @access public
152
     *
153
     * @return string
154
     */
155
    private function get_protocol() {
156
        return is_ssl() ? 'https://' : 'http://';
157
    }
158
159
    /**
160
     * Add required admin scripts.
161
     *
162
     * @since 1.0.0
163
     * @access public
164
     *
165
     * @see  wp_enqueue_style()
166
     * @see  wp_register_script()
167
     * @see  wp_enqueue_script()
168
     *
169
     * @return void
170
     */
171 1
    public function enqueue_admin_scripts() {
172
        // enqueue styles.
173 1
        wp_enqueue_style( 'style-dfi', plugins_url( '/css/style-dfi.css', __FILE__ ), array(), self::VERSION );
174
175
        // register script.
176 1
        wp_register_script( 'scripts-dfi', plugins_url( '/js/script-dfi.js', __FILE__ ), array( 'jquery' ), self::VERSION );
177
178
        // localize the script with required data.
179 1
        wp_localize_script(
180 1
            'scripts-dfi',
181 1
            'DFI_SPECIFIC',
182
            array(
183 1
                'upload_url'               => $this->upload_url,
184 1
                'metabox_title'            => __( $this->metabox_title, self::TEXT_DOMAIN ),
185 1
                'mediaSelector_title'      => __( 'Dynamic Featured Image - Media Selector', self::TEXT_DOMAIN ),
186 1
                'mediaSelector_buttonText' => __( 'Set Featured Image', self::TEXT_DOMAIN ),
187 1
                'ajax_nonce'               => wp_create_nonce( plugin_basename( __FILE__ ) ),
188
            )
189 1
        );
190
191
        // enqueue scripts.
192 1
        wp_enqueue_script( 'scripts-dfi' );
193 1
    }
194
195
    /**
196
     * Add featured meta boxes dynamically.
197
     *
198
     * @since 1.0.0
199
     * @access public
200
     * @global object $post
201
     *
202
     * @see  get_post_meta()
203
     * @see  get_post_types()
204
     * @see  add_meta_box()
205
     * @see  add_filter()
206
     *
207
     * @return void
208
     */
209
    public function initialize_featured_box() {
210
        global $post;
211
212
        // make metabox title dynamic.
213
        $this->metabox_title = apply_filters( 'dfi_set_metabox_title', __( 'Featured Image', self::TEXT_DOMAIN ) );
214
215
        $featured_data  = get_post_meta( $post->ID, 'dfiFeatured', true );
216
        $total_featured = is_array( $featured_data ) ? count( $featured_data ) : 0;
217
218
        $default_filter    = array( 'attachment', 'revision', 'nav_menu_item' );
219
        $this->user_filter = apply_filters( 'dfi_post_type_user_filter', $this->user_filter );
220
221
        $post_types = array_diff( get_post_types(), array_merge( $default_filter, $this->user_filter ) );
222
        $post_types = apply_filters( 'dfi_post_types', $post_types );
223
224
        if ( ! empty( $featured_data ) && $total_featured >= 1 ) {
225
            $i = 2;
226
            foreach ( $featured_data as $featured ) {
227
                if ( $i <= apply_filters("dfi_maximum_allowed_images", 999) )
228
                    $this->dfi_add_meta_box( $post_types, $featured, $i++ );
229
            }
230
        } else {
231
            $this->dfi_add_meta_box( $post_types );
232
        }
233
    }
234
235
    /**
236
     * Translates more than one digit number digit by digit.
237
     *
238
     * @param  int $number Integer to be translated.
239
     *
240
     * @return string Translated number
241
     */
242 3
    protected function get_number_translation( $number ) {
243 3
        if ( $number <= 9 ) {
244 2
            return __( $number, self::TEXT_DOMAIN );
245
        } else {
246 1
            $pieces = str_split( $number, 1 );
247 1
            $buffer = '';
248 1
            foreach ( $pieces as $piece ) {
249 1
                $buffer .= __( $piece, self::TEXT_DOMAIN );
250 1
            }
251
252 1
            return $buffer;
253
        }
254
    }
255
256
    /**
257
     * Adds meta boxes.
258
     *
259
     * @param  array  $post_types Post types to show featured image box.
260
     * @param  object $featured Callback arguments.
261
     * @param  int    $i Index of the featured image.
262
     *
263
     * @return void
264
     */
265
    private function dfi_add_meta_box( $post_types, $featured = null, $i = null ) {
266
        if ( ! is_null( $i ) ) {
267
            foreach ( $post_types as $type ) {
268
                add_meta_box(
269
                    'dfiFeaturedMetaBox-' . $i,
270
                    __( $this->metabox_title, self::TEXT_DOMAIN ) . ' ' . $this->get_number_translation( $i ),
271
                    array( $this, 'featured_meta_box' ),
272
                    $type,
273
                    apply_filters( 'dfi_metabox_context', 'side' ),
274
                    apply_filters( 'dfi_metabox_priority', 'low' ),
275
                    array( $featured, $i + 1 )
276
                );
277
278
                add_filter( "postbox_classes_{$type}_dfiFeaturedMetaBox-" . $i, array( $this, 'add_metabox_classes' ) );
279
            }
280
        } else {
281
            foreach ( $post_types as $type ) {
282
                add_meta_box(
283
                    'dfiFeaturedMetaBox',
284
                    __( $this->metabox_title, self::TEXT_DOMAIN ) . ' ' . __( 2, self::TEXT_DOMAIN ),
285
                    array( $this, 'featured_meta_box' ),
286
                    $type,
287
                    apply_filters( 'dfi_metabox_context', 'side' ),
288
                    apply_filters( 'dfi_metabox_priority', 'low' ),
289
                    array( null, null )
290
                );
291
292
                add_filter( "postbox_classes_{$type}_dfiFeaturedMetaBox", array( $this, 'add_metabox_classes' ) );
293
            }
294
        }
295
    }
296
297
    /**
298
     * Separate thumb and full image url from given URL string.
299
     *
300
     * @since  3.3.1
301
     *
302
     * @param  string $url_string Url string.
303
     * @param  string $state Thumb or full.
304
     *
305
     * @return string|null
306
     */
307 3
    private function separate( $url_string, $state = 'thumb' ) {
308 3
        $image_piece = explode( ',', sanitize_text_field($url_string) );
309
310 3
        if ( 'thumb' === $state ) {
311 2
            return isset( $image_piece[0] ) ? $image_piece[0] : null;
312
        }
313
314 3
        return isset( $image_piece[1] ) ? $image_piece[1] : null;
315
    }
316
317
    /**
318
     * Create a nonce field.
319
     *
320
     * @since  3.5.0
321
     *
322
     * @see  wp_nonce_field()
323
     * @see  plugin_basename()
324
     *
325
     * @codeCoverageIgnore
326
     *
327
     * @param  string $key Nonce key.
328
     *
329
     * @return string
330
     */
331
    protected function nonce_field( $key ) {
332
        return wp_nonce_field( plugin_basename( __FILE__ ), $key, true, false );
333
    }
334
335
    /**
336
     * Featured meta box as seen in the admin.
337
     *
338
     * @since 1.0.0
339
     * @access public
340
     *
341
     * @param  object $post Global post object.
342
     * @param  array  $featured Array containing featured image count.
343
     *
344
     * @throws Exception Medium size image not found.
345
     * @return void
346
     */
347 3
    public function featured_meta_box( $post, $featured ) {
348 3
        $featured_img         = sanitize_text_field($featured['args'][0]);
349 3
        $featured_id          = (int) (is_null( $featured['args'][1] ) ? 2 : --$featured['args'][1]);
350 3
        $featured_img_full    = $featured_img;
351 3
        $featured_img_trimmed = $featured_img;
352
353 3
        if ( ! is_null( $featured_img ) ) {
354 3
            $featured_img_trimmed = $this->separate( $featured_img );
355 3
            $featured_img_full    = $this->separate( $featured_img, 'full' );
356 3
        }
357
358 3
        $thumbnail     = null;
359 3
        $attachment_id = null;
360 3 View Code Duplication
        if ( ! empty( $featured_img_full ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
361 1
            $attachment_id = $this->get_image_id( $this->upload_url . $featured_img_full );
362
363 1
            $thumbnail = $this->get_image_thumb_by_attachment_id( $attachment_id, 'medium' );
364
365 1
            if ( empty( $thumbnail ) ) {
366
                // since medium sized thumbnail image is missing,
367
                // let's set full image url as thumbnail.
368
                $thumbnail = $featured_img_full;
369
            }
370 1
        }
371
372
        // Add a nonce field.
373 3
        echo $this->nonce_field( 'dfi_fimageplug-' . $featured_id ); // WPCS: XSS ok.
374 3
        echo $this->get_featured_box( $featured_img_trimmed, $featured_img, $featured_id, $thumbnail, $post->ID, $attachment_id ); // WPCS: XSS ok.
375 3
    }
376
377
    /**
378
     * Returns featured box html content.
379
     *
380
     * @since  3.1.0
381
     * @access private
382
     *
383
     * @param string $featured_img_trimmed Medium sized image.
384
     * @param string $featured_img         Full sized image.
385
     * @param string $featured_id          Featured id number for translation.
386
     * @param string $thumbnail            Thumb sized image.
387
     * @param int    $post_id              Post id.
388
     * @param int    $attachment_id        Attachment id.
389
     *
390
     * @return string Html content
391
     */
392 3
    private function get_featured_box( $featured_img_trimmed, $featured_img, $featured_id, $thumbnail, $post_id, $attachment_id ) {
393 3
		$featured_img		= sanitize_text_field($featured_img);
394 3
		$featured_id		= (int)$featured_id;
395 3
        $has_featured_image = ! empty( $featured_img_trimmed ) ? ' hasFeaturedImage' : '';
396 3
        $thumbnail          = sanitize_text_field(! is_null( $thumbnail ) ? $thumbnail : '');
397 3
        $dfi_empty          = is_null( $featured_img_trimmed ) ? 'dfiImgEmpty' : '';
398 3
        return "<a href='javascript:void(0)' class='dfiFeaturedImage{$has_featured_image}' title='" . __( 'Set Featured Image', self::TEXT_DOMAIN ) . "' data-post-id='" . $post_id . "' data-attachment-id='" . $attachment_id . "'><span class='dashicons dashicons-camera'></span></a><br/>
399 3
            <img src='" . $thumbnail . "' class='dfiImg {$dfi_empty}'/>
400
            <div class='dfiLinks'>
401 3
                <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>
402 3
                <a href='javascript:void(0)' class='dfiRemove dashicons dashicons-minus' title='" . __( 'Remove', self::TEXT_DOMAIN ) . "'></a>
403
            </div>
404
            <div class='dfiClearFloat'></div>
405 3
            <input type='hidden' name='dfiFeatured[]' value='{$featured_img}'  class='dfiImageHolder' />";
406
    }
407
408
    /**
409
     * Load new featured meta box via ajax.
410
     *
411
     * @since 1.0.0
412
     * @access public
413
     *
414
     * @return void
415
     */
416 2
    public function ajax_callback() {
417 2
        check_ajax_referer( plugin_basename( __FILE__ ), 'security' );
418
419 1
        $featured_id = isset( $_POST['id'] ) ? (int) ( wp_unslash( $_POST['id'] ) ) : null;
420
421 1
        if ( ! is_numeric( $featured_id ) ) {
422
            return;
423
        }
424
        
425 1
        $max_allowed = apply_filters("dfi_maximum_allowed_images", 999);
426
		
427 1
        if ( $featured_id > $max_allowed ) { 
428
            return "";
429
        }
430
		
431
        // @codingStandardsIgnoreStart
432 1
        echo $this->nonce_field( 'dfi_fimageplug-' . $featured_id );
433
        ?>
434
        <a href="javascript:void(0)" class="dfiFeaturedImage"
435
           title="<?php echo __( 'Set Featured Image', self::TEXT_DOMAIN ) ?>"><span
436
                    class="dashicons dashicons-camera"></span></a><br/>
437
        <img src="" class="dfiImg dfiImgEmpty"/>
438
        <div class="dfiLinks">
439
            <?php 
440
            if ( $featured_id < $max_allowed ) { ?>
441
                <a href="javascript:void(0)" data-id="<?php echo $featured_id ?>"
442
               data-id-local="<?php echo $this->get_number_translation( $featured_id + 1 ) ?>"
443
               class="dfiAddNew dashicons dashicons-plus" title="<?php echo __( 'Add New', self::TEXT_DOMAIN ) ?>"></a>
444
            <?php } ?>
445
            <a href="javascript:void(0)" class="dfiRemove dashicons dashicons-minus"
446
               title="<?php echo __( 'Remove', self::TEXT_DOMAIN ) ?>"></a>
447
        </div>
448
        <div class="dfiClearFloat"></div>
449
        <input type="hidden" name="dfiFeatured[]" value="" class="dfiImageHolder"/>
450
        <?php
451
        // @codingStandardsIgnoreEnd
452 1
        wp_die( '' );
453
    }
454
455
    /**
456
     * Add custom class 'featured-meta-box' to meta box.
457
     *
458
     * @since 1.0.0
459
     * @access public
460
     *
461
     * @see  add_metabox_classes
462
     *
463
     * @param array $classes Classes to add in the meta box.
464
     *
465
     * @return array
466
     */
467 1
    public function add_metabox_classes( $classes ) {
468 1
        array_push( $classes, 'featured-meta-box' );
469
470 1
        return $classes;
471
    }
472
473
    /**
474
     * Add custom fields in media uploader.
475
     *
476
     * @since  3.4.0
477
     *
478
     * @param array $form_fields Fields to include in media attachment form.
479
     * @param array $post Post data.
480
     *
481
     * @return array
482
     */
483 1
    public function media_attachment_custom_fields( $form_fields, $post ) {
484 1
        $form_fields['dfi-link-to-image'] = array(
485 1
            'label' => __( 'Link to Image', self::TEXT_DOMAIN ),
486 1
            'input' => 'text',
487 1
            'value' => get_post_meta( $post->ID, '_dfi_link_to_image', true ),
488
        );
489
490 1
        return $form_fields;
491
    }
492
493
    /**
494
     * Save values of media uploader custom fields.
495
     *
496
     * @since 3.4.0
497
     *
498
     * @param array $post Post data for database.
499
     * @param array $attachment Attachment fields from $_POST form.
500
     *
501
     * @return array
502
     */
503 1
    public function media_attachment_custom_fields_save( $post, $attachment ) {
504 1
        if ( isset( $attachment['dfi-link-to-image'] ) ) {
505 1
			$attachment['dfi-link-to-image'] = sanitize_text_field($attachment['dfi-link-to-image']);
506 1
            update_post_meta( $post['ID'], '_dfi_link_to_image', $attachment['dfi-link-to-image'] );
507 1
        }
508
509 1
        return $post;
510
    }
511
512
    /**
513
     * Update featured images in the database.
514
     *
515
     * @since 1.0.0
516
     * @access public
517
     *
518
     * @see  plugin_basename()
519
     * @see  update_post_meta()
520
     * @see  current_user_can()
521
     *
522
     * @param  int $post_id Current post id.
523
     *
524
     * @return bool|null
525
     */
526 2
    public function save_meta( $post_id ) {
527
        // Check auto save.
528 2
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
529 1
            return false;
530
        }
531
532 2
        if ( ! $this->verify_nonces() ) {
533 2
            return false;
534
        }
535
536
        // Check permission before saving data.
537 1
        if ( current_user_can( 'edit_posts', $post_id ) && isset( $_POST['dfiFeatured'] ) ) { // WPCS: CSRF ok.
538 1
            $featured_images = is_array( $_POST['dfiFeatured'] ) ? $_POST['dfiFeatured'] : array(); // WPCS: sanitization ok, CSRF ok.
539
540 1
            update_post_meta( $post_id, 'dfiFeatured', $this->sanitize_array( $featured_images ) );
541 1
        }
542 1
    }
543
544
    /**
545
     * Sanitize array.
546
     *
547
     * @since 3.6.0
548
     * @access protected
549
     *
550
     * @param array $input_array Input array.
551
     *
552
     * @return array
553
     */
554 1
    protected function sanitize_array( $input_array ) {
555 1
        $sanitized = array();
556
557 1
        foreach ( $input_array as $key=>$value ) {
558 1
            $sanitized[$key] = sanitize_text_field( wp_unslash( $value ) );
559 1
        }
560
561 1
        return $sanitized;
562
    }
563
564
    /**
565
     * Verify metabox nonces.
566
     *
567
     * @access protected
568
     * @see  wp_verify_nonce()
569
     *
570
     * @return bool
571
     */
572
    protected function verify_nonces() {
573
        $keys = preg_grep( '/dfi_fimageplug-\d+$/', array_keys( $_POST ) ); // WPCS: CSRF ok.
574
575
        if ( empty( $keys ) ) {
576
            return false;
577
        }
578
579
        foreach ( $keys as $key ) {
580
            // Verify nonce.
581
            if ( ! isset( $_POST[ $key ] ) ||
582
                 ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[ $key ] ) ), plugin_basename( __FILE__ ) )
583
            ) {
584
                return false;
585
            }
586
        }
587
588
        return true;
589
    }
590
591
    /**
592
     * Add update notice. Displayed in plugin update page.
593
     *
594
     * @since 2.0.0
595
     * @access public
596
     *
597
     * @return void
598
     */
599 1
    public function update_notice() {
600 1
        $info = __( 'ATTENTION! Please read the <a href="' . self::WIKI_LINK . '" target="_blank">DOCUMENTATION</a> properly before update.',
601 1
        self::TEXT_DOMAIN );
602
603 1
        echo '<span style="color: red; padding: 7px 0; display: block">' . strip_tags( $info, '<a><b><i><span>' ) . '</span>'; // WPCS: XSS ok.
604 1
    }
605
606
    /**
607
     * Execute query.
608
     *
609
     * @param string $query Query to execute.
610
     *
611
     * @return null|string
612
     */
613 6
    private function execute_query( $query ) {
614 6
        return $this->db->get_var( $query );
615
    }
616
617
    /**
618
     * Get attachment id of the image by image url.
619
     *
620
     * @since 3.1.7
621
     * @access protected
622
     * @global object $wpdb
623
     *
624
     * @param  string $image_url URL of an image.
625
     *
626
     * @return string
627
     */
628 1
    protected function get_attachment_id( $image_url ) {
629 1
        return (int) $this->execute_query( $this->db->prepare( 'SELECT ID FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
630
    }
631
632
    /**
633
     * Get image url of the image by attachment id.
634
     *
635
     * @since 2.0.0
636
     * @access public
637
     *
638
     * @see  wp_get_attachment_image_src()
639
     *
640
     * @param  int    $attachment_id attachment id of an image.
641
     * @param  string $size size of the image to fetch (thumbnail, medium, full).
642
     *
643
     * @return string
644
     */
645 1
    public function get_image_url( $attachment_id, $size = 'full' ) {
646 1
        $image_thumb = wp_get_attachment_image_src( $attachment_id, $size );
647
648 1
        return empty( $image_thumb ) ? null : sanitize_text_field( $image_thumb[0] );
649
    }
650
651
    /**
652
     * Get image thumbnail url of specific size by attachment id.
653
     *
654
     * @since 3.7.0
655
     * @access public
656
     *
657
     * @see wp_get_attachment_image_src()
658
     *
659
     * @param int $attachment_id attachment id of an image.
660
     * @param string $size size of the image to fetch (thumbnail, medium, full).
661
     *
662
     * @return string|null
663
     */
664 1
    public function get_image_thumb_by_attachment_id( $attachment_id, $size = 'thumbnail' ) {
665 1
        if ( empty( $attachment_id ) ) {
666
            return null;
667
        }
668
669 1
        $image_thumb = wp_get_attachment_image_src( $attachment_id, $size );
670
671 1
        return empty( $image_thumb ) ? null : sanitize_text_field( $image_thumb[0] );
672
    }
673
674
    /**
675
     * Get image thumbnail url of specific size by image url.
676
     *
677
     * @since 2.0.0
678
     * @access public
679
     *
680
     * @see  get_image_id()
681
     * @see  wp_get_attachment_image_src()
682
     *
683
     * @param  string $image_url url of an image.
684
     * @param  string $size size of the image to fetch (thumbnail, medium, full).
685
     *
686
     * @return string
687
     */
688 1
    public function get_image_thumb( $image_url, $size = 'thumbnail' ) {
689 1
        $attachment_id = $this->get_image_id( $image_url );
690 1
        $image_thumb   = wp_get_attachment_image_src( $attachment_id, $size );
691
692 1
        return empty( $image_thumb ) ? null : sanitize_text_field( $image_thumb[0] );
693
    }
694
695
    /**
696
     * Gets attachment id from given image url.
697
     *
698
     * @param  string $image_url url of an image.
699
     *
700
     * @since  2.0.0
701
     * @access public
702
     *
703
     * @return int|null attachment id of an image
704
     */
705 5
    public function get_image_id( $image_url ) {
706 5
        $attachment_id = $this->get_attachment_id( $image_url );
707
708 5
        if ( is_null( $attachment_id ) ) {
709
            /*
710
             * Check if the image is an edited image.
711
             * and try to get the attachment id.
712
             */
713
714 1
            global $wp_version;
715
716 1
            if ( intval( $wp_version ) >= 4 ) {
717 1
                return attachment_url_to_postid( $image_url );
718
            }
719
720
            // Fallback.
721
            $image_url = str_replace( $this->upload_url . '/', '', $image_url );
722
723
            $row = $this->execute_query( $this->db->prepare( 'SELECT post_id FROM ' . $this->db->postmeta . ' WHERE meta_key = %s AND meta_value = %s', '_wp_attached_file', $image_url ) );
724
            if ( ! is_null( $row ) ) {
725
                $attachment_id = $row;
726
            }
727
        }
728
729 4
        return (int) $attachment_id;
730
    }
731
732
    /**
733
     * Get image title.
734
     *
735
     * @since 2.0.0
736
     * @access public
737
     *
738
     * @param string $image_url URL of an image.
739
     *
740
     * @return string
741
     */
742 1
    public function get_image_title( $image_url ) {
743 1
        return sanitize_text_field( $this->execute_query( $this->db->prepare( 'SELECT post_title FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) ) );
744
    }
745
746
    /**
747
     * Get image title by id.
748
     *
749
     * @since 2.0.0
750
     * @access public
751
     *
752
     * @param  int $attachment_id Attachment id of an image.
753
     *
754
     * @return string
755
     */
756 1
    public function get_image_title_by_id( $attachment_id ) {
757 1
        return sanitize_text_field( $this->execute_query( $this->db->prepare( 'SELECT post_title FROM ' . $this->db->posts . ' WHERE ID = %d', $attachment_id ) ) );
758
    }
759
760
    /**
761
     * Get image caption.
762
     *
763
     * @since 2.0.0
764
     * @access public
765
     *
766
     * @param  string $image_url URL of an image.
767
     *
768
     * @return string
769
     */
770 1
    public function get_image_caption( $image_url ) {
771 1
        return sanitize_text_field( $this->execute_query( $this->db->prepare( 'SELECT post_excerpt FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) ) );
772
    }
773
774
    /**
775
     * Get image caption by id.
776
     *
777
     * @since 2.0.0
778
     * @access public
779
     *
780
     * @param  int $attachment_id Attachment id of an image.
781
     *
782
     * @return string
783
     */
784 1
    public function get_image_caption_by_id( $attachment_id ) {
785 1
        return sanitize_text_field( $this->execute_query( $this->db->prepare( 'SELECT post_excerpt FROM ' . $this->db->posts . ' WHERE ID = %d', $attachment_id ) ) );
786
    }
787
788
    /**
789
     * Get image alternate text.
790
     *
791
     * @since 2.0.0
792
     * @access public
793
     *
794
     * @see  get_post_meta()
795
     *
796
     * @param  string $image_url URL of an image.
797
     *
798
     * @return string
799
     */
800 1
    public function get_image_alt( $image_url ) {
801 1
        $attachment = $this->db->get_col( $this->db->prepare( 'SELECT ID FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) );
802
803 1
        $alt = null;
804 1
        if ( ! empty( $attachment ) ) {
805 1
            $alt = get_post_meta( $attachment[0], '_wp_attachment_image_alt' );
806 1
        }
807
808 1
        return ( is_null( $alt ) || empty( $alt ) ) ? null : sanitize_text_field($alt[0]);
809
    }
810
811
    /**
812
     * Get image alternate text by attachment id.
813
     *
814
     * @since 2.0.0
815
     * @access public
816
     *
817
     * @see  get_post_meta()
818
     *
819
     * @param  int $attachment_id Attachment id of an image.
820
     *
821
     * @return string
822
     */
823 1
    public function get_image_alt_by_id( $attachment_id ) {
824 1
        $alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt' );
825
826 1
        return empty( $alt ) ? null : sanitize_text_field($alt[0]);
827
    }
828
829
    /**
830
     * Get image description.
831
     *
832
     * @since 3.0.0
833
     * @access public
834
     *
835
     * @param  string $image_url URL of an image.
836
     *
837
     * @return string
838
     */
839 1
    public function get_image_description( $image_url ) {
840 1
        return sanitize_text_field( $this->execute_query( $this->db->prepare( 'SELECT post_content FROM ' . $this->db->posts . ' WHERE guid = %s', $image_url ) ) );
841
    }
842
843
    /**
844
     * Get image description by id.
845
     *
846
     * @since 3.0.0
847
     * @access public
848
     *
849
     * @param  int $attachment_id attachment id of an image.
850
     *
851
     * @return string
852
     */
853 1
    public function get_image_description_by_id( $attachment_id ) {
854 1
        return sanitize_text_field( $this->execute_query( $this->db->prepare( 'SELECT post_content FROM ' . $this->db->posts . ' WHERE ID = %d', $attachment_id ) ) );
855
    }
856
857
    /**
858
     * Get link to image.
859
     *
860
     * @since 3.4.0
861
     * @access public
862
     *
863
     * @param  int $attachment_id Attachment id of an image.
864
     *
865
     * @return string|null
866
     */
867 1
    public function get_link_to_image( $attachment_id ) {
868 1
        return sanitize_text_field( get_post_meta( $attachment_id, '_dfi_link_to_image', true ) );
869
    }
870
871
    /**
872
     * Get all attachment ids of the post.
873
     *
874
     * @since 2.0.0
875
     * @access public
876
     *
877
     * @see  get_post_meta()
878
     *
879
     * @param  int $post_id id of the current post.
880
     *
881
     * @return array
882
     */
883 2
    public function get_post_attachment_ids( $post_id ) {
884 2
        $dfi_images = get_post_meta( $post_id, 'dfiFeatured', true );
885 2
        $ret_val    = array();
886
887 2 View Code Duplication
        if ( ! empty( $dfi_images ) && is_array( $dfi_images ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
888 2
            foreach ( $dfi_images as $dfi_image ) {
889 2
                $dfi_image_full = $this->separate( $dfi_image, 'full' );
890 2
                $ret_val[]      = (int) $this->get_image_id( $this->upload_url . $dfi_image_full );
891 2
            }
892 2
        }
893 2
		$ret_val = $this->sanitize_array( $ret_val );
894 2
        return $ret_val;
895
    }
896
897
    /**
898
     * Get real post id.
899
     *
900
     * @since 3.6.0
901
     * @access protected
902
     *
903
     * @param int|null $post_id Post id.
904
     *
905
     * @return int|null
906
     */
907 6
    protected function get_real_post_id( $post_id = null ) {
908 6
        if ( ! is_null( $post_id ) && is_numeric( $post_id ) ) {
909 5
            return $post_id;
910
        }
911
912 3
        global $post;
913
914 3
        return $post->ID;
915
    }
916
917
    /**
918
     * Fetches featured image data of nth position.
919
     *
920
     * @since  3.0.0
921
     * @access  public
922
     *
923
     * @see  get_featured_images()
924
     *
925
     * @param  int $position Position of the featured image.
926
     * @param  int $post_id Current post id.
927
     *
928
     * @return array if found, null otherwise.
929
     */
930 2
    public function get_nth_featured_image( $position, $post_id = null ) {
931 2
        $post_id = $this->get_real_post_id( ( $post_id ) );
932
933 2
        $featured_images = $this->get_featured_images( $post_id );
934
935 2
        return isset( $featured_images[ $position - 2 ] ) ?  sanitize_text_field( $featured_images[ $position - 2 ] ) : null;
936
    }
937
938
    /**
939
     * Check if the image is attached with the particular post.
940
     *
941
     * @since 2.0.0
942
     * @access public
943
     *
944
     * @see  get_post_attachment_ids()
945
     *
946
     * @param  int $attachment_id Attachment id of an image.
947
     * @param  int $post_id Current post id.
948
     *
949
     * @return bool
950
     */
951 1
    public function is_attached( $attachment_id, $post_id ) {
952 1
        if ( empty( $attachment_id ) ) {
953
            return false;
954
        }
955
956 1
        $attachment_ids = $this->get_post_attachment_ids( $post_id );
957
958 1
        return in_array( $attachment_id, $attachment_ids, true ) ? true : false;
959
    }
960
961
    /**
962
     * Retrieve featured images for specific post(s).
963
     *
964
     * @since 2.0.0
965
     * @access public
966
     *
967
     * @see get_post_meta()
968
     *
969
     * @param  int $post_id id of the current post.
970
     *
971
     * @return array
972
     */
973 7
    public function get_featured_images( $post_id = null ) {
974 7
        $post_id    = $this->get_real_post_id( $post_id );
975 7
        $dfi_images = get_post_meta( $post_id, 'dfiFeatured', true );
976 7
        $ret_images = array();
977
978 7
        if ( ! empty( $dfi_images ) && is_array( $dfi_images ) ) {
979 7
            $dfi_images = array_filter( $dfi_images );
980
981 7
            $count = 0;
982 7
            foreach ( $dfi_images as $dfi_image ) {
983 7
                $dfi_image_trimmed = $this->separate( $dfi_image );
984 7
                $dfi_image_full    = $this->separate( $dfi_image, 'full' );
985
986
                try {
987 7
                    $ret_images[ $count ]['thumb']         = $this->get_real_upload_path( $dfi_image_trimmed );
988 7
                    $ret_images[ $count ]['full']          = $this->get_real_upload_path( $dfi_image_full );
989 7
                    $ret_images[ $count ]['attachment_id'] = $this->get_image_id( $ret_images[ $count ]['full'] );
990 7
					$ret_images[ $count ] 				   = $this->sanitize_array($ret_images[ $count ]);
991 7
                } catch ( Exception $e ) {
992
                    /* Ignore the exception and continue with other featured images */
993
                }
994
995 7
                $count ++;
996 7
            }
997 7
        }
998
999 7
        return $ret_images;
1000
    }
1001
1002
    /**
1003
     * Check to see if the upload url is already available in path.
1004
     *
1005
     * @since  3.1.14
1006
     * @access protected
1007
     *
1008
     * @param  string $img Uploaded image.
1009
     *
1010
     * @return string
1011
     */
1012 2
    protected function get_real_upload_path( $img ) {
1013
        // check if upload path is already attached.
1014 2
        if ( false !== strpos( $img, $this->upload_url ) || preg_match( '/https?:\/\//', $img ) ) {
1015 2
            return $img;
1016
        }
1017
1018 2
        return sanitize_text_field($this->upload_url . $img);
1019
    }
1020
1021
    /**
1022
     * Retrieve featured images for specific post(s) including the default Featured Image.
1023
     *
1024
     * @since 3.1.7
1025
     * @access public
1026
     *
1027
     * @see  $this->get_featured_images()
1028
     *
1029
     * @param int $post_id Current post id.
1030
     *
1031
     * @return array An array of images or an empty array on failure
1032
     */
1033 2
    public function get_all_featured_images( $post_id = null ) {
1034 2
        $post_id      = $this->get_real_post_id( $post_id );
1035 2
        $thumbnail_id = get_post_thumbnail_id( $post_id );
1036 2
        $all_images   = array();
1037
1038 2
        if ( ! empty( $thumbnail_id ) ) {
1039
            $featured_image         = array(
1040 2
                'thumb'         => wp_get_attachment_thumb_url( $thumbnail_id ),
1041 2
                'full'          => wp_get_attachment_url( $thumbnail_id ),
1042 2
                'attachment_id' => $thumbnail_id,
1043 2
            );
1044
1045 2
            $all_images[] = $featured_image;
1046 2
        }
1047
1048 2
        return array_merge( $all_images, $this->get_featured_images( $post_id ) );
1049
    }
1050
1051
    /**
1052
     * Load the plugin's textdomain hooked to 'plugins_loaded'.
1053
     *
1054
     * @since 1.0.0
1055
     * @access public
1056
     *
1057
     * @see    load_plugin_textdomain()
1058
     * @see    plugin_basename()
1059
     * @action plugins_loaded
1060
     *
1061
     * @codeCoverageIgnore
1062
     *
1063
     * @return void
1064
     */
1065
    public function load_plugin_textdomain() {
1066
        load_plugin_textdomain(
1067
            self::TEXT_DOMAIN,
1068
            false,
1069
            dirname( plugin_basename( __FILE__ ) ) . '/languages/'
1070
        );
1071
    }
1072
}
1073
1074
// Sponsors who support this plugin.
1075
include 'sponsors.php';
1076
1077
/**
1078
 * Instantiate the main class.
1079
 *
1080
 * @since 1.0.0
1081
 * @access public
1082
 *
1083
 * @var object $dynamic_featured_image holds the instantiated class {@uses Dynamic_Featured_Image}
1084
 */
1085
global $dynamic_featured_image;
1086
$dynamic_featured_image = new Dynamic_Featured_Image();
1087