Config
3 weeks ago
SBR_Feed_Builder.php
3 weeks ago
SBR_Feed_Saver.php
3 weeks ago
SBR_Feed_Saver_Manager.php
3 weeks ago
SBR_New_Providers_Manager.php
3 weeks ago
SBR_Sources.php
3 weeks ago
SBR_Sources.php
321 lines
| 1 | <?php |
| 2 | |
| 3 | // phpcs:disable WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery |
| 4 | // Note: Legacy file with dynamic table name queries. Table names are internal constants. |
| 5 | |
| 6 | /** |
| 7 | * Reviews Sources Management |
| 8 | * |
| 9 | * @since 1.0 |
| 10 | */ |
| 11 | |
| 12 | namespace SmashBalloon\Reviews\Common\Builder; |
| 13 | |
| 14 | use SmashBalloon\Reviews\Common\Clear_Cache; |
| 15 | use SmashBalloon\Reviews\Common\Customizer\DB; |
| 16 | use SmashBalloon\Reviews\Common\PostAggregator; |
| 17 | |
| 18 | class SBR_Sources{ |
| 19 | /** |
| 20 | * Add a new source as a row in the sbi_sources table |
| 21 | * |
| 22 | * @param array $source_data |
| 23 | * |
| 24 | * @return false|int |
| 25 | * |
| 26 | * @since 1.0 |
| 27 | */ |
| 28 | public static function insert($source_data) |
| 29 | { |
| 30 | $db = new DB(); |
| 31 | // Only use 'id' as 'account_id' if account_id is not already set |
| 32 | if (isset($source_data['id']) && !isset($source_data['account_id'])) { |
| 33 | $source_data['account_id'] = $source_data['id']; |
| 34 | } |
| 35 | // Remove 'id' from data as the DB table uses 'account_id' |
| 36 | if (isset($source_data['id'])) { |
| 37 | unset($source_data['id']); |
| 38 | } |
| 39 | |
| 40 | // Decode HTML entities in account_id (fixes Danish characters like æ, ø, å) |
| 41 | if (isset($source_data['account_id'])) { |
| 42 | $source_data['account_id'] = html_entity_decode($source_data['account_id'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); |
| 43 | } |
| 44 | |
| 45 | $data = $source_data; |
| 46 | |
| 47 | return $db->source_insert($data); |
| 48 | } |
| 49 | |
| 50 | /** |
| 51 | * Whether or not the source exists in the database |
| 52 | * |
| 53 | * @param array $args |
| 54 | * |
| 55 | * @return bool |
| 56 | * |
| 57 | * @since 6.0 |
| 58 | */ |
| 59 | public static function exists_in_database($args) |
| 60 | { |
| 61 | $db = new DB(); |
| 62 | $results = $db->get_single_source($args); |
| 63 | return isset($results[0]); |
| 64 | } |
| 65 | |
| 66 | |
| 67 | /** |
| 68 | * Get Single Source |
| 69 | * |
| 70 | * @param array $args |
| 71 | * |
| 72 | * @return array |
| 73 | * |
| 74 | * @since 6.0 |
| 75 | */ |
| 76 | public static function get_single_source_info($args) |
| 77 | { |
| 78 | $db = new DB(); |
| 79 | $results = $db->get_single_source($args); |
| 80 | return isset($results[0]) ? $results[0] : []; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Used to update or insert connected accounts (sources) |
| 85 | * |
| 86 | * @param array $source_data |
| 87 | * |
| 88 | * @return bool |
| 89 | * |
| 90 | * @since 6.0 |
| 91 | */ |
| 92 | public static function update_or_insert($source_data) |
| 93 | { |
| 94 | if (! isset($source_data['id'])) { |
| 95 | return false; |
| 96 | } |
| 97 | |
| 98 | if (isset($source_data)) { |
| 99 | // data from an API request related to the source is saved as a JSON string |
| 100 | // Only wrap if 'info' is not already set (to avoid double-wrapping) |
| 101 | if (( is_object($source_data) || is_array($source_data) ) && ! isset($source_data['info'])) { |
| 102 | $source_data['info'] = sbr_json_encode($source_data); |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | if (self::exists_in_database($source_data)) { |
| 107 | $source_data['last_updated'] = date('Y-m-d H:i:s'); |
| 108 | self::update($source_data, false); |
| 109 | } else { |
| 110 | self::insert($source_data); |
| 111 | } |
| 112 | |
| 113 | return true; |
| 114 | } |
| 115 | |
| 116 | /** |
| 117 | * Update info in rows that match the source data |
| 118 | * |
| 119 | * @param array $source_data |
| 120 | * |
| 121 | * @return false|int |
| 122 | * |
| 123 | * @since 6.0 |
| 124 | */ |
| 125 | public static function update($source_data) |
| 126 | { |
| 127 | $where = array( |
| 128 | 'id' => $source_data['id'], |
| 129 | 'provider' => $source_data['provider'] |
| 130 | ); |
| 131 | |
| 132 | $data = $source_data; |
| 133 | $db = new DB(); |
| 134 | return $db->source_update($data, $where); |
| 135 | } |
| 136 | |
| 137 | |
| 138 | /** |
| 139 | * Update info in rows that match the source data |
| 140 | * |
| 141 | * @param array $source_data |
| 142 | * |
| 143 | * @return false|int |
| 144 | * |
| 145 | * @since 6.0 |
| 146 | */ |
| 147 | public static function delete_source($source_id) |
| 148 | { |
| 149 | $db = new DB(); |
| 150 | return $db->delete_source($source_id); |
| 151 | } |
| 152 | |
| 153 | /** |
| 154 | * Get Sources |
| 155 | * |
| 156 | * @return array |
| 157 | * |
| 158 | * @since 1.0 |
| 159 | */ |
| 160 | public static function get_sources_list($args = []) |
| 161 | { |
| 162 | $db = new DB(); |
| 163 | return $db->source_query($args); |
| 164 | } |
| 165 | |
| 166 | /** |
| 167 | * Get Sources Count |
| 168 | * |
| 169 | * @param array $args Optional args including 'search' for filtering |
| 170 | * @return int |
| 171 | * |
| 172 | * @since 1.0 |
| 173 | */ |
| 174 | public static function get_sources_count($args = array()) |
| 175 | { |
| 176 | $db = new DB(); |
| 177 | return $db->source_query_count($args); |
| 178 | } |
| 179 | |
| 180 | |
| 181 | |
| 182 | |
| 183 | /** |
| 184 | * Update Collection Info |
| 185 | * Number of Reviews and Ratings average |
| 186 | * |
| 187 | * @return array|boolean |
| 188 | * |
| 189 | * @since 1.0 |
| 190 | */ |
| 191 | public static function update_collection_ratings($account_id) |
| 192 | { |
| 193 | $db = new DB(); |
| 194 | $args = [ |
| 195 | 'id' => $account_id, |
| 196 | 'provider' => 'collection' |
| 197 | ]; |
| 198 | $results = $db->get_single_source($args); |
| 199 | if (!isset($results[0])) { |
| 200 | return false; |
| 201 | } |
| 202 | $collection = $results[0]; |
| 203 | |
| 204 | if (isset($collection['instances']) && sizeof($collection['instances']) > 0) { |
| 205 | $feed_ids = []; |
| 206 | foreach ($collection['instances'] as $instance) { |
| 207 | array_push( |
| 208 | $feed_ids, |
| 209 | $instance['id'], |
| 210 | $instance['id'] . '_CUSTOMIZER' |
| 211 | ); |
| 212 | } |
| 213 | unset($collection['instances']); |
| 214 | unset($collection['used_in']); |
| 215 | Clear_Cache::clear_feed_caches_by_id($feed_ids); |
| 216 | } |
| 217 | |
| 218 | $reviews_list = PostAggregator::get_source_all_posts($account_id); |
| 219 | $rating = 0; |
| 220 | $total_rating = sizeof($reviews_list); |
| 221 | |
| 222 | foreach ($reviews_list as $review) { |
| 223 | $rating += isset($review['rating']) ? intval($review['rating']) : 0; |
| 224 | } |
| 225 | |
| 226 | $info_collection = json_decode($collection['info'], true); |
| 227 | $info_collection['total_rating'] = $total_rating; |
| 228 | $info_collection['rating'] = $total_rating > 0 ? ceil($rating / $total_rating) : 0; |
| 229 | |
| 230 | |
| 231 | $collection['last_updated'] = date('Y-m-d H:i:s'); |
| 232 | $collection['id'] = $account_id; |
| 233 | $collection['info'] = json_encode($info_collection); |
| 234 | SBR_Sources::update($collection); |
| 235 | |
| 236 | return $collection; |
| 237 | } |
| 238 | |
| 239 | /** |
| 240 | * Get Sources List By Provider |
| 241 | * |
| 242 | * @param array $providers |
| 243 | * |
| 244 | * @return array |
| 245 | * |
| 246 | * @since 2.0 |
| 247 | */ |
| 248 | public static function sources_by_providers($providers = []) |
| 249 | { |
| 250 | global $wpdb; |
| 251 | $source_table = $wpdb->prefix . SBR_SOURCES_TABLE; |
| 252 | |
| 253 | if (empty($providers)) { |
| 254 | return []; |
| 255 | } |
| 256 | |
| 257 | // Build placeholders for each provider string (%s for strings, not %d) |
| 258 | $placeholders = implode(', ', array_fill(0, count($providers), '%s')); |
| 259 | |
| 260 | // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare |
| 261 | $sql = $wpdb->prepare( |
| 262 | "SELECT * FROM $source_table WHERE provider IN ($placeholders)", |
| 263 | ...$providers |
| 264 | ); |
| 265 | return $wpdb->get_results($sql, ARRAY_A); |
| 266 | } |
| 267 | |
| 268 | /** |
| 269 | * Check Source reviews were already retrieved |
| 270 | * |
| 271 | * @param string $provider |
| 272 | * @param string $provider_id |
| 273 | * |
| 274 | * @return boolean |
| 275 | * |
| 276 | * @since 2.0 |
| 277 | */ |
| 278 | public static function already_fetched($provider, $provider_id) |
| 279 | { |
| 280 | global $wpdb; |
| 281 | $posts_table = $wpdb->prefix . SBR_POSTS_TABLE; |
| 282 | |
| 283 | // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is safe constant |
| 284 | $sql = $wpdb->prepare( |
| 285 | "SELECT COUNT(*) FROM $posts_table WHERE provider = %s AND provider_id = %s", |
| 286 | $provider, |
| 287 | $provider_id |
| 288 | ); |
| 289 | |
| 290 | return $wpdb->get_var($sql) > 0; |
| 291 | } |
| 292 | |
| 293 | /** |
| 294 | * Check Source reviews were already retrieved |
| 295 | * The Current Week |
| 296 | * |
| 297 | * @param string $provider |
| 298 | * @param string $provider_id |
| 299 | * |
| 300 | * @return boolean |
| 301 | * |
| 302 | * @since 2.0 |
| 303 | */ |
| 304 | public static function already_fetched_week($provider, $provider_id) |
| 305 | { |
| 306 | global $wpdb; |
| 307 | $posts_table = $wpdb->prefix . SBR_POSTS_TABLE; |
| 308 | |
| 309 | // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is safe constant |
| 310 | $sql = $wpdb->prepare( |
| 311 | "SELECT COUNT(*) FROM $posts_table |
| 312 | WHERE provider = %s AND provider_id = %s AND created_on > %s", |
| 313 | $provider, |
| 314 | $provider_id, |
| 315 | gmdate('Y-m-d', strtotime('-1 week', time())) |
| 316 | ); |
| 317 | |
| 318 | return $wpdb->get_var($sql) > 0; |
| 319 | } |
| 320 | } |
| 321 |