Skip to content

Commit 01b900d

Browse files
committed
Restructure queries so phpcs rule passes
Restructure query code so that the WP linters for prepared queries passes. The linters are extremely primitive and only pass if we write the code in a very specific way. In a lot of cases such as working with multiple rows or values, it is impossible to satisfy the linter. In those cases, we add an ignore rule inline. All the code was already prepared correctly, so this doesn't change any behavior. It just satisfies the linter.
1 parent 47481fb commit 01b900d

17 files changed

Lines changed: 408 additions & 306 deletions

phpcs.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
<exclude name="WordPress.DB.DirectDatabaseQuery.DirectQuery" />
5151
<exclude name="WordPress.DB.DirectDatabaseQuery.NoCaching" />
5252
<exclude name="WordPress.DB.DirectDatabaseQuery.SchemaChange" />
53-
<exclude name="WordPress.DB.PreparedSQL" />
5453
<exclude name="WordPress.Files.FileName.InvalidClassFileName" />
5554
<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase" />
5655
<exclude name="WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid" />

src/Addons.php

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,18 @@ public static function registerAddon(
3939

4040
global $wpdb;
4141

42-
$table_name = self::getTableName();
43-
44-
$sql = "INSERT IGNORE INTO {$table_name} (slug,type,name,docs_url,description)" .
45-
' VALUES (%s,%s,%s,%s,%s)';
46-
47-
$sql = $wpdb->prepare( $sql, $slug, $type, $name, $docs_url, $description );
48-
49-
$wpdb->query( $sql );
42+
$wpdb->query(
43+
$wpdb->prepare(
44+
'INSERT IGNORE INTO %i (slug,type,name,docs_url,description)' .
45+
' VALUES (%s,%s,%s,%s,%s)',
46+
self::getTableName(),
47+
$slug,
48+
$type,
49+
$name,
50+
$docs_url,
51+
$description,
52+
),
53+
);
5054
}
5155

5256
/**
@@ -59,17 +63,22 @@ public static function getAll( string $type = 'all' ): array {
5963

6064
$table_name = self::getTableName();
6165

62-
$query_string = "SELECT * FROM $table_name";
63-
$query_params = [];
6466
if ( $type !== 'all' ) {
65-
$query_string .= ' WHERE type = %s';
66-
$query_params[] = $type;
67+
return $wpdb->get_results(
68+
$wpdb->prepare(
69+
'SELECT * FROM %i WHERE type = %s ORDER BY type DESC',
70+
$table_name,
71+
$type
72+
)
73+
);
74+
} else {
75+
return $wpdb->get_results(
76+
$wpdb->prepare(
77+
'SELECT * FROM %i ORDER BY type DESC',
78+
$table_name
79+
)
80+
);
6781
}
68-
$query_string .= ' ORDER BY type DESC';
69-
70-
return $wpdb->get_results(
71-
$wpdb->prepare( $query_string, $query_params )
72-
);
7382
}
7483

7584
/**
@@ -81,14 +90,13 @@ public static function getAll( string $type = 'all' ): array {
8190
public static function getType( string $type ): array {
8291
global $wpdb;
8392

84-
$table_name = self::getTableName();
85-
86-
$query = $wpdb->prepare(
87-
"SELECT * FROM $table_name WHERE type = %s AND enabled = 1 ORDER BY slug",
88-
$type
93+
return $wpdb->get_results(
94+
$wpdb->prepare(
95+
'SELECT * FROM %i WHERE type = %s AND enabled = 1 ORDER BY slug',
96+
self::getTableName(),
97+
$type,
98+
),
8999
);
90-
91-
return $wpdb->get_results( $query );
92100
}
93101

94102
/**
@@ -99,7 +107,7 @@ public static function truncate(): void {
99107

100108
$table_name = self::getTableName();
101109

102-
$wpdb->query( "TRUNCATE TABLE $table_name" );
110+
$wpdb->query( $wpdb->prepare( 'TRUNCATE TABLE %i', $table_name ) );
103111

104112
WsLog::l( 'Deregistered all Addons' );
105113
}

src/AdminBar.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,10 @@ public static function getJobsInProgress(): array {
213213
$table_name = JobQueue::getTableName();
214214

215215
return $wpdb->get_results(
216-
"SELECT * FROM $table_name
217-
WHERE status = 'processing'"
216+
$wpdb->prepare(
217+
"SELECT * FROM %i WHERE status = 'processing'",
218+
$table_name
219+
)
218220
);
219221
}
220222

src/Controller.php

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,9 @@ public static function deactivate(
9292
if ( $network_wide ) {
9393
global $wpdb;
9494

95-
$query = 'SELECT blog_id FROM %s WHERE site_id = %d;';
96-
9795
$site_ids = $wpdb->get_col(
98-
sprintf(
99-
$query,
96+
$wpdb->prepare(
97+
'SELECT blog_id FROM %i WHERE site_id = %d;',
10098
$wpdb->blogs,
10199
$wpdb->siteid
102100
)
@@ -132,11 +130,9 @@ public static function activate(
132130
if ( $network_wide ) {
133131
global $wpdb;
134132

135-
$query = 'SELECT blog_id FROM %s WHERE site_id = %d;';
136-
137133
$site_ids = $wpdb->get_col(
138-
sprintf(
139-
$query,
134+
$wpdb->prepare(
135+
'SELECT blog_id FROM %s WHERE site_id = %d;',
140136
$wpdb->blogs,
141137
$wpdb->siteid
142138
)
@@ -525,8 +521,13 @@ public static function adminSetAddonState(
525521

526522
$table_name = Addons::getTableName();
527523

528-
$addon_type =
529-
$wpdb->get_var( "SELECT type FROM $table_name WHERE slug = '$addon_slug'" );
524+
$addon_type = $wpdb->get_var(
525+
$wpdb->prepare(
526+
'SELECT type FROM %i WHERE slug = %s',
527+
$table_name,
528+
$addon_slug
529+
)
530+
);
530531

531532
// if deploy type, disable other deployers when enabling this one
532533
if ( $enabled && $addon_type === 'deploy' ) {
@@ -578,8 +579,13 @@ public static function adminToggleAddon(
578579
$table_name = Addons::getTableName();
579580

580581
// get target addon's current state
581-
$enabled =
582-
$wpdb->get_var( "SELECT enabled FROM $table_name WHERE slug = '$addon_slug'" );
582+
$enabled = $wpdb->get_var(
583+
$wpdb->prepare(
584+
'SELECT enabled FROM %i WHERE slug = %s',
585+
$table_name,
586+
$addon_slug
587+
)
588+
);
583589

584590
self::adminSetAddonState( $addon_slug, ! $enabled );
585591
}

src/CrawledFiles.php

Lines changed: 68 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static function getHashes(): array {
4343

4444
$table_name = self::getTableName();
4545

46-
return $wpdb->get_col( "SELECT path_hash FROM $table_name" );
46+
return $wpdb->get_col( $wpdb->prepare( 'SELECT path_hash FROM %i', $table_name ) );
4747
}
4848

4949
public static function getTableName(): string {
@@ -68,25 +68,6 @@ public static function addPathsIter( \Iterator $paths ): \Iterator {
6868
$paths[] = $path;
6969
}
7070

71-
$placeholders = implode(
72-
',',
73-
array_fill(
74-
0,
75-
count( $paths ),
76-
'(%s,%s,%s,%s,%s,NOW())'
77-
)
78-
);
79-
$sql = "INSERT INTO $table_name
80-
(path,content_type,redirect_to,status,content_hash,crawled_at)
81-
VALUES $placeholders ON DUPLICATE KEY
82-
UPDATE
83-
path = VALUES(path),
84-
content_type = VALUES(content_type),
85-
redirect_to = VALUES(redirect_to),
86-
status = VALUES(status),
87-
content_hash = VALUES(content_hash),
88-
crawled_at = VALUES(crawled_at)";
89-
9071
$values = [];
9172
foreach ( $paths as $path ) {
9273
array_push(
@@ -99,7 +80,23 @@ public static function addPathsIter( \Iterator $paths ): \Iterator {
9980
);
10081
}
10182

102-
$query = $wpdb->prepare( $sql, ...$values );
83+
$placeholders = array_fill( 0, count( $paths ), '(%s,%s,%s,%s,%s,NOW())' );
84+
// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
85+
$query = $wpdb->prepare(
86+
'INSERT INTO %i ' .
87+
'(path,content_type,redirect_to,status,content_hash,crawled_at) ' .
88+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
89+
'VALUES ' . implode( ',', $placeholders ) .
90+
'ON DUPLICATE KEY UPDATE ' .
91+
'path = VALUES(path), ' .
92+
'content_type = VALUES(content_type), ' .
93+
'redirect_to = VALUES(redirect_to), ' .
94+
'status = VALUES(status), ' .
95+
'content_hash = VALUES(content_hash), ' .
96+
'crawled_at = VALUES(crawled_at)',
97+
$table_name,
98+
...$values
99+
);
103100
Db::query( $query );
104101

105102
foreach ( $paths as $path ) {
@@ -122,22 +119,18 @@ public static function getPathsIter(): \Iterator {
122119
$last_id = 0;
123120
$static_site_path = StaticSite::getPath();
124121
while ( true ) {
125-
$qs = "SELECT
126-
cc.id,
127-
cc.content_hash,
128-
cc.content_type,
129-
cq.filename,
130-
cc.path,
131-
cc.redirect_to,
132-
cc.status
133-
FROM $table_name AS cc
134-
JOIN $queue_table_name AS cq
135-
ON cc.path_hash = cq.path_hash
136-
WHERE cc.id > %d
137-
ORDER BY cc.id ASC
138-
LIMIT %d";
139-
$q = $wpdb->prepare( $qs, $last_id, $batch_size );
140-
$rows = $wpdb->get_results( $q );
122+
$rows = $wpdb->get_results(
123+
$wpdb->prepare(
124+
'SELECT cc.id, cc.content_hash, cc.content_type, cq.filename, ' .
125+
'cc.path, cc.redirect_to, cc.status ' .
126+
'FROM %i AS cc JOIN %i AS cq ON cc.path_hash = cq.path_hash ' .
127+
'WHERE cc.id > %d ORDER BY cc.id ASC LIMIT %d',
128+
$table_name,
129+
$queue_table_name,
130+
$last_id,
131+
$batch_size,
132+
),
133+
);
141134

142135
foreach ( $rows as $row ) {
143136
if ( ! $row->filename ) {
@@ -227,24 +220,22 @@ public static function addUrl(
227220
): void {
228221
global $wpdb;
229222

230-
$table_name = self::getTableName();
231-
$sql = "insert into {$table_name} (crawled_at, path, content_hash, status, redirect_to)
232-
VALUES (%s, %s, %s, %s, %s) ON DUPLICATE KEY
233-
UPDATE crawled_at = %s, content_hash = %s, status = %s, redirect_to = %s";
234-
$sql = $wpdb->prepare(
235-
$sql,
236-
current_time( 'mysql' ),
237-
$path,
238-
$content_hash,
239-
$status,
240-
$redirect_to,
241-
current_time( 'mysql' ),
242-
$content_hash,
243-
$status,
244-
$redirect_to
223+
$wpdb->query(
224+
$wpdb->prepare(
225+
'INSERT INTO %i (crawled_at, path, content_hash, status, redirect_to) ' .
226+
'VALUES (NOW(), %s, %s, %s, %s) ' .
227+
'ON DUPLICATE KEY UPDATE crawled_at = NOW(), content_hash = %s, ' .
228+
'status = %s, redirect_to = %s',
229+
self::getTableName(),
230+
$path,
231+
$content_hash,
232+
$status,
233+
$redirect_to,
234+
$content_hash,
235+
$status,
236+
$redirect_to,
237+
),
245238
);
246-
247-
$wpdb->query( $sql );
248239
}
249240

250241
public static function getUrl( string $path, string $content_hash ): string {
@@ -254,13 +245,12 @@ public static function getUrl( string $path, string $content_hash ): string {
254245

255246
$table_name = self::getTableName();
256247

257-
$sql = $wpdb->prepare(
258-
"SELECT path FROM $table_name WHERE" .
259-
' path_hash = %s and content_hash = %s LIMIT 1',
260-
[ $path_hash, $content_hash ]
261-
);
248+
$sql = 'SELECT path FROM %i WHERE path_hash = %s and content_hash = %s LIMIT 1';
249+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
250+
$query = $wpdb->prepare( $sql, $table_name, $path_hash, $content_hash );
262251

263-
$path = $wpdb->get_var( $sql );
252+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
253+
$path = $wpdb->get_var( $query );
264254

265255
return (string) $path;
266256
}
@@ -283,13 +273,9 @@ public static function getURLs(): array {
283273

284274
$table_name = self::getTableName();
285275

286-
$rows = $wpdb->get_results(
287-
"
288-
SELECT id, path_hash, path, content_hash
289-
FROM $table_name
290-
ORDER BY path
291-
"
292-
);
276+
$sql = 'SELECT id, path_hash, path, content_hash FROM %i ORDER BY path';
277+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
278+
$rows = $wpdb->get_results( $wpdb->prepare( $sql, $table_name ) );
293279

294280
foreach ( $rows as $row ) {
295281
$paths[ $row->id ] = $row;
@@ -317,11 +303,12 @@ public static function rmUrl( string $path ): void {
317303
public static function rmUrlsById( array $ids ): void {
318304
global $wpdb;
319305

320-
$ids = implode( ',', array_map( 'absint', $ids ) );
321-
306+
$ids = array_map( 'absint', $ids );
322307
$table_name = self::getTableName();
323-
324-
$wpdb->query( "DELETE FROM $table_name WHERE ID IN($ids)" );
308+
$placeholders = implode( ',', array_fill( 0, count( $ids ), '%d' ) );
309+
$sql = "DELETE FROM %i WHERE ID IN($placeholders)";
310+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
311+
$wpdb->query( $wpdb->prepare( $sql, $table_name, ...$ids ) );
325312
}
326313

327314
/**
@@ -334,7 +321,9 @@ public static function truncate(): void {
334321

335322
$table_name = self::getTableName();
336323

337-
$wpdb->query( "TRUNCATE TABLE $table_name" );
324+
$sql = 'TRUNCATE TABLE %i';
325+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
326+
$wpdb->query( $wpdb->prepare( $sql, $table_name ) );
338327

339328
$total_crawled_files = self::getTotal();
340329

@@ -351,7 +340,9 @@ public static function getTotal(): int {
351340

352341
$table_name = self::getTableName();
353342

354-
return $wpdb->get_var( "SELECT count(*) FROM $table_name" );
343+
$sql = 'SELECT count(*) FROM %i';
344+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
345+
return $wpdb->get_var( $wpdb->prepare( $sql, $table_name ) );
355346
}
356347

357348
/**
@@ -362,8 +353,11 @@ public static function listRedirects(): array {
362353

363354
$table_name = self::getTableName();
364355

356+
$sql = 'SELECT path, redirect_to FROM %i WHERE 0 < LENGTH(redirect_to)';
357+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
365358
return $wpdb->get_results(
366-
"SELECT path, redirect_to FROM $table_name WHERE 0 < LENGTH(redirect_to)"
359+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
360+
$wpdb->prepare( $sql, $table_name )
367361
);
368362
}
369363
}

0 commit comments

Comments
 (0)