PluginProbe
Post Grid Gutenberg Blocks – PostX / 5.1.1
Post Grid Gutenberg Blocks – PostX v5.1.1
5.1.1 5.1.0 5.0.41 5.0.39 5.0.38 5.0.37 5.0.36 5.0.35 5.0.34 5.0.33 5.0.32 5.0.31 5.0.30 5.0.29 5.0.28 5.0.27 5.0.26 5.0.25 5.0.23 5.0.24 5.0.22 5.0.21 5.0.20 5.0.19 5.0.18 All 240 releases
ultimate-post / addons / dynamic_content / includes / DCController.php

DCController.php in Post Grid Gutenberg Blocks – PostX 5.1.1, at addons/dynamic_content/includes/DCController.php

311 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace ULTP;
3
4 use WP_REST_Response;
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit;
8 }
9
10 /**
11 *
12 * Dynamic Content
13 *
14 * @package ULTP\Addons
15 * @since 4.1.1
16 */
17 final class DCController {
18
19 /**
20 * Setup class.
21 *
22 * @since v.4.1.1
23 */
24 public function __construct() {
25 require_once ULTP_PATH . '/addons/dynamic_content/includes/DCService.php';
26
27 // PostX Pro before 1.9.0 does not answer the custom field filters below.
28 if ( \ULTP\Includes\Durbin\Xpo::is_pro_before_1_9_0() ) {
29 require_once ULTP_PATH . '/addons/dynamic_content/includes/DCLegacyFields.php';
30 new DCLegacyFields();
31 }
32
33 add_action( 'rest_api_init', array( $this, 'register_routes' ) );
34 }
35
36 public function register_routes() {
37 register_rest_route(
38 'ultp/v2',
39 '/get_dynamic_content/',
40 array(
41 array(
42 'methods' => 'POST',
43 'callback' => array( $this, 'handle_dynamic_data' ),
44 // there is an unauthenticated route for fetching user data against post, that can be used to fetch user sensitive data like user email, user password reset token hast ( user_activation_key ) , private or draft post title e.t.c as unauthenticated user.
45 'permission_callback' => function ( $request ) {
46 $post_id = $this->get_request_post_id( $request );
47
48 if ( ! $this->user_can_access_post( $post_id ) ) {
49 return false;
50 }
51
52 $data_type = method_exists( $request, 'get_param' )
53 ? $request->get_param('data_type')
54 : ( isset( $request['data_type'] ) ? $request['data_type'] : '' );
55
56 // Restrict author_info to users who can edit the author OR admins
57 if ( $data_type === 'author_info' ) {
58 $post = get_post( $post_id );
59 $author_id = $post ? (int) $post->post_author : 0;
60 if ( ! current_user_can( 'edit_user', $author_id ) && ! current_user_can( 'manage_options' ) ) {
61 return false;
62 }
63 }
64
65 return true;
66 },
67 'args' => array(),
68 ),
69 )
70 );
71
72 register_rest_route(
73 'ultp/v2',
74 '/get_custom_fields/',
75 array(
76 array(
77 'methods' => 'POST',
78 'callback' => array( $this, 'handle_custom_fields' ),
79 // custom field keys can reveal the meta-field schema of posts the caller shouldn't be able to see (private/draft/pending/scheduled/password-protected), so require the same access check as get_dynamic_content.
80 'permission_callback' => function ( $request ) {
81 return $this->user_can_access_post( $this->get_request_post_id( $request ) );
82 },
83 'args' => array(),
84 ),
85 )
86 );
87 }
88
89 /**
90 * Reads the `post_id` request param, compatible with both WP_REST_Request and plain array access.
91 *
92 * @param WP_REST_Request|array $request Request object or params array.
93 * @return int
94 */
95 private function get_request_post_id( $request ) {
96 return method_exists( $request, 'get_param' )
97 ? intval( $request->get_param( 'post_id' ) )
98 : ( isset( $request['post_id'] ) ? intval( $request['post_id'] ) : 0 );
99 }
100
101 /**
102 * Whether the current user may access dynamic data/custom fields for the given post.
103 *
104 * @param int $post_id
105 * @return bool
106 */
107 private function user_can_access_post( $post_id ) {
108 // User must be logged in
109 if ( ! is_user_logged_in() ) {
110 return false;
111 }
112
113 // If no post_id, require edit_posts capability
114 if ( $post_id <= 0 ) {
115 return current_user_can( 'edit_posts' );
116 }
117
118 // Get the post
119 $post = get_post( $post_id );
120 if ( ! $post ) {
121 return false;
122 }
123
124 // Check if post is password protected
125 if ( post_password_required( $post ) ) {
126 return false;
127 }
128
129 // User must be able to edit this specific post
130 if ( ! current_user_can( 'edit_post', $post_id ) ) {
131 return false;
132 }
133
134 // For non-published posts, user must be author OR have edit_posts capability
135 if ( $post->post_status !== 'publish' ) {
136 if ( (int) $post->post_author !== get_current_user_id() && ! current_user_can( 'edit_posts' ) ) {
137 return false;
138 }
139 }
140
141 return true;
142 }
143
144 /**
145 * Dynamic data to show in the editor
146 *
147 * @since v.4.1.1
148 * @param WP_REST_Request $server
149 * @return WP_REST_Response
150 */
151 public function handle_dynamic_data( $server ) {
152 $args = $server->get_params();
153 $post_id = isset( $args['post_id'] ) ? intval( $args['post_id'] ) : '';
154 $data_type = isset( $args['data_type'] ) ? $args['data_type'] : '';
155 $key = isset( $args['key'] ) ? $args['key'] : '';
156
157 return rest_ensure_response(
158 array(
159 'data' => DCService::get_dynamic_data(
160 array(
161 'post_id' => $post_id,
162 'key' => $key,
163 'data_type' => $data_type,
164 )
165 ),
166 )
167 );
168 }
169
170 /**
171 * Gets custom fields keys and labels
172 *
173 * @since v.4.1.1
174 * @param WP_REST_Request $server
175 * @return WP_REST_Response
176 */
177 public function handle_custom_fields( $server ) {
178 $args = $server->get_params();
179
180 $post_id = isset( $args['post_id'] ) ? intval( $args['post_id'] ) : 0;
181 $post_type = isset( $args['post_type'] ) ? $args['post_type'] : '';
182 $field_type = isset( $args['acf_field_type'] ) ? $args['acf_field_type'] : '';
183
184 $res = array();
185
186 // All metas
187 $all_custom_metas = $this->get_custom_metas( $post_id, $post_type );
188
189 // Field sources other than plain custom metas, added by PostX Pro.
190 $sources = apply_filters(
191 'ultp_dc_custom_field_sources',
192 array(),
193 array(
194 'post_id' => $post_id,
195 'post_type' => $post_type,
196 'field_type' => $field_type,
197 )
198 );
199 $sources = is_array( $sources ) ? $sources : array();
200
201 // Keys and key prefixes that belong to those sources are not plain custom metas.
202 $source_keys = array();
203 $source_prefixes = array();
204 foreach ( $sources as $source ) {
205 if ( ! empty( $source['_fields'] ) && is_array( $source['_fields'] ) ) {
206 $source_keys = array_merge( $source_keys, $source['_fields'] );
207 }
208 if ( ! empty( $source['prefixes'] ) && is_array( $source['prefixes'] ) ) {
209 $source_prefixes = array_merge( $source_prefixes, $source['prefixes'] );
210 }
211 }
212
213 $filtered_custom_metas = array_values( array_diff( $all_custom_metas, $source_keys ) );
214 $filtered_custom_metas = array_values(
215 array_filter(
216 $filtered_custom_metas,
217 function ( $item ) use ( $source_prefixes ) {
218 foreach ( $source_prefixes as $prefix ) {
219 if ( str_starts_with( $item, $prefix ) ) {
220 return false;
221 }
222 }
223 return true;
224 }
225 )
226 );
227
228 // Return value
229 $res['custom_metas'] = array(
230 'fields' => array_map(
231 function ( $item ) {
232 return array(
233 'label' => $item,
234 'value' => $item,
235 );
236 },
237 $filtered_custom_metas
238 ),
239 );
240
241 foreach ( $sources as $key => $source ) {
242 if ( 'custom_metas' === $key || ! is_array( $source ) ) {
243 continue;
244 }
245 $res[ $key ] = array(
246 'fields' => isset( $source['fields'] ) && is_array( $source['fields'] ) ? $source['fields'] : array(),
247 );
248 }
249
250 return rest_ensure_response(
251 array(
252 'data' => $res,
253 )
254 );
255 }
256
257 /**
258 * Get custom post metas
259 *
260 * @param string $post_type Post Type.
261 * @since 4.1.0
262 * @return array
263 */
264 public function get_custom_metas( $post_id, $post_type ) {
265
266 $meta_keys = array();
267 $all_keys = array();
268
269 if ( $post_id !== 0 ) {
270 $all_keys = get_post_custom_keys( $post_id );
271
272 } else {
273 if ( ! isset( $post_type ) ) {
274 return $meta_keys;
275 }
276
277 $posts = get_posts(
278 array(
279 'post_type' => $post_type,
280 'posts_per_page' => -1,
281 'fields' => 'id',
282 )
283 );
284
285 if ( empty( $posts ) ) {
286 return $meta_keys;
287 }
288
289 foreach ( $posts as $post ) {
290 $post_id = isset( $post->ID ) ? $post->ID : 0;
291 $keys = get_post_custom_keys( $post_id );
292 if ( is_array( $keys ) ) {
293 foreach ( $keys as $key ) {
294 $all_keys[] = $key;
295 }
296 }
297 }
298 }
299
300 if ( is_array( $all_keys ) ) {
301 foreach ( $all_keys as $key ) {
302 if ( ! isset( $meta_keys[ $key ] ) && ! str_starts_with( $key, '_' ) ) {
303 $meta_keys[ $key ] = $key;
304 }
305 }
306 }
307
308 return array_keys( $meta_keys );
309 }
310 }
311