PluginProbe
Gutenberg / 23.0.1
Gutenberg v23.0.1
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / experimental / guidelines / class-gutenberg-guidelines-revisions-controller.php

class-gutenberg-guidelines-revisions-controller.php in Gutenberg 23.0.1, at lib/experimental/guidelines/class-gutenberg-guidelines-revisions-controller.php

218 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Guidelines Revisions REST API Controller.
4 *
5 * Extends WP_REST_Revisions_Controller to inherit standard WordPress revision
6 * list/get behavior and adds guideline_categories to responses + a restore endpoint.
7 *
8 * @package gutenberg
9 */
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 /**
16 * REST API controller for Guidelines revisions.
17 */
18 class Gutenberg_Guidelines_Revisions_Controller extends WP_REST_Revisions_Controller {
19
20 /**
21 * The base of the parent controller's route.
22 *
23 * @var string
24 */
25 protected $parent_base;
26
27 /**
28 * Parent post type.
29 *
30 * @var string
31 */
32 protected $parent_post_type;
33
34 /**
35 * Constructor.
36 *
37 * @param string $parent_post_type Post type of the parent.
38 */
39 public function __construct( $parent_post_type = 'wp_guideline' ) {
40 parent::__construct( $parent_post_type );
41
42 // Re-set private properties from WP_REST_Revisions_Controller.
43 $this->parent_post_type = $parent_post_type;
44 $post_type_object = get_post_type_object( $parent_post_type );
45 $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
46 }
47
48 /**
49 * Registers the routes for guideline revisions.
50 *
51 * Calls parent to register standard list + single revision routes,
52 * then adds a custom restore endpoint.
53 */
54 public function register_routes() {
55 parent::register_routes();
56
57 // Register restore revision route.
58 register_rest_route(
59 $this->namespace,
60 '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)/restore',
61 array(
62 array(
63 'methods' => WP_REST_Server::CREATABLE,
64 'callback' => array( $this, 'restore_revision' ),
65 'permission_callback' => array( $this, 'restore_revision_permissions_check' ),
66 'args' => array(
67 'parent' => array(
68 'description' => __( 'The ID for the parent of the revision.', 'gutenberg' ),
69 'type' => 'integer',
70 ),
71 'id' => array(
72 'description' => __( 'Unique identifier for the revision to restore.', 'gutenberg' ),
73 'type' => 'integer',
74 ),
75 ),
76 ),
77 )
78 );
79 }
80
81 /**
82 * Prepares the revision for the REST response.
83 *
84 * Adds guideline_categories from revision meta to the standard revision response.
85 *
86 * @param WP_Post $item Post revision object.
87 * @param WP_REST_Request $request Request object.
88 * @return WP_REST_Response Response object.
89 */
90 public function prepare_item_for_response( $item, $request ) {
91 $response = parent::prepare_item_for_response( $item, $request );
92
93 if ( is_wp_error( $response ) ) {
94 return $response;
95 }
96
97 $fields = $this->get_fields_for_response( $request );
98
99 if ( rest_is_field_included( 'guideline_categories', $fields ) ) {
100 $data = $response->get_data();
101 $guideline_categories = Gutenberg_Guidelines_Post_Type::get_guideline_categories_from_meta( $item->ID );
102 $data['guideline_categories'] = ! empty( $guideline_categories ) ? $guideline_categories : new stdClass();
103 $response->set_data( $data );
104 }
105
106 // Add embeddable author link to get author name in revision history screen
107 if ( ! empty( $item->post_author ) ) {
108 $response->add_link(
109 'author',
110 rest_url( 'wp/v2/users/' . $item->post_author ),
111 array( 'embeddable' => true )
112 );
113 }
114
115 return $response;
116 }
117
118 /**
119 * Retrieves the revision's schema, conforming to JSON Schema.
120 *
121 * Adds guideline_categories to the standard revision schema.
122 *
123 * @return array Item schema data.
124 */
125 public function get_item_schema() {
126 $schema = parent::get_item_schema();
127
128 $schema['properties']['guideline_categories'] = array(
129 'description' => __( 'The guideline categories and their content.', 'gutenberg' ),
130 'type' => 'object',
131 'context' => array( 'view', 'edit' ),
132 'readonly' => true,
133 );
134
135 return $schema;
136 }
137
138 /**
139 * Checks if a given request has access to restore a revision.
140 *
141 * @param WP_REST_Request $request Full details about the request.
142 * @return true|WP_Error True if the request has access, WP_Error object otherwise.
143 */
144 public function restore_revision_permissions_check( $request ) {
145 $parent = get_post( $request['parent'] );
146 if ( ! $parent || $this->parent_post_type !== $parent->post_type ) {
147 return new WP_Error(
148 'rest_post_not_found',
149 __( 'Guidelines not found.', 'gutenberg' ),
150 array( 'status' => 404 )
151 );
152 }
153
154 $post_type = get_post_type_object( $this->parent_post_type );
155 if ( ! current_user_can( $post_type->cap->edit_posts ) ) {
156 return new WP_Error(
157 'rest_cannot_restore',
158 __( 'Sorry, you are not allowed to restore revisions.', 'gutenberg' ),
159 array( 'status' => rest_authorization_required_code() )
160 );
161 }
162
163 return true;
164 }
165
166 /**
167 * Restores a revision to the main guidelines post.
168 *
169 * Uses WordPress's native wp_restore_post_revision() which restores all
170 * revision fields, sets _edit_last meta, fires hooks, and creates a new
171 * revision for audit trail.
172 *
173 * @param WP_REST_Request $request Full details about the request.
174 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error on failure.
175 */
176 public function restore_revision( $request ) {
177 $parent = get_post( $request['parent'] );
178 if ( ! $parent || $this->parent_post_type !== $parent->post_type ) {
179 return new WP_Error(
180 'rest_post_not_found',
181 __( 'Guidelines not found.', 'gutenberg' ),
182 array( 'status' => 404 )
183 );
184 }
185
186 $revision = get_post( $request['id'] );
187 if ( ! $revision || 'revision' !== $revision->post_type || (int) $revision->post_parent !== (int) $parent->ID ) {
188 return new WP_Error(
189 'rest_revision_not_found',
190 __( 'Revision not found.', 'gutenberg' ),
191 array( 'status' => 404 )
192 );
193 }
194
195 $result = wp_restore_post_revision( $revision->ID );
196
197 if ( is_wp_error( $result ) ) {
198 return $result;
199 }
200
201 if ( ! $result ) {
202 return new WP_Error(
203 'rest_cannot_restore',
204 __( 'Could not restore revision.', 'gutenberg' ),
205 array( 'status' => 500 )
206 );
207 }
208
209 // Return the updated parent post using its registered controller for
210 // consistent response formatting including _links and field filtering.
211 $post = get_post( $parent->ID );
212 $post_type_object = get_post_type_object( $this->parent_post_type );
213 $controller = $post_type_object->get_rest_controller();
214
215 return $controller->prepare_item_for_response( $post, $request );
216 }
217 }
218