diff --git a/mailpoet/lib/AdminPages/Pages/DynamicSegments.php b/mailpoet/lib/AdminPages/Pages/DynamicSegments.php index 82e2095042..95152e9e50 100644 --- a/mailpoet/lib/AdminPages/Pages/DynamicSegments.php +++ b/mailpoet/lib/AdminPages/Pages/DynamicSegments.php @@ -227,15 +227,14 @@ class DynamicSegments { } global $wpdb; - $query = " - SELECT DISTINCT pm.meta_key, pm.meta_value - FROM {$wpdb->postmeta} pm - INNER JOIN {$wpdb->posts} p ON pm.post_id = p.ID - WHERE pm.meta_key LIKE 'attribute_%' - AND p.post_type = 'product_variation' - GROUP BY pm.meta_key, pm.meta_value"; - - $results = $wpdb->get_results($query, ARRAY_A); + $results = $wpdb->get_results($wpdb->prepare(" + SELECT DISTINCT pm.meta_key, pm.meta_value + FROM %i pm + INNER JOIN %i p ON pm.post_id = p.ID + WHERE pm.meta_key LIKE %s + AND p.post_type = 'product_variation' + GROUP BY pm.meta_key, pm.meta_value + ", $wpdb->postmeta, $wpdb->posts, 'attribute_%'), ARRAY_A); foreach ($results as $result) { $attribute = substr($result['meta_key'], 10); diff --git a/mailpoet/lib/Config/Populator.php b/mailpoet/lib/Config/Populator.php index 0d06ffb8e8..89336c7587 100644 --- a/mailpoet/lib/Config/Populator.php +++ b/mailpoet/lib/Config/Populator.php @@ -566,16 +566,22 @@ class Populator { private function rowExists(string $tableName, array $columns): bool { global $wpdb; - $conditions = array_map(function($key, $value) { - return esc_sql($key) . "='" . esc_sql($value) . "'"; - }, array_keys($columns), $columns); + $placeholders = []; + $values = [$tableName]; // Start with the table name as the first value for %i - $table = esc_sql($tableName); - // $conditions is escaped - // phpcs:ignore WordPressDotOrg.sniffs.DirectDB.UnescapedDBParameter - return $wpdb->get_var( - "SELECT COUNT(*) FROM $table WHERE " . implode(' AND ', $conditions) - ) > 0; + foreach ($columns as $key => $value) { + $placeholders[] = "%i = %s"; // Use %i for the column name and %s for the value + $values[] = $key; + $values[] = $value; + } + + $whereClause = implode(' AND ', $placeholders); + + + return $wpdb->get_var($wpdb->prepare( + "SELECT COUNT(*) FROM %i WHERE $whereClause", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- All values are prepared with placeholders + ...$values + )) > 0; } private function insertRow($table, $row) { @@ -603,35 +609,33 @@ class Populator { $conditions = ['1=1']; $values = []; foreach ($where as $field => $value) { - $conditions[] = "`t1`.`" . esc_sql($field) . "` = `t2`.`" . esc_sql($field) . "`"; - $conditions[] = "`t1`.`" . esc_sql($field) . "` = %s"; + $conditions[] = "`t1`.%i = `t2`.%i"; + $conditions[] = "`t1`.%i = %s"; + $values[] = $field; + $values[] = $field; + $values[] = $field; $values[] = $value; } - $conditions = implode(' AND ', $conditions); - - $table = esc_sql($table); - // SQLite doesn't support JOIN in DELETE queries, we need to use a subquery. if (Connection::isSQLite()) { + $sql = " + DELETE FROM %i WHERE id IN ( + SELECT t1.id + FROM %i t1 + JOIN %i t2 ON t1.id < t2.id AND " . implode(' AND ', $conditions) . " + )"; return $wpdb->query( $wpdb->prepare( - "DELETE FROM $table WHERE id IN ( - SELECT t1.id - FROM $table t1 - JOIN $table t2 ON t1.id < t2.id AND $conditions - )", - $values + $sql, // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- All values are prepared with placeholders in a variable + array_merge([$table, $table, $table], $values) ) ); } - return $wpdb->query( - $wpdb->prepare( - "DELETE t1 FROM $table t1, $table t2 WHERE t1.id < t2.id AND $conditions", - $values - ) - ); + $sql = "DELETE t1 FROM %i t1, %i t2 WHERE t1.id < t2.id AND " . implode(' AND ', $conditions); + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- All values are prepared with placeholders in a variable + return $wpdb->query($wpdb->prepare($sql, array_merge([$table, $table], $values))); } private function createSourceForSubscribers() { diff --git a/mailpoet/lib/Segments/WooCommerce.php b/mailpoet/lib/Segments/WooCommerce.php index 45e4d7f8fa..53bab70e71 100644 --- a/mailpoet/lib/Segments/WooCommerce.php +++ b/mailpoet/lib/Segments/WooCommerce.php @@ -223,14 +223,16 @@ class WooCommerce { return; } global $wpdb; - $subscribersTableName = esc_sql($this->subscribersRepository->getTableName()); - $mailpoetEmailColumn = $wpdb->get_row( - "SHOW FULL COLUMNS FROM " . $subscribersTableName . " WHERE Field = 'email'" - ); + + $mailpoetEmailColumn = $wpdb->get_row($wpdb->prepare( + "SHOW FULL COLUMNS FROM %i WHERE Field = 'email'", + $this->subscribersRepository->getTableName() + )); $this->mailpoetEmailCollation = $mailpoetEmailColumn->Collation; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps - $wpPostmetaValueColumn = $wpdb->get_row( - "SHOW FULL COLUMNS FROM " . $wpdb->postmeta . " WHERE Field = 'meta_value'" - ); + $wpPostmetaValueColumn = $wpdb->get_row($wpdb->prepare( + "SHOW FULL COLUMNS FROM %i WHERE Field = 'meta_value'", + $wpdb->postmeta + )); $this->wpPostmetaValueCollation = $wpPostmetaValueColumn->Collation; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps } diff --git a/mailpoet/tasks/phpstan/phpstan-7-baseline.neon b/mailpoet/tasks/phpstan/phpstan-7-baseline.neon index cd8d99e29b..d7d235c196 100644 --- a/mailpoet/tasks/phpstan/phpstan-7-baseline.neon +++ b/mailpoet/tasks/phpstan/phpstan-7-baseline.neon @@ -136,21 +136,6 @@ parameters: count: 1 path: ../../lib/Config/Populator.php - - - message: "#^Binary operation \"\\.\" between non-falsy-string and array\\|string results in an error\\.$#" - count: 2 - path: ../../lib/Config/Populator.php - - - - message: "#^Binary operation \"\\.\" between '`t1`\\.`' and array\\|string results in an error\\.$#" - count: 2 - path: ../../lib/Config/Populator.php - - - - message: "#^Part \\$table \\(array\\|string\\) of encapsed string cannot be cast to string\\.$#" - count: 5 - path: ../../lib/Config/Populator.php - - message: "#^Parameter \\#2 \\$args of method MailPoet\\\\WP\\\\Functions\\:\\:wpRemotePost\\(\\) expects array, mixed given\\.$#" count: 1 diff --git a/mailpoet/tasks/phpstan/phpstan-8-baseline.neon b/mailpoet/tasks/phpstan/phpstan-8-baseline.neon index a58abc4722..d9e256d0e6 100644 --- a/mailpoet/tasks/phpstan/phpstan-8-baseline.neon +++ b/mailpoet/tasks/phpstan/phpstan-8-baseline.neon @@ -136,21 +136,6 @@ parameters: count: 1 path: ../../lib/Config/Populator.php - - - message: "#^Binary operation \"\\.\" between non-falsy-string and array\\|string results in an error\\.$#" - count: 2 - path: ../../lib/Config/Populator.php - - - - message: "#^Binary operation \"\\.\" between '`t1`\\.`' and array\\|string results in an error\\.$#" - count: 2 - path: ../../lib/Config/Populator.php - - - - message: "#^Part \\$table \\(array\\|string\\) of encapsed string cannot be cast to string\\.$#" - count: 5 - path: ../../lib/Config/Populator.php - - message: "#^Parameter \\#2 \\$args of method MailPoet\\\\WP\\\\Functions\\:\\:wpRemotePost\\(\\) expects array, mixed given\\.$#" count: 1