PluginProbe
Assistant – Every Day Productivity Apps / 1.5.1
Assistant – Every Day Productivity Apps v1.5.1
1.5.5 trunk 0.1.0 0.2.0 0.2.1 0.2.2 0.3.0 0.3.1 0.4 0.4.1 0.4.2 0.5.0 0.5.1 0.6.0 0.7.0 0.7.0.2 0.7.0.3 0.7.0.4 0.7.0.5 0.7.0.6 0.7.0.7 0.7.0.8 0.7.0.9 0.7.1 1.0 All 71 releases
assistant / backend / src / Controllers / PostsController.php

PostsController.php in Assistant – Every Day Productivity Apps 1.5.1, at backend/src/Controllers/PostsController.php

454 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FL\Assistant\Controllers;
4
5 use FL\Assistant\Data\Repository\LabelsRepository;
6 use FL\Assistant\Data\Repository\PostsRepository;
7 use FL\Assistant\Data\Transformers\PostTransformer;
8 use FL\Assistant\System\Contracts\ControllerAbstract;
9
10 use WP_REST_Request;
11 use WP_REST_Server;
12
13 /**
14 * REST API logic for posts.
15 */
16 class PostsController extends ControllerAbstract {
17
18 protected $labels;
19 protected $posts;
20 protected $transformer;
21
22 public function __construct(
23 LabelsRepository $labels,
24 PostsRepository $posts,
25 PostTransformer $transformer
26 ) {
27 $this->labels = $labels;
28 $this->posts = $posts;
29 $this->transformer = $transformer;
30 }
31
32 /**
33 * Register routes.
34 */
35 public function register_routes() {
36 $this->route(
37 '/posts',
38 [
39 [
40 'methods' => WP_REST_Server::READABLE,
41 'callback' => [ $this, 'posts' ],
42 'permission_callback' => function () {
43 return current_user_can( 'edit_others_posts' );
44 },
45 ],
46 [
47 'methods' => WP_REST_Server::CREATABLE,
48 'callback' => [ $this, 'create_post' ],
49 'permission_callback' => function () {
50 return current_user_can( 'edit_others_posts' );
51 },
52 ],
53 ]
54 );
55
56 $this->route(
57 '/posts/hierarchical',
58 [
59 [
60 'methods' => WP_REST_Server::READABLE,
61 'callback' => [ $this, 'hierarchical_posts' ],
62 'permission_callback' => function () {
63 return current_user_can( 'edit_others_posts' );
64 },
65 ],
66 ]
67 );
68
69 $this->route(
70 '/posts/count',
71 [
72 [
73 'methods' => WP_REST_Server::READABLE,
74 'callback' => [ $this, 'posts_count' ],
75 'permission_callback' => function () {
76 return current_user_can( 'edit_others_posts' );
77 },
78 ],
79 ]
80 );
81
82 $this->route(
83 '/posts/(?P<id>\d+)',
84 [
85 [
86 'methods' => WP_REST_Server::READABLE,
87 'callback' => [ $this, 'post' ],
88 'args' => [
89 'id' => [
90 'required' => true,
91 'type' => 'number',
92 ],
93 ],
94 'permission_callback' => function () {
95 return current_user_can( 'edit_others_posts' );
96 },
97 ],
98 [
99 'methods' => WP_REST_Server::CREATABLE,
100 'callback' => [ $this, 'update_post' ],
101 'args' => [
102 'id' => [
103 'required' => true,
104 'type' => 'number',
105 ],
106 'action' => [
107 'required' => true,
108 'type' => 'string',
109 ],
110 ],
111 'permission_callback' => function () {
112 return current_user_can( 'edit_others_posts' );
113 },
114 ],
115 [
116 'methods' => WP_REST_Server::DELETABLE,
117 'callback' => [ $this, 'delete_post' ],
118 'args' => [
119 'id' => [
120 'required' => true,
121 'type' => 'number',
122 ],
123 ],
124 'permission_callback' => function () {
125 return current_user_can( 'edit_others_posts' );
126 },
127 ],
128 ]
129 );
130
131 $this->route(
132 '/posts/(?P<id>\d+)/clone',
133 [
134 [
135 'methods' => WP_REST_Server::CREATABLE,
136 'callback' => [ $this, 'clone_post' ],
137 'args' => [
138 'id' => [
139 'required' => true,
140 'type' => 'number',
141 ],
142 ],
143 'permission_callback' => function () {
144 return current_user_can( 'edit_others_posts' );
145 },
146 ],
147 ]
148 );
149 }
150
151 /**
152 * Returns an array of posts and related data.
153 */
154 public function posts( WP_REST_Request $request ) {
155
156 $params = $request->get_params();
157 $params['perm'] = 'editable';
158
159 if ( isset( $params['label'] ) && $params['label'] ) {
160 $params['post__in'] = $this->labels->get_object_ids( 'post', $params['label'] );
161 if ( ! count( $params['post__in'] ) ) {
162 $params['post__in'][] = -1; // post__in returns all posts if empty.
163 }
164 }
165
166 $pager = $this->posts->paginate( $params, $this->transformer );
167
168 return rest_ensure_response( $pager->to_array() );
169 }
170
171 /**
172 * Returns an array of posts and related data
173 * with child posts contained in the parent
174 * post's data array.
175 */
176 public function hierarchical_posts( $request ) {
177 $response = [];
178 $children = [];
179 $params = $request->get_params();
180 $posts = get_posts(
181 array_merge(
182 $params,
183 [
184 'perm' => 'editable',
185 ]
186 )
187 );
188
189 foreach ( $posts as $post ) {
190 if ( $post->post_parent ) {
191 if ( ! isset( $children[ $post->post_parent ] ) ) {
192 $children[ $post->post_parent ] = [];
193 }
194 $children [ $post->post_parent ][] = $post;
195 }
196 }
197
198 foreach ( $posts as $post ) {
199 if ( ! $post->post_parent ) {
200 $parent = $this->transform( $post );
201 $parent['children'] = $this->get_child_posts( $post, $children );
202 $response[] = $parent;
203 }
204 }
205
206 return rest_ensure_response( $response );
207 }
208
209 /**
210 * Returns an array of response data for a single post.
211 */
212 public function transform( $post ) {
213 return call_user_func( $this->transformer, $post );
214 }
215
216 /**
217 * Returns an array of child posts for the given post.
218 * A $children array must be passed to search for children.
219 */
220 public function get_child_posts( $post, $children ) {
221 if ( isset( $children[ $post->ID ] ) ) {
222 $post_children = $children[ $post->ID ];
223 foreach ( $post_children as $i => $child ) {
224 $post_children[ $i ] = $this->transform( $child );
225 $post_children[ $i ]['children'] = $this->get_child_posts( $child, $children );
226 }
227
228 return $post_children;
229 }
230
231 return [];
232 }
233
234 /**
235 * Returns an array of counts by post type.
236 */
237 public function posts_count( $request ) {
238
239 $post_types = $this->posts->get_types();
240 $response = [];
241
242 foreach ( $post_types as $slug => $label ) {
243 $counts = wp_count_posts( $slug );
244 $counts->total = $counts->publish + $counts->draft + $counts->pending + $counts->private + $counts->future;
245 $response[ $slug ] = $counts;
246 }
247
248 return rest_ensure_response( $response );
249 }
250
251 /**
252 * Returns data for a single post.
253 */
254 public function post( $request ) {
255 $id = $request->get_param( 'id' );
256
257 if ( current_user_can( 'edit_post', $id ) ) {
258 $post = get_post( $id );
259 return $this->transform( $post );
260 }
261
262 return [];
263 }
264
265 /**
266 * Creates a single post.
267 */
268 public function create_post( $request ) {
269
270 $params = $request->get_params();
271 if ( isset( $params['meta_input'] ) && is_array( $params['meta_input'] ) ) {
272 foreach ( $params['meta_input'] as $meta_key => $meta_value ) {
273 $params['meta_input'][ $meta_key ] = maybe_unserialize( $meta_value );
274 }
275 }
276
277 $id = wp_insert_post( $params );
278
279 if ( ! $id || is_wp_error( $id ) ) {
280 return [
281 'error' => true,
282 ];
283 }
284
285 return $this->transform( get_post( $id ) );
286 }
287
288 /**
289 * Clones a single post.
290 */
291 public function clone_post( $request ) {
292 global $wpdb;
293
294 $post_id = absint( $request->get_param( 'id' ) );
295 $post = get_post( $post_id );
296 $current_user = wp_get_current_user();
297 $post_data = [
298 'comment_status' => $post->comment_status,
299 'ping_status' => $post->ping_status,
300 'post_author' => $current_user->ID,
301 'post_content' => $post->post_content,
302 'post_excerpt' => $post->post_excerpt,
303 'post_name' => $post->post_name . '-copy',
304 'post_parent' => $post->post_parent,
305 'post_password' => $post->post_password,
306 'post_status' => 'draft',
307 /* translators: %s: post/page title */
308 'post_title' => sprintf( _x( '%s - Copy', '%s stands for post/page title.', 'assistant' ), $post->post_title ),
309 'post_type' => $post->post_type,
310 'to_ping' => $post->to_ping,
311 'menu_order' => $post->menu_order,
312 ];
313
314 $new_post_id = wp_insert_post( $post_data );
315 $post_meta = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d", $post_id ) );
316 $taxonomies = get_object_taxonomies( $post->post_type );
317
318 if ( count( $post_meta ) !== 0 ) {
319 foreach ( $post_meta as $meta_info ) {
320 $meta_key = $meta_info->meta_key;
321 $meta_value = addslashes( $meta_info->meta_value );
322 $wpdb->query( "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) values ({$new_post_id}, '{$meta_key}', '{$meta_value}')" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
323 }
324 }
325
326 foreach ( $taxonomies as $taxonomy ) {
327 $post_terms = wp_get_object_terms( $post_id, $taxonomy );
328 for ( $i = 0; $i < count( $post_terms ); $i++ ) {
329 wp_set_object_terms( $new_post_id, $post_terms[ $i ]->slug, $taxonomy, true );
330 }
331 }
332
333 return $this->transform( get_post( $new_post_id ) );
334 }
335
336 /**
337 * Updates a single post based on the specified action.
338 */
339 public function update_post( $request ) {
340 $id = $request->get_param( 'id' );
341 $action = $request->get_param( 'action' );
342
343 if ( ! current_user_can( 'edit_post', $id ) ) {
344 return rest_ensure_response(
345 [
346 'error' => true,
347 ]
348 );
349 }
350
351 switch ( $action ) {
352 case 'data':
353 $data = (array) $request->get_param( 'data' );
354 if ( isset( $data['meta'] ) ) {
355 $this->update_post_meta( $id, $data['meta'] );
356 unset( $data['meta'] );
357 }
358 if ( isset( $data['terms'] ) ) {
359 $this->update_post_terms( $id, $data['terms'] );
360 unset( $data['terms'] );
361 }
362 if ( isset( $data['thumbnail'] ) ) {
363 if ( '0' === $data['thumbnail'] ) {
364 delete_post_meta( $id, '_thumbnail_id' );
365 } else {
366 set_post_thumbnail( $id, $data['thumbnail'] );
367 }
368
369 unset( $data['thumbnail'] );
370 }
371 wp_update_post(
372 array_merge(
373 $data,
374 [
375 'ID' => $id,
376 ]
377 )
378 );
379 break;
380 case 'meta':
381 $data = (array) $request->get_param( 'data' );
382 $this->update_post_meta( $id, $data );
383 break;
384 case 'terms':
385 $data = (array) $request->get_param( 'data' );
386 $this->update_post_terms( $id, $data );
387 break;
388 case 'trash':
389 if ( ! EMPTY_TRASH_DAYS ) {
390 wp_delete_post( $id );
391 } else {
392 wp_trash_post( $id );
393 }
394 break;
395 case 'untrash':
396 wp_untrash_post( $id );
397 break;
398
399 }
400
401 $updated_post = get_post( $id );
402
403 return rest_ensure_response(
404 [
405 'success' => true,
406 'post' => $updated_post ? $this->transform( $updated_post ) : null,
407 ]
408 );
409 }
410
411 /**
412 * Updates post meta values for a post.
413 */
414 public function update_post_meta( $id, $meta ) {
415 foreach ( $meta as $key => $value ) {
416 update_post_meta( $id, $key, $value );
417 }
418 }
419
420 /**
421 * Updates terms for a post.
422 */
423 public function update_post_terms( $id, $terms ) {
424 foreach ( $terms as $taxonomy => $ids ) {
425 wp_set_post_terms( $id, $ids, $taxonomy, false );
426 }
427 }
428
429 /**
430 * Deletes a single post based on the specified ID.
431 */
432 public function delete_post( $request ) {
433 $params = $request->get_params();
434 $id = $params['id'];
435 $force = isset( $params['force'] ) && $params['force'];
436
437 if ( ! current_user_can( 'edit_post', $id ) ) {
438 return rest_ensure_response(
439 [
440 'error' => true,
441 ]
442 );
443 }
444
445 wp_delete_post( $id, $force );
446
447 return rest_ensure_response(
448 [
449 'success' => true,
450 ]
451 );
452 }
453 }
454