PluginProbe
Post Grid Gutenberg Blocks – PostX / 5.0.41
Post Grid Gutenberg Blocks – PostX v5.0.41
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 5.0.17 2.1.1 All 238 releases
← All changes | classes/REST_API.php +804 -188 2.1.15.0.41 View file →
@@ -1,211 +1,827 @@
1 1 <?php
2 -defined('ABSPATH') || exit;
2 +/**
3 + * REST API Action.
4 + *
5 + * @package ULTP\REST_API
6 + * @since v.1.0.0
7 + */
3 8
9 +namespace ULTP;
4 10
5 -// ------------- Custom Endpoint Start ----------
11 +defined( 'ABSPATH' ) || exit;
6 12
7 -add_action( 'rest_api_init', 'ultp_register_route' );
8 -function ultp_register_route() {
9 - register_rest_route( 'ultp', 'posts', array(
10 - 'methods' => WP_REST_Server::READABLE,
11 - 'args' => array('post_type', 'taxonomy', 'include', 'exclude', 'order', 'orderby', 'count', 'size', 'tag', 'cat', 'meta_key', 'queryQuick', 'wpnonce'),
12 - 'callback' => 'ultp_route_post_data',
13 - 'permission_callback' => '__return_true'
14 - )
15 - );
16 - register_rest_route( 'ultp', 'taxonomy', array(
17 - 'methods' => WP_REST_Server::READABLE,
18 - 'args' => array('taxonomy', 'wpnonce'),
19 - 'callback' => 'ultp_route_taxonomy_data',
20 - 'permission_callback' => '__return_true'
21 - )
22 - );
23 - register_rest_route( 'ultp', 'imagesize', array(
24 - 'methods' => WP_REST_Server::READABLE,
25 - 'args' => array('taxonomy', 'wpnonce'),
26 - 'callback' => 'ultp_route_imagesize_data',
27 - 'permission_callback' => '__return_true'
28 - )
29 - );
30 - register_rest_route( 'ultp', 'posttype', array(
31 - 'methods' => WP_REST_Server::READABLE,
32 - 'args' => array('wpnonce'),
33 - 'callback' => 'ultp_route_posttype_data',
34 - 'permission_callback' => '__return_true'
35 - )
36 - );
37 - register_rest_route( 'ultp', 'tax_info', array(
38 - 'methods' => WP_REST_Server::READABLE,
39 - 'args' => array('taxonomy', 'wpnonce'),
40 - 'callback' => 'ultp_route_taxonomy_info_data',
41 - 'permission_callback' => '__return_true'
42 - )
43 - );
44 -}
13 +/**
14 + * REST API class.
15 + *
16 + * Handles custom REST API endpoints for Ultimate Post plugin.
17 + *
18 + * @package ULTP\REST_API
19 + * @since 4.0.0
20 + */
21 +class REST_API {
45 22
46 -function ultp_route_posttype_data() {
47 - if (!wp_verify_nonce($_REQUEST['wpnonce'], 'ultp-nonce') && $local){
48 - return ;
49 - }
50 -
51 - return ultimate_post()->get_post_type();
52 -}
23 + /**
24 + * Upper bound for the search endpoint's postPerPage. Matches the max of the
25 + * Search block's "Show Initial Post" slider, so no UI value is ever capped.
26 + * This is the same max range of the slider in gutenburg editor.
27 + * 100 is enough for search bar result.
28 + *
29 + * @since v.5.0.35
30 + */
31 + const SEARCH_POSTS_PER_PAGE_MAX = 100;
53 32
54 -function ultp_route_imagesize_data() {
55 - if (!wp_verify_nonce($_REQUEST['wpnonce'], 'ultp-nonce') && $local){
56 - return ;
57 - }
58 -
59 - return ultimate_post()->get_image_size();
60 -}
33 + /**
34 + * Longest accepted search term. Longer strings only widen the LIKE pattern
35 + * scanned against every row; no real query needs more.
36 + *
37 + * @since v.5.0.35
38 + */
39 + const SEARCH_TEXT_MAX_LENGTH = 200;
61 40
62 -function ultp_route_post_data($prams,$local=false) {
63 - if (!wp_verify_nonce($_REQUEST['wpnonce'], 'ultp-nonce') && $local){
64 - return ;
65 - }
41 + /**
42 + * Upper bound for excerptLimit. Also keeps $num_words + 1 inside integer range
43 + * in wp_trim_words(), which otherwise overflows to float on a huge value.
44 + *
45 + * @since v.5.0.35
46 + */
47 + const SEARCH_EXCERPT_WORDS_MAX = 400;
66 48
67 - // Query Builder
68 - $args = array(
69 - 'post_type' => 'post',
70 - 'orderby' => 'date',
71 - 'post_status' => 'publish',
72 - 'order' => 'DESC',
73 - );
49 + /**
50 + * Setup class.
51 + *
52 + * @since v.1.0.0
53 + */
54 + public function __construct() {
55 + add_action( 'rest_api_init', array( $this, 'ultp_register_route' ) );
56 + }
74 57
75 - if(isset($prams['count'])){ $args['posts_per_page'] = esc_attr($prams['count']); }
76 - if(isset($prams['post_type'])){ $args['post_type'] = esc_attr( $prams['post_type'] ); }
58 + /**
59 + * REST API Action
60 + *
61 + * @since v.1.0.0
62 + * @return void
63 + */
64 + public function ultp_register_route() {
65 + register_rest_route(
66 + 'ultp',
67 + 'common_data',
68 + array(
69 + 'methods' => \WP_REST_Server::READABLE,
70 + 'args' => array( 'wpnonce' => array() ),
71 + 'callback' => array( $this, 'ultp_route_common_data' ),
72 + 'permission_callback' => function () {
73 + return current_user_can( 'edit_posts' );
74 + },
75 + )
76 + );
77 + register_rest_route(
78 + 'ultp',
79 + '/fetch_posts/',
80 + array(
81 + array(
82 + 'methods' => 'POST',
83 + 'args' => array(),
84 + 'callback' => array( $this, 'ultp_route_post_data' ),
85 + 'permission_callback' => function () {
86 + return current_user_can( 'edit_posts' );
87 + },
88 + ),
89 + )
90 + );
91 + register_rest_route(
92 + 'ultp',
93 + '/specific_taxonomy/',
94 + array(
95 + array(
96 + 'methods' => 'POST',
97 + 'args' => array(),
98 + 'callback' => array( $this, 'ultp_route_taxonomy_info_data' ),
99 + 'permission_callback' => function () {
100 + return current_user_can( 'edit_others_posts' );
101 + },
102 + ),
103 + )
104 + );
105 + register_rest_route(
106 + 'ultp/v1',
107 + '/search/',
108 + array(
109 + array(
110 + 'methods' => 'POST',
111 + 'callback' => array( $this, 'search_settings_action' ),
112 + 'permission_callback' => function () {
113 + return current_user_can( 'edit_others_posts' );
114 + },
115 + 'args' => array(),
116 + ),
117 + )
118 + );
119 + register_rest_route(
120 + 'ultp/v2',
121 + '/premade_wishlist_save/',
122 + array(
123 + array(
124 + 'methods' => 'POST',
125 + 'callback' => array( $this, 'premade_wishlist_save' ),
126 + 'permission_callback' => function () {
127 + return current_user_can( 'edit_others_posts' );
128 + },
129 + 'args' => array(),
130 + ),
131 + )
132 + );
133 + register_rest_route(
134 + 'ultp',
135 + '/ultp_search_data/',
136 + array(
137 + array(
138 + 'methods' => 'POST',
139 + 'callback' => array( $this, 'ultp_search_result' ),
140 + 'permission_callback' => '__return_true',
141 + ),
142 + )
143 + );
144 + register_rest_route(
145 + 'ultp/v2',
146 + '/custom_tax/',
147 + array(
148 + array(
149 + 'methods' => 'POST',
150 + 'callback' => array( $this, 'custom_tax_callback' ),
151 + 'permission_callback' => function () {
152 + return current_user_can( 'manage_options' );
153 + },
154 + 'args' => array(),
155 + ),
156 + )
157 + );
158 + register_rest_route(
159 + 'ultp/v2',
160 + '/init_site_dark_logo/',
161 + array(
162 + array(
163 + 'methods' => 'POST',
164 + 'callback' => array( $this, 'init_site_dark_logo_callback' ),
165 + 'permission_callback' => function () {
166 + return current_user_can( 'edit_others_posts' );
167 + },
168 + 'args' => array(),
169 + ),
170 + )
171 + );
172 + register_rest_route(
173 + 'ultp/v2',
174 + '/get_ultp_image_size/',
175 + array(
176 + array(
177 + 'methods' => 'POST',
178 + 'callback' => array( $this, 'get_custom_image_size' ),
179 + 'permission_callback' => function () {
180 + return current_user_can( 'edit_posts' );
181 + },
182 + 'args' => array(),
183 + ),
184 + )
185 + );
186 + }
77 187
78 - if(isset($prams['taxonomy'])){ // taxonomy slug__val__slug__val
79 - $tax_arr = array('relation' => 'OR');
80 - $tax = explode('__', esc_attr($prams['taxonomy']));
81 - if(!empty($tax)){
82 - for($i=0; $i < count($tax) ; $i++){
83 - if($i%2 == 0){
84 - $tax_arr[] = array('taxonomy'=>$tax[$i], 'field' => 'slug', 'terms' => array($tax[$i+1]));
85 - }
86 - }
87 - }
88 - if(!empty($tax_arr)){
89 - $args['tax_query'] = $tax_arr;
90 - }
91 - }
188 + /**
189 + * Save and get premade_wishlist_save
190 + *
191 + * Handle REST API request.
192 + *
193 + * @since 4.0.0
194 + * @param ARRAY $server $request The REST request object.
195 + * @return array The response data.
196 + */
197 + public function premade_wishlist_save( $server ) {
198 + $post = $server->get_params();
199 + $id = isset( $post['id'] ) ? ultimate_post()->ultp_rest_sanitize_params( $post['id'] ) : '';
200 + $action = isset( $post['action'] ) ? ultimate_post()->ultp_rest_sanitize_params( $post['action'] ) : '';
201 + $wishListArr = get_option( 'ultp_premade_wishlist', array() );
202 + $request_type = isset( $post['type'] ) ? ultimate_post()->ultp_rest_sanitize_params( $post['type'] ) : '';
92 203
93 - if(isset($prams['exclude'])){ $args['post__not_in'] = explode('__', esc_attr($prams['exclude'])); }
94 - if(isset($prams['orderby'])){ $args['orderby'] = esc_attr($prams['orderby']); }
95 - if(isset($prams['order'])){ $args['order'] = esc_attr($prams['order']); }
96 - if(isset($prams['offset'])){ $args['offset'] = esc_attr($prams['offset']); }
97 - if(isset($prams['paged'])){ $args['paged'] = esc_attr($prams['paged']); }
204 + if ( $id && $request_type != 'fetchData' ) {
205 + if ( $action == 'remove' ) {
206 + $index = array_search( $id, $wishListArr );
207 + if ( $index !== false ) {
208 + unset( $wishListArr[ $index ] );
209 + }
210 + } elseif ( ! in_array( $id, $wishListArr ) ) {
211 + array_push( $wishListArr, $id );
212 + }
213 + update_option( 'ultp_premade_wishlist', $wishListArr );
214 + }
215 + return rest_ensure_response(
216 + array(
217 + 'success' => true,
218 + 'message' => $action == 'remove' ? __( 'Item has been removed from wishlist.', 'ultimate-post' ) : __( 'Item added to wishlist.', 'ultimate-post' ),
219 + 'wishListArr' => wp_json_encode( $wishListArr ),
220 + )
221 + );
222 + }
98 223
99 - if(isset($prams['orderby']) && isset($prams['meta_key'])){
100 - if($prams['orderby'] == 'meta_value_num') {
101 - $args['meta_key'] = $prams['meta_key'];
102 - $args['meta_type'] = 'NUMERIC';
103 - }
104 - }
105 224
106 - if(isset($prams['queryQuick'])){
107 - if($prams['queryQuick'] != ''){
108 - if(function_exists('ultimate_post_pro')){
109 - $args = ultimate_post_pro()->get_quick_query($prams, $args);
110 - }
111 - }
112 - }
113 225
114 - if(isset($prams['include'])){
115 - $args['post__in'] = explode('__', esc_attr($prams['include']));
116 - $args['ignore_sticky_posts'] = 1;
117 - $args['orderby'] = 'post__in';
118 - }
119 -
120 - $data = [];
121 - $loop = new WP_Query($args);
122 -
123 - if($loop->have_posts()){
124 - while($loop->have_posts()) {
125 - $loop->the_post();
126 - $var = array();
127 - $post_id = get_the_ID();
128 - $user_id = get_the_author_meta('ID');
129 - $content_data = get_the_content();
130 - $var['ID'] = $post_id;
131 - $var['title'] = get_the_title();
132 - $var['permalink'] = get_permalink();
133 - $var['excerpt'] = strip_tags($content_data);
134 - $var['excerpt_full']= strip_tags(get_the_excerpt());
135 - $var['time'] = get_the_date();
136 - $var['timeModified']= get_the_modified_date();
137 - $var['post_time'] = human_time_diff(get_the_time('U'),current_time('U'));
138 - $var['view'] = get_post_meta(get_the_ID(),'__post_views_count', true);
139 - $var['comments'] = get_comments_number();
140 - $var['author_link'] = get_author_posts_url($user_id);
141 - $var['avatar_url'] = get_avatar_url($user_id);
142 - $var['display_name']= get_the_author_meta('display_name');
143 - $var['reading_time']= ceil(strlen($content_data)/1200).__(' min read', 'ultimate-post');
144 -
145 - // image
146 - if( has_post_thumbnail() ){
147 - $thumb_id = get_post_thumbnail_id($post_id);
148 - $image_sizes = ultimate_post()->get_image_size();
149 - $image_src = array();
150 - foreach ($image_sizes as $key => $value) {
151 - $image_src[$key] = wp_get_attachment_image_src($thumb_id, $key, false)[0];
152 - }
153 - $var['image'] = $image_src;
154 - }
226 + /**
227 + * Search_settings_action
228 + *
229 + * @param mixed $server .
230 + * @return array
231 + */
232 + public function search_settings_action( $server ) {
233 + global $wpdb;
234 + $post = $server->get_params();
235 + $request_type = isset( $post['type'] ) ? ultimate_post()->ultp_rest_sanitize_params( $post['type'] ) : '';
236 + $condition_type = isset( $post['condition'] ) ? ultimate_post()->ultp_rest_sanitize_params( $post['condition'] ) : '';
237 + $term_type = isset( $post['term'] ) ? ultimate_post()->ultp_rest_sanitize_params( $post['term'] ) : '';
238 + // get post type
239 + $get_multiple_post_type = isset( $post['postType'] ) ? ultimate_post()->ultp_rest_sanitize_params( $post['postType'] ) : array();
240 + $multiple_post_type = is_array( $get_multiple_post_type ) ? $get_multiple_post_type : json_decode( $get_multiple_post_type, true );
241 + $split = explode( '###', $condition_type );
242 + $post_type_condition = array();
243 + if ( $split[0] == 'customPostType' && count( $multiple_post_type ) ) {
244 + $post_type_condition = get_object_taxonomies( $multiple_post_type );
245 + }
155 246
156 - // tag
157 - $tag = get_the_terms($post_id, (isset($prams['tag'])?esc_attr($prams['tag']):'post_tag'));
158 - if(!empty($tag)){
159 - $v = array();
160 - foreach ($tag as $val) {
161 - $v[] = array('slug' => $val->slug, 'name' => $val->name, 'url' => get_term_link($val->term_id));
162 - }
163 - $var['tag'] = $v;
164 - }
247 + switch ( $request_type ) {
248 + case 'posts':
249 + case 'allpost':
250 + case 'postExclude':
251 + $post_type = array( 'post' );
252 + if ( $request_type == 'allpost' || $condition_type == 'customPostType' ) {
253 + $post_type = array_keys( ultimate_post()->get_post_type() );
254 + } elseif ( $request_type == 'postExclude' && $condition_type != 'customPostType' ) {
255 + $post_type = array( $condition_type );
256 + }
257 + $args = array(
258 + 'post_type' => $post_type,
259 + 'post_status' => 'publish',
260 + 'posts_per_page' => 10,
261 + );
262 + if ( is_numeric( $term_type ) ) {
263 + $args['p'] = $term_type;
264 + } else {
265 + $args['s'] = $term_type;
266 + }
165 267
166 - // cat
167 - $cat = get_the_terms($post_id, (isset($prams['cat'])?esc_attr($prams['cat']):'category'));
168 - if(!empty($cat)){
169 - $v = array();
170 - foreach ($cat as $val) {
171 - $v[] = array('slug' => $val->slug, 'name' => $val->name, 'url' => get_term_link($val->term_id), 'color' => get_term_meta($val->term_id, 'ultp_category_color', true));
172 - }
173 - $var['category'] = $v;
174 - }
175 - $data[] = $var;
176 - }
177 - wp_reset_postdata();
178 - }
268 + $post_results = new \WP_Query( $args );
269 + $data = array();
270 + if ( ! empty( $post_results ) ) {
271 + while ( $post_results->have_posts() ) {
272 + $post_results->the_post();
273 + $id = get_the_ID();
274 + $title = html_entity_decode( get_the_title() );
275 + $data[] = array(
276 + 'value' => $id,
277 + 'title' => ( $title ? '[ID: ' . $id . '] ' . $title : ( '[ID: ' . $id . ']' ) ),
278 + );
279 + }
280 + wp_reset_postdata();
281 + }
282 + return array(
283 + 'success' => true,
284 + 'data' => $data,
285 + );
286 + break;
179 287
180 - return rest_ensure_response( $data );
181 -}
288 + case 'author':
289 + $term = '%' . $wpdb->esc_like( $term_type ) . '%';
290 + $post_results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
291 + $wpdb->prepare(
292 + "SELECT ID, display_name
293 + FROM $wpdb->users
294 + WHERE user_login LIKE %s OR ID LIKE %s OR user_nicename LIKE %s OR user_email LIKE %s OR display_name LIKE %s LIMIT 10",
295 + $term,
296 + $term,
297 + $term,
298 + $term,
299 + $term
300 + )
301 + );
302 + $data = array();
303 + if ( ! empty( $post_results ) ) {
304 + foreach ( $post_results as $key => $val ) {
305 + $data[] = array(
306 + 'value' => $val->ID,
307 + 'title' => '[ID: ' . $val->ID . '] ' . $val->display_name,
308 + );
309 + }
310 + }
311 + return array(
312 + 'success' => true,
313 + 'data' => $data,
314 + );
315 + break;
182 316
317 + case 'taxvalue':
318 + $split = explode( '###', $condition_type );
319 + $condition = $split[1] != 'multiTaxonomy' ? array( $split[1] ) : get_object_taxonomies( $split[0] );
183 320
321 + if ( $post_type_condition && count( $post_type_condition ) ) {
322 + $condition = $post_type_condition;
323 + }
184 324
185 -function ultp_route_taxonomy_data($prams) {
186 - if (!wp_verify_nonce($_REQUEST['wpnonce'], 'ultp-nonce')){
187 - return rest_ensure_response([]);
188 - }
189 - return rest_ensure_response(ultimate_post()->taxonomy($prams['taxonomy']));
190 -}
325 + $args = array(
326 + 'taxonomy' => $condition,
327 + 'fields' => 'all',
328 + 'orderby' => 'id',
329 + 'order' => 'ASC',
330 + 'name__like' => $term_type,
331 + );
332 + if ( is_numeric( $term_type ) ) {
333 + unset( $args['name__like'] );
334 + $args['include'] = array( $term_type );
335 + }
191 336
192 -function ultp_route_taxonomy_info_data($prams) {
193 - if (!wp_verify_nonce($_REQUEST['wpnonce'], 'ultp-nonce')){
194 - return rest_ensure_response([]);
195 - }
337 + $post_results = get_terms( $args );
338 + $data = array();
339 + if ( ! empty( $post_results ) ) {
340 + foreach ( $post_results as $key => $val ) {
341 + if ( $split[1] == 'multiTaxonomy' ) {
342 + $data[] = array(
343 + 'value' => $val->taxonomy . '###' . $val->slug,
344 + 'title' => '[ID: ' . $val->term_id . '] ' . $val->taxonomy . ': ' . $val->name,
345 + );
346 + } else {
347 + $data[] = array(
348 + 'value' => urldecode( $val->slug ),
349 + 'title' => '[ID: ' . $val->term_id . '] ' . $val->name,
350 + 'live_title' => $val->name,
351 + );
352 + }
353 + }
354 + }
355 + return array(
356 + 'success' => true,
357 + 'data' => $data,
358 + );
359 + break;
196 360
197 - $data = array();
198 - $terms = get_terms( $prams, array(
199 - 'hide_empty' => true,
200 - ));
201 - if( !empty($terms) ){
202 - foreach ($terms as $val) {
203 - $data['name'] = $val->name;
204 - $data['count'] = $val->count;
205 - $data['url'] = get_term_link($val->term_id);
206 - $data['color'] = get_term_meta($val->term_id, '_background', true);
207 - }
208 - }
361 + case 'taxExclude':
362 + $condition = get_object_taxonomies( $condition_type );
363 + if ( $post_type_condition && count( $post_type_condition ) ) {
364 + $condition = $post_type_condition;
365 + }
366 + $args = array(
367 + 'taxonomy' => $condition,
368 + 'fields' => 'all',
369 + 'orderby' => 'id',
370 + 'order' => 'ASC',
371 + 'name__like' => $term_type,
372 + );
373 + if ( is_numeric( $term_type ) ) {
374 + unset( $args['name__like'] );
375 + $args['include'] = array( $term_type );
376 + }
377 + $post_results = get_terms( $args );
378 + $data = array();
379 + if ( ! empty( $post_results ) ) {
380 + foreach ( $post_results as $key => $val ) {
381 + $data[] = array(
382 + 'value' => $val->taxonomy . '###' . $val->slug,
383 + 'title' => '[ID: ' . $val->term_id . '] ' . $val->taxonomy . ': ' . $val->name,
384 + );
385 + }
386 + }
387 + return array(
388 + 'success' => true,
389 + 'data' => $data,
390 + );
391 + break;
392 + // allPostType
393 + case 'allPostType':
394 + $all_types = array_values( get_post_types( array( 'public' => true ), 'names' ) );
395 + $postType = array();
396 + foreach ( $all_types as $type ) {
397 + $postType[] = array(
398 + 'title' => $type,
399 + 'value' => $type,
400 + );
401 + }
209 402
210 - return rest_ensure_response($data);
211 -}
403 + return array(
404 + 'success' => true,
405 + 'data' => $postType,
406 + );
407 + default:
408 + return array(
409 + 'success' => true,
410 + 'data' => array(
411 + array(
412 + 'value' => '',
413 + 'title' => '- Select -',
414 + ),
415 + ),
416 + );
417 + break;
418 + }
419 + }
420 +
421 + /**
422 + * Post Data Response of REST API
423 + *
424 + * @since v.1.0.0
425 + * @param MIXED | $prams (ARRAY), Local (BOOLEAN).
426 + * @return ARRAY | Response Image Size as Array
427 + */
428 + public function ultp_route_post_data( $prams ) {
429 + $prams = $prams->get_params();
430 + if ( ! ( isset( $prams['wpnonce'] ) && wp_verify_nonce( sanitize_key( wp_unslash( $prams['wpnonce'] ) ), 'ultp-nonce' ) ) ) {
431 + die();
432 + }
433 + $data = array();
434 + $loop = new \WP_Query( ultimate_post()->get_query( ultimate_post()->ultp_rest_sanitize_params( $prams ) ) );
435 + $max_tax = isset( $prams['maxTaxonomy'] ) && $prams['maxTaxonomy'] ? ( ultimate_post()->ultp_rest_sanitize_params( $prams['maxTaxonomy'] ) == '0' ? 0 : ultimate_post()->ultp_rest_sanitize_params( $prams['maxTaxonomy'] ) ) : 30;
436 +
437 + if ( $loop->have_posts() ) {
438 + while ( $loop->have_posts() ) {
439 + $loop->the_post();
440 + $var = array();
441 + $post_id = get_the_ID();
442 + $user_id = get_the_author_meta( 'ID' );
443 + $content_data = get_the_content();
444 + $var['ID'] = $post_id;
445 + $var['title'] = get_the_title();
446 + $var['permalink'] = get_permalink();
447 + $var['seo_meta'] = ultimate_post()->get_excerpt( $post_id, 1 );
448 + $var['excerpt'] = wp_strip_all_tags( get_the_excerpt() );
449 + $var['excerpt_full'] = wp_strip_all_tags( get_the_excerpt() );
450 + $var['time'] = (int) get_the_date( 'U' ) * 1000;
451 + $var['timeModified'] = (int) get_the_modified_date( 'U' ) * 1000;
452 + $var['post_time'] = human_time_diff( get_the_time( 'U' ), current_time( 'U' ) );
453 + $var['view'] = get_post_meta( get_the_ID(), '__post_views_count', true );
454 + $var['comments'] = get_comments_number();
455 + $var['author_link'] = get_author_posts_url( $user_id );
456 + $var['avatar_url'] = get_avatar_url( $user_id );
457 + $var['display_name'] = get_the_author_meta( 'display_name' );
458 + $var['reading_time'] = ceil( strlen( $content_data ) / 1200 );
459 + $var['acf'] = null;
460 +
461 + if ( function_exists( 'get_field_objects' ) ) {
462 + $var['acf'] = get_field_objects();
463 + }
464 +
465 + $post_video = get_post_meta( $post_id, '__builder_feature_video', true );
466 + // Video.
467 + if ( $post_video ) {
468 + $var['has_video'] = ultimate_post()->get_youtube_id( $post_video );
469 + }
470 + // image.
471 + $image_sizes = ultimate_post()->get_image_size();
472 + $image_src = array();
473 + if ( has_post_thumbnail() ) {
474 + $thumb_id = get_post_thumbnail_id( $post_id );
475 + foreach ( $image_sizes as $key => $value ) {
476 + $image = wp_get_attachment_image_src( $thumb_id, $key, false );
477 + if ( $image && is_array( $image ) ) {
478 + $image_src[ $key ] = $image[0];
479 + }
480 + }
481 + $var['image'] = $image_src;
482 + } elseif ( isset( $prams['fallbackImg']['id'] ) ) {
483 + foreach ( $image_sizes as $key => $value ) {
484 + $image_src[ $key ] = wp_get_attachment_image_src( esc_attr( $prams['fallbackImg']['id'] ), $key, false )[0];
485 + }
486 + $var['image'] = $image_src;
487 + $var['is_fallback'] = true;
488 + }
489 +
490 + // tag.
491 + $tag = get_the_terms( $post_id, ( isset( $prams['tag'] ) ? esc_attr( $prams['tag'] ) : 'post_tag' ) );
492 + if ( ! empty( $tag ) ) {
493 + $v = array();
494 + foreach ( $tag as $k => $val ) {
495 + if ( $k >= $max_tax ) {
496 + break; }
497 + $v[] = array(
498 + 'slug' => $val->slug,
499 + 'name' => $val->name,
500 + 'url' => get_term_link( $val->term_id ),
501 + );
502 + }
503 + $var['tag'] = $v;
504 + }
505 +
506 + // Taxonomy.
507 + $cat = get_the_terms( $post_id, ( isset( $prams['taxonomy'] ) ? esc_attr( $prams['taxonomy'] ) : 'category' ) );
508 +
509 + if ( ! empty( $cat ) ) {
510 + $v = array();
511 + foreach ( $cat as $k => $val ) {
512 + if ( $k >= $max_tax ) {
513 + break; }
514 + $v[] = array(
515 + 'slug' => $val->slug,
516 + 'name' => $val->name,
517 + 'url' => get_term_link( $val->term_id ),
518 + 'color' => get_term_meta( $val->term_id, 'ultp_category_color', true ),
519 + );
520 + }
521 + $var['category'] = $v;
522 + }
523 + $data[] = $var;
524 + }
525 + wp_reset_postdata();
526 + }
527 + return rest_ensure_response( $data );
528 + }
529 +
530 +
531 + /**
532 + * STaxonomy Data Response of REST API
533 + *
534 + * @since v.1.0.0
535 + * @param ARRAY | $prams (ARRAY).
536 + * @return ARRAY | Response Taxonomy List as Array
537 + */
538 + public function ultp_route_common_data( $prams ) {
539 + if ( ! ( isset( $_REQUEST['wpnonce'] ) && wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['wpnonce'] ) ), 'ultp-nonce' ) ) ) {
540 + return rest_ensure_response( array() );
541 + }
542 +
543 + $all_post_type = ultimate_post()->get_post_type();
544 + $data = array();
545 + foreach ( $all_post_type as $post_type_slug => $post_type ) {
546 + $data_term = array();
547 + $taxonomies = get_object_taxonomies( $post_type_slug );
548 + foreach ( $taxonomies as $key => $taxonomy_slug ) {
549 + $taxonomy_value = get_terms(
550 + array(
551 + 'taxonomy' => $taxonomy_slug,
552 + 'hide_empty' => false,
553 + )
554 + );
555 + if ( ! is_wp_error( $taxonomy_value ) ) {
556 + $data_tax = array();
557 + foreach ( $taxonomy_value as $k => $taxonomy ) {
558 + $data_tax[ urldecode_deep( $taxonomy->slug ) ] = $taxonomy->name;
559 + }
560 + if ( count( $data_tax ) > 0 ) {
561 + $data_term[ $taxonomy_slug ] = $data_tax;
562 + }
563 + }
564 + }
565 + $data[ $post_type_slug ] = $data_term;
566 + }
567 + // Global Customizer.
568 + $global = get_option( 'postx_global', array() );
569 + // Image Size.
570 + $image_sizes = ultimate_post()->get_image_size();
571 +
572 + return rest_ensure_response(
573 + array(
574 + 'taxonomy' => $data,
575 + 'global' => $global,
576 + 'image' => wp_json_encode( $image_sizes ),
577 + 'posttype' => wp_json_encode( $all_post_type ),
578 + )
579 + );
580 + }
581 +
582 + /**
583 + * Specific Taxonomy Data Response of REST API
584 + *
585 + * @since v.1.0.0
586 + * @param ARRAY | $prams .
587 + * @return ARRAY | Response Taxonomy List as Array
588 + */
589 + public function ultp_route_taxonomy_info_data( $prams ) {
590 + $prams = $prams->get_params();
591 + if ( ! ( isset( $prams['wpnonce'] ) && wp_verify_nonce( sanitize_key( wp_unslash( $prams['wpnonce'] ) ), 'ultp-nonce' ) ) ) {
592 + return rest_ensure_response( array() );
593 + }
594 + $taxValue = isset( $prams['taxValue'] ) ? ultimate_post()->ultp_rest_sanitize_params( $prams['taxValue'] ) : '';
595 + $queryNumber = isset( $prams['queryNumber'] ) ? ultimate_post()->ultp_rest_sanitize_params( $prams['queryNumber'] ) : '';
596 + $taxType = isset( $prams['taxType'] ) ? ultimate_post()->ultp_rest_sanitize_params( $prams['taxType'] ) : '';
597 + $taxSlug = isset( $prams['taxSlug'] ) ? ultimate_post()->ultp_rest_sanitize_params( $prams['taxSlug'] ) : '';
598 + $archiveBuilder = isset( $prams['archiveBuilder'] ) ? ultimate_post()->ultp_rest_sanitize_params( $prams['archiveBuilder'] ) : '';
599 +
600 + return rest_ensure_response( ultimate_post()->get_category_data( json_decode( $taxValue ), $queryNumber, $taxType, $taxSlug, $archiveBuilder ) );
601 + }
602 +
603 + /**
604 + * Get Taxonomies for Custom Post Type
605 + *
606 + * @since v.3.2.8
607 + * @param array $prams .
608 + * @return array
609 + */
610 + public function custom_tax_callback( $prams ) {
611 +
612 + $post_types = isset( $prams['postTypes'] ) ? ultimate_post()->ultp_rest_sanitize_params( $prams['postTypes'] ) : array();
613 +
614 + if ( is_string( $post_types ) ) {
615 + $post_types = json_decode( $post_types, true );
616 + if ( ! is_array( $post_types ) ) {
617 + $post_types = array();
618 + }
619 + }
620 +
621 + $data = array(
622 + array(
623 + 'id' => '_all',
624 + 'name' => __( 'All', 'ultimate-post' ),
625 + ),
626 + );
627 +
628 + foreach ( $post_types as $post_type ) {
629 + $taxonomies = get_object_taxonomies( $post_type );
630 + foreach ( $taxonomies as $taxonomy ) {
631 + if ( 'category' !== $taxonomy && 'post_tag' !== $taxonomy ) {
632 + $terms = get_terms(
633 + array(
634 + 'taxonomy' => $taxonomy,
635 + 'hide_empty' => false,
636 + )
637 + );
638 + foreach ( $terms as $term ) {
639 + $data[] = array(
640 + 'id' => $term->slug,
641 + 'name' => $term->name,
642 + );
643 + }
644 + }
645 + }
646 + }
647 +
648 + return rest_ensure_response( $data );
649 + }
650 +
651 + /**
652 + * Search Block Data Showing
653 + *
654 + * @since v.2.9.9
655 + * @param STRING | $server .
656 + * @return ARRAY | Inserted Post Url
657 + */
658 + public function ultp_search_result( $server ) {
659 + $post = $server->get_params();
660 + $searchText = isset( $post['searchText'] ) ? ultimate_post()->ultp_rest_sanitize_params( $post['searchText'] ) : '';
661 + $paged = isset( $post['paged'] ) ? ultimate_post()->ultp_rest_sanitize_params( $post['paged'] ) : '';
662 + $postPerPage = isset( $post['postPerPage'] ) ? ultimate_post()->ultp_rest_sanitize_params( $post['postPerPage'] ) : '';
663 +
664 + // Public route: cap posts_per_page so -1 can never mean "unlimited".
665 + // 0 survives the cap, and WP_Query resolves it to the posts_per_page option.
666 + $postPerPage = min( absint( $postPerPage ), self::SEARCH_POSTS_PER_PAGE_MAX );
667 + // is_scalar first: searchText arrives as an array if the caller sends one, and
668 + // casting that to string is an "Array to string conversion" warning.
669 + $searchText = is_scalar( $searchText ) ? mb_substr( (string) $searchText, 0, self::SEARCH_TEXT_MAX_LENGTH ) : '';
670 +
671 + $query_args = array(
672 + 's' => $searchText,
673 + 'paged' => $paged,
674 + 'orderby' => 'relevance',
675 + 'posts_per_page' => $postPerPage,
676 + );
677 + if ( isset( $post['exclude'] ) && is_array( $post['exclude'] ) && count( $post['exclude'] ) > 0 ) {
678 + $all_types = get_post_types( array( 'public' => true ), 'names' );
679 + $post_exclude = array();
680 +
681 + // Bound before sanitising: this route is public, and sanitising an array
682 + // whose length the caller picks is itself the attack. Excluding more post
683 + // types than exist is meaningless, so nothing valid is dropped.
684 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Length is bounded here only; every element is sanitized below before use.
685 + $exclude_input = array_slice( $post['exclude'], 0, count( $all_types ) );
686 +
687 + foreach ( $exclude_input as $data ) {
688 + // A flat array of strings would index a string here and warn.
689 + if ( ! is_array( $data ) || ! isset( $data['title'] ) || ! is_scalar( $data['title'] ) ) {
690 + continue;
691 + }
692 + $exclude_type = sanitize_text_field( $data['title'] );
693 + $post_exclude[ $exclude_type ] = $exclude_type;
694 + }
695 +
696 + $query_args['post_type'] = array_diff_key( $all_types, $post_exclude );
697 + }
698 + $output = '';
699 + $query_result = new \WP_Query( $query_args );
700 +
701 + /**
702 + * Resolved once here rather than guarded at each use, since the request may
703 + * omit any of them. The loose == is deliberate: the two callers disagree on
704 + * type -- the editor sends real booleans, the frontend sends 1/0 parsed out
705 + * of data attributes -- and both must keep working.
706 + */
707 + $show_image = isset( $post['image'] ) && $post['image'] == 1;
708 + $show_category = isset( $post['category'] ) && $post['category'] == 1;
709 + $show_author = isset( $post['author'] ) && $post['author'] == 1;
710 + $show_date = isset( $post['date'] ) && $post['date'] == 1;
711 + $show_excerpt = isset( $post['excerpt'] ) && $post['excerpt'] == 1;
712 + $excerpt_limit = isset( $post['excerptLimit'] )
713 + ? min( absint( $post['excerptLimit'] ), self::SEARCH_EXCERPT_WORDS_MAX )
714 + : 55;
715 +
716 + if ( $query_result->have_posts() ) {
717 + while ( $query_result->have_posts() ) {
718 + $query_result->the_post();
719 + $post_id = get_the_ID();
720 + $title = get_the_title();
721 +
722 + $output .= '<div class="ultp-search-result__item">';
723 +
724 + if ( $show_image && has_post_thumbnail() ) {
725 + // has_post_thumbnail() only proves the _thumbnail_id meta exists.
726 + // If the attachment behind it was deleted, src() returns false.
727 + $thumb = wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), 'thumbnail', false );
728 + if ( ! empty( $thumb[0] ) ) {
729 + $output .= '<img class="ultp-searchresult-image" src="' . esc_url( $thumb[0] ) . '" alt="' . esc_attr( $title ) . '"/>';
730 + }
731 + }
732 +
733 + $output .= '<div class="ultp-searchresult-content">';
734 + $output .= '<div class="ultp-rescontent-meta">';
735 +
736 + // Category.
737 + $post_cat = get_the_terms( $post_id, 'category' );
738 + if ( $show_category && $post_cat && ! is_wp_error( $post_cat ) ) {
739 + $output .= '<div class="ultp-searchresult-category">';
740 + foreach ( $post_cat as $cat ) {
741 + $term_link = get_term_link( $cat->term_id );
742 + if ( is_wp_error( $term_link ) ) {
743 + continue;
744 + }
745 + $output .= '<a href="' . esc_url( $term_link ) . '">' . esc_html( $cat->name ) . '</a>';
746 + }
747 + $output .= '</div>';
748 + }
749 +
750 + // Author.
751 + if ( $show_author ) {
752 + $user_id = get_the_author_meta( 'ID' );
753 + $output .= '<a href="' . esc_url( get_author_posts_url( $user_id ) ) . '" class="ultp-searchresult-author">' . esc_html( get_the_author_meta( 'display_name' ) ) . '</a>';
754 + }
755 +
756 + // Date.
757 + if ( $show_date ) {
758 + $output .= '<div class="ultp-searchresult-publishdate">' . esc_html( get_the_date( 'F j, Y' ) ) . '</div>';
759 + }
760 +
761 + $output .= '</div>';
762 + $output .= '<a href="' . esc_url( get_permalink() ) . '" class="ultp-searchresult-title">' . esc_html( $title ) . '</a>';
763 +
764 + if ( $show_excerpt ) {
765 + // wp_trim_words() strips tags, so what comes back is plain text.
766 + $output .= '<div class="ultp-searchresult-excerpt">' . esc_html( wp_trim_words( get_the_excerpt(), $excerpt_limit ) ) . '</div>';
767 + }
768 +
769 + $output .= '</div>';
770 + $output .= '</div>';
771 + }
772 + // the_post() overwrote the global $post; hand it back.
773 + wp_reset_postdata();
774 + }
775 +
776 + return array(
777 + 'post_data' => $output,
778 + 'post_count' => $query_result->found_posts,
779 + );
780 + }
781 +
782 + /**
783 + * PostX Site Dark Logo Init
784 + *
785 + * @since v.3.1.9
786 + * @param ARRAY | $server .
787 + * @return BOOOLEAN | Inserted Post Url
788 + */
789 + public function init_site_dark_logo_callback( $server ) {
790 + $logo_data = $server->get_params();
791 + $success = true;
792 + if ( isset( $logo_data['logo']['url'] ) ) {
793 + update_option( 'ultp_site_dark_logo', $logo_data['logo']['url'] );
794 + } else {
795 + $success = false;
796 + }
797 + return rest_ensure_response(
798 + array(
799 + 'success' => $success,
800 + )
801 + );
802 + }
803 +
804 +
805 + /**
806 + * Getting Image Size
807 + *
808 + * @since v.4.0.1
809 + * @param ARRAY | $server (number) .
810 + * @return ARRAY | Image Size List as Array
811 + */
812 + public function get_custom_image_size( $server ) {
813 + $img = $server->get_params();
814 + $image_src = array();
815 + $image_sizes = ultimate_post()->get_image_size();
816 + foreach ( $image_sizes as $key => $value ) {
817 + $image_src[ $key ] = wp_get_attachment_image_src( $img['id'], $key, false )[0];
818 + }
819 + return rest_ensure_response(
820 + array(
821 + 'success' => true,
822 + 'size' => $image_src,
823 + 'id' => $img,
824 + )
825 + );
826 + }
827 +}