| @@ -7,10 +7,8 @@ | ||
| 7 | 7 | |
| 8 | 8 | namespace ElasticPress\Feature\Search; |
| 9 | 9 | |
| 10 | 10 | use ElasticPress\Features; |
| 11 | -use ElasticPress\Feature; | |
| 12 | -use ElasticPress\Indexable\Post\Post; | |
| 13 | 11 | use ElasticPress\Utils; |
| 14 | 12 | |
| 15 | 13 | /** |
| 16 | 14 | * Controls search weighting and search fields dashboard |
| @@ -35,11 +33,12 @@ | ||
| 35 | 33 | return; |
| 36 | 34 | } |
| 37 | 35 | |
| 38 | 36 | add_action( 'admin_menu', [ $this, 'add_weighting_submenu_page' ], 15 ); |
| 39 | - add_action( 'admin_post_ep-weighting', [ $this, 'handle_save' ] ); | |
| 40 | 37 | add_filter( 'ep_formatted_args', [ $this, 'do_weighting' ], 20, 2 ); // After date decay, etc are injected |
| 41 | 38 | add_filter( 'ep_query_weighting_fields', [ $this, 'adjust_weight_for_cross_fields' ], 10, 5 ); |
| 39 | + add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] ); | |
| 40 | + add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] ); | |
| 42 | 41 | } |
| 43 | 42 | |
| 44 | 43 | /** |
| 45 | 44 | * Returns a grouping of all the fields that support weighting for the post type |
| @@ -82,9 +81,9 @@ | ||
| 82 | 81 | $post_type_taxonomies = get_object_taxonomies( $post_type ); |
| 83 | 82 | |
| 84 | 83 | $taxonomies = array_intersect( $public_taxonomies, $post_type_taxonomies ); |
| 85 | 84 | |
| 86 | - if ( $taxonomies ) { | |
| 85 | + if ( ! empty( $taxonomies ) ) { | |
| 87 | 86 | $fields['taxonomies'] = [ |
| 88 | 87 | 'label' => __( 'Taxonomies', 'elasticpress' ), |
| 89 | 88 | 'children' => [], |
| 90 | 89 | ]; |
| @@ -99,8 +98,41 @@ | ||
| 99 | 98 | ]; |
| 100 | 99 | } |
| 101 | 100 | } |
| 102 | 101 | |
| 102 | + $fields['ep_metadata'] = [ | |
| 103 | + 'label' => 'Metadata', | |
| 104 | + 'children' => [], | |
| 105 | + ]; | |
| 106 | + | |
| 107 | + $empty_post = new \WP_Post( new \stdClass() ); | |
| 108 | + | |
| 109 | + $empty_post->post_type = $post_type; | |
| 110 | + | |
| 111 | + /** This filter is documented in includes/classes/Indexable/Post/Post.php */ | |
| 112 | + $allowed_protected_keys = apply_filters( 'ep_prepare_meta_allowed_protected_keys', [], $empty_post ); | |
| 113 | + | |
| 114 | + sort( $allowed_protected_keys, SORT_STRING ); | |
| 115 | + | |
| 116 | + /** This filter is documented in includes/classes/Indexable/Post/Post.php */ | |
| 117 | + $excluded_public_keys = apply_filters( 'ep_prepare_meta_excluded_public_keys', [], $empty_post ); | |
| 118 | + | |
| 119 | + foreach ( $allowed_protected_keys as $meta_key ) { | |
| 120 | + $key = "meta.$meta_key.value"; | |
| 121 | + | |
| 122 | + if ( in_array( $key, $excluded_public_keys, true ) ) { | |
| 123 | + continue; | |
| 124 | + } | |
| 125 | + | |
| 126 | + $required = in_array( $meta_key, $allowed_protected_keys, true ); | |
| 127 | + | |
| 128 | + $fields['ep_metadata']['children'][ $key ] = [ | |
| 129 | + 'key' => $key, | |
| 130 | + 'label' => $meta_key, | |
| 131 | + 'required' => $required, | |
| 132 | + ]; | |
| 133 | + } | |
| 134 | + | |
| 103 | 135 | /** |
| 104 | 136 | * Filter weighting fields for a post type |
| 105 | 137 | * |
| 106 | 138 | * @hook ep_weighting_fields_for_post_type |
| @@ -111,8 +143,54 @@ | ||
| 111 | 143 | return apply_filters( 'ep_weighting_fields_for_post_type', $fields, $post_type ); |
| 112 | 144 | } |
| 113 | 145 | |
| 114 | 146 | /** |
| 147 | + * Get weightable fields for all searchable post types. | |
| 148 | + * | |
| 149 | + * @since 5.0.0 | |
| 150 | + * @return array | |
| 151 | + */ | |
| 152 | + public function get_weightable_fields() { | |
| 153 | + $weightable = array(); | |
| 154 | + $post_types = Features::factory()->get_registered_feature( 'search' )->get_searchable_post_types(); | |
| 155 | + | |
| 156 | + foreach ( $post_types as $post_type ) { | |
| 157 | + $post_type_object = get_post_type_object( $post_type ); | |
| 158 | + $post_type_labels = get_post_type_labels( $post_type_object ); | |
| 159 | + | |
| 160 | + $weightable_fields = $this->get_weightable_fields_for_post_type( $post_type ); | |
| 161 | + | |
| 162 | + $groups = []; | |
| 163 | + $fields = []; | |
| 164 | + | |
| 165 | + foreach ( $weightable_fields as $group => $weightable_field ) { | |
| 166 | + $groups[] = [ | |
| 167 | + 'key' => $group, | |
| 168 | + 'label' => $weightable_field['label'], | |
| 169 | + ]; | |
| 170 | + | |
| 171 | + foreach ( $weightable_field['children'] as $field ) { | |
| 172 | + $fields[] = [ | |
| 173 | + 'group' => $group, | |
| 174 | + 'key' => $field['key'], | |
| 175 | + 'label' => $field['label'], | |
| 176 | + 'required' => isset( $field['required'] ) ? $field['required'] : false, | |
| 177 | + ]; | |
| 178 | + } | |
| 179 | + } | |
| 180 | + | |
| 181 | + $weightable[] = [ | |
| 182 | + 'key' => $post_type, | |
| 183 | + 'label' => $post_type_labels->menu_name, | |
| 184 | + 'groups' => $groups, | |
| 185 | + 'fields' => $fields, | |
| 186 | + ]; | |
| 187 | + } | |
| 188 | + | |
| 189 | + return $weightable; | |
| 190 | + } | |
| 191 | + | |
| 192 | + /** | |
| 115 | 193 | * Returns default settings for any post type |
| 116 | 194 | * |
| 117 | 195 | * Defaults to title, content, excerpt, and author name enabled with zero weight |
| 118 | 196 | * |
| @@ -192,17 +270,68 @@ | ||
| 192 | 270 | return apply_filters( 'ep_weighting_configuration', get_option( 'elasticpress_weighting', [] ) ); |
| 193 | 271 | } |
| 194 | 272 | |
| 195 | 273 | /** |
| 274 | + * Returns the current weighting configuration with defaults for any | |
| 275 | + * missing fields. | |
| 276 | + * | |
| 277 | + * @return array Current weighting configuration with defaults. | |
| 278 | + * @since 5.0.0 | |
| 279 | + */ | |
| 280 | + public function get_weighting_configuration_with_defaults() { | |
| 281 | + $search = Features::factory()->get_registered_feature( 'search' ); | |
| 282 | + | |
| 283 | + $post_types = $search->get_searchable_post_types(); | |
| 284 | + $weighting = $this->get_weighting_configuration(); | |
| 285 | + | |
| 286 | + foreach ( $post_types as $post_type ) { | |
| 287 | + $current = isset( $weighting[ $post_type ] ) ? $weighting[ $post_type ] : []; | |
| 288 | + $defaults = $this->get_post_type_default_settings( $post_type ); | |
| 289 | + | |
| 290 | + $weighting[ $post_type ] = wp_parse_args( $current, $defaults ); | |
| 291 | + } | |
| 292 | + | |
| 293 | + return $weighting; | |
| 294 | + } | |
| 295 | + | |
| 296 | + /** | |
| 297 | + * Returns the current meta mode. | |
| 298 | + * | |
| 299 | + * @return array | |
| 300 | + * @since 5.0.0 | |
| 301 | + */ | |
| 302 | + public function get_meta_mode() { | |
| 303 | + /** | |
| 304 | + * Filter meta management mode. | |
| 305 | + * | |
| 306 | + * Setting the meta mode to 'auto' will restore the pre-5.0.0 behavior | |
| 307 | + * of syncing all public meta fields, but without the ability to | |
| 308 | + * add fields to make them searchable through the UI. Weighting settings | |
| 309 | + * will need to be changed, and a sync performed, any time this value | |
| 310 | + * is changed. | |
| 311 | + * | |
| 312 | + * @hook ep_meta_mode | |
| 313 | + * @since 5.0.0 | |
| 314 | + * @param string $ep_meta_mode Meta mode. | |
| 315 | + * @return string New meta mode. | |
| 316 | + */ | |
| 317 | + return apply_filters( 'ep_meta_mode', 'manual' ); | |
| 318 | + } | |
| 319 | + | |
| 320 | + /** | |
| 196 | 321 | * Adds the submenu page for controlling weighting |
| 197 | 322 | */ |
| 198 | 323 | public function add_weighting_submenu_page() { |
| 324 | + $menu_slug = ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK && ! Utils\is_top_level_admin_context() ) ? | |
| 325 | + 'elasticpress' : | |
| 326 | + 'elasticpress-weighting'; | |
| 327 | + | |
| 199 | 328 | add_submenu_page( |
| 200 | 329 | 'elasticpress', |
| 201 | 330 | esc_html__( 'ElasticPress Search Fields & Weighting', 'elasticpress' ), |
| 202 | 331 | esc_html__( 'Search Fields & Weighting', 'elasticpress' ), |
| 203 | 332 | Utils\get_capability(), |
| 204 | - 'elasticpress-weighting', | |
| 333 | + $menu_slug, | |
| 205 | 334 | [ $this, 'render_settings_page' ] |
| 206 | 335 | ); |
| 207 | 336 | } |
| 208 | 337 | |
| @@ -211,213 +340,205 @@ | ||
| 211 | 340 | */ |
| 212 | 341 | public function render_settings_page() { |
| 213 | 342 | include EP_PATH . '/includes/partials/header.php'; ?> |
| 214 | 343 | <div class="wrap"> |
| 215 | - | |
| 216 | - <h1><?php esc_html_e( 'Manage Search Fields & Weighting', 'elasticpress' ); ?></h1> | |
| 217 | - <p><?php esc_html_e( 'Adding more weight to an item will mean it will have more presence during searches. Add more weight to the items that are more important and need more prominence during searches.', 'elasticpress' ); ?></p> | |
| 218 | - <p><?php esc_html_e( 'For example, adding more weight to the title attribute will cause search matches on the post title to appear more prominently.', 'elasticpress' ); ?></p> | |
| 219 | - | |
| 220 | - <form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post" class="weighting-settings metabox-holder"> | |
| 221 | - <input type="hidden" name="action" value="ep-weighting"> | |
| 222 | - <?php wp_nonce_field( 'save-weighting', 'ep-weighting-nonce' ); ?> | |
| 223 | - <?php | |
| 224 | - if ( isset( $_GET['settings-updated'] ) ) : // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput | |
| 225 | - if ( sanitize_key( $_GET['settings-updated'] ) ) : // phpcs:ignore WordPress.Security.NonceVerification | |
| 226 | - ?> | |
| 227 | - <div class="notice notice-success is-dismissible"> | |
| 228 | - <p><?php esc_html_e( 'Changes Saved!', 'elasticpress' ); ?></p> | |
| 229 | - </div> | |
| 230 | - <?php else : ?> | |
| 231 | - <div class="notice notice-error is-dismissible"> | |
| 232 | - <p><?php esc_html_e( 'An error occurred when saving!', 'elasticpress' ); ?></p> | |
| 233 | - </div> | |
| 234 | - <?php | |
| 235 | - endif; | |
| 236 | - endif; | |
| 237 | - | |
| 238 | - /** Features Class @var Features $features */ | |
| 239 | - $features = Features::factory(); | |
| 240 | - | |
| 241 | - /** Search Feature @var Feature\Search\Search $search */ | |
| 242 | - $search = $features->get_registered_feature( 'search' ); | |
| 243 | - | |
| 244 | - $post_types = $search->get_searchable_post_types(); | |
| 245 | - | |
| 246 | - $current_values = $this->get_weighting_configuration(); | |
| 247 | - | |
| 248 | - foreach ( $post_types as $post_type ) : | |
| 249 | - $fields = $this->get_weightable_fields_for_post_type( $post_type ); | |
| 250 | - $post_type_object = get_post_type_object( $post_type ); | |
| 251 | - ?> | |
| 252 | - <div class="postbox"> | |
| 253 | - <h2 class="hndle"><?php echo esc_html( $post_type_object->labels->menu_name ); ?></h2> | |
| 254 | - | |
| 255 | - <?php | |
| 256 | - foreach ( $fields as $field_group ) : | |
| 257 | - $this->render_settings_section( $post_type, $field_group, $current_values ); | |
| 258 | - endforeach; | |
| 259 | - ?> | |
| 260 | - </div> | |
| 261 | - <?php | |
| 262 | - endforeach; | |
| 263 | - | |
| 264 | - submit_button(); | |
| 265 | - ?> | |
| 266 | - </form> | |
| 344 | + <div id="ep-weighting-screen"></div> | |
| 267 | 345 | </div> |
| 268 | 346 | <?php |
| 269 | 347 | } |
| 270 | 348 | |
| 271 | 349 | /** |
| 272 | - * Recursively renders each settings section and its children | |
| 350 | + * Recursively renders each settings section and its children. | |
| 273 | 351 | * |
| 274 | 352 | * @param string $post_type Current post type we're rendering |
| 275 | 353 | * @param array $field Current field to render |
| 276 | 354 | * @param array $current_values Current stored weighting values |
| 355 | + * | |
| 356 | + * @deprecated | |
| 277 | 357 | */ |
| 278 | - public function render_settings_section( $post_type, $field, $current_values ) { | |
| 279 | - if ( isset( $field['children'] ) && ! empty( $field['children'] ) ) : | |
| 280 | - ?> | |
| 281 | - <div class="field-group"> | |
| 282 | - <h3><?php echo esc_html( $field['label'] ); ?></h3> | |
| 283 | - <div class="fields"> | |
| 284 | - <?php | |
| 285 | - foreach ( $field['children'] as $child ) { | |
| 286 | - $this->render_settings_section( $post_type, $child, $current_values ); | |
| 287 | - } | |
| 288 | - ?> | |
| 289 | - </div> | |
| 290 | - </div> | |
| 291 | - <?php | |
| 292 | - elseif ( isset( $field['key'] ) ) : | |
| 293 | - $key = $field['key']; | |
| 358 | + public function render_settings_section( $post_type, $field, $current_values ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed | |
| 359 | + _doing_it_wrong( | |
| 360 | + __METHOD__, | |
| 361 | + esc_html( 'Weighting sections display are now handled via React components.' ), | |
| 362 | + 'ElasticPress 5.0.0' | |
| 363 | + ); | |
| 364 | + } | |
| 294 | 365 | |
| 295 | - $post_type_settings = isset( $current_values[ $post_type ] ) ? $current_values[ $post_type ] : $this->get_post_type_default_settings( $post_type ); | |
| 366 | + /** | |
| 367 | + * Handles processing the new weighting values and saving them | |
| 368 | + * to the elasticpress.io service. | |
| 369 | + * | |
| 370 | + * @deprecated | |
| 371 | + */ | |
| 372 | + public function handle_save() { | |
| 373 | + _doing_it_wrong( | |
| 374 | + __METHOD__, | |
| 375 | + esc_html( 'Weighting settings are now updated using the REST API.' ), | |
| 376 | + 'ElasticPress 5.0.0' | |
| 377 | + ); | |
| 378 | + } | |
| 296 | 379 | |
| 297 | - $weight = isset( $post_type_settings[ $key ] ) && isset( $post_type_settings[ $key ]['weight'] ) ? (int) $post_type_settings[ $key ]['weight'] : 0; | |
| 380 | + /** | |
| 381 | + * We need this method to test handle_save properly. | |
| 382 | + * | |
| 383 | + * @param string $redirect_url Redirect URL. | |
| 384 | + * @deprecated | |
| 385 | + */ | |
| 386 | + protected function redirect( $redirect_url ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed,Generic.CodeAnalysis.UnusedFunctionParameter.Found | |
| 387 | + _doing_it_wrong( | |
| 388 | + __METHOD__, | |
| 389 | + esc_html( 'Weighting settings are now updated using the REST API, and do not redirect server-side.' ), | |
| 390 | + 'ElasticPress 5.0.0' | |
| 391 | + ); | |
| 392 | + } | |
| 298 | 393 | |
| 299 | - $range_disabled = ''; | |
| 394 | + /** | |
| 395 | + * Save weighting configuration for each searchable post_type. | |
| 396 | + * | |
| 397 | + * @param array $settings weighting settings | |
| 398 | + * @return void | |
| 399 | + * @since 3.4.1 | |
| 400 | + * @deprecated | |
| 401 | + */ | |
| 402 | + public function save_weighting_configuration( $settings ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed,Generic.CodeAnalysis.UnusedFunctionParameter.Found | |
| 403 | + _doing_it_wrong( | |
| 404 | + __METHOD__, | |
| 405 | + esc_html( 'Weighting sections display are now handled via React components.' ), | |
| 406 | + 'ElasticPress 5.0.0' | |
| 407 | + ); | |
| 408 | + } | |
| 300 | 409 | |
| 301 | - $enabled = ( | |
| 302 | - isset( $post_type_settings ) && | |
| 303 | - isset( $post_type_settings[ $key ] ) && | |
| 304 | - isset( $post_type_settings[ $key ]['enabled'] ) | |
| 305 | - ) | |
| 306 | - ? boolval( $post_type_settings[ $key ]['enabled'] ) : false; | |
| 307 | - | |
| 308 | - if ( ! $enabled ) { | |
| 309 | - $range_disabled = 'disabled="disabled" '; | |
| 310 | - $weight = 0; | |
| 311 | - } | |
| 312 | - ?> | |
| 313 | - <fieldset> | |
| 314 | - <legend><?php echo esc_html( $field['label'] ); ?></legend> | |
| 315 | - | |
| 316 | - <p class="searchable"> | |
| 317 | - <input type="checkbox" value="on" <?php checked( $enabled ); ?> id="<?php echo esc_attr( "{$post_type}-{$key}-enabled" ); ?>" name="weighting[<?php echo esc_attr( $post_type ); ?>][<?php echo esc_attr( $key ); ?>][enabled]"> | |
| 318 | - <label for="<?php echo esc_attr( "{$post_type}-{$key}-enabled" ); ?>"><?php esc_html_e( 'Searchable', 'elasticpress' ); ?></label> | |
| 319 | - </p> | |
| 320 | - | |
| 321 | - <p class="weighting"> | |
| 322 | - <label for="<?php echo esc_attr( "{$post_type}-{$key}-weight" ); ?>"> | |
| 323 | - <?php esc_html_e( 'Weight: ', 'elasticpress' ); ?> | |
| 324 | - <span class="weighting-value"> | |
| 325 | - <?php echo esc_html( $weight ); ?> | |
| 326 | - </span> | |
| 327 | - </label> | |
| 328 | - <input type="range" min="1" max="100" step="1" value="<?php echo esc_attr( $weight ); ?>" id="<?php echo esc_attr( "{$post_type}-{$key}-weight" ); ?>" name="weighting[<?php echo esc_attr( $post_type ); ?>][<?php echo esc_attr( $key ); ?>][weight]" <?php echo $range_disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> | |
| 329 | - </p> | |
| 330 | - </fieldset> | |
| 331 | - <?php | |
| 332 | - endif; | |
| 410 | + /** | |
| 411 | + * Register REST routes. | |
| 412 | + * | |
| 413 | + * @return void | |
| 414 | + * @since 5.0.0 | |
| 415 | + */ | |
| 416 | + public function register_rest_routes() { | |
| 417 | + register_rest_route( | |
| 418 | + 'elasticpress/v1', | |
| 419 | + 'weighting', | |
| 420 | + [ | |
| 421 | + 'callback' => [ $this, 'update_weighting' ], | |
| 422 | + 'methods' => 'POST', | |
| 423 | + 'permission_callback' => function () { | |
| 424 | + return current_user_can( Utils\get_capability() ); | |
| 425 | + }, | |
| 426 | + ] | |
| 427 | + ); | |
| 333 | 428 | } |
| 334 | 429 | |
| 335 | 430 | /** |
| 336 | - * Handles processing the new weighting values and saving them to the elasticpress.io service | |
| 431 | + * Enqueue scripts and styles. | |
| 432 | + * | |
| 433 | + * @since 5.3.3 | |
| 434 | + * @return void | |
| 337 | 435 | */ |
| 338 | - public function handle_save() { | |
| 339 | - if ( ! isset( $_POST['ep-weighting-nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['ep-weighting-nonce'] ), 'save-weighting' ) ) { | |
| 436 | + public function admin_enqueue_scripts() { | |
| 437 | + if ( 'weighting' !== \ElasticPress\Screen::factory()->get_current_screen() ) { | |
| 340 | 438 | return; |
| 341 | 439 | } |
| 342 | 440 | |
| 343 | - if ( ! current_user_can( Utils\get_capability() ) ) { | |
| 344 | - return; | |
| 345 | - } | |
| 441 | + wp_enqueue_style( | |
| 442 | + 'ep_weighting_styles', | |
| 443 | + EP_URL . 'dist/css/weighting-script.css', | |
| 444 | + [ 'wp-components', 'wp-edit-post' ], | |
| 445 | + Utils\get_asset_info( 'weighting-script', 'version' ) | |
| 446 | + ); | |
| 346 | 447 | |
| 347 | - $this->save_weighting_configuration( $_POST ); | |
| 448 | + wp_enqueue_script( | |
| 449 | + 'ep_weighting_script', | |
| 450 | + EP_URL . 'dist/js/weighting-script.js', | |
| 451 | + Utils\get_asset_info( 'weighting-script', 'dependencies' ), | |
| 452 | + Utils\get_asset_info( 'weighting-script', 'version' ), | |
| 453 | + true | |
| 454 | + ); | |
| 348 | 455 | |
| 349 | - $redirect_url = admin_url( 'admin.php?page=elasticpress-weighting' ); | |
| 350 | - $redirect_url = add_query_arg( 'settings-updated', true, $redirect_url ); | |
| 456 | + $api_url = esc_url_raw( rest_url( 'elasticpress/v1/weighting' ) ); | |
| 457 | + $meta_mode = $this->get_meta_mode(); | |
| 458 | + $weightable_fields = $this->get_weightable_fields(); | |
| 459 | + $weighting_configuration = $this->get_weighting_configuration_with_defaults(); | |
| 351 | 460 | |
| 352 | - $this->redirect( $redirect_url ); | |
| 353 | - } | |
| 461 | + /** | |
| 462 | + * Filter weighting dashboard options. | |
| 463 | + * | |
| 464 | + * @hook ep_weighting_options | |
| 465 | + * @param {array} $data Weighting dashboard options | |
| 466 | + * @return {array} New options array | |
| 467 | + * @since 5.1.0 | |
| 468 | + */ | |
| 469 | + $data = apply_filters( | |
| 470 | + 'ep_weighting_options', | |
| 471 | + [ | |
| 472 | + 'apiUrl' => $api_url, | |
| 473 | + 'metaMode' => $meta_mode, | |
| 474 | + 'weightableFields' => $weightable_fields, | |
| 475 | + 'weightingConfiguration' => $weighting_configuration, | |
| 476 | + ] | |
| 477 | + ); | |
| 354 | 478 | |
| 355 | - /** | |
| 356 | - * We need this method to test handle_save properly. | |
| 357 | - * | |
| 358 | - * @param string $redirect_url Redirect URL. | |
| 359 | - */ | |
| 360 | - protected function redirect( $redirect_url ) { | |
| 361 | - // @codeCoverageIgnoreStart | |
| 362 | - wp_safe_redirect( $redirect_url ); | |
| 363 | - exit(); | |
| 364 | - // @codeCoverageIgnoreEnd | |
| 479 | + wp_localize_script( | |
| 480 | + 'ep_weighting_script', | |
| 481 | + 'epWeighting', | |
| 482 | + $data | |
| 483 | + ); | |
| 484 | + | |
| 485 | + wp_set_script_translations( 'ep_weighting_script', 'elasticpress' ); | |
| 365 | 486 | } |
| 366 | 487 | |
| 367 | 488 | /** |
| 368 | - * Save weighting configuration for each searchable post_type | |
| 489 | + * Handles processing the new weighting values and saving them. | |
| 369 | 490 | * |
| 370 | - * @param array $settings weighting settings | |
| 371 | - * | |
| 372 | - * @return array final settings | |
| 373 | - * @since 3.4.1 | |
| 491 | + * @param \WP_Rest_Request $request REST API request. | |
| 492 | + * @return array | |
| 493 | + * @since 5.0.0 | |
| 374 | 494 | */ |
| 375 | - public function save_weighting_configuration( $settings ) { | |
| 376 | - $new_config = array(); | |
| 377 | - $previous_config_formatted = array(); | |
| 378 | - $current_config = $this->get_weighting_configuration(); | |
| 495 | + public function update_weighting( $request = null ) { | |
| 496 | + $meta_mode = $this->get_meta_mode(); | |
| 497 | + $weighting = $request->get_json_params(); | |
| 379 | 498 | |
| 380 | - foreach ( $current_config as $post_type => $post_type_weighting ) { | |
| 381 | - // This also ensures the string is safe, since this would return false otherwise | |
| 382 | - if ( ! post_type_exists( $post_type ) ) { | |
| 383 | - continue; | |
| 384 | - } | |
| 499 | + $post_types = Features::factory()->get_registered_feature( 'search' )->get_searchable_post_types(); | |
| 385 | 500 | |
| 386 | - // We need a way to know if fields have been explicitly set before, let's compare a previous state against $_POST['weighting'] | |
| 387 | - foreach ( $post_type_weighting as $weighting_field => $weighting_values ) { | |
| 388 | - $previous_config_formatted[ $post_type ][ sanitize_text_field( $weighting_field ) ] = [ | |
| 389 | - 'weight' => isset( $settings['weighting'][ $post_type ][ $weighting_field ]['weight'] ) ? intval( $settings['weighting'][ $post_type ][ $weighting_field ]['weight'] ) : 0, | |
| 390 | - 'enabled' => isset( $settings['weighting'][ $post_type ][ $weighting_field ]['enabled'] ) && 'on' === $settings['weighting'][ $post_type ][ $weighting_field ]['enabled'] ? true : false, | |
| 391 | - ]; | |
| 501 | + // Add default fields for post types not sent. | |
| 502 | + foreach ( $post_types as $post_type ) { | |
| 503 | + if ( ! isset( $weighting[ $post_type ] ) ) { | |
| 504 | + $weighting[ $post_type ] = []; | |
| 392 | 505 | } |
| 393 | 506 | } |
| 394 | 507 | |
| 395 | - $search = Features::factory()->get_registered_feature( 'search' ); | |
| 396 | - $post_types = $search->get_searchable_post_types(); | |
| 508 | + /** | |
| 509 | + * If metadata is not being managed manually, remove any custom | |
| 510 | + * fields that have not been registered as weightable fields. | |
| 511 | + */ | |
| 512 | + if ( 'manual' !== $meta_mode ) { | |
| 513 | + foreach ( $weighting as $post_type => $fields ) { | |
| 514 | + $weightable_fields = $this->get_weightable_fields_for_post_type( $post_type ); | |
| 397 | 515 | |
| 398 | - foreach ( $post_types as $post_type ) { | |
| 399 | - // This also ensures the string is safe, since this would return false otherwise | |
| 400 | - if ( ! post_type_exists( $post_type ) ) { | |
| 401 | - continue; | |
| 402 | - } | |
| 516 | + foreach ( $fields as $key => $value ) { | |
| 517 | + $is_weightable = false; | |
| 403 | 518 | |
| 404 | - /** override default post_type settings while saving */ | |
| 405 | - $new_config[ $post_type ] = array(); | |
| 519 | + foreach ( $weightable_fields as $group ) { | |
| 520 | + if ( isset( $group['children'][ $key ] ) ) { | |
| 521 | + $is_weightable = true; | |
| 522 | + continue; | |
| 523 | + } | |
| 524 | + } | |
| 406 | 525 | |
| 407 | - if ( isset( $settings['weighting'][ $post_type ] ) ) { | |
| 408 | - foreach ( $settings['weighting'][ $post_type ] as $weighting_field => $weighting_values ) { | |
| 409 | - $new_config[ $post_type ][ sanitize_text_field( $weighting_field ) ] = [ | |
| 410 | - 'weight' => isset( $weighting_values['weight'] ) ? intval( $weighting_values['weight'] ) : 0, | |
| 411 | - 'enabled' => isset( $weighting_values['enabled'] ) && 'on' === $weighting_values['enabled'] ? true : false, | |
| 412 | - ]; | |
| 526 | + if ( ! $is_weightable ) { | |
| 527 | + unset( $weighting[ $post_type ][ $key ] ); | |
| 528 | + } | |
| 413 | 529 | } |
| 414 | 530 | } |
| 415 | 531 | } |
| 416 | 532 | |
| 417 | - $final_config = array_replace_recursive( $previous_config_formatted, $new_config ); | |
| 533 | + // Cleanup any post type sent (or added via filters) that does not exist. | |
| 534 | + foreach ( $weighting as $post_type => $fields ) { | |
| 535 | + if ( ! post_type_exists( $post_type ) ) { | |
| 536 | + unset( $weighting[ $post_type ] ); | |
| 537 | + } | |
| 538 | + } | |
| 418 | 539 | |
| 419 | - update_option( 'elasticpress_weighting', $final_config ); | |
| 540 | + update_option( 'elasticpress_weighting', $weighting ); | |
| 420 | 541 | |
| 421 | 542 | /** |
| 422 | 543 | * Fires right after the weighting configuration is saved. |
| 423 | 544 | * |
| @@ -425,9 +546,12 @@ | ||
| 425 | 546 | * @hook ep_saved_weighting_configuration |
| 426 | 547 | */ |
| 427 | 548 | do_action( 'ep_saved_weighting_configuration' ); |
| 428 | 549 | |
| 429 | - return $final_config; | |
| 550 | + return [ | |
| 551 | + 'data' => $weighting, | |
| 552 | + 'success' => true, | |
| 553 | + ]; | |
| 430 | 554 | } |
| 431 | 555 | |
| 432 | 556 | /** |
| 433 | 557 | * Iterates through arrays in the formatted args to find "fields" and injects weighting values |
| @@ -448,9 +572,9 @@ | ||
| 448 | 572 | } |
| 449 | 573 | } |
| 450 | 574 | |
| 451 | 575 | foreach ( $fieldset['fields'] as $key => $field ) { |
| 452 | - if ( isset( $weights[ $field ] ) && false !== $weights[ $field ]['enabled'] ) { | |
| 576 | + if ( isset( $weights[ $field ]['enabled'] ) && false !== $weights[ $field ]['enabled'] ) { | |
| 453 | 577 | $weight = (int) $weights[ $field ]['weight']; |
| 454 | 578 | |
| 455 | 579 | if ( 0 !== $weight ) { |
| 456 | 580 | if ( 'author_name' === $field ) { |
| @@ -526,9 +650,9 @@ | ||
| 526 | 650 | * |
| 527 | 651 | * @hook ep_weighting_configuration_for_search |
| 528 | 652 | * @param {array} $weight_config Current weight config |
| 529 | 653 | * @param {array} $args WP Query arguments |
| 530 | - * @return {array} New configutation | |
| 654 | + * @return {array} New configuration | |
| 531 | 655 | */ |
| 532 | 656 | $weight_config = apply_filters( 'ep_weighting_configuration_for_search', $weight_config, $args ); |
| 533 | 657 | |
| 534 | 658 | if ( ! isset( $weight_config[ $post_type ] ) ) { |
| @@ -550,9 +674,9 @@ | ||
| 550 | 674 | $fields = array_diff_key( $weights, $ignore_keys ); |
| 551 | 675 | |
| 552 | 676 | $found_enabled = false; |
| 553 | 677 | foreach ( $fields as $field ) { |
| 554 | - if ( filter_var( $field['enabled'], FILTER_VALIDATE_BOOLEAN ) ) { | |
| 678 | + if ( isset( $field['enabled'] ) && filter_var( $field['enabled'], FILTER_VALIDATE_BOOLEAN ) ) { | |
| 555 | 679 | $found_enabled = true; |
| 556 | 680 | break; |
| 557 | 681 | } |
| 558 | 682 | } |