PluginProbe
WOLF – WordPress Posts Bulk Editor and Manager Professional / trunk
WOLF – WordPress Posts Bulk Editor and Manager Professional vtrunk
bulk-editor / index.php

index.php in WOLF – WordPress Posts Bulk Editor and Manager Professional trunk, at index.php

1,553 lines 50.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: WOLF - WordPress Posts Bulk Editor and Manager Professional
4 Plugin URI: https://bulk-editor.pro/
5 Description: Tools for managing and bulk edit posts, pages and all custom types data in the reliable and flexible way! Be professionals with managing data of your site!
6 Requires at least: 5.0
7 Tested up to: 7.0
8 Author: realmag777
9 Author URI: https://pluginus.net/
10 Version: 1.1.1
11 Requires PHP: 7.4
12 Tags: bulk,bulk edit,bulk editor,posts editor,bulk delete,real estate,posts manager,meta bulk edit
13 Text Domain: bulk-editor
14 Domain Path: /languages
15 Forum URI: https://pluginus.net/support/forum/wpbe-wordpress-posts-bulk-editor-professional/
16 License: GPLv2 or later и License URI: https://www.gnu.org/licenses/gpl-2.0.html
17 */
18
19 //update_option('wpbe_options_' . get_current_user_id(), ''); //reset of the plugin settings - be care
20 if (!defined('ABSPATH')) {
21 exit; // Exit if accessed directly
22 }
23
24 if (defined('WPBE_PATH')) {
25 add_action('admin_notices', function () {
26 ?>
27 <div class="notice notice-error">
28 <p><?php esc_html_e("Hello, looks like you bought and installed premium version of WOLF - WordPress Posts Bulk Editor and Manager Professional, please deactivate free version before, then uninstall it. 2 versions of the same plugin cannot be activated on the same time!", 'bulk-editor'); ?></p>
29 </div>
30 <?php
31 });
32 return;
33 }
34
35 //***
36
37 define('WPBE_PATH', plugin_dir_path(__FILE__));
38 define('WPBE_LINK', plugin_dir_url(__FILE__));
39 define('WPBE_ASSETS_LINK', WPBE_LINK . 'assets/');
40 define('WPBE_DATA_PATH', WPBE_PATH . 'data/');
41 define('WPBE_PLUGIN_NAME', plugin_basename(__FILE__));
42 define('WPBE_VERSION', '1.1.1');
43 //define('WPBE_VERSION', uniqid('wpbe-')); //dev
44 define('WPBE_MIN_WP_VERSION', '5.0');
45
46 //libs
47 include WPBE_PATH . 'lib/storage.php';
48
49 //data
50 include_once WPBE_DATA_PATH . 'fields.php';
51 include_once WPBE_DATA_PATH . 'settings.php';
52
53 //classes
54 include WPBE_PATH . 'classes/helper.php';
55 include WPBE_PATH . 'classes/models/profiles.php';
56 include WPBE_PATH . 'classes/models/settings.php';
57 include WPBE_PATH . 'classes/models/posts.php';
58 include WPBE_PATH . 'classes/ext.php';
59
60 //13-07-2026
61 final class WPBE {
62
63 public $storage = NULL;
64 public $settings = NULL;
65 public $posts = NULL;
66 public $profiles = NULL;
67 private $ext = array('filters', 'bulk', 'export', 'meta', 'history', 'calculator', 'info', 'fprofiles', 'author_area');
68 public $show_notes = true;
69 //extensions
70 public $filters = null;
71 public $bulk = null;
72 public $export = null;
73 public $meta = null;
74 public $history = null;
75 public $calculator = null;
76 public $info = null;
77 public $fprofiles = null;
78 public $author_area = null;
79
80 public function __construct() {
81 add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
82 add_filter('wpbe_post_statuses', array($this, 'add_statuses'));
83 }
84
85 public function init() {
86
87 if (!is_admin()) {
88 return;
89 }
90 //wp editor
91 add_action('admin_footer', array($this, 'wp_editor_compatibility'));
92
93 //no one operation is possible if user is not a posts administrator!!
94 if (!WPBE_HELPER::can_manage_data()) {
95 return;
96 }
97
98 $this->ask_favour();
99
100 //***
101
102 add_filter('plugin_action_links_' . WPBE_PLUGIN_NAME, array($this, 'plugin_action_links'), 50);
103
104 if (class_exists('SitePress')) {
105 add_filter('wpbe_current_language', function () {
106 //WPML compatibility
107 //because if it will be selected 'all' language - will be shown default one
108 return ICL_LANGUAGE_CODE;
109 });
110 }
111
112 //***
113
114 if (isset($_GET['page']) AND $_GET['page'] == 'wpbe') {
115
116 add_action('admin_notices', function () {
117 $user_id = get_current_user_id();
118 if (!get_user_meta($user_id, 'wpbe_notice_dismissed')) {
119 ?>
120 <div class="notice notice-warning">
121 <p>
122 <?php esc_html_e('If you not familiar with the plugin, firstly', 'bulk-editor') ?>
123 <?php
124 WPBE_HELPER::draw_link_e(array(
125 'title' => esc_html__('visit this page', 'bulk-editor'),
126 'href' => 'https://bulk-editor.pro/document/posts-editor/',
127 'target' => '_blank',
128 ));
129 ?>
130 <?php esc_html_e('please', 'bulk-editor') ?>
131 </p>
132 <a href="admin.php?page=wpbe&wpbe-notice-dismissed=1&notice_nonce=<?php echo esc_attr(wp_create_nonce('wpbe_notice_nonce')) ?>" class="notice-dismiss"></a>
133 </div>
134 <?php
135 }
136 });
137 add_action('admin_init', function () {
138 $user_id = get_current_user_id();
139 if (isset($_GET['wpbe-notice-dismissed']) && isset($_GET['notice_nonce']) && wp_verify_nonce($_GET['notice_nonce'], 'wpbe_notice_nonce')) {
140 add_user_meta($user_id, 'wpbe_notice_dismissed', 'true', true);
141 }
142 });
143 }
144
145 //side bar menu
146 if (WPBE_HELPER::can_manage_data()) {
147 add_action('admin_menu', function () {
148 add_menu_page(esc_html__('WOLF Bulk Editor', 'bulk-editor'), esc_html__('WOLF Bulk Editor', 'bulk-editor'), 'publish_posts', 'wpbe', function () {
149 $this->print_plugin_options();
150 }, 'dashicons-hammer', 90);
151 }, 99);
152 }
153
154 add_action('admin_bar_menu', function ($wp_admin_bar) {
155 $opt = get_option('wpbe_options_' . get_current_user_id()); //not beauty but we need it here
156
157 if (isset($opt['options']['show_admin_bar_menu_btn']) AND intval($opt['options']['show_admin_bar_menu_btn']) === 1) {
158 $args = array(
159 'id' => 'wpbe-btn',
160 'title' => esc_html__('WOLF Bulk Editor', 'bulk-editor'),
161 'href' => admin_url('admin.php?page=wpbe'),
162 'meta' => array(
163 'class' => 'wp-admin-bar-wpbe-btn',
164 'title' => 'WOLF - Posts Bulk Editor Professional'
165 )
166 );
167 $wp_admin_bar->add_node($args);
168 }
169 unset($opt);
170 }, 250);
171
172 //do not init hooks and all other parts of the plugins as we not need it on all site pages
173 if (!$this->is_should_init()) {
174 return;
175 }
176
177 //***
178 //include extensions and their hooks
179 if (!empty($this->ext)) {
180 foreach ($this->ext as $ext_slug) {
181 include WPBE_PATH . 'ext' . DIRECTORY_SEPARATOR . $ext_slug . DIRECTORY_SEPARATOR . $ext_slug . '.php';
182 $class_name = 'WPBE_' . strtoupper($ext_slug);
183 $this->$ext_slug = new $class_name();
184 }
185 }
186
187 //wpbe_ext - include extensions from wp-content folder
188 $wpbe_more_ext_path = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'wpbe_ext';
189 if (file_exists($wpbe_more_ext_path)) {
190 $dir = new DirectoryIterator($wpbe_more_ext_path);
191 foreach ($dir as $fileinfo) {
192 if ($fileinfo->isDir() AND !$fileinfo->isDot()) {
193 $ext_slug = trim($fileinfo->getFilename());
194 include $wpbe_more_ext_path . DIRECTORY_SEPARATOR . $ext_slug . DIRECTORY_SEPARATOR . $ext_slug . '.php';
195 $class_name = 'WPBE_' . strtoupper($ext_slug);
196 $this->$ext_slug = new $class_name();
197 $this->ext[] = $ext_slug;
198 }
199 }
200 }
201
202
203 //***
204 //init variables and hooks of the extensions will be applied, for example hook wpbe_extend_fields
205 $this->storage = new WPBE_STORAGE();
206 $this->settings = new WPBE_SETTINGS(); //must be reinit because hooks from exts applied!!
207 $this->profiles = new WPBE_PROFILES($this->settings);
208 $this->posts = new WPBE_POSTS($this->settings, $this->storage);
209
210 if (!empty($this->ext)) {
211 foreach ($this->ext as $ext_slug) {
212 //we do it to allow ext hooks works everywhere (in the application and all its extensions)
213 $this->$ext_slug->init_vars($this->storage, $this->profiles, $this->settings, $this->posts);
214 }
215 }
216
217
218 //***
219
220 load_plugin_textdomain('bulk-editor', false, 'bulk-editor/languages');
221
222 //ajax
223 add_action('wp_ajax_wpbe_get_posts', array($this, 'wpbe_get_posts'), 1);
224 add_action('wp_ajax_wpbe_update_page_field', array($this, 'wpbe_update_page_field'), 1);
225 add_action('wp_ajax_wpbe_redraw_table_row', array($this, 'wpbe_redraw_table_row'), 1);
226 add_action('wp_ajax_wpbe_get_post_field', array($this, 'get_post_field'), 1);
227 add_action('wp_ajax_wpbe_get_gallery', array($this, 'wpbe_get_gallery'), 1);
228 add_action('wp_ajax_wpbe_get_upsells', array($this, 'wpbe_get_upsells'), 1);
229
230 add_action('wp_ajax_wpbe_create_new_post', array($this, 'wpbe_create_new_post'), 1);
231 add_action('wp_ajax_wpbe_duplicate_posts', array($this, 'wpbe_duplicate_posts'), 1);
232 add_action('wp_ajax_wpbe_delete_posts', array($this, 'wpbe_delete_posts'), 1);
233
234 add_action('wp_ajax_wpbe_create_new_term', array($this, 'wpbe_create_new_term'), 1);
235 add_action('wp_ajax_wpbe_update_tax_term', array($this, 'wpbe_update_tax_term'), 1);
236 add_action('wp_ajax_wpbe_delete_tax_term', array($this, 'wpbe_delete_tax_term'), 1);
237
238 add_action('wp_ajax_wpbe_set_active_post_type', function () {
239
240 if (!WPBE_HELPER::can_manage_data()) {
241 wp_die('0');
242 }
243
244 if (!empty($_REQUEST['post_type']) AND post_type_exists($_REQUEST['post_type'])) {
245 $this->storage->set_val('wpbe_current_post_type_' . get_current_user_id(), $_REQUEST['post_type']);
246 }
247 exit;
248 }, 1);
249
250 //***
251 add_action('wp_ajax_wpbe_title_autocomplete', array($this, 'wpbe_title_autocomplete'));
252 add_action('wp_ajax_wpbe_save_options', array($this, 'wpbe_save_options'), 1);
253
254 //***
255 add_post_type_support($this->settings->current_post_type, 'author');
256 }
257
258 /**
259 * Show action links on the plugins page screen
260 */
261 public function plugin_action_links($links) {
262
263 $wpbe_links = array(
264 '<a href="' . admin_url('admin.php?page=wpbe') . '">' . esc_html__('Posts Editor', 'bulk-editor') . '</a>',
265 '<a target="_blank" href="' . esc_url('https://bulk-editor.pro/') . '"><span class="icon-book"></span>&nbsp;' . esc_html__('Documentation', 'bulk-editor') . '</a>'
266 );
267
268 if ($this->show_notes) {
269 $wpbe_links[] = '<a target="_blank" href="https://bulk-editor.pro/downloads"><span style="color: red; font-weight: bold;">&nbsp;Go Pro!</span></a>';
270 }
271
272 return array_merge($wpbe_links, $links);
273 }
274
275 public function admin_enqueue_scripts() {
276 if (isset($_GET['page']) AND $_GET['page'] == 'wpbe') {
277 ?>
278 <script>
279 var lang = {
280 move: "<?php esc_html_e('move', 'bulk-editor') ?>",
281 search: "<?php esc_html_e('Search', 'bulk-editor') ?>",
282 rest_failed: "<?php esc_html_e('Failed', 'bulk-editor') ?>",
283 error: "<?php esc_html_e('Error', 'bulk-editor') ?>",
284 delete: "<?php esc_html_e('delete', 'bulk-editor') ?>",
285 ignore: "<?php esc_html_e('ignore', 'bulk-editor') ?>",
286 no_deletable: "<?php esc_html_e('This is not deletable!', 'bulk-editor') ?>",
287 no_items: "<?php esc_html_e('no items', 'bulk-editor') ?>",
288 none: "<?php esc_html_e('none', 'bulk-editor') ?>",
289 no_data: "<?php esc_html_e('no data', 'bulk-editor') ?>",
290 loading: "<?php esc_html_e('Loading', 'bulk-editor') ?> ...",
291 loaded: "<?php esc_html_e('Loaded', 'bulk-editor') ?>.",
292 saved: "<?php esc_html_e('Saved', 'bulk-editor') ?>.",
293 saving: "<?php esc_html_e('Saving', 'bulk-editor') ?> ...",
294 apply: "<?php esc_html_e('Apply', 'bulk-editor') ?>",
295 cancel: "<?php esc_html_e('Cancel', 'bulk-editor') ?>",
296 canceled: "<?php esc_html_e('Canceled', 'bulk-editor') ?>",
297 sure: "<?php esc_html_e('Sure?', 'bulk-editor') ?>",
298 creating: "<?php esc_html_e('Creating', 'bulk-editor') ?> ...",
299 created: "<?php esc_html_e('Created!', 'bulk-editor') ?>",
300 duplicating: "<?php esc_html_e('Duplicating', 'bulk-editor') ?> ...",
301 duplicated: "<?php esc_html_e('Duplicated!', 'bulk-editor') ?>",
302 deleting: "<?php esc_html_e('Deleting', 'bulk-editor') ?> ...",
303 deleted: "<?php esc_html_e('Deleted!', 'bulk-editor') ?>",
304 reseting: "<?php esc_html_e('Reseting', 'bulk-editor') ?> ...",
305 reseted: "<?php esc_html_e('Reseted!', 'bulk-editor') ?>",
306 upload_image: "<?php esc_html_e('Upload image', 'bulk-editor') ?>",
307 upload_images: "<?php esc_html_e('Upload images', 'bulk-editor') ?>",
308 upload_file: "<?php esc_html_e('Upload file', 'bulk-editor') ?>",
309 fill_up_data: "<?php esc_html_e('Fill up the data please!', 'bulk-editor') ?>",
310 enter_duplicate_count: "<?php
311 printf(
312 /* translators: %s: name */
313 esc_html__('Enter how many time duplicate selected [%s](s)!', 'bulk-editor'), esc_html($this->settings->current_post_type))
314 ?>",
315 enter_new_count: "<?php
316 printf(
317 /* translators: %s: name */
318 esc_html__('Enter how many new [%s](s) to create!', 'bulk-editor'), esc_html($this->settings->current_post_type))
319 ?>",
320 search_input_placeholder: "<?php esc_html_e('Text search by title or SKU', 'bulk-editor') ?>",
321 show_panel: "<?php esc_html_e('Show: Filters/Bulk Edit/Export', 'bulk-editor') ?>",
322 close_panel: "<?php esc_html_e('Hide: Filters/Bulk Edit/Export', 'bulk-editor') ?>",
323 per_page: "<?php esc_html_e('Per page', 'bulk-editor') ?>",
324 color_picker_col: "<?php esc_html_e('Select background color', 'bulk-editor') ?>",
325 color_picker_txt: "<?php esc_html_e('Select text color', 'bulk-editor') ?>",
326 sEmptyTable: "<?php esc_html_e('No data available in the table', 'bulk-editor') ?>",
327 sInfo: "<?php esc_html_e('Showing _START_ to _END_ of _TOTAL_ entries', 'bulk-editor') ?>",
328 sInfoEmpty: "<?php esc_html_e('Showing 0 to 0 of 0 entries', 'bulk-editor') ?>",
329 sInfoFiltered: "<?php esc_html_e('(filtered from _MAX_ total entries)', 'bulk-editor') ?>",
330 sLoadingRecords: "<?php esc_html_e('Loading...', 'bulk-editor') ?>",
331 sProcessing: "<?php esc_html_e('Processing...', 'bulk-editor') ?>",
332 sZeroRecords: "<?php esc_html_e('No matching records found', 'bulk-editor') ?>",
333 sFirst: "<?php esc_html_e('First', 'bulk-editor') ?>",
334 sLast: "<?php esc_html_e('Last', 'bulk-editor') ?>",
335 sNext: "<?php esc_html_e('Next', 'bulk-editor') ?>",
336 sPrevious: "<?php esc_html_e('Previous', 'bulk-editor') ?>",
337 action_state_1: "<?php
338 printf(
339 /* translators: %s: selection */
340 esc_html__('all the [%s] on the site', 'bulk-editor'), esc_html($this->settings->current_post_type))
341 ?>",
342 action_state_2: "<?php
343 printf(
344 /* translators: %s: name */
345 esc_html__('the filtered [%s]. To remove filtering press reset button on the tools panel below', 'bulk-editor'), esc_html($this->settings->current_post_type))
346 ?>",
347 action_state_31: "<?php
348 printf(
349 /* translators: %s: name */
350 esc_html__('the selected [%s](s)', 'bulk-editor'), esc_html($this->settings->current_post_type))
351 ?>",
352 action_state_32: "<?php
353 printf(
354 /* translators: %s: name */
355 esc_html__('You can reset selection of the [%s](s) by its reset button on the panel of the editor OR uncheck them manually!', 'bulk-editor'), esc_html($this->settings->current_post_type))
356 ?>",
357 term_maybe_exist: "<?php esc_html_e('Maybe term(s) with such name(s) already exists!', 'bulk-editor') ?>",
358 free_ver_profiles: "<?php esc_html_e('In FREE version of the plugin you can create one profile only!', 'bulk-editor') ?>",
359 append_sub_item: "<?php esc_html_e('append sub item', 'bulk-editor') ?>",
360 is_deactivated_in_free: "<?php esc_html_e('This field is deactivated in FREE version for bulk edit!', 'bulk-editor') ?>",
361 checked_post: "<?php esc_html_e('Posts checked', 'bulk-editor') ?>",
362 };
363
364 var wpbe_settings = {
365 show_thumbnail_preview: <?php echo intval($this->settings->show_thumbnail_preview) ?>,
366 load_switchers: <?php echo intval($this->settings->load_switchers) ?>,
367 autocomplete_max_elem_count: <?php echo intval($this->settings->autocomplete_max_elem_count) ?>
368 };
369 var wpbe_field_update_nonce = "<?php echo esc_attr(wp_create_nonce('wpbe_field_update')) ?>";
370 var wpbe_assets_link = "<?php echo esc_attr(WPBE_ASSETS_LINK) ?>";
371 var spinner = wpbe_assets_link + "/images/spinner.gif";
372 var start_page = <?php echo (isset($_GET['start_page']) ? intval($_GET['start_page']) : 0) ?>;
373
374 //***
375
376 var wpbe_lang = '<?php echo esc_attr(apply_filters('wpbe_current_language', '')) ?>';//for translating compatibilities
377
378
379 </script>
380
381 <?php
382 wp_enqueue_style('wpbe_open_sans_font', '//fonts.googleapis.com/css?family=Open+Sans');
383 wp_enqueue_style('wpbe-bootstrap-grid', WPBE_ASSETS_LINK . 'css/bootstrap-grid.css', [], WPBE_VERSION);
384 wp_enqueue_style('wpbe', WPBE_ASSETS_LINK . 'css/wpbe.css', [], WPBE_VERSION);
385 wp_enqueue_style('wpbe_scrollbar', WPBE_ASSETS_LINK . 'css/jquery.scrollbar.css', [], WPBE_VERSION);
386 wp_enqueue_style('wpbe_fontello', WPBE_ASSETS_LINK . 'css/fontello.css', [], WPBE_VERSION);
387
388 //***
389
390 wp_enqueue_media();
391 wp_enqueue_script('media-upload');
392 wp_enqueue_style('thickbox');
393 wp_enqueue_script('thickbox');
394
395 wp_enqueue_style('wp-color-picker');
396 wp_enqueue_script('wp-color-picker');
397
398 wp_enqueue_script('wpbe_modernizr', WPBE_ASSETS_LINK . 'js/modernizr.js', [], WPBE_VERSION);
399
400 wp_enqueue_style('wpbe_datatables', WPBE_ASSETS_LINK . 'css/tables.css', [], WPBE_VERSION);
401 wp_enqueue_script('wpbe_datatables_net', WPBE_ASSETS_LINK . 'js/jquery.dataTables.js', array('jquery'), WPBE_VERSION);
402 wp_enqueue_script('wpbe_data_tables', WPBE_ASSETS_LINK . 'js/data-tables.js', array('wpbe_datatables_net'), WPBE_VERSION);
403 wp_enqueue_script('wpbe_jquery_growl', WPBE_ASSETS_LINK . 'js/jquery.growl.js', array('jquery'), WPBE_VERSION);
404
405 wp_enqueue_style('wpbe_switchery', WPBE_ASSETS_LINK . 'js/switchery/switchery.min.css', [], WPBE_VERSION);
406 wp_enqueue_script('wpbe_switchery', WPBE_ASSETS_LINK . 'js/switchery/switchery.min.js', array('jquery'), WPBE_VERSION);
407
408 wp_enqueue_style('wpbe_chosen', WPBE_ASSETS_LINK . 'js/chosen/chosen.min.css', [], WPBE_VERSION);
409 wp_enqueue_script('wpbe_chosen', WPBE_ASSETS_LINK . 'js/chosen/chosen.jquery.min.js', array('jquery'), WPBE_VERSION);
410
411 wp_enqueue_style('wpbe_autocomplete', WPBE_ASSETS_LINK . 'js/easy-autocomplete/easy-autocomplete.min.css', [], WPBE_VERSION);
412 wp_enqueue_style('wpbe_autocomplete_theme', WPBE_ASSETS_LINK . 'js/easy-autocomplete/easy-autocomplete.themes.min.css', [], WPBE_VERSION);
413 wp_enqueue_script('wpbe_autocomplete', WPBE_ASSETS_LINK . 'js/easy-autocomplete/jquery.easy-autocomplete.min.js', array('jquery'), WPBE_VERSION);
414
415 wp_enqueue_style('wpbe_datetimepicker', WPBE_ASSETS_LINK . 'js/bootstrap-material-datetimepicker/css/bootstrap-material-datetimepicker.css', [], WPBE_VERSION);
416 wp_enqueue_script('wpbe_datetimepicker_moment', WPBE_ASSETS_LINK . 'js/datepicker/moment-with-locales.min.js', array('jquery'), WPBE_VERSION);
417 wp_enqueue_script('wpbe_datetimepicker', WPBE_ASSETS_LINK . 'js/bootstrap-material-datetimepicker/bootstrap-material-datetimepicker.js', array('jquery'), WPBE_VERSION);
418
419 wp_enqueue_script('wpbe_placeholder_label', WPBE_ASSETS_LINK . 'js/jquery.placeholder.label.min.js', array('jquery'), WPBE_VERSION);
420 wp_enqueue_script('wpbe_tooltip', WPBE_ASSETS_LINK . 'js/tooltip.js', array('jquery'), WPBE_VERSION);
421
422 wp_enqueue_script('wpbe_tabs', WPBE_ASSETS_LINK . 'js/tabs.js', [], WPBE_VERSION);
423 wp_enqueue_script('wpbe_scrollbar', WPBE_ASSETS_LINK . 'js/jquery.scrollbar.min.js', [], WPBE_VERSION);
424
425 //***
426
427 wp_enqueue_script('wpbe', WPBE_ASSETS_LINK . 'js/wpbe.js', array('jquery', 'jquery-ui-core', 'jquery-ui-sortable', 'wpbe_tabs'), WPBE_VERSION);
428 do_action('wpbe_ext_scripts'); //including extensions scripts
429 }
430 }
431
432 public function print_plugin_options() {
433 $args = array();
434 $args['options'] = $this->settings->get_options();
435 $args['total_settings'] = $this->settings->get_total_settings();
436 $args['tax_keys'] = array();
437
438 $args['meta_popup_editor'] = FALSE;
439
440 //to generate terms in popup taxonomies data
441 if (!empty($this->settings->active_fields)) {
442 foreach ($this->settings->active_fields as $k => $f) {
443 if ($f['field_type'] == 'taxonomy' AND $f['edit_view'] == 'popup') {
444 $args['tax_keys'][] = $f['taxonomy'];
445 }
446
447
448 //***
449
450 if ($f['edit_view'] == 'popupeditor') {
451 $args['is_popupeditor'] = TRUE;
452 }
453
454
455 if ($f['edit_view'] == 'gallery_popup_editor') {
456 $args['is_gallery'] = TRUE;
457 }
458
459 if ($f['edit_view'] == 'meta_popup_editor') {
460 $args['meta_popup_editor'] = TRUE;
461 }
462 }
463 }
464
465 //***
466
467 $args['active_fields'] = $this->settings->active_fields;
468 $args['settings_fields'] = $this->settings->get_fields();
469 $args['settings_fields_full'] = $this->settings->get_fields(false);
470 $args['settings_fields_keys'] = $this->settings->get_fields_keys();
471 $args['editable'] = $this->settings->editable;
472 $args['default_sortby_col_num'] = $this->settings->get_default_sortby_col_num();
473 $args['default_sort'] = $this->settings->default_sort;
474 $args['no_order'] = $this->settings->no_order;
475 $args['per_page'] = $this->settings->per_page;
476 $args['extend_per_page'] = $this->settings->add_more_per_page;
477 $args['show_notes'] = $this->show_notes;
478 $args['current_user_role'] = $this->settings->current_user_role;
479 $args['profiles'] = $this->profiles->get();
480
481 //***
482
483 WPBE_HELPER::render_html_e(WPBE_PATH . 'views/wpbe.php', apply_filters('wpbe_print_plugin_options', $args));
484 }
485
486 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
487 //ajax
488 public function wpbe_get_posts($args = array(), $return = false) {
489
490 if (!WPBE_HELPER::can_manage_data()) {
491 return;
492 }
493
494 //***
495
496 $res = array();
497 $res['draw'] = isset($_REQUEST['draw']) ? intval($_REQUEST['draw']) : 0;
498 $res['data'] = array();
499 $fileds_keys = $this->settings->get_fields_keys();
500
501 if (empty($args)) {
502 //for ajax only
503 $args = array(
504 'lang' => apply_filters('wpbe_current_language', ''),
505 'per_page' => intval($_REQUEST['length']),
506 'offset' => intval($_REQUEST['start']),
507 'order_by' => $fileds_keys[intval($_REQUEST['order'][0]['column'])],
508 'order' => sanitize_key($_REQUEST['order'][0]['dir']),
509 'search' => $_REQUEST['search']['value']
510 );
511 }
512
513 $posts = $this->posts->gets($args);
514
515 $res['recordsFiltered'] = $res['recordsTotal'] = $posts->found_posts;
516 if ($posts->found_posts > 0) {
517 $posts_types = array();
518 $posts_titles = array();
519 foreach ($posts->posts as $p) {
520 $post_type = 'simple';
521 $res['data'][] = $this->__pack_row($p);
522 $posts_types[$p->ID] = $post_type;
523 $posts_titles[$p->ID] = str_replace('"', "", str_replace("'", "", $p->post_title));
524
525 //get variations if exists and requested
526 if ($post_type == 'variable' AND ( isset($_REQUEST['wpbe_show_variations']) AND intval($_REQUEST['wpbe_show_variations']) > 0)) {
527 //removed, but for todo ideas
528 }
529
530 //***
531 //data for javascript functionality on the front
532 $res['posts_types'] = $posts_types;
533 $res['posts_titles'] = $posts_titles;
534 }
535 }
536
537 //***
538
539 if (!$return) {
540 //if requested by ajax
541 wp_die(json_encode($res));
542 }
543
544 return $res;
545 }
546
547 //service
548 private function __pack_row($p) {
549 $row = array();
550 $p = (array) $p;
551
552 foreach ($this->settings->get_fields_keys() as $key) {
553 $row[] = $this->wrap_field_val($p, $key);
554 }
555
556 $row[] = WPBE_HELPER::draw_link(array(
557 'title' => '&#xea0b;',
558 'href' => get_permalink($p['ID']),
559 'target' => '_blank',
560 'class' => 'button button-primary button-small',
561 'title_attr' => esc_html__('View the post on the site front', 'bulk-editor')
562 )) . '&nbsp;' . WPBE_HELPER::draw_link(array(
563 'title' => '&#xea25;',
564 'href' => get_admin_url() . 'post.php?post=' . $p['ID'] . '&action=edit',
565 'target' => '_blank',
566 'class' => 'button button-primary button-small',
567 'title_attr' => esc_html__('Editing of the post on its page', 'bulk-editor')
568 ));
569
570 return $row;
571 }
572
573 //ajax
574 public function wpbe_update_page_field($post_id = 0, $field_key = '', $value = '') {
575
576 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_field_update')) {
577 die('Forbidden!');
578 }
579
580 if (!$post_id) {
581 $post_id = intval($_REQUEST['post_id']);
582 }
583 if (!isset($_REQUEST['value']) || $_REQUEST['value'] == null) {
584 $_REQUEST['value'] = '';
585 }
586 $field_type = '';
587 if (isset($_REQUEST['field_type'])) {
588 $field_type = sanitize_text_field($_REQUEST['field_type']);
589 }
590 //leaved as attention info
591 //$field_key = sanitize_key($_REQUEST['field']);//if sanitize not all meta keys works normally!!
592
593 if (empty($field_key)) {
594 $field_key = sanitize_text_field(trim($_REQUEST['field'])); //if sanitize by sanitize_key not all meta keys works normally!!
595 }
596
597 if ($post_id > 0 AND isset($_REQUEST['value'])) {
598
599 if (empty($value)) {
600 if (is_array($_REQUEST['value'])) {
601 //$value = (array) $_REQUEST['value'];
602 $value = WPBE_HELPER::sanitize_array((array) $_REQUEST['value']);
603 } else {
604
605 $allowedpost = wp_kses_allowed_html('post');
606 if ('post_content' == $field_key OR 'post_excerpt' == $field_key OR $this->settings->active_fields[$field_key]['edit_view'] === 'popupeditor') {
607 $is_encoded = false;
608 $allowedpost['iframe'] = array(
609 'align' => true,
610 'frameborder' => true,
611 'height' => true,
612 'width' => true,
613 'sandbox' => true,
614 'seamless' => true,
615 'scrolling' => true,
616 'srcdoc' => true,
617 'src' => true,
618 'class' => true,
619 'id' => true,
620 'style' => true,
621 'border' => true,
622 );
623 }
624 //***
625
626 if (is_string($_REQUEST['value'])) {
627 $is_encoded = preg_match('~%[0-9A-F]{2}~i', $_REQUEST['value']);
628 if ($is_encoded) {
629 //for example gallery
630 $data_array = [];
631
632 parse_str($_REQUEST['value'], $data_array);
633 $data_array = WPBE_HELPER::sanitize_array($data_array);
634 if (isset($data_array[$field_key])) {
635 $data_array = $data_array[$field_key];
636 }
637
638 switch ($field_type) {
639 case 'gallery_popup_editor':
640 $value = implode(',', $data_array); //images ids
641
642 break;
643 }
644 }
645
646 if (empty($value)) {
647
648 if (apply_filters('wpbe_use_kses_for_page_field', true)) {
649 $value = wp_kses($_REQUEST['value'], $allowedpost);
650 } else {
651 $value = sanitize_text_field($_REQUEST['value']);
652 }
653
654
655 if ($this->settings->active_fields[$field_key]['edit_view'] === 'meta_popup_editor') {
656 $value = htmlspecialchars_decode($value);
657 }
658 }
659 } else {
660 $value = sanitize_text_field(trim($_REQUEST['value']));
661 }
662 }
663 }
664
665
666
667
668
669 //***
670 //normalize calendar date
671 if ($this->settings->active_fields[$field_key]['edit_view'] === 'calendar') {
672 $value = $this->posts->normalize_calendar_date($value, $field_key);
673 }
674
675
676
677
678 $value = $this->posts->__string_replacer($value, $post_id);
679 $response = $this->posts->update_page_field($post_id, $field_key, $value, $field_type);
680
681 //echo wp_kses_post($response); //danger - breaks gallery button data-images attribute
682 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML built from trusted internal template, values escaped inside the template
683 echo $response;
684 }
685
686 if (isset($_REQUEST['post_id'])) {
687 exit; //ajax
688 }
689 }
690
691 //ajax
692 public function wpbe_redraw_table_row() {
693
694 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_field_update')) {
695 die('Forbidden!');
696 }
697
698 if (!WPBE_HELPER::can_manage_data()) {
699 wp_die('0');
700 }
701
702 $post_id = intval($_REQUEST['post_id']);
703
704 if ($post_id > 0 && !current_user_can('edit_post', $post_id)) {
705 wp_die('0');
706 }
707
708 //+++
709
710 if (is_array($_REQUEST['value'])) {
711 $value = (array) $_REQUEST['value'];
712 } else {
713 $value = trim($_REQUEST['value']);
714 }
715
716 //***
717
718 if (isset($_REQUEST['field']) AND !empty($_REQUEST['field'])) {
719 $field_key = sanitize_key($_REQUEST['field']);
720 $this->posts->update_page_field($post_id, $field_key, $value);
721 }
722
723
724 //generate table row by $post_id
725 $res = $this->wpbe_get_posts(array(
726 'p' => $post_id,
727 'post_type' => array($this->settings->current_post_type)
728 ), true);
729
730 if (!empty($res['data'])) {
731 wp_send_json($res['data'][0]);
732 }
733
734 exit;
735 }
736
737 //ajax
738 public function get_post_field() {
739
740 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_field_update')) {
741 die('Forbidden!');
742 }
743 if (!WPBE_HELPER::can_manage_data()) {
744 wp_die('0');
745 }
746
747 $response = $this->posts->get_post_field(intval($_REQUEST['post_id']), sanitize_key($_REQUEST['field']), (isset($_REQUEST['post_parent']) ? $_REQUEST['post_parent'] : 0));
748 echo wp_kses_post($response);
749 exit;
750 }
751
752 //ajax
753 public function wpbe_get_gallery() {
754
755 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_field_update')) {
756 die('Forbidden!');
757 }
758 if (!WPBE_HELPER::can_manage_data()) {
759 wp_die('0');
760 }
761
762 $post_id = intval($_REQUEST['post_id']);
763
764 if (!$post_id) {
765 exit;
766 }
767
768 $post = $this->posts->get_post($post_id);
769
770 WPBE_HELPER::render_html_e(WPBE_PATH . 'views/parts/post-gallery.php', array(
771 'images' => $post->get_gallery_image_ids('edit')
772 ));
773
774 exit;
775 }
776
777 //ajax
778 public function wpbe_get_upsells() {
779
780 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_field_update')) {
781 die('Forbidden!');
782 }
783 if (!WPBE_HELPER::can_manage_data()) {
784 wp_die('0');
785 }
786
787
788 $post_id = intval($_REQUEST['post_id']);
789
790 if (!$post_id) {
791 exit;
792 }
793
794 $post = $this->posts->get_post($post_id);
795
796 WPBE_HELPER::render_html_e(WPBE_PATH . 'views/parts/post-upsells.php', array(
797 'posts' => $post->get_upsell_ids('edit')
798 ));
799
800 exit;
801 }
802
803 //ajax
804 public function wpbe_save_options() {
805
806 if (!WPBE_HELPER::can_manage_data()) {
807 wp_die('0');
808 }
809 if (!isset($_REQUEST['save_nonce']) || !wp_verify_nonce($_REQUEST['save_nonce'], 'wpbe_settings_nonce')) {
810 die('0');
811 }
812 $data = array();
813 parse_str($_REQUEST['formdata'], $data);
814
815 if (isset($data['wpbe_options'])) {
816 if (is_array($data['wpbe_options'])) {
817 $this->settings->update_options($data['wpbe_options']);
818 }
819
820 //***
821 //save site editor fields visibility
822 if (in_array($this->settings->current_user_role, apply_filters('wpbe_permit_special_roles', ['administrator']))) {
823 $visibility = array();
824
825 foreach ($data['wpbe_options']['fields'] as $key => $v) {
826 if (isset($v['site_editor_visibility'])) {
827 $visibility[$key] = intval($v['site_editor_visibility']);
828 }
829 }
830
831 update_option('wpbe_site_editor_visibility', $visibility);
832
833 //***
834 update_option('wpbe_site_editors_post_types', $data['wpbe_site_editors_post_types']);
835
836 if (isset($data['wpbe_site_separate_settings'])) {
837 update_option('wpbe_site_separate_settings', $data['wpbe_site_separate_settings']);
838 update_option('wpbe_show_text_editor', $data['wpbe_show_text_editor']);
839 }
840 }
841 }
842
843 exit;
844 }
845
846 //ajax
847 public function wpbe_title_autocomplete() {
848
849 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_field_update')) {
850 die('Forbidden!');
851 }
852 if (!WPBE_HELPER::can_manage_data()) {
853 wp_die('0');
854 }
855
856
857 $results = array();
858 $results[] = array(
859 "name" => esc_html__("Posts not found!", 'bulk-editor'),
860 "id" => 0,
861 "type" => "",
862 "link" => "#",
863 "icon" => WPBE_ASSETS_LINK . 'images/not-found.jpg'
864 );
865
866 //***
867
868 if (!empty($_REQUEST['wpbe_txt_search'])) {
869 $args = array(
870 'nopaging' => true,
871 'post_type' => array($this->settings->current_post_type),
872 'post_status' => array_keys(get_post_statuses()),
873 'order_by' => 'title',
874 'order' => 'ASC',
875 'per_page' => intval($_REQUEST['auto_res_count']) > 0 ? intval($_REQUEST['auto_res_count']) : 10,
876 'max_num_pages' => intval($_REQUEST['auto_res_count']) > 0 ? intval($_REQUEST['auto_res_count']) : 10
877 );
878
879 //***
880
881 if (!empty($_REQUEST['exept_ids'])) {
882 $exept_ids = array(); //which posts exclude as they are on the list already
883 parse_str($_REQUEST['exept_ids'], $exept_ids);
884 $args['post__not_in'] = $exept_ids['wpbe_prod_ids'];
885 }
886
887 //***
888 $st = $_REQUEST['wpbe_txt_search'];
889 $_REQUEST['wpbe_txt_search'] = array();
890 $_REQUEST['wpbe_txt_search_behavior'] = array();
891 $_REQUEST['wpbe_txt_search']['post_title'] = $st;
892 $_REQUEST['wpbe_txt_search_behavior']['post_title'] = 'like';
893 $this->posts->suppress_filters = true;
894 add_filter('posts_where', array($this->filters, 'posts_txt_where'), 101);
895 $query = $this->posts->gets($args);
896
897 //+++
898 //http://easyautocomplete.com/guide
899 if ($query->have_posts()) {
900 $results = array();
901 foreach ($query->posts as $p) {
902 $data = array(
903 "name" => $p->post_title . ' (#' . $p->ID . ')',
904 "id" => $p->ID,
905 "type" => "post"
906 );
907 if (has_post_thumbnail($p->ID)) {
908 $img_src = wp_get_attachment_image_src(get_post_thumbnail_id($p->ID), 'thumbnail');
909 $data['icon'] = $img_src[0];
910 } else {
911 $data['icon'] = WPBE_ASSETS_LINK . 'images/not-found.jpg';
912 }
913 $data['link'] = get_post_permalink($p->ID);
914 $results[] = $data;
915 }
916 }
917 }
918
919
920 wp_die(json_encode($results));
921 }
922
923 //ajax
924 public function wpbe_create_new_post() {
925
926 if (!WPBE_HELPER::can_manage_data()) {
927 wp_die('0');
928 }
929 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_tools_panel_nonce')) {
930 wp_die('0');
931 }
932 $to_create = intval($_REQUEST['to_create']);
933 while ($to_create) {
934 wp_insert_post(array(
935 'post_type' => $this->settings->current_post_type,
936 'post_title' => sprintf(
937 /* translators: %s: post name */
938 esc_html__('New %s', 'bulk-editor'), $this->settings->current_post_type),
939 'post_status' => apply_filters('wpbe_new_post_status', 'draft', $this->settings->current_post_type)
940 ));
941
942 $to_create--;
943 }
944
945 exit;
946 }
947
948 //ajax
949 public function wpbe_duplicate_posts() {
950
951 if (!WPBE_HELPER::can_manage_data()) {
952 wp_die('0');
953 }
954 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_tools_panel_nonce')) {
955 wp_die('0');
956 }
957 if (!empty($_REQUEST['posts_ids'])) {
958
959 global $wpdb;
960
961 foreach ($_REQUEST['posts_ids'] as $post_id) {
962 $post_id = intval($post_id);
963
964 $post = get_post($post_id);
965 if (isset($post) && $post != null) {
966
967 $args = array(
968 'comment_status' => $post->comment_status,
969 'ping_status' => $post->ping_status,
970 'post_author' => get_current_user_id(),
971 'post_content' => $post->post_content,
972 'post_excerpt' => $post->post_excerpt,
973 'post_name' => '',
974 'post_parent' => $post->post_parent,
975 'post_password' => $post->post_password,
976 'post_status' => 'publish',
977 'post_title' => $post->post_title . ' (' . esc_html__('copy', 'bulk-editor') . ')',
978 'post_type' => $post->post_type,
979 'to_ping' => $post->to_ping,
980 'menu_order' => $post->menu_order
981 );
982
983 $new_post_id = wp_insert_post($args);
984 $taxonomies = get_object_taxonomies($post->post_type); //returns array of taxonomy names for post type, ex array("category", "post_tag");
985
986 if (!empty($taxonomies)) {
987 foreach ($taxonomies as $taxonomy) {
988 $post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
989 wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
990 }
991 }
992
993 //***
994
995 $post_meta_infos = $wpdb->get_results($wpdb->prepare("SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id=%d", $post_id));
996
997 if (count($post_meta_infos) !== 0) {
998 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
999 $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value)";
1000 foreach ($post_meta_infos as $meta_info) {
1001 $meta_key = $meta_info->meta_key;
1002 if ($meta_key == '_wp_old_slug') {
1003 continue;
1004 }
1005
1006 $meta_value = $meta_info->meta_value;
1007 $sql_query_sel[] = $wpdb->prepare("SELECT %d, %s, %s", $new_post_id, $meta_key, $meta_value);
1008 }
1009 $sql_query .= implode(" UNION ALL ", $sql_query_sel);
1010 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- each SELECT is prepared above
1011 $wpdb->query($sql_query);
1012 }
1013
1014 //***
1015
1016 $this->posts->update_page_field($new_post_id, 'post_status', 'draft');
1017 }
1018 }
1019
1020 //wp_cache_flush();
1021 }
1022
1023 wp_die('done');
1024 }
1025
1026 //ajax
1027 public function wpbe_delete_posts() {
1028
1029 if (!WPBE_HELPER::can_manage_data()) {
1030 wp_die('0');
1031 }
1032 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_tools_panel_nonce')) {
1033 wp_die('0');
1034 }
1035 if (!empty($_REQUEST['posts_ids'])) {
1036 foreach ($_REQUEST['posts_ids'] as $post_id) {
1037 //wp_delete_post($post_id, false);
1038 wp_trash_post($post_id);
1039 }
1040
1041 //wp_cache_flush();
1042 }
1043
1044 wp_die('done');
1045 }
1046
1047 public function wrap_field_val($post, $field_key) {
1048
1049 $res = NULL;
1050
1051 $post = $this->posts->get_post($post['ID']);
1052 $post_id = $post['ID'];
1053
1054 if (isset($this->settings->active_fields[$field_key]['allow_post_types'])) {
1055 try {
1056 if (!in_array($this->settings->current_post_type, $this->settings->active_fields[$field_key]['allow_post_types'])) {
1057 return WPBE_HELPER::draw_restricked();
1058 }
1059 } catch (Exception $e) {
1060 //***
1061 }
1062 }
1063
1064 if (isset($this->settings->active_fields[$field_key]['prohibit_post_types'])) {
1065 try {
1066 if (in_array($this->settings->current_post_type, $this->settings->active_fields[$field_key]['prohibit_post_types'])) {
1067 return WPBE_HELPER::draw_restricked();
1068 }
1069 } catch (Exception $e) {
1070 //***
1071 }
1072 }
1073
1074 //***
1075 $val = '';
1076 switch ($this->settings->active_fields[$field_key]['field_type']) {
1077 case 'meta':
1078 $val = $this->posts->get_post_field($post_id, $field_key);
1079 break;
1080
1081 case 'taxonomy':
1082 $terms = $this->posts->get_post_field($post_id, $field_key);
1083
1084 $ids = array();
1085 $titles = array();
1086
1087 //***
1088
1089 if (!empty($terms)) {
1090 foreach ($terms as $t) {
1091 $ids[] = $t->term_id;
1092 $titles[] = $t->name;
1093 }
1094 }
1095
1096 if (!empty($ids)) {
1097 $ids = array_map(function ($v) {
1098 return intval($v);
1099 }, $ids);
1100 }
1101
1102 //***
1103
1104 if ($this->settings->active_fields[$field_key]['type'] === 'array') {
1105 $val = array(
1106 'terms_ids' => $ids,
1107 'terms_titles' => $titles
1108 );
1109
1110 //for drop-down view
1111 if ($this->settings->active_fields[$field_key]['edit_view'] == 'select') {
1112 $val['selected'] = $val['terms_ids'];
1113 }
1114 } else {
1115 //string, for example: post_type
1116 $val = $titles[0];
1117 }
1118
1119 break;
1120
1121 default:
1122 if (isset($post[$field_key])) {
1123 $val = $post[$field_key];
1124 }
1125 break;
1126 }
1127
1128 //***
1129
1130 switch ($this->settings->active_fields[$field_key]['edit_view']) {
1131 case 'select':
1132
1133 $select_options = $this->settings->active_fields[$field_key]['select_options'];
1134
1135 //as example
1136 if ($field_key === 'post_status') {
1137 //***
1138 }
1139
1140 //***
1141
1142 $res = WPBE_HELPER::draw_select(array(
1143 'field' => $field_key,
1144 'post_id' => $post_id,
1145 'class' => 'wpbe_data_select',
1146 'options' => $select_options,
1147 'selected' => (isset($val['selected']) ? $val['selected'] : $val),
1148 'disabled' => (isset($this->settings->active_fields[$field_key]['disabled']) ? $this->settings->active_fields[$field_key]['disabled'] : FALSE),
1149 'onchange' => 'wpbe_act_select(this)'
1150 ));
1151 break;
1152
1153 case 'multi_select':
1154
1155 $res = WPBE_HELPER::render_html(WPBE_PATH . 'views/elements/multi_select.php', array(
1156 'field_key' => $field_key,
1157 'post_id' => $post_id,
1158 'val' => $val,
1159 'active_fields' => $this->settings->active_fields,
1160 'post' => $post,
1161 ));
1162 break;
1163
1164 case 'popup':
1165 $res = WPBE_HELPER::draw_taxonomy_popup_btn($val, $field_key, $post);
1166 break;
1167
1168 case 'popupeditor':
1169 $res = WPBE_HELPER::draw_popup_editor_btn($val, $field_key, $post);
1170 break;
1171
1172 case 'meta_popup_editor':
1173 $res = WPBE_HELPER::draw_meta_popup_editor_btn($field_key, $post_id);
1174 break;
1175
1176 case 'thumbnail':
1177 $thumbnail = wp_get_attachment_image_src($val, 'thumbnail');
1178 $full = wp_get_attachment_image_src($val, 'full');
1179
1180 if (!empty($thumbnail)) {
1181 $thumbnail = $thumbnail[0];
1182 $full = $full[0];
1183 } else {
1184 $thumbnail = WPBE_ASSETS_LINK . 'images/not-found.jpg';
1185 $full = WPBE_ASSETS_LINK . 'images/not-found.jpg';
1186 }
1187
1188 $onmouseover = '';
1189 if ($this->settings->show_thumbnail_preview) {
1190 $onmouseover = 'onmouseover="wpbe_init_image_preview(this)"';
1191 }
1192
1193 $res = '<a href="' . $full . '" onclick="return wpbe_act_thumbnail(this)" ' . $onmouseover . ' title="' . $post['post_title'] . '"><img src="' . $thumbnail . '" class="attachment-thumbnail size-thumbnail" alt="" /></a>';
1194 break;
1195
1196 case 'switcher':
1197 $labels = array_values($this->settings->active_fields[$field_key]['select_options']);
1198 $values = array_keys($this->settings->active_fields[$field_key]['select_options']);
1199 if ($val) {//do switcher
1200 $val = WPBE_HELPER::over_switcher_val_to_swicher($val, $field_key);
1201 }
1202 $res = WPBE_HELPER::draw_advanced_switcher(($val == $values[0] ? TRUE : FALSE), $post_id . '_' . $field_key, $field_key, array('true' => $labels[0], 'false' => $labels[1]), array('true' => $values[0], 'false' => $values[1]), 'yes');
1203 break;
1204
1205 case 'calendar':
1206 if ($this->settings->active_fields[$field_key]['type'] === 'timestamp') {
1207 $val = strtotime($val);
1208 }
1209
1210 $post_title = $post['post_title'];
1211
1212 if ($post['post_type'] === 'post_variation') {
1213 //removed
1214 }
1215
1216 if ($this->settings->active_fields[$field_key]['type'] === 'timestamp') {
1217 $val = strtotime($val);
1218 } elseif (!empty($val) && !is_numeric($val)) {
1219 $val = strtotime($val);
1220 }
1221
1222 $res = WPBE_HELPER::draw_calendar($post_id, $post_title . ' (' . $this->settings->active_fields[$field_key]['title'] . ')', $field_key, $val);
1223 break;
1224
1225 case 'checkbox':
1226 //using for posts selection
1227 $res = WPBE_HELPER::draw_checkbox(array(
1228 'class' => 'wpbe_post_check',
1229 'data-post-id' => $post_id
1230 ));
1231 break;
1232
1233 case 'gallery_popup_editor':
1234
1235 $images = $this->posts->get_post_field($post_id, $field_key);
1236
1237 if ($images) {
1238 $images = explode(',', $images);
1239 } else {
1240 $images = [];
1241 }
1242
1243 return WPBE_HELPER::render_html(WPBE_PATH . 'views/elements/draw_gallery_popup_editor_btn.php', array(
1244 'field_key' => $field_key,
1245 'post_id' => $post_id,
1246 'images' => $images
1247 ));
1248
1249 break;
1250
1251 default:
1252 //textinput
1253 $sanitize = '';
1254 if (isset($this->settings->active_fields[$field_key]['sanitize'])) {
1255 $sanitize = $this->settings->active_fields[$field_key]['sanitize'];
1256 }
1257
1258 $res = $this->posts->__sanitize_answer_value($field_key, $sanitize, $val);
1259
1260 break;
1261 }
1262
1263 //***
1264 //lets show post ID as LINK to the post
1265 if ($field_key === 'ID') {
1266 $class = 'wpbe-id-permalink';
1267 $title = esc_html__('see the post on the site', 'bulk-editor');
1268 $res = '<a href="' . get_permalink($res) . '" class="' . $class . '" title="' . $title . '" target="_blank">' . $res . '</a>';
1269 }
1270
1271 //***
1272
1273 return apply_filters('wpbe_wrap_field_val', $res, $post, $field_key);
1274 }
1275
1276 //ajax
1277 public function wpbe_create_new_term() {
1278
1279 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_field_update')) {
1280 die('Forbidden!');
1281 }
1282 $titles = $_REQUEST['titles'];
1283 $slugs = $_REQUEST['slugs'];
1284 $taxonomy = $_REQUEST['tax_key'];
1285
1286 //***
1287
1288 if (!empty($titles)) {
1289
1290 if (substr_count($titles, ',') > 0) {
1291 $titles = explode(',', $titles);
1292 } else {
1293 $titles = array($titles);
1294 }
1295
1296
1297 if (substr_count($slugs, ',') > 0) {
1298 $slugs = explode(',', $slugs);
1299 } else {
1300 $slugs = array($slugs);
1301 }
1302
1303 //***
1304
1305 $terms_ids = array();
1306 foreach ($titles as $k => $t) {
1307 $t = trim($t);
1308 if (!term_exists($t, $taxonomy)) {
1309 if (!empty($t)) {
1310 $res = wp_insert_term($t, $taxonomy, array(
1311 'parent' => intval($_REQUEST['parent']),
1312 'slug' => (isset($slugs[$k]) ? trim($slugs[$k]) : '')
1313 ));
1314 $terms_ids[] = $res['term_id'];
1315 } else {
1316 unset($titles[$k]);
1317 }
1318 }
1319 }
1320
1321 //***
1322
1323 echo json_encode(array(
1324 'titles' => array_reverse($titles),
1325 'terms_ids' => array_reverse($terms_ids),
1326 'terms' => WPBE_HELPER::get_taxonomies_terms_hierarchy($taxonomy)
1327 ));
1328 }
1329 exit;
1330 }
1331
1332 //do not init functionality on all site pages as it not nessesary
1333 private function is_should_init() {
1334 //do not onit it exept of one wpbe page and its ajax requests
1335 $init = isset($_GET['page']) AND $_GET['page'] === 'wpbe';
1336
1337 if (defined('DOING_AJAX')) {
1338 if (strpos($_REQUEST['action'], 'wpbe_') !== FALSE) {
1339 $init = true;
1340 }
1341 }
1342
1343 return $init;
1344 }
1345
1346 public function add_statuses($statuses) {
1347
1348 $statuses['future'] = esc_html__('Scheduled', 'bulk-editor');
1349
1350 return $statuses;
1351 }
1352
1353 public function wpbe_delete_tax_term() {
1354 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_field_update')) {
1355 die('Forbidden!');
1356 }
1357 $term_id = (int) $_REQUEST['term_id'];
1358 $taxonomy = sanitize_text_field(trim($_REQUEST['tax_key']));
1359 if (!taxonomy_exists($taxonomy)) {
1360 die('Wrong taxonomy name.');
1361 }
1362 $result = wp_delete_term($term_id, $taxonomy);
1363 // check the result
1364 if (is_wp_error($result)) {
1365
1366 die('error wp_update_term');
1367 } else {
1368
1369 echo json_encode(WPBE_HELPER::get_taxonomies_terms_hierarchy($taxonomy));
1370 }
1371 exit;
1372 }
1373
1374 public function wpbe_update_tax_term() {
1375 if (!isset($_REQUEST['wpbe_nonce']) || !wp_verify_nonce($_REQUEST['wpbe_nonce'], 'wpbe_field_update')) {
1376 die('Forbidden!');
1377 }
1378
1379 $term_id = (int) $_REQUEST['term_id'];
1380 $title = sanitize_textarea_field($_REQUEST['title']);
1381 $slug = sanitize_textarea_field($_REQUEST['slug']);
1382 $description = sanitize_textarea_field($_REQUEST['description'] ?? '');
1383 $parent = (int) $_REQUEST['parent'];
1384 $taxonomy = sanitize_text_field(trim($_REQUEST['tax_key']));
1385 if (!taxonomy_exists($taxonomy)) {
1386 die('Wrong taxonomy name.');
1387 }
1388
1389 $result = wp_update_term($term_id, $taxonomy, [
1390 'name' => $title,
1391 'slug' => $slug,
1392 'description' => $description,
1393 'parent' => $parent
1394 ]);
1395
1396 // check the result
1397 if (is_wp_error($result)) {
1398
1399 die('error wp_update_term');
1400 } else {
1401
1402 echo json_encode(WPBE_HELPER::get_taxonomies_terms_hierarchy($taxonomy));
1403 }
1404 exit;
1405 }
1406
1407 public function wp_editor_compatibility() {
1408 if (!isset($_GET['wpbe_popup_editor']) || $_GET['wpbe_popup_editor'] != 1) {
1409 return;
1410 }
1411 ?>
1412 <style>
1413 .edit-post-header__settings .editor-post-switch-to-draft{
1414 display: none;
1415 }
1416 .edit-post-header__settings .block-editor-post-preview__dropdown{
1417 display: none;
1418 }
1419 .edit-post-header__settings .editor-post-publish-button{
1420 display: none;
1421 }
1422 .edit-post-sidebar .components-panel .components-panel__body {
1423 display: none;
1424 }
1425 .edit-post-header .edit-post-fullscreen-mode-close{
1426 display: none;
1427 }
1428 .edit-post-header__settings .interface-more-menu-dropdown {
1429 display: block;
1430 }
1431 </style>
1432 <script>
1433
1434 function wpbe_popup_editor_get_content() {
1435 return wp.data.select("core/editor").getEditedPostContent();
1436 }
1437 </script>
1438 <?php
1439 }
1440
1441 public function ask_favour() {
1442 if (get_option('wpbe_rate_alert', 0)) {
1443 //old rate system mark for already set review users
1444 return;
1445 }
1446
1447 $slug = strtolower(get_class($this));
1448
1449 add_action("wp_ajax_{$slug}_dismiss_rate_alert", function () use ($slug) {
1450 update_option("{$slug}_dismiss_rate_alert", 2);
1451 });
1452
1453 add_action("wp_ajax_{$slug}_later_rate_alert", function () use ($slug) {
1454 update_option("{$slug}_later_rate_alert", time() + 4 * 7 * 24 * 60 * 60); //4 weeks
1455 });
1456
1457 //+++
1458
1459 add_action('admin_notices', function () use ($slug) {
1460
1461 if (!current_user_can('manage_options')) {
1462 return; //show to admin only
1463 }
1464
1465 if (intval(get_option("{$slug}_dismiss_rate_alert", 0)) === 2) {
1466 return;
1467 }
1468
1469 if (intval(get_option("{$slug}_later_rate_alert", 0)) === 0) {
1470 update_option("{$slug}_later_rate_alert", time() + 1 * 3 * 24 * 60 * 60); //3 days after install
1471 return;
1472 }
1473
1474 if (intval(get_option("{$slug}_later_rate_alert", 0)) > time()) {
1475 return;
1476 }
1477
1478 //$link = 'https://codecanyon.net/downloads#item-24376112';
1479 //$on = 'CodeCanyon';
1480 //if ($this->show_notes) {
1481 $link = 'https://wordpress.org/support/plugin/bulk-editor/reviews/';
1482 $on = 'WordPress';
1483 //}
1484 ?>
1485 <div class="notice notice-info" id="pn_<?php echo esc_attr($slug) ?>_ask_favour" style="position: relative;">
1486 <button onclick="javascript: pn_<?php echo esc_attr($slug) ?>_dismiss_review(1);
1487 void(0);" title="<?php esc_html_e('Later', 'bulk-editor'); ?>" class="notice-dismiss"></button>
1488 <div id="pn_<?php echo esc_attr($slug) ?>_review_suggestion">
1489 <p><?php esc_html_e('Hi! Are you enjoying using WOLF – WordPress Posts Bulk Editor Professional?', 'bulk-editor'); ?></p>
1490 <p><a href="javascript: pn_<?php echo esc_attr($slug) ?>_set_review(1); void(0);"><?php esc_html_e('Yes, I love it', 'bulk-editor'); ?></a> 🙂 | <a href="javascript: pn_<?php echo esc_attr($slug) ?>_set_review(0); void(0);"><?php esc_html_e('Not really...', 'bulk-editor'); ?></a></p>
1491 </div>
1492
1493 <div id="pn_<?php echo esc_attr($slug) ?>_review_yes" style="display: none;">
1494 <p><?php
1495 /* translators: %s: name */
1496 printf(esc_html__('That\'s awesome! Could you please do us a BIG favor and give it a 5-star rating on %s to help us spread the word and boost our motivation?', 'bulk-editor'), esc_html($on)) ?></p>
1497 <p style="font-weight: bold;">~ PluginUs.NET developers team</p>
1498 <p>
1499 <a href="<?php echo esc_attr($link) ?>" style="display: inline-block; margin-right: 10px;" onclick="pn_<?php echo esc_attr($slug) ?>_dismiss_review(2)" target="_blank"><?php esc_html_e('Okay, you deserve it', 'bulk-editor'); ?></a>
1500 <a href="javascript: pn_<?php echo esc_attr($slug) ?>_dismiss_review(1); void(0);" style="display: inline-block; margin-right: 10px;"><?php esc_html_e('Nope, maybe later', 'bulk-editor'); ?></a>
1501 <a href="javascript: pn_<?php echo esc_attr($slug) ?>_dismiss_review(2); void(0);"><?php esc_html_e('I already did', 'bulk-editor'); ?></a>
1502 </p>
1503 </div>
1504
1505 <div id="pn_<?php echo esc_attr($slug) ?>_review_no" style="display: none;">
1506 <p><?php esc_html_e('We are sorry to hear you aren\'t enjoying WOLF. We would love a chance to improve it. Could you take a minute and let us know what we can do better?', 'bulk-editor'); ?></p>
1507 <p>
1508 <a href="https://pluginus.net/contact-us/" onclick="pn_<?php echo esc_attr($slug) ?>_dismiss_review(2)" target="_blank"><?php esc_html_e('Give Feedback', 'bulk-editor'); ?></a>&nbsp;
1509 |&nbsp;<a href="javascript: pn_<?php echo esc_attr($slug) ?>_dismiss_review(2); void(0);"><?php esc_html_e('No thanks', 'bulk-editor'); ?></a>
1510 </p>
1511 </div>
1512
1513
1514 <script>
1515 function pn_<?php echo esc_attr($slug) ?>_set_review(yes) {
1516 document.getElementById('pn_<?php echo esc_attr($slug) ?>_review_suggestion').style.display = 'none';
1517 if (yes) {
1518 document.getElementById('pn_<?php echo esc_attr($slug) ?>_review_yes').style.display = 'block';
1519 } else {
1520 document.getElementById('pn_<?php echo esc_attr($slug) ?>_review_no').style.display = 'block';
1521 }
1522 }
1523
1524 function pn_<?php echo esc_attr($slug) ?>_dismiss_review(what = 1) {
1525 //1 maybe later, 2 do not ask more
1526 jQuery('#pn_<?php echo esc_attr($slug) ?>_ask_favour').fadeOut();
1527
1528 if (what === 1) {
1529 jQuery.post(ajaxurl, {
1530 action: '<?php echo esc_attr($slug) ?>_later_rate_alert'
1531 });
1532 } else {
1533 jQuery.post(ajaxurl, {
1534 action: '<?php echo esc_attr($slug) ?>_dismiss_rate_alert'
1535 });
1536 }
1537
1538 return true;
1539 }
1540 </script>
1541 </div>
1542 <?php
1543 });
1544 }
1545 }
1546
1547 //***
1548
1549 $WPBE = new WPBE();
1550 $GLOBALS['WPBE'] = $WPBE;
1551 add_action('init', array($WPBE, 'init'), 9999);
1552
1553