/**
  * Return the live preview data of table that has non-saved changes.
  *
  * @since 1.0.0
  */
 public function ajax_action_preview_table()
 {
     if (empty($_POST['tablepress']) || empty($_POST['tablepress']['id'])) {
         wp_die('-1');
     } else {
         $preview_table = wp_unslash($_POST['tablepress']);
     }
     // Check if the submitted nonce matches the generated nonce we created earlier, dies -1 on failure.
     TablePress::check_nonce('preview_table', $preview_table['id'], '_ajax_nonce', true);
     // Ignore the request if the current user doesn't have sufficient permissions.
     if (!current_user_can('tablepress_preview_table', $preview_table['id'])) {
         wp_die('-1');
     }
     // Default response data.
     $success = false;
     do {
         // to be able to "break;" (allows for better readable code)
         // Load table, without table data, but with options and visibility settings.
         $existing_table = TablePress::$model_table->load($preview_table['id'], false, true);
         if (is_wp_error($existing_table)) {
             // maybe somehow load a new table here? (TablePress::$model_table->get_table_template())?
             break;
         }
         // Check and convert data that was transmitted as JSON.
         if (empty($preview_table['data']) || empty($preview_table['options']) || empty($preview_table['visibility'])) {
             break;
         }
         $preview_table['data'] = (array) json_decode($preview_table['data'], true);
         $preview_table['options'] = (array) json_decode($preview_table['options'], true);
         $preview_table['visibility'] = (array) json_decode($preview_table['visibility'], true);
         // Check consistency of new table, and then merge with existing table.
         $table = TablePress::$model_table->prepare_table($existing_table, $preview_table, true, true);
         if (is_wp_error($table)) {
             break;
         }
         // DataTables Custom Commands can only be edit by trusted users.
         if (!current_user_can('unfiltered_html')) {
             $table['options']['datatables_custom_commands'] = $existing_table['options']['datatables_custom_commands'];
         }
         // If the ID has changed, and the new ID is valid, render with the new ID (important e.g. for CSS classes/HTML ID).
         if ($table['id'] !== $table['new_id'] && 0 === preg_match('/[^a-zA-Z0-9_-]/', $table['new_id'])) {
             $table['id'] = $table['new_id'];
         }
         // Sanitize all table data to remove unsafe HTML from the preview output.
         $table = TablePress::$model_table->sanitize($table);
         // At this point, the table data is valid and sanitized and can be rendered.
         $success = true;
     } while (false);
     // Do-while-loop through this exactly once, to be able to "break;" early.
     // Initialize i18n support, load plugin's textdomain, to retrieve correct translations for the description of the preview.
     load_plugin_textdomain('tablepress', false, dirname(TABLEPRESS_BASENAME) . '/i18n');
     if ($success) {
         // Create a render class instance.
         $_render = TablePress::load_class('TablePress_Render', 'class-render.php', 'classes');
         // Merge desired options with default render options (see TablePress_Controller_Frontend::shortcode_table()).
         $default_render_options = $_render->get_default_render_options();
         /** This filter is documented in controllers/controller-frontend.php */
         $default_render_options = apply_filters('tablepress_shortcode_table_default_shortcode_atts', $default_render_options);
         $render_options = shortcode_atts($default_render_options, $table['options']);
         /** This filter is documented in controllers/controller-frontend.php */
         $render_options = apply_filters('tablepress_shortcode_table_shortcode_atts', $render_options);
         $_render->set_input($table, $render_options);
         $head_html = $_render->get_preview_css();
         $custom_css = TablePress::$model_options->get('custom_css');
         if (!empty($custom_css)) {
             $head_html .= "<style type=\"text/css\">\n{$custom_css}\n</style>\n";
         }
         $body_html = '<div id="tablepress-page"><p>' . __('This is a preview of your table.', 'tablepress') . ' ' . __('Because of CSS styling in your theme, the table might look different on your page!', 'tablepress') . ' ' . __('The features of the DataTables JavaScript library are also not available or visible in this preview!', 'tablepress') . '<br />' . sprintf(__('To insert the table into a page, post, or text widget, copy the Shortcode %s and paste it into the editor.', 'tablepress'), '<input type="text" class="table-shortcode table-shortcode-inline" value="' . esc_attr('[' . TablePress::$shortcode . " id={$table['id']} /]") . '" readonly="readonly" />') . '</p>' . $_render->get_output() . '</div>';
     } else {
         $head_html = '';
         $body_html = __('The preview could not be loaded.', 'tablepress');
     }
     // Generate the response.
     $response = array('success' => $success, 'head_html' => $head_html, 'body_html' => $body_html);
     // Buffer all outputs, to prevent errors/warnings being printed that make the JSON invalid.
     $output_buffer = ob_get_clean();
     if (!empty($output_buffer)) {
         $response['output_buffer'] = $output_buffer;
     }
     // Send the response.
     wp_send_json($response);
 }
 /**
  * Uninstall TablePress, and delete all tables and options.
  *
  * @since 1.0.0
  */
 public function handle_get_action_uninstall_tablepress()
 {
     TablePress::check_nonce('uninstall_tablepress');
     $plugin = TABLEPRESS_BASENAME;
     if (!current_user_can('activate_plugins') || !current_user_can('tablepress_edit_options') || !current_user_can('tablepress_delete_tables') || is_plugin_active_for_network($plugin)) {
         wp_die(__('You do not have sufficient permissions to access this page.', 'default'), 403);
     }
     // Deactivate TablePress for the site (but not for the network).
     deactivate_plugins($plugin, false, false);
     update_option('recently_activated', array($plugin => time()) + (array) get_option('recently_activated', array()));
     // Delete all tables, "Custom CSS" files, and options.
     TablePress::$model_table->delete_all();
     $tablepress_css = TablePress::load_class('TablePress_CSS', 'class-css.php', 'classes');
     $css_files_deleted = $tablepress_css->delete_custom_css_files();
     TablePress::$model_options->remove_access_capabilities();
     TablePress::$model_table->destroy();
     TablePress::$model_options->destroy();
     $this->init_i18n_support();
     $output = '<strong>' . __('TablePress was uninstalled successfully.', 'tablepress') . '</strong><br /><br />';
     $output .= __('All tables, data, and options were deleted.', 'tablepress');
     if (is_multisite()) {
         $output .= ' ' . __('You may now ask the network admin to delete the plugin&#8217;s folder <code>tablepress</code> from the server, if no other site in the network uses it.', 'tablepress');
     } else {
         $output .= ' ' . __('You may now manually delete the plugin&#8217;s folder <code>tablepress</code> from the <code>plugins</code> directory on your server or use the &#8220;Delete&#8221; link for TablePress on the WordPress &#8220;Plugins&#8221; page.', 'tablepress');
     }
     if ($css_files_deleted) {
         $output .= ' ' . __('Your TablePress &#8220;Custom CSS&#8221; files have been deleted automatically.', 'tablepress');
     } else {
         if (is_multisite()) {
             $output .= ' ' . __('Please also ask him to delete your TablePress &#8220;Custom CSS&#8221; files from the server.', 'tablepress');
         } else {
             $output .= ' ' . __('You may now also delete your TablePress &#8220;Custom CSS&#8221; files in the <code>wp-content</code> folder.', 'tablepress');
         }
     }
     $output .= "</p>\n<p>";
     if (!is_multisite() || is_super_admin()) {
         $output .= '<a class="button" href="' . esc_url(admin_url('plugins.php')) . '">' . __('Go to &#8220;Plugins&#8221; page', 'tablepress') . '</a> ';
     }
     $output .= '<a class="button" href="' . esc_url(admin_url('index.php')) . '">' . __('Go to Dashboard', 'tablepress') . '</a>';
     wp_die($output, __('Uninstall TablePress', 'tablepress'), array('response' => 200, 'back_link' => false));
 }
 /**
  * Save changes on the Stockflock screen.
  *
  */
 public function handle_post_action_stockflock()
 {
     if (!isset($_POST['stockflock'])) {
         return;
     }
     TablePress::check_nonce('stockflock');
     if (!current_user_can('manage_options')) {
         wp_die(__('You do not have sufficient permissions to access this page.'));
     }
     if (empty($_POST['stockflock']) || !is_array($_POST['stockflock'])) {
         TablePress::redirect(array('action' => 'stockflock', 'message' => 'error_save'));
     } else {
         $stockflock = stripslashes_deep($_POST['stockflock']);
     }
     $params = array('option_name' => 'tablepress_stockflock_config', 'default_value' => array());
     $stockflock_config = TablePress::load_class('TablePress_WP_Option', 'class-wp_option.php', 'classes', $params);
     //trim and restrict array length to be not more than 20
     $raw_companies = explode(',', $stockflock['companies']);
     $valid_companies = array_slice(array_map('trim', $raw_companies), 0, $this->company_limit);
     $stockflock['companies'] = strtoupper(implode(',', $valid_companies));
     //give default value to data_points
     $data_point_list = ['short_name', 'price_value', 'industry_name', 'dividend_yield', 'earning_value', 'dividend_per_share', 'book_value', 'debt_assets', 'net_asset_value', 'gearing_ratio', 'property_yield_ratio'];
     if (is_array($stockflock['data_points'])) {
         foreach ($data_point_list as $key => $value) {
             if (!array_key_exists($value, $stockflock['data_points'])) {
                 $stockflock['data_points'][$value] = "false";
             }
         }
     }
     //store to wp_options
     $stockflock_config->update($stockflock);
     TablePress::redirect(array('action' => 'stockflock', 'message' => 'success_save'));
 }
 /**
  * Show a list of tables in the Editor toolbar Thickbox (opened by TinyMCE or Quicktags button)
  *
  * @since 1.0.0
  */
 public function handle_get_action_editor_button_thickbox()
 {
     TablePress::check_nonce('editor_button_thickbox');
     $this->init_i18n_support();
     $view_data = array('tables' => $this->model_table->load_all());
     set_current_screen('tablepress_editor_button_thickbox');
     // Prepare, initialize, and render the view
     $this->view = TablePress::load_view('editor_button_thickbox', $view_data);
     $this->view->render();
 }
 /**
  * Return the live preview data of table that has non-saved changes
  *
  * @since 1.0.0
  */
 public function ajax_action_preview_table()
 {
     if (empty($_POST['tablepress']) || empty($_POST['tablepress']['id'])) {
         wp_die('-1');
     } else {
         $preview_table = stripslashes_deep($_POST['tablepress']);
     }
     // check to see if the submitted nonce matches with the generated nonce we created earlier, dies -1 on fail
     TablePress::check_nonce('preview_table', $preview_table['id'], '_ajax_nonce', true);
     // ignore the request if the current user doesn't have sufficient permissions
     if (!current_user_can('tablepress_preview_table', $preview_table['id'])) {
         wp_die('-1');
     }
     // default response data:
     $success = false;
     do {
         // to be able to "break;" (allows for better readable code)
         // Load existing table from DB
         $existing_table = $this->model_table->load($preview_table['id']);
         if (false === $existing_table) {
             // maybe somehow load a new table here? ($this->model_table->get_table_template())?
             break;
         }
         // Check and convert data that was transmitted as JSON
         if (empty($preview_table['data']) || empty($preview_table['options']) || empty($preview_table['visibility'])) {
             break;
         }
         $preview_table['data'] = json_decode($preview_table['data'], true);
         $preview_table['options'] = json_decode($preview_table['options'], true);
         $preview_table['visibility'] = json_decode($preview_table['visibility'], true);
         // Check consistency of new table, and then merge with existing table
         $table = $this->model_table->prepare_table($existing_table, $preview_table, true, true);
         if (false === $table) {
             break;
         }
         // DataTables Custom Commands can only be edit by trusted users
         if (!current_user_can('unfiltered_html')) {
             $table['options']['datatables_custom_commands'] = $existing_table['options']['datatables_custom_commands'];
         }
         // If the ID has changed, and the new ID is valid, render with the new ID (important e.g. for CSS classes/HTML ID)
         if ($table['id'] !== $table['new_id'] && 0 === preg_match('/[^a-zA-Z0-9_-]/', $table['new_id'])) {
             $table['id'] = $table['new_id'];
         }
         // at this point, the table data is valid and can be rendered
         $success = true;
     } while (false);
     // do-while-loop through this exactly once, to be able to "break;" early
     if ($success) {
         // Create a render class instance
         $_render = TablePress::load_class('TablePress_Render', 'class-render.php', 'classes');
         // Merge desired options with default render options (as not all of them are stored in the table options, but are just Shortcode parameters)
         $render_options = shortcode_atts($_render->get_default_render_options(), $table['options']);
         $_render->set_input($table, $render_options);
         $head_html = '<style type="text/css">body{margin:10px;}</style>';
         $head_html .= $_render->get_preview_css();
         // Add "Custom CSS"
         if ($this->model_options->get('use_custom_css_file')) {
             $custom_css = $this->model_options->load_custom_css_from_file('normal');
             // fall back to "Custom CSS" in options, if it could not be retrieved from file
             if (false === $custom_css) {
                 $custom_css = $this->model_options->get('custom_css');
             }
         } else {
             // get "Custom CSS" from options
             $custom_css = $this->model_options->get('custom_css');
         }
         if (!empty($custom_css)) {
             $head_html .= "<style type=\"text/css\">\n{$custom_css}\n</style>\n";
         }
         $body_html = '<div id="tablepress-page"><p>' . __('This is a preview of your table.', 'tablepress') . ' ' . __('Because of CSS styling, the table might look different on your page!', 'tablepress') . ' ' . __('The features of the DataTables JavaScript library are also not visible in this preview!', 'tablepress') . '<br />' . sprintf(__('To insert the table into a page, post, or text widget, copy the Shortcode %s and paste it into the editor.', 'tablepress'), '<input type="text" class="table-shortcode table-shortcode-inline" value="[' . TablePress::$shortcode . ' id=' . esc_attr($table['id']) . ' /]" readonly="readonly" />') . '</p>' . $_render->get_output() . '</div>';
     } else {
         $head_html = '';
         $body_html = __('The preview could not be loaded.', 'tablepress');
     }
     // Generate the response
     $response = array('success' => $success, 'head_html' => $head_html, 'body_html' => $body_html);
     // Send the response
     $response['output_buffer'] = ob_get_clean();
     // buffer all outputs, to prevent errors/warnings being printed that make the JSON invalid
     wp_send_json($response);
 }