| @@ -10,19 +10,8 @@ | ||
| 10 | 10 | if ( ! defined( 'ABSPATH' ) ) { |
| 11 | 11 | exit; // Exit if accessed directly. |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | -/** | |
| 15 | - * SQL building helpers below interpolate WP-provided $wpdb table identifiers | |
| 16 | - * (`$wpdb->posts`, `$wpdb->term_relationships`, `$wpdb->term_taxonomy`) and use | |
| 17 | - * dynamic %d placeholder lists derived from integer arrays. Suppressing the | |
| 18 | - * related PHPCS notices class-wide rather than per-call. | |
| 19 | - * | |
| 20 | - * phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 21 | - * phpcs:disable WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare | |
| 22 | - * phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery | |
| 23 | - * phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 24 | - */ | |
| 25 | 14 | #[\AllowDynamicProperties] |
| 26 | 15 | class WPExporter { |
| 27 | 16 | /** |
| 28 | 17 | * @var array |
| @@ -72,10 +61,9 @@ | ||
| 72 | 61 | |
| 73 | 62 | // Handle additional filters (author, dates, meta) |
| 74 | 63 | $where .= $this->build_additional_filters(); |
| 75 | 64 | |
| 76 | - // $join/$where are composed from prepared fragments above; identifiers are WP-provided. | |
| 77 | - // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,PluginCheck.Security.DirectDB.UnescapedDBParameter | |
| 65 | + // Get the main doc post IDs | |
| 78 | 66 | $post_ids = $this->wpdb->get_col( "SELECT DISTINCT {$this->wpdb->posts}.ID FROM {$this->wpdb->posts} $join WHERE $where" ); |
| 79 | 67 | |
| 80 | 68 | // Handle FAQ posts separately |
| 81 | 69 | $faq_post_ids = []; |
| @@ -85,10 +73,8 @@ | ||
| 85 | 73 | |
| 86 | 74 | // Combine post IDs |
| 87 | 75 | $all_post_ids = array_merge( $post_ids, $faq_post_ids ); |
| 88 | 76 | |
| 89 | - $all_post_ids = WPMLSupport::expand_with_translations( $all_post_ids ); | |
| 90 | - | |
| 91 | 77 | // Handle featured images |
| 92 | 78 | $thumbnail_ids = $this->get_thumbnail_ids( $all_post_ids ); |
| 93 | 79 | |
| 94 | 80 | // Generate final post IDs array |
| @@ -106,26 +92,14 @@ | ||
| 106 | 92 | array_push($glossary_term_ids, $term_object->term_id); |
| 107 | 93 | } |
| 108 | 94 | } |
| 109 | 95 | } else { |
| 110 | - // $this->wpdb->term_taxonomy is a WP-core table identifier; %s placeholder binds taxonomy name. | |
| 111 | - // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,PluginCheck.Security.DirectDB.UnescapedDBParameter | |
| 112 | - $glossary_term_ids = $this->wpdb->get_col( | |
| 113 | - $this->wpdb->prepare( | |
| 114 | - "SELECT term_id FROM {$this->wpdb->term_taxonomy} WHERE taxonomy = %s", | |
| 115 | - (string) $this->args['content'] | |
| 116 | - ) | |
| 117 | - ); | |
| 118 | - // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,PluginCheck.Security.DirectDB.UnescapedDBParameter | |
| 96 | + $glossary_term_ids = $this->wpdb->get_col( "SELECT term_id from {$this->wpdb->term_taxonomy} where taxonomy='{$this->args['content']}';" ); | |
| 119 | 97 | } |
| 120 | 98 | |
| 121 | 99 | return $glossary_term_ids; |
| 122 | 100 | } |
| 123 | 101 | |
| 124 | - // The query-builder methods below interpolate only $wpdb core table names | |
| 125 | - // ({$this->wpdb->posts}, etc.) — never user input — and bind every value via | |
| 126 | - // %s/%d placeholders, so the InterpolatedNotPrepared warnings are spurious. | |
| 127 | - // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 128 | 102 | public function build_base_query(): array { |
| 129 | 103 | $where = $this->wpdb->prepare("{$this->wpdb->posts}.post_type = %s", 'docs'); |
| 130 | 104 | return [ |
| 131 | 105 | 'where' => $where, |
| @@ -223,17 +197,14 @@ | ||
| 223 | 197 | |
| 224 | 198 | return $where; |
| 225 | 199 | } |
| 226 | 200 | |
| 227 | - // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 228 | 201 | public function get_faq_posts(): array { |
| 229 | 202 | return get_posts([ |
| 230 | - 'numberposts' => -1, | |
| 231 | - 'post_type' => 'betterdocs_faq', | |
| 232 | - 'fields' => 'ids', | |
| 233 | - 'post_status' => 'publish', | |
| 234 | - // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.SuppressFilters_suppress_filters -- intentional: export the raw, untranslated FAQ set so multilingual filters don't drop or swap rows during export. | |
| 235 | - 'suppress_filters' => true, | |
| 203 | + 'numberposts' => -1, | |
| 204 | + 'post_type' => 'betterdocs_faq', | |
| 205 | + 'fields' => 'ids', | |
| 206 | + 'post_status' => 'publish' | |
| 236 | 207 | ]); |
| 237 | 208 | } |
| 238 | 209 | |
| 239 | 210 | public function get_thumbnail_ids(array $post_ids): array { |
| @@ -285,8 +256,9 @@ | ||
| 285 | 256 | 'hide_empty' => false, |
| 286 | 257 | ]); |
| 287 | 258 | |
| 288 | 259 | if (is_wp_error($terms)) { |
| 260 | + error_log('Error fetching terms for glossaries: ' . $terms->get_error_message()); | |
| 289 | 261 | return []; |
| 290 | 262 | } |
| 291 | 263 | |
| 292 | 264 | // Include parent terms for hierarchical glossaries |