Completed
Push — fix/videopress-missing-from-se... ( 60564b )
by
unknown
22:41 queued 12:31
created

class.wpcom-json-api-list-media-v1-1-endpoint.php (1 issue)

Labels
Severity

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
class WPCOM_JSON_API_List_Media_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint {
4
5
	public $date_range = array();
6
	public $page_handle = array();
7
8
	function callback( $path = '', $blog_id = 0 ) {
9
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
10
		if ( is_wp_error( $blog_id ) ) {
11
			return $blog_id;
12
		}
13
14
		//upload_files can probably be used for other endpoints but we want contributors to be able to use media too
15
		if ( ! current_user_can( 'edit_posts' ) ) {
16
			return new WP_Error( 'unauthorized', 'User cannot view media', 403 );
17
		}
18
19
		$args = $this->query_args();
20
		$is_eligible_for_page_handle = true;
21
22
		if ( $args['number'] < 1 ) {
23
			$args['number'] = 20;
24
		} elseif ( 100 < $args['number'] ) {
25
			return new WP_Error( 'invalid_number',  'The NUMBER parameter must be less than or equal to 100.', 400 );
26
		}
27
28
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
29
			$this->load_theme_functions();
30
		}
31
32
		if ( isset( $args['before'] ) ) {
33
			$this->date_range['before'] = $args['before'];
34
		}
35
		if ( isset( $args['after'] ) ) {
36
			$this->date_range['after'] = $args['after'];
37
		}
38
39
		$query = array(
40
			'post_type'      => 'attachment',
41
			'post_status'    => 'inherit',
42
			'post_parent'    => isset( $args['post_ID'] ) ? $args['post_ID'] : null,
43
			'posts_per_page' => $args['number'],
44
			'post_mime_type' => isset( $args['mime_type'] ) ? $args['mime_type'] : null,
45
			'order'          => isset( $args['order'] ) ? $args['order'] : 'DESC',
46
			'orderby'        => isset( $args['order_by'] ) ? $args['order_by'] : 'date',
47
			's'              => isset( $args['search'] ) ? $args['search'] : null,
48
		);
49
50 View Code Duplication
		if ( isset( $args['page'] ) ) {
51
			if ( $args['page'] < 1 ) {
52
				$args['page'] = 1;
53
			}
54
55
			$query['paged'] = $args['page'];
56
			if ( $query['paged'] !== 1 ) {
57
				$is_eligible_for_page_handle = false;
58
			}
59
		} else {
60
			if ( $args['offset'] < 0 ) {
61
				$args['offset'] = 0;
62
			}
63
64
			$query['offset'] = $args['offset'];
65
			if ( $query['offset'] !== 0 ) {
66
				$is_eligible_for_page_handle = false;
67
			}
68
		}
69
70 View Code Duplication
		if ( isset( $args['page_handle'] ) ) {
71
			$page_handle = wp_parse_args( $args['page_handle'] );
72
			if ( isset( $page_handle['value'] ) && isset( $page_handle['id'] ) ) {
73
				// we have a valid looking page handle
74
				$this->page_handle = $page_handle;
75
				add_filter( 'posts_where', array( $this, 'handle_where_for_page_handle' ) );
76
			}
77
		}
78
79
		if ( $this->date_range ) {
80
			add_filter( 'posts_where', array( $this, 'handle_date_range' ) );
81
		}
82
83
		$this->performed_query = $query;
0 ignored issues
show
The property performed_query does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
84
		add_filter( 'posts_orderby', array( $this, 'handle_orderby_for_page_handle' ) );
85
86
		$media = new WP_Query( $query );
87
88
		remove_filter( 'posts_orderby', array( $this, 'handle_orderby_for_page_handle' ) );
89
90
		if ( $this->date_range ) {
91
			remove_filter( 'posts_where', array( $this, 'handle_date_range' ) );
92
			$this->date_range = array();
93
		}
94
95
		if ( $this->page_handle ) {
96
			remove_filter( 'posts_where', array( $this, 'handle_where_for_page_handle' ) );
97
		}
98
99
		$response = array();
100
		foreach ( $media->posts as $item ) {
101
			$response[] = $this->get_media_item_v1_1( $item->ID );
102
		}
103
104
		$return = array(
105
			'found' => (int) $media->found_posts,
106
			'media' => $response
107
		);
108
109
		if ( $is_eligible_for_page_handle && $return['media'] ) {
110
			$last_post = end( $return['media'] );
111
			reset( $return['media'] );
112
113
			if ( ( $return['found'] > count( $return['media'] ) ) && $last_post ) {
114
				$return['meta'] = array();
115
				$return['meta']['next_page'] = $this->build_page_handle( $last_post, $query );
116
			}
117
		}
118
119
		return $return;
120
	}
121
122 View Code Duplication
	function build_page_handle( $post, $query ) {
123
		$column = $query['orderby'];
124
		if ( ! $column ) {
125
			$column = 'date';
126
		}
127
		return build_query( array( 'value' => urlencode( $post->$column ), 'id' => $post->ID ) );
128
	}
129
130 View Code Duplication
	function handle_where_for_page_handle( $where ) {
131
		global $wpdb;
132
133
		$column = $this->performed_query['orderby'];
134
		if ( ! $column ) {
135
			$column = 'date';
136
		}
137
		$order = $this->performed_query['order'];
138
		if ( ! $order ) {
139
			$order = 'DESC';
140
		}
141
142
		if ( ! in_array( $column, array( 'ID', 'title', 'date', 'modified', 'comment_count' ) ) ) {
143
			return $where;
144
		}
145
146
		if ( ! in_array( $order, array( 'DESC', 'ASC' ) ) ) {
147
			return $where;
148
		}
149
150
		$db_column = '';
151
		$db_value = '';
152
		switch( $column ) {
153
			case 'ID':
154
				$db_column = 'ID';
155
				$db_value = '%d';
156
				break;
157
			case 'title':
158
				$db_column = 'post_title';
159
				$db_value = '%s';
160
				break;
161
			case 'date':
162
				$db_column = 'post_date';
163
				$db_value = 'CAST( %s as DATETIME )';
164
				break;
165
			case 'modified':
166
				$db_column = 'post_modified';
167
				$db_value = 'CAST( %s as DATETIME )';
168
				break;
169
			case 'comment_count':
170
				$db_column = 'comment_count';
171
				$db_value = '%d';
172
				break;
173
		}
174
175
		if ( 'DESC'=== $order ) {
176
			$db_order = '<';
177
		} else {
178
			$db_order = '>';
179
		}
180
181
		// Add a clause that limits the results to items beyond the passed item, or equivalent to the passed item
182
		// but with an ID beyond the passed item. When we're ordering by the ID already, we only ask for items
183
		// beyond the passed item.
184
		$where .= $wpdb->prepare( " AND ( ( `$wpdb->posts`.`$db_column` $db_order $db_value ) ", $this->page_handle['value'] );
185
		if ( $db_column !== 'ID' ) {
186
			$where .= $wpdb->prepare( "OR ( `$wpdb->posts`.`$db_column` = $db_value AND `$wpdb->posts`.ID $db_order %d )", $this->page_handle['value'], $this->page_handle['id'] );
187
		}
188
		$where .= ' )';
189
190
		return $where;
191
	}
192
193 View Code Duplication
	function handle_date_range( $where ) {
194
		global $wpdb;
195
196
		switch ( count( $this->date_range ) ) {
197
		case 2 :
198
			$where .= $wpdb->prepare(
199
				" AND `$wpdb->posts`.post_date BETWEEN CAST( %s AS DATETIME ) AND CAST( %s AS DATETIME ) ",
200
				$this->date_range['after'],
201
				$this->date_range['before']
202
			);
203
			break;
204
		case 1 :
205
			if ( isset( $this->date_range['before'] ) ) {
206
				$where .= $wpdb->prepare(
207
					" AND `$wpdb->posts`.post_date <= CAST( %s AS DATETIME ) ",
208
					$this->date_range['before']
209
				);
210
			} else {
211
				$where .= $wpdb->prepare(
212
					" AND `$wpdb->posts`.post_date >= CAST( %s AS DATETIME ) ",
213
					$this->date_range['after']
214
				);
215
			}
216
			break;
217
		}
218
219
		return $where;
220
	}
221
222 View Code Duplication
	function handle_orderby_for_page_handle( $orderby ) {
223
		global $wpdb;
224
		if ( $this->performed_query['orderby'] === 'ID' ) {
225
			// bail if we're already ordering by ID
226
			return $orderby;
227
		}
228
229
		if ( $orderby ) {
230
			$orderby .= ' ,';
231
		}
232
		$order = $this->performed_query['order'];
233
		if ( ! $order ) {
234
			$order = 'DESC';
235
		}
236
		$orderby .= " `$wpdb->posts`.ID $order";
237
		return $orderby;
238
	}
239
240
}
241