Ejemplo n.º 1
1
 /**
  * Init the Table model by instantiating a Post model and loading the list of tables option.
  *
  * @since 1.0.0
  */
 public function __construct()
 {
     parent::__construct();
     $this->model_post = TablePress::load_model('post');
     $params = array('option_name' => 'tablepress_tables', 'default_value' => $this->default_tables);
     $this->tables = TablePress::load_class('TablePress_WP_Option', 'class-wp_option.php', 'classes', $params);
 }
Ejemplo n.º 2
0
 /**
  * Init Options Model by creating the object instances for the Plugin and User Options.
  *
  * @since 1.0.0
  */
 public function __construct()
 {
     parent::__construct();
     $params = array('option_name' => 'tablepress_plugin_options', 'default_value' => $this->default_plugin_options);
     $this->plugin_options = TablePress::load_class('TablePress_WP_Option', 'class-wp_option.php', 'classes', $params);
     $params = array('option_name' => 'tablepress_user_options', 'default_value' => $this->default_user_options);
     $this->user_options = TablePress::load_class('TablePress_WP_User_Option', 'class-wp_user_option.php', 'classes', $params);
     // Filter to map Meta capabilities to Primitive Capabilities.
     add_filter('map_meta_cap', array($this, 'map_tablepress_meta_caps'), 10, 4);
 }
 /**
  * Set up the view with data and do things that are specific for this view.
  *
  * @param string $action Action for this view.
  * @param array $data Data for this view.
  */
 public function setup($action, array $data)
 {
     $params = array('option_name' => 'tablepress_stockflock_config', 'default_value' => array());
     $this->stockflock_config = TablePress::load_class('TablePress_WP_Option', 'class-wp_option.php', 'classes', $params);
     parent::setup($action, $data);
     $this->add_header_message('<span>' . __('Please contact stockflock if you get any issue with this plugin.', 'tablepress') . '</span>', 'notice-info');
     $this->process_action_messages(array('success_save' => __('Stockflock Changes saved successfully.', 'tablepress'), 'error_save' => __('Error: Stockflock Changes could not be saved.', 'tablepress')));
     $this->add_meta_box('stockflock-options', __('Stockflock Options', 'tablepress'), array($this, 'stockflock_plugin_options'), 'normal');
     $this->add_text_box('submit', array($this, 'textbox_submit_button'), 'submit');
 }
 /**
  * Set up the view with data and do things that are specific for this view.
  *
  * @since 1.0.0
  *
  * @param string $action Action for this view.
  * @param array  $data   Data for this view.
  */
 public function setup($action, array $data)
 {
     // Set action manually here, to get correct page title and nav bar entries.
     $this->action = 'options';
     $this->data = $data;
     // Set page title.
     $GLOBALS['title'] = sprintf(__('%1$s &lsaquo; %2$s', 'tablepress'), $this->data['view_actions'][$this->action]['page_title'], 'TablePress');
     $this->add_header_message('<strong>' . __('Attention: Further action is required to save the changes to your &#8220;Custom CSS&#8221;!', 'tablepress') . '</strong>', 'updated');
     // Admin page helpers, like script/style loading, could be moved to view.
     $this->admin_page = TablePress::load_class('TablePress_Admin_Page', 'class-admin-page-helper.php', 'classes');
     $this->admin_page->enqueue_style('common');
     $this->admin_page->add_admin_footer_text();
     $this->add_text_box('explanation-text', array($this, 'textbox_explanation_text'), 'normal');
     $this->add_text_box('credentials-form', array($this, 'textbox_credentials_form'), 'normal');
     $this->add_text_box('proceed-no-file-saving', array($this, 'textbox_proceed_no_file_saving'), 'submit');
 }
Ejemplo n.º 5
0
 /**
  * Minify a string of CSS code, that should have been sanitized/tidied before
  *
  * @since 1.1.0
  *
  * @uses CSSTidy
  *
  * @param string $css CSS code
  * @return string Minified CSS code
  */
 function minify_css($css)
 {
     $csstidy = TablePress::load_class('csstidy', 'class.csstidy.php', 'libraries/csstidy');
     $csstidy->optimise = new csstidy_custom_sanitize($csstidy);
     $csstidy->set_cfg('remove_bslash', false);
     $csstidy->set_cfg('compress_colors', true);
     $csstidy->set_cfg('compress_font-weight', true);
     $csstidy->set_cfg('lowercase_s', false);
     $csstidy->set_cfg('optimise_shorthands', 1);
     $csstidy->set_cfg('remove_last_;', true);
     $csstidy->set_cfg('case_properties', false);
     $csstidy->set_cfg('sort_properties', false);
     $csstidy->set_cfg('sort_selectors', false);
     $csstidy->set_cfg('discard_invalid_selectors', false);
     $csstidy->set_cfg('discard_invalid_properties', true);
     $csstidy->set_cfg('merge_selectors', false);
     $csstidy->set_cfg('css_level', 'CSS3.0');
     $csstidy->set_cfg('preserve_css', false);
     $csstidy->set_cfg('timestamp', false);
     $csstidy->set_cfg('template', 'highest');
     $csstidy->parse($css);
     return $csstidy->print->plain();
 }
Ejemplo n.º 6
0
 /**
  * Set up the view with data and do things that are necessary for all views.
  *
  * @since 1.0.0
  *
  * @param string $action Action for this view.
  * @param array  $data   Data for this view.
  */
 public function setup($action, array $data)
 {
     $this->action = $action;
     $this->data = $data;
     // Set page title.
     $GLOBALS['title'] = sprintf(__('%1$s &lsaquo; %2$s', 'tablepress'), $this->data['view_actions'][$this->action]['page_title'], 'TablePress');
     // Admin page helpers, like script/style loading, could be moved to view.
     $this->admin_page = TablePress::load_class('TablePress_Admin_Page', 'class-admin-page-helper.php', 'classes');
     $this->admin_page->enqueue_style('common');
     // RTL styles for the admin interface.
     if (is_rtl()) {
         $this->admin_page->enqueue_style('common-rtl', array('tablepress-common'));
     }
     $this->admin_page->enqueue_script('common', array('jquery-core', 'postbox'), array('common' => array('ays_delete_single_table' => _n('Do you really want to delete this table?', 'Do you really want to delete these tables?', 1, 'tablepress'), 'ays_delete_multiple_tables' => _n('Do you really want to delete this table?', 'Do you really want to delete these tables?', 2, 'tablepress'))));
     $this->admin_page->add_admin_footer_text();
     // Initialize WP feature pointers for TablePress.
     $this->_init_wp_pointers();
     // Necessary fields for all views.
     $this->add_text_box('default_nonce_fields', array($this, 'default_nonce_fields'), 'header', false);
     $this->add_text_box('action_nonce_field', array($this, 'action_nonce_field'), 'header', false);
     $this->add_text_box('action_field', array($this, 'action_field'), 'header', false);
 }
 /**
  * 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);
 }
Ejemplo n.º 8
0
 /**
  * Check if the plugin was updated and perform necessary actions, like updating the options.
  *
  * @since 1.0.0
  */
 protected function plugin_update_check()
 {
     // First activation or plugin update.
     $current_plugin_options_db_version = TablePress::$model_options->get('plugin_options_db_version');
     if ($current_plugin_options_db_version < TablePress::db_version) {
         // Allow more PHP execution time for update process.
         @set_time_limit(300);
         // Add TablePress capabilities to the WP_Roles objects, for new installations and all versions below 12.
         if ($current_plugin_options_db_version < 12) {
             TablePress::$model_options->add_access_capabilities();
         }
         if (0 === TablePress::$model_options->get('first_activation')) {
             // Save initial set of plugin options, and time of first activation of the plugin, on first activation.
             TablePress::$model_options->update(array('first_activation' => current_time('timestamp'), 'plugin_options_db_version' => TablePress::db_version));
         } else {
             // Update Plugin Options Options, if necessary.
             TablePress::$model_options->merge_plugin_options_defaults();
             $updated_options = array('plugin_options_db_version' => TablePress::db_version, 'prev_tablepress_version' => TablePress::$model_options->get('tablepress_version'), 'tablepress_version' => TablePress::version, 'message_plugin_update' => true);
             // Only write files, if "Custom CSS" is to be used, and if there is "Custom CSS".
             if (TablePress::$model_options->get('use_custom_css') && '' !== TablePress::$model_options->get('custom_css')) {
                 // Re-save "Custom CSS" to re-create all files (as TablePress Default CSS might have changed).
                 /**
                  * Load WP file functions to provide filesystem access functions early.
                  */
                 require_once ABSPATH . 'wp-admin/includes/file.php';
                 /**
                  * Load WP admin template functions to provide `submit_button()` which is necessary for `request_filesystem_credentials()`.
                  */
                 require_once ABSPATH . 'wp-admin/includes/template.php';
                 $tablepress_css = TablePress::load_class('TablePress_CSS', 'class-css.php', 'classes');
                 $result = $tablepress_css->save_custom_css_to_file(TablePress::$model_options->get('custom_css'), TablePress::$model_options->get('custom_css_minified'));
                 // If saving was successful, use "Custom CSS" file.
                 $updated_options['use_custom_css_file'] = $result;
                 // Increase the "Custom CSS" version number for cache busting.
                 if ($result) {
                     $updated_options['custom_css_version'] = TablePress::$model_options->get('custom_css_version') + 1;
                 }
             }
             TablePress::$model_options->update($updated_options);
             // Clear table caches.
             if ($current_plugin_options_db_version < 16) {
                 // For pre-0.9-RC, where the arrays are serialized and not JSON encoded.
                 TablePress::$model_table->invalidate_table_output_caches_tp09();
             } else {
                 // For 0.9-RC and onwards.
                 TablePress::$model_table->invalidate_table_output_caches();
             }
             // Add mime type field to existing posts with the TablePress Custom Post Type, so that other plugins know that they are not dealing with plain text.
             if ($current_plugin_options_db_version < 25) {
                 TablePress::$model_table->add_mime_type_to_posts();
             }
             // Convert old parameter names to new ones in DataTables "Custom Commands".
             if ($current_plugin_options_db_version < 26) {
                 TablePress::$model_table->convert_datatables_parameter_names_tp15();
             }
         }
         TablePress::$model_options->update(array('message_plugin_update_content' => TablePress::$model_options->plugin_update_message(TablePress::$model_options->get('prev_tablepress_version'), TablePress::version, get_locale())));
     }
     // Maybe update the table scheme in each existing table, independently from updating the plugin options.
     if (TablePress::$model_options->get('table_scheme_db_version') < TablePress::table_scheme_version) {
         // Convert parameter "datatables_scrollX" to "datatables_scrollx", has to be done before merge_table_options_defaults() is called!
         if (TablePress::$model_options->get('table_scheme_db_version') < 3) {
             TablePress::$model_table->merge_table_options_tp08();
         }
         TablePress::$model_table->merge_table_options_defaults();
         // Merge print_name/print_description changes made for 0.6-beta.
         if (TablePress::$model_options->get('table_scheme_db_version') < 2) {
             TablePress::$model_table->merge_table_options_tp06();
         }
         TablePress::$model_options->update(array('table_scheme_db_version' => TablePress::table_scheme_version));
     }
     /*
      * Update User Options, if necessary.
      * User Options are not saved in DB until first change occurs.
      */
     if (is_user_logged_in() && TablePress::$model_options->get('user_options_db_version') < TablePress::db_version) {
         TablePress::$model_options->merge_user_options_defaults();
         TablePress::$model_options->update(array('user_options_db_version' => TablePress::db_version));
     }
 }
Ejemplo n.º 9
0
 /**
  * Set up the view with data and do things that are necessary for all views
  *
  * @since 1.0.0
  *
  * @param string $action Action for this view
  * @param array $data Data for this view
  */
 public function setup($action, $data)
 {
     $this->action = $action;
     $this->data = $data;
     // Set page <title>
     $GLOBALS['title'] = sprintf(__('%1$s &lsaquo; %2$s', 'tablepress'), $this->data['view_actions'][$this->action]['page_title'], 'TablePress');
     // admin page helpers, like script/style loading, could be moved to view
     $this->admin_page = TablePress::load_class('TablePress_Admin_Page', 'class-admin-page-helper.php', 'classes');
     $this->admin_page->enqueue_style('common');
     remove_action('admin_print_styles', array(TablePress::$controller, 'add_tablepress_hidpi_css'), 21);
     // Don't load HiDPI CSS via <style> on TablePress pages, as it's part of common.css
     /* // @TODO: maybe later necessary: RTL styles for admin interface
     		if ( is_rtl() )
     			$this->admin_page->enqueue_style( 'common-rtl' );
     		*/
     $this->admin_page->enqueue_script('common', array('jquery', 'postbox'), array('common' => array('ays_delete_single_table' => _n('Do you really want to delete this table?', 'Do you really want to delete these tables?', 1, 'tablepress'), 'ays_delete_multiple_tables' => _n('Do you really want to delete this table?', 'Do you really want to delete these tables?', 2, 'tablepress'))));
     $this->admin_page->add_admin_footer_text();
     // Initialize WP feature pointers for TablePress
     $this->_init_wp_pointers();
     // necessary fields for all views
     $this->add_text_box('default_nonce_fields', array($this, 'default_nonce_fields'), 'header', false);
     $this->add_text_box('action_nonce_field', array($this, 'action_nonce_field'), 'header', false);
     $this->add_text_box('action_field', array($this, 'action_field'), 'header', false);
 }
Ejemplo n.º 10
0
 /**
  * Initialize the Rendering class, include the EvalMath class
  *
  * @since 1.0.0
  */
 public function __construct()
 {
     $this->evalmath = TablePress::load_class('EvalMath', 'evalmath.class.php', 'libraries', true);
     // true for some default constants
     $this->evalmath->suppress_errors = true;
     // don't raise PHP warnings
 }
Ejemplo n.º 11
0
 /**
  * Loop through the table to evaluate math expressions/formulas.
  *
  * @since 1.0.0
  */
 protected function _evaluate_table_data()
 {
     $orig_table = $this->table;
     $formula_evaluator = TablePress::load_class('TablePress_Evaluate', 'class-evaluate.php', 'classes');
     $this->table['data'] = $formula_evaluator->evaluate_table_data($this->table['data']);
     /**
      * Filter the table after evaluating formulas in the table.
      *
      * @since 1.0.0
      *
      * @param array $table          The table with evaluated formulas.
      * @param array $orig_table     The table with unevaluated formulas.
      * @param array $render_options The render options for the table.
      */
     $this->table = apply_filters('tablepress_table_evaluate_data', $this->table, $orig_table, $this->render_options);
 }
Ejemplo n.º 12
0
 /**
  * Handle Shortcode [table id=<ID> /] in the_content()
  *
  * @since 1.0.0
  *
  * @param array $shortcode_atts List of attributes that where included in the Shortcode
  * @return string Resulting HTML code for the table with the ID <ID>
  */
 public function shortcode_table($shortcode_atts)
 {
     $_render = TablePress::load_class('TablePress_Render', 'class-render.php', 'classes');
     $default_shortcode_atts = $_render->get_default_render_options();
     $default_shortcode_atts = apply_filters('tablepress_shortcode_table_default_shortcode_atts', $default_shortcode_atts);
     // parse Shortcode attributes, only allow those that are specified
     $shortcode_atts = shortcode_atts($default_shortcode_atts, $shortcode_atts);
     $shortcode_atts = apply_filters('tablepress_shortcode_table_shortcode_atts', $shortcode_atts);
     // check, if a table with the given ID exists
     $table_id = preg_replace('/[^a-zA-Z0-9_-]/', '', $shortcode_atts['id']);
     if (!$this->model_table->table_exists($table_id)) {
         $message = "[table &#8220;{$table_id}&#8221; not found /]<br />\n";
         $message = apply_filters('tablepress_table_not_found_message', $message, $table_id);
         return $message;
     }
     // load the table
     $table = $this->model_table->load($table_id);
     if (false === $table) {
         $message = "[table &#8220;{$table_id}&#8221; could not be loaded /]<br />\n";
         $message = apply_filters('tablepress_table_load_error_message', $message, $table_id);
         return $message;
     }
     // Disable the "datatables_custom_commands" Shortcode parameter by default, for security reasons
     if (!is_null($shortcode_atts['datatables_custom_commands']) && apply_filters('tablepress_disable_custom_commands_shortcode_parameter', true)) {
         $shortcode_atts['datatables_custom_commands'] = null;
     }
     // determine options to use (if set in Shortcode, use those, otherwise use stored options, i.e. "Edit Table" screen)
     $render_options = array();
     foreach ($shortcode_atts as $key => $value) {
         // have to check this, because strings 'true' or 'false' are not recognized as boolean!
         if ('true' == strtolower($value)) {
             $render_options[$key] = true;
         } elseif ('false' == strtolower($value)) {
             $render_options[$key] = false;
         } elseif (is_null($value) && isset($table['options'][$key])) {
             $render_options[$key] = $table['options'][$key];
         } else {
             $render_options[$key] = $value;
         }
     }
     // generate unique HTML ID, depending on how often this table has already been shown on this page
     if (!isset($this->shown_tables[$table_id])) {
         $this->shown_tables[$table_id] = array('count' => 0, 'instances' => array());
     }
     $this->shown_tables[$table_id]['count']++;
     $count = $this->shown_tables[$table_id]['count'];
     $render_options['html_id'] = "tablepress-{$table_id}";
     if ($count > 1) {
         $render_options['html_id'] .= "-no-{$count}";
     }
     $render_options['html_id'] = apply_filters('tablepress_html_id', $render_options['html_id'], $table_id, $count);
     // generate "Edit Table" link
     $render_options['edit_table_url'] = '';
     if (is_user_logged_in() && apply_filters('tablepress_edit_link_below_table', true) && current_user_can('tablepress_edit_table', $table['id'])) {
         $render_options['edit_table_url'] = TablePress::url(array('action' => 'edit', 'table_id' => $table['id']));
     }
     $render_options = apply_filters('tablepress_table_render_options', $render_options, $table);
     // eventually add this table to list of tables which have a JS library enabled and thus are to be included in the script's call in the footer
     if ($render_options['use_datatables'] && $render_options['table_head'] && count($table['data']) > 1) {
         // get options for the DataTables JavaScript library from the table's render options
         $js_options = array();
         foreach (array('alternating_row_colors', 'datatables_sort', 'datatables_paginate', 'datatables_paginate', 'datatables_paginate_entries', 'datatables_lengthchange', 'datatables_filter', 'datatables_info', 'datatables_scrollx', 'datatables_scrolly', 'datatables_locale', 'datatables_custom_commands') as $option) {
             $js_options[$option] = $render_options[$option];
         }
         $js_options = apply_filters('tablepress_table_js_options', $js_options, $table_id, $render_options);
         // need this filter to e.g. set JS parameters depending on Shortcode attributes
         $this->shown_tables[$table_id]['instances'][$render_options['html_id']] = $js_options;
         $this->_enqueue_datatables();
     }
     // check if table output shall and can be loaded from the transient cache, otherwise generate the output
     if ($render_options['cache_table_output'] && !is_user_logged_in()) {
         $table_hash = md5(json_encode($render_options));
         // hash the Render Options array to get a unique cache identifier
         $transient_name = 'tablepress_' . $table_hash;
         // Attention: This string must not be longer than 45 characters!
         $output = get_transient($transient_name);
         if (false === $output || '' == $output) {
             // render/generate the table HTML, as it was not found in the cache
             $_render->set_input($table, $render_options);
             $output = $_render->get_output();
             // save output to a transient
             set_transient($transient_name, $output, DAY_IN_SECONDS);
             // store $output in a transient, set cache timeout to 24 hours
             // update output caches list transient (necessary for cache invalidation upon table saving)
             $caches_list_transient_name = 'tablepress_c_' . md5($table_id);
             $caches_list = get_transient($caches_list_transient_name);
             if (false === $caches_list) {
                 $caches_list = array();
             } else {
                 $caches_list = json_decode($caches_list, true);
             }
             if (!in_array($transient_name, $caches_list, true)) {
                 $caches_list[] = $transient_name;
             }
             set_transient($caches_list_transient_name, json_encode($caches_list), 2 * DAY_IN_SECONDS);
         } else {
             $output .= apply_filters('tablepress_cache_hit_comment', "<!-- #{$render_options['html_id']} from cache -->");
         }
     } else {
         // render/generate the table HTML, as no cache is to be used
         $_render->set_input($table, $render_options);
         $output = $_render->get_output();
     }
     return $output;
 }
Ejemplo n.º 13
0
 /**
  * Preview a table
  *
  * @since 1.0.0
  */
 public function handle_get_action_preview_table()
 {
     $table_id = !empty($_GET['item']) ? $_GET['item'] : false;
     TablePress::check_nonce('preview_table', $table_id);
     $this->init_i18n_support();
     if (false === $table_id) {
         // nonce check should actually catch this already
         wp_die(__('The preview could not be loaded.', 'tablepress'), __('Preview', 'tablepress'));
     }
     if (!current_user_can('tablepress_preview_table', $table_id)) {
         wp_die(__('You do not have sufficient permissions to access this page.', 'default'));
     }
     // Load existing table from DB
     $table = $this->model_table->load($table_id);
     if (false === $table) {
         wp_die(__('The table could not be loaded.', 'tablepress'), __('Preview', 'tablepress'));
     }
     // 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);
     $view_data = array('table_id' => $table_id, 'head_html' => $_render->get_preview_css(), 'body_html' => $_render->get_output());
     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)) {
         $view_data['head_html'] .= "<style type=\"text/css\">\n{$custom_css}\n</style>\n";
     }
     // Prepare, initialize, and render the view
     $this->view = TablePress::load_view('preview_table', $view_data);
     $this->view->render();
 }
 /**
  * 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'));
 }
Ejemplo n.º 15
0
 /**
  * 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);
 }
Ejemplo n.º 16
0
 /**
  * Initialize the Formula Evaluation class, include the EvalMath class.
  *
  * @since 1.0.0
  */
 public function __construct()
 {
     $this->evalmath = TablePress::load_class('EvalMath', 'evalmath.class.php', 'libraries');
     // Don't raise PHP warnings.
     $this->evalmath->suppress_errors = true;
 }
 /**
  * Handle Shortcode [table id=<ID> /] in the_content()
  *
  * @since 1.0.0
  *
  * @param array $shortcode_atts List of attributes that where included in the Shortcode
  * @return string Resulting HTML code for the table with the ID <ID>
  */
 public function shortcode_table($shortcode_atts)
 {
     // For empty Shortcodes like [table] or [table /], an empty string is passed, see Core #26927
     $shortcode_atts = (array) $shortcode_atts;
     $_render = TablePress::load_class('TablePress_Render', 'class-render.php', 'classes');
     $default_shortcode_atts = $_render->get_default_render_options();
     /**
      * Filter the available/default attributes for the [table] Shortcode.
      *
      * @since 1.0.0
      *
      * @param array $default_shortcode_atts The [table] Shortcode default attributes.
      */
     $default_shortcode_atts = apply_filters('tablepress_shortcode_table_default_shortcode_atts', $default_shortcode_atts);
     // parse Shortcode attributes, only allow those that are specified
     $shortcode_atts = shortcode_atts($default_shortcode_atts, $shortcode_atts);
     // Optional third argument left out on purpose. Use filter in the next line instead.
     /**
      * Filter the attributes that were passed to the [table] Shortcode.
      *
      * @since 1.0.0
      *
      * @param array $shortcode_atts The attributes passed to the [table] Shortcode.
      */
     $shortcode_atts = apply_filters('tablepress_shortcode_table_shortcode_atts', $shortcode_atts);
     // check, if a table with the given ID exists
     $table_id = preg_replace('/[^a-zA-Z0-9_-]/', '', $shortcode_atts['id']);
     if (!TablePress::$model_table->table_exists($table_id)) {
         $message = "[table &#8220;{$table_id}&#8221; not found /]<br />\n";
         /**
          * Filter the "Table not found" message.
          *
          * @since 1.0.0
          *
          * @param string $message  The "Table not found" message.
          * @param string $table_id The current table ID.
          */
         $message = apply_filters('tablepress_table_not_found_message', $message, $table_id);
         return $message;
     }
     // load the table
     $table = TablePress::$model_table->load($table_id, true, true);
     // Load table, with table data, options, and visibility settings
     if (is_wp_error($table)) {
         $message = "[table &#8220;{$table_id}&#8221; could not be loaded /]<br />\n";
         /**
          * Filter the "Table could not be loaded" message.
          *
          * @since 1.0.0
          *
          * @param string   $message  The "Table could not be loaded" message.
          * @param string   $table_id The current table ID.
          * @param WP_Error $table    The error object for the table.
          */
         $message = apply_filters('tablepress_table_load_error_message', $message, $table_id, $table);
         return $message;
     }
     if (isset($table['is_corrupted']) && $table['is_corrupted']) {
         $message = "<div>Attention: The internal data of table &#8220;{$table_id}&#8221; is corrupted!</div>";
         /**
          * Filter the "Table data is corrupted" message.
          *
          * @since 1.0.0
          *
          * @param string $message    The "Table data is corrupted" message.
          * @param string $table_id   The current table ID.
          * @param string $json_error The JSON error with information about the corrupted table.
          */
         $message = apply_filters('tablepress_table_corrupted_message', $message, $table_id, $table['json_error']);
         return $message;
     }
     /**
      * Filter whether the "datatables_custom_commands" Shortcode parameter is disabled.
      *
      * By default, the "datatables_custom_commands" Shortcode parameter is disabled for security reasons.
      *
      * @since 1.0.0
      *
      * @param bool $disable Whether to disable the "datatables_custom_commands" Shortcode parameter. Default true.
      */
     if (!is_null($shortcode_atts['datatables_custom_commands']) && apply_filters('tablepress_disable_custom_commands_shortcode_parameter', true)) {
         $shortcode_atts['datatables_custom_commands'] = null;
     }
     // determine options to use (if set in Shortcode, use those, otherwise use stored options, i.e. "Edit Table" screen)
     $render_options = array();
     foreach ($shortcode_atts as $key => $value) {
         // have to check this, because strings 'true' or 'false' are not recognized as boolean!
         if ('true' == strtolower($value)) {
             $render_options[$key] = true;
         } elseif ('false' == strtolower($value)) {
             $render_options[$key] = false;
         } elseif (is_null($value) && isset($table['options'][$key])) {
             $render_options[$key] = $table['options'][$key];
         } else {
             $render_options[$key] = $value;
         }
     }
     // generate unique HTML ID, depending on how often this table has already been shown on this page
     if (!isset($this->shown_tables[$table_id])) {
         $this->shown_tables[$table_id] = array('count' => 0, 'instances' => array());
     }
     $this->shown_tables[$table_id]['count']++;
     $count = $this->shown_tables[$table_id]['count'];
     $render_options['html_id'] = "tablepress-{$table_id}";
     if ($count > 1) {
         $render_options['html_id'] .= "-no-{$count}";
     }
     /**
      * Filter the ID of the table HTML element.
      *
      * @since 1.0.0
      *
      * @param string $html_id  The ID of the table HTML element.
      * @param string $table_id The current table ID.
      * @param string $count    Number of copies of the table with this table ID on the page.
      */
     $render_options['html_id'] = apply_filters('tablepress_html_id', $render_options['html_id'], $table_id, $count);
     // generate "Edit Table" link
     $render_options['edit_table_url'] = '';
     /**
      * Filter whether the "Edit" link below the table shall be shown.
      *
      * The "Edit" link is only shown to logged-in users who possess the necessary capability to edit the table.
      *
      * @since 1.0.0
      *
      * @param bool   $show     Whether to show the "Edit" link below the table. Default true.
      * @param string $table_id The current table ID.
      */
     if (is_user_logged_in() && apply_filters('tablepress_edit_link_below_table', true, $table['id']) && current_user_can('tablepress_edit_table', $table['id'])) {
         $render_options['edit_table_url'] = TablePress::url(array('action' => 'edit', 'table_id' => $table['id']));
     }
     /**
      * Filter the render options for the table.
      *
      * The render options are determined from the settings on a table's "Edit" screen and the Shortcode parameters.
      *
      * @since 1.0.0
      *
      * @param array $render_options The render options for the table.
      * @param array $table          The current table.
      */
     $render_options = apply_filters('tablepress_table_render_options', $render_options, $table);
     // eventually add this table to list of tables which have a JS library enabled and thus are to be included in the script's call in the footer
     if ($render_options['use_datatables'] && $render_options['table_head'] && count($table['data']) > 1) {
         // get options for the DataTables JavaScript library from the table's render options
         $js_options = array();
         foreach (array('alternating_row_colors', 'datatables_sort', 'datatables_paginate', 'datatables_paginate', 'datatables_paginate_entries', 'datatables_lengthchange', 'datatables_filter', 'datatables_info', 'datatables_scrollx', 'datatables_scrolly', 'datatables_locale', 'datatables_custom_commands') as $option) {
             $js_options[$option] = $render_options[$option];
         }
         /**
          * Filter the JavaScript options for the table.
          *
          * The JavaScript options are determined from the settings on a table's "Edit" screen and the Shortcode parameters.
          * They are part of the render options and can be overwritten with Shortcode parameters.
          *
          * @since 1.0.0
          *
          * @param array  $js_options     The JavaScript options for the table.
          * @param string $table_id       The current table ID.
          * @param array  $render_options The render options for the table.
          */
         $js_options = apply_filters('tablepress_table_js_options', $js_options, $table_id, $render_options);
         $this->shown_tables[$table_id]['instances'][$render_options['html_id']] = $js_options;
         $this->_enqueue_datatables();
     }
     // check if table output shall and can be loaded from the transient cache, otherwise generate the output
     if ($render_options['cache_table_output'] && !is_user_logged_in()) {
         $table_hash = md5(json_encode($render_options));
         // hash the Render Options array to get a unique cache identifier
         $transient_name = 'tablepress_' . $table_hash;
         // Attention: This string must not be longer than 45 characters!
         $output = get_transient($transient_name);
         if (false === $output || '' == $output) {
             // render/generate the table HTML, as it was not found in the cache
             $_render->set_input($table, $render_options);
             $output = $_render->get_output();
             // save output to a transient
             set_transient($transient_name, $output, DAY_IN_SECONDS);
             // store $output in a transient, set cache timeout to 24 hours
             // update output caches list transient (necessary for cache invalidation upon table saving)
             $caches_list_transient_name = 'tablepress_c_' . md5($table_id);
             $caches_list = get_transient($caches_list_transient_name);
             if (false === $caches_list) {
                 $caches_list = array();
             } else {
                 $caches_list = json_decode($caches_list, true);
             }
             if (!in_array($transient_name, $caches_list, true)) {
                 $caches_list[] = $transient_name;
             }
             set_transient($caches_list_transient_name, json_encode($caches_list), 2 * DAY_IN_SECONDS);
         } else {
             /**
              * Filter the cache hit comment message.
              *
              * @since 1.0.0
              *
              * @param string $comment The cache hit comment message.
              */
             $output .= apply_filters('tablepress_cache_hit_comment', "<!-- #{$render_options['html_id']} from cache -->");
         }
     } else {
         // render/generate the table HTML, as no cache is to be used
         $_render->set_input($table, $render_options);
         $output = $_render->get_output();
     }
     // Maybe print a list of used render options
     if ($render_options['shortcode_debug'] && is_user_logged_in()) {
         $output .= '<pre>' . var_export($render_options, true) . '</pre>';
     }
     return $output;
 }
Ejemplo n.º 18
0
 /**
  * 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));
 }
Ejemplo n.º 19
0
 /**
  * Import Microsoft Excel 97-2003 data
  *
  * @since 1.1.0
  */
 protected function import_xls()
 {
     $excel_reader = TablePress::load_class('Spreadsheet_Excel_Reader', 'excel-reader.class.php', 'libraries', $this->import_data);
     // loop through Excel file and retrieve value and colspan/rowspan properties for each cell
     $sheet = 0;
     // import first sheet of the Workbook
     $table = array();
     for ($row = 1; $row <= $excel_reader->rowcount($sheet); $row++) {
         $table_row = array();
         for ($col = 1; $col <= $excel_reader->colcount($sheet); $col++) {
             $cell = array();
             $cell['rowspan'] = $excel_reader->rowspan($row, $col, $sheet);
             $cell['colspan'] = $excel_reader->colspan($row, $col, $sheet);
             $cell['val'] = $excel_reader->val($row, $col, $sheet);
             $table_row[] = $cell;
         }
         $table[] = $table_row;
     }
     // transform colspan/rowspan properties to TablePress equivalent (cell content)
     foreach ($table as $row_idx => $row) {
         foreach ($row as $col_idx => $cell) {
             if (1 == $cell['rowspan'] && 1 == $cell['colspan']) {
                 continue;
             }
             if (1 < $cell['colspan']) {
                 for ($i = 1; $i < $cell['colspan']; $i++) {
                     $table[$row_idx][$col_idx + $i]['val'] = '#colspan#';
                 }
             }
             if (1 < $cell['rowspan']) {
                 for ($i = 1; $i < $cell['rowspan']; $i++) {
                     $table[$row_idx + $i][$col_idx]['val'] = '#rowspan#';
                 }
             }
             if (1 < $cell['rowspan'] && 1 < $cell['colspan']) {
                 for ($i = 1; $i < $cell['rowspan']; $i++) {
                     for ($j = 1; $j < $cell['colspan']; $j++) {
                         $table[$row_idx + $i][$col_idx + $j]['val'] = '#span#';
                     }
                 }
             }
         }
     }
     // flatten value property to two-dimensional array
     $result_table = array();
     foreach ($table as $row_idx => $row) {
         $table_row = array();
         foreach ($row as $col_idx => $cell) {
             $table_row[] = (string) $cell['val'];
         }
         $result_table[] = $table_row;
     }
     $this->imported_table = array('data' => $this->pad_array_to_max_cols($result_table));
 }
Ejemplo n.º 20
0
 /**
  * Import CSV data
  *
  * @since 1.0.0
  */
 protected function import_csv()
 {
     $csv_parser = TablePress::load_class('CSV_Parser', 'csv-parser.class.php', 'libraries');
     $csv_parser->load_data($this->import_data);
     $delimiter = $csv_parser->find_delimiter();
     $data = $csv_parser->parse($delimiter);
     $this->imported_table = array('data' => $this->pad_array_to_max_cols($data));
 }