PluginProbe
Assistant – Every Day Productivity Apps / 1.4.3
Assistant – Every Day Productivity Apps v1.4.3
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.4.3, at backend/src/Controllers/PostsController.php

444 lines 10.5 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 $id = wp_insert_post( $request->get_params() );
270
271 if ( ! $id || is_wp_error( $id ) ) {
272 return [
273 'error' => true,
274 ];
275 }
276
277 return $this->transform( get_post( $id ) );
278 }
279
280 /**
281 * Clones a single post.
282 */
283 public function clone_post( $request ) {
284 global $wpdb;
285
286 $post_id = absint( $request->get_param( 'id' ) );
287 $post = get_post( $post_id );
288 $current_user = wp_get_current_user();
289 $post_data = [
290 'comment_status' => $post->comment_status,
291 'ping_status' => $post->ping_status,
292 'post_author' => $current_user->ID,
293 'post_content' => $post->post_content,
294 'post_excerpt' => $post->post_excerpt,
295 'post_name' => $post->post_name . '-copy',
296 'post_parent' => $post->post_parent,
297 'post_password' => $post->post_password,
298 'post_status' => 'draft',
299 /* translators: %s: post/page title */
300 'post_title' => sprintf( _x( '%s - Copy', '%s stands for post/page title.', 'fl-assistant' ), $post->post_title ),
301 'post_type' => $post->post_type,
302 'to_ping' => $post->to_ping,
303 'menu_order' => $post->menu_order,
304 ];
305
306 $new_post_id = wp_insert_post( $post_data );
307 $post_meta = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d", $post_id ) );
308 $taxonomies = get_object_taxonomies( $post->post_type );
309
310 if ( count( $post_meta ) !== 0 ) {
311 foreach ( $post_meta as $meta_info ) {
312 $meta_key = $meta_info->meta_key;
313 $meta_value = addslashes( $meta_info->meta_value );
314 $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
315 }
316 }
317
318 foreach ( $taxonomies as $taxonomy ) {
319 $post_terms = wp_get_object_terms( $post_id, $taxonomy );
320 for ( $i = 0; $i < count( $post_terms ); $i++ ) {
321 wp_set_object_terms( $new_post_id, $post_terms[ $i ]->slug, $taxonomy, true );
322 }
323 }
324
325 return $this->transform( get_post( $new_post_id ) );
326 }
327
328 /**
329 * Updates a single post based on the specified action.
330 */
331 public function update_post( $request ) {
332 $id = $request->get_param( 'id' );
333 $action = $request->get_param( 'action' );
334
335 if ( ! current_user_can( 'edit_post', $id ) ) {
336 return rest_ensure_response(
337 [
338 'error' => true,
339 ]
340 );
341 }
342
343 switch ( $action ) {
344 case 'data':
345 $data = (array) $request->get_param( 'data' );
346 if ( isset( $data['meta'] ) ) {
347 $this->update_post_meta( $id, $data['meta'] );
348 unset( $data['meta'] );
349 }
350 if ( isset( $data['terms'] ) ) {
351 $this->update_post_terms( $id, $data['terms'] );
352 unset( $data['terms'] );
353 }
354 if ( isset( $data['thumbnail'] ) ) {
355 if ( '0' === $data['thumbnail'] ) {
356 delete_post_meta( $id, '_thumbnail_id' );
357 } else {
358 set_post_thumbnail( $id, $data['thumbnail'] );
359 }
360
361 unset( $data['thumbnail'] );
362 }
363 wp_update_post(
364 array_merge(
365 $data,
366 [
367 'ID' => $id,
368 ]
369 )
370 );
371 break;
372 case 'meta':
373 $data = (array) $request->get_param( 'data' );
374 $this->update_post_meta( $id, $data );
375 break;
376 case 'terms':
377 $data = (array) $request->get_param( 'data' );
378 $this->update_post_terms( $id, $data );
379 break;
380 case 'trash':
381 if ( ! EMPTY_TRASH_DAYS ) {
382 wp_delete_post( $id );
383 } else {
384 wp_trash_post( $id );
385 }
386 break;
387 case 'untrash':
388 wp_untrash_post( $id );
389 break;
390
391 }
392
393 $updated_post = get_post( $id );
394
395 return rest_ensure_response(
396 [
397 'success' => true,
398 'post' => $updated_post ? $this->transform( $updated_post ) : null,
399 ]
400 );
401 }
402
403 /**
404 * Updates post meta values for a post.
405 */
406 public function update_post_meta( $id, $meta ) {
407 foreach ( $meta as $key => $value ) {
408 update_post_meta( $id, $key, $value );
409 }
410 }
411
412 /**
413 * Updates terms for a post.
414 */
415 public function update_post_terms( $id, $terms ) {
416 foreach ( $terms as $taxonomy => $ids ) {
417 wp_set_post_terms( $id, $ids, $taxonomy, false );
418 }
419 }
420
421 /**
422 * Deletes a single post based on the specified ID.
423 */
424 public function delete_post( $request ) {
425 $id = $request->get_param( 'id' );
426
427 if ( ! current_user_can( 'edit_post', $id ) ) {
428 return rest_ensure_response(
429 [
430 'error' => true,
431 ]
432 );
433 }
434
435 wp_delete_post( $id );
436
437 return rest_ensure_response(
438 [
439 'success' => true,
440 ]
441 );
442 }
443 }
444