rform the query and save it to the results. */ protected function query_results() { $this->results = $this->wpdb->get_results( $this->build_query(), // phpcs:ignore WordPress.DB.PreparedSQL ARRAY_A ); } /** * Count the results and save the result. */ protected function count_results() { $this->count = (int) $this->wpdb->get_var( $this->build_query( true ) ); // phpcs:ignore WordPress.DB.PreparedSQL } /** * Validate that a given column is valid for the current table. * * @param string $column * * @throws InvalidQuery When the given column is not valid for the current table. */ protected function validate_column( string $column ) { if ( ! array_key_exists( $column, $this->table->get_columns() ) ) { throw InvalidQuery::from_column( $column, get_class( $this->table ) ); } } /** * Validate that a compare operator is valid. * * @param string $compare * * @throws InvalidQuery When the compare value is not valid. */ protected function validate_compare( string $compare ) { switch ( $compare ) { case '=': case '>': case '<': case 'IN': case 'NOT IN': // These are all valid. return; default: throw InvalidQuery::from_compare( $compare ); } } /** * Validate that a where relation is valid. * * @param string $relation * * @throws InvalidQuery When the relation value is not valid. */ protected function validate_where_relation( string $relation ) { switch ( $relation ) { case 'AND': case 'OR': // These are all valid. return; default: throw InvalidQuery::where_relation( $relation ); } } /** * Normalize the string for the order. * * Converts the string to uppercase, and will return only DESC or ASC. * * @param string $order * * @return string */ protected function normalize_order( string $order ): string { $order = strtoupper( $order ); return 'DESC' === $order ? $order : 'ASC'; } /** * Build the query and return the query string. * * @param bool $get_count False to build a normal query, true to build a COUNT(*) query. * * @return string */ protected function build_query( bool $get_count = false ): string { $columns = $get_count ? 'COUNT(*)' : '*'; $pieces = [ "SELECT {$columns} FROM `{$this->table->get_name()}`" ]; $pieces = array_merge( $pieces, $this->generate_where_pieces() ); if ( ! empty( $this->groupby ) ) { $pieces[] = 'GROUP BY ' . implode( ', ', $this->groupby ); } if ( ! $get_count ) { if ( empty( $this->groupby ) ) { $pieces[] = "GROUP BY `{$this->table->get_name()}`.`{$this->table->get_primary_column()}`"; } if ( $this->orderby ) { $pieces[] = 'ORDER BY ' . implode( ', ', $this->orderby ); } if ( $this->limit ) { $pieces[] = "LIMIT {$this->limit}"; } if ( $this->offset ) { $pieces[] = "OFFSET {$this->offset}"; } } return join( "\n", $pieces ); } /** * Generate the pieces for the WHERE part of the query. * * @return string[] */ protected function generate_where_pieces(): array { if ( empty( $this->where ) ) { return []; } $where_pieces = [ 'WHERE' ]; foreach ( $this->where as $where ) { $column = $where['column']; $compare = $where['compare']; if ( $compare === 'IN' || $compare === 'NOT IN' ) { $value = sprintf( "('%s')", join( "','", array_map( function ( $value ) { return $this->wpdb->_escape( $value ); }, $where['value'] ) ) ); } else { $value = "'{$this->wpdb->_escape( $where['value'] )}'"; } if ( count( $where_pieces ) > 1 ) { $where_pieces[] = $this->where_relation ?? 'AND'; } $where_pieces[] = "{$column} {$compare} {$value}"; } return $where_pieces; } /** * Insert a row of data into the table. * * @param array $data * * @return int * @throws InvalidQuery When there is an error inserting the data. */ public function insert( array $data ): int { foreach ( $data as $column => &$value ) { $this->validate_column( $column ); $value = $this->sanitize_value( $column, $value ); } $result = $this->wpdb->insert( $this->table->get_name(), $data ); if ( false === $result ) { throw InvalidQuery::from_insert( $this->wpdb->last_error ?: 'Error inserting data.' ); } // Save a local copy of the last inserted ID. $this->last_insert_id = $this->wpdb->insert_id; return $result; } /** * Returns the last inserted ID. Must be called after insert. * * @since 1.12.0 * * @return int|null */ public function last_insert_id(): ?int { return $this->last_insert_id; } /** * Delete rows from the database. * * @param string $where_column Column to use when looking for values to delete. * @param mixed $value Value to use when determining what rows to delete. * * @return int The number of rows deleted. * @throws InvalidQuery When there is an error deleting data. */ public function delete( string $where_column, $value ): int { $this->validate_column( $where_column ); $result = $this->wpdb->delete( $this->table->get_name(), [ $where_column => $value ] ); if ( false === $result ) { throw InvalidQuery::from_delete( $this->wpdb->last_error ?: 'Error deleting data.' ); } return $result; } /** * Update data in the database. * * @param array $data Array of columns and their values. * @param array $where Array of where conditions for updating values. * * @return int * @throws InvalidQuery When there is an error updating data, or when an empty where array is provided. */ public function update( array $data, array $where ): int { if ( empty( $where ) ) { throw InvalidQuery::empty_where(); } foreach ( $data as $column => &$value ) { $this->validate_column( $column ); $value = $this->sanitize_value( $column, $value ); } $result = $this->wpdb->update( $this->table->get_name(), $data, $where ); if ( false === $result ) { throw InvalidQuery::from_update( $this->wpdb->last_error ?: 'Error updating data.' ); } return $result; } /** * Batch update or insert a set of records. * * @param array $records Array of records to be updated or inserted. * * @throws InvalidQuery If an invalid column name is provided. */ public function update_or_insert( array $records ): void { if ( empty( $records ) ) { return; } $update_values = []; $columns = array_keys( reset( $records ) ); foreach ( $columns as $c ) { $this->validate_column( $c ); $update_values[] = "`$c`=VALUES(`$c`)"; } $single_placeholder = '(' . implode( ',', array_fill( 0, count( $columns ), "'%s'" ) ) . ')'; $chunk_size = 200; $num_issues = count( $records ); for ( $i = 0; $i < $num_issues; $i += $chunk_size ) { $all_values = []; $all_placeholders = []; foreach ( array_slice( $records, $i, $chunk_size ) as $issue ) { if ( array_keys( $issue ) !== $columns ) { throw new InvalidQuery( 'Not all records contain the same columns' ); } $all_placeholders[] = $single_placeholder; array_push( $all_values, ...array_values( $issue ) ); } $column_names = '(`' . implode( '`, `', $columns ) . '`)'; $query = "INSERT INTO `{$this->table->get_name()}` $column_names VALUES "; $query .= implode( ', ', $all_placeholders ); $query .= ' ON DUPLICATE KEY UPDATE ' . implode( ', ', $update_values ); $this->wpdb->query( $this->wpdb->prepare( $query, $all_values ) ); // phpcs:ignore WordPress.DB.PreparedSQL } } /** * Sanitize a value for a given column before inserting it into the DB. * * @param string $column The column name. * @param mixed $value The value to sanitize. * * @return mixed The sanitized value. */ abstract protected function sanitize_value( string $column, $value ); }
Fatal error: Uncaught Error: Class "Automattic\WooCommerce\GoogleListingsAndAds\DB\Query" not found in /htdocs/wp-content/plugins/google-listings-and-ads/src/DB/Query/AttributeMappingRulesQuery.php:17 Stack trace: #0 /htdocs/wp-content/plugins/jetpack/vendor/jetpack-autoloader/class-php-autoloader.php(90): require() #1 [internal function]: Automattic\Jetpack\Autoloader\jpf11009ded9fc4592b6a05b61ce272b3c_jetpackā“„13_5\al3_0_8\PHP_Autoloader::load_class('Automattic\\WooC...') #2 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(211): class_exists('Automattic\\WooC...') #3 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/DefinitionAggregate.php(94): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolve(false) #4 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Container.php(157): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\DefinitionAggregate->resolve('Automattic\\WooC...', false) #5 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(45): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Container->get('Automattic\\WooC...') #6 [internal function]: Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Argument\{closure}('Automattic\\WooC...') #7 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(19): array_map(Object(Closure), Array) #8 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(253): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveArguments(Array) #9 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(212): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveClass('Automattic\\WooC...') #10 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/DefinitionAggregate.php(94): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolve(false) #11 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Container.php(157): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\DefinitionAggregate->resolve('Automattic\\WooC...', false) #12 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(45): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Container->get('Automattic\\WooC...') #13 [internal function]: Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Argument\{closure}('Automattic\\WooC...') #14 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(19): array_map(Object(Closure), Array) #15 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(253): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveArguments(Array) #16 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(212): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveClass('Automattic\\WooC...') #17 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/DefinitionAggregate.php(94): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolve(false) #18 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Container.php(157): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\DefinitionAggregate->resolve('Automattic\\WooC...', false) #19 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(45): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Container->get('Automattic\\WooC...') #20 [internal function]: Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Argument\{closure}('Automattic\\WooC...') #21 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(19): array_map(Object(Closure), Array) #22 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(253): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveArguments(Array) #23 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(212): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveClass('Automattic\\WooC...') #24 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/DefinitionAggregate.php(106): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolve(false) #25 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Container.php(162): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\DefinitionAggregate->resolveTagged('Automattic\\WooC...', false) #26 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(45): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Container->get('Automattic\\WooC...') #27 [internal function]: Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Argument\{closure}('Automattic\\WooC...') #28 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(19): array_map(Object(Closure), Array) #29 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(253): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveArguments(Array) #30 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(212): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveClass('Automattic\\WooC...') #31 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/DefinitionAggregate.php(94): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolve(false) #32 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Container.php(157): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\DefinitionAggregate->resolve('Automattic\\WooC...', false) #33 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(45): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Container->get('Automattic\\WooC...') #34 [internal function]: Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Argument\{closure}('Automattic\\WooC...') #35 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(19): array_map(Object(Closure), Array) #36 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(253): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveArguments(Array) #37 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(212): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveClass('Automattic\\WooC...') #38 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/DefinitionAggregate.php(106): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolve(false) #39 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Container.php(162): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\DefinitionAggregate->resolveTagged('Automattic\\WooC...', false) #40 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(45): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Container->get('Automattic\\WooC...') #41 [internal function]: Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Argument\{closure}('Automattic\\WooC...') #42 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Argument/ArgumentResolverTrait.php(19): array_map(Object(Closure), Array) #43 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(237): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveArguments(Array) #44 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/Definition.php(198): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolveCallable(Object(Closure)) #45 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Definition/DefinitionAggregate.php(106): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\Definition->resolve(false) #46 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Container.php(162): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Definition\DefinitionAggregate->resolveTagged('Automattic\\WooC...', false) #47 /htdocs/wp-content/plugins/google-listings-and-ads/vendor/league/container/src/Container.php(178): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Container->get('Automattic\\WooC...', false) #48 /htdocs/wp-content/plugins/google-listings-and-ads/src/Container.php(90): Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Container->get('Automattic\\WooC...') #49 /htdocs/wp-content/plugins/google-listings-and-ads/src/Infrastructure/GoogleListingsAndAdsPlugin.php(130): Automattic\WooCommerce\GoogleListingsAndAds\Container->get('Automattic\\WooC...') #50 /htdocs/wp-content/plugins/google-listings-and-ads/src/Infrastructure/GoogleListingsAndAdsPlugin.php(91): Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\GoogleListingsAndAdsPlugin->maybe_register_services() #51 /htdocs/wp-includes/class-wp-hook.php(324): Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\GoogleListingsAndAdsPlugin->Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\{closure}('') #52 /htdocs/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #53 /htdocs/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #54 /htdocs/wp-settings.php(559): do_action('plugins_loaded') #55 /htdocs/wp-config.php(85): require_once('/htdocs/wp-sett...') #56 /htdocs/wp-load.php(50): require_once('/htdocs/wp-conf...') #57 /htdocs/wp-blog-header.php(13): require_once('/htdocs/wp-load...') #58 /htdocs/index.php(17): require('/htdocs/wp-blog...') #59 {main} thrown in /htdocs/wp-content/plugins/google-listings-and-ads/src/DB/Query/AttributeMappingRulesQuery.php on line 17