Ticket #38342: 38342-6.diff
File 38342-6.diff, 26.7 KB (added by , 8 years ago) |
---|
-
src/wp-admin/css/dashboard.css
diff --git src/wp-admin/css/dashboard.css src/wp-admin/css/dashboard.css index 72b0230..3ef5d82 100644
form.initial-form.quickpress-open input#title { 518 518 resize: none; 519 519 } 520 520 521 #quick-press.is-saving .spinner { 522 visibility: inherit; 523 } 524 521 525 /* Dashboard Quick Draft - Drafts list */ 522 526 523 527 .js #dashboard_quick_press .drafts { … … form.initial-form.quickpress-open input#title { 541 545 margin: 0 12px; 542 546 } 543 547 548 #dashboard_quick_press .drafts ul.is-placeholder li { 549 padding: 3px 0; 550 color: transparent; 551 } 552 553 @keyframes loading-fade { 554 0% { opacity: .5; } 555 50% { opacity: 1; } 556 100% { opacity: .5; } 557 } 558 559 #dashboard_quick_press .drafts ul.is-placeholder li:before, 560 #dashboard_quick_press .drafts ul.is-placeholder li:after { 561 content: ''; 562 display: block; 563 height: 13px; 564 background: #eee; 565 animation: loading-fade 1.6s ease-in-out infinite; 566 } 567 568 #dashboard_quick_press .drafts ul.is-placeholder li:before { 569 margin-bottom: 5px; 570 width: 40%; 571 } 572 573 #dashboard_quick_press .drafts ul.is-placeholder li:after { 574 width: 80%; 575 } 576 544 577 #dashboard_quick_press .drafts li { 545 578 margin-bottom: 1em; 546 579 } 580 581 #dashboard_quick_press .drafts li.is-new { 582 background-color: #fffbe5; 583 } 584 547 585 #dashboard_quick_press .drafts li time { 548 586 color: #72777c; 549 587 } -
src/wp-admin/includes/dashboard.php
diff --git src/wp-admin/includes/dashboard.php src/wp-admin/includes/dashboard.php index aab5976..4a23fc4 100644
function wp_dashboard_quick_press( $error_msg = false ) { 491 491 $post_ID = (int) $post->ID; 492 492 ?> 493 493 494 <form name="post" action="<?php echo esc_url( admin_url( 'post.php' ) ); ?>" method="post" id="quick-press" class="initial-form hide-if-no-js"> 495 496 <?php if ( $error_msg ) : ?> 497 <div class="error"><?php echo $error_msg; ?></div> 498 <?php endif; ?> 494 <form name="post" method="post" id="quick-press" class="initial-form hide-if-no-js"> 499 495 500 496 <div class="input-text-wrap" id="title-wrap"> 501 <label class=" screen-reader-textprompt" for="title" id="title-prompt-text">497 <label class="prompt" for="title" id="title-prompt-text"> 502 498 503 499 <?php 504 500 /** This filter is documented in wp-admin/edit-form-advanced.php */ 505 501 echo apply_filters( 'enter_title_here', __( 'Title' ), $post ); 506 502 ?> 507 503 </label> 508 <input type="text" name=" post_title" id="title" autocomplete="off" />504 <input type="text" name="title" id="title" autocomplete="off" /> 509 505 </div> 510 506 511 507 <div class="textarea-wrap" id="description-wrap"> 512 <label class=" screen-reader-textprompt" for="content" id="content-prompt-text"><?php _e( 'What’s on your mind?' ); ?></label>508 <label class="prompt" for="content" id="content-prompt-text"><?php _e( 'What’s on your mind?' ); ?></label> 513 509 <textarea name="content" id="content" class="mceEditor" rows="3" cols="15" autocomplete="off"></textarea> 514 510 </div> 515 516 511 <p class="submit"> 517 <input type="hidden" name="action" id="quickpost-action" value="post-quickdraft-save" /> 518 <input type="hidden" name="post_ID" value="<?php echo $post_ID; ?>" /> 519 <input type="hidden" name="post_type" value="post" /> 520 <?php wp_nonce_field( 'add-post' ); ?> 512 <div class="error inline" style="display: none;"><p></p></div> 513 <div class="spinner no-float"></div> 521 514 <?php submit_button( __( 'Save Draft' ), 'primary', 'save', false, array( 'id' => 'save-post' ) ); ?> 522 515 <br class="clear" /> 523 516 </p> 524 517 525 518 </form> 526 519 <?php 527 wp_dashboard_recent_drafts();520 echo wp_dashboard_get_recent_drafts_js_template(); 528 521 } 529 522 530 523 /** … … function wp_dashboard_recent_drafts( $drafts = false ) { 581 574 } 582 575 echo "</ul>\n</div>"; 583 576 } 577 /** 578 * Get the HTML template for the Quick Draft recent posts. 579 * 580 * @since 4.8.0 581 * 582 * @return string The template HTML. 583 */ 584 function wp_dashboard_get_recent_drafts_js_template() { 585 $template_html = '<div id="quick-press-drafts" class="drafts">'; 586 $template_html .= '<p class="view-all" style="display: none;"><a href="' . esc_url( admin_url( 'edit.php?post_status=draft' ) ) . '" aria-label="' . __( 'View all drafts' ) . '">' . _x( 'View all', 'drafts' ) . "</a></p>\n"; 587 $template_html .= '<h2 class="hide-if-no-js">' . __( 'Drafts' ) . "</h2>\n"; 588 $template_html .= '<script id="tmpl-item-quick-press-draft" type="text/template">'; 589 $template_html .= '<div class="draft-title"><a href="{{{ data.edit_link }}}" aria-label="' . esc_attr( __( 'Edit Post' ) ) . '">{{ data.title }}</a>'; 590 $template_html .= '<time datetime="{{ data.date.raw }}">{{ data.date.rendered }}</time></div>'; 591 $template_html .= '{{{ data.content }}}'; 592 $template_html .= '</script>'; 593 $template_html .= '<ul class="drafts-list is-placeholder">'; 594 595 // Add a placeholder for each draft. 596 $query_args = array( 597 'post_type' => 'post', 598 'post_status' => 'draft', 599 'author' => get_current_user_id(), 600 'posts_per_page' => 4, 601 'fields' => 'ids', 602 'no_found_rows' => true, 603 ); 604 605 /** This filter is documented in wp-admin/includes/dashboard.php */ 606 $query_args = apply_filters( 'dashboard_recent_drafts_query_args', $query_args ); 607 608 $count_query = new WP_Query( $query_args ); 609 if ( $count_query->have_posts() ) { 610 for ( $i = 0; $i < ($count_query->post_count ? $count_query->post_count : 4 ); $i++ ) { 611 $template_html .= '<li><span class="screen-reader-text">' . esc_html( __( 'Loading…' ) ) . '</span></li>'; 612 } 613 } 614 $template_html .= '</ul></div>'; 615 616 return $template_html; 617 } 584 618 585 619 /** 586 620 * Outputs a row for the Recent Comments widget. -
src/wp-admin/js/dashboard.js
diff --git src/wp-admin/js/dashboard.js src/wp-admin/js/dashboard.js index fa100dd..9a11c4f 100644
1 /* global pagenow, ajaxurl, postboxes, wpActiveEditor:true */2 var ajaxWidgets, ajaxPopulateWidgets , quickPressLoad;1 /* global _, wp, quickPress, pagenow, ajaxurl, postboxes, wpActiveEditor:true */ 2 var ajaxWidgets, ajaxPopulateWidgets; 3 3 4 4 jQuery(document).ready( function($) { 5 5 var welcomePanel = $( '#welcome-panel' ), … … jQuery(document).ready( function($) { 61 61 62 62 postboxes.add_postbox_toggles(pagenow, { pbshow: ajaxPopulateWidgets } ); 63 63 64 /* QuickPress */65 quickPressLoad = function() {66 var act = $('#quickpost-action'), t;67 68 $( '#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]' ).prop( 'disabled' , false );69 70 t = $('#quick-press').submit( function( e ) {71 e.preventDefault();72 $('#dashboard_quick_press #publishing-action .spinner').show();73 $('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').prop('disabled', true);74 75 $.post( t.attr( 'action' ), t.serializeArray(), function( data ) {76 // Replace the form, and prepend the published post.77 $('#dashboard_quick_press .inside').html( data );78 $('#quick-press').removeClass('initial-form');79 quickPressLoad();80 highlightLatestPost();81 $('#title').focus();82 });83 84 function highlightLatestPost () {85 var latestPost = $('.drafts ul li').first();86 latestPost.css('background', '#fffbe5');87 setTimeout(function () {88 latestPost.css('background', 'none');89 }, 1000);90 }91 } );92 93 $('#publish').click( function() { act.val( 'post-quickpress-publish' ); } );94 95 $('#title, #tags-input, #content').each( function() {96 var input = $(this), prompt = $('#' + this.id + '-prompt-text');97 98 if ( '' === this.value ) {99 prompt.removeClass('screen-reader-text');100 }101 102 prompt.click( function() {103 $(this).addClass('screen-reader-text');104 input.focus();105 });106 107 input.blur( function() {108 if ( '' === this.value ) {109 prompt.removeClass('screen-reader-text');110 }111 });112 113 input.focus( function() {114 prompt.addClass('screen-reader-text');115 });116 });117 118 $('#quick-press').on( 'click focusin', function() {119 wpActiveEditor = 'content';120 });121 122 autoResizeTextarea();123 };124 quickPressLoad();125 126 64 $( '.meta-box-sortables' ).sortable( 'option', 'containment', '#wpwrap' ); 127 65 128 66 function autoResizeTextarea() { … … jQuery(document).ready( function($) { 186 124 }); 187 125 } 188 126 127 autoResizeTextarea(); 128 129 }); 130 131 wp.api.loadPromise.done( function( endpoint ) { 132 var $ = jQuery, 133 QuickPress = {}, 134 draftsCollection; 135 136 /** 137 * Models 138 */ 139 140 QuickPress.Models = {}; 141 142 QuickPress.Models.Draft = wp.api.models.Post.extend( { 143 url: endpoint.get( 'apiRoot' ) + 'wp-admin/v1/quick-drafts', 144 145 validate: function( attributes ) { 146 if ( ! attributes.title && ! attributes.content ) { 147 return 'no-content'; 148 } 149 } 150 } ); 151 152 /** 153 * Collections 154 */ 155 156 QuickPress.Collections = {}; 157 158 QuickPress.Collections.Drafts = wp.api.collections.Posts.extend( { 159 model: QuickPress.Models.Draft, 160 161 url: QuickPress.Models.Draft.prototype.url, 162 163 comparator: function( a, b ) { 164 // Sort by date descending, date is an ISO8601 string and can be 165 // compared lexicographically 166 return a.get( 'date' ).raw < b.get( 'date' ).raw; 167 } 168 } ); 169 170 /** 171 * Collections 172 */ 173 174 QuickPress.Views = {}; 175 176 QuickPress.Views.Form = wp.Backbone.View.extend( { 177 events: { 178 'click :input': 'hidePromptAndFocus', 179 'focus :input': 'hidePrompt', 180 'blur :input': 'showPrompt', 181 reset: 'showAllPrompts', 182 click: 'setActiveEditor', 183 focusin: 'setActiveEditor', 184 submit: 'submit' 185 }, 186 187 initialize: function() { 188 this.showAllPrompts(); 189 190 this.listenTo( this.model, 'invalid', this.render ); 191 this.listenTo( this.model, 'error', this.showSyncError ); 192 }, 193 194 togglePrompt: function( element, visible ) { 195 var $input = $( element ), 196 hasContent = $input.val().length > 0; 197 198 $( element ).siblings( '.prompt' ).toggleClass( 'screen-reader-text', ! visible || hasContent ); 199 }, 200 201 showAllPrompts: function() { 202 this.$el.find( ':input' ).each( _.bind( function( i, input ) { 203 // Prompt toggling must be deferred because the reset event is 204 // fired before the input values have been cleared 205 _.defer( _.bind( this.togglePrompt, this, input, true ) ); 206 }, this ) ); 207 }, 208 209 showPrompt: function( event ) { 210 this.togglePrompt( event.target, true ); 211 }, 212 213 hidePrompt: function( event ) { 214 this.togglePrompt( event.target, false ); 215 }, 216 217 hidePromptAndFocus: function( event ) { 218 this.togglePrompt( event.target, false ); 219 $( ':input', event.target ).focus(); 220 }, 221 222 setActiveEditor: function() { 223 wpActiveEditor = 'content'; 224 }, 225 226 showSyncError: function() { 227 this.syncError = true; 228 this.render(); 229 }, 230 231 submit: function( event ) { 232 var values, isValid; 233 234 delete this.syncError; 235 event.preventDefault(); 236 237 // jQuery's serializeArray returns an array of field tuples, which 238 // we need to transform into an object before sending to API 239 values = _.reduce( this.$el.serializeArray(), function( memo, field ) { 240 memo[ field.name ] = field.value; 241 return memo; 242 }, {} ); 243 244 // Ensure that by setting these fields on model that it is valid 245 // before proceeding with save 246 this.model.set( values ); 247 isValid = this.model.isValid(); 248 249 // Render again after validating to ensure error notice is accurate 250 this.render(); 251 252 // Abort save attempt if invalid 253 if ( ! isValid ) { 254 return; 255 } 256 257 // Show a spinner during the callback. 258 this.$el.addClass( 'is-saving' ); 259 260 this.model.save() 261 .always( _.bind( function() { 262 this.$el.removeClass( 'is-saving' ); 263 }, this ) ) 264 .success( _.bind( function() { 265 this.collection.add( this.model ); 266 this.model = new QuickPress.Models.Draft(); 267 this.el.reset(); 268 }, this ) ); 269 270 // Clear any previous error messages 271 this.render(); 272 }, 273 274 render: function() { 275 var $error = this.$el.find( '.error' ), 276 errorText; 277 278 if ( this.model.validationError ) { 279 // Error via submission validation 280 errorText = quickPress.l10n[ this.model.validationError ]; 281 } else if ( this.syncError ) { 282 // Error via API save failure 283 errorText = quickPress.l10n.error; 284 } 285 286 // Error notice is only visible if error text determined 287 $error.toggle( !! errorText ); 288 if ( errorText ) { 289 $error.html( $( '<p />', { text: errorText } ) ); 290 } 291 } 292 } ); 293 294 QuickPress.Views.DraftList = wp.Backbone.View.extend( { 295 initialize: function() { 296 this.listenTo( this.collection, 'sync', this.onDraftsLoaded ); 297 }, 298 299 onDraftsLoaded: function() { 300 this.listenTo( this.collection, 'add', this.renderNew ); 301 this.render(); 302 }, 303 304 renderNew: function() { 305 // Display highlight effect to first (added) item for one second 306 var $newEl = this.render().$el.find( 'li:first' ).addClass( 'is-new' ); 307 setTimeout( function() { 308 $newEl.removeClass( 'is-new' ); 309 }, 1000 ); 310 }, 311 312 render: function() { 313 // Hide drafts list if no drafts exist 314 this.$el.toggle( this.collection.length > 0 ); 315 316 // "View All" link is visible if 5 or more drafts, since we only 317 // show a maximum of 5 drafts in the list 318 this.$el.find( '.view-all' ).toggle( this.collection.length > 0 ); 319 320 // If after drafts load, this could be the first render, so remove 321 // placeholder effect and render the first four drafts 322 this.$el.find( '.drafts-list' ) 323 .removeClass( 'is-placeholder' ) 324 .html( _.map( _.take( this.collection.models, 4 ), function( draft ) { 325 return new QuickPress.Views.DraftListItem( { 326 model: draft 327 } ).render().el; 328 } ) ); 329 330 return this; 331 } 332 } ); 333 334 QuickPress.Views.DraftListItem = wp.Backbone.View.extend( { 335 tagName: 'li', 336 337 template: wp.template( 'item-quick-press-draft' ), 338 339 render: function() { 340 this.$el.html( this.template( this.model.attributes ) ); 341 342 return this; 343 } 344 } ); 345 346 /** 347 * Initialize 348 */ 349 350 // Fetch drafts 351 draftsCollection = new QuickPress.Collections.Drafts(); 352 draftsCollection.fetch(); 353 354 // Drafts list is initialized but not rendered until drafts load 355 new QuickPress.Views.DraftList( { 356 el: '#quick-press-drafts', 357 collection: draftsCollection 358 } ); 359 360 new QuickPress.Views.Form( { 361 el: '#quick-press', 362 model: new QuickPress.Models.Draft(), 363 collection: draftsCollection 364 } ).render(); 189 365 } ); -
src/wp-includes/rest-api.php
diff --git src/wp-includes/rest-api.php src/wp-includes/rest-api.php index 1a7da17..e41412f 100644
function create_initial_rest_routes() { 229 229 // Settings. 230 230 $controller = new WP_REST_Settings_Controller; 231 231 $controller->register_routes(); 232 233 // Quick Drafts. 234 $controller = new WP_REST_Quick_Drafts_Controller; 235 $controller->register_routes(); 232 236 } 233 237 234 238 /** -
new file src/wp-includes/rest-api/endpoints/class-wp-rest-quick-drafts-controller.php
diff --git src/wp-includes/rest-api/endpoints/class-wp-rest-quick-drafts-controller.php src/wp-includes/rest-api/endpoints/class-wp-rest-quick-drafts-controller.php new file mode 100644 index 0000000..0084590
- + 1 <?php 2 /** 3 * REST API: WP_REST_Quick_Drafts_Controller class 4 * 5 * @package WordPress 6 * @subpackage REST_API 7 * @since 4.8.0 8 */ 9 10 /** 11 * Core class to access dashboard Quick Drafts via the REST API. 12 * 13 * @since 4.8.0 14 * 15 * @see WP_REST_Controller 16 */ 17 class WP_REST_Quick_Drafts_Controller extends WP_REST_Posts_Controller { 18 19 /** 20 * Post type. 21 * 22 * @since 4.8.0 23 * @access protected 24 * @var string 25 */ 26 protected $post_type = 'post'; 27 28 /** 29 * Constructor. 30 * 31 * @since 4.8.0 32 * @access public 33 */ 34 public function __construct() { 35 $this->namespace = 'wp-admin/v1'; 36 $this->rest_base = 'quick-drafts'; 37 $this->meta = new WP_REST_Post_Meta_Fields( $this->post_type ); 38 } 39 40 /** 41 * Registers the routes for the objects of the controller. 42 * 43 * @since 4.8.0 44 * @access public 45 * 46 * @see register_rest_route() 47 */ 48 public function register_routes() { 49 register_rest_route( $this->namespace, '/' . $this->rest_base, array( 50 array( 51 'methods' => WP_REST_Server::READABLE, 52 'callback' => array( $this, 'get_items' ), 53 'permission_callback' => array( $this, 'get_items_permissions_check' ) 54 ), 55 array( 56 'methods' => WP_REST_Server::CREATABLE, 57 'callback' => array( $this, 'create_item' ), 58 'permission_callback' => array( $this, 'create_item_permissions_check' ), 59 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), 60 ), 61 'schema' => array( $this, 'get_public_item_schema' ), 62 ) ); 63 } 64 65 /** 66 * Checks if a given request has access to read posts. 67 * 68 * @since 4.8.0 69 * @access public 70 * 71 * @param WP_REST_Request $request Full details about the request. 72 * @return true|WP_Error True if the request has read access, WP_Error object otherwise. 73 */ 74 public function get_items_permissions_check( $request ) { 75 if ( ! current_user_can( 'edit_posts' ) ) { 76 return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit these posts.' ), array( 'status' => rest_authorization_required_code() ) ); 77 } 78 79 return true; 80 } 81 82 /** 83 * Retrieves a collection of posts. 84 * 85 * @since 4.8.0 86 * @access public 87 * 88 * @param WP_REST_Request $request Full details about the request. 89 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 90 */ 91 public function get_items( $request ) { 92 $query_args = array( 93 'post_type' => 'post', 94 'post_status' => 'draft', 95 'author' => get_current_user_id(), 96 'posts_per_page' => 4, 97 'orderby' => 'modified', 98 'order' => 'DESC' 99 ); 100 101 /** 102 * Filters the post query arguments for the 'Recent Drafts' dashboard widget. 103 * 104 * @since 4.4.0 105 * 106 * @param array $query_args The query arguments for the 'Recent Drafts' dashboard widget. 107 */ 108 $query_args = apply_filters( 'dashboard_recent_drafts_query_args', $query_args ); 109 110 $posts_query = new WP_Query(); 111 $query_result = $posts_query->query( $query_args ); 112 113 $posts = array(); 114 115 foreach ( $query_result as $post ) { 116 if ( ! $this->check_read_permission( $post ) ) { 117 continue; 118 } 119 120 $data = $this->prepare_item_for_response( $post, $request ); 121 $posts[] = $this->prepare_response_for_collection( $data ); 122 } 123 124 $response = rest_ensure_response( $posts ); 125 126 return $response; 127 } 128 129 /** 130 * Checks if a given request has access to create a post. 131 * 132 * @since 4.8.0 133 * @access public 134 * 135 * @param WP_REST_Request $request Full details about the request. 136 * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. 137 */ 138 public function create_item_permissions_check( $request ) { 139 if ( ! current_user_can( 'edit_posts' ) ) { 140 return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create new posts.' ), array( 'status' => rest_authorization_required_code() ) ); 141 } 142 143 return true; 144 } 145 146 /** 147 * Creates a single post. 148 * 149 * @since 4.8.0 150 * @access public 151 * 152 * @param WP_REST_Request $request Full details about the request. 153 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 154 */ 155 public function create_item( $request ) { 156 $post = $this->prepare_item_for_database( $request ); 157 158 if ( is_wp_error( $post ) ) { 159 return $post; 160 } 161 162 $post->post_type = $this->post_type; 163 $post_id = wp_insert_post( $post, true ); 164 165 if ( is_wp_error( $post_id ) ) { 166 if ( 'db_insert_error' === $post_id->get_error_code() ) { 167 $post_id->add_data( array( 'status' => 500 ) ); 168 } else { 169 $post_id->add_data( array( 'status' => 400 ) ); 170 } 171 172 return $post_id; 173 } 174 175 $schema = $this->get_item_schema(); 176 177 $post = $this->get_post( $post_id ); 178 179 $fields_update = $this->update_additional_fields_for_object( $post, $request ); 180 181 if ( is_wp_error( $fields_update ) ) { 182 return $fields_update; 183 } 184 185 /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ 186 do_action( "rest_insert_{$this->post_type}", $post, $request, true ); 187 188 $request->set_param( 'context', 'edit' ); 189 190 $response = $this->prepare_item_for_response( $post, $request ); 191 $response = rest_ensure_response( $response ); 192 193 $response->set_status( 201 ); 194 $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $post_id ) ) ); 195 196 return $response; 197 } 198 199 /** 200 * Prepares a single post for create. 201 * 202 * @since 4.8.0 203 * @access protected 204 * 205 * @param WP_REST_Request $request Request object. 206 * @return stdClass|WP_Error Post object or WP_Error. 207 */ 208 protected function prepare_item_for_database( $request ) { 209 $prepared_post = new stdClass; 210 211 $schema = $this->get_item_schema(); 212 213 // Post title. 214 if ( ! empty( $schema['properties']['title'] ) && is_string( $request['title'] ) ) { 215 $prepared_post->post_title = wp_filter_post_kses( $request['title'] ); 216 } 217 218 // Post content. 219 if ( ! empty( $schema['properties']['content'] ) && is_string( $request['content'] ) ) { 220 $prepared_post->post_content = wp_filter_post_kses( $request['content'] ); 221 } 222 223 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ 224 return apply_filters( "rest_pre_insert_{$this->post_type}", $prepared_post, $request ); 225 226 } 227 228 /** 229 * Checks if a post can be read. 230 * 231 * Correctly handles posts with the inherit status. 232 * 233 * @since 4.8.0 234 * @access public 235 * 236 * @param object $post Post object. 237 * @return bool Whether the post can be read. 238 */ 239 public function check_read_permission( $post ) { 240 return current_user_can( 'edit_posts' ); 241 } 242 243 /** 244 * Checks if a post can be created. 245 * 246 * @since 4.8.0 247 * @access protected 248 * 249 * @param object $post Post object. 250 * @return bool Whether the post can be created. 251 */ 252 protected function check_create_permission( $post ) { 253 return current_user_can( 'edit_posts' ); 254 } 255 256 /** 257 * Prepares a single post output for response. 258 * 259 * @since 4.8.0 260 * @access public 261 * 262 * @param WP_Post $post Post object. 263 * @param WP_REST_Request $request Request object. 264 * @return WP_REST_Response Response object. 265 */ 266 public function prepare_item_for_response( $post, $request ) { 267 $GLOBALS['post'] = $post; 268 269 setup_postdata( $post ); 270 271 $schema = $this->get_item_schema(); 272 273 $data = array(); 274 275 if ( ! empty( $schema['properties']['date'] ) ) { 276 $data['date'] = array( 277 'raw' => $this->prepare_date_response( $post->post_date_gmt, $post->post_date ), 278 'rendered' => get_the_time( __( 'F j, Y' ), $post->ID ), 279 ); 280 } 281 282 if ( ! empty( $schema['properties']['title'] ) ) { 283 $data['title'] = get_the_title( $post->ID ); 284 } 285 286 if ( ! empty( $schema['properties']['content'] ) ) { 287 $data['content'] = wp_trim_words( $post->post_content, 10 ); 288 } 289 290 if ( ! empty( $schema['properties']['edit_link'] ) ) { 291 $data['edit_link'] = get_edit_post_link( $post->ID ); 292 } 293 294 $data = $this->add_additional_fields_to_object( $data, $request ); 295 296 // Wrap the data in a response object. 297 $response = rest_ensure_response( $data ); 298 299 $response->add_links( $this->prepare_links( $post ) ); 300 301 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ 302 return apply_filters( "rest_prepare_{$this->post_type}", $response, $post, $request ); 303 } 304 305 /** 306 * Retrieves the post's schema, conforming to JSON Schema. 307 * 308 * @since 4.8.0 309 * @access public 310 * 311 * @return array Item schema data. 312 */ 313 public function get_item_schema() { 314 $schema = array( 315 '$schema' => 'http://json-schema.org/draft-04/schema#', 316 'title' => $this->post_type, 317 'type' => 'object', 318 'properties' => array( 319 'title' => array( 320 'description' => __( 'The title for the object.' ), 321 'type' => 'string', 322 'arg_options' => array( 323 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database() 324 ), 325 ), 326 'content' => array( 327 'description' => __( 'The truncated content for the object.' ), 328 'type' => 'string', 329 'arg_options' => array( 330 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database() 331 ), 332 ), 333 'date' => array( 334 'description' => __( 'The date the object was published.' ), 335 'type' => 'object', 336 'readonly' => true, 337 'properties' => array( 338 'raw' => array( 339 'description' => __( 'The ISO8601 compliant date the object was published.' ), 340 'type' => 'string', 341 'format' => 'date-time', 342 'readonly' => true, 343 ), 344 'rendered' => array( 345 'description' => __( "The date the object was published, in the site's timezone." ), 346 'type' => 'string', 347 'readonly' => true, 348 ), 349 ), 350 ), 351 'edit_link' => array( 352 'description' => __( 'URL to edit the post.' ), 353 'type' => 'string', 354 'readonly' => true, 355 ), 356 ), 357 ); 358 359 return $this->add_additional_fields_schema( $schema ); 360 } 361 } -
src/wp-includes/script-loader.php
diff --git src/wp-includes/script-loader.php src/wp-includes/script-loader.php index 143bfa1..531bb0f 100644
function wp_default_scripts( &$scripts ) { 716 716 'current' => __( 'Current Color' ), 717 717 ) ); 718 718 719 $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox' ), false, 1 ); 719 $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-api', 'wp-backbone' ), false, 2 ); 720 did_action( 'init' ) && $scripts->localize( 'dashboard', 'quickPress', array( 721 'l10n' => array( 722 'no-content' => __( 'Post content cannot be empty.' ), 723 'error' => __( 'An error has occurred. Please reload the page and try again.' ) 724 ) 725 ) ); 720 726 721 727 $scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" ); 722 728 -
src/wp-settings.php
diff --git src/wp-settings.php src/wp-settings.php index 3347cc9..054001d 100644
require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-terms-controller.p 227 227 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-users-controller.php' ); 228 228 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-comments-controller.php' ); 229 229 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-settings-controller.php' ); 230 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-quick-drafts-controller.php' ); 230 231 require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-meta-fields.php' ); 231 232 require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-comment-meta-fields.php' ); 232 233 require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-post-meta-fields.php' );