PageRenderTime 27ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/shop quần áo starloveshop.com/wp-content/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-v1-1-endpoint.php

https://gitlab.com/phamngsinh/baitaplon_sinhvien
PHP | 370 lines | 300 code | 56 blank | 14 comment | 73 complexity | 9612a698dbe1fa12872530a591726efb MD5 | raw file
  1. <?php
  2. class WPCOM_JSON_API_List_Posts_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_Endpoint {
  3. var $date_range = array();
  4. var $modified_range = array();
  5. var $page_handle = array();
  6. var $performed_query = null;
  7. var $response_format = array(
  8. 'found' => '(int) The total number of posts found that match the request (ignoring limits, offsets, and pagination).',
  9. 'posts' => '(array:post) An array of post objects.',
  10. );
  11. // /sites/%s/posts/ -> $blog_id
  12. function callback( $path = '', $blog_id = 0 ) {
  13. $blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
  14. if ( is_wp_error( $blog_id ) ) {
  15. return $blog_id;
  16. }
  17. $args = $this->query_args();
  18. $is_eligible_for_page_handle = true;
  19. if ( $args['number'] < 1 ) {
  20. $args['number'] = 20;
  21. } elseif ( 100 < $args['number'] ) {
  22. return new WP_Error( 'invalid_number', 'The NUMBER parameter must be less than or equal to 100.', 400 );
  23. }
  24. if ( isset( $args['type'] ) && ! $this->is_post_type_allowed( $args['type'] ) ) {
  25. return new WP_Error( 'unknown_post_type', 'Unknown post type', 404 );
  26. }
  27. // Normalize post_type
  28. if ( isset( $args['type'] ) && 'any' == $args['type'] ) {
  29. if ( version_compare( $this->api->version, '1.1', '<' ) ) {
  30. $args['type'] = array( 'post', 'page' );
  31. } else { // 1.1+
  32. $args['type'] = $this->_get_whitelisted_post_types();
  33. }
  34. }
  35. // determine statuses
  36. $status = $args['status'];
  37. $status = ( $status ) ? explode( ',', $status ) : array( 'publish' );
  38. if ( in_array( 'any', $status ) ) {
  39. $status = array();
  40. } else {
  41. $statuses_whitelist = array(
  42. 'publish',
  43. 'trash',
  44. 'pending',
  45. 'draft',
  46. 'future',
  47. 'private',
  48. );
  49. $status = array_intersect( $status, $statuses_whitelist );
  50. }
  51. $query = array(
  52. 'posts_per_page' => $args['number'],
  53. 'order' => $args['order'],
  54. 'orderby' => $args['order_by'],
  55. 'post_type' => isset( $args['type'] ) ? $args['type'] : null,
  56. 'post_status' => $status,
  57. 'post_parent' => isset( $args['parent_id'] ) ? $args['parent_id'] : null,
  58. 'author' => isset( $args['author'] ) && 0 < $args['author'] ? $args['author'] : null,
  59. 's' => isset( $args['search'] ) ? $args['search'] : null,
  60. );
  61. if ( isset( $args['meta_key'] ) ) {
  62. $show = false;
  63. if ( $this->is_metadata_public( $args['meta_key'] ) )
  64. $show = true;
  65. if ( current_user_can( 'edit_post_meta', $query['post_type'], $args['meta_key'] ) )
  66. $show = true;
  67. if ( is_protected_meta( $args['meta_key'], 'post' ) && ! $show )
  68. return new WP_Error( 'invalid_meta_key', 'Invalid meta key', 404 );
  69. $meta = array( 'key' => $args['meta_key'] );
  70. if ( isset( $args['meta_value'] ) )
  71. $meta['value'] = $args['meta_value'];
  72. $query['meta_query'] = array( $meta );
  73. }
  74. if ( $args['sticky'] === 'include' ) {
  75. $query['ignore_sticky_posts'] = 1;
  76. } else if ( $args['sticky'] === 'exclude' ) {
  77. $sticky = get_option( 'sticky_posts' );
  78. if ( is_array( $sticky ) ) {
  79. $query['post__not_in'] = $sticky;
  80. }
  81. }
  82. if ( isset( $args['exclude'] ) ) {
  83. $excluded_ids = (array) $args['exclude'];
  84. $query['post__not_in'] = isset( $query['post__not_in'] ) ? array_merge( $query['post__not_in'], $excluded_ids ) : $excluded_ids;
  85. }
  86. if ( isset( $args['category'] ) ) {
  87. $category = get_term_by( 'slug', $args['category'], 'category' );
  88. if ( $category === false) {
  89. $query['category_name'] = $args['category'];
  90. } else {
  91. $query['cat'] = $category->term_id;
  92. }
  93. }
  94. if ( isset( $args['tag'] ) ) {
  95. $query['tag'] = $args['tag'];
  96. }
  97. if ( isset( $args['page'] ) ) {
  98. if ( $args['page'] < 1 ) {
  99. $args['page'] = 1;
  100. }
  101. $query['paged'] = $args['page'];
  102. if ( $query['paged'] !== 1 ) {
  103. $is_eligible_for_page_handle = false;
  104. }
  105. } else {
  106. if ( $args['offset'] < 0 ) {
  107. $args['offset'] = 0;
  108. }
  109. $query['offset'] = $args['offset'];
  110. if ( $query['offset'] !== 0 ) {
  111. $is_eligible_for_page_handle = false;
  112. }
  113. }
  114. if ( isset( $args['before'] ) ) {
  115. $this->date_range['before'] = $args['before'];
  116. }
  117. if ( isset( $args['after'] ) ) {
  118. $this->date_range['after'] = $args['after'];
  119. }
  120. if ( isset ( $args['modified_before'] ) ) {
  121. $this->modified_range['before'] = $args['modified_before'];
  122. }
  123. if ( isset ( $args['modified_after'] ) ) {
  124. $this->modified_range['after'] = $args['modified_after'];
  125. }
  126. if ( $this->date_range ) {
  127. add_filter( 'posts_where', array( $this, 'handle_date_range' ) );
  128. }
  129. if ( $this->modified_range ) {
  130. add_filter( 'posts_where', array( $this, 'handle_modified_range' ) );
  131. }
  132. if ( isset ( $args['page_handle'] ) ) {
  133. $page_handle = wp_parse_args( $args['page_handle'] );
  134. if ( isset( $page_handle['value'] ) && isset( $page_handle['id'] ) ) {
  135. // we have a valid looking page handle
  136. $this->page_handle = $page_handle;
  137. add_filter( 'posts_where', array( $this, 'handle_where_for_page_handle' ) );
  138. }
  139. }
  140. /**
  141. * 'column' necessary for the me/posts endpoint (which extends sites/$site/posts).
  142. * Would need to be added to the sites/$site/posts definition if we ever want to
  143. * use it there.
  144. */
  145. $column_whitelist = array( 'post_modified_gmt' );
  146. if ( isset( $args['column'] ) && in_array( $args['column'], $column_whitelist ) ) {
  147. $query['column'] = $args['column'];
  148. }
  149. $this->performed_query = $query;
  150. add_filter( 'posts_orderby', array( $this, 'handle_orderby_for_page_handle' ) );
  151. $wp_query = new WP_Query( $query );
  152. remove_filter( 'posts_orderby', array( $this, 'handle_orderby_for_page_handle' ) );
  153. if ( $this->date_range ) {
  154. remove_filter( 'posts_where', array( $this, 'handle_date_range' ) );
  155. $this->date_range = array();
  156. }
  157. if ( $this->page_handle ) {
  158. remove_filter( 'posts_where', array( $this, 'handle_where_for_page_handle' ) );
  159. }
  160. $return = array();
  161. $excluded_count = 0;
  162. foreach ( array_keys( $this->response_format ) as $key ) {
  163. switch ( $key ) {
  164. case 'found' :
  165. $return[$key] = (int) $wp_query->found_posts;
  166. break;
  167. case 'posts' :
  168. if ( isset( $args['exclude_tree'] ) && is_post_type_hierarchical( $args['type'] ) ) {
  169. // get_page_children is a misnomer; it supports all hierarchical post types
  170. $post_descendants = get_page_children( $args['exclude_tree'], $wp_query->posts );
  171. $exclude_tree = array( $args['exclude_tree'] );
  172. foreach ( $post_descendants as $child ) {
  173. $exclude_tree[] = $child->ID;
  174. }
  175. }
  176. $posts = array();
  177. foreach ( $wp_query->posts as $post ) {
  178. $the_post = $this->get_post_by( 'ID', $post->ID, $args['context'] );
  179. $is_excluded_from_tree = isset( $exclude_tree ) && in_array( $post->ID, $exclude_tree );
  180. if ( $the_post && ! is_wp_error( $the_post ) && ! $is_excluded_from_tree ) {
  181. $posts[] = $the_post;
  182. } else {
  183. $excluded_count++;
  184. }
  185. }
  186. if ( $posts ) {
  187. do_action( 'wpcom_json_api_objects', 'posts', count( $posts ) );
  188. }
  189. $return[$key] = $posts;
  190. break;
  191. }
  192. }
  193. if ( $is_eligible_for_page_handle && $return['posts'] ) {
  194. $last_post = end( $return['posts'] );
  195. reset( $return['posts'] );
  196. if ( ( $return['found'] > count( $return['posts'] ) ) && $last_post ) {
  197. $return['meta'] = array();
  198. $return['meta']['next_page'] = $this->build_page_handle( $last_post, $query );
  199. }
  200. }
  201. $return['found'] -= $excluded_count;
  202. return $return;
  203. }
  204. function build_page_handle( $post, $query ) {
  205. $column = $query['orderby'];
  206. if ( ! $column ) {
  207. $column = 'date';
  208. }
  209. return build_query( array( 'value' => urlencode($post[$column]), 'id' => $post['ID'] ) );
  210. }
  211. function _build_date_range_query( $column, $range, $where ) {
  212. global $wpdb;
  213. switch ( count( $range ) ) {
  214. case 2 :
  215. $where .= $wpdb->prepare(
  216. " AND `$wpdb->posts`.$column >= CAST( %s AS DATETIME ) AND `$wpdb->posts`.$column < CAST( %s AS DATETIME ) ",
  217. $range['after'],
  218. $range['before']
  219. );
  220. break;
  221. case 1 :
  222. if ( isset( $range['before'] ) ) {
  223. $where .= $wpdb->prepare(
  224. " AND `$wpdb->posts`.$column < CAST( %s AS DATETIME ) ",
  225. $range['before']
  226. );
  227. } else {
  228. $where .= $wpdb->prepare(
  229. " AND `$wpdb->posts`.$column > CAST( %s AS DATETIME ) ",
  230. $range['after']
  231. );
  232. }
  233. break;
  234. }
  235. return $where;
  236. }
  237. function handle_date_range( $where ) {
  238. return $this->_build_date_range_query( 'post_date', $this->date_range, $where );
  239. }
  240. function handle_modified_range( $where ) {
  241. return $this->_build_date_range_query( 'post_modified_gmt', $this->modified_range, $where );
  242. }
  243. function handle_where_for_page_handle( $where ) {
  244. global $wpdb;
  245. $column = $this->performed_query['orderby'];
  246. if ( ! $column ) {
  247. $column = 'date';
  248. }
  249. $order = $this->performed_query['order'];
  250. if ( ! $order ) {
  251. $order = 'DESC';
  252. }
  253. if ( ! in_array( $column, array( 'ID', 'title', 'date', 'modified', 'comment_count' ) ) ) {
  254. return $where;
  255. }
  256. if ( ! in_array( $order, array( 'DESC', 'ASC' ) ) ) {
  257. return $where;
  258. }
  259. $db_column = '';
  260. $db_value = '';
  261. switch( $column ) {
  262. case 'ID':
  263. $db_column = 'ID';
  264. $db_value = '%d';
  265. break;
  266. case 'title':
  267. $db_column = 'post_title';
  268. $db_value = '%s';
  269. break;
  270. case 'date':
  271. $db_column = 'post_date';
  272. $db_value = 'CAST( %s as DATETIME )';
  273. break;
  274. case 'modified':
  275. $db_column = 'post_modified';
  276. $db_value = 'CAST( %s as DATETIME )';
  277. break;
  278. case 'comment_count':
  279. $db_column = 'comment_count';
  280. $db_value = '%d';
  281. break;
  282. }
  283. if ( 'DESC'=== $order ) {
  284. $db_order = '<';
  285. } else {
  286. $db_order = '>';
  287. }
  288. // Add a clause that limits the results to items beyond the passed item, or equivalent to the passed item
  289. // but with an ID beyond the passed item. When we're ordering by the ID already, we only ask for items
  290. // beyond the passed item.
  291. $where .= $wpdb->prepare( " AND ( ( `$wpdb->posts`.`$db_column` $db_order $db_value ) ", $this->page_handle['value'] );
  292. if ( $db_column !== 'ID' ) {
  293. $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'] );
  294. }
  295. $where .= ' )';
  296. return $where;
  297. }
  298. function handle_orderby_for_page_handle( $orderby ) {
  299. global $wpdb;
  300. if ( $this->performed_query['orderby'] === 'ID' ) {
  301. // bail if we're already ordering by ID
  302. return $orderby;
  303. }
  304. if ( $orderby ) {
  305. $orderby .= ' ,';
  306. }
  307. $order = $this->performed_query['order'];
  308. if ( ! $order ) {
  309. $order = 'DESC';
  310. }
  311. $orderby .= " `$wpdb->posts`.ID $order";
  312. return $orderby;
  313. }
  314. }