Completed
Push — master ( 4713b5...48986a )
by David
05:28 queued 15s
created

Wordlift_Attachment_Service::get_gallery()   D

Complexity

Conditions 10
Paths 2

Size

Total Lines 45
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 18
nc 2
nop 1
dl 0
loc 45
rs 4.8196
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Services: Attachment Service.
4
 *
5
 * Provide functions to manipulate attachments.
6
 *
7
 * @since   3.10.0
8
 * @package Wordlift
9
 */
10
11
/**
12
 * Define the {@link Wordlift_Attachment_Service} class.
13
 *
14
 * @since   3.10.0
15
 * @package Wordlift
16
 */
17
class Wordlift_Attachment_Service {
18
19
	/**
20
	 * Get an attachment ID given a URL.
21
	 *
22
	 * Inspired from https://wpscholar.com/blog/get-attachment-id-from-wp-image-url/
23
	 *
24
	 * @since 3.10.0
25
	 *
26
	 * @param string $url The attachment URL.
27
	 *
28
	 * @return int|false Attachment ID on success, false on failure
29
	 */
30
	public function get_attachment_id( $url ) {
31
32
		// Get the upload directory data, we need the base URL to check whether
33
		// the URL we received is within WP.
34
		$dir = wp_upload_dir();
35
36
		// If the image is not inside WP's base url, return.
37
		if ( false === strpos( $url, $dir['baseurl'] . '/' ) ) {
38
			return false;
39
		}
40
41
		// Get the filename, the extension is kept.
42
		$filename = basename( $url );
43
44
		// Query for attachments with the specified filename.
45
		$query = new WP_Query( array(
46
			'post_type'   => 'attachment',
47
			'post_status' => 'inherit',
48
			'fields'      => 'ids',
49
			'meta_query'  => array(
50
				array(
51
					'value'   => $filename,
52
					'compare' => 'LIKE',
53
					'key'     => '_wp_attachment_metadata',
54
				),
55
			),
56
		) );
57
58
		// If there are no posts, return.
59
		if ( $query->have_posts() ) {
60
			foreach ( $query->posts as $attachment_id ) {
61
62
				// Get the attachment metadata, we need the filename.
63
				$metadata          = wp_get_attachment_metadata( $attachment_id );
64
				$original_filename = basename( $metadata['file'] );
65
66
				// Get the cropped filenames, or an empty array in case there are no files.
67
				$sizes_filenames = isset( $metadata['sizes'] ) ? wp_list_pluck( $metadata['sizes'], 'file' ) : array();
68
69
				// If the provided filename matches the attachment filename (or one of its resized images), return the id.
70
				if ( $original_filename === $filename || in_array( $filename, $sizes_filenames ) ) {
71
					return $attachment_id;
72
				}
73
			}
74
		}
75
76
		// If we got here, we couldn't find any attachment.
77
		return false;
78
	}
79
80
	/**
81
	 * Get images embedded in the post content.
82
	 *
83
	 * @since 3.10.0
84
	 *
85
	 * @param string $content The post content.
86
	 *
87
	 * @return array An array of attachment ids.
88
	 */
89
	public function get_image_embeds( $content ) {
90
91
		// Go over all the images included in the post content, check if they are
92
		// in the DB, and if so include them.
93
		$images = array();
94
		if ( false === preg_match_all( '#<img [^>]*src="([^\\">]*)"[^>]*>#', $content, $images ) ) {
95
			return array();
96
		}
97
98
		// Map the image URLs to attachment ids.
99
		$that = $this;
100
		$ids  = array_map( function ( $url ) use ( $that ) {
101
			return $that->get_attachment_id( $url );
102
		}, $images[1] );
103
104
		// Filter out not found ids (i.e. id is false).
105
		return array_filter( $ids, function ( $item ) {
106
			return false !== $item;
107
		} );
108
	}
109
110
	/**
111
	 * Get images linked via the `gallery` shortcode.
112
	 *
113
	 * @since 3.10.0
114
	 *
115
	 * @param \WP_Post $post A {@link WP_Post} instance.
116
	 *
117
	 * @return array An array of attachment ids.
118
	 */
119
	public function get_gallery( $post ) {
120
121
		// @todo: the `gallery` shortcode has an `exclude` attribute which isn't
122
		// checked at the moment.
123
124
		// Prepare the return value.
125
		$ids = array();
126
127
		// As the above for images in galleries.
128
		// Code inspired by http://wordpress.stackexchange.com/questions/80408/how-to-get-page-post-gallery-attachment-images-in-order-they-are-set-in-backend
129
		$pattern = get_shortcode_regex();
130
131
		if ( preg_match_all( '/' . $pattern . '/s', $post->post_content, $matches )
132
		     && array_key_exists( 2, $matches )
133
		     && in_array( 'gallery', $matches[2] )
134
		) {
135
136
			$keys = array_keys( $matches[2], 'gallery' );
137
138
			foreach ( $keys as $key ) {
139
				$atts = shortcode_parse_atts( $matches[3][ $key ] );
140
141
				if ( is_array( $atts ) && array_key_exists( 'ids', $atts ) ) {
142
					// gallery images insert explicitly by their ids.
143
144
					foreach ( explode( ',', $atts['ids'] ) as $attachment_id ) {
145
						// Since we do not check for actual image existence
146
						// when generating the json content, check it now.
147
						if ( wp_get_attachment_image_src( $attachment_id, 'full' ) ) {
148
							$ids[ $attachment_id ] = true;
149
						}
150
					}
151
				} else {
152
					// gallery shortcode with no ids uses all the images
153
					// attached to the post.
154
					$images = get_attached_media( 'image', $post->ID );
155
					foreach ( $images as $attachment ) {
156
						$ids[ $attachment->ID ] = true;
157
					}
158
				}
159
			}
160
		}
161
162
		return array_keys( $ids );
163
	}
164
165
}
166