Advertisement
Guest User

Untitled

a guest
Jan 17th, 2017
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.17 KB | None | 0 0
  1. <?php
  2. /**
  3. * Integrate with WP_Query
  4. *
  5. * @since 1.0
  6. * @package elasticpress
  7. */
  8.  
  9. if ( ! defined( 'ABSPATH' ) ) {
  10. exit; // Exit if accessed directly.
  11. }
  12.  
  13. class EP_WP_Query_Integration {
  14.  
  15. /**
  16. * Is set only when we are within a multisite loop
  17. *
  18. * @var bool|WP_Query
  19. */
  20. private $query_stack = array();
  21.  
  22. private $posts_by_query = array();
  23.  
  24. /**
  25. * Placeholder method
  26. *
  27. * @since 0.9
  28. */
  29. public function __construct() { }
  30.  
  31. /**
  32. * Checks to see if we should be integrating and if so, sets up the appropriate actions and filters.
  33. * @since 0.9
  34. */
  35. public function setup() {
  36. // Ensure that we are currently allowing ElasticPress to override the normal WP_Query
  37. if ( ep_is_indexing() ) {
  38. return;
  39. }
  40.  
  41. // Make sure we return nothing for MySQL posts query
  42. add_filter( 'posts_request', array( $this, 'filter_posts_request' ), 10, 2 );
  43.  
  44. // Add header
  45. add_action( 'pre_get_posts', array( $this, 'action_pre_get_posts' ), 5 );
  46.  
  47. // Nukes the FOUND_ROWS() database query
  48. add_filter( 'found_posts_query', array( $this, 'filter_found_posts_query' ), 5, 2 );
  49.  
  50. // Query and filter in EP_Posts to WP_Query
  51. // Added to caster for early return of result set if id field is filtered
  52. add_filter( 'posts_pre_query', array( $this, 'filter_the_posts' ), 10, 2 );
  53.  
  54. // Query and filter in EP_Posts to WP_Query
  55. add_filter( 'the_posts', array( $this, 'filter_the_posts' ), 10, 2 );
  56.  
  57. // Ensure we're in a loop before we allow blog switching
  58. add_action( 'loop_start', array( $this, 'action_loop_start' ), 10, 1 );
  59.  
  60. // Properly restore blog if necessary
  61. add_action( 'loop_end', array( $this, 'action_loop_end' ), 10, 1 );
  62.  
  63. // Properly switch to blog if necessary
  64. add_action( 'the_post', array( $this, 'action_the_post' ), 10, 1 );
  65. }
  66.  
  67. /**
  68. * Disables cache_results, adds header.
  69. *
  70. * @param $query
  71. * @since 0.9
  72. */
  73. public function action_pre_get_posts( $query ) {
  74. if ( ! ep_elasticpress_enabled( $query ) || apply_filters( 'ep_skip_query_integration', false, $query ) ) {
  75. return;
  76. }
  77.  
  78. /**
  79. * `cache_results` defaults to false but can be enabled.
  80. *
  81. * @since 1.5
  82. */
  83. $query->set( 'cache_results', false );
  84. if ( ! empty( $query->query['cache_results'] ) ) {
  85. $query->set( 'cache_results', true );
  86. }
  87.  
  88. if ( ! headers_sent() ) {
  89. /**
  90. * Manually setting a header as $wp_query isn't yet initialized
  91. * when we call: add_filter('wp_headers', 'filter_wp_headers');
  92. */
  93. header( 'X-ElasticPress-Search: true' );
  94. }
  95. }
  96.  
  97. /**
  98. * Switch to the correct site if the post site id is different than the actual one
  99. *
  100. * @param array $post
  101. * @since 0.9
  102. */
  103. public function action_the_post( $post ) {
  104. if ( ! is_multisite() ) {
  105. return;
  106. }
  107.  
  108. if ( empty( $this->query_stack ) ) {
  109. return;
  110. }
  111.  
  112. if ( ! ep_elasticpress_enabled( $this->query_stack[0] ) || apply_filters( 'ep_skip_query_integration', false, $this->query_stack[0] ) ) {
  113. return;
  114. }
  115.  
  116. if ( ! empty( $post->site_id ) && get_current_blog_id() != $post->site_id ) {
  117. restore_current_blog();
  118.  
  119. switch_to_blog( $post->site_id );
  120.  
  121. remove_action( 'the_post', array( $this, 'action_the_post' ), 10, 1 );
  122. setup_postdata( $post );
  123. add_action( 'the_post', array( $this, 'action_the_post' ), 10, 1 );
  124. }
  125.  
  126. }
  127.  
  128. /**
  129. * Ensure we've started a loop before we allow ourselves to change the blog
  130. *
  131. * @since 0.9.2
  132. */
  133. public function action_loop_start( $query ) {
  134. if ( ! is_multisite() ) {
  135. return;
  136. }
  137.  
  138. array_unshift( $this->query_stack, $query );
  139. }
  140.  
  141. /**
  142. * Make sure the correct blog is restored
  143. *
  144. * @since 0.9
  145. */
  146. public function action_loop_end( $query ) {
  147. if ( ! is_multisite() ) {
  148. return;
  149. }
  150.  
  151. array_pop( $this->query_stack );
  152.  
  153. if ( ! ep_elasticpress_enabled( $query ) || apply_filters( 'ep_skip_query_integration', false, $query ) ) {
  154. return;
  155. }
  156.  
  157. if ( ! empty( $GLOBALS['switched'] ) ) {
  158. restore_current_blog();
  159. }
  160. }
  161.  
  162. /**
  163. * Filter the posts array to contain ES query results in EP_Post form. Pull previously queried posts.
  164. *
  165. * @param array $posts
  166. * @param object &$query
  167. * @return array
  168. */
  169. public function filter_the_posts( $posts, &$query ) {
  170. if ( ! ep_elasticpress_enabled( $query ) || apply_filters( 'ep_skip_query_integration', false, $query ) || ! isset( $this->posts_by_query[spl_object_hash( $query )] ) ) {
  171. return $posts;
  172. }
  173.  
  174. $new_posts = $this->posts_by_query[spl_object_hash( $query )];
  175.  
  176. return $new_posts;
  177. }
  178.  
  179. /**
  180. * Remove the found_rows from the SQL Query
  181. *
  182. * @param string $sql
  183. * @param object $query
  184. * @since 0.9
  185. * @return string
  186. */
  187. public function filter_found_posts_query( $sql, $query ) {
  188. if ( ! ep_elasticpress_enabled( $query ) || apply_filters( 'ep_skip_query_integration', false, $query ) ) {
  189. return $sql;
  190. }
  191.  
  192. return '';
  193. }
  194.  
  195. /**
  196. * Filter query string used for get_posts(). Query for posts and save for later.
  197. * Return a query that will return nothing.
  198. *
  199. * @param string $request
  200. * @param object $query
  201. * @since 0.9
  202. * @return string
  203. */
  204. public function filter_posts_request( $request, $query ) {
  205. global $wpdb;
  206.  
  207. if ( ! ep_elasticpress_enabled( $query ) || apply_filters( 'ep_skip_query_integration', false, $query ) ) {
  208. return $request;
  209. }
  210.  
  211. $query_vars = $query->query_vars;
  212.  
  213. /**
  214. * Allows us to filter in searchable post types if needed
  215. *
  216. * @since 2.1
  217. */
  218. $query_vars['post_type'] = apply_filters( 'ep_query_post_type', $query_vars['post_type'], $query );
  219.  
  220. if ( 'any' === $query_vars['post_type'] ) {
  221. unset( $query_vars['post_type'] );
  222. }
  223.  
  224. /**
  225. * If not search and not set default to post. If not set and is search, use searchable post tpyes
  226. */
  227. if ( empty( $query_vars['post_type'] ) ) {
  228. if ( empty( $query_vars['s'] ) ) {
  229. $query_vars['post_type'] = 'post';
  230. } else {
  231. $query_vars['post_type'] = array_values( get_post_types( array( 'exclude_from_search' => false ) ) );
  232. }
  233. }
  234.  
  235. if ( empty( $query_vars['post_type'] ) ) {
  236. $this->posts_by_query[spl_object_hash( $query )] = array();
  237.  
  238. return "SELECT * FROM $wpdb->posts WHERE 1=0";
  239. }
  240.  
  241. $new_posts = apply_filters( 'ep_wp_query_search_cached_posts', array(), $query );
  242.  
  243. $ep_query = array();
  244.  
  245. if( count( $new_posts ) < 1 ) {
  246.  
  247. $scope = 'current';
  248. if ( ! empty( $query_vars['sites'] ) ) {
  249. $scope = $query_vars['sites'];
  250. }
  251.  
  252. $formatted_args = ep_format_args( $query_vars );
  253.  
  254. /**
  255. * Filter search scope
  256. *
  257. * @since 2.1
  258. *
  259. * @param mixed $scope The search scope. Accepts `all` (string), a single
  260. * site id (int or string), or an array of site ids (array).
  261. */
  262. $scope = apply_filters( 'ep_search_scope', $scope );
  263.  
  264. $ep_query = ep_query( $formatted_args, $query->query_vars, $scope );
  265.  
  266. if ( false === $ep_query ) {
  267. return $request;
  268. }
  269.  
  270. $query->found_posts = $ep_query['found_posts'];
  271. $query->max_num_pages = ceil( $ep_query['found_posts'] / $query->get( 'posts_per_page' ) );
  272.  
  273. foreach ( $ep_query['posts'] as $post_array ) {
  274. //prepare result based on fields
  275. if ($query->query_vars['fields'] == 'ids') {
  276. $post = $post_array['post_id'];
  277. } elseif ($query->query_vars['fields'] == 'id=>parent') {
  278. $post = new stdClass();
  279. $post->ID = $post_array['post_id'];
  280. $post->parent_id = $post_array['post_parent'];
  281. } else {
  282. $post = new stdClass();
  283.  
  284. $post->ID = $post_array['post_id'];
  285. $post->site_id = get_current_blog_id();
  286.  
  287. if ( ! empty( $post_array['site_id'] ) ) {
  288. $post->site_id = $post_array['site_id'];
  289. }
  290. // ep_search_request_args
  291. $post_return_args = apply_filters( 'ep_search_post_return_args',
  292. array(
  293. 'post_type',
  294. 'post_author',
  295. 'post_name',
  296. 'post_status',
  297. 'post_title',
  298. 'post_parent',
  299. 'post_content',
  300. 'post_excerpt',
  301. 'post_date',
  302. 'post_date_gmt',
  303. 'post_modified',
  304. 'post_modified_gmt',
  305. 'post_mime_type',
  306. 'comment_count',
  307. 'comment_status',
  308. 'ping_status',
  309. 'menu_order',
  310. 'permalink',
  311. 'terms',
  312. 'post_meta',
  313. 'meta',
  314. )
  315. );
  316.  
  317. foreach ( $post_return_args as $key ) {
  318. if( $key === 'post_author' ) {
  319. $post->$key = $post_array[$key]['id'];
  320. } elseif ( isset( $post_array[ $key ] ) ) {
  321. $post->$key = $post_array[$key];
  322. }
  323. }
  324.  
  325. $post->elasticsearch = true; // Super useful for debugging
  326. }
  327.  
  328. if ( $post ) {
  329. $new_posts[] = $post;
  330. }
  331. }
  332.  
  333. do_action( 'ep_wp_query_non_cached_search', $new_posts, $ep_query, $query );
  334. }
  335.  
  336. $this->posts_by_query[spl_object_hash( $query )] = $new_posts;
  337.  
  338. do_action( 'ep_wp_query_search', $new_posts, $ep_query, $query );
  339.  
  340. return "SELECT * FROM $wpdb->posts WHERE 1=0";
  341. }
  342.  
  343.  
  344. /**
  345. * Return a singleton instance of the current class
  346. *
  347. * @since 0.9
  348. * @return object
  349. */
  350. public static function factory() {
  351. static $instance = false;
  352.  
  353. if ( ! $instance ) {
  354. $instance = new self();
  355. add_action( 'init', array( $instance, 'setup' ) );
  356. }
  357.  
  358. return $instance;
  359. }
  360. }
  361.  
  362. EP_WP_Query_Integration::factory();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement