Changeset 60838
- Timestamp:
- 09/30/2025 05:06:32 PM (5 weeks ago)
- Location:
- branches/4.8
- Files:
-
- 11 edited
-
. (modified) (1 prop)
-
src/wp-admin/js/customize-nav-menus.js (modified) (2 diffs)
-
src/wp-admin/js/nav-menu.js (modified) (2 diffs)
-
src/wp-includes/class-wp-customize-nav-menus.php (modified) (3 diffs)
-
src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php (modified) (11 diffs)
-
src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php (modified) (1 diff)
-
src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php (modified) (1 diff)
-
src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php (modified) (4 diffs)
-
tests/phpunit/tests/customize/nav-menu-item-setting.php (modified) (2 diffs)
-
tests/phpunit/tests/customize/nav-menus.php (modified) (4 diffs)
-
tests/phpunit/tests/rest-api/rest-users-controller.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/4.8
- Property svn:mergeinfo changed
/trunk merged: 60814-60816
- Property svn:mergeinfo changed
-
branches/4.8/src/wp-admin/js/customize-nav-menus.js
r41057 r60838 517 517 } 518 518 519 this.currentMenuControl.addItemToMenu( menu_item.attributes ); 519 // Leave the title as empty to reuse the original title as a placeholder if set. 520 var nav_menu_item = Object.assign( {}, menu_item.attributes ); 521 if ( nav_menu_item.title === nav_menu_item.original_title ) { 522 nav_menu_item.title = ''; 523 } 524 525 this.currentMenuControl.addItemToMenu( nav_menu_item ); 520 526 521 527 $( menuitemTpl ).find( '.menu-item-handle' ).addClass( 'item-added' ); … … 2641 2647 { 2642 2648 nav_menu_term_id: menuControl.params.menu_id, 2643 original_title: item.title,2644 2649 position: position 2645 2650 } -
branches/4.8/src/wp-admin/js/nav-menu.js
r39928 r60838 1170 1170 1171 1171 eventOnClickMenuSave : function() { 1172 var locs = '',1173 menuName = $('#menu-name'),1174 menuNameVal = menuName.val(); 1175 // Cancel and warn if invalid menu name 1172 var menuName = $('#menu-name'), 1173 menuNameVal = menuName.val(); 1174 1175 // Cancel and warn if invalid menu name. 1176 1176 if( !menuNameVal || menuNameVal == menuName.attr('title') || !menuNameVal.replace(/\s+/, '') ) { 1177 1177 menuName.parent().addClass('form-invalid'); 1178 1178 return false; 1179 1179 } 1180 // Copy menu theme locations 1180 // Copy menu theme locations. 1181 // Note: This appears to be dead code since #nav-menu-theme-locations no longer exists, perhaps removed in r32842. 1182 var $updateNavMenu = $('#update-nav-menu'); 1181 1183 $('#nav-menu-theme-locations select').each(function() { 1182 locs += '<input type="hidden" name="' + this.name + '" value="' + $(this).val() + '" />'; 1183 }); 1184 $('#update-nav-menu').append( locs ); 1185 // Update menu item position data 1184 $updateNavMenu.append( 1185 $( '<input>', { 1186 type: 'hidden', 1187 name: this.name, 1188 value: $( this ).val() 1189 } ) 1190 ); 1191 }); 1192 // Update menu item position data. 1186 1193 api.menuList.find('.menu-item-data-position').val( function(index) { return index + 1; } ); 1187 1194 window.onbeforeunload = null; … … 1223 1230 1224 1231 if( ! $items.length ) { 1225 $('.categorychecklist', panel).html( '<li><p>' + navMenuL10n.noResultsFound + '</p></li>' ); 1232 var li = $( '<li>' ); 1233 var p = $( '<p>', { text: navMenuL10n.noResultsFound } ); 1234 li.append( p ); 1235 $('.categorychecklist', panel).empty().append( li ); 1226 1236 $( '.spinner', panel ).removeClass( 'is-active' ); 1227 1237 wrapper.addClass( 'has-no-menu-item' ); -
branches/4.8/src/wp-includes/class-wp-customize-nav-menus.php
r39951 r60838 165 165 } elseif ( 'post' !== $object && 0 === $page && $post_type->has_archive ) { 166 166 // Add a post type archive link. 167 $title = $post_type->labels->archives; 167 168 $items[] = array( 168 'id' => $object . '-archive', 169 'title' => $post_type->labels->archives, 170 'type' => 'post_type_archive', 171 'type_label' => __( 'Post Type Archive' ), 172 'object' => $object, 173 'url' => get_post_type_archive_link( $object ), 169 'id' => $object_name . '-archive', 170 'title' => $title, 171 'original_title' => $title, 172 'type' => 'post_type_archive', 173 'type_label' => __( 'Post Type Archive' ), 174 'object' => $object_name, 175 'url' => get_post_type_archive_link( $object_name ), 174 176 ); 175 177 } … … 200 202 $post_title = sprintf( __( '#%d (no title)' ), $post->ID ); 201 203 } 204 205 $title = html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ); 202 206 $items[] = array( 203 'id' => "post-{$post->ID}", 204 'title' => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ), 205 'type' => 'post_type', 206 'type_label' => get_post_type_object( $post->post_type )->labels->singular_name, 207 'object' => $post->post_type, 208 'object_id' => intval( $post->ID ), 209 'url' => get_permalink( intval( $post->ID ) ), 207 'id' => "post-{$post->ID}", 208 'title' => $title, 209 'original_title' => $title, 210 'type' => 'post_type', 211 'type_label' => get_post_type_object( $post->post_type )->labels->singular_name, 212 'object' => $post->post_type, 213 'object_id' => (int) $post->ID, 214 'url' => get_permalink( (int) $post->ID ), 210 215 ); 211 216 } … … 228 233 229 234 foreach ( $terms as $term ) { 235 $title = html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ); 230 236 $items[] = array( 231 'id' => "term-{$term->term_id}", 232 'title' => html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ), 233 'type' => 'taxonomy', 234 'type_label' => get_taxonomy( $term->taxonomy )->labels->singular_name, 235 'object' => $term->taxonomy, 236 'object_id' => intval( $term->term_id ), 237 'url' => get_term_link( intval( $term->term_id ), $term->taxonomy ), 237 'id' => "term-{$term->term_id}", 238 'title' => $title, 239 'original_title' => $title, 240 'type' => 'taxonomy', 241 'type_label' => get_taxonomy( $term->taxonomy )->labels->singular_name, 242 'object' => $term->taxonomy, 243 'object_id' => (int) $term->term_id, 244 'url' => get_term_link( (int) $term->term_id, $term->taxonomy ), 238 245 ); 239 246 } -
branches/4.8/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php
r39393 r60838 59 59 'xfn' => '', 60 60 'status' => 'publish', 61 'original_title' => '',62 61 'nav_menu_term_id' => 0, // This will be supplied as the $menu_id arg for wp_update_nav_menu_item(). 63 62 '_invalid' => false, … … 225 224 */ 226 225 public function value() { 227 if ( $this->is_previewed && $this->_previewed_blog_id === get_current_blog_id() ) { 226 $type_label = null; 227 if ( $this->is_previewed && get_current_blog_id() === $this->_previewed_blog_id ) { 228 228 $undefined = new stdClass(); // Symbol. 229 229 $post_value = $this->post_value( $undefined ); … … 233 233 } else { 234 234 $value = $post_value; 235 }236 if ( ! empty( $value ) && empty( $value['original_title'] ) ) {237 $value['original_title'] = $this->get_original_title( (object) $value );238 235 } 239 236 } elseif ( isset( $this->value ) ) { … … 248 245 $is_title_empty = empty( $post->post_title ); 249 246 $value = (array) wp_setup_nav_menu_item( $post ); 247 if ( isset( $value['type_label'] ) ) { 248 $type_label = $value['type_label']; 249 } 250 250 if ( $is_title_empty ) { 251 251 $value['title'] = ''; … … 264 264 } 265 265 266 if ( ! empty( $value ) && empty( $value['type_label'] ) ) { 267 $value['type_label'] = $this->get_type_label( (object) $value ); 268 } 269 266 // These properties are read-only and are part of the setting for use in the Customizer UI. 267 if ( is_array( $value ) ) { 268 $value_obj = (object) $value; 269 $value['type_label'] = isset( $type_label ) ? $type_label : $this->get_type_label( $value_obj ); 270 $value['original_title'] = $this->get_original_title( $value_obj ); 271 } 272 273 return $value; 274 } 275 276 /** 277 * Prepares the value for editing on the client. 278 * 279 * @since 6.8.3 280 * 281 * @return array|false Value prepared for the client. 282 */ 283 public function js_value() { 284 $value = parent::js_value(); 285 if ( is_array( $value ) && isset( $value['original_title'] ) ) { 286 // Decode entities for the sake of displaying the original title as a placeholder. 287 $value['original_title'] = html_entity_decode( $value['original_title'], ENT_QUOTES, get_bloginfo( 'charset' ) ); 288 } 270 289 return $value; 271 290 } … … 278 297 * 279 298 * @param object $item Nav menu item. 280 * @return string The original title .299 * @return string The original title, without entity decoding. 281 300 */ 282 301 protected function get_original_title( $item ) { … … 304 323 } 305 324 } 306 $original_title = html_entity_decode( $original_title, ENT_QUOTES, get_bloginfo( 'charset' ) );307 325 return $original_title; 308 326 } … … 362 380 $this->value['status'] = $this->value['post_status']; 363 381 unset( $this->value['post_status'] ); 364 }365 366 if ( ! isset( $this->value['original_title'] ) ) {367 $this->value['original_title'] = $this->get_original_title( (object) $this->value );368 382 } 369 383 … … 607 621 unset( $item->position ); 608 622 609 if ( empty( $item->original_title ) ) {610 $item->original_title = $this->get_original_title( $item );611 }612 623 if ( empty( $item->title ) && ! empty( $item->original_title ) ) { 613 $item->title = $item->original_title; 624 $item->title = $item->original_title; // This is NOT entity-decoded. It comes from self::get_original_title(). 614 625 } 615 626 if ( $item->title ) { … … 662 673 * @access public 663 674 * 664 * @param array $menu_item_value The value to sanitize.675 * @param array|false $menu_item_value The value to sanitize. 665 676 * @return array|false|null Null if an input isn't valid. False if it is marked for deletion. 666 677 * Otherwise the sanitized value. … … 716 727 } 717 728 718 $menu_item_value['original_title'] = sanitize_text_field( $menu_item_value['original_title'] );719 720 729 // Apply the same filters as when calling wp_insert_post(). 721 730 $menu_item_value['title'] = wp_unslash( apply_filters( 'title_save_pre', wp_slash( $menu_item_value['title'] ) ) ); -
branches/4.8/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
r50734 r60838 345 345 346 346 foreach ( $query_result as $post ) { 347 if ( ! $this->check_read_permission( $post ) ) { 347 if ( 'edit' === $request['context'] ) { 348 $permission = $this->check_update_permission( $post ); 349 } else { 350 $permission = $this->check_read_permission( $post ); 351 } 352 353 if ( ! $permission ) { 348 354 continue; 349 355 } -
branches/4.8/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php
r54568 r60838 317 317 318 318 foreach ( $query_result as $term ) { 319 if ( 'edit' === $request['context'] && ! current_user_can( 'edit_term', $term->term_id ) ) { 320 continue; 321 } 319 322 $data = $this->prepare_item_for_response( $term, $request ); 320 323 $response[] = $this->prepare_response_for_collection( $data ); -
branches/4.8/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
r56864 r60838 185 185 186 186 if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { 187 return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) );187 return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit users.' ), array( 'status' => rest_authorization_required_code() ) ); 188 188 } 189 189 … … 283 283 284 284 foreach ( $query->results as $user ) { 285 if ( 'edit' === $request['context'] && ! current_user_can( 'edit_user', $user->ID ) ) { 286 continue; 287 } 285 288 $data = $this->prepare_item_for_response( $user, $request ); 286 289 $users[] = $this->prepare_response_for_collection( $data ); … … 378 381 } 379 382 380 if ( 'edit' === $request['context'] && ! current_user_can( ' list_users') ) {381 return new WP_Error( 'rest_ user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) );383 if ( 'edit' === $request['context'] && ! current_user_can( 'edit_user', $user->ID ) ) { 384 return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this user.' ), array( 'status' => rest_authorization_required_code() ) ); 382 385 } elseif ( ! count_user_posts( $user->ID, $types ) && ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) ) { 383 386 return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) ); … … 880 883 } 881 884 882 if ( ! empty( $schema['properties']['roles'] ) ) {885 if ( ! empty( $schema['properties']['roles'] ) && ( current_user_can( 'list_users' ) || current_user_can( 'edit_user', $user->ID ) ) ) { 883 886 // Defensively call array_values() to ensure an array is returned. 884 887 $data['roles'] = array_values( $user->roles ); -
branches/4.8/tests/phpunit/tests/customize/nav-menu-item-setting.php
r39393 r60838 90 90 'xfn' => '', 91 91 'status' => 'publish', 92 'original_title' => '',93 92 'nav_menu_term_id' => 0, 94 93 '_invalid' => false, … … 506 505 'xfn' => 'hello inject', 507 506 'status' => 'draft', 508 'original_title' => 'Hi',507 'original_title' => 'Hi<script>unfilteredHtml()</script>', 509 508 'nav_menu_term_id' => 0, 510 509 ); -
branches/4.8/tests/phpunit/tests/customize/nav-menus.php
r39924 r60838 171 171 'id' => "post-{$post_id}", 172 172 'title' => 'Post Title', 173 'original_title' => 'Post Title', 173 174 'type' => 'post_type', 174 175 'type_label' => 'Post', … … 198 199 'id' => "post-{$page_id}", 199 200 'title' => 'Page Title', 201 'original_title' => 'Page Title', 200 202 'type' => 'post_type', 201 203 'type_label' => 'Page', … … 224 226 'id' => "post-{$post_id}", 225 227 'title' => 'Post Title', 228 'original_title' => 'Post Title', 226 229 'type' => 'post_type', 227 230 'type_label' => 'Post', … … 250 253 'id' => "term-{$term_id}", 251 254 'title' => 'Term Title', 255 'original_title' => 'Term Title', 252 256 'type' => 'taxonomy', 253 257 'type_label' => 'Category', -
branches/4.8/tests/phpunit/tests/rest-api/rest-users-controller.php
r40564 r60838 857 857 $request->set_param( 'context', 'edit' ); 858 858 $response = $this->server->dispatch( $request ); 859 $this->assertErrorResponse( 'rest_ user_cannot_view', $response, 401 );859 $this->assertErrorResponse( 'rest_forbidden_context', $response, 401 ); 860 860 } 861 861
Note: See TracChangeset
for help on using the changeset viewer.