Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/columns-visibility/columns-visibility.php
+++ b/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/columns-visibility/columns-visibility.php
@@ -13,7 +13,6 @@
static $unfiltered_columns = array();
private function __construct() {
-
}
/**
@@ -36,7 +35,6 @@
add_action( 'wp_ajax_vgse_remove_column', array( $this, 'remove_column' ) );
add_action( 'wp_ajax_vgse_restore_columns', array( $this, 'restore_columns' ) );
add_filter( 'vg_sheet_editor/columns/blacklisted_columns', array( $this, 'blacklist_removed_columns' ), 10, 2 );
- add_action( 'wp_ajax_vgse_load_columns_manager_content', array( $this, 'ajax_load_columns_manager_content' ) );
}
static function get_visibility_options( $post_type = null ) {
@@ -70,7 +68,7 @@
}
if ( $changed ) {
- update_option( self::$columns_visibility_key, $options );
+ update_option( self::$columns_visibility_key, $options, false );
}
}
@@ -99,8 +97,8 @@
$old_settings = VGSE()->options;
$new_settings = $this->migrate_old_settings_raw( $old_settings );
- update_option( self::$columns_visibility_key, $new_settings );
- update_option( self::$columns_visibility_key . '_migrated', 1 );
+ update_option( self::$columns_visibility_key, $new_settings, false );
+ update_option( self::$columns_visibility_key . '_migrated', 1, false );
}
public function migrate_old_settings_raw( $old_settings ) {
@@ -125,7 +123,7 @@
$removed_columns[ $post_type ] = $columns;
$removed_columns[ $post_type ] = array_unique( array_filter( $removed_columns[ $post_type ] ) );
- update_option( $this->removed_columns_key, $removed_columns );
+ update_option( $this->removed_columns_key, $removed_columns, false );
}
public function get_removed_columns( $post_type ) {
@@ -143,7 +141,7 @@
public function blacklist_removed_columns( $blacklisted_columns, $post_type ) {
$removed_columns = $this->get_removed_columns( $post_type );
foreach ( $removed_columns[ $post_type ] as $removed_column_key ) {
- $blacklisted_columns[] = '^' . preg_quote($removed_column_key, '/') . '$';
+ $blacklisted_columns[] = '^' . preg_quote( $removed_column_key, '/' ) . '$';
}
return $blacklisted_columns;
}
@@ -261,31 +259,9 @@
*/
public function enqueue_assets() {
wp_enqueue_script( 'wp-sheet-editor-sortable', plugins_url( '/assets/vendor/Sortable/Sortable.min.js', __FILE__ ), array( 'jquery' ), VGSE()->version );
- wp_enqueue_script( 'wp-sheet-editor-columns-visibility-modal', plugins_url( '/assets/js/init.js', __FILE__ ), array( 'wp-sheet-editor-sortable' ), VGSE()->version );
+ wp_enqueue_script( 'wp-sheet-editor-columns-visibility-modal', plugins_url( '/assets/js/init.js', __FILE__ ), array( 'wp-sheet-editor-sortable' ), filemtime( __DIR__ . '/assets/js/init.js' ) );
}
- public function ajax_load_columns_manager_content() {
- if ( ! isset( $_GET['is_editor_page'] ) || empty( $_GET['post_type'] ) || ! VGSE()->helpers->verify_nonce_from_request() ) {
- wp_send_json_error( array( 'message' => __( 'You dont have enough permissions to execute this action.', 'vg_sheet_editor' ) ) );
- }
- $post_type = sanitize_text_field( $_GET['post_type'] );
- if ( ! empty( $_GET['is_editor_page'] ) ) {
- add_filter( 'vg_sheet_editor/is_editor_page', '__return_true' );
- }
- ob_start();
- $this->render_settings_modal( $post_type );
- $html = ob_get_clean();
-
- wp_send_json_success( array( 'html' => $html ) );
- }
- /**
- * Render modal html
- * @param str $post_type
- */
- public function render_lazy_settings_modal( $post_type ) {
- $random_id = rand();
- include __DIR__ . '/views/lazy-form.php';
- }
public function render_settings_modal( $post_type, $partial_form = false, $options = null, $current_url = null, $visible_columns = null ) {
$nonce = wp_create_nonce( 'bep-nonce' );
$random_id = rand();
@@ -330,13 +306,68 @@
// might not appear in the enabled nor disabled lists. Force them to appear at least as disabled.
foreach ( $filtered_columns as $column_key => $column_settings ) {
if ( ! isset( $visible_columns[ $column_key ] ) ) {
- $options[ $post_type ]['disabled'][ $column_key ] = $column_settings;
+ $options[ $post_type ]['disabled'][ $column_key ] = $column_settings['title'];
+ }
+ }
+ $default_column_data = array(
+ 'title' => '',
+ 'status' => 'enabled',
+ 'key' => '',
+ );
+ $prepared_columns = array();
+
+ $index = 0;
+ foreach ( $visible_columns as $column_key => $column ) {
+ if ( is_numeric( $column_key ) || in_array( $column_key, $not_allowed_columns ) || ( isset( $options[ $post_type ]['disabled'] ) && isset( $options[ $post_type ]['disabled'][ $column_key ] ) ) || ! isset( $column['title'] ) ) {
+ unset( $visible_columns[ $column_key ] );
+ continue;
}
+ $prepared_columns[ $column_key ] = array(
+ 'title' => $column['title'],
+ 'status' => 'enabled',
+ 'key' => $column_key,
+ 'order' => $index,
+ 'allow_custom_format' => $column['allow_custom_format'],
+ 'allow_readonly_option_in_columns_manager' => $column['allow_readonly_option_in_columns_manager'],
+ 'allow_role_restrictions_in_columns_manager' => $column['allow_role_restrictions_in_columns_manager'],
+ );
+ ++$index;
}
- $editor = VGSE()->helpers->get_provider_editor( $post_type );
+ $editor = VGSE()->helpers->get_provider_editor( $post_type );
+ $post_type_options = $options[ $post_type ];
+
+ $index = 0;
+ foreach ( $post_type_options['disabled'] as $column_key => $column_title ) {
+
+ if ( is_numeric( $column_key ) || in_array( $column_key, $not_allowed_columns, true ) ) {
+ unset( $post_type_options['disabled'][ $column_key ] );
+ continue;
+
+ }
+ $skip_blacklist = isset( $columns[ $column_key ] ) && ! empty( $columns[ $column_key ]['skip_blacklist'] );
+ if ( ! $skip_blacklist && is_object( $editor->args['columns'] ) && $editor->args['columns']->is_column_blacklisted( $column_key, $post_type ) ) {
+ unset( $post_type_options['disabled'][ $column_key ] );
+ continue;
+ }
- include __DIR__ . '/views/form.php';
+ if ( ! isset( $prepared_columns[ $column_key ] ) ) {
+ $prepared_columns[ $column_key ] = array(
+ 'title' => isset( $columns[ $column_key ] ) ? $columns[ $column_key ]['title'] : $column_title,
+ 'status' => 'disabled',
+ 'key' => $column_key,
+ 'order' => $index,
+ );
+ ++$index;
+ }
+ }
+ ?>
+ <script>
+ var vgseColumnsManager =
+ <?php echo wp_json_encode( apply_filters( 'vg_sheet_editor/columns_visibility/js/columns_manager', compact( 'nonce', 'prepared_columns', 'not_allowed_columns', 'default_column_data' ), $post_type ) ); ?>;
+ </script>
+ <?php
+ require_once __DIR__ . '/views/form.php';
}
/**
@@ -349,16 +380,14 @@
$post_types = $editor->args['enabled_post_types'];
foreach ( $post_types as $post_type ) {
$editor->args['toolbars']->register_item(
- 'visibility_settings',
+ 'columns_manager',
array(
'type' => 'button',
'allow_in_frontend' => false,
- 'content' => __( 'Hide / Display / Sort columns', 'vg_sheet_editor' ),
- 'icon' => 'fa fa-sort',
+ 'content' => __( 'Columns manager', 'vg_sheet_editor' ),
'toolbar_key' => 'secondary',
'extra_html_attributes' => 'data-remodal-target="modal-columns-visibility"',
- 'parent' => 'settings',
- 'footer_callback' => array( $this, 'render_lazy_settings_modal' ),
+ 'footer_callback' => array( $this, 'render_settings_modal' ),
),
$post_type
);
@@ -375,7 +404,7 @@
return $columns;
}
// Filter by required capabilities before they're added to the $unfiltered_columns
- if( method_exists('WP_Sheet_Editor_Columns', '_filter_by_require_capabilities')){
+ if ( method_exists( 'WP_Sheet_Editor_Columns', '_filter_by_require_capabilities' ) ) {
$columns = WP_Sheet_Editor_Columns::_filter_by_require_capabilities( $columns );
}
self::$unfiltered_columns = array_merge( $columns, self::$unfiltered_columns );
--- a/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/columns-visibility/views/form.php
+++ b/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/columns-visibility/views/form.php
@@ -1,186 +1,202 @@
<?php defined( 'ABSPATH' ) || exit; ?>
-<div data-remodal-id="modal-columns-visibility" data-remodal-options="closeOnOutsideClick: false" class="remodal remodal<?php echo esc_attr($random_id); ?> modal-columns-visibility">
+<div data-remodal-id="modal-columns-visibility" data-remodal-options="closeOnOutsideClick: false" class="remodal remodal<?php echo esc_attr( $random_id ); ?> modal-columns-visibility" x-data="vgseColumnsManager">
<div class="modal-content">
- <?php if (!$partial_form) { ?>
- <form action="<?php echo esc_url(admin_url('admin-ajax.php')); ?>" method="POST" class="vgse-modal-form" data-nonce="<?php echo wp_create_nonce('bep-nonce'); ?>" id="columns-manager-form">
+ <?php if ( ! $partial_form ) { ?>
+ <form action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" method="POST" class="vgse-modal-form"
+ data-nonce="<?php echo wp_create_nonce( 'bep-nonce' ); ?>" id="columns-manager-form" @submit.prevent="submitForm">
<?php } ?>
- <h3><?php _e('Columns manager', 'vg_sheet_editor' ); ?></h3>
+ <h3><?php _e( 'Columns manager', 'vg_sheet_editor' ); ?></h3>
<ul class="unstyled-list">
<li>
- <p><?php _e('Drag the columns to the left or right side to enable/disable them, drag them to the top or bottom to sort them, click on the "edit" button to rename them, click on the "x" button to delete them completely (only when they are disabled previously).', 'vg_sheet_editor' ); ?><?php do_action('vg_sheet_editor/columns_visibility/after_instructions', $post_type, $visible_columns, $options[$post_type], $editor); ?></p>
-
- <!--These options were replaced with the "bulk actions" added to each list-->
- <!--<button class="button vgse-change-all-states" data-to="enabled"><?php _e('Enable all', 'vg_sheet_editor' ); ?></button> --->
- <!--<button class="button vgse-change-all-states" data-to="disabled"><?php _e('Disable all', 'vg_sheet_editor' ); ?></button>-->
-
+ <p><?php _e( 'Drag the columns to the left or right side to enable/disable them, drag them to the top or bottom to sort them, click on the "edit" button to rename them, click on the "x" button to delete them completely (only when they are disabled previously).', 'vg_sheet_editor' ); ?><?php do_action( 'vg_sheet_editor/columns_visibility/after_instructions', $post_type, $visible_columns, $options[ $post_type ], $editor ); ?>
+ </p>
</li>
<li>
<div class="vgse-sorter-section">
- <h3><?php _e('Enabled', 'vg_sheet_editor' ); ?> <button type="button" class="toggle-search-button"><i class="fa fa-edit"></i> <?php _e('Bulk', 'vg_sheet_editor' ); ?></button></h3>
- <div class="wpse-columns-bulk-actions">
- <input type="search" class="wpse-filter-list" placeholder="<?php _e('Enter a search term...', 'vg_sheet_editor' ); ?>">
- <select class="wpse-bulk-action">
- <option value=""><?php _e('Bulk actions', 'vg_sheet_editor' ); ?></option>
- <option value="disable"><?php _e('Disable all', 'vg_sheet_editor' ); ?></option>
- <option value="sort_alphabetically_asc"><?php _e('Sort alphabetically ASC', 'vg_sheet_editor' ); ?></option>
- <option value="sort_alphabetically_desc"><?php _e('Sort alphabetically DESC', 'vg_sheet_editor' ); ?></option>
+ <h3><?php _e( 'Enabled', 'vg_sheet_editor' ); ?> <button @click.prevent="showBulkActions = !showBulkActions; bulkToggleClicked = 'enabled'" type="button"
+
+ class="toggle-search-button"><i class="fa fa-edit"></i>
+ <?php _e( 'Bulk', 'vg_sheet_editor' ); ?></button></h3>
+ <template x-if="showBulkActions">
+ <div class="wpse-columns-bulk-actions" x-init="if(bulkToggleClicked == 'enabled') { $refs.enabledSearchInput.focus()}">
+ <input x-model="enabledSearchTerm" x-ref="enabledSearchInput" type="search" class="wpse-filter-list"
+ placeholder="<?php _e( 'Enter a search term...', 'vg_sheet_editor' ); ?>">
+ <select class="wpse-bulk-action" x-model="enabledBulkAction" @change="handleBulkAction('enabled')">
+ <option value=""><?php _e( 'Bulk actions', 'vg_sheet_editor' ); ?></option>
+ <option value="disable"><?php _e( 'Disable all', 'vg_sheet_editor' ); ?></option>
+ <option value="sort_alphabetically_asc">
+ <?php _e( 'Sort alphabetically ASC', 'vg_sheet_editor' ); ?></option>
+ <option value="sort_alphabetically_desc">
+ <?php _e( 'Sort alphabetically DESC', 'vg_sheet_editor' ); ?></option>
</select>
+ <a href="#" data-wpse-tooltip="right"
+ aria-label="<?php esc_attr_e( 'Select "Disable all" to disable all the columns from the list', 'vg_sheet_editor' ); ?>">(?)</a>
</div>
+ </template>
<ul class="vgse-sorter columns-enabled" id="vgse-columns-enabled">
- <?php
- foreach ($visible_columns as $column_key => $column) {
- if (is_numeric($column_key)) {
- continue;
- }
- if (in_array($column_key, $not_allowed_columns)) {
- continue;
- }
- if (isset($options[$post_type]['disabled']) && isset($options[$post_type]['disabled'][$column_key])) {
- continue;
- }
- if (!isset($column['title'])) {
- continue;
- }
- $title = $column['title'];
- ?>
- <li><span class="handle">::</span> <span class="column-title" title="<?php echo esc_attr($title); ?>"><?php echo esc_html($title); ?></span>
- <input type="hidden" name="columns[]" class="js-column-key" value="<?php echo esc_attr($column_key); ?>" />
- <input type="hidden" name="columns_names[]" class="js-column-title" value="<?php echo esc_attr($title); ?>" />
-
- <?php if( wp_doing_ajax()){ ?>
- <!-- Insert extra buttons here with JS -->
- <?php } else { ?>
- <?php if (VGSE()->helpers->user_can_manage_options()) { ?>
- <button class="remove-column column-action" title="<?php echo esc_attr(__('Remove column completely. If you want to use it later you can disable it by dragging and dropping to the right column', 'vg_sheet_editor' )); ?>"><i class="fa fa-remove"></i></button>
- <?php } ?>
- <button class="deactivate-column column-action" title="<?php echo esc_attr(__('Disable column. You can enable it later.', 'vg_sheet_editor' )); ?>"><i class="fa fa-arrow-right"></i></button>
- <button class="enable-column column-action" title="<?php echo esc_attr(__('Enable column', 'vg_sheet_editor' )); ?>"><i class="fa fa-arrow-left"></i></button>
- <?php } ?>
- <?php do_action('vg_sheet_editor/columns_visibility/enabled/after_column_action', $column, $post_type); ?>
+ <!-- Must use the key with random id to be able to use the sortable() function, otherwise Alpine will reuse DOM elements and lose track of the order -->
+ <template x-for="column in getFilteredEnabledColumns()" :key="column.key + Date.now()">
+ <li><span class="handle">::</span> <span class="column-title" :title="column.title"
+ x-text="column.title"></span>
+ <template x-if="vgse_editor_settings && !vgse_editor_settings.columnsFormat[column.key]">
+ <i class="fa fa-refresh" data-wpse-tooltip="right"
+ aria-label="cm_requires_reload"></i>
+ </template>
+ <input type="hidden" name="columns[]" class="js-column-key" :value="column.key" />
+ <input type="hidden" name="columns_names[]" class="js-column-title"
+ :value="column.title" />
+
+ <button class="deactivate-column column-action"
+ title="<?php echo esc_attr( __( 'Disable column. You can enable it later.', 'vg_sheet_editor' ) ); ?>" @click.prevent="deactivateColumn(column.key)"><i
+ class="fa fa-arrow-right"></i></button>
+ <?php do_action( 'vg_sheet_editor/columns_visibility/enabled/after_column_action_alpine', $post_type ); ?>
+ <div class="clear"></div>
</li>
- <?php }
- ?>
+ </template>
</ul>
</div>
<div class="vgse-sorter-section">
- <h3><?php _e('Disabled', 'vg_sheet_editor' ); ?> <button type="button" class="toggle-search-button"><i class="fa fa-edit"></i> <?php _e('Bulk', 'vg_sheet_editor' ); ?></button></h3>
-
- <div class="wpse-columns-bulk-actions">
- <input type="search" class="wpse-filter-list" placeholder="<?php _e('Enter a search term...', 'vg_sheet_editor' ); ?>">
- <select class="wpse-bulk-action">
- <option value=""><?php _e('Bulk actions', 'vg_sheet_editor' ); ?></option>
- <option value="enable"><?php _e('Enable all', 'vg_sheet_editor' ); ?></option>
- <option value="delete"><?php _e('Delete all', 'vg_sheet_editor' ); ?></option>
- <option value="sort_alphabetically_asc"><?php _e('Sort alphabetically ASC', 'vg_sheet_editor' ); ?></option>
- <option value="sort_alphabetically_desc"><?php _e('Sort alphabetically DESC', 'vg_sheet_editor' ); ?></option>
+ <h3><?php _e( 'Disabled', 'vg_sheet_editor' ); ?> <button @click.prevent="showBulkActions = !showBulkActions; bulkToggleClicked = 'disabled'" type="button"
+ class="toggle-search-button"><i class="fa fa-edit"></i>
+ <?php _e( 'Bulk', 'vg_sheet_editor' ); ?></button></h3>
+
+ <template x-if="showBulkActions">
+ <div class="wpse-columns-bulk-actions" x-init="if(bulkToggleClicked == 'disabled') { $refs.disabledSearchInput.focus() }">
+ <input x-model="disabledSearchTerm" x-ref="disabledSearchInput" type="search" class="wpse-filter-list"
+ placeholder="<?php _e( 'Enter a search term...', 'vg_sheet_editor' ); ?>">
+ <select class="wpse-bulk-action" x-model="disabledBulkAction" @change="handleBulkAction('disabled')">
+ <option value=""><?php _e( 'Bulk actions', 'vg_sheet_editor' ); ?></option>
+ <option value="enable"><?php _e( 'Enable all', 'vg_sheet_editor' ); ?></option>
+ <option value="delete"><?php _e( 'Hide all', 'vg_sheet_editor' ); ?></option>
+ <option value="sort_alphabetically_asc">
+ <?php _e( 'Sort alphabetically ASC', 'vg_sheet_editor' ); ?></option>
+ <option value="sort_alphabetically_desc">
+ <?php _e( 'Sort alphabetically DESC', 'vg_sheet_editor' ); ?></option>
</select>
+ <a href="#" data-wpse-tooltip="right"
+ aria-label="<?php esc_attr_e( 'Select "Enable all" to enable all the columns from the list, "Hide all" to blacklist the columns and stop showing them', 'vg_sheet_editor' ); ?>">(?)</a>
</div>
- <ul class="vgse-sorter columns-disabled" id="vgse-columns-disabled"><?php
- if (isset($options[$post_type]['disabled'])) {
- foreach ($options[$post_type]['disabled'] as $column_key => $column_title) {
- if (is_numeric($column_key)) {
- continue;
- }
- if (in_array($column_key, $not_allowed_columns)) {
- continue;
- }
- $skip_blacklist = isset($columns[$column_key]) && !empty( $columns[$column_key]['skip_blacklist']);
- if (is_object($editor->args['columns']) && $editor->args['columns']->is_column_blacklisted($column_key, $post_type) && !$skip_blacklist ) {
- continue;
- }
- if (isset($columns[$column_key])) {
- $column_title = $columns[$column_key]['title'];
- }
- ?>
- <li><span class="handle">::</span> <span class="column-title" title="<?php echo esc_attr($column_title); ?>"><?php echo esc_html($column_title); ?></span> <i class="fa fa-refresh" data-wpse-tooltip="right" aria-label="cm_requires_reload"></i>
- <input type="hidden" name="disallowed_columns[]" class="js-column-key" value="<?php echo esc_attr($column_key); ?>" />
- <input type="hidden" name="disallowed_columns_names[]" class="js-column-title" value="<?php echo esc_attr($column_title); ?>" />
+ </template>
+ <ul class="vgse-sorter columns-disabled" id="vgse-columns-disabled">
+ <template x-for="column in getFilteredDisabledColumns()" :key="column.key + Date.now()">
+ <li>
+ <span class="handle">::</span> <span class="column-title" :title="column.title"
+ x-text="column.title"></span>
-
- <?php if( wp_doing_ajax()){ ?>
- <!-- Insert extra buttons here with JS -->
- <?php } else { ?>
- <?php if (VGSE()->helpers->user_can_manage_options()) { ?>
- <button class="remove-column column-action" title="<?php echo esc_attr(__('Remove column completely. If you want to use it later you can disable it by dragging and dropping to the right column', 'vg_sheet_editor' )); ?>"><i class="fa fa-remove"></i></button>
- <?php } ?>
- <button class="deactivate-column column-action" title="<?php echo esc_attr(__('Disable column. You can enable it later.', 'vg_sheet_editor' )); ?>"><i class="fa fa-arrow-right"></i></button>
- <button class="enable-column column-action" title="<?php echo esc_attr(__('Enable column', 'vg_sheet_editor' )); ?>"><i class="fa fa-arrow-left"></i></button>
+ <template x-if="vgse_editor_settings && !vgse_editor_settings.columnsFormat[column.key]">
+ <i class="fa fa-refresh" data-wpse-tooltip="right"
+ aria-label="cm_requires_reload"></i>
+ </template>
+ <input type="hidden" name="disallowed_columns[]" class="js-column-key"
+ :value="column.key" />
+ <input type="hidden" name="disallowed_columns_names[]" class="js-column-title"
+ :value="column.title" />
+
+ <?php if ( VGSE()->helpers->user_can_manage_options() ) { ?>
+ <button type="button" class="remove-column column-action"
+ title="<?php echo esc_attr( __( 'The column values will remain in the database, this only excludes/hides the column from the list.', 'vg_sheet_editor' ) ); ?>" @click.prevent="deleteColumn(column.key)"><i
+ class="fa fa-remove"></i></button>
<?php } ?>
- <?php do_action('vg_sheet_editor/columns_visibility/disabled/after_column_action', $column, $post_type); ?>
- </li>
- <?php
- }
- }
- ?></ul>
+ <button class="enable-column column-action"
+ title="<?php echo esc_attr( __( 'Enable column', 'vg_sheet_editor' ) ); ?>" @click.prevent="enableColumn(column.key)"><i
+ class="fa fa-arrow-left"></i></button>
+ <?php do_action( 'vg_sheet_editor/columns_visibility/disabled/after_column_action_alpine', $post_type ); ?>
+ <div class="clear"></div>
+ </li>
+ </template>
+ </ul>
</div>
<div class="clear"></div>
</li>
- <?php if (is_admin() && VGSE()->helpers->user_can_manage_options()) { ?>
- <li class="missing-column-tips">
- <h3><?php _e('A column is missing?', 'vg_sheet_editor' ); ?></h3>
+ <?php if ( is_admin() && VGSE()->helpers->user_can_manage_options() ) { ?>
+ <li class="missing-column-tips" x-data="{showMissingColumnTips: false}">
+ <p><?php _e( 'A column is missing?', 'vg_sheet_editor' ); ?> <a href="#"
+ @click.prevent="showMissingColumnTips = !showMissingColumnTips"><?php _e( 'Read more', 'vg_sheet_editor' ); ?></a>
+ </p>
+
+ <template x-if="showMissingColumnTips">
<ul>
- <li><?php _e('- First, edit one item in the normal editor and fill all the fields manually.', 'vg_sheet_editor' ); ?></li>
+ <li><?php _e( '- First, edit one item in the normal editor and fill all the fields manually.', 'vg_sheet_editor' ); ?>
+ </li>
<?php
- if (empty($options[$post_type]['enabled'])) {
- $options[$post_type]['enabled'] = array();
+ if ( empty( $options[ $post_type ]['enabled'] ) ) {
+ $options[ $post_type ]['enabled'] = array();
}
- if (empty($options[$post_type]['disabled'])) {
- $options[$post_type]['disabled'] = array();
+ if ( empty( $options[ $post_type ]['disabled'] ) ) {
+ $options[ $post_type ]['disabled'] = array();
}
?>
- <li><?php _e('- We can scan the database, find new fields, and create columns automatically', 'vg_sheet_editor' ); ?> <a class="wpse-scan-db-link" href="<?php
- if( wp_doing_ajax() ){
- $rescan_url = add_query_arg(array('wpse_rescan_db_fields' => $post_type), wp_get_referer());
- } else {
- $rescan_url = ( $current_url ) ? add_query_arg(array('wpse_rescan_db_fields' => $post_type), $current_url) : add_query_arg(array('wpse_rescan_db_fields' => $post_type));
- }
- echo esc_url($rescan_url);
- ?>" data-wpse-tooltip="right" aria-label="<?php esc_attr_e('You can do this multiple times', 'vg_sheet_editor' ); ?>"><?php _e('Scan Now', 'vg_sheet_editor' ); ?></a></li>
+ <li><?php _e( '- We can scan the database, find new fields, and create columns automatically', 'vg_sheet_editor' ); ?>
+ <a class="wpse-scan-db-link" href="
+ <?php
+ if ( wp_doing_ajax() ) {
+ $rescan_url = add_query_arg( array( 'wpse_rescan_db_fields' => $post_type ), wp_get_referer() );
+ } else {
+ $rescan_url = ( $current_url ) ? add_query_arg( array( 'wpse_rescan_db_fields' => $post_type ), $current_url ) : add_query_arg( array( 'wpse_rescan_db_fields' => $post_type ) );
+ }
+ echo esc_url( $rescan_url );
+ ?>
+ " data-wpse-tooltip="right"
+ aria-label="<?php esc_attr_e( 'You can do this multiple times', 'vg_sheet_editor' ); ?>"><?php _e( 'Scan Now', 'vg_sheet_editor' ); ?></a>
+ </li>
- <?php
- if (class_exists('WP_Sheet_Editor_Custom_Columns') && VGSE()->helpers->is_editor_page()) {
+ <?php
+ if ( class_exists( 'WP_Sheet_Editor_Custom_Columns' ) && VGSE()->helpers->is_editor_page() ) {
?>
- <li><?php _e('- If the previous solution failed, you can create new columns manually.', 'vg_sheet_editor' ); ?> <a class="" href="<?php echo esc_url(admin_url('admin.php?page=vg_sheet_editor_custom_columns')); ?>"><?php _e('Create column', 'vg_sheet_editor' ); ?></a></li>
+ <li><?php _e( '- If the previous solution failed, you can create new columns manually.', 'vg_sheet_editor' ); ?>
+ <a class=""
+ href="<?php echo esc_url( admin_url( 'admin.php?page=vg_sheet_editor_custom_columns' ) ); ?>"><?php _e( 'Create column', 'vg_sheet_editor' ); ?></a>
+ </li>
<?php } ?>
- <li><?php _e('- Maybe you deleted the columns from the list.', 'vg_sheet_editor' ); ?> <a class="vgse-restore-removed-columns" href="javascript:void(0)"><?php _e('Restore deleted columns', 'vg_sheet_editor' ); ?></a></li>
- <li><?php _e('- We can help you.', 'vg_sheet_editor' ); ?> <a class="" target="_blank" href="<?php echo esc_url(VGSE()->get_support_links('contact_us', 'url', 'sheet-missing-column')); ?>"><?php _e('Contact us', 'vg_sheet_editor' ); ?></a></li>
+ <li><?php _e( '- Maybe you deleted the columns from the list.', 'vg_sheet_editor' ); ?> <a
+ class="vgse-restore-removed-columns"
+ href="#" @click.prevent="restoreDeletedColumns"><?php _e( 'Restore deleted columns', 'vg_sheet_editor' ); ?></a>
+ </li>
+ <li><?php _e( '- We can help you.', 'vg_sheet_editor' ); ?> <a class="" target="_blank"
+ href="<?php echo esc_url( VGSE()->get_support_links( 'contact_us', 'url', 'sheet-missing-column' ) ); ?>"><?php _e( 'Contact us', 'vg_sheet_editor' ); ?></a>
+ </li>
</ul>
- </p>
- </li>
+ </template>
+ </li>
<?php } ?>
<li class="vgse-allow-save-settings">
- <label><input type="checkbox" value="yes" name="save_post_type_settings" class="save_post_type_settings" /> <?php _e('Save these settings for future sessions?', 'vg_sheet_editor' ); ?> <a href="#" data-wpse-tooltip="right" aria-label="If you enable this option, we will use these settings the next time you load the editor for this post type.">( ? )</a></label>
+ <label><input type="checkbox" value="yes" x-model="saveChangesInServer" />
+ <?php _e( 'Save these settings for future sessions?', 'vg_sheet_editor' ); ?> <a href="#"
+ data-wpse-tooltip="right"
+ aria-label="If you enable this option, we will use these settings the next time you load the editor for this post type.">(
+ ? )</a></label>
</li>
- <?php do_action('vg_sheet_editor/columns_visibility/after_fields', $post_type); ?>
+ <?php do_action( 'vg_sheet_editor/columns_visibility/after_fields', $post_type ); ?>
<li class="vgse-save-settings">
- <?php if (!$partial_form) { ?>
- <button type="submit" class="remodal-confirm"><?php _e('Apply settings', 'vg_sheet_editor' ); ?></button>
- <button data-remodal-action="confirm" class="remodal-cancel"><?php _e('Close', 'vg_sheet_editor' ); ?></button>
+ <?php if ( ! $partial_form ) { ?>
+ <button type="submit"
+ class="remodal-confirm"><?php _e( 'Apply settings', 'vg_sheet_editor' ); ?></button>
+ <button data-remodal-action="confirm"
+ class="remodal-cancel"><?php _e( 'Close', 'vg_sheet_editor' ); ?></button>
<?php } ?>
</li>
</ul>
- <input type="hidden" value="<?php echo esc_attr(implode(',', $not_allowed_columns)); ?>" class="not-allowed-columns" name="vgse_columns_disabled_all_keys">
- <input type="hidden" value="" class="all-allowed-columns" name="vgse_columns_enabled_all_keys">
- <?php if (!$partial_form) { ?>
- <input type="hidden" value="vgse_update_columns_visibility" name="action">
- <input type="hidden" value="<?php echo esc_attr($nonce); ?>" name="nonce">
- <input type="hidden" value="<?php echo esc_attr($post_type); ?>" name="post_type">
+ <input type="hidden" value="yes" name="vgse_columns_manager_form">
+ <?php if ( ! $partial_form ) { ?>
+ <input type="hidden" value="vgse_update_columns_visibility" name="action">
+ <input type="hidden" value="<?php echo esc_attr( $nonce ); ?>" name="nonce">
+ <input type="hidden" value="<?php echo esc_attr( $post_type ); ?>" name="post_type">
<?php } ?>
- <input type="hidden" value="<?php echo esc_attr($post_type); ?>" name="wpsecv_post_type">
- <input type="hidden" value="<?php echo esc_attr($nonce); ?>" name="wpsecv_nonce">
+ <input type="hidden" value="<?php echo esc_attr( $post_type ); ?>" name="wpsecv_post_type">
+ <input type="hidden" value="<?php echo esc_attr( $nonce ); ?>" name="wpsecv_nonce">
<input type="hidden" value="" name="wpse_auto_reload_after_saving">
- <?php if (!$partial_form) { ?>
- </form>
+ <?php if ( ! $partial_form ) { ?>
+ </form>
<?php } ?>
</div>
<br>
-</div>
No newline at end of file
+</div>
--- a/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/columns-visibility/views/lazy-form.php
+++ b/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/columns-visibility/views/lazy-form.php
@@ -1,8 +0,0 @@
-<?php defined( 'ABSPATH' ) || exit; ?>
-
-<div data-remodal-id="modal-columns-visibility" data-remodal-options="closeOnOutsideClick: false" class="remodal remodal<?php echo esc_attr( $random_id ); ?> modal-columns-visibility lazy-modal-columns-visibility">
-
-<div class="modal-content">
-
- </div>
-</div>
--- a/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/filters/filters.php
+++ b/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/filters/filters.php
@@ -6,7 +6,7 @@
*/
class WP_Sheet_Editor_Filters {
- private static $instance = false;
+ private static $instance = null;
var $plugin_url = null;
var $plugin_dir = null;
@@ -201,10 +201,11 @@
$editor->args['toolbars']->register_item(
'column_locator',
array(
- 'type' => 'html',
- 'help_tooltip' => __( 'Enter a word and we will find the first matching column. You will avoid scrolling through dozens of columns to find the one you need.', 'vg_sheet_editor' ),
- 'content' => '<input type="search" id="column-locator-input" placeholder="' . __( 'Locate column', 'vg_sheet_editor' ) . '"/>',
- 'label' => __( 'Locate column', 'vg_sheet_editor' ),
+ 'type' => 'html',
+ 'help_tooltip' => __( 'Enter a word and we will find the first matching column. You will avoid scrolling through dozens of columns to find the one you need.', 'vg_sheet_editor' ),
+ 'content' => '<input type="search" id="column-locator-input" list="column-locator-dropdown" placeholder="' . __( 'Locate column', 'vg_sheet_editor' ) . '"/>',
+ 'label' => __( 'Locate column', 'vg_sheet_editor' ),
+ 'tooltip_position' => 'right',
),
$post_type
);
@@ -330,7 +331,8 @@
$columns = VGSE()->helpers->get_unfiltered_provider_columns( $post_type );
}
$is_date_filter = isset( $columns[ $meta_query['key'] ] ) && $columns[ $meta_query['key'] ]['value_type'] === 'date';
- if ( $is_date_filter ) {
+ $formatted_str = isset( $columns[ $meta_query['key'] ] ) && isset( $columns[ $meta_query['key'] ]['formatted'] ) ? serialize( array_keys( $columns[ $meta_query['key'] ]['formatted'] ) ) : '';
+ if ( $is_date_filter && preg_match( '(customDatabaseFormat|dateFormatPhp)', $formatted_str ) ) {
$date_format_for_db = isset( $columns[ $meta_query['key'] ]['formatted']['customDatabaseFormat'] ) ? $columns[ $meta_query['key'] ]['formatted']['customDatabaseFormat'] : $columns[ $meta_query['key'] ]['formatted']['dateFormatPhp'];
}
if ( empty( $date_format_for_db ) ) {
--- a/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/init.php
+++ b/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/init.php
@@ -154,7 +154,7 @@
}
// WPML : Change language to english when we load the spreadsheet page
if ( !function_exists( 'vgse_filter_wpml_admin_language' ) ) {
- if ( isset( $_GET['page'] ) && strpos( $_GET['page'], 'vgse-bulk-edit-' ) !== false && strpos( json_encode( $_COOKIE ), '_icl_' ) !== false ) {
+ if ( isset( $_GET['page'] ) && strpos( $_GET['page'], 'vgse-bulk-edit-' ) !== false && !empty( $_COOKIE ) && strpos( json_encode( $_COOKIE ), '_icl_' ) !== false ) {
add_filter(
'get_user_metadata',
'vgse_filter_wpml_admin_language',
--- a/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/user-path/user-path.php
+++ b/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/user-path/user-path.php
@@ -1,137 +0,0 @@
-<?php
-
-if (!class_exists('WPSE_User_Path')) {
-
- /**
- * Note to reviewers. This class saves in the database the last 100 admin pages
- * related to this plugin used by the administrator (either when the admin opens
- * a page with a slug from this plugin or opens a admin URL containing a identifier as query string.
- *
- * This information is intended to be used to build a little activity profile and customize
- * the experience on the site (hide features that the admin rarely uses, for example).
- *
- * This information never leaves your server when you are using the free version hosted on wp.org
- * , it's just a bunch of activity data stored in your database and used by the plugin locally
- */
- class WPSE_User_Path {
-
- var $args = null;
-
- function __construct($args = array()) {
- if (!is_user_logged_in() || !current_user_can('manage_options')) {
- return;
- }
-
- $defaults = array(
- 'user_id' => get_current_user_id(),
- 'user_path_key' => null,
- 'is_free' => null, // bool
- );
- $this->args = wp_parse_args($args, $defaults);
-
- if ((int) get_option('vgse_user_path_sent')) {
- delete_option($this->args['user_path_key'] . '_user_path');
- return;
- }
-
- $this->register_page_open();
- $this->register_trigger_used();
- $this->register_ajax_used();
-
- do_action('wpse_user_path_init', $this);
- }
-
- function register_ajax_used() {
- if (!defined('DOING_AJAX') || !DOING_AJAX || empty($_REQUEST['action']) || strpos($_REQUEST['action'], 'vgse') === false) {
- return;
- }
- $this->register_event(array(
- 'eventAction' => 'ajax',
- 'eventLabel' => sanitize_text_field($_REQUEST['action']),
- ));
- }
-
- function register_trigger_used() {
- if (empty($_GET['vgseup_t'])) {
- return;
- }
- $this->register_event(array(
- 'eventAction' => 'click',
- 'eventLabel' => sanitize_text_field($_GET['vgseup_t']),
- ));
- }
-
- function register_page_open() {
- $pages_to_load_assets = VGSE()->frontend_assets_allowed_on_pages();
- if (empty($_GET['page']) ||
- !in_array($_GET['page'], $pages_to_load_assets)) {
- return;
- }
-
- $this->register_event(array(
- 'eventAction' => 'open',
- 'eventLabel' => sanitize_text_field($_GET['page']),
- ));
- }
-
- function get_events($user_id = null) {
- if (!$user_id) {
- $user_id = $this->args['user_id'];
- }
-
- $events = get_option($this->args['user_path_key'] . '_user_path', array());
- if (!is_array($events)) {
- $events = array();
- }
- if (!isset($events[$this->args['user_id']])) {
- $events[$this->args['user_id']] = array();
- }
- return $events;
- }
-
- function register_event($args = array()) {
- $defaults = array(
- 'hitType' => 'event',
- 'eventCategory' => ($this->args['is_free'] ? 'Free' : 'Paid') . ' - ' . sanitize_text_field($_SERVER['HTTP_HOST']),
- 'eventAction' => '',
- 'eventLabel' => '',
- 'eventValue' => date('YmdHis', current_time('timestamp')),
- 'vgStatus' => 0
- );
- $args = apply_filters('vg_sheet_editor/user_path/event_data', wp_parse_args($args, $defaults), $this);
-
- if (empty($args['eventLabel'])) {
- return;
- }
-
- $events = $this->get_events();
- $events[$this->args['user_id']][] = $args;
-
- $is_event_repeated_much = count(wp_list_filter($events[$this->args['user_id']], array(
- 'eventLabel' => $args['eventLabel']
- ))) > 5;
-
- // If the same event happened more than 5 times, we don't register it to
- // avoid crossing the 100 events limit with the same type of events
- if ($is_event_repeated_much) {
- return;
- }
-
- // Save only the last 100 items
- $events[$this->args['user_id']] = array_slice($events[$this->args['user_id']], -100, 100);
- update_option($this->args['user_path_key'] . '_user_path', $events, false);
- }
-
- }
-
-}
-
-
-$inc_files = glob(__DIR__ . '/*.php');
-foreach ($inc_files as $inc_file) {
- if (!is_file($inc_file)) {
- continue;
- }
-
- require_once $inc_file;
-}
No newline at end of file
--- a/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/wp-sheet-editor/inc/ajax.php
+++ b/wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages/modules/wp-sheet-editor/inc/ajax.php
@@ -1,647 +1,649 @@
-<?php defined( 'ABSPATH' ) || exit;
-
-if ( ! class_exists( 'WP_Sheet_Editor_Ajax' ) ) {
-
- class WP_Sheet_Editor_Ajax {
-
- private static $instance = false;
-
- private function __construct() {
-
- }
-
- /*
- * Controller for loading posts to the spreadsheet
- */
-
- function delete_row_ids() {
-
- $error_message = array( 'message' => __( 'You dont have enough permissions to do this action.', 'vg_sheet_editor' ) );
- if ( empty( $_REQUEST['post_type'] ) || empty( VGSE()->helpers->get_nonce_from_request() ) || empty( $_REQUEST['ids'] ) || ! VGSE()->helpers->verify_nonce_from_request() ) {
- wp_send_json_error( $error_message );
- }
- $post_type = VGSE()->helpers->sanitize_table_key( $_REQUEST['post_type'] );
- if ( ! VGSE()->helpers->user_can_edit_post_type( $post_type ) || ! VGSE()->helpers->user_can_delete_post_type( $post_type ) ) {
- wp_send_json_error( $error_message );
- }
- $row_ids = array_map( 'intval', $_REQUEST['ids'] );
- $row_ids = VGSE()->helpers->get_current_provider()->filter_rows_before_edit( $row_ids, $post_type );
-
- foreach ( $row_ids as $id ) {
- VGSE()->helpers->get_current_provider()->update_item_data(
- array(
- 'ID' => (int) $id,
- 'post_status' => 'delete',
- 'wpse_status' => 'delete',
- 'comment_approved' => 'delete',
- )
- );
- }
- wp_send_json_success( array( 'message' => __( 'Rows deleted successfully', 'vg_sheet_editor' ) ) );
- }
-
- function get_taxonomy_terms() {
-
- $error_message = array( 'message' => __( 'You dont have enough permissions to do this action.', 'vg_sheet_editor' ) );
- if ( empty( $_REQUEST['post_type'] ) || empty( VGSE()->helpers->get_nonce_from_request() ) || ! VGSE()->helpers->verify_nonce_from_request() ) {
- wp_send_json_error( $error_message );
- }
-
- $post_type = VGSE()->helpers->sanitize_table_key( $_REQUEST['post_type'] );
- // If this is a WC attribute, use WC's sanitization function
- if ( class_exists( 'WooCommerce' ) && strpos( $_REQUEST['taxonomy_key'], 'pa_' ) === 0 ) {
- $taxonomy_key = wc_sanitize_taxonomy_name( $_REQUEST['taxonomy_key'] );
- } else {
- $taxonomy_key = VGSE()->helpers->sanitize_table_key( $_REQUEST['taxonomy_key'] );
- }
- if ( ! VGSE()->helpers->user_can_view_post_type( $post_type ) || ! taxonomy_exists( $taxonomy_key ) ) {
- wp_send_json_error( $error_message );
- }
-
- $source = ( ! empty( $_REQUEST['wpse_source'] ) ) ? sanitize_text_field( $_REQUEST['wpse_source'] ) : '';
- $out = VGSE()->data_helpers->get_taxonomy_terms( $taxonomy_key, $source );
-
- if ( is_array( $out ) ) {
- $out = array_map( 'html_entity_decode', $out );
-
- $search_term = ( ! empty( $_REQUEST['search'] ) ) ? html_entity_decode( sanitize_text_field( $_REQUEST['search'] ) ) : '';
- if ( ! empty( $search_term ) ) {
- foreach ( $out as $index => $term ) {
- if ( stripos( $term, $search_term ) === false ) {
- unset( $out[ $index ] );
- }
- }
- }
- $out = array_values( $out );
- }
- wp_send_json_success( $out );
- }
-
- function load_rows() {
-
- if ( empty( $_REQUEST['post_type'] ) || empty( VGSE()->helpers->get_nonce_from_request() ) ) {
- wp_send_json_error( array( 'message' => __( 'Missing parameters.', 'vg_sheet_editor' ) ) );
- }
- if ( ! VGSE()->helpers->verify_nonce_from_request() || ! VGSE()->helpers->user_can_view_post_type( $_REQUEST['post_type'] ) ) {
- $message = array( 'message' => __( 'You dont have enough permissions to load rows.', 'vg_sheet_editor' ) );
- wp_send_json_error( $message );
- }
-
- $request_data = array(
- 'nonce' => sanitize_text_field( VGSE()->helpers->get_nonce_from_request() ),
- 'post_type' => VGSE()->helpers->sanitize_table_key( $_REQUEST['post_type'] ),
- 'paged' => isset( $_REQUEST['paged'] ) ? intval( $_REQUEST['paged'] ) : 1,
- 'posts_per_page' => isset( $_REQUEST['posts_per_page'] ) ? intval( $_REQUEST['posts_per_page'] ) : 0,
- 'wpse_reset_posts_per_page' => isset( $_REQUEST['wpse_reset_posts_per_page'] ) ? (int) $_REQUEST['wpse_reset_posts_per_page'] : 0,
- 'wpse_source_suffix' => isset( $_REQUEST['wpse_source_suffix'] ) ? sanitize_text_field( $_REQUEST['wpse_source_suffix'] ) : '',
- 'wpse_source' => isset( $_REQUEST['wpse_source'] ) ? sanitize_text_field( $_REQUEST['wpse_source'] ) : '',
- 'filters' => vgse_filters_init()->get_raw_filters(),
- );
- // Reset the number of rows per page, we receive this parameter from the client when
- // the current rows per page > 300 and the request failed
- if ( ! empty( $request_data['wpse_reset_posts_per_page'] ) ) {
- VGSE()->update_option( 'be_posts_per_page', (int) $request_data['wpse_reset_posts_per_page'] );
- }
-
- $source_prefix = ( ! empty( $request_data['wpse_source_suffix'] ) ) ? (string) $request_data['wpse_source_suffix'] : '';
- $request_data['wpse_source'] = 'load_rows' . $source_prefix;
-
- $rows = VGSE()->helpers->get_rows( $request_data );
-
- if ( is_wp_error( $rows ) ) {
- wp_send_json_error(
- wp_parse_args(
- array(
- 'message' => $rows->get_error_message(),
- ),
- $rows->get_error_data()
- )
- );
- }
-
- $rows['rows'] = array_values( $rows['rows'] );
- $rows['deleted'] = array_unique( VGSE()->deleted_rows_ids );
- wp_send_json_success( $rows );
- }
-
- /*
- * Controller for saving posts changes
- */
-
- function save_rows() {
- if ( empty( $_REQUEST['post_type'] ) || empty( VGSE()->helpers->get_nonce_from_request() ) || ! VGSE()->helpers->verify_sheet_permissions_from_request( 'edit' ) || ! VGSE()->helpers->verify_nonce_from_request() ) {
- wp_send_json_error( array( 'message' => __( 'You dont have enough permissions to save changes.', 'vg_sheet_editor' ) ) );
- }
- $params = array(
- 'nonce' => sanitize_text_field( VGSE()->helpers->get_nonce_from_request() ),
- 'post_type' => VGSE()->helpers->sanitize_table_key( $_REQUEST['post_type'] ),
- 'allow_to_create_new' => ! empty( $_REQUEST['allow_to_create_new'] ),
- 'wpse_source' => isset( $_REQUEST['wpse_source'] ) ? sanitize_text_field( $_REQUEST['wpse_source'] ) : null,
- 'filters' => vgse_filters_init()->get_raw_filters(),
- );
- $params['data'] = VGSE()->helpers->sanitize_data_for_db( $_REQUEST['data'], $params['post_type'] );
-
- $result = VGSE()->helpers->save_rows( $params );
-
- if ( is_wp_error( $result ) ) {
- wp_send_json_error(
- array(
- 'message' => $result->get_error_message(),
- )
- );
- }
-
- // We use this flag to customize the user experience and hide some notifications for people that already learned how to use the sheet
- update_user_meta( get_current_user_id(), 'wpse_has_saved_sheet', 1 );
- wp_send_json_success(
- array(
- 'message' => __( 'Changes saved successfully', 'vg_sheet_editor' ),
- 'deleted' => array_unique( VGSE()->deleted_rows_ids ),
- )
- );
- }
-
- /*
- * Controller for saving new post.
- */
-
- function insert_individual_post() {
- if ( empty( $_REQUEST['post_type'] ) || empty( $_REQUEST['rows'] ) || empty( VGSE()->helpers->get_nonce_from_request() ) ) {
- wp_send_json_error( array( 'message' => __( 'Missing parameters.', 'vg_sheet_editor' ) ) );
- }
- if ( ! VGSE()->helpers->verify_nonce_from_request() || ! VGSE()->helpers->verify_sheet_permissions_from_request( 'edit' ) ) {
- wp_send_json_error( array( 'message' => __( 'You dont have enough permissions to create new rows.', 'vg_sheet_editor' ) ) );
- }
- $post_type = VGSE()->helpers->sanitize_table_key( $_REQUEST['post_type'] );
- $rows = (int) $_REQUEST['rows'];
- $dont_return_new_rows = ! empty( $_REQUEST['dont_return_new_rows'] ) && $_REQUEST['dont_return_new_rows'] === 'yes';
-
- $result = VGSE()->helpers->create_placeholder_posts( $post_type, $rows, $dont_return_new_rows ? 'ids' : 'rows' );
- if ( $dont_return_new_rows ) {
- $result = array();
- }
-
- if ( is_wp_error( $result ) ) {
- wp_send_json_error(
- array(
- 'message' => $result->get_error_message(),
- )
- );
- }
- wp_send_json_success(
- array(
- 'message' => $result,
- 'deleted' => array_unique( VGSE()->deleted_rows_ids ),
- )
- );
- }
-
- function list_posts_by_title() {
- global $wpdb;
-
- if ( empty( $_REQUEST['search_post_type'] ) || empty( VGSE()->helpers->get_nonce_from_request() ) ) {
- wp_send_json_error( array( 'message' => __( 'Missing parameters.', 'vg_sheet_editor' ) ) );
- }
- $post_type = VGSE()->helpers->sanitize_table_key( $_REQUEST['search_post_type'] );
-
- if ( ! VGSE()->helpers->verify_nonce_from_request() || ! VGSE()->helpers->user_can_view_post_type( $post_type ) ) {
- wp_send_json_error( array( 'message' => __( 'Request not allowed. Try again later.', 'vg_sheet_editor' ) ) );
- }
-
- $titles = $wpdb->get_col( $wpdb->prepare( "SELECT post_title FROM $wpdb->posts WHERE post_type = %s LIMIT 500", $post_type ) );
-
- wp_send_json_success( array( 'data' => $titles ) );
- }
-
- /**
- * Find posts by name
- */
- function find_post_by_name() {
- global $wpdb;
-
- if ( empty( $_REQUEST['post_type'] ) || empty( $_REQUEST['search'] ) || empty( VGSE()->helpers->get_nonce_from_request() ) ) {
- wp_send_json_error( array( 'message' => __( 'Missing parameters.', 'vg_sheet_editor' ) ) );
- }
- $post_type = VGSE()->helpers->sanitize_table_key( $_REQUEST['post_type'] );
- $search = sanitize_text_field( wp_unslash( html_entity_decode( $_REQUEST['search'], ENT_QUOTES ) ) );
-
- if ( ! VGSE()->helpers->verify_nonce_from_request() || ! VGSE()->helpers->user_can_view_post_type( $post_type ) ) {
- wp_send_json_error( array( 'message' => __( 'Request not allowed. Try again later.', 'vg_sheet_editor' ) ) );
- }
-
- $where = ' post_type = %s AND (post_title LIKE %s ';
- $prepared_data = array( $post_type, '%' . $wpdb->esc_like( $search ) . '%' );
- $join = '';
- if ( $post_type === 'product' && class_exists( 'WooCommerce' ) ) {
- $where .= ' OR lookup.sku = %s ';
- $prepared_data[] = $search;
- $join = " LEFT JOIN {$wpdb->prefix}wc_product_meta_lookup lookup ON {$wpdb->posts}.ID = lookup.product_id ";
- }
- if ( is_numeric( $search ) ) {
- $where .= ' OR ID = %d ';
- $prepared_data[] = (int) $search;
- }
- $where .= ') ';
- $sql = apply_filters( 'vg_sheet_editor/find_post_by_name_sql', $wpdb->prepare( "SELECT * FROM $wpdb->posts $join WHERE " . $where . ' LIMIT 10', $prepared_data ), $search, $post_type );
- $posts_found = $wpdb->get_results( $sql );
-
- if ( empty( $posts_found ) ) {
- wp_send_json_error( array( 'message' => __( 'No items found.', 'vg_sheet_editor' ) ) );
- }
-
- $out = array();
- foreach ( $posts_found as $post ) {
- $out[] = array(
- 'id' => $post->post_type . '--' . $post->ID,
- 'text' => $post->post_title . ' ( ID: ' . $post->ID . ', ' . $post->post_type . ' )',
- 'title' => $post->post_title,
- );
- }
- wp_send_json_success( array( 'data' => $out ) );
- }
-
- /**
- * Controller for saving individual field of post
- */
- function save_single_post_data() {
- if ( empty( $_REQUEST['post_id'] ) || empty( $_REQUEST['key'] ) || empty( VGSE()->helpers->get_nonce_from_request() ) || empty( $_REQUEST['type'] ) || empty( $_REQUEST['post_type'] ) ) {
- wp_send_json_error( array( 'message' => __( 'Missing parameters.', 'vg_sheet_editor' ) ) );
- }
- if ( ! VGSE()->helpers->verify_nonce_from_request() ) {
- wp_send_json_error( array( 'message' => __( 'You dont have enough permissions to save changes.', 'vg_sheet_editor' ) ) );
- }
- $post_type = VGSE()->helpers->sanitize_table_key( $_REQUEST['post_type'] );
- if ( ! VGSE()->helpers->user_can_edit_post_type( $post_type ) ) {
- wp_send_json_error( array( 'message' => __( 'You dont have enough permissions to save changes.', 'vg_sheet_editor' ) ) );
- }
- $content = wp_kses_post( html_entity_decode( $_REQUEST['content'] ) );
- $id = (int) $_REQUEST['post_id'];
- $key = sanitize_text_field( $_REQUEST['key'] );
- $type = sanitize_text_field( $_REQUEST['type'] );
-
- if ( VGSE()->options['be_disable_post_actions'] ) {
- $post_type = get_post_type( $id );
- VGSE()->helpers->remove_all_post_actions( $post_type );
- }
-
- do_action( 'vg_sheet_editor/save_single_post_data/before', $id, $content, $key, $type );
- $result = VGSE()->data_helpers->save_single_post_data( $id, $content, $key, $type );
-
- do_action( 'vg_sheet_editor/save_single_post_data/after', $result, $id, $content, $key, $type );
- if ( is_wp_error( $result ) ) {
-
- $errors = $result->get_error_messages();
- wp_send_json_success( array( 'message' => sprintf( __( 'Error: %s', 'vg_sheet_editor' ), implode( ', ', $errors ) ) ) );
- } else {
- VGSE()->helpers->increase_counter( 'editions' );
- VGSE()->helpers->increase_counter( 'processed' );
-
- $title = VGSE()->data_helpers->get_post_data( 'post_title', $id );
- wp_send_json_success( array( 'message' => sprintf( __( 'Saved: %s', 'vg_sheet_editor' ), $title ) ) );
- }
- }
-
- function search_users_select2() {
- $_REQUEST['include_ids'] = 'yes';
- return $this->search_users();
- }
- /**
- * Search taxonomy term
- * @global obj $wpdb
- */
- function search_users() {
- global $wpdb;
- if ( empty( $_REQUEST['search'] ) || empty( VGSE()->helpers->get_nonce_from_request() ) || empty( $_REQUEST['post_type'] ) ) {
- wp_send_json_error( array( 'message' => __( 'Missing parameters.', 'vg_sheet_editor' ) ) );
- }
-
- if ( ! VGSE()->helpers->verify_nonce_from_request() || ! VGSE()->helpers->user_can_view_post_type( $_REQUEST['post_type'] ) ) {
- wp_send_json_error( array( 'message' => __( 'You dont have enough permissions to search taxonomy terms.', 'vg_sheet_editor' ) ) );
- }
- $search = sanitize_text_field( $_REQUEST['search'] );
- $include_ids = ! empty( $_REQUEST['include_ids'] );
-
- if ( $include_ids ) {
- $rows = $wpdb->get_results( $wpdb->prepare( "SELECT ID,user_login FROM $wpdb->users WHERE user_email LIKE %s OR user_nicename LIKE %s OR user_login LIKE %s OR display_name LIKE %s LIMIT 5", '%' . $wpdb->esc_like( $search ) . '%', '%' . $wpdb->esc_like( $search ) . '%', '%' . $wpdb->esc_like( $search ) . '%', '%' . $wpdb->esc_like( $search ) . '%' ) );
- $out = wp_list_pluck( $rows, 'user_login', 'ID' );
- } else {
- $out = $wpdb->get_col( $wpdb->prepare( "SELECT user_login FROM $wpdb->users WHERE user_email LIKE %s OR user_nicename LIKE %s OR user_login LIKE %s OR display_name LIKE %s LIMIT 5", '%' . $wpdb->esc_like( $search ) . '%', '%' . $wpdb->esc_like( $search ) . '%', '%' . $wpdb->esc_like( $search ) . '%', '%' . $wpdb->esc_like( $search ) . '%' ) );
- }
- wp_send_json_success( array( 'data' => $out ) );
- }
-
- function search_taxonomy_terms() {
- global $wpdb;
- if ( empty( $_REQUEST['search'] ) || empty( VGSE()->helpers->get_nonce_from_request() ) || empty( $_REQUEST['post_type'] ) ) {
- wp_send_json_error( array( 'message' => __( 'Missing parameters.', 'vg_sheet_editor' ) ) );
- }
-
- $post_type = VGSE()->helpers->sanitize_table_key( $_REQUEST['post_type'] );
- $is_global_search = ! empty( $_REQUEST['global_search'] );
-
- // Note. The global search is allowed for administrators only
- if ( ! VGSE()->helpers->verify_nonce_from_request() || ( ! $is_global_search && ! VGSE()->helpers->user_can_view_post_type( $post_type ) ) || ( $is_global_search && ! VGSE()->helpers->user_can_manage_options() ) ) {
- wp_send_json_error( array( 'message' => __( 'You dont have enough permissions to search taxonomy terms.', 'vg_sheet_editor' ) ) );
- }
-
- $search = wp_unslash( sanitize_text_field( $_REQUEST['search'] ) );
- $output_format = ( isset( $_REQUEST['output_format'] ) ) ? sanitize_text_field( $_REQUEST['output_format'] ) : '';
-
- if ( $is_global_search ) {
- $taxonomies = get_taxonomies(
- array(
- 'show_ui' => true,
- 'hierarchical' => true,
- ),
- 'names'
- );
- } else {
- $taxonomies = VGSE()->helpers->get_post_type_taxonomies_single_data( $post_type, 'name' );
- }
-
- if ( ! empty( $_REQUEST['taxonomies'] ) ) {
- $taxonomies = is_string( $_REQUEST['taxonomies'] ) ? explode( ',', sanitize_text_field( $_REQUEST['taxonomies'] ) ) : array_map( 'sanitize_text_field', $_REQUEST['taxonomies'] );
- }
-
- if ( empty( $taxonomies ) ) {
- wp_send_json_error( array( 'message' => __( 'No taxonomies found.', 'vg_sheet_editor' ) ) );
- }
-
- $taxonomies_in_query_placeholders = implode( ', ', array_fill( 0, count( $taxonomies ), '%s' ) );
- $sql = $wpdb->prepare( "SELECT term.slug id,term.name text,tax.taxonomy taxonomy, term.slug slug FROM $wpdb->term_taxonomy as tax JOIN $wpdb->terms as term ON term.term_id = tax.term_id WHERE tax.taxonomy IN ($taxonomies_in_query_placeholders) AND term.name LIKE %s ", array_merge( $taxonomies, array( '%' . $wpdb->esc_like( $search ) . '%' ) ) );
- $results = $wpdb->get_results( $sql, ARRAY_A );
-
- if ( ! $results || is_wp_error( $results ) ) {
- $results = array();
- }
-
- if ( empty( $output_format ) ) {
- $output_format = '%taxonomy%--%slug%';
- } else {
- $output_format = sanitize_text_field( $output_format );
- }
- $taxonomies_labels = array();
- $out = array();
- foreach ( $results as $result ) {
-
- if ( ! isset( $taxonomies_labels[ $result['taxonomy'] ] ) ) {
- $tmp_tax = get_taxonomy( $result['taxonomy'] );
- $label = ( $tmp_tax->label === __( 'Tags' ) && $tmp_tax->name !== 'post_tag' ) ? $tmp_tax->name : $tmp_tax->label;
- $taxonomies_labels[ $result['taxonomy'] ] = $label;
- }
-
- $output_key = strtr(
- $output_format,
- array(
- '%name%' => $result['text'],
- '%taxonomy%' => $result['taxonomy'],
- '%slug%' => $result['id'],
- )
- );
- $out[] = array(
- 'id' => $output_key,
- 'text' => $result['text'] . ' ( ' . $taxonomies_labels[ $result['taxonomy'] ] . ', ' . urldecode( $result['slug'] ) . ' )',
- );
- }
- wp_send_json_success( array( 'data' => $out ) );
- }
-
- /**
- * Enable the spreadsheet editor on some post types
- */
- function save_post_types_setting() {
- if ( empty( VGSE()->helpers->get_nonce_from_request() ) || empty( $_REQUEST['post_types'] ) || empty( $_REQUEST['append'] ) ) {
- wp_send_json_error( array( 'message' => __( 'Missing parameters.', 'vg_sheet_editor' ) ) );
- }
- if ( ! VGSE()->helpers->verify_nonce_from_request() || ! VGSE()->helpers->user_can_manage_options() ) {
- wp_send_json_error( array( 'message' => __( 'You dont have enough permissions to perform this action.', 'vg_sheet_editor' ) ) );
- }
- $post_types = array_map( array( VGSE()->helpers, 'sanitize_table_key' ), $_REQUEST['post_types'] );
- $append = sanitize_text_field( $_REQUEST['append'] );
-
- $settings = get_option( VGSE()->options_key, array() );
- if ( empty( $settings['be_post_types'] ) ) {
- $settings['be_post_types'] = array();
- }
-
- if ( $append === 'yes' ) {
- $new_post_types = array_unique( array_merge( $settings['be_post_types'], $post_types ) );
- } else {
- $new_post_types = $post_types;
- }
- $settings['be_post_types'] = $new_post_types;
-
- update_option( VGSE()->options_key, $settings, false );
-
- do_action( 'vg_sheet_editor/quick_setup/post_types_saved/after', $new_post_types );
-
- wp_send_json_success();
- }
-
- function save_gutenberg_content() {
- $_REQUEST['content'] = wp_kses_post( $_REQUEST['data'] );
- $_REQUEST['post_id'] = (int) $_REQUEST['postId'];
- $_REQUEST['post_type'] = VGSE()->helpers->sanitize_table_key( $_REQUEST['postType'] );
- $_REQUEST['type'] = 'post_dat