PluginProbe
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets / 4.5.0
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets v4.5.0
4.5.6 4.5.5 4.5.4 4.2.1 4.2.2 4.2.3 4.5.0 4.5.2 4.5.3 4.2.0 4.1.18 4.1.17 4.1.16 4.1.15 4.1.14 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.0.9 4.1.0 4.1.1 4.1.2 All 148 releases
ultimate-post-kit / modules / alex-grid / module.php

module.php in Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets 4.5.0, at modules/alex-grid/module.php

241 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace UltimatePostKit\Modules\AlexGrid;
3
4 use UltimatePostKit\Base\Ultimate_Post_Kit_Module_Base;
5 use UltimatePostKit\Traits\Global_Widget_Functions;
6 use Elementor\Icons_Manager;
7 use UltimatePostKit\Utils;
8
9 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
11 class Module extends Ultimate_Post_Kit_Module_Base {
12
13 use Global_Widget_Functions;
14
15 public function __construct() {
16 parent::__construct();
17
18 add_action('wp_ajax_nopriv_upk_alex_grid_loadmore_posts', [$this, 'callback_ajax_loadmore_posts']);
19 add_action('wp_ajax_upk_alex_grid_loadmore_posts', [$this, 'callback_ajax_loadmore_posts']);
20 }
21
22 public function get_name() {
23 return 'alex-grid';
24 }
25
26 public function get_widgets() {
27
28 $widgets = [
29 'Alex_Grid',
30 ];
31
32 return $widgets;
33 }
34
35 public function callback_ajax_loadmore_posts() {
36 // Verify the front-end nonce (sent by UltimatePostKitConfig.nonce) before
37 // processing this public load-more request.
38 if ( ! check_ajax_referer( 'upk-site', 'nonce', false ) ) {
39 wp_send_json_error( array( 'message' => esc_html__( 'Security check failed.', 'ultimate-post-kit' ) ), 403 );
40 }
41
42
43 // Security: Verify nonce
44 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'upk-site' ) ) {
45 wp_send_json_error( [ 'message' => esc_html__( 'Security verification failed', 'ultimate-post-kit' ) ], 403 );
46 wp_die();
47 }
48
49 $settings = [];
50
51 if ( isset( $_POST['settings'] ) && is_array( $_POST['settings'] ) ) {
52 $settings = map_deep( wp_unslash( $_POST['settings'] ), 'sanitize_text_field' );
53 }
54
55 $post_type = $settings['post_source'] ?? 'post';
56
57 // Security: Enforce query limits to prevent DoS
58 $per_page = isset( $_POST['per_page'] ) ? absint( $_POST['per_page'] ) : 6;
59 $per_page = min( $per_page, 50 ); // Maximum 50 posts per request
60 $offset = isset( $_POST['offset'] ) ? absint( $_POST['offset'] ) : 0;
61 $offset = min( $offset, 1000 ); // Maximum offset of 1000
62
63 // Security: Whitelist allowed post types
64 $allowed_post_types = [ 'post', 'page' ];
65 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- established hook name relied on across the plugin family; renaming would break integration.
66 $allowed_post_types = apply_filters( 'upk_alex_grid_allowed_post_types', $allowed_post_types );
67 $post_type = in_array( $post_type, $allowed_post_types, true ) ? $post_type : 'post';
68
69 // Security: Whitelist orderby values
70 $allowed_orderby = [ 'date', 'title', 'modified', 'rand', 'comment_count', 'menu_order' ];
71 $posts_orderby = isset( $settings['posts_orderby'] ) && in_array( $settings['posts_orderby'], $allowed_orderby, true ) ? $settings['posts_orderby'] : 'date';
72
73 // Security: Whitelist order values
74 $posts_order = isset( $settings['posts_order'] ) && in_array( strtoupper( $settings['posts_order'] ), [ 'ASC', 'DESC' ], true ) ? strtoupper( $settings['posts_order'] ) : 'DESC';
75
76 $settings = array_merge(
77 [
78 'posts_source' => $post_type,
79 'posts_orderby' => $posts_orderby,
80 'posts_order' => $posts_order,
81 'posts_ignore_sticky_posts' => 'no',
82 'posts_only_with_featured_image' => 'no',
83 'posts_select_date' => '',
84 'posts_exclude_by' => [],
85 'posts_include_by' => [],
86 'posts_per_page' => $per_page,
87 'posts_offset' => $offset,
88 ],
89 $settings
90 );
91
92 $ajaxposts = $this->query_args( $settings );
93
94 // Security: Override post_status to ensure only published posts are shown
95 if ( ! current_user_can( 'edit_posts' ) ) {
96 $ajaxposts->query_vars['post_status'] = 'publish';
97 }
98
99 ob_start();
100 $found_posts = false;
101
102 if ($ajaxposts->have_posts()) :
103 while ($ajaxposts->have_posts()) :
104 $ajaxposts->the_post();
105 $found_posts = true;
106
107 $title = get_the_title();
108 $post_link = esc_url(get_permalink());
109 $image_src = wp_get_attachment_image_url(get_post_thumbnail_id(), 'large');
110 $image_src = $image_src ? esc_url($image_src) : esc_url(\Elementor\Utils::get_placeholder_image_src());
111 $category = wp_kses_post(upk_get_category($post_type));
112 $author_url = esc_url(get_author_posts_url(get_the_author_meta('ID')));
113 $author_name = esc_html(get_the_author());
114 $title_tag = Utils::get_valid_html_tag($settings['title_tags'] );
115
116 $meta_separator = isset( $settings['meta_separator'] ) ? $settings['meta_separator'] : '|';
117
118 $onclick = '';
119 if (!empty($settings['global_link']) && $settings['global_link'] === 'yes') {
120 $onclick = ' onclick="window.open(\'' . $post_link . '\', \'_self\')"';
121 }
122
123 $date = '';
124 if (!empty($settings['human_diff_time']) && $settings['human_diff_time'] === 'yes') {
125 $date = ultimate_post_kit_post_time_diff(($settings['human_diff_time_short'] === 'yes') ? 'short' : '');
126 } else {
127 $date = esc_html(get_the_date());
128 }
129
130 $format_icons = [
131 'aside' => 'upk-icon-aside',
132 'gallery' => 'upk-icon-gallery',
133 'link' => 'upk-icon-link',
134 'image' => 'upk-icon-image',
135 'quote' => 'upk-icon-quote',
136 'status' => 'upk-icon-status',
137 'video' => 'upk-icon-video',
138 'audio' => 'upk-icon-music',
139 'chat' => 'upk-icon-chat',
140 ];
141
142 $post_format_icon = isset($format_icons[get_post_format()]) ? $format_icons[get_post_format()] : 'upk-icon-post';
143
144 ?>
145 <div <?php if ( ! empty( $settings['global_link'] ) && $settings['global_link'] === 'yes' ) { printf( 'onclick="window.open(\'%s\', \'_self\')"', esc_url( $post_link ) ); } ?> class="upk-item">
146 <div class="upk-image-wrap">
147 <img class="upk-img" src="<?php echo esc_url( $image_src ); ?>" alt="<?php echo esc_attr($title); ?>">
148
149 <?php if (
150 $settings['show_author'] === 'yes' ||
151 $settings['show_date'] === 'yes' ||
152 $settings['show_time'] === 'yes' ||
153 $settings['show_reading_time'] === 'yes'
154 ) : ?>
155 <div class="upk-meta">
156 <?php if ($settings['show_author'] === 'yes') : ?>
157 <div class="upk-author-img"><?php echo wp_kses_post(get_avatar(get_the_author_meta('ID'), 48)); ?></div>
158 <?php endif; ?>
159
160 <div>
161 <?php if ($settings['show_author'] === 'yes') : ?>
162 <div class="upk-author-name">
163 <a href="<?php echo esc_url( $author_url ); ?>"><?php echo esc_html( $author_name ); ?></a>
164 </div>
165 <?php endif; ?>
166
167 <div class="upk-flex upk-flex-middle upk-date-reading-wrap">
168 <?php if ( $settings['show_date'] === 'yes' ) : ?>
169 <div class="upk-date"><?php echo esc_html( $date ); ?></div>
170 <?php if ( $settings['show_time'] === 'yes' ) : ?>
171 <div class="upk-post-time" data-separator="<?php echo esc_attr( $meta_separator ); ?>">
172 <i class="upk-icon-clock" aria-hidden="true"></i><?php echo esc_html( get_the_time() ); ?>
173 </div>
174 <?php endif; ?>
175 <?php endif; ?>
176
177 <?php if ( function_exists( '_is_upk_pro_activated' ) && _is_upk_pro_activated() && $settings['show_reading_time'] === 'yes' ) : ?>
178 <div class="upk-reading-time" data-separator="<?php echo esc_attr( $meta_separator ); ?>">
179 <?php echo wp_kses_post( ultimate_post_kit_reading_time( get_the_content(), $settings['avg_reading_speed'], $settings['hide_seconds'] ?? 'no', $settings['hide_minutes'] ?? 'no' ) ); ?>
180 </div>
181 <?php endif; ?>
182 </div>
183 </div>
184 </div>
185 <?php endif; ?>
186
187 <?php if ($settings['show_post_format'] === 'yes') : ?>
188 <div class="upk-post-format">
189 <a href="<?php echo esc_url( $post_link ); ?>">
190 <i class="<?php echo esc_attr($post_format_icon); ?>" aria-hidden="true"></i>
191 </a>
192 </div>
193 <?php endif; ?>
194 </div>
195
196 <div class="upk-content-wrap">
197 <div class="upk-content">
198 <?php if ($settings['show_category'] === 'yes') : ?>
199 <div class="upk-category"><?php echo wp_kses_post( $category ); ?></div>
200 <?php endif; ?>
201
202 <?php if ($settings['show_title'] === 'yes') : ?>
203 <<?php echo esc_attr( $title_tag ); ?> class="upk-title">
204 <a class="title-animation-<?php echo esc_attr($settings['title_style']); ?>"
205 href="<?php echo esc_url( $post_link ); ?>"
206 title="<?php echo esc_attr($title); ?>"
207 <?php echo $settings['upk_link_new_tab'] === 'yes' ? 'target="_blank"' : ''; ?>
208 >
209 <?php echo esc_html($title); ?>
210 </a>
211 </<?php echo esc_attr( $title_tag); ?>>
212 <?php endif; ?>
213 </div>
214
215 <?php if ($settings['show_readmore'] === 'yes') : ?>
216 <div class="upk-button-wrap">
217 <a href="<?php echo esc_url( $post_link ); ?>"
218 class="upk-readmore"
219 target="<?php echo ($settings['upk_link_new_tab'] === 'yes') ? '_blank' : '_self'; ?>">
220 <span class="upk-readmore-icon"><span></span></span>
221 </a>
222 </div>
223 <?php endif; ?>
224 </div>
225 </div>
226 <?php
227 endwhile;
228 endif;
229
230 wp_reset_postdata();
231 $markup = ob_get_clean();
232
233 wp_send_json(
234 [
235 'success' => $found_posts,
236 'markup' => $found_posts ? $markup : esc_html__('No more found', 'ultimate-post-kit'),
237 ]
238 );
239 }
240 }
241