get_blog_prefix()`). * @return list */ public static function tables( string $prefix ): array { return array_map( static fn ( string $name ): string => $prefix . 'consentfold_' . $name, self::TABLES ); } /** * Tables that add-on code created for a site: every table named `{prefix}consentfold_ext_*`. They are found * by name, so removing them needs no add-on code to be loaded. * * @param string $prefix Table prefix of the site (`$wpdb->get_blog_prefix()`). * @return list */ public static function extension_tables( string $prefix ): array { global $wpdb; $tables = $wpdb->get_col( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $prefix . 'consentfold_ext_' ) . '%' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Lists the tables of this plugin. return array_values( array_map( 'strval', $tables ) ); } /** * The `CREATE TABLE` statements, keyed by short table name. * * @param string $prefix Table prefix of the site. * @param string $charset Charset and collation clause (`$wpdb->get_charset_collate()`). * @return array */ public static function definitions( string $prefix, string $charset ): array { $consents = $prefix . 'consentfold_consents'; $services = $prefix . 'consentfold_services'; $scan_results = $prefix . 'consentfold_scan_results'; return array( 'consents' => "CREATE TABLE {$consents} ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, created_at datetime NOT NULL, visitor_hash char(64) NOT NULL, consent_id char(36) NOT NULL, categories varchar(255) NOT NULL, method varchar(20) NOT NULL, banner_version smallint(5) unsigned NOT NULL, policy_version smallint(5) unsigned NOT NULL, region varchar(8) DEFAULT NULL, lang varchar(10) DEFAULT NULL, ua_class varchar(20) DEFAULT NULL, PRIMARY KEY (id), KEY created_at (created_at), KEY consent_id (consent_id) ) {$charset};", 'services' => "CREATE TABLE {$services} ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, slug varchar(64) NOT NULL, source varchar(10) NOT NULL, category varchar(32) NOT NULL, enabled tinyint(1) NOT NULL DEFAULT 1, data longtext NOT NULL, updated_at datetime NOT NULL, PRIMARY KEY (id), UNIQUE KEY slug (slug) ) {$charset};", 'scan_results' => "CREATE TABLE {$scan_results} ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, run_id char(36) NOT NULL, kind varchar(10) NOT NULL, found_at datetime NOT NULL, item_type varchar(10) NOT NULL, item_key varchar(255) NOT NULL, service_slug varchar(64) DEFAULT NULL, context varchar(255) DEFAULT NULL, PRIMARY KEY (id), KEY run_id (run_id), KEY item_key (item_key(100)) ) {$charset};", ); } /** * Create or update the current site's tables. Safe to run any number of times. * * @return array What `dbDelta` did; empty when everything was already up to date. * @throws RuntimeException When a table still does not exist afterwards. */ public static function install(): array { global $wpdb; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; $result = dbDelta( array_values( self::definitions( $wpdb->prefix, $wpdb->get_charset_collate() ) ) ); foreach ( self::tables( $wpdb->prefix ) as $table ) { $found = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table ) ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Existence probe on a table of this plugin. if ( $table !== $found ) { throw new RuntimeException( sprintf( 'Could not create the database table %s.', esc_html( $table ) ) ); } } return $result; } /** * Drop the current site's tables, the ones add-on code created included. */ public static function drop(): void { global $wpdb; foreach ( array_merge( self::tables( $wpdb->prefix ), self::extension_tables( $wpdb->prefix ) ) as $table ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name built from the site prefix. $wpdb->query( 'DROP TABLE IF EXISTS `' . esc_sql( $table ) . '`' ); } } }