Admin
1 month ago
Builder
6 days ago
Customizer
6 days ago
Exceptions
6 months ago
Helpers
2 months ago
Integrations
6 days ago
Migrations
3 years ago
ReviewAlerts
3 weeks ago
Services
6 days ago
Settings
6 days ago
Support
3 months ago
Traits
1 month ago
UsageTracking
6 days ago
Utils
2 months ago
AuthorizationStatusCheck.php
1 month ago
BusinessDataCache.php
6 months ago
Clear_Cache.php
3 months ago
Container.php
6 months ago
DisplayElements.php
2 months ago
Email_Notification.php
6 months ago
Error_Reporter.php
3 months ago
Feed.php
3 weeks ago
FeedCache.php
5 months ago
FeedCacheUpdater.php
3 months ago
FeedDisplay.php
1 month ago
Feed_Locator.php
6 months ago
Parser.php
3 weeks ago
PostAggregator.php
2 months ago
RemoteRequest.php
6 days ago
SBR_Education.php
3 months ago
SBR_Schema_Service.php
3 weeks ago
SBR_Settings.php
6 months ago
ServiceContainer.php
6 days ago
SinglePostCache.php
3 weeks ago
TemplateRenderer.php
6 months ago
Tooltip_Wizard.php
1 month ago
Util.php
6 days ago
PostAggregator.php
576 lines
| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * Class SinglePostCache |
| 5 | * |
| 6 | * @since 1.0 |
| 7 | */ |
| 8 | |
| 9 | namespace SmashBalloon\Reviews\Common; |
| 10 | |
| 11 | use SmashBalloon\Reviews\Common\Builder\SBR_Feed_Saver_Manager; |
| 12 | use SmashBalloon\Reviews\Common\Helpers\Data_Encryption; |
| 13 | use SmashBalloon\Reviews\Pro\Integrations\Forms\ReviewsSubmissionsRules; |
| 14 | |
| 15 | class PostAggregator { |
| 16 | public const UPLOAD_FOLDER_NAME = 'sbr-feed-images'; |
| 17 | public const POSTS_TABLE_NAME = SBR_POSTS_TABLE; |
| 18 | |
| 19 | /** |
| 20 | * @var array |
| 21 | */ |
| 22 | private $post_set = array(); |
| 23 | |
| 24 | private $upload_dir; |
| 25 | |
| 26 | private $upload_url; |
| 27 | |
| 28 | private $missing_media_found; |
| 29 | |
| 30 | public function __construct() |
| 31 | { |
| 32 | $upload = wp_upload_dir(); |
| 33 | $upload_dir = $upload['basedir']; |
| 34 | $upload_dir = trailingslashit($upload_dir) . self::UPLOAD_FOLDER_NAME; |
| 35 | $this->upload_dir = $upload_dir; |
| 36 | |
| 37 | $upload_url = trailingslashit($upload['baseurl']) . self::UPLOAD_FOLDER_NAME; |
| 38 | $this->upload_url = $upload_url; |
| 39 | $this->missing_media_found = false; |
| 40 | } |
| 41 | |
| 42 | public function missing_media_found() |
| 43 | { |
| 44 | return $this->missing_media_found; |
| 45 | } |
| 46 | |
| 47 | public function add($post_set) |
| 48 | { |
| 49 | return $this->post_set = array_merge($this->post_set, $post_set); |
| 50 | } |
| 51 | |
| 52 | /** |
| 53 | * Get posts from database for given sources |
| 54 | * |
| 55 | * @param array $requests_needed Source IDs to fetch posts for |
| 56 | * @param string|int $language_or_limit Language code (deprecated, ignored) or limit number |
| 57 | * @param int $limit Maximum number of posts to fetch (default 150) |
| 58 | * @return array |
| 59 | */ |
| 60 | public function db_post_set($requests_needed, $language_or_limit = null, $limit = 150) |
| 61 | { |
| 62 | global $wpdb; |
| 63 | $table_name = esc_sql($wpdb->prefix . self::POSTS_TABLE_NAME); |
| 64 | $where_clause = $this->build_provider_business_where_clause($requests_needed); |
| 65 | |
| 66 | // Handle backwards compatibility: if second param is numeric, treat it as limit |
| 67 | // Otherwise, use third param (for calls that pass language string as second param) |
| 68 | if (is_numeric($language_or_limit) && $language_or_limit > 0) { |
| 69 | $limit = absint($language_or_limit); |
| 70 | } else { |
| 71 | $limit = absint($limit); |
| 72 | } |
| 73 | |
| 74 | // Ensure minimum limit of 1 |
| 75 | $limit = max(1, $limit); |
| 76 | |
| 77 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is esc_sql'd, where_clause built from sanitized values |
| 78 | $results = $wpdb->get_results( |
| 79 | "SELECT * FROM $table_name |
| 80 | WHERE $where_clause ORDER BY time_stamp DESC LIMIT $limit", |
| 81 | ARRAY_A |
| 82 | ); |
| 83 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 84 | $results = self::remove_duplicated_posts_list($results); |
| 85 | return $results; |
| 86 | } |
| 87 | |
| 88 | // phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh -- Pre-existing complexity |
| 89 | public static function remove_duplicated_posts_list($posts_list, $type = 'db') |
| 90 | { |
| 91 | // phpcs:enable Generic.Metrics.CyclomaticComplexity.TooHigh |
| 92 | $posts_db = []; |
| 93 | $posts_list_result = []; |
| 94 | $encryption = new Data_Encryption(); |
| 95 | foreach ($posts_list as $postKey => $post) { |
| 96 | $post = is_array($post) ? $post : json_decode($encryption->maybe_decrypt($post), true); |
| 97 | if ($type === 'db') { |
| 98 | $post['post_content'] = $post['provider'] === 'facebook' ? $encryption->maybe_decrypt($post['post_content']) : $post['post_content']; |
| 99 | $post['json_data'] = $post['provider'] === 'facebook' ? $encryption->maybe_decrypt($post['json_data']) : $post['json_data']; |
| 100 | $post_json = isset($post['json_data']) ? json_decode($post['json_data'], true) : null; |
| 101 | if (!empty($post_json)) { |
| 102 | $post_json['source'] = ['id' => $post['provider_id'], 'url' => $post_json['url'] ?? '']; |
| 103 | if (intval($post['images_done']) === 0) { |
| 104 | self::cache_review_images($post, $post_json); |
| 105 | } |
| 106 | } |
| 107 | } else { |
| 108 | $post_json = $post; |
| 109 | } |
| 110 | |
| 111 | if ($post_json !== null) { |
| 112 | // SMASH-1587: PHP 7-era json_data can hold a scalar 'provider' slug; |
| 113 | // the $post_json['provider']['name'] reads below fatal on PHP 8 without this. |
| 114 | $post_json = Util::normalize_review_shape($post_json); |
| 115 | $search_value = $post_json['source']['id'] . '-' . $post_json['rating'] . '-' . $post_json['reviewer']['name'] . '-' . $post_json['provider']['name']; |
| 116 | //IF EDD CHECK WITH TIME TOO SINCE A USER CAN POST MULTIPLE REVIEWS |
| 117 | $search_value .= $post_json['provider']['name'] === 'edd' ? $post_json['time'] : ''; |
| 118 | // Include text content hash to allow same rating from same reviewer with different content |
| 119 | $review_text = $post_json['text'] ?? ''; |
| 120 | if (! empty($review_text)) { |
| 121 | $search_value .= '-' . md5($review_text); |
| 122 | } |
| 123 | |
| 124 | if (!in_array($search_value, $posts_db)) { |
| 125 | array_push($posts_db, $search_value); |
| 126 | // For the 'json' path (cache-hit render, Feed.php:172) push the |
| 127 | // shape-normalized review so display readers (FeedDisplay/Parser) |
| 128 | // can't fatal on a scalar provider/reviewer/source from an old |
| 129 | // cache. The 'db' path returns raw rows that normalize_db_post_set |
| 130 | // re-decodes + normalizes, so it stays as-is. (SMASH-1587/WPSA-63160) |
| 131 | array_push($posts_list_result, $type === 'json' ? $post_json : $post); |
| 132 | } |
| 133 | } |
| 134 | } |
| 135 | return $posts_list_result; |
| 136 | } |
| 137 | |
| 138 | public static function cache_review_images($post, $post_json) |
| 139 | { |
| 140 | return; |
| 141 | $cache_post = [ |
| 142 | 'review_id' => $post_json['review_id'], |
| 143 | 'text' => $post_json['text'], |
| 144 | 'rating' => $post_json['rating'], |
| 145 | 'time' => $post_json['time'], |
| 146 | 'reviewer' => $post_json['reviewer'], |
| 147 | 'source' => [ |
| 148 | 'id' => $post_json['source']['id'], |
| 149 | 'url' => $post_json['source']['url'] |
| 150 | ], |
| 151 | 'lang' => $post['lang'], |
| 152 | ]; |
| 153 | SBR_Feed_Saver_Manager::cache_single_review( |
| 154 | $cache_post, |
| 155 | [ |
| 156 | 'id' => $post['provider_id'], |
| 157 | 'provider' => $post['provider'], |
| 158 | 'name' => $post['provider'], |
| 159 | 'url' => $post_json['source']['url'] |
| 160 | ], |
| 161 | $post['lang'], |
| 162 | sbr_get_no_media_providers(), |
| 163 | sbr_get_lang_providers() |
| 164 | ); |
| 165 | } |
| 166 | |
| 167 | // phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh -- Pre-existing complexity |
| 168 | public static function remove_duplicated_posts_routine() |
| 169 | { |
| 170 | global $wpdb; |
| 171 | $table_name = esc_sql($wpdb->prefix . self::POSTS_TABLE_NAME); |
| 172 | $posts_db = []; |
| 173 | $posts_id_todelete = []; |
| 174 | |
| 175 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is esc_sql'd |
| 176 | $results = $wpdb->get_results( |
| 177 | "SELECT * FROM $table_name", |
| 178 | ARRAY_A |
| 179 | ); |
| 180 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 181 | |
| 182 | foreach ($results as $post) { |
| 183 | $post_json = isset($post['json_data']) ? json_decode($post['json_data'], true) : null; |
| 184 | if ($post_json !== null) { |
| 185 | // SMASH-1587: scalar 'provider' in old json_data would fatal the reads below on PHP 8. |
| 186 | $post_json = Util::normalize_review_shape($post_json); |
| 187 | $search_value = $post_json['source']['id'] . '-' . $post_json['rating'] . '-' . $post_json['reviewer']['name'] . '-' . $post_json['provider']['name']; |
| 188 | //IF EDD CHECK WITH TIME TOO SINCE A USER CAN POST MULTIPLE REVIEWS |
| 189 | $search_value .= $post_json['provider']['name'] === 'edd' ? $post_json['time'] : ''; |
| 190 | |
| 191 | if (in_array($search_value, $posts_db)) { |
| 192 | array_push($posts_id_todelete, $post['id']); |
| 193 | } else { |
| 194 | array_push($posts_db, $search_value); |
| 195 | } |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | if (sizeof($posts_id_todelete) > 0) { |
| 200 | $posts_ids = implode(',', $posts_id_todelete); |
| 201 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- IDs are integers from DB, table name is esc_sql'd |
| 202 | $wpdb->query( |
| 203 | "DELETE FROM $table_name WHERE id IN ($posts_ids)" |
| 204 | ); |
| 205 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 206 | } |
| 207 | } |
| 208 | // phpcs:enable Generic.Metrics.CyclomaticComplexity.TooHigh |
| 209 | |
| 210 | |
| 211 | public function db_posts_for_media_finding_and_resizing_set($requests_needed) |
| 212 | { |
| 213 | global $wpdb; |
| 214 | $table_name = esc_sql($wpdb->prefix . self::POSTS_TABLE_NAME); |
| 215 | |
| 216 | $where_clause = $this->build_provider_business_where_clause($requests_needed); |
| 217 | |
| 218 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is esc_sql'd, where_clause built from sanitized values |
| 219 | $results = $wpdb->get_results( |
| 220 | "SELECT * FROM $table_name |
| 221 | WHERE $where_clause |
| 222 | AND images_done = 0 |
| 223 | ORDER BY time_stamp DESC LIMIT 150", |
| 224 | ARRAY_A |
| 225 | ); |
| 226 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 227 | |
| 228 | return $results; |
| 229 | } |
| 230 | |
| 231 | |
| 232 | |
| 233 | public function normalize_db_post_set($results) |
| 234 | { |
| 235 | $normalized_set = array(); |
| 236 | foreach ($results as $result) { |
| 237 | if (! empty($result['json_data'])) { |
| 238 | $post = json_decode($result['json_data'], true); |
| 239 | if (! empty($post)) { |
| 240 | // SMASH-1587/WPSA-63160: PHP 7-era json_data can hold scalar |
| 241 | // provider/reviewer/source/media shapes. This is the render-path |
| 242 | // source (posts_from_db, moderation, media-finding), so coerce here |
| 243 | // once — covers add_local_image_urls below + every FeedDisplay / |
| 244 | // Parser reader downstream, which would otherwise fatal on PHP 8. |
| 245 | $post = Util::normalize_review_shape($post); |
| 246 | $post = self::add_local_image_urls($post, $result); |
| 247 | } |
| 248 | if ((int)$result['images_done'] === 0) { |
| 249 | $this->missing_media_found = true; |
| 250 | } |
| 251 | $normalized_set[] = $post; |
| 252 | } |
| 253 | } |
| 254 | |
| 255 | return $normalized_set; |
| 256 | } |
| 257 | |
| 258 | public function add_local_image_urls($post, $result) |
| 259 | { |
| 260 | $return = $post; |
| 261 | $base_url = $this->upload_url; |
| 262 | $resize_url = apply_filters('sbr_resize_url', trailingslashit($base_url)); |
| 263 | |
| 264 | if (! empty($post['reviewer']['avatar'])) { |
| 265 | if (! empty($result['avatar_id']) && $result['avatar_id'] !== 'error') { |
| 266 | $return['reviewer']['avatar_local'] = $resize_url . $result['avatar_id'] . '.png'; |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | if (! empty($post['media'])) { |
| 271 | $sizes = ! empty($result['sizes']) ? json_decode($result['sizes']) : array(); |
| 272 | $i = 0; |
| 273 | foreach ($post['media'] as $single_image) { |
| 274 | // A scalar media element (e.g. a flat URL string) would make the |
| 275 | // $return['media'][$i]['local'] write below a string-offset write = |
| 276 | // PHP 8 fatal. Skip it (keep $i aligned to the media index). SMASH-1587. |
| 277 | if (! is_array($single_image)) { |
| 278 | $i++; |
| 279 | continue; |
| 280 | } |
| 281 | if (! empty($result['media_id']) && $result['media_id'] !== 'error') { |
| 282 | $return['media'][ $i ]['local'] = array(); |
| 283 | $media_id = $result['media_id']; |
| 284 | foreach ($sizes as $size) { |
| 285 | $local_url_for_size = $resize_url . $media_id . '-' . $i . '-' . $size . '.jpg'; |
| 286 | $return['media'][ $i ]['local'][ $size ] = $local_url_for_size; |
| 287 | } |
| 288 | } |
| 289 | $i++; |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | return $return; |
| 294 | } |
| 295 | |
| 296 | public function update_last_requested($requests_needed) |
| 297 | { |
| 298 | global $wpdb; |
| 299 | $table_name = esc_sql($wpdb->prefix . self::POSTS_TABLE_NAME); |
| 300 | $where_clause = $this->build_provider_business_where_clause($requests_needed); |
| 301 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is esc_sql'd, where_clause built from sanitized values |
| 302 | $query = $wpdb->query( |
| 303 | $wpdb->prepare( |
| 304 | "UPDATE $table_name |
| 305 | SET last_requested = %s |
| 306 | WHERE $where_clause;", |
| 307 | date('Y-m-d') |
| 308 | ) |
| 309 | ); |
| 310 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 311 | } |
| 312 | |
| 313 | private function build_provider_business_where_clause($requests_needed) |
| 314 | { |
| 315 | |
| 316 | $i = 1; |
| 317 | $where_clause = ''; |
| 318 | foreach ($requests_needed as $request) { |
| 319 | $single_clause = sprintf('provider_id = "%s"', esc_sql($request['account_id'])); |
| 320 | if (isset($request['lang'])) { |
| 321 | $single_clause .= sprintf(' AND lang = "%s"', esc_sql($request['lang'])); |
| 322 | } |
| 323 | $where_clause .= '(' . $single_clause . ')'; |
| 324 | if ($i < count($requests_needed)) { |
| 325 | $where_clause .= ' OR '; |
| 326 | } |
| 327 | $i++; |
| 328 | } |
| 329 | |
| 330 | return $where_clause; |
| 331 | } |
| 332 | |
| 333 | |
| 334 | /** |
| 335 | * Get List Provider/Source Posts |
| 336 | * |
| 337 | * @param string $provider_id | int $page |
| 338 | * |
| 339 | * @return array |
| 340 | * |
| 341 | * @since 1.4 |
| 342 | */ |
| 343 | public static function get_source_posts_list($provider_id, $page = 1) |
| 344 | { |
| 345 | global $wpdb; |
| 346 | $table_name = esc_sql($wpdb->prefix . self::POSTS_TABLE_NAME); |
| 347 | $limit = 40; |
| 348 | $offset = ($page - 1) * $limit; |
| 349 | $encryption = new Data_Encryption(); |
| 350 | |
| 351 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is esc_sql'd |
| 352 | $results = $wpdb->get_results( |
| 353 | $wpdb->prepare( |
| 354 | "SELECT * |
| 355 | FROM $table_name |
| 356 | WHERE provider_id = %s |
| 357 | ORDER BY id DESC |
| 358 | LIMIT %d |
| 359 | OFFSET %d |
| 360 | ", |
| 361 | $provider_id, |
| 362 | $limit, |
| 363 | $offset |
| 364 | ), |
| 365 | ARRAY_A |
| 366 | ); |
| 367 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 368 | |
| 369 | $decrypted_results = []; |
| 370 | foreach ($results as $s_post) { |
| 371 | if ($s_post['provider'] === 'facebook') { |
| 372 | $s_post['post_content'] = $encryption->maybe_decrypt($s_post['post_content']); |
| 373 | $s_post['json_data'] = $encryption->maybe_decrypt($s_post['json_data']); |
| 374 | $json_data = json_decode($s_post['json_data'], true); |
| 375 | |
| 376 | if (isset($json_data['rating']) && !is_numeric($json_data['rating'])) { |
| 377 | $rating = isset($json_data['rating']) && $json_data['rating'] === 'negative' ? 1 : 5; |
| 378 | $json_data['rating'] = $rating; |
| 379 | } |
| 380 | |
| 381 | $s_post['json_data'] = wp_json_encode($json_data); |
| 382 | } |
| 383 | array_push($decrypted_results, $s_post); |
| 384 | } |
| 385 | return $decrypted_results; |
| 386 | } |
| 387 | |
| 388 | /** |
| 389 | * Delete Review from Collection |
| 390 | * |
| 391 | * @param string $provider_id | string $provider |
| 392 | * |
| 393 | * @return void |
| 394 | * |
| 395 | * @since 1.4 |
| 396 | */ |
| 397 | public static function delete_review($provider_id, $review_id, $provider) |
| 398 | { |
| 399 | global $wpdb; |
| 400 | $table_name = esc_sql($wpdb->prefix . self::POSTS_TABLE_NAME); |
| 401 | $provider_value = $provider === 'collection' ? 'none' : $provider; |
| 402 | |
| 403 | ReviewsSubmissionsRules::remove_auto_approved($review_id, $provider_id, '', 'single', false); |
| 404 | |
| 405 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is esc_sql'd |
| 406 | $wpdb->query( |
| 407 | $wpdb->prepare( |
| 408 | "DELETE FROM $table_name |
| 409 | WHERE provider_id = %s AND provider = %s AND post_id = %s |
| 410 | ", |
| 411 | $provider_id, |
| 412 | $provider_value, |
| 413 | $review_id |
| 414 | ) |
| 415 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 416 | ); |
| 417 | } |
| 418 | |
| 419 | |
| 420 | /** |
| 421 | * Select a List of reviews By Review ID |
| 422 | * |
| 423 | * @param array $reviews_ids |
| 424 | * |
| 425 | * @return array|boolean |
| 426 | * |
| 427 | * @since 1.4 |
| 428 | */ |
| 429 | public static function get_list_reviews_by_ids($reviews_ids) |
| 430 | { |
| 431 | global $wpdb; |
| 432 | $table_name = $wpdb->prefix . self::POSTS_TABLE_NAME; |
| 433 | |
| 434 | if (empty($reviews_ids) || ! is_array($reviews_ids)) { |
| 435 | return false; |
| 436 | } |
| 437 | |
| 438 | // Filter out empty values |
| 439 | $reviews_ids = array_filter($reviews_ids, function ($id) { |
| 440 | return ! empty($id); |
| 441 | }); |
| 442 | |
| 443 | if (empty($reviews_ids)) { |
| 444 | return false; |
| 445 | } |
| 446 | |
| 447 | // Build placeholders for prepare() - one %s for each ID |
| 448 | $placeholders = implode(', ', array_fill(0, count($reviews_ids), '%s')); |
| 449 | |
| 450 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is internal constant, placeholders are dynamically generated |
| 451 | $results = $wpdb->get_results( |
| 452 | $wpdb->prepare( |
| 453 | "SELECT * FROM {$table_name} WHERE post_id IN ({$placeholders})", |
| 454 | ...$reviews_ids |
| 455 | ), |
| 456 | ARRAY_A |
| 457 | ); |
| 458 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 459 | |
| 460 | return $results; |
| 461 | } |
| 462 | |
| 463 | /** |
| 464 | * Select a List of reviews By Review ID |
| 465 | * |
| 466 | * @param string $provider_id | array $reviews_ids |
| 467 | * |
| 468 | * @return void |
| 469 | * |
| 470 | * @since 1.4 |
| 471 | */ |
| 472 | public static function insert_multiple_reviews($provider_id, $reviews_ids) |
| 473 | { |
| 474 | $reviews_to_insert = PostAggregator::get_list_reviews_by_ids($reviews_ids); |
| 475 | $encryption = new Data_Encryption(); |
| 476 | if (is_array($reviews_to_insert)) { |
| 477 | foreach ($reviews_to_insert as $rev) { |
| 478 | $review_id = $provider_id . time() . wp_rand(); |
| 479 | $json_data = $encryption->maybe_decrypt($rev['json_data']); |
| 480 | $review = json_decode($json_data, true); |
| 481 | $review_store = Util::parse_single_review($review, $provider_id, $review_id); |
| 482 | $review_store['json_data'] = $review_store; |
| 483 | |
| 484 | $single_post_cache = new \SmashBalloon\Reviews\Pro\SinglePostCache($review_store, new \SmashBalloon\Reviews\Pro\MediaFinder($review_store['source'])); |
| 485 | $single_post_cache->set_provider_id($provider_id); |
| 486 | $single_post_cache->store(); |
| 487 | } |
| 488 | } |
| 489 | } |
| 490 | |
| 491 | /** |
| 492 | * Delete All Reviews from Provider/Source ID |
| 493 | * |
| 494 | * @param string $provider_id |
| 495 | * |
| 496 | * @return void |
| 497 | * |
| 498 | * @since 1.4 |
| 499 | */ |
| 500 | public static function delete_reviews_by_provide_id($provider_id) |
| 501 | { |
| 502 | global $wpdb; |
| 503 | $table_name = esc_sql($wpdb->prefix . self::POSTS_TABLE_NAME); |
| 504 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is esc_sql'd |
| 505 | $wpdb->query( |
| 506 | $wpdb->prepare( |
| 507 | "DELETE FROM $table_name |
| 508 | WHERE provider_id = %s", |
| 509 | $provider_id |
| 510 | ) |
| 511 | ); |
| 512 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 513 | } |
| 514 | |
| 515 | /** |
| 516 | * Get List Provider/Source Posts |
| 517 | * |
| 518 | * @param string $provider_id |
| 519 | * |
| 520 | * @return array |
| 521 | * |
| 522 | * @since 1.4 |
| 523 | */ |
| 524 | public static function get_source_all_posts($provider_id) |
| 525 | { |
| 526 | global $wpdb; |
| 527 | $table_name = esc_sql($wpdb->prefix . self::POSTS_TABLE_NAME); |
| 528 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is esc_sql'd |
| 529 | $results = $wpdb->get_results( |
| 530 | $wpdb->prepare( |
| 531 | "SELECT * |
| 532 | FROM $table_name |
| 533 | WHERE provider_id = %s |
| 534 | ", |
| 535 | $provider_id |
| 536 | ), |
| 537 | ARRAY_A |
| 538 | ); |
| 539 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 540 | return $results; |
| 541 | } |
| 542 | |
| 543 | |
| 544 | /** |
| 545 | * Search Reviews of a specific Provider |
| 546 | * |
| 547 | * @param string $provider_id | string $search_text |
| 548 | * |
| 549 | * @return array |
| 550 | * |
| 551 | * @since 1.4 |
| 552 | */ |
| 553 | public static function search_source_posts_list($provider_id, $search_text) |
| 554 | { |
| 555 | global $wpdb; |
| 556 | $table_name = esc_sql($wpdb->prefix . self::POSTS_TABLE_NAME); |
| 557 | $search_text_array = explode(' ', $search_text); |
| 558 | $search_string = implode('.*', $search_text_array); |
| 559 | // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder -- Table name is esc_sql'd, REGEXP requires quotes |
| 560 | $results = $wpdb->get_results( |
| 561 | $wpdb->prepare( |
| 562 | "SELECT * |
| 563 | FROM $table_name |
| 564 | WHERE provider_id = %s |
| 565 | AND json_data REGEXP '%s' |
| 566 | ", |
| 567 | $provider_id, |
| 568 | $search_string |
| 569 | ), |
| 570 | ARRAY_A |
| 571 | ); |
| 572 | // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder |
| 573 | return $results; |
| 574 | } |
| 575 | } |
| 576 |