/** * Create a WP post and "sync" it to Elasticsearch. We are mocking the sync * * @param array $post_args * @param array $post_meta * @param int $site_id * @since 0.9 * @return int|WP_Error */ function ep_create_and_sync_post($post_args = array(), $post_meta = array(), $site_id = null) { if ($site_id != null) { switch_to_blog($site_id); } $post_types = ep_get_indexable_post_types(); $post_type_values = array_values($post_types); $args = array('post_status' => 'publish', 'post_title' => 'Test Post ' . time()); if (!empty($post_type_values)) { $args['post_type'] = $post_type_values[0]; } $args = wp_parse_args($post_args, $args); $post_id = wp_insert_post($args); // Quit if we have a WP_Error object if (is_wp_error($post_id)) { return $post_id; } if (!empty($post_meta)) { foreach ($post_meta as $key => $value) { // No need for sanitization here update_post_meta($post_id, $key, $value); } } // Force a re-sync wp_update_post(array('ID' => $post_id)); if ($site_id != null) { restore_current_blog(); } return $post_id; }
/** * Sync ES index with what happened to the post being saved * * @param string $new_status * @param string $old_status * @param object $post * @since 0.1.0 */ public function action_sync_on_transition($new_status, $old_status, $post) { global $importer; // If we have an importer we must be doing an import - let's abort if (!empty($importer)) { return; } $indexable_post_statuses = ep_get_indexable_post_status(); if (!in_array($new_status, $indexable_post_statuses) && !in_array($old_status, $indexable_post_statuses)) { return; } if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE || !current_user_can('edit_post', $post->ID) || 'revision' === get_post_type($post->ID)) { return; } // Our post was published, but is no longer, so let's remove it from the Elasticsearch index if (!in_array($new_status, $indexable_post_statuses)) { $this->action_delete_post($post->ID); } else { $post_type = get_post_type($post->ID); $indexable_post_types = ep_get_indexable_post_types(); if (in_array($post_type, $indexable_post_types)) { do_action('ep_sync_on_transition', $post->ID); $this->sync_post($post->ID); } } }
/** * Test to verify that a post type that is set to exclude_from_search isn't indexable. * * @since 1.6 * @link https://github.com/10up/ElasticPress/issues/321 */ public function testExcludeIndexablePostType() { $post_types = ep_get_indexable_post_types(); $this->assertArrayNotHasKey('ep_test_excluded', $post_types); $this->assertArrayNotHasKey('ep_test_not_public', $post_types); }
/** * Helper method for indexing posts * * @param bool $no_bulk disable bulk indexing * @param int $posts_per_page * @param int $offset * @param bool $show_bulk_errors whether or not to show bulk error messages. * * @since 0.9 * @return array */ private function _index_helper($no_bulk = false, $posts_per_page, $offset = 0, $show_bulk_errors = false) { global $wpdb, $wp_object_cache; $synced = 0; $errors = array(); while (true) { $args = apply_filters('ep_index_posts_args', array('posts_per_page' => $posts_per_page, 'post_type' => ep_get_indexable_post_types(), 'post_status' => ep_get_indexable_post_status(), 'offset' => $offset, 'ignore_sticky_posts' => true)); $query = new WP_Query($args); if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); if ($no_bulk) { // index the posts one-by-one. not sure why someone may want to do this. $result = ep_sync_post(get_the_ID()); } else { $result = $this->queue_post(get_the_ID(), $query->post_count, $show_bulk_errors); } if (!$result) { $errors[] = get_the_ID(); } else { $synced++; } } } else { break; } WP_CLI::log('Indexed ' . ($query->post_count + $offset) . '/' . $query->found_posts . ' entries. . .'); $offset += $posts_per_page; usleep(500); // Avoid running out of memory $wpdb->queries = array(); if (is_object($wp_object_cache)) { $wp_object_cache->group_ops = array(); $wp_object_cache->stats = array(); $wp_object_cache->memcache_debug = array(); $wp_object_cache->cache = array(); if (is_callable($wp_object_cache, '__remoteset')) { call_user_func(array($wp_object_cache, '__remoteset')); // important } } } if (!$no_bulk) { $this->send_bulk_errors(); } wp_reset_postdata(); return array('synced' => $synced, 'errors' => $errors); }
/** * Helper method for indexing posts * * @param array $args * * @since 0.9 * @return array */ private function _index_helper($args) { $synced = 0; $errors = array(); $no_bulk = false; if (isset($args['nobulk'])) { $no_bulk = true; } $show_bulk_errors = false; if (isset($args['show-bulk-errors'])) { $show_bulk_errors = true; } $posts_per_page = 350; if (!empty($args['posts-per-page'])) { $posts_per_page = absint($args['posts-per-page']); } $offset = 0; if (!empty($args['offset'])) { $offset = absint($args['offset']); } $post_type = ep_get_indexable_post_types(); if (!empty($args['post-type'])) { $post_type = explode(',', $args['post-type']); $post_type = array_map('trim', $post_type); } if (is_array($post_type)) { $post_type = array_values($post_type); } /** * Create WP_Query here and reuse it in the loop to avoid high memory consumption. */ $query = new WP_Query(); while (true) { $args = apply_filters('ep_index_posts_args', array('posts_per_page' => $posts_per_page, 'post_type' => $post_type, 'post_status' => ep_get_indexable_post_status(), 'offset' => $offset, 'ignore_sticky_posts' => true, 'orderby' => 'ID', 'order' => 'DESC')); $query->query($args); if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); if ($no_bulk) { // index the posts one-by-one. not sure why someone may want to do this. $result = ep_sync_post(get_the_ID()); do_action('ep_cli_post_index', get_the_ID()); } else { $result = $this->queue_post(get_the_ID(), $query->post_count, $show_bulk_errors); } if (!$result) { $errors[] = get_the_ID(); } elseif (true === $result) { $synced++; } } } else { break; } WP_CLI::log('Processed ' . ($query->post_count + $offset) . '/' . $query->found_posts . ' entries. . .'); $offset += $posts_per_page; usleep(500); // Avoid running out of memory $this->stop_the_insanity(); } if (!$no_bulk) { $this->send_bulk_errors(); } wp_reset_postdata(); return array('synced' => $synced, 'errors' => $errors); }
/** * Sync ES index with what happened to the post being saved * * @param $post_ID * @since 0.1.0 */ public function action_sync_on_update($post_ID) { global $importer; // If we have an importer we must be doing an import - let's abort if (!empty($importer)) { return; } $indexable_post_statuses = ep_get_indexable_post_status(); $post_type = get_post_type($post_ID); if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE || 'revision' === $post_type) { // Bypass saving if doing autosave or post type is revision return; } elseif (!current_user_can('edit_post', $post_ID) && (!defined('DOING_CRON') || !DOING_CRON)) { // Bypass saving if user does not have access to edit post and we're not in a cron process return; } $post = get_post($post_ID); // If the post is an auto-draft - let's abort. if ('auto-draft' == $post->post_status) { return; } // Our post was published, but is no longer, so let's remove it from the Elasticsearch index if (!in_array($post->post_status, $indexable_post_statuses)) { $this->action_delete_post($post_ID); } else { $post_type = get_post_type($post_ID); $indexable_post_types = ep_get_indexable_post_types(); if (in_array($post_type, $indexable_post_types)) { do_action('ep_sync_on_transition', $post_ID); $this->sync_post($post_ID); } } }
/** * Continue index * * @since 2.1 */ public function action_wp_ajax_ep_index() { if (!check_ajax_referer('ep_nonce', 'nonce', false)) { wp_send_json_error(); exit; } if (defined('EP_IS_NETWORK') && EP_IS_NETWORK) { $index_meta = get_site_option('ep_index_meta', false); } else { $index_meta = get_option('ep_index_meta', false); } $status = false; // No current index going on. Let's start over if (false === $index_meta) { $status = 'start'; $index_meta = array('offset' => 0, 'start' => true); if (defined('EP_IS_NETWORK') && EP_IS_NETWORK) { $sites = ep_get_sites(); $index_meta['site_stack'] = array(); foreach ($sites as $site) { $index_meta['site_stack'][] = array('url' => untrailingslashit($site['domain'] . $site['path']), 'id' => (int) $site['blog_id']); } $index_meta['current_site'] = array_shift($index_meta['site_stack']); } else { if (!apply_filters('ep_skip_index_reset', false, $index_meta)) { ep_delete_index(); ep_put_mapping(); } } if (!empty($_POST['module_sync'])) { $index_meta['module_sync'] = esc_attr($_POST['module_sync']); } } else { if (!empty($index_meta['site_stack']) && $index_meta['offset'] >= $index_meta['found_posts']) { $status = 'start'; $index_meta['start'] = true; $index_meta['offset'] = 0; $index_meta['current_site'] = array_shift($index_meta['site_stack']); } else { $index_meta['start'] = false; } } $index_meta = apply_filters('ep_index_meta', $index_meta); if (defined('EP_IS_NETWORK') && EP_IS_NETWORK) { switch_to_blog($index_meta['current_site']['id']); if (!empty($index_meta['start'])) { if (!apply_filters('ep_skip_index_reset', false, $index_meta)) { ep_delete_index(); ep_put_mapping(); } } } $posts_per_page = apply_filters('ep_index_posts_per_page', 350); do_action('ep_pre_dashboard_index', $index_meta, $status); $args = apply_filters('ep_index_posts_args', array('posts_per_page' => $posts_per_page, 'post_type' => ep_get_indexable_post_types(), 'post_status' => ep_get_indexable_post_status(), 'offset' => $index_meta['offset'], 'ignore_sticky_posts' => true, 'orderby' => 'ID', 'order' => 'DESC', 'fields' => 'all')); $query = new WP_Query($args); $index_meta['found_posts'] = $query->found_posts; if ($status !== 'start') { if ($query->have_posts()) { $queued_posts = array(); while ($query->have_posts()) { $query->the_post(); $killed_post_count = 0; $post_args = ep_prepare_post(get_the_ID()); if (apply_filters('ep_post_sync_kill', false, $post_args, get_the_ID())) { $killed_post_count++; } else { // Post wasn't killed so process it. $queued_posts[get_the_ID()][] = '{ "index": { "_id": "' . absint(get_the_ID()) . '" } }'; if (function_exists('wp_json_encode')) { $queued_posts[get_the_ID()][] = addcslashes(wp_json_encode($post_args), "\n"); } else { $queued_posts[get_the_ID()][] = addcslashes(json_encode($post_args), "\n"); } } } if (!empty($queued_posts)) { $flatten = array(); foreach ($queued_posts as $post) { $flatten[] = $post[0]; $flatten[] = $post[1]; } // make sure to add a new line at the end or the request will fail $body = rtrim(implode("\n", $flatten)) . "\n"; ep_bulk_index_posts($body); } $index_meta['offset'] = absint($index_meta['offset'] + $posts_per_page); if ($index_meta['offset'] >= $index_meta['found_posts']) { $index_meta['offset'] = $index_meta['found_posts']; } if (defined('EP_IS_NETWORK') && EP_IS_NETWORK) { update_site_option('ep_index_meta', $index_meta); } else { update_option('ep_index_meta', $index_meta); } } else { // We are done (with this site) if (defined('EP_IS_NETWORK') && EP_IS_NETWORK) { if (empty($index_meta['site_stack'])) { delete_site_option('ep_index_meta'); $sites = ep_get_sites(); $indexes = array(); foreach ($sites as $site) { switch_to_blog($site['blog_id']); $indexes[] = ep_get_index_name(); restore_current_blog(); } ep_create_network_alias($indexes); } else { $index_meta['offset'] = (int) $query->found_posts; } } else { $index_meta['offset'] = (int) $query->found_posts; delete_option('ep_index_meta'); } } } else { if (defined('EP_IS_NETWORK') && EP_IS_NETWORK) { update_site_option('ep_index_meta', $index_meta); } else { update_option('ep_index_meta', $index_meta); } } if (defined('EP_IS_NETWORK') && EP_IS_NETWORK) { restore_current_blog(); } wp_send_json_success($index_meta); }