| @@ -7,10 +7,14 @@ | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | namespace ElasticPress\Screen; |
| 10 | 10 | |
| 11 | +use ElasticPress\Elasticsearch; | |
| 12 | +use ElasticPress\Indexables; | |
| 11 | 13 | use ElasticPress\IndexHelper; |
| 14 | +use ElasticPress\REST; | |
| 12 | 15 | use ElasticPress\Screen; |
| 16 | +use ElasticPress\Stats; | |
| 13 | 17 | use ElasticPress\Utils; |
| 14 | 18 | |
| 15 | 19 | if ( ! defined( 'ABSPATH' ) ) { |
| 16 | 20 | exit; // Exit if accessed directly. |
| @@ -26,105 +30,13 @@ | ||
| 26 | 30 | /** |
| 27 | 31 | * Initialize class |
| 28 | 32 | */ |
| 29 | 33 | public function setup() { |
| 30 | - add_action( 'wp_ajax_ep_index', [ $this, 'action_wp_ajax_ep_index' ] ); | |
| 31 | - add_action( 'wp_ajax_ep_index_status', [ $this, 'action_wp_ajax_ep_index_status' ] ); | |
| 32 | - add_action( 'wp_ajax_ep_cancel_index', [ $this, 'action_wp_ajax_ep_cancel_index' ] ); | |
| 33 | - | |
| 34 | 34 | add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] ); |
| 35 | + add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] ); | |
| 35 | 36 | } |
| 36 | 37 | |
| 37 | 38 | /** |
| 38 | - * Getting the status of ongoing index fired by WP CLI | |
| 39 | - * | |
| 40 | - * @since 3.6.0 | |
| 41 | - */ | |
| 42 | - public function action_wp_ajax_ep_index_status() { | |
| 43 | - if ( ! check_ajax_referer( 'ep_dashboard_nonce', 'nonce', false ) || ! EP_DASHBOARD_SYNC ) { | |
| 44 | - wp_send_json_error( null, 403 ); | |
| 45 | - exit; | |
| 46 | - } | |
| 47 | - | |
| 48 | - $index_meta = Utils\get_indexing_status(); | |
| 49 | - | |
| 50 | - if ( isset( $index_meta['method'] ) && 'cli' === $index_meta['method'] ) { | |
| 51 | - wp_send_json_success( | |
| 52 | - [ | |
| 53 | - 'message' => sprintf( | |
| 54 | - /* translators: 1. Number of objects indexed, 2. Total number of objects, 3. Last object ID */ | |
| 55 | - esc_html__( 'Processed %1$d/%2$d. Last Object ID: %3$d', 'elasticpress' ), | |
| 56 | - $index_meta['offset'], | |
| 57 | - $index_meta['found_items'], | |
| 58 | - $index_meta['current_sync_item']['last_processed_object_id'] | |
| 59 | - ), | |
| 60 | - 'index_meta' => $index_meta, | |
| 61 | - ] | |
| 62 | - ); | |
| 63 | - } | |
| 64 | - | |
| 65 | - wp_send_json_success( | |
| 66 | - [ | |
| 67 | - 'is_finished' => true, | |
| 68 | - 'totals' => Utils\get_option( 'ep_last_index' ), | |
| 69 | - ] | |
| 70 | - ); | |
| 71 | - } | |
| 72 | - | |
| 73 | - /** | |
| 74 | - * Perform index | |
| 75 | - * | |
| 76 | - * @since 3.6.0 | |
| 77 | - */ | |
| 78 | - public function action_wp_ajax_ep_index() { | |
| 79 | - if ( ! check_ajax_referer( 'ep_dashboard_nonce', 'nonce', false ) || ! EP_DASHBOARD_SYNC ) { | |
| 80 | - wp_send_json_error( null, 403 ); | |
| 81 | - exit; | |
| 82 | - } | |
| 83 | - | |
| 84 | - $index_meta = Utils\get_indexing_status(); | |
| 85 | - | |
| 86 | - if ( isset( $index_meta['method'] ) && 'cli' === $index_meta['method'] ) { | |
| 87 | - $this->action_wp_ajax_ep_index_status(); | |
| 88 | - exit; | |
| 89 | - } | |
| 90 | - | |
| 91 | - IndexHelper::factory()->full_index( | |
| 92 | - [ | |
| 93 | - 'method' => 'dashboard', | |
| 94 | - 'put_mapping' => ! empty( $_REQUEST['put_mapping'] ), | |
| 95 | - 'output_method' => [ $this, 'index_output' ], | |
| 96 | - 'show_errors' => true, | |
| 97 | - 'network_wide' => 0, | |
| 98 | - ] | |
| 99 | - ); | |
| 100 | - } | |
| 101 | - | |
| 102 | - /** | |
| 103 | - * Cancel index | |
| 104 | - * | |
| 105 | - * @since 3.6.0 | |
| 106 | - */ | |
| 107 | - public function action_wp_ajax_ep_cancel_index() { | |
| 108 | - if ( ! check_ajax_referer( 'ep_dashboard_nonce', 'nonce', false ) || ! EP_DASHBOARD_SYNC ) { | |
| 109 | - wp_send_json_error( null, 403 ); | |
| 110 | - exit; | |
| 111 | - } | |
| 112 | - | |
| 113 | - $index_meta = Utils\get_indexing_status(); | |
| 114 | - | |
| 115 | - if ( isset( $index_meta['method'] ) && 'cli' === $index_meta['method'] ) { | |
| 116 | - set_transient( 'ep_wpcli_sync_interrupted', true, MINUTE_IN_SECONDS ); | |
| 117 | - wp_send_json_success(); | |
| 118 | - exit; | |
| 119 | - } | |
| 120 | - | |
| 121 | - Utils\delete_option( 'ep_index_meta' ); | |
| 122 | - | |
| 123 | - wp_send_json_success(); | |
| 124 | - } | |
| 125 | - | |
| 126 | - /** | |
| 127 | 39 | * Enqueue script. |
| 128 | 40 | * |
| 129 | 41 | * @since 3.6.0 |
| 130 | 42 | * @return void |
| @@ -135,113 +47,55 @@ | ||
| 135 | 47 | } |
| 136 | 48 | |
| 137 | 49 | wp_enqueue_script( |
| 138 | 50 | 'ep_sync_scripts', |
| 139 | - EP_URL . 'dist/js/sync-script.min.js', | |
| 51 | + EP_URL . 'dist/js/sync-script.js', | |
| 140 | 52 | Utils\get_asset_info( 'sync-script', 'dependencies' ), |
| 141 | 53 | Utils\get_asset_info( 'sync-script', 'version' ), |
| 142 | 54 | true |
| 143 | 55 | ); |
| 144 | 56 | |
| 145 | - wp_enqueue_style( 'wp-components' ); | |
| 146 | - wp_enqueue_style( 'wp-edit-post' ); | |
| 57 | + wp_set_script_translations( 'ep_sync_scripts', 'elasticpress' ); | |
| 147 | 58 | |
| 148 | 59 | wp_enqueue_style( |
| 149 | 60 | 'ep_sync_style', |
| 150 | - EP_URL . 'dist/css/sync-styles.min.css', | |
| 151 | - Utils\get_asset_info( 'sync-styles', 'dependencies' ), | |
| 152 | - Utils\get_asset_info( 'sync-styles', 'version' ) | |
| 61 | + EP_URL . 'dist/css/sync-script.css', | |
| 62 | + [ 'wp-components', 'wp-edit-post' ], | |
| 63 | + Utils\get_asset_info( 'sync-script', 'version' ) | |
| 153 | 64 | ); |
| 154 | 65 | |
| 155 | - $data = array( 'nonce' => wp_create_nonce( 'ep_dashboard_nonce' ) ); | |
| 156 | - $index_meta = Utils\get_indexing_status(); | |
| 66 | + $indexables = Indexables::factory()->get_all(); | |
| 157 | 67 | |
| 158 | - if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) { | |
| 159 | - $install_complete_url = admin_url( 'network/admin.php?page=elasticpress&install_complete' ); | |
| 160 | - $last_sync = get_site_option( 'ep_last_sync', false ); | |
| 161 | - } else { | |
| 162 | - $install_complete_url = admin_url( 'admin.php?page=elasticpress&install_complete' ); | |
| 163 | - $last_sync = get_option( 'ep_last_sync', false ); | |
| 164 | - } | |
| 68 | + $indices_comparison = Elasticsearch::factory()->get_indices_comparison(); | |
| 69 | + $indices_missing = count( $indices_comparison['missing_indices'] ) > 0; | |
| 165 | 70 | |
| 166 | - if ( isset( $_GET['do_sync'] ) && ( ! defined( 'EP_DASHBOARD_SYNC' ) || EP_DASHBOARD_SYNC ) ) { // phpcs:ignore WordPress.Security.NonceVerification | |
| 167 | - $data['auto_start_index'] = true; | |
| 168 | - } | |
| 71 | + $post_types = Indexables::factory()->get( 'post' )->get_indexable_post_types(); | |
| 72 | + $post_types = array_values( $post_types ); | |
| 169 | 73 | |
| 170 | - if ( ! empty( $index_meta ) ) { | |
| 171 | - $data['index_meta'] = $index_meta; | |
| 172 | - } | |
| 74 | + $sync_history = ! $indices_missing ? IndexHelper::factory()->get_sync_history() : []; | |
| 173 | 75 | |
| 174 | - $ep_last_index = IndexHelper::factory()->get_last_index(); | |
| 76 | + $data = [ | |
| 77 | + 'apiUrl' => rest_url( 'elasticpress/v1/sync' ), | |
| 78 | + 'autoIndex' => Utils\isset_do_sync_parameter() && ( ! defined( 'EP_DASHBOARD_SYNC' ) || EP_DASHBOARD_SYNC ), | |
| 79 | + 'indexMeta' => Utils\get_indexing_status(), | |
| 80 | + 'indexables' => array_map( fn( $indexable ) => [ $indexable->slug, $indexable->labels['plural'] ], $indexables ), | |
| 81 | + 'isEpio' => Utils\is_epio(), | |
| 82 | + 'nonce' => wp_create_nonce( 'wp_rest' ), | |
| 83 | + 'postTypes' => array_map( fn( $post_type ) => [ $post_type, get_post_type_object( $post_type )->labels->name ], $post_types ), | |
| 84 | + 'syncHistory' => $sync_history, | |
| 85 | + 'syncTrigger' => Utils\isset_do_sync_parameter() ? sanitize_text_field( wp_unslash( $_GET['do_sync'] ) ) : null, // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated | |
| 86 | + ]; | |
| 175 | 87 | |
| 176 | - if ( ! empty( $ep_last_index ) ) { | |
| 177 | - $data['ep_last_sync_date'] = ! empty( $ep_last_index['end_date_time'] ) ? $ep_last_index['end_date_time'] : false; | |
| 178 | - $data['ep_last_sync_failed'] = ! empty( $ep_last_index['failed'] ) ? true : false; | |
| 179 | - } | |
| 180 | - | |
| 181 | - /** | |
| 182 | - * Filter indexable labels used in dashboard sync UI | |
| 183 | - * | |
| 184 | - * @since 3.0 | |
| 185 | - * @hook ep_dashboard_indexable_labels | |
| 186 | - * @param {array} $labels Current indexable lables | |
| 187 | - * @return {array} New labels | |
| 188 | - */ | |
| 189 | - $data['sync_indexable_labels'] = apply_filters( | |
| 190 | - 'ep_dashboard_indexable_labels', | |
| 191 | - [ | |
| 192 | - 'post' => [ | |
| 193 | - 'singular' => esc_html__( 'Post', 'elasticpress' ), | |
| 194 | - 'plural' => esc_html__( 'Posts', 'elasticpress' ), | |
| 195 | - ], | |
| 196 | - 'term' => [ | |
| 197 | - 'singular' => esc_html__( 'Term', 'elasticpress' ), | |
| 198 | - 'plural' => esc_html__( 'Terms', 'elasticpress' ), | |
| 199 | - ], | |
| 200 | - 'user' => [ | |
| 201 | - 'singular' => esc_html__( 'User', 'elasticpress' ), | |
| 202 | - 'plural' => esc_html__( 'Users', 'elasticpress' ), | |
| 203 | - ], | |
| 204 | - 'comment' => [ | |
| 205 | - 'singular' => esc_html__( 'Comment', 'elasticpress' ), | |
| 206 | - 'plural' => esc_html__( 'Comments', 'elasticpress' ), | |
| 207 | - ], | |
| 208 | - ] | |
| 209 | - ); | |
| 210 | - | |
| 211 | - $data['ajax_url'] = admin_url( 'admin-ajax.php' ); | |
| 212 | - $data['install_sync'] = empty( $last_sync ); | |
| 213 | - $data['install_complete_url'] = esc_url( $install_complete_url ); | |
| 214 | - $data['sync_complete'] = esc_html__( 'Sync complete', 'elasticpress' ); | |
| 215 | - $data['sync_paused'] = esc_html__( 'Sync paused', 'elasticpress' ); | |
| 216 | - $data['sync_syncing'] = esc_html__( 'Syncing', 'elasticpress' ); | |
| 217 | - $data['sync_initial'] = esc_html__( 'Starting sync', 'elasticpress' ); | |
| 218 | - $data['sync_wpcli'] = esc_html__( 'WP CLI sync is occurring.', 'elasticpress' ); | |
| 219 | - $data['sync_error'] = esc_html__( 'An error occurred while syncing', 'elasticpress' ); | |
| 220 | - $data['sync_interrupted'] = esc_html__( 'Sync interrupted.', 'elasticpress' ); | |
| 221 | - $data['is_epio'] = Utils\is_epio(); | |
| 222 | - | |
| 223 | 88 | wp_localize_script( 'ep_sync_scripts', 'epDash', $data ); |
| 224 | 89 | } |
| 225 | 90 | |
| 226 | 91 | /** |
| 227 | - * Output information received from the index helper class. | |
| 92 | + * Register REST API routes. | |
| 228 | 93 | * |
| 229 | - * @param array $message Message to be outputted with its status and additional info, if needed. | |
| 94 | + * @since 5.0.0 | |
| 95 | + * @return void | |
| 230 | 96 | */ |
| 231 | - public static function index_output( $message ) { | |
| 232 | - switch ( $message['status'] ) { | |
| 233 | - case 'success': | |
| 234 | - wp_send_json_success( $message ); | |
| 235 | - break; | |
| 236 | - | |
| 237 | - case 'error': | |
| 238 | - wp_send_json_error( $message ); | |
| 239 | - break; | |
| 240 | - | |
| 241 | - default: | |
| 242 | - wp_send_json( [ 'data' => $message ] ); | |
| 243 | - break; | |
| 244 | - } | |
| 245 | - exit; | |
| 97 | + public function register_rest_routes() { | |
| 98 | + $controller = new REST\Sync(); | |
| 99 | + $controller->register_routes(); | |
| 246 | 100 | } |
| 247 | 101 | } |