'query' ) ) { throw new \InvalidArgumentException( 'Foreign key item must contain `query` property.' ); } /** * Suppress errors. * * We suppress errors because adding foreign keys to for example * a `$wpdb->users` MyISAM table will trigger the following error: * * "Error in query (1005): Can't create table '●●●●●●●●. # Sql-●●●●●●●●●●' (errno: 150)" * * @link https://github.com/WordPress/WordPress/blob/5.3/wp-includes/wp-db.php#L1544-L1559 */ $suppress_errors = $wpdb->suppress_errors( true ); /** * Check if foreign key exists * * @link https://github.com/woocommerce/woocommerce/blob/3.9.0/includes/class-wc-install.php#L663-L681 */ $result = $wpdb->get_var( $wpdb->prepare( " SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = %s AND CONSTRAINT_NAME = %s AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_NAME = %s ", $wpdb->dbname, $item->name, $item->table ) ); if ( null === $result ) { throw new \Exception( \sprintf( 'Could not count foreign keys: %s, database error: %s.', $item->name, $wpdb->last_error ) ); } $number_constraints = \intval( $result ); if ( 0 === $number_constraints ) { // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is prepared. $result = $wpdb->query( $item->query ); $wpdb->suppress_errors( $suppress_errors ); if ( false === $result ) { throw new \Exception( \sprintf( 'Could not add foreign key: %s, database error: %s.', $item->name, $wpdb->last_error ) ); } } $wpdb->suppress_errors( $suppress_errors ); } /** * Convert user meta. * * @return void * @throws \Exception Throws exception when database update query fails. */ private function convert_user_meta() { global $wpdb; $query = " INSERT IGNORE INTO $wpdb->pronamic_pay_mollie_customers ( mollie_id, test_mode ) SELECT meta_value AS mollie_id, '_pronamic_pay_mollie_customer_id_test' = meta_key AS test_mode FROM $wpdb->usermeta WHERE meta_key IN ( '_pronamic_pay_mollie_customer_id', '_pronamic_pay_mollie_customer_id_test' ) AND meta_value != '' ; "; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is prepared. $result = $wpdb->query( $query ); if ( false === $result ) { throw new \Exception( sprintf( 'Could not convert user meta, database error: %s.', $wpdb->last_error ) ); } /** * Collate caluse. * * Force a specific collate to fix: * "Illegal mix of collations (utf8mb4_unicode_ci,IMPLICIT) and * (utf8mb4_unicode_520_ci,IMPLICIT) for operation '='. ". * * @link https://dev.mysql.com/doc/refman/8.0/en/charset-collate.html */ $collate_clause = ''; if ( ! empty( $wpdb->collate ) ) { $collate_clause = \sprintf( 'COLLATE %s', $wpdb->collate ); } $query = " INSERT IGNORE INTO $wpdb->pronamic_pay_mollie_customer_users ( customer_id, user_id ) SELECT mollie_customer.id AS mollie_customer_id, wp_user.ID AS wp_user_id FROM $wpdb->pronamic_pay_mollie_customers AS mollie_customer INNER JOIN $wpdb->usermeta AS wp_user_meta ON wp_user_meta.meta_value = mollie_customer.mollie_id $collate_clause INNER JOIN $wpdb->users AS wp_user ON wp_user_meta.user_id = wp_user.ID WHERE wp_user_meta.meta_key IN ( '_pronamic_pay_mollie_customer_id', '_pronamic_pay_mollie_customer_id_test' ) AND wp_user_meta.meta_value != '' ; "; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is prepared. $result = $wpdb->query( $query ); if ( false === $result ) { throw new \Exception( sprintf( 'Could not convert user meta, database error: %s.', $wpdb->last_error ) ); } } }