?AlkantarClanX12
| Current Path : /home/rankinh/saintgilleslesbains-bis/wp-content/plugins/reviews-feed/class/Common/ |
| Current File : /home/rankinh/saintgilleslesbains-bis/wp-content/plugins/reviews-feed/class/Common/Feed.php |
<?php
// phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
// Note: Legacy file with complex feed rendering logic. Refactoring planned.
/**
* Class Feed
*
* @since 1.0
*/
namespace SmashBalloon\Reviews\Common;
use SmashBalloon\Reviews\Common\Builder\SBR_Feed_Saver_Manager;
use SmashBalloon\Reviews\Common\Builder\SBR_Sources;
use SmashBalloon\Reviews\Common\Helpers\Data_Encryption;
class Feed
{
protected $posts = array();
protected $header_data = array();
/**
* @var FeedCache
*/
protected $feed_cache;
protected $statuses = array();
protected $settings;
protected $feed_id;
private $feed_style;
private $flag_media_check;
private $providers_languages;
/**
* Data_Encryption
*/
private $encryption;
/**
* @var array|string[]
*/
protected $providers_no_media = [];
public function __construct($settings, $feed_id, FeedCache $feed_cache)
{
$this->feed_cache = $feed_cache;
$this->feed_id = $feed_id;
// Ensure settings is an array to prevent PHP 8.1+ deprecation warning
$this->settings = is_array($settings) ? $settings : [];
$this->settings['apiCallLanguage'] = Util::get_api_call_language($this->settings);
$this->feed_style = is_array($settings) && isset($settings['feed_style']) ? $settings['feed_style'] : '';
$this->statuses = array(
'from_cache' => false,
'post_found_before_filter' => false,
'errors' => array()
);
$this->flag_media_check = false;
$this->providers_languages = [
'facebook',
'google'
];
$this->providers_no_media = sbr_get_no_media_providers();
$this->encryption = new Data_Encryption();
}
public function init()
{
if (empty($this->settings)) {
$this->add_error(sprintf(__('No feed with the ID %d found.', 'reviews-feed'), $this->feed_id), sprintf(__('Please go to the %sReviews Feed%s settings page to create a feed.', 'reviews-feed'), '<a href="' . esc_url(admin_url('admin.php?page=sbr')) . '" target="_blank" rel="noopener noreferrer">', '</a>'));
return;
}
if (empty($this->settings['sources']) && ! $this->is_single_manual_review()) {
$this->add_error(sprintf(__('No sources available for this feed.', 'reviews-feed'), $this->feed_id), sprintf(__('Please go to the %sReviews Feed%s settings page add sources for this feed to use.', 'reviews-feed'), '<a href="' . esc_url(admin_url('admin.php?page=sbr')) . '" target="_blank" rel="noopener noreferrer">', '</a>'));
return;
}
if (! $this->is_single_manual_review()) {
$this->hydrate_sources();
}
}
public function get_settings()
{
return $this->settings;
}
public function get_errors()
{
return $this->statuses['errors'];
}
public function set_errors($errors_array)
{
$this->statuses['errors'] = $errors_array;
}
public function add_error($message, $instructions)
{
$this->statuses['errors'][] = array(
'message' => $message,
'directions' => $instructions
);
}
public function get_feed_id()
{
return $this->feed_id;
}
public function get_feed_style()
{
return $this->feed_style;
}
public function set_posts($posts)
{
$this->posts = $posts;
}
public function get_posts()
{
return $this->posts;
}
public function should_check_media()
{
return $this->flag_media_check;
}
public function set_header_data($header_data)
{
$this->header_data = $header_data;
}
public function get_header_data()
{
return $this->header_data;
}
public function is_single_manual_review()
{
return isset($this->settings['singleManualReview']) && $this->settings['singleManualReview'] === true;
}
public function get_set_cache()
{
if (! $this->is_single_manual_review()) {
$this->feed_cache->retrieve_and_set();
if ($this->feed_cache->is_expired()) {
$posts = $this->update_posts_cache();
$header_data = $this->update_header_cache();
} else {
$this->statuses['from_cache'] = true;
$posts = json_decode($this->feed_cache->get('posts'), true);
$header_data = $this->feed_cache->get('header') !== null ? json_decode($this->feed_cache->get('header'), true) : $this->update_header_cache_from_source();
$error_cache = $this->feed_cache->get('errors');
if (is_string($error_cache)) {
$error_cache = json_decode($error_cache, true);
}
$this->set_errors($error_cache);
}
$posts = PostAggregator::remove_duplicated_posts_list($posts, 'json');
if (empty($header_data)) {
$header_data = $this->update_header_cache_from_source();
}
$this->set_posts($posts);
$this->set_header_data($header_data);
}
}
public function update_posts_cache()
{
$settings = $this->get_settings();
if (empty($settings['sources'])) {
return array();
}
$remote_posts = $this->get_remote_posts($settings);
foreach ($remote_posts as $provider_remote_posts) {
if (isset($provider_remote_posts['data']['reviews'])) {
$this->cache_single_posts_from_set($provider_remote_posts['data']['reviews'], $provider_remote_posts['provider_id']);
}
}
$posts = $this->posts_from_db();
if (empty($posts)) {
$no_posts_found = __('No Posts Found.', 'reviews-feed');
if ($this->statuses['post_found_before_filter']) {
$this->add_error($no_posts_found, sprintf(__('There were no posts that fit your filters. Try modifying the filters set or add more sources with reviews that fit the filter by %sediting your feed%s', 'reviews-feed'), '<a href="' . esc_url(admin_url('admin.php?page=sbr')) . '" target="_blank" rel="noopener noreferrer">', '</a>'));
} else {
$this->add_error($no_posts_found, sprintf(__('There were no posts found for the sources selected. Make sure reviews are available for this source or change the source by %sediting your feed%s', 'reviews-feed'), '<a href="' . esc_url(admin_url('admin.php?page=sbr')) . '" target="_blank" rel="noopener noreferrer">', '</a>'));
}
}
$posts = $this->maybe_encrypt_cached_posts($posts);
$this->update_cache($posts);
return $posts;
}
/**
* Used to filter Posts and check Facebook that should be encrypted
*
* @param $posts posts list
*
* @return array
*
*/
public function maybe_encrypt_cached_posts($posts)
{
foreach ($posts as $key => $s_post) {
if (isset($s_post['provider']['name']) && $s_post['provider']['name'] === 'facebook') {
$posts[$key] = $this->encryption->maybe_encrypt(wp_json_encode($s_post));
}
}
return $posts;
}
public function posts_from_db()
{
$settings = $this->get_settings();
$aggregator = new PostAggregator();
// Pass limit from settings (default 150 for backward compatibility)
$limit = isset($settings['numPostDesktop']) ? max(150, (int) $settings['numPostDesktop']) : 150;
$posts = $aggregator->db_post_set($settings['sources'], $this->settings['apiCallLanguage'], $limit);
$posts = $aggregator->normalize_db_post_set($posts);
if ($aggregator->missing_media_found()) {
$this->flag_media_check = true;
}
$aggregator->update_last_requested($settings['sources']);
if (! empty($posts)) {
$this->statuses['post_found_before_filter'] = true;
}
return $this->filter_posts($posts, $settings, true);
}
public function update_cache($posts)
{
$this->feed_cache->update_or_insert('posts', json_encode($posts));
$this->feed_cache->clear('errors');
$this->feed_cache->update_or_insert('errors', json_encode($this->get_errors()));
}
public function update_header_cache()
{
$settings = $this->get_settings();
if (empty($settings['sources'])) {
return array();
}
$remote_header_data = $this->get_remote_header_data($settings);
if (!empty($remote_header_data) && isset($remote_header_data[0]) && isset($remote_header_data[0]['info']) && isset($remote_header_data[0]['info']['id'])) {
$persistent_business_data_cache = new BusinessDataCache();
$persistent_business_data_cache->update_data($settings['sources'][0]['provider'], $remote_header_data[0]['info']['id'], $remote_header_data);
$this->feed_cache->update_or_insert('header', json_encode($remote_header_data));
$source_to_update = [
'id' => $remote_header_data[0]['info']['id'],
'provider' => $settings['sources'][0]['provider'],
'last_updated' => date('Y-m-d H:i:s'),
'info' => json_encode($remote_header_data[0]['info'])
];
SBR_Sources::update($source_to_update);
}
return $remote_header_data;
}
public function update_header_cache_from_source()
{
$settings = $this->get_settings();
if (empty($settings['sources'])) {
return array();
}
// Decode info field if it's a JSON string
foreach ($settings['sources'] as $key => $source) {
if (isset($source['info']) && is_string($source['info'])) {
$decoded = json_decode($source['info'], true);
// Handle malformed JSON by setting empty array to prevent null access errors
$settings['sources'][$key]['info'] = is_array($decoded) ? $decoded : [];
}
}
$total_rating = 0;
$rating = 0;
foreach ($settings['sources'] as $s_source) {
// Handle both standard sources (total_rating/rating) and WooCommerce (review_count/average_rating)
$source_total = $s_source['info']['total_rating'] ?? $s_source['info']['review_count'] ?? 0;
$source_rating = $s_source['info']['rating'] ?? $s_source['info']['average_rating'] ?? 0;
$total_rating += intval($source_total);
$rating += floatval($source_rating);
}
$rating_average = $rating > 0 ? $rating / sizeof($settings['sources']) : 0;
// Get source ID - use account_id as fallback for WooCommerce multi-product sources
$source_id = $settings['sources'][0]['info']['id'] ?? $settings['sources'][0]['account_id'] ?? '';
$source_name = $settings['sources'][0]['info']['name'] ?? $settings['sources'][0]['info']['source_name'] ?? $settings['sources'][0]['name'] ?? 'Unknown';
$remote_header_data = [
[
'info' => [
'id' => $source_id,
'name' => $source_name,
'rating' => $rating_average,
'total_rating' => $total_rating,
'url' => $settings['sources'][0]['info']['url'] ?? ''
]
]
];
$persistent_business_data_cache = new BusinessDataCache();
$persistent_business_data_cache->update_data($settings['sources'][0]['provider'], $source_id, $remote_header_data);
$this->feed_cache->update_or_insert('header', json_encode($remote_header_data));
return $remote_header_data ;
}
public function get_remote_posts($settings)
{
if (empty($settings['sources'])) {
return array();
}
return $this->api_request($settings['sources']);
}
public function get_remote_header_data_old($settings)
{
if (empty($settings['sources'])) {
return array();
}
$needed = array($settings['sources'][0]);
return $this->api_request($needed, 'sources');
}
public function get_remote_header_data($settings)
{
if (empty($settings['sources'])) {
return array();
}
$needed = $settings['sources'];
return $this->api_request($needed, 'sources');
}
public function cache_single_posts_from_set($posts, $provider_id)
{
foreach ($posts as $single_review) {
$single_post_cache = new SinglePostCache($single_review);
$single_post_cache->set_provider_id($provider_id);
$single_post_cache->set_lang($this->get_db_lang($provider_id));
if (Util::sbr_is_pro() && method_exists($single_post_cache, 'check_api_media')) {
$single_post_cache->check_api_media();
}
if (! $single_post_cache->db_record_exists()) {
$single_post_cache->resize_avatar(150);
if (in_array($this->provider_for_provider_id($provider_id), $this->providers_no_media, true)) {
$single_post_cache->set_storage_data('images_done', 1);
}
$single_post_cache->store();
} else {
$single_post_cache->update_single();
}
}
}
public function api_request($requests_needed, $type = 'reviews')
{
$data = array();
foreach ($requests_needed as $request) {
// Handle collections separately
if ($request['provider'] === 'collection') {
if ($type === 'sources') {
$collection = SBR_Sources::update_collection_ratings($request['account_id']);
$info = isset($collection['info']) ? json_decode($collection['info'], true) : [];
$data[] = [
'info' => $info
];
}
continue;
}
// Apply Trustpilot-specific settings
if ($type === 'reviews' && $request['provider'] === 'trustpilot') {
$request['language'] = !empty($this->settings['trustpilotLanguage'])
? $this->settings['trustpilotLanguage']
: 'default';
$request['starsFilter'] = !empty($this->settings['includedStarFilters'])
? implode(',', $this->settings['includedStarFilters'])
: '';
}
// Skip if API limit reached for this provider
if (SBR_Feed_Saver_Manager::check_api_limit($request['provider'])) {
continue;
}
// Skip if provider call limit reached
if (SBR_Feed_Saver_Manager::limit_provider_api_calls($request['provider'], $request['account_id'])) {
continue;
}
// Apply language settings if applicable
if (in_array($request['provider'], $this->providers_languages)) {
$request['language'] = Util::get_api_call_language($this->settings);
}
// Fetch data from the appropriate provider
$new_data = null;
if ($request['provider'] === 'facebook') {
// Check if Pro version is active (Facebook provider is Pro-only)
if (!Util::sbr_is_pro() || !class_exists('\SmashBalloon\Reviews\Pro\Integrations\Providers\Facebook')) {
$new_data = [
'data' => [
'error' => __('Facebook sources require Reviews Feed Pro.', 'reviews-feed')
],
'message' => __('Please upgrade to Reviews Feed Pro to display Facebook reviews.', 'reviews-feed')
];
} else {
$new_data = \SmashBalloon\Reviews\Pro\Integrations\Providers\Facebook::get_facebook_info($type, $request);
}
} elseif ($request['provider'] === 'woocommerce') {
// Check if Pro version is active (WooCommerce provider is Pro-only)
if (!Util::sbr_is_pro() || !class_exists('\SmashBalloon\Reviews\Pro\Integrations\Providers\WooCommerce')) {
$new_data = [
'data' => [
'error' => __('WooCommerce sources require Reviews Feed Pro.', 'reviews-feed')
],
'message' => __('Please upgrade to Reviews Feed Pro to display WooCommerce reviews.', 'reviews-feed')
];
} elseif (!function_exists('wc_get_product')) {
// Check if WooCommerce plugin is active
$new_data = [
'data' => [
'error' => __('WooCommerce plugin is not active.', 'reviews-feed')
],
'message' => __('Please activate WooCommerce to display reviews from this source.', 'reviews-feed')
];
} else {
// WooCommerce is a local provider, fetch reviews directly from database
$woocommerce = new \SmashBalloon\Reviews\Pro\Integrations\Providers\WooCommerce();
$is_multi_product = strpos($request['account_id'], 'wc_multi_') === 0;
if ($type === 'reviews') {
if ($is_multi_product) {
// Multi-product source: extract product IDs from info
$product_ids = [];
if (!empty($request['info']['products']) && is_array($request['info']['products'])) {
foreach ($request['info']['products'] as $product_info) {
if (!empty($product_info['id'])) {
$product_ids[] = absint($product_info['id']);
}
}
}
if (!empty($product_ids)) {
$reviews = $woocommerce->fetch_reviews_multi($product_ids);
$normalized_reviews = $woocommerce->normalize_reviews_multi($reviews);
$new_data = [
'data' => [
'reviews' => $normalized_reviews
]
];
} else {
$new_data = [
'data' => [
'error' => __('No valid products found in WooCommerce multi-product source.', 'reviews-feed')
],
'message' => __('The WooCommerce source has no valid products configured.', 'reviews-feed')
];
}
} else {
// Single product source
$product = wc_get_product($request['account_id']);
if ($product) {
$reviews = $woocommerce->fetch_reviews($request['account_id']);
$normalized_reviews = $woocommerce->normalize_reviews($reviews, $product);
$new_data = [
'data' => [
'reviews' => $normalized_reviews
]
];
} else {
// Product not found or deleted
$new_data = [
'data' => [
'error' => __('WooCommerce product not found or has been deleted.', 'reviews-feed')
],
'message' => sprintf(
/* translators: %s: product ID */
__('The WooCommerce product (ID: %s) no longer exists. Please update or remove this source.', 'reviews-feed'),
esc_html($request['account_id'])
)
];
}
}
} elseif ($type === 'sources') {
if ($is_multi_product) {
// Multi-product source: aggregate info from all products
$product_ids = [];
if (!empty($request['info']['products']) && is_array($request['info']['products'])) {
foreach ($request['info']['products'] as $product_info) {
if (!empty($product_info['id'])) {
$product_ids[] = absint($product_info['id']);
}
}
}
if (!empty($product_ids)) {
$new_data = [
'data' => [
'info' => $woocommerce->get_multi_source_info($product_ids, $request['account_id'], $request['info'])
]
];
}
} else {
// Single product source
$product = wc_get_product($request['account_id']);
if ($product) {
$new_data = [
'data' => [
'info' => $woocommerce->get_source_info($product)
]
];
}
}
}
}
} else {
$remote_request = new RemoteRequest($request['provider'], $request, $type);
$new_data = $remote_request->fetch();
}
// Skip if no data was returned
if (!isset($new_data['data'])) {
continue;
}
// Handle errors
if (! empty($new_data['data']['error'])) {
$message = ! empty(( $new_data['message'] )) ? wp_strip_all_tags($new_data['message']) : 'An error has occurred when fetching new reviews';
if (is_array($new_data['data']['error'])) {
$message .= '<br>';
foreach ($new_data['data']['error'] as $key => $value) {
$message .= '<br>' . $key . ': ' . wp_strip_all_tags($value);
}
}
$message .= '<br><br>';
$message .= sprintf(__('This is affecting the source %s for %s. New reviews will not be fetched until this is resolved.', 'reviews-feed'), wp_strip_all_tags($request['name']), wp_strip_all_tags($request['provider']));
$message .= '<br><br>';
$this->add_error($message, sprintf(__('Troubleshoot by visiting %serror message reference page%s.', 'reviews-feed'), '<a href="https://smashballoon.com/doc/reviews-feed-error-message-reference/?reviews&utm_campaign=reviews-pro&utm_source=feed&utm_medium=apierror&utm_content=Error%20Message%20Reference" target="_blank" rel="noopener noreferrer">', '</a>'));
}
$new_data = $this->add_source_to_post_set($request, $new_data);
$to_push = $type === 'reviews' ? [
'provider_id' => $request['account_id'],
'data' => $new_data['data']
] : $new_data['data'];
array_push($data, $to_push);
}
return $data;
}
public function add_source_to_post_set($source, $post_set)
{
if (! isset($post_set['data']['reviews'][0])) {
return $post_set;
}
foreach ($post_set['data']['reviews'] as $index => $review) {
$post_set['data']['reviews'][ $index ]['source'] = array(
'id' => $source['info']['id'] ?? $source['account_id'] ?? '',
'url' => $source['info']['url'] ?? '',
);
}
return $post_set;
}
public function get_post_set_page($page = 1)
{
if ($this->is_single_manual_review()) {
return [
$this->hydrate_single_manual_review($this->settings['singleManualReviewContent'])
];
}
$posts = $this->get_posts();
$max = $this->settings['numPostDesktop'];
if ($this->settings['numPostTablet'] > $this->settings['numPostDesktop']) {
$max = $this->settings['numPostTablet'];
}
if ($this->settings['numPostMobile'] > $this->settings['numPostTablet']) {
$max = $this->settings['numPostMobile'];
}
$offset = ($page - 1) * $max;
return is_array($posts) ? array_slice($posts, $offset, $max) : [];
}
public function is_last_page($page)
{
$posts = $this->get_posts();
$posts_counts = count($posts);
$posts_per_page = $this->settings['numPostDesktop'];
if ($this->settings['numPostTablet'] > $this->settings['numPostDesktop']) {
$posts_per_page = $this->settings['numPostTablet'];
}
if ($this->settings['numPostMobile'] > $this->settings['numPostTablet']) {
$posts_per_page = $this->settings['numPostMobile'];
}
$posts_per_page = (int) $posts_per_page;
return $posts_counts <= ($page * $posts_per_page);
}
public function hydrate_sources()
{
if (!is_array($this->settings['sources'])) {
$this->settings['sources'] = explode(',', $this->settings['sources']);
}
$db_sources = SBR_Sources::get_sources_list([
'id' => $this->settings['sources']
]);
$hydrated_sources = array();
foreach ($this->settings['sources'] as $single_source) {
foreach ($db_sources as $db_source) {
if (
!is_array($single_source)
&& !empty($db_source['account_id'])
&& (string) $db_source['account_id'] === $single_source
) {
$final_source = $db_source;
$final_source['business'] = $db_source['account_id'];
if (!empty($final_source['info'])) {
$decoded = json_decode($final_source['info'], true);
// Handle malformed JSON by setting empty array to prevent null access errors
$final_source['info'] = is_array($decoded) ? $decoded : [];
} else {
// Ensure info is always an array even when empty/falsy
$final_source['info'] = [];
}
if ($final_source['provider'] === 'google') {
$final_source['lang'] = $this->settings['apiCallLanguage'];
}
$hydrated_sources[] = $final_source;
}
}
}
$this->settings['sources'] = $hydrated_sources;
}
protected function get_db_lang($provider_id)
{
$settings = $this->get_settings();
if ('google' === $this->provider_for_provider_id($provider_id)) {
return $settings['apiCallLanguage'];
}
return '';
}
protected function provider_for_provider_id($provider_id)
{
foreach ($this->settings['sources'] as $single_source) {
if ($provider_id === $single_source['account_id']) {
return $single_source['provider'];
}
}
return '';
}
public function filter_posts($posts, $settings, $moderatePosts = false)
{
$filtered_posts = [];
$is_star_filters = isset($settings['includedStarFilters']) && sizeof($settings['includedStarFilters']) > 0 ? true : false;
$is_includeword = isset($settings['includeWords']) && !empty($settings['includeWords']) ? true : false;
$is_excludeword = isset($settings['excludeWords']) && !empty($settings['excludeWords']) ? true : false;
$is_sortbydate = isset($settings['sortByDateEnabled']) && !empty($settings['sortByDateEnabled']) && $settings['sortByDateEnabled'] == true ? true : false;
$is_sortbyrating = isset($settings['sortByRatingEnabled']) && !empty($settings['sortByRatingEnabled']) && $settings['sortByRatingEnabled'] == true ? true : false;
$is_randomize = isset($settings['sortRandomEnabled']) && !empty($settings['sortRandomEnabled']) && $settings['sortRandomEnabled'] == true ? true : false;
$is_minchar = isset($settings['filterCharCountMin']) && !empty($settings['filterCharCountMin']) ? true : false;
$is_maxchar = isset($settings['filterCharCountMax']) && !empty($settings['filterCharCountMax']) ? true : false;
$sort_by_date = $settings['sortByDate'];
$sort_by_rating = $settings['sortByRating'];
$includewords = $is_includeword ? explode(',', $settings['includeWords']) : [];
$excludewords = $is_excludeword ? explode(',', $settings['excludeWords']) : [];
foreach ($posts as $post) {
if (!is_null($post)) {
$keep_post = false;
//Work Around for facebook Positive / Negative Reviews
if (!empty($post['provider']['name']) && $post['provider']['name'] === 'facebook') {
if (in_array($post['rating'], [ 'positive', 'negative' ])) {
$post['rating'] = $post['rating'] === 'positive' ? 5 : 1;
}
}
$passes_star_filter = !$is_star_filters || ($is_star_filters && (isset($post['rating']) && in_array($post['rating'], $settings['includedStarFilters']))) ? true : false;
$has_includeword = false;
$has_excludeword = false;
$passes_word_filter = false;
$passes_moderation = true;
if ($is_includeword && !empty($includewords)) {
foreach ($includewords as $includeword) {
if (strpos(strtolower($post['text']), strtolower($includeword)) !== false) {
$has_includeword = true;
}
}
}
if ($is_excludeword && !empty($excludewords)) {
foreach ($excludewords as $excludeword) {
if (strpos(strtolower($post['text']), strtolower($excludeword)) !== false) {
$has_excludeword = true;
}
}
}
if (!empty($excludewords) && !empty($includewords)) {
$passes_word_filter = $has_includeword && !$has_excludeword;
} elseif (!empty($includewords)) {
$passes_word_filter = $has_includeword;
} else {
$passes_word_filter = !$has_excludeword;
}
if ($moderatePosts === true && isset($settings['moderationEnabled']) && $settings['moderationEnabled'] === true) {
$moderation_ids = isset($settings['moderationType']) && $settings['moderationType'] === 'allow' ? $settings['moderationAllowList'] : $settings['moderationBlockList'];
if ($settings['moderationType'] === 'allow') {
$passes_moderation = in_array($post['review_id'], $moderation_ids);
}
if ($settings['moderationType'] === 'block') {
$passes_moderation = !in_array($post['review_id'], $moderation_ids);
}
}
//Max Length and Min Length checking
$text_length = strlen($post['text']);
$passes_minchar_filter = ( !$is_minchar || ( $is_minchar && $text_length >= intval($settings['filterCharCountMin']) ) ) ? true : false;
$passes_maxchar_filter = ( !$is_maxchar || ( $is_maxchar && $text_length <= intval($settings['filterCharCountMax']) ) ) ? true : false;
if ($passes_star_filter === true && $passes_word_filter && $passes_moderation && $passes_minchar_filter && $passes_maxchar_filter) {
$keep_post = true;
}
// $keep_post = apply_filters( 'sbr_passes_filter', $keep_post, $post, $settings );
if ($keep_post) {
$filtered_posts[] = $post;
}
}
}
if (!$is_randomize) {
if ($is_sortbydate && !$is_sortbyrating) {
$filtered_posts = $this->sort_array_bydate($filtered_posts, $sort_by_date);
}
if ($is_sortbyrating && !$is_sortbydate) {
$filtered_posts = $this->sort_array_byrating($filtered_posts, $sort_by_rating);
}
if ($is_sortbyrating && $is_sortbydate) {
$filtered_posts = $this->sort_array_byrating_and_date($filtered_posts, $sort_by_rating, $sort_by_date);
}
}
return $filtered_posts;
}
public function sort_array_bydate($posts, $type = 'latest')
{
usort($posts, function ($a, $b) use ($type) {
return $type == 'latest' ? $b['time'] <=> $a['time'] : $a['time'] <=> $b['time'];
});
return $posts;
}
public function sort_array_byrating($posts, $type = 'lowest')
{
usort($posts, function ($a, $b) use ($type) {
return $type == 'highest' ? $b['rating'] <=> $a['rating'] : $a['rating'] <=> $b['rating'];
});
return $posts;
}
public function sort_array_byrating_and_date($posts, $rating_type = 'lowest', $date_type = 'latest')
{
usort($posts, function ($a, $b) use ($rating_type, $date_type) {
if ($a['rating'] === $b['rating']) {
return $date_type == 'latest' ? $b['time'] <=> $a['time'] : $a['time'] <=> $b['time'];
}
return $rating_type == 'highest' ? $b['rating'] <=> $a['rating'] : $a['rating'] <=> $b['rating'];
});
return $posts;
}
public function get_posts_for_moderation()
{
$settings = $this->get_settings();
$aggregator = new PostAggregator();
// Pass limit from settings (default 150 for backward compatibility)
$limit = isset($settings['numPostDesktop']) ? max(150, (int) $settings['numPostDesktop']) : 150;
$posts = $aggregator->db_post_set($settings['sources'], null, $limit);
$posts = $aggregator->normalize_db_post_set($posts);
$post_set = $this->filter_posts($posts, $settings);
return $post_set;
}
public function hydrate_single_manual_review($review)
{
return [
'review_id' => uniqid(),
'text' => $review['content'],
'rating' => $review['rating'],
'time' => $review['time'],
'reviewer' => [
'name' => $review['name'],
'avatar' => $review['avatar']
],
'provider' => [
'name' => $review['provider']
]
];
}
public function is_init_wpml()
{
return false;
}
}