Changeset 60837
- Timestamp:
- 09/30/2025 05:06:24 PM (5 weeks ago)
- Location:
- branches/4.9
- 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) (12 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) (3 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.9
- Property svn:mergeinfo changed
/trunk merged: 60814-60816
- Property svn:mergeinfo changed
-
branches/4.9/src/wp-admin/js/customize-nav-menus.js
r42846 r60837 518 518 } 519 519 520 this.currentMenuControl.addItemToMenu( menu_item.attributes ); 520 // Leave the title as empty to reuse the original title as a placeholder if set. 521 var nav_menu_item = Object.assign( {}, menu_item.attributes ); 522 if ( nav_menu_item.title === nav_menu_item.original_title ) { 523 nav_menu_item.title = ''; 524 } 525 526 this.currentMenuControl.addItemToMenu( nav_menu_item ); 521 527 522 528 $( menuitemTpl ).find( '.menu-item-handle' ).addClass( 'item-added' ); … … 2972 2978 { 2973 2979 nav_menu_term_id: menuControl.params.menu_id, 2974 original_title: item.title,2975 2980 position: position 2976 2981 } -
branches/4.9/src/wp-admin/js/nav-menu.js
r41227 r60837 1169 1169 1170 1170 eventOnClickMenuSave : function() { 1171 var locs = '',1172 menuName = $('#menu-name'),1173 menuNameVal = menuName.val(); 1174 // Cancel and warn if invalid menu name 1171 var menuName = $('#menu-name'), 1172 menuNameVal = menuName.val(); 1173 1174 // Cancel and warn if invalid menu name. 1175 1175 if( !menuNameVal || menuNameVal == menuName.attr('title') || !menuNameVal.replace(/\s+/, '') ) { 1176 1176 menuName.parent().addClass('form-invalid'); 1177 1177 return false; 1178 1178 } 1179 // Copy menu theme locations 1179 // Copy menu theme locations. 1180 // Note: This appears to be dead code since #nav-menu-theme-locations no longer exists, perhaps removed in r32842. 1181 var $updateNavMenu = $('#update-nav-menu'); 1180 1182 $('#nav-menu-theme-locations select').each(function() { 1181 locs += '<input type="hidden" name="' + this.name + '" value="' + $(this).val() + '" />'; 1182 }); 1183 $('#update-nav-menu').append( locs ); 1184 // Update menu item position data 1183 $updateNavMenu.append( 1184 $( '<input>', { 1185 type: 'hidden', 1186 name: this.name, 1187 value: $( this ).val() 1188 } ) 1189 ); 1190 }); 1191 // Update menu item position data. 1185 1192 api.menuList.find('.menu-item-data-position').val( function(index) { return index + 1; } ); 1186 1193 window.onbeforeunload = null; … … 1222 1229 1223 1230 if( ! $items.length ) { 1224 $('.categorychecklist', panel).html( '<li><p>' + navMenuL10n.noResultsFound + '</p></li>' ); 1231 var li = $( '<li>' ); 1232 var p = $( '<p>', { text: navMenuL10n.noResultsFound } ); 1233 li.append( p ); 1234 $('.categorychecklist', panel).empty().append( li ); 1225 1235 $( '.spinner', panel ).removeClass( 'is-active' ); 1226 1236 wrapper.addClass( 'has-no-menu-item' ); -
branches/4.9/src/wp-includes/class-wp-customize-nav-menus.php
r43481 r60837 159 159 } elseif ( 'post' !== $object && 0 === $page && $post_type->has_archive ) { 160 160 // Add a post type archive link. 161 $title = $post_type->labels->archives; 161 162 $items[] = array( 162 'id' => $object . '-archive', 163 'title' => $post_type->labels->archives, 164 'type' => 'post_type_archive', 165 'type_label' => __( 'Post Type Archive' ), 166 'object' => $object, 167 'url' => get_post_type_archive_link( $object ), 163 'id' => $object_name . '-archive', 164 'title' => $title, 165 'original_title' => $title, 166 'type' => 'post_type_archive', 167 'type_label' => __( 'Post Type Archive' ), 168 'object' => $object_name, 169 'url' => get_post_type_archive_link( $object_name ), 168 170 ); 169 171 } … … 194 196 $post_title = sprintf( __( '#%d (no title)' ), $post->ID ); 195 197 } 198 199 $title = html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ); 196 200 $items[] = array( 197 'id' => "post-{$post->ID}", 198 'title' => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ), 199 'type' => 'post_type', 200 'type_label' => get_post_type_object( $post->post_type )->labels->singular_name, 201 'object' => $post->post_type, 202 'object_id' => intval( $post->ID ), 203 'url' => get_permalink( intval( $post->ID ) ), 201 'id' => "post-{$post->ID}", 202 'title' => $title, 203 'original_title' => $title, 204 'type' => 'post_type', 205 'type_label' => get_post_type_object( $post->post_type )->labels->singular_name, 206 'object' => $post->post_type, 207 'object_id' => (int) $post->ID, 208 'url' => get_permalink( (int) $post->ID ), 204 209 ); 205 210 } … … 222 227 223 228 foreach ( $terms as $term ) { 229 $title = html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ); 224 230 $items[] = array( 225 'id' => "term-{$term->term_id}", 226 'title' => html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ), 227 'type' => 'taxonomy', 228 'type_label' => get_taxonomy( $term->taxonomy )->labels->singular_name, 229 'object' => $term->taxonomy, 230 'object_id' => intval( $term->term_id ), 231 'url' => get_term_link( intval( $term->term_id ), $term->taxonomy ), 231 'id' => "term-{$term->term_id}", 232 'title' => $title, 233 'original_title' => $title, 234 'type' => 'taxonomy', 235 'type_label' => get_taxonomy( $term->taxonomy )->labels->singular_name, 236 'object' => $term->taxonomy, 237 'object_id' => (int) $term->term_id, 238 'url' => get_term_link( (int) $term->term_id, $term->taxonomy ), 232 239 ); 233 240 } -
branches/4.9/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php
r41894 r60837 57 57 'xfn' => '', 58 58 'status' => 'publish', 59 'original_title' => '',60 59 'nav_menu_term_id' => 0, // This will be supplied as the $menu_id arg for wp_update_nav_menu_item(). 61 60 '_invalid' => false, … … 212 211 */ 213 212 public function value() { 214 if ( $this->is_previewed && $this->_previewed_blog_id === get_current_blog_id() ) { 213 $type_label = null; 214 if ( $this->is_previewed && get_current_blog_id() === $this->_previewed_blog_id ) { 215 215 $undefined = new stdClass(); // Symbol. 216 216 $post_value = $this->post_value( $undefined ); … … 220 220 } else { 221 221 $value = $post_value; 222 }223 if ( ! empty( $value ) && empty( $value['original_title'] ) ) {224 $value['original_title'] = $this->get_original_title( (object) $value );225 222 } 226 223 } elseif ( isset( $this->value ) ) { … … 235 232 $is_title_empty = empty( $post->post_title ); 236 233 $value = (array) wp_setup_nav_menu_item( $post ); 234 if ( isset( $value['type_label'] ) ) { 235 $type_label = $value['type_label']; 236 } 237 237 if ( $is_title_empty ) { 238 238 $value['title'] = ''; … … 251 251 } 252 252 253 if ( ! empty( $value ) && empty( $value['type_label'] ) ) { 254 $value['type_label'] = $this->get_type_label( (object) $value ); 253 // These properties are read-only and are part of the setting for use in the Customizer UI. 254 if ( is_array( $value ) ) { 255 $value_obj = (object) $value; 256 $value['type_label'] = isset( $type_label ) ? $type_label : $this->get_type_label( $value_obj ); 257 $value['original_title'] = $this->get_original_title( $value_obj ); 255 258 } 256 259 … … 259 262 260 263 /** 264 * Prepares the value for editing on the client. 265 * 266 * @since 6.8.3 267 * 268 * @return array|false Value prepared for the client. 269 */ 270 public function js_value() { 271 $value = parent::js_value(); 272 if ( is_array( $value ) && isset( $value['original_title'] ) ) { 273 // Decode entities for the sake of displaying the original title as a placeholder. 274 $value['original_title'] = html_entity_decode( $value['original_title'], ENT_QUOTES, get_bloginfo( 'charset' ) ); 275 } 276 return $value; 277 } 278 279 /** 261 280 * Get original title. 262 281 * … … 264 283 * 265 284 * @param object $item Nav menu item. 266 * @return string The original title .285 * @return string The original title, without entity decoding. 267 286 */ 268 287 protected function get_original_title( $item ) { … … 290 309 } 291 310 } 292 $original_title = html_entity_decode( $original_title, ENT_QUOTES, get_bloginfo( 'charset' ) );293 311 return $original_title; 294 312 } … … 346 364 $this->value['status'] = $this->value['post_status']; 347 365 unset( $this->value['post_status'] ); 348 }349 350 if ( ! isset( $this->value['original_title'] ) ) {351 $this->value['original_title'] = $this->get_original_title( (object) $this->value );352 366 } 353 367 … … 587 601 unset( $item->position ); 588 602 589 if ( empty( $item->original_title ) ) {590 $item->original_title = $this->get_original_title( $item );591 }592 603 if ( empty( $item->title ) && ! empty( $item->original_title ) ) { 593 $item->title = $item->original_title; 604 $item->title = $item->original_title; // This is NOT entity-decoded. It comes from self::get_original_title(). 594 605 } 595 606 if ( $item->title ) { … … 641 652 * @since 4.3.0 642 653 * 643 * @param array $menu_item_value Thevalue to sanitize.654 * @param array|false $value The menu item value to sanitize. 644 655 * @return array|false|null|WP_Error Null or WP_Error if an input isn't valid. False if it is marked for deletion. 645 656 * Otherwise the sanitized value. … … 695 706 } 696 707 697 $menu_item_value['original_title'] = sanitize_text_field( $menu_item_value['original_title'] );698 699 708 // Apply the same filters as when calling wp_insert_post(). 700 709 -
branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
r50732 r60837 339 339 340 340 foreach ( $query_result as $post ) { 341 if ( ! $this->check_read_permission( $post ) ) { 341 if ( 'edit' === $request['context'] ) { 342 $permission = $this->check_update_permission( $post ); 343 } else { 344 $permission = $this->check_read_permission( $post ); 345 } 346 347 if ( ! $permission ) { 342 348 continue; 343 349 } -
branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php
r54569 r60837 319 319 320 320 foreach ( $query_result as $term ) { 321 if ( 'edit' === $request['context'] && ! current_user_can( 'edit_term', $term->term_id ) ) { 322 continue; 323 } 321 324 $data = $this->prepare_item_for_response( $term, $request ); 322 325 $response[] = $this->prepare_response_for_collection( $data ); -
branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
r56865 r60837 180 180 181 181 if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { 182 return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) );182 return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit users.' ), array( 'status' => rest_authorization_required_code() ) ); 183 183 } 184 184 … … 294 294 295 295 foreach ( $query->results as $user ) { 296 if ( 'edit' === $request['context'] && ! current_user_can( 'edit_user', $user->ID ) ) { 297 continue; 298 } 299 296 300 $data = $this->prepare_item_for_response( $user, $request ); 297 301 $users[] = $this->prepare_response_for_collection( $data ); … … 388 392 } 389 393 390 if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { 391 return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) ); 392 } elseif ( ! count_user_posts( $user->ID, $types ) && ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) ) { 394 if ( 'edit' === $request['context'] && ! current_user_can( 'edit_user', $user->ID ) ) { 395 return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this user.' ), array( 'status' => rest_authorization_required_code() ) ); 396 } 397 398 if ( ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) && ! count_user_posts( $user->ID, $types ) ) { 393 399 return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) ); 394 400 } … … 891 897 } 892 898 893 if ( in_array( 'roles', $fields, true ) ) {899 if ( in_array( 'roles', $fields, true ) && ( current_user_can( 'list_users' ) || current_user_can( 'edit_user', $user->ID ) ) ) { 894 900 // Defensively call array_values() to ensure an array is returned. 895 901 $data['roles'] = array_values( $user->roles ); -
branches/4.9/tests/phpunit/tests/customize/nav-menu-item-setting.php
r41697 r60837 90 90 'xfn' => '', 91 91 'status' => 'publish', 92 'original_title' => '',93 92 'nav_menu_term_id' => 0, 94 93 '_invalid' => false, … … 544 543 'xfn' => 'hello inject', 545 544 'status' => 'draft', 546 'original_title' => 'Hi',545 'original_title' => 'Hi<script>unfilteredHtml()</script>', 547 546 'nav_menu_term_id' => 0, 548 547 ); … … 842 841 'xfn' => '', 843 842 'status' => 'publish', 844 'original_title' => '',845 843 'nav_menu_term_id' => 0, 846 844 '_invalid' => false, -
branches/4.9/tests/phpunit/tests/customize/nav-menus.php
r43481 r60837 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.9/tests/phpunit/tests/rest-api/rest-users-controller.php
r43445 r60837 934 934 $request->set_param( 'context', 'edit' ); 935 935 $response = $this->server->dispatch( $request ); 936 $this->assertErrorResponse( 'rest_ user_cannot_view', $response, 401 );936 $this->assertErrorResponse( 'rest_forbidden_context', $response, 401 ); 937 937 } 938 938
Note: See TracChangeset
for help on using the changeset viewer.