1

I have the following scenario I have a lot of tables created by TablePress. one column in them is called Size which displays the size of some files in bytes. tablepress have a summing function called "sum" I will use it in the last row to sum all of the data in that column, I want to make that data saved as a post meta so I can sum it later any idea on how to do that?

1

The code is quite tricky and difficult, cause table press math evaluation class has some protected method.

By the by I solved your issue.

Just the code in the functions.php in the theme.. just copy and paste it should be work. You can use multiple row sum.

require_once TABLEPRESS_ABSPATH . 'classes/class-tablepress.php';
$formula_evaluator = TablePress::load_class( 'TablePress_Evaluate', 'class-evaluate.php', 'classes' );
add_action( 'wp_ajax_link_check_click_counter', 'link_check_click_counter');
add_action( 'wp_ajax_nopriv_link_check_click_counter', 'link_check_click_counter' );

function link_check_click_counter() {

  $table_name = $_POST['old_data']['tablepress']['name'];
  $table_id = $_POST['old_data']['tablepress']['id'];
  $table_description = $_POST['old_data']['tablepress']['description'];
  $table_data = $_POST['old_data']['tablepress']['data'];
  $allResults = json_decode(stripslashes($table_data));
  $table_meta = $table_name ."_". $table_id;

  $neval = new TablePress_NEvaluate();
  $data = $neval->evaluate_table_data( $allResults );
  foreach($data as $value){
    update_option( 'table_press' . $table_meta, $value );
    update_option( 'table_press' . $table_id, $table_id );
  }
  die();
}

add_action('admin_footer' , 'table_press_custom_meta_add',0);
function table_press_custom_meta_add(){

   ?>
   <script type="text/javascript">
   //
   jQuery( '.wp-admin .save-changes-button' ).on( 'click',function() {
      var data =  { action: 'link_check_click_counter', old_data: tp.table.prepare_ajax_request( 'tablepress_save_table', '#nonce-edit-table' )  };
      jQuery.ajax({
        'type': 'POST',
        'dataType': 'json',
        'url': ajaxurl,
        // 'data': tp.table.prepare_ajax_request( 'tablepress_save_table', '#nonce-edit-table' ),
        'data': data,
       success: function(data) {
          console.log('test');
       }

      } );

   });

   </script>
<?php
}

class TablePress_NEvaluate {

  /**
   * Instance of the EvalMath class.
   *
   * @since 1.0.0
   * @var EvalMath
   */
  public $evalmath;

  /**
   * Table data in which formulas shall be evaluated.
   *
   * @since 1.5.0
   * @var array
   */
  public $table_data;

  /**
   * Storage for cell ranges that have been replaced in formulas.
   *
   * @since 1.0.0
   * @var array
   */
  public $known_ranges = array();

  /**
   * 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;
  }

  /**
   * Evaluate formulas in the passed table.
   *
   * @since 1.0.0
   *
   * @param array $table_data Table data in which formulas shall be evaluated.
   * @return array Table data with evaluated formulas.
   */
  public function evaluate_table_data( array $table_data ) {
    $this->table_data = $table_data;
    $rows = count( $this->table_data );
    $columns = count( $this->table_data[0] );

    // Use two for-loops instead of foreach here to be sure to always work on the "live" table data and not some in-memory copy.
    $i = 0;
    $data = array();
    for ( $row_idx = 0; $row_idx < $rows; $row_idx++ ) {
      for ( $col_idx = 0; $col_idx < $columns; $col_idx++ ) {
        $test = $this->_evaluate_cell( $this->table_data[ $row_idx ][ $col_idx ] );
        //print_r($test);
          if (strpos($test, 'Sum') !== false) {
            $data[] = $test;
          }

        $this->table_data[ $row_idx ][ $col_idx ] = $this->_evaluate_cell( $this->table_data[ $row_idx ][ $col_idx ] );
      }
    }

    return $data;
  }

  /**
   * Parse and evaluate the content of a cell.
   *
   * @since 1.0.0
   *
   * @param string $content Content of a cell.
   * @param array  $parents Optional. List of cells that depend on this cell (to prevent circle references).
   * @return string Result of the parsing/evaluation.
   */
  public function _evaluate_cell( $content, array $parents = array() ) {
    if ( '' === $content || '=' === $content || '=' !== $content[0] ) {
      return $content;
    }

    // Cut off the leading =.
    $content = substr( $content, 1 );

    // Support putting formulas in strings, like =Total: {A3+A4}.
    $expressions = array();
    if ( preg_match_all( '#{(.+?)}#', $content, $expressions, PREG_SET_ORDER ) ) {
      $formula_in_string = true;
    } else {
      $formula_in_string = false;
      // Fill array so that it has the same structure as if it came from preg_match_all().
      $expressions[] = array( $content, $content );
    }

    foreach ( $expressions as $expression ) {
      $orig_expression = $expression[0];
      $expression = $expression[1];

      $replaced_references = $replaced_ranges = array();

      // Remove all whitespace characters.
      $expression = str_replace( array( "\n", "\r", "\t", ' ' ), '', $expression );

      // Expand cell ranges (like A3:A6) to a list of single cells (like A3,A4,A5,A6).
      if ( preg_match_all( '#([A-Z]+)([0-9]+):([A-Z]+)([0-9]+)#', $expression, $referenced_cell_ranges, PREG_SET_ORDER ) ) {
        foreach ( $referenced_cell_ranges as $cell_range ) {
          if ( in_array( $cell_range[0], $replaced_ranges, true ) ) {
            continue;
          }

          $replaced_ranges[] = $cell_range[0];

          if ( isset( $this->known_ranges[ $cell_range[0] ] ) ) {
            $expression = preg_replace( '#(?<![A-Z])' . preg_quote( $cell_range[0], '#' ) . '(?![0-9])#', $this->known_ranges[ $cell_range[0] ], $expression );
            continue;
          }

          // No -1 necessary for this transformation, as we don't actually access the table.
          $first_col = TablePress::letter_to_number( $cell_range[1] );
          $first_row = $cell_range[2];
          $last_col = TablePress::letter_to_number( $cell_range[3] );
          $last_row = $cell_range[4];

          $col_start = min( $first_col, $last_col );
          $col_end = max( $first_col, $last_col ) + 1; // +1 for loop below
          $row_start = min( $first_row, $last_row );
          $row_end = max( $first_row, $last_row ) + 1; // +1 for loop below

          $cell_list = array();
          for ( $col = $col_start; $col < $col_end; $col++ ) {
            for ( $row = $row_start; $row < $row_end; $row++ ) {
              $column = TablePress::number_to_letter( $col );
              $cell_list[] = "{$column}{$row}";
            }
          }
          $cell_list = implode( ',', $cell_list );

          $expression = preg_replace( '#(?<![A-Z])' . preg_quote( $cell_range[0], '#' ) . '(?![0-9])#', $cell_list, $expression );
          $this->known_ranges[ $cell_range[0] ] = $cell_list;
        }
      }

      // Parse and evaluate single cell references (like A3 or XY312), while prohibiting circle references.
      if ( preg_match_all( '#([A-Z]+)([0-9]+)#', $expression, $referenced_cells, PREG_SET_ORDER ) ) {
        foreach ( $referenced_cells as $cell_reference ) {
          if ( in_array( $cell_reference[0], $parents, true ) ) {
            return '!ERROR! Circle Reference';
          }

          if ( in_array( $cell_reference[0], $replaced_references, true ) ) {
            continue;
          }

          $replaced_references[] = $cell_reference[0];

          $ref_col = TablePress::letter_to_number( $cell_reference[1] ) - 1;
          $ref_row = $cell_reference[2] - 1;

          if ( ! isset( $this->table_data[ $ref_row ] ) || ! isset( $this->table_data[ $ref_row ][ $ref_col ] ) ) {
            return "!ERROR! Cell {$cell_reference[0]} does not exist";
          }

          $ref_parents = $parents;
          $ref_parents[] = $cell_reference[0];

          $result = $this->table_data[ $ref_row ][ $ref_col ] = $this->_evaluate_cell( $this->table_data[ $ref_row ][ $ref_col ], $ref_parents );
          // Bail if there was an error already.
          if ( false !== strpos( $result, '!ERROR!' ) ) {
            return $result;
          }
          // Remove all whitespace characters.
          $result = str_replace( array( "\n", "\r", "\t", ' ' ), '', $result );
          // Treat empty cells as 0.
          if ( '' === $result ) {
            $result = 0;
          }
          // Bail if the cell does not result in a number (meaning it was a number or expression before being evaluated).
          if ( ! is_numeric( $result ) ) {
            return "!ERROR! {$cell_reference[0]} does not contain a number or expression";
          }

          $expression = preg_replace( '#(?<![A-Z])' . $cell_reference[0] . '(?![0-9])#', $result, $expression );
        }
      }

      $result = $this->_evaluate_math_expression( $expression );
      // Support putting formulas in strings, like =Total: {A3+A4}.
      if ( $formula_in_string ) {
        $content = str_replace( $orig_expression, $result, $content );
      } else {
        $content = $result;
      }
    }

    return $content;
  }

  /**
   * Evaluate a math expression.
   *
   * @since 1.0.0
   *
   * @param string $expression without leading = sign.
   * @return string Result of the evaluation.
   */
  public function _evaluate_math_expression( $expression ) {
    // Straight up evaluation, without parsing of variable or function assignments (which is why we only need one instance of the object).

    $result = $this->evalmath->evaluate( $expression );
    if ( false === $result ) {
      return '!ERROR! ' . $this->evalmath->last_error;
    } else {
      return (string) $result;
    }
  }

}

I am updating the in value in the update_option table.It is better cause you to have specific table id.

get_option('table_press' .$table_id); // get the id so now you can use any where in the shortcode.

get_option('table_press' .$table_name ."_". $table_id); // get sum of table press specific name and id

i am also answer your question from here. I will brief you how use this in that question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.