Create a table programmatically (PHP function)
-
Hi. Thanks for all your work on this plugin.
I’m trying to create a PHP function that creates tables programatically. Basically, every time a Woocommerce product is published, a table with the same name should be created. I’ve tested the trigger which works but tables are not created. I tried to read through the documentation and GitHub but couldn’t really find any answers. I feel like there’s probably a simple fix or a hook that’s not quite right. Here’s what I have so far:
function create_tablepress_table_for_sport_product( $post_id ) {
// Check if the published post is a "main" product
$product = wc_get_product( $post_id );
if ( ! $product || ! has_term( 'main', 'product_cat', $product ) ) {
return;
}
// Get the product name
$product_name = $product->get_name();
// Create the TablePress table
$table_args = array(
'post_type' => 'tablepress_table',
'post_title' => $product_name,
'post_status' => 'publish',
);
$table_id = wp_insert_post( $table_args );
}
add_action( 'publish_product', 'create_tablepress_table_for_sport_product' );Appreciate any help you can offer to clarify the issue here. Thanks in advance!
-
This topic was modified 3 months, 3 weeks ago by
glabs.
-
This topic was modified 3 months, 3 weeks ago by
-
Hi!
Thanks for your post and sorry for the trouble!
Your code would indeed only add the table data internally, to the database, without any table data, and without TablePress then knowing that this database entry exists.
My recommendation here is to follow the code process from https://github.com/TablePress/TablePress/blob/3.0.2/controllers/controller-admin.php#L888-L907.
Best wishes,
TobiasThanks for the quick reply and pointing me in the right direction. I tried updating the code but it doesn’t seem to be working:
/**
* Create a TablePress table when a "main" product is published.
*/
function create_tablepress_table_for_sport_product( $post_id ) {
// Check if the published post is a "main" product
$product = wc_get_product( $post_id );
if ( ! $product || ! has_term( 'main', 'product_cat', $product ) ) {
return;
}
// Get the product name
$product_name = $product->get_name();
// Create the TablePress table
$new_table = array(
'name' => $product_name,
'description' => 'Standings for: ' . $product_name,
'data' => array_fill( 0, $num_rows, array_fill( 0, $num_columns, '' ) ),
'visibility' => array(
'rows' => array_fill( 0, $num_rows, 1 ),
'columns' => array_fill( 0, $num_columns, 1 ),
),
);
// Merge this data into an empty table template.
$table = TablePress::$model_table->prepare_table( TablePress::$model_table->get_table_template(), $new_table, false );
if ( is_wp_error( $table ) ) {
TablePress::redirect( array( 'action' => 'add', 'message' => 'error_add', 'error_details' => TablePress::get_wp_error_string( $table ) ) );
}
// Add the new table (and get its first ID).
$table_id = TablePress::$model_table->add( $table );
if ( is_wp_error( $table_id ) ) {
TablePress::redirect( array( 'action' => 'add', 'message' => 'error_add', 'error_details' => TablePress::get_wp_error_string( $table_id ) ) );
}
}
// Hook the function to the 'publish_product' action
add_action( 'publish_product', 'create_tablepress_table_for_sport_product' );Where am I going wrong?
Hi,
well, just changing the name and the description will not be enough here 🙂 You would also need to configure the table size, via the
$num_columns
and$num_rows
variables. Also, the error handling should be adjusted, as calling theredirect
function from TablePress does not really make sense here.Best wishes,
TobiasThanks, Tobias. Appreciate your help. We’re planning on upgrading to the pro version of the plugin but wanted to confirm that this would work there as well. Please let me know. We updated our code but still can’t get it working. I’m sure we’re missing something simple but haven’t been able to figure it out.
/**
* Create a TablePress table when a "main" product is published.
*/
function create_tablepress_table_for_sport_product( $post_id ) {
// Check if the published post is a "main" product
$product = wc_get_product( $post_id );
if ( ! $product || ! has_term( 'main', 'product_cat', $product ) ) {
return;
}
// Get the product name
$product_name = $product->get_name();
// Define table dimensions
$num_columns = 5;
$num_rows = 10;
// Create the TablePress table data
$new_table = array(
'name' => $product_name,
'description' => 'Standings for: ' . $product_name,
'data' => array_fill( 0, $num_rows, array_fill( 0, $num_columns, '' ) ),
'visibility' => array(
'rows' => array_fill( 0, $num_rows, 1 ),
'columns' => array_fill( 0, $num_columns, 1 ),
),
);
// Get the TablePress model
$tablepress_model = TablePress::$model_table;
// Merge this data into an empty table template.
$table = $tablepress_model->prepare_table( $tablepress_model->get_table_template(), $new_table, false );
if ( is_wp_error( $table ) ) {
error_log( 'Error preparing TablePress table "' . $product_name . '": ' . $table->get_error_message() );
return false;
}
// Add the new table (and get its first ID).
$table_id = $tablepress_model->add( $table );
if ( is_wp_error( $table_id ) ) {
error_log( 'Error creating TablePress table "' . $product_name . '": ' . $table_id->get_error_message() );
return false;
}
return true;
}
// Hook the function to the 'publish_product' action
add_action( 'publish_product', 'create_tablepress_table_for_sport_product' );Hi,
sure, this will work with the TablePress premium versions as well! These use the same functions for adding/saving tables.
I can’t spot any obvious errors here, but from what I can see, you are on a good track already, with debugging in the error log. I suggest continuing with that step by step, or rather line by line. You might want to start with a check on whether that action hook handler actually gets executed.
Best wishes,
TobiasHi Tobias! It’s been a while but we made progress on this and were able to create the tables using the code below. Now, we’re trying to do one last thing which is to change the created table’s ID to match the product slug so that we can automatically embed these tables. We’ve tried iterating through a few different approaches but can’t seem to quite get that table ID to change programatically. What do you think?
/**
* Create a TablePress table when a "main" product is published.
*/
function create_tablepress_table_for_main_product( $post_id ) {
error_log( 'create_tablepress_table_for_main_product function called! Post ID: ' . $post_id );
// Check if the published post is a "main" product
$product = wc_get_product( $post_id );
if ( ! $product || ! has_term( 'main', 'product_cat', $post_id ) ) {
error_log('Product does not have term "main"');
return;
}
// Get the product name and slug
$product_name = $product->get_name();
$product_slug = $product->get_slug();
// Define table dimensions
$num_columns = 5;
$num_rows = 10;
// Create the TablePress table data
$new_table = array(
'name' => $product_name,
'description' => 'Table for: ' . $product_name,
'data' => array_fill( 0, $num_rows, array_fill( 0, $num_columns, '' ) ),
'visibility' => array(
'rows' => array_fill( 0, $num_rows, 1 ),
'columns' => array_fill( 0, $num_columns, 1 ),
),
);
// Get the TablePress model
$tablepress_model = TablePress::$model_table;
// Merge this data into an empty table template.
$table = $tablepress_model->prepare_table( $tablepress_model->get_table_template(), $new_table, false );
if ( is_wp_error( $table ) ) {
error_log( 'Error preparing TablePress table "' . $product_name . '": ' . $table->get_error_message() );
return false;
}
// Add the new table.
$table_id = $tablepress_model->add( $table );
if ( is_wp_error( $table_id ) ) {
error_log( 'Error creating TablePress table "' . $product_name . '": ' . $table_id->get_error_message() );
return false;
}
// Update the table ID directly in the database
global $wpdb;
$table_name = $wpdb->prefix . 'tablepress_tables';
$wpdb->update(
$table_name,
array( 'id' => $product_slug ), // New table ID
array( 'id' => $table_id ) // WHERE clause: internal table ID
);
if ( $wpdb->last_error ) {
error_log( 'Error updating TablePress table ID: ' . $wpdb->last_error );
}
return true;
}
// Hook the function to the 'publish_product' action
add_action( 'publish_product', 'create_tablepress_table_for_sport_product' );Scratch that. We were able to resolve it with this:
// Get the new table's post ID by querying the database directly
global $wpdb;
$new_table_post_id = $wpdb->get_var( $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = 'tablepress_table' AND post_title = %s ORDER BY ID DESC LIMIT 1",
$product_name
) );
if ( ! $new_table_post_id ) {
error_log( 'Failed to retrieve post ID for TablePress table: ' . $product_name );
return false;
}
// Update the tablepress_tables option with the custom table ID
$tablepress_tables_json = get_option( 'tablepress_tables' );
if ( is_string( $tablepress_tables_json ) ) {
$tablepress_tables_option = json_decode( $tablepress_tables_json, true );
} else {
$tablepress_tables_option = array( 'last_id' => 0, 'table_post' => array() );
}
if ( ! is_array( $tablepress_tables_option ) ) {
$tablepress_tables_option = array( 'last_id' => 0, 'table_post' => array() );
}
// Check if the slug already exists to avoid duplicates
foreach ( $tablepress_tables_option['table_post'] as $key => $value ) {
if ( $key === $product_slug ) {
error_log( 'Table for slug "' . $product_slug . '" already exists. Skipping creation.' );
return;
}
}
// Remove any existing key with the same post_id to avoid duplicates
foreach ( $tablepress_tables_option['table_post'] as $key => $value ) {
if ( (string)$value === (string)$new_table_post_id ) {
unset( $tablepress_tables_option['table_post'][ $key ] );
}
}
// Add the new mapping
$tablepress_tables_option['table_post'][ $product_slug ] = $new_table_post_id;
// Save the updated option as JSON
if ( ! update_option( 'tablepress_tables', wp_json_encode( $tablepress_tables_option ) ) ) {
error_log( 'Failed to update the tablepress_tables option.' );
}
error_log( 'TablePress table created with ID: ' . $table_id . ', name: ' . $product_name . ', slug-based ID: ' . $product_slug );
return true;
}Hi,
I really don’t recommend directly modifying the option value. Please use the TablePress PHP functions instead, see e.g. https://github.com/TablePress/TablePress/blob/3.1.1/controllers/controller-admin_ajax.php#L142-L160
Best wishes,
Tobias
- You must be logged in to reply to this topic.