PluginProbe
Post Grid Gutenberg Blocks – PostX / trunk
Post Grid Gutenberg Blocks – PostX vtrunk
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 2.1.2 All 237 releases
ultimate-post / classes / Blocks.php

Blocks.php in Post Grid Gutenberg Blocks – PostX trunk, at classes/Blocks.php

767 lines 34.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // phpcs:ignore
3 // @codingStandardsIgnoreFile
4 // @ignoreWarnings
5 /**
6 * Require All Blocks and handle block ajax action
7 *
8 * @package ULTP\Blocks
9 * @since 4.1.11
10 */
11
12 namespace ULTP;
13 defined( 'ABSPATH' ) || exit;
14
15 /**
16 * Blocks class.
17 */
18 class Blocks {
19
20 /**
21 * Setup class.
22 *
23 * Registers AJAX actions and includes all block classes.
24 *
25 * @since 4.1.11
26 */
27 public function __construct() {
28 $this->include_all_blocks(); // Include Blocks .
29 add_action( 'wp_ajax_ultp_next_prev', array( $this, 'ultp_next_prev_callback' ) ); // Next Previous AJAX Call .
30 add_action( 'wp_ajax_nopriv_ultp_next_prev', array( $this, 'ultp_next_prev_callback' ) ); // Next Previous AJAX Call Logout User .
31
32 add_action( 'wp_ajax_ultp_filter', array( $this, 'ultp_filter_callback' ) ); // Next Previous AJAX Call .
33 add_action( 'wp_ajax_nopriv_ultp_filter', array( $this, 'ultp_filter_callback' ) ); // Next Previous AJAX Call Logout User .
34
35 add_action( 'wp_ajax_ultp_adv_filter', array( $this, 'ultp_adv_filter_callback' ) );
36 add_action( 'wp_ajax_nopriv_ultp_adv_filter', array( $this, 'ultp_adv_filter_callback' ) );
37
38 add_action( 'wp_ajax_ultp_pagination', array( $this, 'ultp_pagination_callback' ) ); // Page Number AJAX Call .
39 add_action( 'wp_ajax_nopriv_ultp_pagination', array( $this, 'ultp_pagination_callback' ) ); // Page Number AJAX Call Logout User .
40
41 add_action( 'wp_ajax_ultp_share_count', array( $this, 'ultp_share_count_callback' ) ); // share Count save .
42 add_action( 'wp_ajax_nopriv_ultp_share_count', array( $this, 'ultp_share_count_callback' ) ); // share Count save .
43 add_action( 'wp_ajax_ultp_get_nonce', array( $this, 'ultp_get_nonce_callback' ) ); // Nonce Generating Callback
44 add_action( 'wp_ajax_nopriv_ultp_get_nonce', array( $this, 'ultp_get_nonce_callback' ) ); // Nonce Generating Callback
45 }
46
47 /**
48 * Require Blocks
49 *
50 * @since v.1.0.0
51 * @return NULL
52 */
53 public function include_all_blocks() {
54 spl_autoload_register(
55 function ( $class ) {
56 if ( strpos( $class, 'ULTP\blocks' ) === 0 ) {
57 $source = ULTP_PATH . 'blocks/' . explode( '\\', $class )[2] . '.php';
58 if ( file_exists( $source ) ) {
59 include_once $source;
60 } else {
61 $source = ULTP_PATH . 'addons/builder/blocks/' . explode( '\\', $class )[2] . '.php';
62 if ( file_exists( $source ) ) {
63 include_once $source;
64 }
65 }
66 }
67 }
68 );
69
70 $request = isset( $_POST['action'] ) ? sanitize_text_field( $_POST['action'] ) : '';
71 $get_action = isset( $_GET['action'] ) ? sanitize_text_field( $_GET['action'] ) : '';
72
73 if (
74 is_admin() &&
75 $request != 'et_fb_ajax_render_shortcode' && // Divi Module Check .
76 $get_action != 'elementor' && // Elementor Widget Check .
77 $request != 'elementor_ajax' // Elementor Widget Check .
78 ) {
79 return;
80 }
81
82 $settings = ultimate_post()->get_setting();
83 $blocks = array(
84 'post_list_1' => 'Post_List_1',
85 'post_list_2' => 'Post_List_2',
86 'post_list_3' => 'Post_List_3',
87 'post_list_4' => 'Post_List_4',
88 'post_grid_1' => 'Post_Grid_1',
89 'post_grid_2' => 'Post_Grid_2',
90 'post_grid_3' => 'Post_Grid_3',
91 'post_grid_4' => 'Post_Grid_4',
92 'post_grid_5' => 'Post_Grid_5',
93 'post_grid_6' => 'Post_Grid_6',
94 'post_grid_7' => 'Post_Grid_7',
95 'post_slider_1' => 'Post_Slider_1',
96 'post_slider_2' => 'Post_Slider_2',
97 'post_module_1' => 'Post_Module_1',
98 'post_module_2' => 'Post_Module_2',
99 'heading' => 'Heading',
100 'image' => 'Image',
101 'taxonomy' => 'Taxonomy',
102 'news_ticker' => 'News_Ticker',
103 'advanced_search' => 'Advanced_Search',
104 'advanced_filter' => 'Advanced_Filter',
105 'dark_Light' => 'Dark_Light',
106 'advanced_list' => 'Advanced_List',
107 'button' => 'Button',
108 'youtube_gallery' => 'Youtube_Gallery',
109 );
110
111 foreach ( $blocks as $id => $block ) {
112 if ( isset( $settings[ $id ] ) && $settings[ $id ] != 'yes' ) {
113 } else {
114 $obj = '\ULTP\blocks\\' . $block;
115 new $obj();
116 }
117 }
118
119 if ( isset( $settings['ultp_builder'] ) && $settings['ultp_builder'] == 'true' ) {
120 $builder_blocks = array(
121 'builder_archive_title' => 'Archive_Title',
122 'builder_post_title' => 'Post_Title',
123 'builder_post_content' => 'Post_Content',
124 'builder_post_featured_image' => 'Post_Featured_Image',
125 'builder_post_breadcrumb' => 'Post_Breadcrumb',
126 'builder_post_tag' => 'Post_Tag',
127 'builder_post_category' => 'Post_Category',
128 'builder_post_next_previous' => 'Next_Previous',
129 'builder_post_excerpt' => 'Post_Excerpt',
130 'builder_author_box' => 'Author_Box',
131 'builder_post_comments' => 'Post_Comments',
132 'builder_post_view_count' => 'Post_View_Count',
133 'builder_post_reading_time' => 'Post_Reading_Time',
134 'builder_post_comment_count' => 'Post_Comment_Count',
135 'builder_post_author_meta' => 'Post_Author_Meta',
136 'builder_post_date_meta' => 'Post_Date_Meta',
137 'builder_post_social_share' => 'Post_Social_Share',
138 'builder_advance_post_meta' => 'Advance_Post_Meta',
139 );
140 foreach ( $builder_blocks as $id => $block ) {
141 if ( isset( $settings[ $id ] ) && $settings[ $id ] != 'yes' ) {
142 } else {
143 $obj = '\ULTP\blocks\\' . $block;
144 new $obj();
145 }
146 }
147 }
148 }
149
150
151 /**
152 * Blocks Content Start.
153 *
154 * @since v.1.0.0
155 *
156 * @param ARRAY $blocks The blocks array.
157 * @param STRING $paged The current page number.
158 * @param STRING $blockId The block ID.
159 * @param STRING $blockRaw The raw block name.
160 * @param STRING $blockName The block name.
161 * @param STRING $builder The builder flag.
162 * @param STRING $postId The post ID.
163 * @param STRING|ARRAY $filterValue The filter value.
164 * @param STRING $filterType The filter type.
165 * @param ARRAY $ultp_uniqueIds Unique IDs for pagination.
166 * @param ARRAY $ultp_current_unique_posts Current unique posts.
167 * @param STRING $widgetBlockId The widget block ID.
168 * @param STRING $exclude_post_id The post ID to exclude.
169 * @param ARRAY $adv_filter_data Advanced filter data.
170 * @return STRING The AJAX response.
171 */
172 public function pagination_content_return( $blocks, $paged, $blockId, $blockRaw, $blockName, $builder, $postId, $filterValue, $filterType, $ultp_uniqueIds = array(), $ultp_current_unique_posts = array(), $widgetBlockId = '', $exclude_post_id = '', $adv_filter_data = array() ) {
173 foreach ( $blocks as $key => $value ) {
174 if ( $blockName == $value['blockName'] ) {
175 if ( $value['attrs']['blockId'] == $blockId ) {
176 $objName = str_replace( ' ', '_', ucwords( str_replace( array( 'ultimate-post/', '-' ), array( '', ' ' ), $blockName ) ) );
177 $new_obj = '\ULTP\blocks\\' . $objName;
178 $objectBlock = new $new_obj();
179 $attr = $objectBlock->get_attributes( true );
180
181 // Fix for grid blocks that do not support load more by default (pagination block)
182 if ( isset( $adv_filter_data['notFirstLoad'] ) && $adv_filter_data['notFirstLoad'] ) {
183 $attr['notFirstLoad'] = $adv_filter_data['notFirstLoad'];
184 }
185
186 $value['attrs']['paged'] = $paged;
187 if ( $builder ) {
188 $value['attrs']['builder'] = $builder;
189 }
190 if ( $postId ) {
191 $attr['current_post'] = $postId;
192 if ( get_post_type( $postId ) == 'ultp_builder' && ! $builder ) {
193 $attr['current_post'] = $exclude_post_id;
194 }
195 }
196 if ( isset( $value['attrs']['queryUnique'] ) && $value['attrs']['queryUnique'] ) {
197 $value['attrs']['loadMoreQueryUnique'] = $ultp_uniqueIds;
198 $ultp_uniqueIds[ $value['attrs']['queryUnique'] ] = array_diff( $ultp_uniqueIds[ $value['attrs']['queryUnique'] ], $ultp_current_unique_posts );
199 $value['attrs']['savedQueryUnique'] = $ultp_uniqueIds;
200 $value['attrs']['ultp_current_unique_posts'] = $ultp_current_unique_posts;
201 }
202 if ( isset( $value['attrs']['queryUnique'] ) && $value['attrs']['queryUnique'] && ( $value['attrs']['paginationType'] == 'loadMore' || $value['attrs']['paginationType'] == 'navigation' ) && isset( $ultp_uniqueIds ) && ! isset( $ultp_current_unique_posts ) ) {
203 die();
204 }
205
206 if ( $filterValue ) {
207 $value['attrs']['queryTaxValue'] = $adv_filter_data['is_adv'] ? wp_json_encode( $filterValue ) : wp_json_encode( array( $filterValue ) );
208 $value['attrs']['queryTax'] = $filterType;
209 $value['attrs']['checkFilter'] = true;
210 $value['attrs']['filterShow'] = $adv_filter_data['filterShow'];
211 $value['attrs']['queryAuthor'] = $adv_filter_data['author'];
212 $value['attrs']['queryOrderBy'] = $adv_filter_data['orderby'];
213 $value['attrs']['queryOrder'] = $adv_filter_data['order'];
214 $value['attrs']['querySearch'] = $adv_filter_data['search'];
215 $value['attrs']['queryQuick'] = $adv_filter_data['adv_sort'];
216
217 if ( $adv_filter_data['is_adv'] ) {
218 $value['attrs']['queryRelation'] = 'AND';
219 }
220 }
221 // Exclude Current Post From Pagination
222 if ( $exclude_post_id ) {
223 $queryArr = json_decode( $value['attrs']['queryExclude'] );
224 $queryArr[] = array(
225 'value' => $exclude_post_id,
226 'title' => '',
227 );
228 $value['attrs']['queryExclude'] = wp_json_encode( $queryArr );
229 }
230 $attr = array_merge( $attr, $value['attrs'] );
231 echo $objectBlock->content($attr, true); //phpcs:ignore
232 die();
233 }
234 }
235 if ( ! empty( $value['innerBlocks'] ) ) {
236 $this->pagination_content_return( $value['innerBlocks'], $paged, $blockId, $blockRaw, $blockName, $builder, $postId, $filterValue, $filterType, $ultp_uniqueIds, $ultp_current_unique_posts, $widgetBlockId, $exclude_post_id, $adv_filter_data );
237 }
238 }
239 }
240
241
242 /**
243 * Next Preview Callback of the Blocks.
244 *
245 * @since v.1.0.0
246 *
247 * @return STRING The AJAX response.
248 */
249 public function ultp_next_prev_callback() {
250 if ( ! ( isset( $_REQUEST['wpnonce'] ) && wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['wpnonce'] ) ), 'ultp-nonce' ) ) ) {
251 return;
252 }
253
254 $paged = isset( $_POST['paged'] ) ? sanitize_text_field( $_POST['paged'] ) : '';
255 $blockId = isset( $_POST['blockId'] ) ? sanitize_text_field( $_POST['blockId'] ) : '';
256 $postId = isset( $_POST['postId'] ) ? sanitize_text_field( $_POST['postId'] ) : '';
257 $blockRaw = isset( $_POST['blockName'] ) ? sanitize_text_field( $_POST['blockName'] ) : '';
258 $builder = isset( $_POST['builder'] ) ? sanitize_text_field( $_POST['builder'] ) : '';
259 $blockName = str_replace( '_', '/', $blockRaw );
260 $widgetBlockId = isset( $_POST['widgetBlockId'] ) ? sanitize_text_field( $_POST['widgetBlockId'] ) : '';
261 $exclude_post_id = isset( $_POST['exclude'] ) ? sanitize_text_field( $_POST['exclude'] ) : '';
262
263 if ( $postId ) { // patch security issue
264 $post = get_post( (int) $postId );
265
266 if ( ! $post ) {
267 wp_send_json_error( array( 'message' => 'Post not found' ) );
268 return;
269 }
270
271 // Block private posts
272 if ( $post->post_status === 'private' && ! current_user_can( 'read_private_posts' ) ) {
273 wp_send_json_error( array( 'message' => 'Private post' ) );
274 return;
275 }
276
277 // Block draft/pending
278 if ( in_array( $post->post_status, array( 'draft', 'pending' ), true )
279 && ! current_user_can( 'edit_post', $post->ID ) ) {
280 wp_send_json_error( array( 'message' => 'Not allowed' ) );
281 return;
282 }
283
284 // Block password protected
285 if ( post_password_required( $post ) ) {
286 wp_send_json_error( array( 'message' => 'Password protected' ) );
287 return;
288 }
289 }
290
291 $is_adv = isset( $_POST['isAdv'] ) ? ultimate_post()->ultp_rest_sanitize_params( $_POST['isAdv'] ) : false;
292 $filterValue = isset( $_POST['filterValue'] ) ?
293 (
294 is_array( $_POST['filterValue'] ) ?
295 ultimate_post()->ultp_rest_sanitize_params( $_POST['filterValue'] ) :
296 sanitize_text_field( $_POST['filterValue'] )
297 ) :
298 '';
299
300 $filterType = isset( $_POST['filterType'] ) ? sanitize_text_field( $_POST['filterType'] ) : '';
301 $filterShow = isset( $_POST['filterShow'] ) ? sanitize_text_field( $_POST['filterShow'] ) : false;
302 $checkFilter = isset( $_POST['checkFilter'] ) ? sanitize_text_field( $_POST['checkFilter'] ) : false;
303 $author = isset( $_POST['author'] ) ? sanitize_text_field( $_POST['author'] ) : false;
304 $orderby = isset( $_POST['orderby'] ) ? sanitize_text_field( $_POST['orderby'] ) : 'date';
305 $order = isset( $_POST['order'] ) ? sanitize_text_field( $_POST['order'] ) : 'DESC';
306 $search = isset( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '';
307 $adv_sort = isset( $_POST['adv_sort'] ) ? sanitize_text_field( $_POST['adv_sort'] ) : '';
308
309 $adv_filter_data = array(
310 'is_adv' => filter_var( $is_adv, FILTER_VALIDATE_BOOLEAN ),
311 'filterShow' => filter_var( $filterShow, FILTER_VALIDATE_BOOLEAN ),
312 'checkFilter' => filter_var( $checkFilter, FILTER_VALIDATE_BOOLEAN ),
313 'author' => $author ? wp_json_encode( $author ) : false,
314 'orderby' => $orderby,
315 'order' => $order,
316 'search' => $search,
317 'adv_sort' => $adv_sort,
318 'notFirstLoad' => true,
319 );
320
321 $ultp_uniqueIds = isset( $_POST['ultpUniqueIds'] ) ? json_decode( stripslashes( sanitize_text_field( $_POST['ultpUniqueIds'] ) ), true ) : array();
322 $ultp_current_unique_posts = isset( $_POST['ultpCurrentUniquePosts'] ) ? json_decode( stripslashes( sanitize_text_field( $_POST['ultpCurrentUniquePosts'] ) ), true ) : array();
323
324 if ( $widgetBlockId ) {
325 $blocks = parse_blocks( get_option( 'widget_block' )[ $widgetBlockId ]['content'] );
326 $this->pagination_content_return( $blocks, $paged, $blockId, $blockRaw, $blockName, $builder, '', $filterValue, $filterType, $ultp_uniqueIds, $ultp_current_unique_posts, $widgetBlockId, '', $adv_filter_data );
327 } elseif ( $paged && $blockId && $postId && $blockName ) {
328 $post = get_post( $postId );
329 if ( has_blocks( $post->post_content ) ) {
330 $blocks = parse_blocks( $post->post_content );
331 $this->pagination_content_return( $blocks, $paged, $blockId, $blockRaw, $blockName, $builder, $postId, $filterValue, $filterType, $ultp_uniqueIds, $ultp_current_unique_posts, '', $exclude_post_id, $adv_filter_data );
332 }
333 }
334 }
335
336 /**
337 * Filter Callback of the Blocks.
338 *
339 * @since v.1.0.0
340 *
341 * @return STRING The AJAX response.
342 */
343 public function ultp_filter_callback() {
344 if ( ! ( isset( $_REQUEST['wpnonce'] ) && wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['wpnonce'] ) ), 'ultp-nonce' ) ) ) {
345 return;
346 }
347
348 $taxtype = isset( $_POST['taxtype'] ) ? sanitize_text_field( $_POST['taxtype'] ) : '';
349 if ( $taxtype ) {
350 $blockId = isset( $_POST['blockId'] ) ? sanitize_text_field( $_POST['blockId'] ) : '';
351 $postId = isset( $_POST['postId'] ) ? sanitize_text_field( $_POST['postId'] ) : '';
352 $taxonomy = isset( $_POST['taxonomy'] ) ? sanitize_text_field( $_POST['taxonomy'] ) : '';
353 $blockRaw = isset( $_POST['blockName'] ) ? sanitize_text_field( $_POST['blockName'] ) : '';
354 $blockName = str_replace( '_', '/', $blockRaw );
355 $post = get_post( $postId );
356 $widgetBlockId = isset( $_POST['widgetBlockId'] ) ? sanitize_text_field( $_POST['widgetBlockId'] ) : '';
357 $ultp_uniqueIds = isset( $_POST['ultpUniqueIds'] ) ? json_decode( stripslashes( sanitize_text_field( $_POST['ultpUniqueIds'] ) ), true ) : array();
358 $ultp_current_unique_posts = isset( $_POST['ultpCurrentUniquePosts'] ) ? json_decode( stripslashes( sanitize_text_field( $_POST['ultpCurrentUniquePosts'] ) ), true ) : array();
359 $toReturn = array();
360
361 if ( $widgetBlockId ) {
362 $blocks = parse_blocks( get_option( 'widget_block' )[ $widgetBlockId ]['content'] );
363 $data = $this->filter_content_return( $blocks, $blockId, $blockRaw, $blockName, $taxtype, $taxonomy, $postId, $toReturn, $widgetBlockId, array(), $ultp_uniqueIds, $ultp_current_unique_posts );
364 } elseif ( has_blocks( $post->post_content ) ) {
365 $blocks = parse_blocks( $post->post_content );
366 $data = $this->filter_content_return( $blocks, $blockId, $blockRaw, $blockName, $taxtype, $taxonomy, $postId, $toReturn, '', array(), $ultp_uniqueIds, $ultp_current_unique_posts );
367 }
368 return wp_send_json_success(
369 array(
370 'filteredData' => $data,
371 )
372 );
373 }
374 }
375
376 /**
377 * Advanced Filter Callback of the Blocks.
378 *
379 * @since v.3.2.4
380 *
381 * @return STRING The AJAX response.
382 */
383 public function ultp_adv_filter_callback() {
384 if ( ! ( isset( $_REQUEST['wpnonce'] ) && wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['wpnonce'] ) ), 'ultp-nonce' ) ) ) {
385 return;
386 }
387
388 $blockId = isset( $_POST['blockId'] ) ? sanitize_text_field( $_POST['blockId'] ) : '';
389 $postId = isset( $_POST['postId'] ) ? sanitize_text_field( $_POST['postId'] ) : '';
390
391 $taxonomy = isset( $_POST['taxonomy'] ) ? ultimate_post()->ultp_rest_sanitize_params( $_POST['taxonomy'] ) : '[]';
392 $builder_id = isset( $_POST['builder_id'] ) ? sanitize_text_field( $_POST['builder_id'] ) : '';
393 $author = isset( $_POST['author'] ) ? ultimate_post()->ultp_rest_sanitize_params( $_POST['author'] ) : false;
394 $orderby = isset( $_POST['orderby'] ) ? sanitize_text_field( $_POST['orderby'] ) : ''; // default orderbyt title requested from support
395 $order = isset( $_POST['order'] ) ? sanitize_text_field( $_POST['order'] ) : 'DESC';
396 $search = isset( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '';
397 $adv_sort = isset( $_POST['adv_sort'] ) ? sanitize_text_field( $_POST['adv_sort'] ) : '';
398
399 $adv_filter_data = array(
400 'is_adv' => true,
401 'filterShow' => true,
402 'checkFilter' => true,
403 'author' => $author ? wp_json_encode( $author ) : false,
404 'orderby' => $orderby,
405 'order' => $order,
406 'search' => $search,
407 'adv_sort' => $adv_sort,
408 'builder' => $builder_id,
409 );
410
411 $blockRaw = isset( $_POST['blockName'] ) ? sanitize_text_field( $_POST['blockName'] ) : '';
412 $blockName = str_replace( '_', '/', $blockRaw );
413 $post = get_post( $postId );
414 $widgetBlockId = isset( $_POST['widgetBlockId'] ) ? sanitize_text_field( $_POST['widgetBlockId'] ) : '';
415 $toReturn = array();
416
417 $ultp_uniqueIds = isset( $_POST['ultpUniqueIds'] ) ? json_decode( stripslashes( sanitize_text_field( $_POST['ultpUniqueIds'] ) ), true ) : array();
418 $ultp_current_unique_posts = isset( $_POST['ultpCurrentUniquePosts'] ) ? json_decode( stripslashes( sanitize_text_field( $_POST['ultpCurrentUniquePosts'] ) ), true ) : array();
419
420 if ( $widgetBlockId ) {
421 $blocks = parse_blocks( get_option( 'widget_block' )[ $widgetBlockId ]['content'] );
422 $data = $this->filter_content_return( $blocks, $blockId, $blockRaw, $blockName, 'multiTaxonomy', $taxonomy, $postId, $toReturn, $widgetBlockId, $adv_filter_data, $ultp_uniqueIds, $ultp_current_unique_posts );
423 } elseif ( has_blocks( $post->post_content ) ) {
424 $blocks = parse_blocks( $post->post_content );
425 $data = $this->filter_content_return( $blocks, $blockId, $blockRaw, $blockName, 'multiTaxonomy', $taxonomy, $postId, $toReturn, '', $adv_filter_data, $ultp_uniqueIds, $ultp_current_unique_posts );
426 }
427 return wp_send_json_success(
428 array(
429 'filteredData' => $data,
430 )
431 );
432 }
433
434 /**
435 * Pagination of the Blocks.
436 *
437 * @since v.1.0.0
438 *
439 * @return STRING The AJAX response.
440 */
441 public function ultp_pagination_callback() {
442 if ( ! ( isset( $_REQUEST['wpnonce'] ) && wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['wpnonce'] ) ), 'ultp-nonce' ) ) ) {
443 return;
444 }
445
446 $paged = isset( $_POST['paged'] ) ? sanitize_text_field( $_POST['paged'] ) : '';
447 if ( $paged ) {
448 $blockId = isset( $_POST['blockId'] ) ? sanitize_text_field( $_POST['blockId'] ) : '';
449 $postId = isset( $_POST['postId'] ) ? sanitize_text_field( $_POST['postId'] ) : '';
450 $blockRaw = isset( $_POST['blockName'] ) ? sanitize_text_field( $_POST['blockName'] ) : '';
451 $builder = isset( $_POST['builder'] ) ? sanitize_text_field( $_POST['builder'] ) : '';
452 $blockName = str_replace( '_', '/', $blockRaw );
453 $post = get_post( $postId );
454 $widgetBlockId = isset( $_POST['widgetBlockId'] ) ? sanitize_text_field( $_POST['widgetBlockId'] ) : '';
455 $exclude_post_id = isset( $_POST['exclude'] ) ? sanitize_text_field( $_POST['exclude'] ) : '';
456
457 $is_adv = isset( $_POST['isAdv'] ) ? ultimate_post()->ultp_rest_sanitize_params( $_POST['isAdv'] ) : false;
458
459 $filterValue = array();
460
461 if ( isset( $_POST['filterValue'] ) ) {
462 if ( is_array( $_POST['filterValue'] ) ) {
463 $filterValue = ultimate_post()->ultp_rest_sanitize_params( $_POST['filterValue'] );
464 } else {
465 $decoded = json_decode( $_POST['filterValue'] );
466 if ( is_array( $decoded ) ) {
467 $filterValue = ultimate_post()->ultp_rest_sanitize_params( $decoded );
468 } elseif ( $decoded ) {
469 $filterValue = sanitize_text_field( $_POST['filterValue'] );
470 }
471 }
472 }
473
474 $filterType = isset( $_POST['filterType'] ) ? sanitize_text_field( $_POST['filterType'] ) : '';
475 $filterShow = isset( $_POST['filterShow'] ) ? sanitize_text_field( $_POST['filterShow'] ) : false;
476 $checkFilter = isset( $_POST['checkFilter'] ) ? sanitize_text_field( $_POST['checkFilter'] ) : false;
477 $author = isset( $_POST['author'] ) ? sanitize_text_field( $_POST['author'] ) : false;
478 $orderby = isset( $_POST['orderby'] ) ? sanitize_text_field( $_POST['orderby'] ) : 'title'; // default orderbyt title requested from support
479 $order = isset( $_POST['order'] ) ? sanitize_text_field( $_POST['order'] ) : 'DESC';
480 $search = isset( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '';
481 $adv_sort = isset( $_POST['adv_sort'] ) ? sanitize_text_field( $_POST['adv_sort'] ) : '';
482
483 $adv_filter_data = array(
484 'is_adv' => filter_var( $is_adv, FILTER_VALIDATE_BOOLEAN ),
485 'filterShow' => filter_var( $filterShow, FILTER_VALIDATE_BOOLEAN ),
486 'checkFilter' => filter_var( $checkFilter, FILTER_VALIDATE_BOOLEAN ),
487 'author' => $author ? wp_json_encode( $author ) : false,
488 'orderby' => $orderby,
489 'order' => $order,
490 'search' => $search,
491 'adv_sort' => $adv_sort,
492 );
493
494 $ultp_uniqueIds = isset( $_POST['ultpUniqueIds'] ) ? json_decode( stripslashes( sanitize_text_field( $_POST['ultpUniqueIds'] ) ), true ) : array();
495 $ultp_current_unique_posts = isset( $_POST['ultpCurrentUniquePosts'] ) ? json_decode( stripslashes( sanitize_text_field( $_POST['ultpCurrentUniquePosts'] ) ), true ) : array();
496
497 if ( $widgetBlockId ) {
498 $blocks = parse_blocks( get_option( 'widget_block' )[ $widgetBlockId ]['content'] );
499 $this->pagination_content_return( $blocks, $paged, $blockId, $blockRaw, $blockName, $builder, '', $filterValue, $filterType, $ultp_uniqueIds, $ultp_current_unique_posts, $widgetBlockId, '', $adv_filter_data );
500 } elseif ( has_blocks( $post->post_content ) ) {
501 $blocks = parse_blocks( $post->post_content );
502 $this->pagination_content_return( $blocks, $paged, $blockId, $blockRaw, $blockName, $builder, $postId, $filterValue, $filterType, $ultp_uniqueIds, $ultp_current_unique_posts, '', $exclude_post_id, $adv_filter_data );
503 }
504 }
505 }
506
507 /**
508 * Share Count callback.
509 *
510 * @since v.1.0.0
511 *
512 * @return void
513 */
514 public function ultp_share_count_callback() {
515 if ( ! ( isset( $_REQUEST['wpnonce'] ) && wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['wpnonce'] ) ), 'ultp-nonce' ) ) ) {
516 return;
517 }
518
519 $post_id = isset( $_POST['postId'] ) ? absint( $_POST['postId'] ) : 0;
520
521 // Validate post ID
522 if ( ! $post_id ) {
523 wp_send_json_error( array( 'message' => 'Invalid post ID' ) );
524 return;
525 }
526
527 // Check if post exists
528 $post = get_post( $post_id );
529 if ( ! $post ) {
530 wp_send_json_error( array( 'message' => 'Post not found' ) );
531 return;
532 }
533
534 // Block private posts
535 if ( $post->post_status === 'private' && ! current_user_can( 'read_private_posts' ) ) {
536 wp_send_json_error( array( 'message' => 'Private post' ) );
537 return;
538 }
539
540 // Block draft/pending posts
541 if ( in_array( $post->post_status, array( 'draft', 'pending' ), true )
542 && ! current_user_can( 'edit_post', $post->ID ) ) {
543 wp_send_json_error( array( 'message' => 'Not allowed' ) );
544 return;
545 }
546
547 // Block password protected posts
548 if ( post_password_required( $post ) ) {
549 wp_send_json_error( array( 'message' => 'Password protected' ) );
550 return;
551 }
552
553 // Only allow published posts to have share count updated
554 if ( $post->post_status !== 'publish' ) {
555 wp_send_json_error( array( 'message' => 'Post not published' ) );
556 return;
557 }
558
559 // Rate limiting - 60 second cooldown per user per post
560 $user_identifier = is_user_logged_in() ? 'user_' . get_current_user_id() : 'ip_' . sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ?? '' ) );
561 $transient_key = 'ultp_share_' . $post_id . '_' . md5( $user_identifier );
562
563 if ( get_transient( $transient_key ) ) {
564 return; // Already shared within last 60 seconds
565 }
566
567 set_transient( $transient_key, true, 60 ); // 60 seconds cooldown
568
569 // Always increment by 1 from database - ignore POST shareCount
570 $current_count = get_post_meta( $post_id, 'share_count', true );
571 $current_count = $current_count ? absint( $current_count ) : 0;
572 $new_count = $current_count + 1;
573
574 update_post_meta( $post_id, 'share_count', $new_count );
575 }
576
577 /**
578 * Filter Callback of the Blocks.
579 *
580 * @since v.1.0.0
581 *
582 * @param ARRAY $blocks The blocks array.
583 * @param STRING $blockId The block ID.
584 * @param STRING $blockRaw The raw block name.
585 * @param STRING $blockName The block name.
586 * @param STRING $taxtype The taxonomy type.
587 * @param STRING|ARRAY $taxonomy The taxonomy.
588 * @param STRING $postId The post ID.
589 * @param ARRAY $toReturn The array to return.
590 * @param STRING $widgetBlockId The widget block ID.
591 * @param ARRAY $adv_filter_data The advanced filter data.
592 * @param ARRAY $ultp_uniqueIds The unique IDs.
593 * @param ARRAY $ultp_current_unique_posts The current unique posts.
594 * @return ARRAY
595 */
596 public function filter_content_return( $blocks, $blockId, $blockRaw, $blockName, $taxtype, $taxonomy, $postId, &$toReturn, $widgetBlockId = '', $adv_filter_data = array(), $ultp_uniqueIds = array(), $ultp_current_unique_posts = array() ) {
597 foreach ( $blocks as $key => $value ) {
598 if ( ( $value['blockName'] ?? '' ) === 'core/shortcode' ) {
599 if ( preg_match( '/id="([^"]+)"/', $value['innerHTML'] ?? '', $matches ) ) {
600 $template_post = get_post( $matches[1] );
601 if ( $template_post && ! empty( $template_post->post_content ) ) {
602 $template_blocks = parse_blocks( $template_post->post_content );
603 // recurse into the expanded blocks instead
604 $this->filter_content_return( $template_blocks, $blockId, $blockRaw, $blockName, $taxtype, $taxonomy, $postId, $toReturn, $widgetBlockId, $adv_filter_data, $ultp_uniqueIds, $ultp_current_unique_posts );
605 continue; // skip the shortcode block itself
606 }
607 }
608 }
609 if ( $blockName == $value['blockName'] ) {
610 if ( $value['attrs']['blockId'] == $blockId ) {
611 $objName = str_replace( ' ', '_', ucwords( str_replace( array( 'ultimate-post/', '-' ), array( '', ' ' ), $blockName ) ) );
612 $new_obj = '\ULTP\blocks\\' . $objName;
613 $objectBlock = new $new_obj();
614 $attr = $objectBlock->get_attributes( true );
615 if ( $taxonomy ) {
616
617 if ( isset( $adv_filter_data['is_adv'] ) && $adv_filter_data['is_adv'] ) {
618 $value['attrs']['queryTaxValue'] = wp_json_encode( $taxonomy );
619 $value['attrs']['queryRelation'] = 'AND';
620 $value['attrs']['queryAuthor'] = $adv_filter_data['author'];
621 $value['attrs']['queryOrder'] = $adv_filter_data['order'];
622 $value['attrs']['querySearch'] = $adv_filter_data['search'];
623 $value['attrs']['queryQuick'] = $adv_filter_data['adv_sort'];
624 if ( ! empty( $adv_filter_data['orderby'] ) ) {
625 $value['attrs']['queryOrderBy'] = $adv_filter_data['orderby'];
626 }
627 } else {
628 $value['attrs']['queryTaxValue'] = wp_json_encode( array( $taxonomy ) );
629 }
630
631 $value['attrs']['queryTax'] = $taxtype;
632 $value['attrs']['ajaxCall'] = true;
633 }
634 if ( isset( $value['attrs']['queryNumber'] ) ) {
635 $value['attrs']['queryNumber'] = $value['attrs']['queryNumber'];
636 }
637
638 if ( isset( $value['attrs']['queryUnique'] ) && $value['attrs']['queryUnique'] ) {
639 $value['attrs']['loadMoreQueryUnique'] = $ultp_uniqueIds;
640 $ultp_uniqueIds[ $value['attrs']['queryUnique'] ] = array_diff( $ultp_uniqueIds[ $value['attrs']['queryUnique'] ], $ultp_current_unique_posts );
641 $value['attrs']['savedQueryUnique'] = $ultp_uniqueIds;
642 $value['attrs']['ultp_current_unique_posts'] = $ultp_current_unique_posts;
643 }
644
645 if ( $adv_filter_data['builder'] ) {
646 $value['attrs']['builder'] = $adv_filter_data['builder'];
647 }
648
649 $attr = array_merge( $attr, $value['attrs'] );
650
651 $filter_attributes = array();
652
653 $filter_attributes['isAdv'] = isset( $adv_filter_data['is_adv'] ) ? $adv_filter_data['is_adv'] : false;
654 $filter_attributes['queryTaxValue'] = $filter_attributes['isAdv'] ? wp_json_encode( $taxonomy ) : $taxonomy;
655 $filter_attributes['queryTax'] = $taxtype;
656
657 if ( $filter_attributes['isAdv'] ) {
658 $filter_attributes['queryAuthor'] = $adv_filter_data['author'];
659 $filter_attributes['queryOrder'] = $adv_filter_data['order'];
660 $filter_attributes['querySearch'] = $adv_filter_data['search'];
661 $filter_attributes['queryQuick'] = $adv_filter_data['adv_sort'];
662 $filter_attributes['queryOrderBy'] =
663 ! empty( $adv_filter_data['orderby'] ) ? $adv_filter_data['orderby'] : ( $value['attrs']['queryOrderBy'] ?? '' );
664 }
665 $pagination = $this->pagination_for_filter( $attr, $postId, $blockRaw, $filter_attributes );
666 $toReturn = array(
667 'blocks' => $objectBlock->content( $attr, true ),
668 'notFound' => isset( $attr['notFoundMessage'] ) ? $attr['notFoundMessage'] : '',
669 'pagination' => $pagination['pagination_content'],
670 'data_attrs' => $pagination['data_attrs'],
671 'data_all_attrs' => $pagination['data_attrs'],
672 'paginationType' => $attr['paginationType'],
673 'paginationShow' => $attr['paginationShow'],
674 );
675 }
676 }
677 if ( ! empty( $value['innerBlocks'] ) ) {
678 $this->filter_content_return( $value['innerBlocks'], $blockId, $blockRaw, $blockName, $taxtype, $taxonomy, $postId, $toReturn, $widgetBlockId, $adv_filter_data, $ultp_uniqueIds, $ultp_current_unique_posts );
679 }
680 }
681 return $toReturn;
682 }
683
684 /**
685 * Pagination for filter callback
686 *
687 * @since v.2.8.9
688 *
689 * @param ARRAY $attr .
690 * @param STRING $postId .
691 * @param STRING $blockRaw .
692 * @param ARRAY $filter_attributes .
693 * @return STRING
694 */
695 public function pagination_for_filter( $attr, $postId, $blockRaw, $filter_attributes ) {
696 $attr['queryNumber'] = ultimate_post()->get_post_number( 4, $attr['queryNumber'], $attr['queryNumPosts'] );
697 $recent_posts = new \WP_Query( ultimate_post()->get_query( $attr ) );
698 $pageNum = ultimate_post()->get_page_number( $attr, $recent_posts->found_posts );
699
700 $datasets = ultimate_post()->get_adv_data_attrs( null, $filter_attributes );
701 $datasets .= ' data-for="ultp-block-' . sanitize_html_class( $attr['blockId'] ) . '" ';
702
703 $wraper_after = '';
704 $style = $pageNum == 1 ? 'style="display:none"' : '';
705
706 if ( $attr['paginationType'] == 'loadMore' ) {
707 $wraper_after .= '<div ' . $style . ' class="ultp-loadmore "' . '>';
708 $wraper_after .= '<span class="ultp-loadmore-action" tabindex="0" role="button" data-pages="' . $pageNum . '" data-pagenum="1" data-blockid="' . $attr['blockId'] . '" data-blockname="' . $blockRaw . '" data-postid="' . $postId . '" ' . ultimate_post()->get_builder_attr( $attr['queryType'] ) . $datasets . '>' . ( isset( $attr['loadMoreText'] ) ? $attr['loadMoreText'] : 'Load More' ) . ' <span class="ultp-spin">' . ultimate_post()->get_svg_icon( 'refresh' ) . '</span></span>';
709 $wraper_after .= '</div>';
710 } elseif ( $attr['paginationType'] == 'navigation' ) {
711 $wraper_after .= '<div ' . $style . ' class="ultp-next-prev-wrap" data-pages="' . $pageNum . '" data-pagenum="1" data-blockid="' . $attr['blockId'] . '" data-blockname="' . $blockRaw . '" data-postid="' . $postId . '" ' . ultimate_post()->get_builder_attr( $attr['queryType'] ) . $datasets . '>';
712 $wraper_after .= ultimate_post()->next_prev();
713 $wraper_after .= '</div>';
714 } elseif ( $attr['paginationType'] == 'pagination' ) {
715 $wraper_after .= '<div class="ultp-pagination-wrap' . ( $attr['paginationAjax'] ? ' ultp-pagination-ajax-action' : '' ) . '" data-paged="1" data-blockid="' . $attr['blockId'] . '" data-postid="' . $postId . '" data-pages="' . $pageNum . '" data-blockname="' . $blockRaw . '" ' . ultimate_post()->get_builder_attr( $attr['queryType'] ) . $datasets . '>';
716
717 $wraper_after .= ultimate_post()->pagination(
718 $pageNum,
719 $attr['paginationNav'],
720 $attr['paginationText'],
721 $attr['paginationAjax'],
722 isset( $_SERVER['HTTP_REFERER'] ) ? esc_url_raw( $_SERVER['HTTP_REFERER'] ) : '',
723 $attr['blockId']
724 );
725
726 $wraper_after .= '</div>';
727 }
728 wp_reset_query();
729
730 // queryQuick
731 return array(
732 'pagination_content' => $wraper_after,
733 'data_attrs' => wp_json_encode( array(
734 'paged' => 1,
735 'blockid' => $attr['blockId'],
736 'postid' => $postId,
737 'pages' => $pageNum,
738 'blockname' => $blockRaw,
739 'filter_value' => isset( $filter_attributes['queryTaxValue'] ) ? $filter_attributes['queryTaxValue'] : '',
740 'filter_type' => isset( $filter_attributes['queryTax'] ) ? $filter_attributes['queryTax'] : '',
741 'filter_author' => isset( $filter_attributes['queryAuthor'] ) ? $filter_attributes['queryAuthor'] : '',
742 'filter_order' => isset( $filter_attributes['queryOrder'] ) ? $filter_attributes['queryOrder'] : 'DESC',
743 'filter_orderby' => isset( $filter_attributes['queryOrderBy'] ) ? $filter_attributes['queryOrderBy'] : '',
744 'filter_search' => isset( $filter_attributes['querySearch'] ) ? $filter_attributes['querySearch'] : '',
745 'filter_queryQuick' => isset( $filter_attributes['queryQuick'] ) ? $filter_attributes['queryQuick'] : '',
746 'filter_for' => 'ultp-block-' . $attr['blockId'],
747 )),
748 );
749 }
750
751 /**
752 * Nonce Generation Callback
753 *
754 * @since v.5.0.6
755 *
756 * @return STRING The AJAX response.
757 */
758 public function ultp_get_nonce_callback() {
759 nocache_headers();
760 wp_send_json_success(
761 array(
762 'nonce' => wp_create_nonce( 'ultp-nonce' ),
763 )
764 );
765 }
766 }
767