PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.8.3
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.8.3
8.8.3 8.8.2 8.8.1 8.8.0 8.7.9 8.7.8 8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 All 539 releases
← All changes | addons/automator/includes/actions/tables-actions.php +187 -187 8.7.9 → 8.8.3 View file →
@@ -1,187 +1,187 @@
1 -<?php
2 -/**
3 - * Tables Actions
4 - *
5 - * @package WPbot_Automator
6 - */
7 -
8 -namespace WPbot_Automator\Actions;
9 -
10 -use WPbot_Automator\Core\Tables;
11 -
12 -if ( ! defined( 'ABSPATH' ) ) {
13 - exit;
14 -}
15 -
16 -/**
17 - * Class Tables_Actions
18 - *
19 - * Provides workflow actions that read/write rows in user-created custom tables.
20 - *
21 - * Config fields expected in workflow_data:
22 - *
23 - * tables_insert_record:
24 - * table_id — numeric table ID (supports tokens, e.g. {table_id})
25 - * record_data — JSON object mapping column slugs to values, e.g.
26 - * {"name":"{user_name}","email":"{user_email}"}
27 - *
28 - * tables_update_record:
29 - * table_id — numeric table ID
30 - * row_id — row ID to update (supports tokens, e.g. {record_id})
31 - * record_data — JSON object with columns to update
32 - */
33 -class Tables_Actions extends Action {
34 -
35 - public function __construct() {
36 - $this->id = 'tables';
37 - $this->group = __( 'Tables', 'wpbot-automator' );
38 - }
39 -
40 - /**
41 - * Dispatch to the correct sub-action.
42 - */
43 - public function execute( $action_data, $trigger_data ) {
44 - $action_id = isset( $action_data['actionId'] ) ? $action_data['actionId'] : '';
45 -
46 - switch ( $action_id ) {
47 - case 'tables_insert_record':
48 - return $this->insert_record( $action_data, $trigger_data );
49 - case 'tables_update_record':
50 - return $this->update_record( $action_data, $trigger_data );
51 - default:
52 - return false;
53 - }
54 - }
55 -
56 - // ── Sub-actions ──────────────────────────────────────────────────────────
57 -
58 - /**
59 - * Insert a new record into a custom table.
60 - *
61 - * Returns array with 'record_id' on success, false on failure.
62 - */
63 - private function insert_record( $action_data, $trigger_data ) {
64 - global $wpdb;
65 -
66 - $config = isset( $action_data['config'] ) ? $action_data['config'] : array();
67 - $table_id = absint( $this->parse_tokens( isset( $config['table_id'] ) ? $config['table_id'] : '', $trigger_data ) );
68 -
69 - if ( ! $table_id ) {
70 - //error_log( 'WPbot Tables_Actions::insert_record — missing table_id.' );
71 - return false;
72 - }
73 -
74 - $table = Tables::get_table_meta_by_id( $table_id );
75 - if ( ! $table ) {
76 - //error_log( 'WPbot Tables_Actions::insert_record — table not found: ' . $table_id );
77 - return false;
78 - }
79 -
80 - $raw = ! empty( $config['record_data'] ) ? $config['record_data'] : '{}';
81 - $raw_json = $this->parse_tokens( $raw, $trigger_data );
82 - $record = json_decode( $raw_json, true );
83 -
84 - if ( ! is_array( $record ) ) {
85 - // Fallback: try to auto-map trigger data keys that match column slugs.
86 - $record = array();
87 - }
88 -
89 - // Auto-fill any column that still has no value from trigger data (slug must match).
90 - foreach ( $table['columns'] as $col ) {
91 - if ( ! isset( $record[ $col['slug'] ] ) && isset( $trigger_data[ $col['slug'] ] ) ) {
92 - $record[ $col['slug'] ] = $trigger_data[ $col['slug'] ];
93 - }
94 - }
95 -
96 - $clean = Tables::extract_record_data_public( $record, $table['columns'] );
97 - // Allow inserting with partial data — only require at least one column.
98 - if ( empty( $clean ) ) {
99 - //error_log( 'WPbot Tables_Actions::insert_record — no column data resolved (record_data empty and no trigger keys matched column slugs).' );
100 - return false;
101 - }
102 -
103 - $clean['created_at'] = current_time( 'mysql' );
104 - $clean['updated_at'] = current_time( 'mysql' );
105 -
106 - $ut = Tables::get_user_table( $table['slug'] );
107 - $wpdb->insert( $ut, $clean );
108 - $new_id = (int) $wpdb->insert_id;
109 -
110 - if ( ! $new_id ) {
111 - //error_log( 'WPbot Tables_Actions::insert_record — DB insert failed: ' . $wpdb->last_error );
112 - return false;
113 - }
114 -
115 - // Fire table trigger so workflows listening to "new_record" can chain.
116 - do_action( 'wpbot_table_new_record', $table_id, $table, $clean, $new_id );
117 -
118 - return array( 'record_id' => $new_id, 'table_id' => $table_id );
119 - }
120 -
121 - /**
122 - * Update an existing record in a custom table.
123 - *
124 - * Returns array with 'success' on success, false on failure.
125 - */
126 - private function update_record( $action_data, $trigger_data ) {
127 - global $wpdb;
128 -
129 - $config = isset( $action_data['config'] ) ? $action_data['config'] : array();
130 - $table_id = absint( $this->parse_tokens( isset( $config['table_id'] ) ? $config['table_id'] : '', $trigger_data ) );
131 - $row_id = absint( $this->parse_tokens( isset( $config['row_id'] ) ? $config['row_id'] : '', $trigger_data ) );
132 -
133 - if ( ! $table_id || ! $row_id ) {
134 - //error_log( 'WPbot Tables_Actions::update_record — missing table_id or row_id.' );
135 - return false;
136 - }
137 -
138 - $table = Tables::get_table_meta_by_id( $table_id );
139 - if ( ! $table ) {
140 - //error_log( 'WPbot Tables_Actions::update_record — table not found: ' . $table_id );
141 - return false;
142 - }
143 -
144 - $raw = ! empty( $config['record_data'] ) ? $config['record_data'] : '{}';
145 - $raw_json = $this->parse_tokens( $raw, $trigger_data );
146 - $record = json_decode( $raw_json, true );
147 -
148 - if ( ! is_array( $record ) ) {
149 - $record = array();
150 - }
151 -
152 - foreach ( $table['columns'] as $col ) {
153 - if ( ! isset( $record[ $col['slug'] ] ) && isset( $trigger_data[ $col['slug'] ] ) ) {
154 - $record[ $col['slug'] ] = $trigger_data[ $col['slug'] ];
155 - }
156 - }
157 -
158 - $clean = Tables::extract_record_data_public( $record, $table['columns'] );
159 - if ( empty( $clean ) ) {
160 - return false;
161 - }
162 -
163 - $clean['updated_at'] = current_time( 'mysql' );
164 -
165 - $ut = Tables::get_user_table( $table['slug'] );
166 - $old_record = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM `{$ut}` WHERE id = %d", $row_id ), ARRAY_A );
167 -
168 - $wpdb->update( $ut, $clean, array( 'id' => $row_id ) );
169 -
170 - // Fire per-cell change triggers.
171 - if ( is_array( $old_record ) ) {
172 - foreach ( $clean as $col_slug => $new_val ) {
173 - if ( in_array( $col_slug, array( 'updated_at' ), true ) ) {
174 - continue;
175 - }
176 - $old_val = $old_record[ $col_slug ] ?? null;
177 - if ( (string) $old_val !== (string) $new_val ) {
178 - do_action( 'wpbot_table_updated_cell', $table_id, $table, $row_id, $col_slug, $old_val, $new_val );
179 - }
180 - }
181 - }
182 -
183 - do_action( 'wpbot_table_updated_record', $table_id, $table, $clean, $row_id, $old_record );
184 -
185 - return array( 'success' => true, 'record_id' => $row_id );
186 - }
187 -}
1 +<?php
2 +/**
3 + * Tables Actions
4 + *
5 + * @package WPbot_Automator
6 + */
7 +
8 +namespace WPbot_Automator\Actions;
9 +
10 +use WPbot_Automator\Core\Tables;
11 +
12 +if ( ! defined( 'ABSPATH' ) ) {
13 + exit;
14 +}
15 +
16 +/**
17 + * Class Tables_Actions
18 + *
19 + * Provides workflow actions that read/write rows in user-created custom tables.
20 + *
21 + * Config fields expected in workflow_data:
22 + *
23 + * tables_insert_record:
24 + * table_id — numeric table ID (supports tokens, e.g. {table_id})
25 + * record_data — JSON object mapping column slugs to values, e.g.
26 + * {"name":"{user_name}","email":"{user_email}"}
27 + *
28 + * tables_update_record:
29 + * table_id — numeric table ID
30 + * row_id — row ID to update (supports tokens, e.g. {record_id})
31 + * record_data — JSON object with columns to update
32 + */
33 +class Tables_Actions extends Action {
34 +
35 + public function __construct() {
36 + $this->id = 'tables';
37 + $this->group = __( 'Tables', 'wpbot-automator' );
38 + }
39 +
40 + /**
41 + * Dispatch to the correct sub-action.
42 + */
43 + public function execute( $action_data, $trigger_data ) {
44 + $action_id = isset( $action_data['actionId'] ) ? $action_data['actionId'] : '';
45 +
46 + switch ( $action_id ) {
47 + case 'tables_insert_record':
48 + return $this->insert_record( $action_data, $trigger_data );
49 + case 'tables_update_record':
50 + return $this->update_record( $action_data, $trigger_data );
51 + default:
52 + return false;
53 + }
54 + }
55 +
56 + // ── Sub-actions ──────────────────────────────────────────────────────────
57 +
58 + /**
59 + * Insert a new record into a custom table.
60 + *
61 + * Returns array with 'record_id' on success, false on failure.
62 + */
63 + private function insert_record( $action_data, $trigger_data ) {
64 + global $wpdb;
65 +
66 + $config = isset( $action_data['config'] ) ? $action_data['config'] : array();
67 + $table_id = absint( $this->parse_tokens( isset( $config['table_id'] ) ? $config['table_id'] : '', $trigger_data ) );
68 +
69 + if ( ! $table_id ) {
70 + //error_log( 'WPbot Tables_Actions::insert_record — missing table_id.' );
71 + return false;
72 + }
73 +
74 + $table = Tables::get_table_meta_by_id( $table_id );
75 + if ( ! $table ) {
76 + //error_log( 'WPbot Tables_Actions::insert_record — table not found: ' . $table_id );
77 + return false;
78 + }
79 +
80 + $raw = ! empty( $config['record_data'] ) ? $config['record_data'] : '{}';
81 + $raw_json = $this->parse_tokens( $raw, $trigger_data );
82 + $record = json_decode( $raw_json, true );
83 +
84 + if ( ! is_array( $record ) ) {
85 + // Fallback: try to auto-map trigger data keys that match column slugs.
86 + $record = array();
87 + }
88 +
89 + // Auto-fill any column that still has no value from trigger data (slug must match).
90 + foreach ( $table['columns'] as $col ) {
91 + if ( ! isset( $record[ $col['slug'] ] ) && isset( $trigger_data[ $col['slug'] ] ) ) {
92 + $record[ $col['slug'] ] = $trigger_data[ $col['slug'] ];
93 + }
94 + }
95 +
96 + $clean = Tables::extract_record_data_public( $record, $table['columns'] );
97 + // Allow inserting with partial data — only require at least one column.
98 + if ( empty( $clean ) ) {
99 + //error_log( 'WPbot Tables_Actions::insert_record — no column data resolved (record_data empty and no trigger keys matched column slugs).' );
100 + return false;
101 + }
102 +
103 + $clean['created_at'] = current_time( 'mysql' );
104 + $clean['updated_at'] = current_time( 'mysql' );
105 +
106 + $ut = Tables::get_user_table( $table['slug'] );
107 + $wpdb->insert( $ut, $clean );
108 + $new_id = (int) $wpdb->insert_id;
109 +
110 + if ( ! $new_id ) {
111 + //error_log( 'WPbot Tables_Actions::insert_record — DB insert failed: ' . $wpdb->last_error );
112 + return false;
113 + }
114 +
115 + // Fire table trigger so workflows listening to "new_record" can chain.
116 + do_action( 'wpbot_table_new_record', $table_id, $table, $clean, $new_id );
117 +
118 + return array( 'record_id' => $new_id, 'table_id' => $table_id );
119 + }
120 +
121 + /**
122 + * Update an existing record in a custom table.
123 + *
124 + * Returns array with 'success' on success, false on failure.
125 + */
126 + private function update_record( $action_data, $trigger_data ) {
127 + global $wpdb;
128 +
129 + $config = isset( $action_data['config'] ) ? $action_data['config'] : array();
130 + $table_id = absint( $this->parse_tokens( isset( $config['table_id'] ) ? $config['table_id'] : '', $trigger_data ) );
131 + $row_id = absint( $this->parse_tokens( isset( $config['row_id'] ) ? $config['row_id'] : '', $trigger_data ) );
132 +
133 + if ( ! $table_id || ! $row_id ) {
134 + //error_log( 'WPbot Tables_Actions::update_record — missing table_id or row_id.' );
135 + return false;
136 + }
137 +
138 + $table = Tables::get_table_meta_by_id( $table_id );
139 + if ( ! $table ) {
140 + //error_log( 'WPbot Tables_Actions::update_record — table not found: ' . $table_id );
141 + return false;
142 + }
143 +
144 + $raw = ! empty( $config['record_data'] ) ? $config['record_data'] : '{}';
145 + $raw_json = $this->parse_tokens( $raw, $trigger_data );
146 + $record = json_decode( $raw_json, true );
147 +
148 + if ( ! is_array( $record ) ) {
149 + $record = array();
150 + }
151 +
152 + foreach ( $table['columns'] as $col ) {
153 + if ( ! isset( $record[ $col['slug'] ] ) && isset( $trigger_data[ $col['slug'] ] ) ) {
154 + $record[ $col['slug'] ] = $trigger_data[ $col['slug'] ];
155 + }
156 + }
157 +
158 + $clean = Tables::extract_record_data_public( $record, $table['columns'] );
159 + if ( empty( $clean ) ) {
160 + return false;
161 + }
162 +
163 + $clean['updated_at'] = current_time( 'mysql' );
164 +
165 + $ut = Tables::get_user_table( $table['slug'] );
166 + $old_record = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM `{$ut}` WHERE id = %d", $row_id ), ARRAY_A );
167 +
168 + $wpdb->update( $ut, $clean, array( 'id' => $row_id ) );
169 +
170 + // Fire per-cell change triggers.
171 + if ( is_array( $old_record ) ) {
172 + foreach ( $clean as $col_slug => $new_val ) {
173 + if ( in_array( $col_slug, array( 'updated_at' ), true ) ) {
174 + continue;
175 + }
176 + $old_val = $old_record[ $col_slug ] ?? null;
177 + if ( (string) $old_val !== (string) $new_val ) {
178 + do_action( 'wpbot_table_updated_cell', $table_id, $table, $row_id, $col_slug, $old_val, $new_val );
179 + }
180 + }
181 + }
182 +
183 + do_action( 'wpbot_table_updated_record', $table_id, $table, $clean, $row_id, $old_record );
184 +
185 + return array( 'success' => true, 'record_id' => $row_id );
186 + }
187 +}