PluginProbe
Photo Gallery by Re Gallery: Responsive Image Gallery with AI SEO / trunk
Photo Gallery by Re Gallery: Responsive Image Gallery with AI SEO vtrunk
1.20.14 1.20.13 1.20.12 1.20.11 1.20.10 1.20.9 1.20.8 1.20.7 1.20.6 1.20.5 1.20.4 1.20.3 1.20.2 1.20.1 1.20.0 1.19.2 1.19.1 1.19.0 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 All 135 releases
regallery / includes / posts.php

posts.php in Photo Gallery by Re Gallery: Responsive Image Gallery with AI SEO trunk, at includes/posts.php

368 lines 14.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 defined('ABSPATH') || die('Access Denied');
3
4 class REACG_Posts {
5 private $obj;
6
7 public function __construct($that) {
8 $this->obj = $that;
9 add_action('wp_ajax_reacg_get_posts', [$this, 'get_posts'] );
10 }
11
12 private function get_taxonomies( $post_type, $saved_data ) {
13 // Organize saved data.
14 $saved_taxonomies = [];
15 foreach ( $saved_data as $data ) {
16 $term = explode(":", $data);
17 $term_taxonomy = isset($term[0]) ? $term[0] : '';
18 $term_id = isset($term[1]) ? $term[1] : 0;
19 $saved_taxonomies[$term_taxonomy][] = $term_id;
20 }
21
22 // Get taxonomy and terms by post type.
23 $taxonomies = get_object_taxonomies($post_type, 'objects');
24 $result = [];
25 foreach ( $taxonomies as $taxonomy ) {
26 $terms = get_terms([
27 'taxonomy' => $taxonomy->name,
28 'hide_empty' => TRUE,
29 ]);
30 if ( !empty($terms) ) {
31 $result[$taxonomy->name] = [];
32 foreach ( $terms as $term ) {
33 $result[$taxonomy->name][] = [
34 'id' => $term->term_id,
35 'name' => $term->name,
36 'selected' => !empty($saved_taxonomies[$taxonomy->name]) && in_array($term->term_id, $saved_taxonomies[$taxonomy->name]),
37 ];
38 }
39 }
40 }
41
42 return $result;
43 }
44
45 public function get_posts() {
46 if ( !REACGLibrary::verify_nonce() ) {
47 wp_die();
48 }
49
50 if ( !current_user_can('edit_posts') ) {
51 wp_die();
52 }
53
54 $select_type_defaults = ['manual', 'dynamic'];
55 $select_type = '';
56 if ( !empty( $_POST['select_type'] ) ) {
57 $select_type_input = sanitize_text_field( wp_unslash( $_POST['select_type'] ) );
58 if ( in_array( $select_type_input, $select_type_defaults ) ) {
59 $select_type = $select_type_input;
60 }
61 }
62
63 $type = 'post';
64 if ( !empty( $_POST['type'] ) ) {
65 $type_input = sanitize_key( wp_unslash( $_POST['type'] ) );
66 if ( array_key_exists( $type_input, REACG_ALLOWED_POST_TYPES ) ) {
67 $type = $type_input;
68 }
69 }
70 $type_title = REACG_ALLOWED_POST_TYPES[$type]['title'];
71
72 $gallery_id = !empty($_POST['gallery_id']) ? intval($_POST['gallery_id']) : 0;
73
74 $additional_data = get_post_meta( $gallery_id, 'additional_data', TRUE );
75
76 if ( empty($select_type) ) {
77 ob_end_clean();
78 ob_start();
79 ?>
80 <div class="reacg_select_type_wrapper">
81 <span class="spinner is-active"></span>
82 <div>
83 <button type="button"
84 class="button button-hero reacg_select_type"
85 data-select-type="manual"
86 title="<?php
87 /* translators: %s: the type name (e.g., Posts, Pages, WooCommerce Products) */
88 echo sprintf(esc_html('Select %s manually', 'regallery'), esc_html($type_title));
89 ?>">
90 <?php esc_html_e("Manual selection", "regallery"); ?>
91 </button>
92 <button type="button"
93 class="button button-hero reacg_select_type"
94 data-select-type="dynamic"
95 <?php disabled(!empty($additional_data)); ?>
96 title="<?php
97 if ( !empty($additional_data) ) {
98 esc_html_e('Dynamic gallery already added', 'regallery');
99 }
100 else {
101 /* translators: %s: the type name (e.g., Posts, Pages, WooCommerce Products) */
102 echo sprintf(esc_html('Select %s dynamically', 'regallery'), esc_html($type_title));
103 }
104 ?>">
105 <?php echo esc_html__("Dynamic", "regallery"); ?>
106 </button>
107 </div>
108 </div>
109 <?php
110 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentional output of trusted HTML generated by the plugin.
111 echo ob_get_clean();
112 }
113 elseif ( $select_type === "dynamic" ) {
114 $relation = ["or" => __("OR", "regallery"), "and" => __("AND", "regallery")];
115
116 // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- User-defined exclusion required for post filtering.
117 $additional_data_arr = ['taxonomies' => [], 'relation' => '', 'exclude' => [], 'exclude_without_image' => 0, 'count' => 6];
118 if ( !empty($additional_data) ) {
119 $additional_data_arr = json_decode($additional_data, TRUE);
120 }
121
122 $taxonomies = $this->get_taxonomies($type, $additional_data_arr['taxonomies']);
123
124 $args = [
125 'post_type' => $type,
126 'post_status' => 'publish',
127 'posts_per_page' => -1,
128 ];
129 $posts = get_posts($args);
130
131 ob_end_clean();
132 ob_start();
133 ?>
134 <div class="reacg_dynamic_wrapper">
135 <div>
136 <div>
137 <label for="reacg_taxanomies"><?php esc_html_e('Taxonomies', 'regallery'); ?></label>
138 <select multiple="multiple" name="reacg_taxanomies[]" id="reacg_taxanomies" class="reacg_searchable_select reacg_change_listener" style="width: 100%">
139 <?php
140 foreach ( $taxonomies as $taxonomy => $terms ) {
141 ?>
142 <optgroup label="<?php echo esc_html(ucfirst(str_replace("_", "", $taxonomy))); ?>">
143 <?php
144 foreach ( $terms as $term ) {
145 $value = $taxonomy . ":" . $term['id'];
146 $title = $term['name'];
147 ?>
148 <option
149 value="<?php echo esc_attr($value); ?>" <?php selected(TRUE, $term['selected']); ?>><?php echo esc_html($title); ?></option>
150 <?php
151 }
152 ?>
153 </optgroup>
154 <?php
155 }
156 ?>
157 </select>
158 </div>
159 <div>
160 <label for="reacg_relation"><?php esc_html_e('Relation', 'regallery'); ?></label>
161 <select name="reacg_relation" id="reacg_relation" class="reacg_change_listener reacg_auto_width">
162 <?php
163 foreach ( $relation as $value => $name ) {
164 ?>
165 <option
166 value="<?php echo esc_attr($value); ?>" <?php selected($value, $additional_data_arr['relation']); ?>><?php echo esc_html($name); ?></option>
167 <?php
168 }
169 ?>
170 </select>
171 </div>
172 <div>
173 <label for="reacg_exclude">
174 <?php
175 /* translators: %s: the type name (e.g., Posts, Pages, WooCommerce Products) */
176 echo sprintf(esc_html__('Exclude %s', 'regallery'), esc_html($type_title));
177 ?>
178 </label>
179 <select multiple="multiple" name="reacg_exclude" id="reacg_exclude" class="reacg_searchable_select reacg_change_listener" style="width: 100%">
180 <?php
181 foreach ( $posts as $post ) {
182 $title = get_the_title($post->ID);
183 if ( empty($title) ) {
184 $title = __('(no title)', 'regallery');
185 }
186 ?>
187 <option
188 value="<?php echo intval($post->ID); ?>" <?php selected(TRUE, in_array($post->ID, $additional_data_arr['exclude'])); ?>><?php echo esc_html($title); ?></option>
189 <?php
190 }
191 ?>
192 </select>
193 </div>
194 <div>
195 <input type="checkbox"
196 name="reacg_exclude_without_image"
197 id="reacg_exclude_without_image"
198 class="reacg_change_listener"
199 <?php checked(TRUE, !empty($additional_data_arr['exclude_without_image'])); ?> />
200 <label class="reacg_inline_label" for="reacg_exclude_without_image">
201 <?php
202 /* translators: %s: the type name (e.g., Posts, Pages, WooCommerce Products) */
203 echo sprintf(esc_html__('Exclude %s without images', 'regallery'), esc_html($type_title));
204 ?>
205 </label>
206 </div>
207 <div>
208 <label>
209 <?php
210 /* translators: %s: the type name (e.g., Posts, Pages, WooCommerce Products) */
211 echo sprintf(esc_html__('%s count', 'regallery'), esc_html($type_title));
212 ?>
213 </label>
214 <label class="reacg_inline_label reacg_small_label"><?php esc_html_e('All', 'regallery'); ?>
215 <input type="radio"
216 name="reacg_count_option"
217 id="reacg_count_all"
218 class="reacg_change_listener"
219 <?php checked(TRUE, empty($additional_data_arr['count'])); ?> />
220 </label>
221 <label class="reacg_inline_label reacg_small_label"><?php esc_html_e('Custom', 'regallery'); ?>
222 <input type="radio"
223 name="reacg_count_option"
224 id="reacg_count_custom"
225 class="reacg_change_listener"
226 <?php checked(TRUE, !empty($additional_data_arr['count'])); ?> />
227 </label>
228 <input type="number"
229 name="reacg_count"
230 id="reacg_count"
231 min="1"
232 class="reacg_change_listener <?php echo esc_html(empty($additional_data_arr['count']) ? 'reacg-invisible' : ''); ?>"
233 value="<?php echo intval($additional_data_arr['count']); ?>" />
234 </div>
235 </div>
236 </div>
237 <?php
238 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentional output of trusted HTML generated by the plugin.
239 echo ob_get_clean();
240 }
241 elseif ( $select_type === "manual" ) {
242 $s = !empty($_POST['s']) ? sanitize_text_field(wp_unslash($_POST['s'])) : '';
243
244 $orderby_defaults = [
245 'date' => __('Date', 'regallery'),
246 'title' => __('Title', 'regallery'),
247 'comment_count' => __('Comment count', 'regallery'),
248 'menu_order' => __('Menu order', 'regallery'),
249 ];
250 $orderby = 'date';
251 if ( !empty( $_POST['orderby'] ) ) {
252 $orderby_input = sanitize_text_field(wp_unslash($_POST['orderby']));
253 if ( array_key_exists( $orderby_input, $orderby_defaults ) ) {
254 $orderby = $orderby_input;
255 }
256 }
257
258 $order_defaults = [
259 'ASC' => __('Ascending', 'regallery'),
260 'DESC' => __('Descending', 'regallery'),
261 ];
262 $order = 'DESC';
263 if ( !empty( $_POST['order'] ) ) {
264 $order_input = strtoupper(sanitize_text_field(wp_unslash($_POST['order'])));
265 if ( array_key_exists( $order_input, $order_defaults ) ) {
266 $order = $order_input;
267 }
268 }
269
270 $args = [
271 'post_type' => $type,
272 'post_status' => 'publish',
273 's' => $s,
274 'posts_per_page' => -1,
275 'orderby' => $orderby,
276 'order' => $order,
277 ];
278
279 $query = new WP_Query($args);
280
281 ob_start();
282 ?>
283 <div class="media-toolbar">
284 <div class="media-toolbar-secondary">
285 <h2 class="media-attachments-filter-heading"><?php echo esc_html__("Order", "regallery"); ?></h2>
286 <label for="media-attachment-order-by" class="screen-reader-text"><?php echo esc_html__("Order by", "regallery"); ?></label>
287 <select id="media-attachment-order-by" class="posts-filters">
288 <?php
289 foreach ( $orderby_defaults as $key => $value ) {
290 ?>
291 <option <?php echo $key === $orderby ? "selected" : ""; ?> value="<?php echo esc_html($key); ?>"><?php echo esc_html($value); ?></option>
292 <?php
293 }
294 ?>
295 </select>
296 <select id="media-attachment-order" class="posts-filters">
297 <?php
298 foreach ( $order_defaults as $key => $value ) {
299 ?>
300 <option <?php echo $key === $order ? "selected" : ""; ?> value="<?php echo esc_html($key); ?>"><?php echo esc_html($value); ?></option>
301 <?php
302 }
303 ?>
304 </select>
305 <span class="spinner"></span>
306 </div>
307 <div class="media-toolbar-primary search-form">
308 <label for="media-search-input" class="media-search-input-label"><?php echo esc_html__("Search", "regallery"); ?></label>
309 <input type="search" id="media-search-input" class="search" value="<?php echo esc_html($s); ?>"/>
310 </div>
311 <div class="media-bg-overlay" style="display: none;"></div>
312 </div>
313 <div class="attachments-wrapper">
314 <?php
315 if ( $query->have_posts() ) {
316 ?>
317 <ul tabindex="-1" class="attachments ui-sortable ui-sortable-disabled">
318 <?php
319 while ($query->have_posts()) {
320 $query->the_post();
321 $id = get_the_ID();
322 $title = get_the_title();
323 $thumbnail = get_the_post_thumbnail_url($id, 'thumbnail') ?: $this->obj->plugin_url . $this->obj->no_image;
324 ?>
325 <li tabindex="0" role="checkbox" aria-label="<?php echo esc_html($title); ?>" title="<?php echo esc_html($title); ?>" aria-checked="false"
326 data-id="<?php echo esc_attr($type . $id); ?>"
327 data-title="<?php echo esc_html($title); ?>"
328 data-thumbnail="<?php echo esc_url($thumbnail); ?>"
329 class="attachment save-ready">
330 <div class="attachment-preview js--select-attachment type-image subtype-png landscape">
331 <div class="thumbnail">
332 <div class="centered">
333 <img src="<?php echo esc_url($thumbnail); ?>" draggable="false" alt="<?php echo esc_html($title); ?>" />
334 </div>
335 </div>
336 </div>
337 <button type="button" class="check" tabindex="-1">
338 <span class="media-modal-icon"></span>
339 <span class="screen-reader-text"><?php echo esc_html__("Deselect", "regallery"); ?></span>
340 </button>
341 </li>
342 <?php
343 }
344 ?>
345 </ul>
346 <?php
347 }
348 else {
349 ?>
350 <div class="uploader-inline">
351 <div class="uploader-inline-content has-upload-message">
352 <h2 class="upload-message"><?php echo esc_html__("No items found.", "regallery"); ?></h2>
353 </div>
354 </div>
355 <?php
356 }
357 ?>
358 </div>
359 <?php
360 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentional output of trusted HTML generated by the plugin.
361 echo ob_get_clean();
362 wp_reset_postdata();
363 }
364
365 wp_die();
366 }
367 }
368