connect_error ) { throw new RuntimeException( 'Integration test DB connection failed: ' . $_mysqli_init->connect_error ); } $_db_name_quoted = '`' . str_replace( '`', '``', $_db_name ) . '`'; if ( ! $_mysqli_init->query( "CREATE DATABASE IF NOT EXISTS {$_db_name_quoted} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" ) ) { throw new RuntimeException( "Failed to create test database '{$_db_name}': " . $_mysqli_init->error ); } $_mysqli_init->close(); unset( $_mysqli_init, $_db_name_quoted ); $_mysqli = new mysqli( $_db_host, $_db_user, $_db_pass, $_db_name ); if ( $_mysqli->connect_error ) { throw new RuntimeException( 'Integration test DB connection failed: ' . $_mysqli->connect_error ); } $_mysqli->set_charset( 'utf8mb4' ); // ── Real $wpdb ───────────────────────────────────────────────────────────── global $wpdb; $wpdb = new class( $_mysqli ) { private mysqli $db; public string $prefix = 'wp_itest_'; public string $postmeta = 'wp_itest_postmeta'; public string $posts = 'wp_itest_posts'; public string $options = 'wp_itest_options'; public string $usermeta = 'wp_itest_usermeta'; public string $users = 'wp_itest_users'; public string $terms = 'wp_itest_terms'; public string $termmeta = 'wp_itest_termmeta'; public string $comments = 'wp_itest_comments'; public string $commentmeta = 'wp_itest_commentmeta'; public int $insert_id = 0; public string $last_error = ''; public function __construct( mysqli $db ) { $this->db = $db; } public function prepare( string $sql, ...$args ): string { $i = 0; return preg_replace_callback( '/%([sdf])/', function ( $m ) use ( &$i, $args ) { $val = $args[ $i++ ] ?? ''; if ( $m[1] === 'd' ) { return (string) (int) $val; } if ( $m[1] === 'f' ) { return (string) (float) $val; } return "'" . $this->db->real_escape_string( (string) $val ) . "'"; }, $sql ); } public function get_var( string $sql ): ?string { $result = $this->db->query( $sql ); if ( ! $result || ! ( $row = $result->fetch_row() ) ) { return null; } return $row[0] !== null ? (string) $row[0] : null; } public function get_row( string $sql, $output = 'OBJECT' ) { $result = $this->db->query( $sql ); if ( ! $result ) { return null; } return ARRAY_A === $output ? ( $result->fetch_assoc() ?: null ) : ( $result->fetch_object() ?: null ); } public function get_results( string $sql, $output = 'OBJECT' ): array { $result = $this->db->query( $sql ); if ( ! $result ) { return []; } $rows = []; while ( $row = ( ARRAY_A === $output ? $result->fetch_assoc() : $result->fetch_object() ) ) { $rows[] = $row; } return $rows; } public function get_col( string $sql, int $col_index = 0 ): array { $result = $this->db->query( $sql ); if ( ! $result ) { return []; } $values = []; while ( $row = $result->fetch_row() ) { $values[] = $row[ $col_index ] ?? null; } return $values; } public function get_charset_collate(): string { return 'DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci'; } public function insert( string $table, array $data, $format = null ): int|false { $cols = implode( ', ', array_map( fn( $c ) => '`' . $c . '`', array_keys( $data ) ) ); $vals = implode( ', ', array_map( fn( $v ) => $v === null ? 'NULL' : "'" . $this->db->real_escape_string( (string) $v ) . "'", array_values( $data ) ) ); $ok = $this->db->query( "INSERT INTO `{$table}` ({$cols}) VALUES ({$vals})" ); if ( $ok ) { $this->insert_id = (int) $this->db->insert_id; return $this->insert_id; } $this->last_error = (string) $this->db->error; return false; } public function update( string $table, array $data, array $where, $format = null, $wf = null ): int|false { $set = implode( ', ', array_map( fn( $k, $v ) => '`' . $k . '` = ' . ( $v === null ? 'NULL' : "'" . $this->db->real_escape_string( (string) $v ) . "'" ), array_keys( $data ), $data ) ); $cond = implode( ' AND ', array_map( fn( $k, $v ) => '`' . $k . '` = ' . ( $v === null ? 'NULL' : "'" . $this->db->real_escape_string( (string) $v ) . "'" ), array_keys( $where ), $where ) ); $ok = $this->db->query( "UPDATE `{$table}` SET {$set} WHERE {$cond}" ); return $ok ? $this->db->affected_rows : false; } public function delete( string $table, array $where, $format = null ): int|false { $cond = implode( ' AND ', array_map( fn( $k, $v ) => '`' . $k . '` = ' . ( $v === null ? 'NULL' : "'" . $this->db->real_escape_string( (string) $v ) . "'" ), array_keys( $where ), $where ) ); $ok = $this->db->query( "DELETE FROM `{$table}` WHERE {$cond}" ); return $ok ? $this->db->affected_rows : false; } public function replace( string $table, array $data, $format = null ): int|false { $cols = implode( ', ', array_map( fn( $c ) => '`' . $c . '`', array_keys( $data ) ) ); $vals = implode( ', ', array_map( fn( $v ) => $v === null ? 'NULL' : "'" . $this->db->real_escape_string( (string) $v ) . "'", array_values( $data ) ) ); $ok = $this->db->query( "REPLACE INTO `{$table}` ({$cols}) VALUES ({$vals})" ); if ( $ok ) { $this->insert_id = (int) $this->db->insert_id; return $this->db->affected_rows; } $this->last_error = (string) $this->db->error; return false; } public function esc_like( string $s ): string { return addcslashes( $s, '_%\\' ); } public function flush(): void {} public function query( string $sql ): int|bool { $result = $this->db->query( $sql ); if ( $result instanceof mysqli_result ) { $result->free(); return true; } if ( false === $result ) { return false; } return $this->db->affected_rows; } }; // ── WordPress function stubs ─────────────────────────────────────────────── if ( ! function_exists( 'trailingslashit' ) ) { function trailingslashit( string $s ): string { return rtrim( $s, '/' ) . '/'; } } if ( ! function_exists( 'sanitize_key' ) ) { function sanitize_key( string $key ): string { return strtolower( preg_replace( '/[^a-z0-9_\-]/', '', $key ) ); } } if ( ! function_exists( 'absint' ) ) { function absint( $v ): int { return abs( (int) $v ); } } if ( ! function_exists( 'wp_unslash' ) ) { function wp_unslash( $v ) { return is_string( $v ) ? stripslashes( $v ) : $v; } } if ( ! function_exists( 'esc_like' ) ) { function esc_like( string $s ): string { return addcslashes( $s, '_%\\' ); } } if ( ! function_exists( 'current_time' ) ) { function current_time( string $type, bool $gmt = false ): string|int { if ( 'timestamp' === $type || 'U' === $type ) { return time(); } return gmdate( 'Y-m-d H:i:s' ); } } if ( ! function_exists( 'wp_parse_args' ) ) { function wp_parse_args( $args, array $defaults = [] ): array { if ( is_string( $args ) ) { parse_str( $args, $args ); } return array_merge( $defaults, (array) $args ); } } $GLOBALS['_wp_filter_callbacks'] = []; if ( ! function_exists( 'add_filter' ) ) { function add_filter( string $hook, $cb, int $p = 10, int $a = 1 ): bool { $GLOBALS['_wp_filter_callbacks'][ $hook ][] = $cb; return true; } } if ( ! function_exists( 'add_action' ) ) { function add_action( string $hook, $cb, int $p = 10, int $a = 1 ): bool { $GLOBALS['_wp_filter_callbacks'][ $hook ][] = $cb; return true; } } if ( ! function_exists( 'remove_filter' ) ) { function remove_filter( string $hook, $cb, int $p = 10 ): bool { if ( isset( $GLOBALS['_wp_filter_callbacks'][ $hook ] ) ) { $GLOBALS['_wp_filter_callbacks'][ $hook ] = array_values( array_filter( $GLOBALS['_wp_filter_callbacks'][ $hook ], fn( $c ) => $c !== $cb ) ); } return true; } } if ( ! function_exists( 'apply_filters' ) ) { function apply_filters( string $hook, $value, ...$args ) { foreach ( $GLOBALS['_wp_filter_callbacks'][ $hook ] ?? [] as $cb ) { $value = $cb( $value, ...$args ); } return $value; } } if ( ! function_exists( 'do_action' ) ) { function do_action( string $hook, ...$args ): void { foreach ( $GLOBALS['_wp_filter_callbacks'][ $hook ] ?? [] as $cb ) { $cb( ...$args ); } } } if ( ! function_exists( 'is_admin' ) ) { function is_admin(): bool { return ! empty( $GLOBALS['_wp_is_admin'] ); } } if ( ! function_exists( 'is_singular' ) ) { function is_singular( $t = '' ): bool { return false; } } if ( ! function_exists( 'wp_doing_ajax' ) ) { function wp_doing_ajax(): bool { return false; } } if ( ! function_exists( 'wp_next_scheduled' ) ) { function wp_next_scheduled( string $hook ): int|false { return false; } } if ( ! function_exists( 'wp_schedule_event' ) ) { function wp_schedule_event( int $t, string $r, string $h ): bool { return true; } } if ( ! function_exists( 'wp_schedule_single_event' ) ) { function wp_schedule_single_event( int $ts, string $hook ): bool { return true; } } if ( ! function_exists( 'wp_clear_scheduled_hook' ) ) { function wp_clear_scheduled_hook( string $hook ): int|false { return 0; } } if ( ! function_exists( 'sanitize_text_field' ) ) { function sanitize_text_field( string $s ): string { return trim( strip_tags( $s ) ); } } if ( ! function_exists( '__' ) ) { function __( string $text, string $domain = 'default' ): string { return $text; } } if ( ! function_exists( 'esc_html' ) ) { function esc_html( $s ): string { return htmlspecialchars( (string) $s, ENT_QUOTES, 'UTF-8' ); } } if ( ! function_exists( 'esc_attr' ) ) { function esc_attr( string $s ): string { return htmlspecialchars( $s, ENT_QUOTES, 'UTF-8' ); } } if ( ! function_exists( 'esc_url' ) ) { function esc_url( string $url ): string { return filter_var( $url, FILTER_SANITIZE_URL ) ?: ''; } } if ( ! function_exists( 'esc_sql' ) ) { function esc_sql( $s ): string { return addslashes( is_string( $s ) ? $s : (string) $s ); } } if ( ! function_exists( '_doing_it_wrong' ) ) { function _doing_it_wrong( string $fn, string $msg, string $ver ): void {} } if ( ! function_exists( 'wp_strip_all_tags' ) ) { function wp_strip_all_tags( string $s ): string { return strip_tags( $s ); } } if ( ! function_exists( 'get_option' ) ) { function get_option( string $key, $default = false ) { return $GLOBALS['_wp_options'][ $key ] ?? $default; } } if ( ! function_exists( 'update_option' ) ) { function update_option( string $key, $value ): bool { $GLOBALS['_wp_options'][ $key ] = $value; return true; } } if ( ! function_exists( 'delete_option' ) ) { function delete_option( string $key ): bool { unset( $GLOBALS['_wp_options'][ $key ] ); return true; } } if ( ! function_exists( 'get_transient' ) ) { function get_transient( string $key ) { return $GLOBALS['_wp_transients'][ $key ] ?? false; } } if ( ! function_exists( 'set_transient' ) ) { function set_transient( string $key, $value, int $exp = 0 ): bool { $GLOBALS['_wp_transients'][ $key ] = $value; return true; } } if ( ! function_exists( 'delete_transient' ) ) { function delete_transient( string $key ): bool { unset( $GLOBALS['_wp_transients'][ $key ] ); return true; } } if ( ! function_exists( 'get_post_meta' ) ) { function get_post_meta( int $post_id, string $key = '', bool $single = false ) { return $GLOBALS['_wp_postmeta'][ $post_id ][ $key ] ?? ( $single ? '' : [] ); } } if ( ! function_exists( 'update_post_meta' ) ) { function update_post_meta( int $post_id, string $key, $value, $prev = '' ): int|bool { global $wpdb; $has_table = (bool) $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->postmeta ) ); if ( $has_table ) { $existing = $wpdb->get_var( $wpdb->prepare( "SELECT meta_id FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = %s LIMIT 1", $post_id, $key ) ); if ( $existing ) { $wpdb->update( $wpdb->postmeta, array( 'meta_value' => is_scalar( $value ) ? (string) $value : maybe_serialize( $value ) ), array( 'meta_id' => $existing ) ); } else { $wpdb->insert( $wpdb->postmeta, array( 'post_id' => $post_id, 'meta_key' => $key, 'meta_value' => is_scalar( $value ) ? (string) $value : maybe_serialize( $value ) ) ); } } $GLOBALS['_wp_postmeta'][ $post_id ][ $key ] = $value; return true; } } if ( ! function_exists( 'get_user_meta' ) ) { function get_user_meta( int $uid, string $key = '', bool $single = false ) { return $GLOBALS['_wp_usermeta'][ $uid ][ $key ] ?? ( $single ? '' : [] ); } } if ( ! function_exists( 'update_user_meta' ) ) { function update_user_meta( int $uid, string $key, $value, $prev = '' ): bool { $GLOBALS['_wp_usermeta'][ $uid ][ $key ] = $value; return true; } } if ( ! function_exists( 'get_term_meta' ) ) { function get_term_meta( int $tid, string $key = '', bool $single = false ) { return $GLOBALS['_wp_termmeta'][ $tid ][ $key ] ?? ( $single ? '' : [] ); } } if ( ! function_exists( 'update_term_meta' ) ) { function update_term_meta( int $tid, string $key, $value, $prev = '' ): bool { $GLOBALS['_wp_termmeta'][ $tid ][ $key ] = $value; return true; } } if ( ! function_exists( 'get_comment_meta' ) ) { function get_comment_meta( int $cid, string $key = '', bool $single = false ) { return $GLOBALS['_wp_commentmeta'][ $cid ][ $key ] ?? ( $single ? '' : [] ); } } if ( ! function_exists( 'update_comment_meta' ) ) { function update_comment_meta( int $cid, string $key, $value, $prev = '' ): bool { $GLOBALS['_wp_commentmeta'][ $cid ][ $key ] = $value; return true; } } if ( ! function_exists( 'get_post_type' ) ) { function get_post_type( $post_id ) { return $GLOBALS['_wp_post_types'][ (int) $post_id ] ?? false; } } if ( ! function_exists( 'get_post_status' ) ) { function get_post_status( $post_id ) { return $GLOBALS['_wp_post_status'][ (int) $post_id ] ?? 'publish'; } } if ( ! function_exists( 'is_post_publicly_viewable' ) ) { function is_post_publicly_viewable( $post_id ): bool { if ( isset( $GLOBALS['_wp_post_publicly_viewable'][ (int) $post_id ] ) ) { return (bool) $GLOBALS['_wp_post_publicly_viewable'][ (int) $post_id ]; } return 'publish' === ( $GLOBALS['_wp_post_status'][ (int) $post_id ] ?? 'publish' ); } } if ( ! function_exists( 'current_user_can' ) ) { function current_user_can( string $cap, ...$args ): bool { if ( ! empty( $args ) ) { $key = $cap . ':' . implode( ',', array_map( 'strval', $args ) ); if ( isset( $GLOBALS['_wp_current_user_can'][ $key ] ) ) { return (bool) $GLOBALS['_wp_current_user_can'][ $key ]; } } return $GLOBALS['_wp_current_user_can'][ $cap ] ?? false; } } if ( ! function_exists( 'get_current_user_id' ) ) { function get_current_user_id(): int { return (int) ( $GLOBALS['_wp_current_user_id'] ?? 0 ); } } if ( ! function_exists( 'is_multisite' ) ) { function is_multisite(): bool { return (bool) ( $GLOBALS['_wp_is_multisite'] ?? false ); } } if ( ! function_exists( 'is_super_admin' ) ) { function is_super_admin( ?int $uid = null ): bool { return (bool) ( $GLOBALS['_wp_is_super_admin'] ?? false ); } } if ( ! function_exists( 'switch_to_blog' ) ) { function switch_to_blog( int $blog_id ): bool { $GLOBALS['_wp_current_blog_id'] = $blog_id; return true; } } if ( ! function_exists( 'restore_current_blog' ) ) { function restore_current_blog(): bool { unset( $GLOBALS['_wp_current_blog_id'] ); return true; } } if ( ! function_exists( 'get_sites' ) ) { function get_sites( array $args = [] ): array { return $GLOBALS['_wp_sites'] ?? []; } } if ( ! function_exists( 'is_plugin_active_for_network' ) ) { function is_plugin_active_for_network( string $plugin ): bool { return (bool) ( $GLOBALS['_wp_plugin_active_for_network'][ $plugin ] ?? false ); } } if ( ! function_exists( 'is_plugin_active' ) ) { function is_plugin_active( string $plugin ): bool { return false; } } if ( ! function_exists( 'deactivate_plugins' ) ) { function deactivate_plugins( $plugin, bool $silent = false ): void {} } if ( ! function_exists( 'plugin_basename' ) ) { function plugin_basename( string $file ): string { return basename( dirname( $file ) ) . '/' . basename( $file ); } } if ( ! function_exists( 'wp_generate_password' ) ) { function wp_generate_password( int $len = 12, bool $special = true ): string { return substr( str_replace( [ '/', '+', '=' ], '', base64_encode( random_bytes( $len ) ) ), 0, $len ); } } if ( ! function_exists( 'wp_json_encode' ) ) { function wp_json_encode( $data, int $flags = 0 ): string|false { return json_encode( $data, $flags ); } } if ( ! function_exists( 'wp_rand' ) ) { function wp_rand( int $min = 0, int $max = 0 ): int { return random_int( $min, $max ?: PHP_INT_MAX ); } } if ( ! function_exists( 'is_wp_error' ) ) { function is_wp_error( $thing ): bool { return $thing instanceof WP_Error; } } if ( ! function_exists( 'wp_verify_nonce' ) ) { function wp_verify_nonce( $nonce, string $action = '' ) { return $GLOBALS['_wp_valid_nonces'][ (string) $nonce ] ?? false; } } if ( ! function_exists( 'wp_create_nonce' ) ) { function wp_create_nonce( string $action = '' ): string { $nonce = 'test_nonce_' . md5( $action ); $GLOBALS['_wp_valid_nonces'][ $nonce ] = 1; return $nonce; } } if ( ! function_exists( 'wp_die' ) ) { function wp_die( $message = '' ): void { throw new RuntimeException( is_string( $message ) ? $message : 'wp_die' ); } } if ( ! function_exists( 'maybe_serialize' ) ) { function maybe_serialize( $data ) { return is_array( $data ) || is_object( $data ) ? serialize( $data ) : $data; } } if ( ! function_exists( 'maybe_unserialize' ) ) { function maybe_unserialize( $value ) { if ( ! is_string( $value ) ) { return $value; } $u = @unserialize( $value ); return ( false !== $u || 'b:0;' === $value ) ? $u : $value; } } if ( ! function_exists( 'get_bloginfo' ) ) { function get_bloginfo( string $key ): string { return 'version' === $key ? '6.9.4' : ''; } } if ( ! function_exists( 'sanitize_title' ) ) { function sanitize_title( string $title ): string { return strtolower( preg_replace( '/[^a-z0-9-]+/i', '-', trim( $title ) ) ); } } if ( ! function_exists( 'taxonomy_exists' ) ) { function taxonomy_exists( string $taxonomy ): bool { if ( isset( $GLOBALS['_taxonomy_exists_override'] ) ) { return (bool) $GLOBALS['_taxonomy_exists_override']; } return in_array( $taxonomy, [ 'category', 'post_tag', 'listing_category', 'listing_tag' ], true ); } } if ( ! function_exists( 'clean_term_cache' ) ) { function clean_term_cache( $ids, string $taxonomy = '', bool $clean_taxonomy = true ): void {} } if ( ! function_exists( 'get_taxonomies' ) ) { function get_taxonomies( array $args = [], string $output = 'names' ): array { $taxonomies = [ 'category', 'post_tag', 'listing_category', 'listing_tag' ]; if ( 'objects' === $output ) { $out = []; foreach ( $taxonomies as $slug ) { $out[ $slug ] = (object) [ 'name' => $slug, 'labels' => (object) [ 'singular_name' => ucfirst( str_replace( '_', ' ', $slug ) ) ] ]; } return $out; } return $taxonomies; } } if ( ! function_exists( 'is_serialized' ) ) { function is_serialized( $data ): bool { return is_string( $data ) && strlen( $data ) >= 4 && in_array( $data[0], [ 'a', 's', 'i', 'd', 'b', 'O', 'N' ], true ) && str_ends_with( $data, ';' ); } } if ( ! function_exists( 'wp_upload_dir' ) ) { function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = false ): array { $upload_path = sys_get_temp_dir() . '/wp-uploads-test'; return [ 'path' => $upload_path, 'url' => 'http://localhost/wp-content/uploads', 'subdir' => '', 'basedir' => $upload_path, 'baseurl' => 'http://localhost/wp-content/uploads', 'error' => false, ]; } } if ( ! function_exists( 'wp_mkdir_p' ) ) { function wp_mkdir_p( string $dir ): bool { if ( is_dir( $dir ) ) { return true; } return mkdir( $dir, 0777, true ); } } $GLOBALS['_wp_cache'] = []; if ( ! function_exists( 'wp_cache_get' ) ) { function wp_cache_get( $key, $group = '' ) { return $GLOBALS['_wp_cache'][ $group ][ $key ] ?? false; } } if ( ! function_exists( 'wp_cache_set' ) ) { function wp_cache_set( $key, $value, $group = '', $ttl = 0 ): bool { $GLOBALS['_wp_cache'][ $group ][ $key ] = $value; return true; } } if ( ! function_exists( 'wp_cache_delete' ) ) { function wp_cache_delete( $key, $group = '' ): bool { unset( $GLOBALS['_wp_cache'][ $group ][ $key ] ); return true; } } if ( ! class_exists( 'WP_Query' ) ) { class WP_Query { private array $vars = []; public function get( string $key, $default = '' ) { return $this->vars[ $key ] ?? $default; } public function set( string $key, $value ): void { $this->vars[ $key ] = $value; } } } if ( ! class_exists( 'WP_Error' ) ) { class WP_Error { private string $code; private string $message; public function __construct( string $code = '', string $message = '' ) { $this->code = $code; $this->message = $message; } public function get_error_code(): string { return $this->code; } public function get_error_message(): string { return $this->message; } } } if ( ! class_exists( 'WP_REST_Request' ) ) { class WP_REST_Request { private array $params = []; private array $headers = []; public function __construct( string $method = 'GET', string $route = '' ) {} public function get_param( string $key ) { return $this->params[ $key ] ?? null; } public function set_param( string $key, $value ): void { $this->params[ $key ] = $value; } public function get_header( string $key ): ?string { return $this->headers[ strtolower( $key ) ] ?? null; } public function set_header( string $key, string $value ): void { $this->headers[ strtolower( $key ) ] = $value; } } } if ( ! class_exists( 'WP_REST_Response' ) ) { class WP_REST_Response { private $data; private int $status; private array $headers = []; public function __construct( $data = null, int $status = 200 ) { $this->data = $data; $this->status = $status; } public function get_data() { return $this->data; } public function get_status(): int { return $this->status; } public function header( string $k, string $v ): void { $this->headers[ $k ] = $v; } public function get_headers(): array { return $this->headers; } } } if ( ! class_exists( 'WP_REST_Server' ) ) { class WP_REST_Server { const READABLE = 'GET'; const CREATABLE = 'POST'; } } if ( ! function_exists( 'register_rest_route' ) ) { function register_rest_route( string $ns, string $route, array $args ): bool { return true; } } if ( ! function_exists( 'dbDelta' ) ) { function dbDelta( string $sql ): array { global $wpdb; $sql_idempotent = preg_replace( '/^CREATE TABLE/i', 'CREATE TABLE IF NOT EXISTS', trim( $sql ), 1 ); $wpdb->query( $sql_idempotent ); return []; } } if ( ! function_exists( 'wp_insert_post' ) ) { function wp_insert_post( array $postarr, bool $wp_error = false ) { global $wpdb; $now = current_time( 'mysql' ); $defaults = [ 'post_title' => '', 'post_type' => 'post', 'post_status' => 'publish', 'post_content' => '', 'post_excerpt' => '', 'post_content_filtered' => '', 'to_ping' => '', 'pinged' => '', 'post_date' => $now, 'post_date_gmt' => $now, 'post_modified' => $now, 'post_modified_gmt' => $now, 'post_name' => '', 'guid' => '' ]; $row = array_merge( $defaults, $postarr ); if ( '' === $row['post_name'] ) { $row['post_name'] = sanitize_title( (string) $row['post_title'] ); } $ok = $wpdb->insert( $wpdb->posts, $row ); return $ok ? (int) $wpdb->insert_id : ( $wp_error ? new WP_Error( 'insert_failed', 'Insert failed' ) : 0 ); } } if ( ! function_exists( 'wp_insert_term' ) ) { function wp_insert_term( string $term, string $taxonomy, array $args = [] ) { global $wpdb; $slug = $args['slug'] ?? sanitize_title( $term ); $ok = $wpdb->insert( $wpdb->terms, [ 'name' => $term, 'slug' => $slug, 'term_group' => 0 ] ); if ( ! $ok ) { return new WP_Error( 'insert_failed', 'terms insert failed' ); } $term_id = (int) $wpdb->insert_id; $wpdb->insert( $wpdb->prefix . 'term_taxonomy', [ 'term_id' => $term_id, 'taxonomy' => $taxonomy, 'description' => '', 'parent' => 0, 'count' => 0 ] ); return [ 'term_id' => $term_id, 'term_taxonomy_id' => (int) $wpdb->insert_id ]; } } if ( ! function_exists( 'wp_insert_comment' ) ) { function wp_insert_comment( array $data ) { global $wpdb; $ok = $wpdb->insert( $wpdb->comments, [ 'comment_post_ID' => (int) ( $data['comment_post_ID'] ?? 0 ), 'comment_author' => (string) ( $data['comment_author'] ?? '' ), 'comment_author_email' => (string) ( $data['comment_author_email'] ?? '' ), 'comment_author_url' => (string) ( $data['comment_author_url'] ?? '' ), 'comment_author_IP' => (string) ( $data['comment_author_IP'] ?? '127.0.0.1' ), 'comment_date' => (string) ( $data['comment_date'] ?? gmdate( 'Y-m-d H:i:s' ) ), 'comment_date_gmt' => (string) ( $data['comment_date_gmt'] ?? gmdate( 'Y-m-d H:i:s' ) ), 'comment_content' => (string) ( $data['comment_content'] ?? '' ), 'comment_karma' => (int) ( $data['comment_karma'] ?? 0 ), 'comment_approved' => (string) ( $data['comment_approved'] ?? '1' ), 'comment_agent' => (string) ( $data['comment_agent'] ?? '' ), 'comment_type' => (string) ( $data['comment_type'] ?? 'comment' ), 'comment_parent' => (int) ( $data['comment_parent'] ?? 0 ), 'user_id' => (int) ( $data['user_id'] ?? 0 ), ] ); if ( ! $ok ) { return false; } return (int) $wpdb->insert_id; } } if ( ! class_exists( 'WP_CLI' ) ) { class WP_CLI { public static function log( string $msg ): void {} public static function warning( string $msg ): void {} public static function success( string $msg ): void {} public static function error( string $msg ): void {} public static function add_command( string $name, $class ): void {} } } // ── Load plugin classes ──────────────────────────────────────────────────── require_once TMDO_PATH . 'includes/class-tmdo-capability.php'; require_once TMDO_PATH . 'includes/class-tmdo-crypto.php'; require_once TMDO_PATH . 'includes/class-tmdo-safe-unserialize.php'; require_once TMDO_PATH . 'includes/class-tmdo-db.php'; require_once TMDO_PATH . 'includes/class-tmdo-logger.php'; require_once TMDO_PATH . 'includes/class-tmdo-feature-flags.php'; require_once TMDO_PATH . 'includes/class-tmdo-sqlite-compat.php'; require_once TMDO_PATH . 'includes/class-tmdo-installer.php'; require_once TMDO_PATH . 'includes/class-tmdo-schema-registry.php'; require_once TMDO_PATH . 'includes/class-tmdo-custom-table-registry.php'; require_once TMDO_PATH . 'includes/trait-tmdo-anti-eav-aware.php'; require_once TMDO_PATH . 'includes/class-tmdo-hook-bus-bridge.php'; require_once TMDO_PATH . 'includes/class-tmdo-conflict-monitor.php'; require_once TMDO_PATH . 'includes/class-tmdo-compatibility.php'; require_once TMDO_PATH . 'includes/interceptors/class-tmdo-interceptor-base.php'; require_once TMDO_PATH . 'includes/interceptors/class-tmdo-sync-bridge.php'; require_once TMDO_PATH . 'includes/zones/class-tmdo-zone-hot.php'; require_once TMDO_PATH . 'includes/zones/class-tmdo-zone-warm.php'; require_once TMDO_PATH . 'includes/zones/class-tmdo-zone-cold.php'; require_once TMDO_PATH . 'includes/zones/class-tmdo-zone-archive.php'; require_once TMDO_PATH . 'includes/query/class-tmdo-query-interceptor-base.php'; require_once TMDO_PATH . 'includes/query/class-tmdo-query-router.php'; require_once TMDO_PATH . 'includes/query/class-tmdo-post-query-router.php'; require_once TMDO_PATH . 'includes/migration/class-tmdo-migration-base.php'; require_once TMDO_PATH . 'includes/migration/class-tmdo-migration-engine.php'; require_once TMDO_PATH . 'includes/migration/class-tmdo-hot-migration.php'; require_once TMDO_PATH . 'includes/migration/class-tmdo-warm-migration.php'; require_once TMDO_PATH . 'includes/migration/class-tmdo-cold-migration.php'; require_once TMDO_PATH . 'includes/migration/class-tmdo-archive-migration.php'; require_once TMDO_PATH . 'includes/integrations/class-tmdo-term-comment-garbage-filter.php'; require_once TMDO_PATH . 'includes/integrations/class-tmdo-term-comment-misc-bucket.php'; require_once TMDO_PATH . 'includes/integrations/class-tmdo-member-fields.php'; require_once TMDO_PATH . 'includes/integrations/class-tmdo-post-fields.php'; require_once TMDO_PATH . 'includes/integrations/class-tmdo-points-manager.php'; require_once TMDO_PATH . 'includes/integrations/class-tmdo-demo-entity-counter.php'; require_once TMDO_PATH . 'includes/class-tmdo-cache-layer.php'; require_once TMDO_PATH . 'includes/class-tmdo-zone-classifier.php'; require_once TMDO_PATH . 'includes/class-tmdo-api.php'; require_once TMDO_PATH . 'includes/class-tmdo-v2-upgrader.php'; require_once TMDO_PATH . 'includes/snapshots/class-tmdo-snapshot-manager.php'; require_once TMDO_PATH . 'includes/snapshots/class-tmdo-snapshot-writer.php'; require_once TMDO_PATH . 'includes/snapshots/class-tmdo-snapshot-reader.php'; require_once TMDO_PATH . 'includes/snapshots/class-tmdo-snapshot-pruner.php'; require_once TMDO_PATH . 'includes/safety/class-tmdo-fsm-guard.php'; require_once TMDO_PATH . 'includes/class-tmdo-rest-api.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-type-caster.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-mode-manager.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-audit-logger.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-shadow-diff-logger.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-conflict-detector.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-cache-orchestrator.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-query-compiler.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-schema-manager.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-entity-registry.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-entity-migration-engine.php'; require_once TMDO_PATH . 'includes/engine/class-tmdo-entity-health.php'; require_once TMDO_PATH . 'includes/adapters/interface-entity-adapter.php'; require_once TMDO_PATH . 'includes/adapters/class-tmdo-adapter-post.php'; require_once TMDO_PATH . 'includes/adapters/class-tmdo-adapter-user.php'; require_once TMDO_PATH . 'includes/adapters/class-tmdo-adapter-term.php'; require_once TMDO_PATH . 'includes/adapters/class-tmdo-adapter-comment.php'; require_once TMDO_PATH . 'includes/migration/class-tmdo-migration-orchestrator.php'; require_once TMDO_PATH . 'includes/migration/class-tmdo-post-migration.php'; require_once TMDO_PATH . 'modules/options/class-tmdo-options-manager.php'; require_once TMDO_PATH . 'includes/class-tmdo-postmeta-cleaner.php'; require_once TMDO_PATH . 'includes/class-tmdo-termmeta-cleaner.php'; require_once TMDO_PATH . 'includes/class-tmdo-commentmeta-cleaner.php'; require_once TMDO_PATH . 'includes/class-tmdo-term-comment-shadow-verifier.php'; require_once TMDO_PATH . 'includes/class-tmdo-term-comment-backfill.php'; require_once TMDO_PATH . 'includes/class-tmdo-term-stress-tester.php'; require_once TMDO_PATH . 'includes/class-tmdo-comment-stress-tester.php'; require_once TMDO_PATH . 'includes/class-tmdo-user-stress-tester.php'; require_once TMDO_PATH . 'includes/class-tmdo-post-stress-tester.php'; require_once TMDO_PATH . 'includes/class-tmdo-post-shadow-verifier.php'; require_once TMDO_PATH . 'includes/class-tmdo-core.php'; // Back-compat aliases (WPDO_* → TMDO_*). require_once TMDO_PATH . 'includes/class-tmdo-back-compat.php'; // FSM Guard bypass for integration tests (real DB transitions should work). if ( ! function_exists( '__return_true' ) ) { function __return_true(): bool { return true; } } add_filter( 'wpdo/fsm_guard/bypass', '__return_true' ); // TMDO_Listing_Stats moved to HP AddOn; stub here for tests that reference it. if ( ! class_exists( 'TMDO_Listing_Stats' ) ) { class TMDO_Listing_Stats { public static function register(): void {} public static function get_view_count( int $post_id ): int { return 0; } public static function increment_view( int $post_id, string $ip = '' ): int { return 0; } public static function is_rate_limited( int $post_id, string $ip ): bool { return false; } public static function flush_views_to_postmeta(): int { return 0; } } class_alias( 'TMDO_Listing_Stats', 'WPDO_Listing_Stats' ); }