['id' => true, 'class' => true, 'style' => true], 'pre' => ['id' => true, 'style' => true, 'class' => true], 'div' => [ 'id' => true, 'class' => true, 'style' => true, 'aria-label' => true, 'role' => true, 'tabindex' => true, 'data-template-id' => true, 'data-css-url' => true, 'data-no-translation' => true, 'data-time-locale' => true, 'data-layout-id' => true, 'data-layout-category' => true, 'data-set-id' => true, 'data-pid' => true, 'data-language' => true, 'data-close-locale' => true, 'data-review-target-width' => true, 'data-css-version' => true, 'data-review-text' => true, 'data-reply-by-locale' => true, 'data-pager-autoplay-timeout' => true, 'data-empty' => true, 'data-time' => true, 'data-id' => true, 'data-container' => true, 'data-collapse-text' => true, 'data-open-text' => true, 'data-is-valid' => true, 'data-domain' => true, 'data-auto-dark-mode' => true, 'data-rotate-to' => true, 'data-slider-loop' => true, 'data-size' => true, 'data-load-more-rows' => true, 'data-column-vertical-separate' => true, 'data-hide-count' => true, 'data-fomo-day' => true, 'data-style' => true, 'data-src' => true, 'data-type' => true, 'data-plugin-version' => true, 'data-only-rating-locale' => true, ], 'a' => [ 'class' => true, 'style' => true, 'href' => true, 'role' => true, 'target' => true, 'rel' => true, 'aria-label' => true, 'data-subcontent' => true, 'data-subcontent-target' => true, ], 'img' => ['class' => true, 'style' => true, 'src' => true, 'srcset' => true, 'alt' => true, 'width' => true, 'height' => true, 'loading' => true], 'trustindex-image' => ['data-imgurl' => true, 'class' => true, 'style' => true, 'src' => true, 'srcset' => true, 'alt' => true, 'width' => true, 'height' => true, 'loading' => true], 'span' => [ 'class' => true, 'style' => true, 'data-id' => true, 'data-empty' => true, 'data-time' => true, 'data-container' => true, 'data-collapse-text' => true, 'data-open-text' => true, ], 'p' => ['class' => true, 'style' => true], 'font' => ['class' => true, 'style' => true], 'strong' => ['class' => true, 'style' => true], 'br' => [], 'i' => ['class' => true, 'style' => true], 'style' => ['type' => true], 'script' => ['type' => true, 'src' => true], ]; public function __construct($shortname, $pluginFilePath, $version, $pluginName, $platformName) { $this->shortname = $shortname; $this->plugin_file_path = $pluginFilePath; $this->version = $version; $this->plugin_name = $pluginName; $this->platform_name = $platformName; } public function getPluginTabs() { $tabs = []; $tabs[] = [ 'place' => 'left', 'slug' => 'free-widget-configurator', 'name' => __('Free Widget Configurator', 'wp-reviews-plugin-for-google') ]; if ($this->is_noreg_linked()) { $tabs[] = [ 'place' => 'left', 'slug' => 'my-reviews', 'name' => __('My reviews', 'wp-reviews-plugin-for-google') ]; } $tabs[] = [ 'place' => 'left', 'slug' => 'get-reviews', 'name' => __('Get Reviews', 'wp-reviews-plugin-for-google') ]; $tabs[] = [ 'place' => 'left', 'slug' => 'rate-us', 'name' => __('Rate Us', 'wp-reviews-plugin-for-google') ]; if (!$this->is_trustindex_connected()) { $tabs[] = [ 'place' => 'left', 'slug' => 'get-more-features', 'name' => __('Get more Features', 'wp-reviews-plugin-for-google') ]; } $tabs[] = [ 'place' => 'right', 'slug' => 'instagram-feed-widget', 'name' => 'Instagram Feed Widget', ]; $tabs[] = [ 'place' => 'right', 'slug' => 'advanced', 'name' => __('Advanced', 'wp-reviews-plugin-for-google') ]; return $tabs; } public function getShortName() { return $this->shortname; } public function getWebhookAction() { return 'trustindex_reviews_hook_' . $this->getShortName(); } public function getWebhookUrl() { return admin_url('admin-ajax.php') . '?action='. $this->getWebhookAction(); } public function getProFeatureButton($campaignId) { return ''. __('Create a Free Account for More Features', 'wp-reviews-plugin-for-google') .''; } public function is_review_download_in_progress() { return get_option($this->get_option_name('review-download-inprogress'), 0); } public function is_review_manual_download() { return get_option($this->get_option_name('review-manual-download'), 0); } public function delete_async_request() { $requestId = get_option($this->get_option_name('review-download-request-id')); if (!$requestId) { return false; } wp_remote_post('https://admin.trustindex.io/source/wordpressPageRequest', [ 'body' => [ 'is_delete' => 1, 'id' => $requestId ], 'timeout' => 300, 'redirection' => '5', 'blocking' => true ]); return true; } public function save_details($tmp) { $name = isset($tmp['name']) ? sanitize_text_field(wp_unslash($tmp['name'])) : ""; $name = json_encode($name); $details = [ 'id' => isset($tmp['page_id']) ? $tmp['page_id'] : $tmp['id'], 'name' => $name, 'address' => isset($tmp['address']) ? sanitize_text_field(wp_unslash($tmp['address'])) : "", 'avatar_url' => isset($tmp['avatar_url']) ? sanitize_text_field(wp_unslash($tmp['avatar_url'])) : "", 'rating_number' => isset($tmp['reviews']['count']) ? (int)$tmp['reviews']['count'] : 0, 'rating_score' => isset($tmp['reviews']['score']) ? (float)$tmp['reviews']['score'] : 0, ]; if (isset($tmp['access_token'])) { $details['access_token'] = sanitize_text_field(wp_unslash($tmp['access_token'])); } update_option($this->get_option_name('page-details'), $details, false); } public function save_reviews($tmp) { global $wpdb; $tableName = $this->get_tablename('reviews'); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $oldReviews = $wpdb->get_results($wpdb->prepare('SELECT reviewId, hidden, highlight FROM %i ORDER BY date DESC', $tableName), ARRAY_A); $oldReviews = array_combine(array_column($oldReviews, 'reviewId'), $oldReviews); $wpdb->query($wpdb->prepare('TRUNCATE %i', $tableName)); if ($wpdb->last_error) { throw new Exception('DB truncate failed: '. esc_html($wpdb->last_error)); } foreach ($tmp as $i => $review) { foreach ($review as $key => $value) { if (is_array($value)) { if ($key === 'reviewer') { $review[ $key ] = array_map(function($v) { return $v ? sanitize_text_field(wp_unslash($v)) : $v; }, $value); } else { unset($review[ $key ]); } } else if ($key === 'text') { $review[ $key ] = $value ? wp_kses_post(wp_unslash($value)) : $value; } else { $review[ $key ] = $value ? sanitize_text_field(wp_unslash($value)) : $value; } } $hidden = 0; $highlight = null; if (isset($review['id']) && isset($oldReviews[$review['id']])) { $hidden = $oldReviews[$review['id']]['hidden']; $highlight = $oldReviews[$review['id']]['highlight']; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $wpdb->insert($tableName, [ 'user' => $review['reviewer']['name'], 'user_photo' => $review['reviewer']['avatar_url'], 'text' => $review['text'], 'rating' => $review['rating'] ? $review['rating'] : 5, 'date' => substr($review['created_at'], 0, 10), 'reviewId' => isset($review['id']) ? $review['id'] : null, 'reply' => isset($review['reply']) ? $review['reply'] : "", 'hidden' => $hidden, 'highlight' => $highlight ? $highlight : null, ]); if ($wpdb->last_error) { throw new Exception('DB insert failed: '. esc_html($wpdb->last_error)); } } update_option($this->get_option_name('review-download-modal'), 0, false); } public function get_plugin_dir() { return plugin_dir_path($this->plugin_file_path); } public function get_plugin_file_url($file, $addVersioning = true) { $url = plugins_url($file, $this->plugin_file_path); if ($addVersioning) { $appendMark = strpos($url, '?') === FALSE ? '?' : '&'; $url .= $appendMark . 'ver=' . $this->getVersion(); } return $url; } public function get_plugin_slug() { return basename($this->get_plugin_dir()); } public function uninstall() { $this->delete_async_request(); include $this->get_plugin_dir() . 'include' . DIRECTORY_SEPARATOR . 'uninstall.php'; if (is_file($this->getCssFile())) { wp_delete_file($this->getCssFile()); } } public function activate() { include $this->get_plugin_dir() . 'include' . DIRECTORY_SEPARATOR . 'activate.php'; $this->setNotificationParam('not-using-no-connection', 'timestamp', time() + 86400); if (!$this->getNotificationParam('rate-us', 'hidden', false) && $this->getNotificationParam('rate-us', 'active', true)) { $this->setNotificationParam('rate-us', 'active', true); $this->setNotificationParam('rate-us', 'timestamp', time() + 86400); } update_option($this->get_option_name('activation-redirect'), 1, false); } public function deactivate() { update_option($this->get_option_name('active'), '0'); } public function load() { global $wpdb; $this->loadI18N(); include $this->get_plugin_dir() . 'include' . DIRECTORY_SEPARATOR . 'update.php'; if (get_option($this->get_option_name('activation-redirect'))) { delete_option($this->get_option_name('activation-redirect')); wp_safe_redirect(admin_url('admin.php?page=' . $this->get_plugin_slug() . '/settings.php')); exit; } if ( $this->is_noreg_linked() && !$this->is_review_download_in_progress() && get_option($this->get_option_name('download-timestamp'), time()) < time() && !$this->getNotificationParam('review-download-available', 'hidden') && $this->getNotificationParam('review-download-available', 'do-check', true) ) { $this->setNotificationParam('review-download-available', 'active', true); $this->setNotificationParam('review-download-available', 'do-check', false); } if ( !$this->is_noreg_linked() && !$this->getNotificationParam('not-using-no-connection', 'active', false) && $this->getNotificationParam('not-using-no-connection', 'do-check', true) ) { $this->setNotificationParam('not-using-no-connection', 'active', true); $this->setNotificationParam('not-using-no-connection', 'do-check', false); } if ( !class_exists('TrustindexGutenbergPlugin') && function_exists( 'register_block_type' ) && !WP_Block_Type_Registry::get_instance()->is_registered( 'trustindex/block-selector' )) { require_once $this->get_plugin_dir() . 'static' . DIRECTORY_SEPARATOR . 'block-editor' . DIRECTORY_SEPARATOR . 'block-editor.php'; TrustindexGutenbergPlugin::instance(); } } public function loadI18N() { load_textdomain( $this->get_plugin_slug(), $this->get_plugin_dir() . 'languages/'.$this->get_plugin_slug().'-' . get_locale() . '.mo' ); } public function is_enabled() { return get_option($this->get_option_name('active'), 0); } public function add_setting_menu() { global $menu, $submenu; $settingsPageUrl = $this->get_plugin_slug() . "/settings.php"; $settingsPageTitle = $this->platform_name . ' '; if (function_exists('mb_strtolower')) { $settingsPageTitle .= mb_strtolower(__('Reviews', 'wp-reviews-plugin-for-google')); } else { $settingsPageTitle .= strtolower(__('Reviews', 'wp-reviews-plugin-for-google')); } $topMenu = false; foreach ($menu as $key => $item) { if ($item[0] === 'Trustindex.io') { $topMenu = $item; break; } } if ($topMenu === false) { add_menu_page( $settingsPageTitle, 'Trustindex.io', self::$permissionNeeded, $settingsPageUrl, '', $this->get_plugin_file_url('static/img/trustindex-sign-logo.png') ); } else { if (!isset($submenu[ $topMenu[2] ])) { add_submenu_page( $topMenu[2], 'Trustindex.io', $topMenu[3], self::$permissionNeeded, $topMenu[2] ); } add_submenu_page( $topMenu[2], 'Trustindex.io', $settingsPageTitle, self::$permissionNeeded, $settingsPageUrl ); } } public function add_plugin_action_links($links, $file) { if (!is_array($links)) { $links = []; } if (basename($file) === basename($this->plugin_file_path)) { $platformLink = 'get_option_name('widget-setted-up'), 0)) { $platformLink .= 'href="' . admin_url('admin.php?page=' . $this->get_plugin_slug() . '/settings.php&tab=my-reviews') . '">'. __('Review Management', 'wp-reviews-plugin-for-google'); } else { $platformLink .= 'href="' . admin_url('admin.php?page=' . $this->get_plugin_slug() . '/settings.php') . '">'; if (!$this->is_noreg_linked()) { /* translators: %s: Platform name */ $platformLink .= sprintf(__('Connect %s', 'wp-reviews-plugin-for-google'), $this->platform_name); } else { $platformLink .= __('Create Widget', 'wp-reviews-plugin-for-google'); } } $platformLink .= ''; $settingsLink = '' . __('Settings', 'wp-reviews-plugin-for-google') . ''; array_unshift($links, $platformLink, $settingsLink); } return $links; } public function add_plugin_meta_links($meta, $file) { if (basename($file) === basename($this->plugin_file_path)) { $meta[] = ''. __('Get more Features', 'wp-reviews-plugin-for-google') . ' →'; $meta[] = ''. __('Rate our plugin', 'wp-reviews-plugin-for-google') . ' ★★★★★'; } return $meta; } public function init_widget() { if (!class_exists('TrustindexWidget_'.$this->getShortName())) { require $this->get_plugin_dir() . 'trustindex-'. $this->getShortName() .'-widget.class.php'; } } public function register_widget() { return register_widget('TrustindexWidget_'.$this->getShortName()); } public function get_option_name($opt_name) { if (!in_array($opt_name, $this->get_option_names())) { echo esc_html('Option not registered in plugin (Trustindex class)'); } if (in_array($opt_name, [ 'subscription-id', 'proxy-check' ])) { return 'trustindex-'. $opt_name; } else { return 'trustindex-'. $this->getShortName() .'-'. $opt_name; } } public function get_option_names() { return [ 'active', 'page-details', 'subscription-id', 'proxy-check', 'style-id', 'review-content', 'filter', 'scss-set', 'css-content', 'lang', 'no-rating-text', 'dateformat', 'nameformat', 'rate-us-feedback', 'verified-icon', 'enable-animation', 'show-arrows', 'show-reviewers-photo', 'download-timestamp', 'widget-setted-up', 'disable-font', 'show-logos', 'show-stars', 'load-css-inline', 'align', 'review-text-mode', 'amp-hidden-notification', 'review-download-token', 'review-download-inprogress', 'review-download-request-id', 'review-download-modal', 'review-download-is-connecting', 'review-download-is-failed', 'review-manual-download', 'reply-generated', 'instagram-promo-opened', 'footer-filter-text', 'show-header-button', 'reviews-load-more', 'activation-redirect', 'notifications', 'top-rated-type', 'top-rated-date', 'show-review-replies', 'verified-by-trustindex', 'fomo-open', 'fomo-link', 'fomo-border', 'fomo-arrow', 'fomo-icon', 'fomo-color', 'fomo-margin', 'fomo-title', 'fomo-text', 'fomo-url', 'fomo-icon-background', 'fomo-day', 'fomo-hide-count', 'cdn-version-control', 'version-control', 'preview', ]; } private $widgetOptions = []; private $widgetOptionDefaultOverride = []; public function getWidgetOption($name, $forceDatabaseValue = false, $returnDefault = false) { if (isset($this->widgetOptions[$name]) && !$forceDatabaseValue && !$returnDefault) { return $this->widgetOptions[$name]; } if ($returnDefault && isset($this->widgetOptionDefaultOverride[$name])) { return $this->widgetOptionDefaultOverride[$name]; } global $wpdb; if (!in_array($name, ['style-id', 'scss-set'])) { $styleId = $this->getWidgetOption('style-id'); $scssSet = $this->getWidgetOption('scss-set'); } $default = null; if (!$forceDatabaseValue) { switch ($name) { case 'style-id': $default = 4; break; case 'scss-set': $default = 'light-background'; break; case 'lang': $default = 'en'; break; case 'dateformat': $default = 'modern'; break; case 'nameformat': $default = 1; break; case 'filter': global $wpdb; $onlyRatingsDefault = false; if ($this->is_noreg_linked()) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $onlyRatingsDefault = (float)$wpdb->get_var($wpdb->prepare('SELECT COUNT(`id`) FROM %i WHERE `text` != ""', $this->get_tablename('reviews'))) >= 3; } $default = [ 'stars' => [1, 2, 3, 4, 5], 'only-ratings' => $onlyRatingsDefault ]; break; case 'no-rating-text': $default = !in_array($styleId, [6, 8, 37]) ? 1 : 0; break; case 'verified-icon': case 'enable-animation': case 'show-arrows': case 'show-header-button': case 'reviews-load-more': case 'fomo-open': case 'fomo-border': case 'fomo-arrow': $default = 1; break; case 'widget-setted-up': case 'disable-font': case 'footer-filter-text': case 'floating-mobile-open': case 'show-review-replies': case 'fomo-link': case 'fomo-margin': $default = 0; break; case 'align': $default = in_array($styleId, [ 36, 37, 38, 39 ]) ? 'center' : ($this->isRtlLanguage() ? 'right' : 'left'); break; case 'review-text-mode': $default = 'readmore'; break; case 'show-logos': $default = isset(self::$widget_styles[$scssSet]) && self::$widget_styles[$scssSet]['hide-logos'] ? 0 : 1; break; case 'show-stars': $default = isset(self::$widget_styles[$scssSet]) && self::$widget_styles[$scssSet]['hide-stars'] ? 0 : 1; break; case 'show-reviewers-photo': $default = isset(self::$widget_styles[$scssSet]) && self::$widget_styles[$scssSet]['reviewer-photo'] ? 1 : 0; break; case 'top-rated-type': $default = 'Service'; break; case 'top-rated-date': $default = in_array($styleId, [98, 100, 102, 104]) ? 'hide' : ''; break; case 'verified-by-trustindex': $default = 0; break; case 'fomo-icon': $default = self::$widget_templates['templates'][$styleId]['params']['fomo-icon']; break; case 'fomo-color': $params = self::$widget_templates['templates'][$styleId]['params']; $default = isset($params['fomo-color']) ? $params['fomo-color'] : '#FF552B'; break; case 'fomo-icon-background': $default = 0; break; case 'fomo-title': $default = ""; $content = $this->getWidgetOption('review-content'); preg_match('/
(.+)<\/div>/U', $content, $matches); if (isset($matches[1]) && !$returnDefault) { $default = $matches[1]; } break; case 'fomo-text': $default = ""; $params = self::$widget_templates['templates'][$styleId]['params']; if (isset($params['fomo-subtitle-text-choices'])) { $default = $params['fomo-subtitle-text-choices'][0]; } else { $content = $this->getWidgetOption('review-content'); preg_match('/
(.+)<\/div>/U', $content, $matches); if (isset($matches[1]) && !$returnDefault) { $default = $matches[1]; } } break; case 'fomo-url': $default = $this->getReviewPageUrl(); break; case 'fomo-day': $params = self::$widget_templates['templates'][$styleId]['params']; $default = 7; break; case 'fomo-hide-count': $params = self::$widget_templates['templates'][$styleId]['params']; $isOnlineVisitors = isset($params['fomo-title-text']) && strpos($params['fomo-title-text'], '%online-visitors%') !== false; $default = $isOnlineVisitors ? 5 : 20; break; } } if ($returnDefault) { return $default; } $this->widgetOptions[$name] = get_option($this->get_option_name($name), $default); if ('fomo-text' === $name || 'fomo-title' === $name) { $this->widgetOptions[$name] = html_entity_decode($this->widgetOptions[$name]); } return $this->widgetOptions[$name]; } public function getNotificationOptions($type = "") { $platformName = $this->get_platform_name($this->getShortName()); $defaultRedirect = '?page='. $this->get_plugin_slug() .'/settings.php&tab=free-widget-configurator'; $list = [ 'rate-us' => [ 'type' => 'warning', 'extra-class' => 'trustindex-popup', 'button-text' => "", 'is-closeable' => true, 'hide-on-close' => false, 'hide-on-open' => true, 'redirect' => 'https://wordpress.org/support/plugin/'. $this->get_plugin_slug() .'/reviews/?rate=5#new-post', 'text' => /* translators: %s: Name of the plugin */ sprintf(__('We have worked a lot on the free "%s" plugin.', 'wp-reviews-plugin-for-google'), $this->plugin_name) . '
' . __('If you love our features, please write a review to help us make the plugin even better.', 'wp-reviews-plugin-for-google') . '
' . /* translators: %s: Trustindex CEO */ sprintf(__('Thank you. Gabor, %s', 'wp-reviews-plugin-for-google'), 'Trustindex CEO'), ], 'not-using-no-connection' => [ 'type' => 'warning', 'extra-class' => "", /* translators: %s: Platform name */ 'button-text' => sprintf(__('Create a free %s widget! »', 'wp-reviews-plugin-for-google'), $platformName), 'is-closeable' => true, 'hide-on-close' => true, 'hide-on-open' => true, 'remind-later-button' => false, 'redirect' => $defaultRedirect, /* translators: %s: Platform name */ 'text' => sprintf(__('Display %s reviews on your website.', 'wp-reviews-plugin-for-google'), $platformName), ], 'not-using-no-widget' => [ 'type' => 'warning', 'extra-class' => "", /* translators: %s: Platform name */ 'button-text' => sprintf(__('Embed the %s reviews widget! »', 'wp-reviews-plugin-for-google'), $platformName), 'is-closeable' => true, 'hide-on-close' => true, 'hide-on-open' => true, 'remind-later-button' => true, 'redirect' => $defaultRedirect, /* translators: %s: Platform name */ 'text' => sprintf(__('Build trust and display your %s reviews on your website.', 'wp-reviews-plugin-for-google'), $platformName), ], 'review-download-available' => [ 'type' => 'warning', 'extra-class' => "", 'button-text' => __('Download your latest reviews! »', 'wp-reviews-plugin-for-google'), 'is-closeable' => true, 'hide-on-close' => true, 'hide-on-open' => true, 'remind-later-button' => false, 'redirect' => '?page='. $this->get_plugin_slug() .'/settings.php&tab=my-reviews', /* translators: %s: Platform name */ 'text' => sprintf(__('You can update your %s reviews.', 'wp-reviews-plugin-for-google'), $platformName), ], 'review-download-finished' => [ 'type' => 'warning', 'extra-class' => "", /* translators: %s: Service name (ChatGPT) */ 'button-text' => sprintf(__('Reply with %s! »', 'wp-reviews-plugin-for-google'), 'ChatGPT'), 'is-closeable' => true, 'hide-on-close' => true, 'hide-on-open' => true, 'remind-later-button' => false, 'redirect' => '?page='. $this->get_plugin_slug() .'/settings.php&tab=my-reviews', /* translators: %s: Platform name */ 'text' => sprintf(__('Your new %s reviews have been downloaded.', 'wp-reviews-plugin-for-google'), $platformName), ], ]; return $type ? $list[$type] : $list; } public function setNotificationParam($type, $param, $value) { $notifications = get_option($this->get_option_name('notifications'), []); if (!isset($notifications[ $type ])) { $notifications[ $type ] = []; } $notifications[ $type ][ $param ] = $value; update_option($this->get_option_name('notifications'), $notifications, false); } public function getNotificationParam($type, $param, $default = null) { $notifications = get_option($this->get_option_name('notifications'), []); if (!isset($notifications[ $type ]) || !isset($notifications[ $type ][ $param ])) { return $default; } return $notifications[ $type ][ $param ]; } public function isNotificationActive($type) { $notifications = get_option($this->get_option_name('notifications'), []); if ( !isset($notifications[ $type ]) || !isset($notifications[ $type ]['active']) || !$notifications[ $type ]['active'] || (isset($notifications[ $type ]['hidden']) && $notifications[ $type ]['hidden']) || (isset($notifications[ $type ]['timestamp']) && $notifications[ $type ]['timestamp'] > time()) ) { return false; } return true; } public function getNotificationEmailContent($type) { $platformName = $this->get_platform_name($this->getShortName()); $subject = ""; $message = ""; switch ($type) { case 'review-download-finished': $subject = $platformName . ' Reviews Downloaded'; $message = '

Great news.

Your new '. $platformName .' reviews have been downloaded.

Reply with ChatGPT! »
'; break; } return [ 'subject' => $subject, 'message' => $message ]; } public function sendNotificationEmail($type) { if ($email = $this->getNotificationParam($type, 'email', get_option('admin_email'))) { $msg = $this->getNotificationEmailContent($type); if ($msg['subject'] && $msg['message']) { try { wp_mail($email, $msg['subject'], $msg['message'], [ 'Content-Type: text/html; charset=UTF-8' ], [ '' ]); } catch(Exception $e) { } } } } public function get_platforms() { return array ( 0 => 'facebook', 1 => 'google', 2 => 'tripadvisor', 3 => 'yelp', 4 => 'booking', 5 => 'amazon', 6 => 'arukereso', 7 => 'airbnb', 8 => 'hotels', 9 => 'opentable', 10 => 'foursquare', 11 => 'capterra', 12 => 'szallashu', 13 => 'thumbtack', 14 => 'expedia', 15 => 'zillow', 16 => 'wordpressPlugin', 17 => 'aliexpress', 18 => 'alibaba', 19 => 'sourceForge', 20 => 'ebay', ); } private $plugin_slugs = array ( 'facebook' => 'free-facebook-reviews-and-recommendations-widgets', 'google' => 'wp-reviews-plugin-for-google', 'tripadvisor' => 'review-widgets-for-tripadvisor', 'yelp' => 'reviews-widgets-for-yelp', 'booking' => 'review-widgets-for-booking-com', 'amazon' => 'review-widgets-for-amazon', 'arukereso' => 'review-widgets-for-arukereso', 'airbnb' => 'review-widgets-for-airbnb', 'hotels' => 'review-widgets-for-hotels-com', 'opentable' => 'review-widgets-for-opentable', 'foursquare' => 'review-widgets-for-foursquare', 'capterra' => 'review-widgets-for-capterra', 'szallashu' => 'review-widgets-for-szallas-hu', 'thumbtack' => 'widgets-for-thumbtack-reviews', 'expedia' => 'widgets-for-expedia-reviews', 'zillow' => 'widgets-for-zillow-reviews', 'wordpressPlugin' => 'reviews-widgets', 'aliexpress' => 'widgets-for-aliexpress-reviews', 'alibaba' => 'widgets-for-alibaba-reviews', 'sourceForge' => 'widgets-for-sourceforge-reviews', 'ebay' => 'widgets-for-ebay-reviews', ); public function get_plugin_slugs() { return array_values($this->plugin_slugs); } public static function get_noticebox($type, $message) { return '

'. $message .'

'; } public static function get_alertbox($type, $content, $newline_content = true) { $types = [ 'warning' => [ 'css' => 'color: #856404; background-color: #fff3cd; border-color: #ffeeba;', 'icon' => 'dashicons-warning' ], 'info' => [ 'css' => 'color: #0c5460; background-color: #d1ecf1; border-color: #bee5eb;', 'icon' => 'dashicons-info' ], 'error' => [ 'css' => 'color: #721c24; background-color: #f8d7da; border-color: #f5c6cb;', 'icon' => 'dashicons-info' ] ]; return '
' . ' '. strtoupper($type) .'' . ($newline_content ? '
' : "") . $content . '
'; } public function get_shortcode_name() { return 'trustindex'; } public function init_shortcode() { $tag = $this->get_shortcode_name(); if (shortcode_exists($tag)) { $initedVersion = get_option('trustindex-core-shortcode-inited', '1.0'); if (!$initedVersion || version_compare($initedVersion, $this->getVersion())) { remove_shortcode($tag); } else { return false; } } update_option('trustindex-core-shortcode-inited', $this->getVersion(), false); add_shortcode($tag, [ $this, 'shortcode_func' ]); } public function shortcode_func($atts) { $atts = shortcode_atts([ 'data-widget-id' => null, 'no-registration' => null ], $atts); if (isset($atts['data-widget-id']) && $atts['data-widget-id']) { $content = $this->renderWidgetFrontend(esc_attr($atts['data-widget-id'])); if ($this->isElementorEditing()) { // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript $content .= ''; } return wp_kses($content, self::$allowedAttributesForWidget); } else if (isset($atts['no-registration']) && $atts['no-registration']) { $forcePlatform = esc_attr($atts['no-registration']); if (substr($forcePlatform, 0, 5) !== 'trust' && substr($forcePlatform, -4) !== 'ilot' && !in_array($forcePlatform, $this->get_platforms())) { $avPlatforms = $this->get_platforms(); $forcePlatform = $avPlatforms[0]; } $filePath = __FILE__; if (isset($this->plugin_slugs[ $forcePlatform ])) { $filePath = preg_replace('/[^\/\\\\]+([\\\\\/]trustindex-plugin\.class\.php)/', $this->plugin_slugs[ $forcePlatform ] . '$1', $filePath); } $className = 'TrustindexPlugin_' . $forcePlatform; if (!class_exists($className)) { return wp_kses_post($this->frontEndErrorForAdmins(ucfirst($forcePlatform) . ' plugin is not active or not found!')); } $chosedPlatform = new $className($forcePlatform, $filePath, "do-not-care-13.2.9", "do-not-care-Widgets for Google Reviews", "do-not-care-Google"); $chosedPlatform->setNotificationParam('not-using-no-widget', 'active', false); if (!$chosedPlatform->is_noreg_linked()) { /* translators: %s: Platform name */ return wp_kses_post($this->frontEndErrorForAdmins(sprintf(__('You have to connect your business (%s)!', 'wp-reviews-plugin-for-google'), $forcePlatform))); } else if (!$chosedPlatform->getWidgetOption('widget-setted-up')) { return wp_kses_post($this->frontEndErrorForAdmins('You have to complete your widget setup!')); } else { if ($this->isElementorEditing()) { $html = preg_replace('/]*>.*?<\/style>/is', '', $chosedPlatform->renderWidgetAdmin(true)); $html = wp_kses($html, $className::$allowedAttributesForWidget); $html .= ''; return $html; } else { $html = preg_replace('/]*>.*?<\/style>/is', '', $chosedPlatform->renderWidgetFrontend()); $html = wp_kses($html, $className::$allowedAttributesForWidget); if (!is_file($chosedPlatform->getCssFile()) || get_option($chosedPlatform->get_option_name('load-css-inline'), 0)) { $html .= ''; } return $html; } } } else { return wp_kses_post($this->frontEndErrorForAdmins(__('Your shortcode is deficient: Trustindex Widget ID is empty! Example: ', 'wp-reviews-plugin-for-google') . '
['.$this->get_shortcode_name().' data-widget-id="478dcc2136263f2b3a3726ff"]')); } } public function frontEndErrorForAdmins($text) { if (!current_user_can('manage_options')) { return " "; } return self::get_alertbox('error', ' @ '. __('Trustindex plugin', 'wp-reviews-plugin-for-google') .' ('. __('This message is not be visible to visitors in public mode.', 'wp-reviews-plugin-for-google') .')

'. $text, false); } public function is_noreg_linked() { $pageDetails = $this->getPageDetails(); return $pageDetails && !empty($pageDetails); } private $pageDetails = null; public function getPageDetails() { if ($this->pageDetails) { return $this->pageDetails; } $pageDetails = get_option($this->get_option_name('page-details')); if (isset($pageDetails['name']) && $this->isJson($pageDetails['name'])) { $pageDetails['name'] = json_decode($pageDetails['name']); } $this->pageDetails = $pageDetails; return $pageDetails; } public function noreg_save_css($setChange = false) { $defaultSet = 'light-background'; $styleId = (int)get_option($this->get_option_name('style-id'), 4); $setId = get_option($this->get_option_name('scss-set'), $defaultSet); $response = wp_remote_get('https://cdn.trustindex.io/assets/widget-presetted-css/v2/'.$styleId.'-'.$setId.'.css', [ 'timeout' => 30 ]); $cssContent = wp_remote_retrieve_body($response); $cssContent = str_replace('../../../assets', 'https://cdn.trustindex.io/assets', $cssContent); $cssContent = str_replace(".ti-widget[data-layout-id='$styleId'][data-set-id='$setId']", '.ti-widget.ti-'. substr($this->getShortName(), 0, 4), $cssContent); if (is_wp_error($response) || !$cssContent) { echo wp_kses_post($this->get_alertbox('error', "Trustindex's system is not available at the moment, please try again later.")); die; } if (!$setChange) { update_option($this->get_option_name('scss-set'), $defaultSet, false); } if (in_array($styleId, [17, 21, 52, 53, 112, 114])) { $cssContent .= '.ti-preview-box { position: unset !important }'; } update_option($this->get_option_name('css-content'), $cssContent, false); return $this->handleCssFile(); } public function getCssFile($returnOnlyFile = false) { $file = 'trustindex-'. $this->getShortName() .'-widget.css'; if ($returnOnlyFile) { return $file; } $uploadDir = wp_upload_dir(); return trailingslashit($uploadDir['basedir']) . $file; } private function getCssUrl() { $path = wp_upload_dir()['baseurl'] .'/'. $this->getCssFile(true); if (is_ssl()) { $path = str_replace('http://', 'https://', $path); } return $path; } public function handleCssFile() { $css = get_option($this->get_option_name('css-content')); if (!$css) { return; } if (get_option($this->get_option_name('load-css-inline'), 0)) { return; } $fileExists = is_file($this->getCssFile()); $success = false; $errorType = null; $errorMessage = ""; if ($fileExists && !is_readable($this->getCssFile())) { $errorType = 'permission'; } else { if ($fileExists && $css === file_get_contents($this->getCssFile())) { return; } require_once(ABSPATH . 'wp-admin' . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'file.php'); global $wp_filesystem; // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler set_error_handler(function ($err_severity, $err_msg, $err_file, $err_line, $err_context = []) { throw new ErrorException(esc_html($err_msg), 0, esc_html($err_severity), esc_html($err_file), esc_html($err_line)); }, E_WARNING); add_filter('filesystem_method', array($this, 'filter_filesystem_method')); WP_Filesystem(); try { $success = $wp_filesystem->put_contents($this->getCssFile(), $css, 0644); } catch (Exception $e) { if (strpos($e->getMessage(), 'Permission denied') !== FALSE) { $errorType = 'permission'; } else { $errorType = 'filesystem'; $errorMessage = $e->__toString(); } } restore_error_handler(); remove_filter('filesystem_method', array($this, 'filter_filesystem_method')); } if (!$success) { add_action('admin_notices', function() use ($fileExists, $errorType, $errorMessage) { $html = '

' . ''. __('ERROR with the following plugin:', 'wp-reviews-plugin-for-google') .' '. $this->plugin_name .'

' . __('CSS file could not saved.', 'wp-reviews-plugin-for-google') .' ('. $this->getCssFile() .') '. __('Your widgets do not display properly!', 'wp-reviews-plugin-for-google') . '
'; if ($errorType === 'filesystem') { $html .= '
There is an error with your filesystem. We got the following error message:

'. $errorMessage .'
Maybe you configured your filesystem incorrectly.
Here you can read about how to configure filesystem in your WordPress.
'; } else { if ($fileExists) { $html .= __('CSS file exists and it is not writeable. Delete the file', 'wp-reviews-plugin-for-google'); } else { $html .= __('Grant write permissions to upload folder', 'wp-reviews-plugin-for-google'); } $html .= '
' . __('or', 'wp-reviews-plugin-for-google') . '
' . /* translators: %s: Advanced page link */ sprintf(__("enable 'CSS internal loading' in the %s page!", 'wp-reviews-plugin-for-google'), 'getPageDetails(); if (!$pageDetails) { return ""; } $pageId = $pageDetails['id']; $domain = ""; $url = str_replace([ '%domain%', '%page_id%', '%25page_id%25' ], [ $domain, $pageId, $pageId ], self::$page_urls[ $this->getShortName() ]); if ($this->getGoogleType($pageId) === 'shop') { $url = 'https://customerreviews.google.com/v/merchant?q=' . $pageId; } return $url; } private function getDefaultCompanyAvatarUrl() { return 'https://cdn.trustindex.io/companies/default_avatar.jpg'; } private function getGoogleType($pageId) { return preg_match('/&c=\w+&v=\d+/', $pageId) ? 'shop' : 'map'; } private function getReviewPageUrl() { $pageDetails = $this->getPageDetails(); if (!$pageDetails) { return ""; } $pageId = $pageDetails['id']; if ($this->getGoogleType($pageId) === 'shop') { return 'https://customerreviews.google.com/v/merchant?q=' . $pageId; } else { return 'https://admin.trustindex.io/api/googleReview?place-id=' . $pageId; } } private function getReviewWriteUrl() { $pageDetails = $this->getPageDetails(); if (!$pageDetails) { return ""; } $pageId = $pageDetails['id']; if ($this->getGoogleType($pageId) === 'shop') { return 'https://customerreviews.google.com/v/merchant?q=' . $pageId; } else { return 'https://admin.trustindex.io/api/googleWriteReview?place-id=' . $pageId; } } public function getReviewHtml($review) { $html = $review->text; if ($review->text) { $html = $this->parseReviewText($review->text); } if (isset($review->highlight) && $review->highlight) { $tmp = explode(',', $review->highlight); $start = (int)$tmp[0]; $length = (int)$tmp[1]; $html = mb_substr($html, 0, $start) . '' . mb_substr($html, $start, $length) . '' . mb_substr($html, $start + $length, mb_strlen($html)); /* format tags in other tags * like: * .......... * to: * .......... */ preg_match('/(.*)<\/mark>/Us', $html, $matches); if (isset($matches[1])) { $replaced_content = preg_replace('/(<\/?[^>]+>)/U', '$1', $matches[1]); $html = str_replace($matches[0], '' . $replaced_content . '', $html); } } return $html; } private function parseReviewText($text) { return wp_kses_post(preg_replace('/\r\n|\r|\n/', "\n", trim(html_entity_decode($text, ENT_HTML5 | ENT_QUOTES)))); } private function getProfileImageUrl($imageUrl, $layoutId, $sizeMultiply = 1) { $size = $this->getProfileImageSize($layoutId) * $sizeMultiply; $imageUrl = preg_replace('/([=-])(?:s\d+|w\d+-h\d+)(-|$)/', "$1w$size-h$size$2", $imageUrl); return $imageUrl; } private function getProfileImageSize($layoutId) { if (in_array($layoutId, [36,37,38,39,44])) { return 64; } return 40; } private function getHeaderProfileImageSize($layoutId) { return 65; } public function renderWidgetFrontend($tiPublicId = null) { $this->enqueueLoaderScript(); if ($tiPublicId) { $tiPublicId = preg_replace('/[^a-zA-Z0-9]/', '', $tiPublicId); } $preContent = ""; $attributes = ['data-src' => 'https://cdn.trustindex.io/loader.js?'.$tiPublicId]; if (!$tiPublicId) { $pageDetails = $this->getPageDetails(); $styleId = (int)$this->getWidgetOption('style-id'); if (self::is_amp_active() && self::is_amp_enabled()) { return $this->frontEndErrorForAdmins(__('Free plugin features are unavailable with AMP plugin.', 'wp-reviews-plugin-for-google')); } if (self::$widget_templates['templates'][$styleId]['is-top-rated-badge'] && (float)$pageDetails['rating_score'] < self::$topRatedMinimumScore) { /* translators: %s: min score (4.5) */ $text = sprintf(__('Our exclusive "Top Rated" badge is awarded to service providers with a rating of %s and above.', 'wp-reviews-plugin-for-google'), self::$topRatedMinimumScore) .'
' .'
'.__('Please select another widget', 'wp-reviews-plugin-for-google').'.'; return $this->frontEndErrorForAdmins($text); } if ($reviews = $this->getReviewsForWidgetHtml()) { $this->increaseViews(); $templateId = 'trustindex-'.$this->getShortName().'-widget-html'; $attributes['data-src'] .= 'wp-widget'; $attributes['data-template-id'] = $templateId; $preContent = ''; } else { /* translators: %s: Platform name */ $text = sprintf(__('There are no reviews on your %s platform.', 'wp-reviews-plugin-for-google'), ucfirst($this->getShortName())); return $this->frontEndErrorForAdmins($text); } } $attributesHtml = implode(' ', array_map(function($attribute, $value) { return esc_attr($attribute).'="'.esc_attr($value).'"'; }, array_keys($attributes), $attributes)); return $preContent.'
'; } public function renderWidgetAdmin($isDemoReviews = false, $isForceDemoReviews = false, $previewData = null) { $this->widgetOptionDefaultOverride = []; if ($previewData) { $this->widgetOptions['style-id'] = $previewData['style-id']; $this->widgetOptions['scss-set'] = $previewData['set-id']; $this->widgetOptions['review-content'] = ""; $fileName = $previewData['style-id'].'-'.$previewData['set-id'].'.css'; wp_enqueue_style('trustindex-widget-preview-'.$fileName, "https://cdn.trustindex.io/assets/widget-presetted-css/v2/$fileName", [], true); if (isset($previewData['verified-by-trustindex']) && $previewData['verified-by-trustindex']) { $this->widgetOptionDefaultOverride['verified-by-trustindex'] = 1; } } $reviews = $this->getReviewsForWidgetHtml(true, $isForceDemoReviews, (bool)$previewData); if (!$reviews) { return self::get_alertbox('error', __('You do not have reviews with the current filters.
Change your filters if you would like to display reviews on your page!', 'wp-reviews-plugin-for-google')); } $html = $this->getWidgetHtml($reviews, (bool)$previewData, true); if (!$previewData) { if (is_file($this->getCssFile()) && !$this->isElementorEditing()) { wp_enqueue_style('trustindex-widget-editor', $this->getCssUrl(), [], filemtime($this->getCssFile())); } else { $html .= ''; } } if ($this->isElementorEditing()) { // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript $html .= ''; } else { $this->enqueueLoaderScript(); } return $html; } public function renderNameFormat($name, $formatId = null) { if (!$formatId) { $formatId = $this->getWidgetOption('nameformat'); } if (!isset(self::$widget_nameformats[$formatId])) { return $name; } $format = self::$widget_nameformats[$formatId]; if (!$format['regex']) { return $name; } $result = preg_replace($format['regex'], '$1 $2', $name); if ($format['ucfirst']) { $result = ucfirst($result); } if ($format['toupper']) { $result = function_exists('mb_strtoupper') ? mb_strtoupper($result) : strtoupper($result); } return $result; } public function enqueueLoaderScript() { if (wp_script_is('trustindex-loader-js', 'registered')) { wp_enqueue_script('trustindex-loader-js'); } else { wp_enqueue_script('trustindex-loader-js', 'https://cdn.trustindex.io/loader.js', [], true, [ 'strategy' => 'async', 'in_footer' => true, ]); } } private $templateCache = null; private function getWidgetHtml($reviews, $isPreview = false, $isAdmin = false) { $styleId = (int)$this->getWidgetOption('style-id'); $setId = $this->getWidgetOption('scss-set'); $content = $this->getWidgetOption('review-content'); $language = $this->getWidgetOption('lang', false, $isPreview); if (!$content || strpos($content, '') === false) { if (!$this->templateCache) { add_action('http_api_curl', function($handle) { // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false); // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false); }, 10); if (strlen($language) > 3) { $language = 'en'; } $response = wp_remote_get("https://cdn.trustindex.io/widget-assets/template/v2/$language.json", [ 'timeout' => 300 ]); if (is_wp_error($response)) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r return $this->frontEndErrorForAdmins(__('Could not download the template for the widget.
Please reload the page.
If the problem persists, please write an email to support@trustindex.io.', 'wp-reviews-plugin-for-google') .'

'. print_r($response, true)); } $this->templateCache = json_decode($response['body'], true); } $content = $this->templateCache[$styleId]; if (!$isPreview) { update_option($this->get_option_name('review-content'), $content, false); } } $content = $this->parseWidgetHtml($reviews, $content, $isPreview, $isAdmin); $content = preg_replace('/data-set[_-]id=[\'"][^\'"]*[\'"]/m', 'data-set-id="'. $setId .'"', $content); $classAppends = ['ti-' . substr($this->getShortName(), 0, 4)]; if (!$this->getWidgetOption('show-reviewers-photo', false, $isPreview)) { $classAppends []= 'ti-no-profile-img'; } if ($this->getWidgetOption('disable-font', false, $isPreview)) { $classAppends []= 'ti-disable-font'; } if (!$this->getWidgetOption('show-arrows', false, $isPreview)) { $classAppends []= 'ti-disable-nav'; } if (!$this->getWidgetOption('enable-animation', false, $isPreview)) { $classAppends []= 'ti-disable-animation'; } if ($this->isFomoWidget()) { $classAppends []= 'ti-fomo-align-'.$this->getWidgetOption('align', false, $isPreview); if (!$this->getWidgetOption('fomo-border', false, $isPreview)) { $classAppends []= 'ti-hide-fomo-border'; } if (!$this->getWidgetOption('fomo-arrow', false, $isPreview)) { $classAppends []= 'ti-hide-fomo-arrow'; } if ('hide' === $this->getWidgetOption('fomo-icon', false, $isPreview)) { $classAppends []= 'ti-icon-hide'; } if ($this->getWidgetOption('fomo-icon-background', false, $isPreview)) { $classAppends []= 'ti-icon-background'; } } else { if (!$this->getWidgetOption('no-rating-text', false, $isPreview)) { $classAppends []= 'ti-show-rating-text'; } $classAppends []= 'ti-review-text-mode-'.$this->getWidgetOption('review-text-mode', false, $isPreview); $classAppends []= 'ti-'.(in_array($styleId, [36, 37, 38, 39]) ? 'content' : 'text').'-align-'.$this->getWidgetOption('align', false, $isPreview); } if (self::$widget_styles[$setId]['hide-stars'] === 'custom') { $classAppends []= 'ti-custom-stars'; } $content = str_replace('" data-layout-id=', ' '. implode(' ', $classAppends) .'" data-no-translation="true" data-layout-id=', $content); if ($this->isRtlLanguage()) { $content = str_replace('" data-layout-id=', '" data-rotate-to="left" data-layout-id=', $content); } if ($this->getWidgetOption('dateformat', false, $isPreview) === 'modern') { $language = $this->getWidgetOption('lang', false, $isPreview); $content = str_replace('" data-layout-id=', '" data-time-locale="'. self::$widget_date_format_locales[$language] .'" data-layout-id=', $content); } if ($this->isFomoWidget()) { $styleText = '--fomo-color:'.$this->getWidgetOption('fomo-color', false, $isPreview).';'; if ('right' === $this->getWidgetOption('align', false, $isPreview)) { $styleText .= 'left: auto;right: '.$this->getWidgetOption('fomo-margin', false, $isPreview).'px;'; } else { $styleText .= 'left: '.$this->getWidgetOption('fomo-margin', false, $isPreview).'px;'; } $hideCount = $this->getWidgetOption('fomo-hide-count', false, $isPreview); $content = str_replace('" data-layout-id=', '" style="'.$styleText.'" data-hide-count='.$hideCount.' data-layout-id=', $content); } $content = str_replace('" data-layout-id=', '" data-plugin-version="'.str_replace('do-not-care-', '', $this->getVersion()).'" data-layout-id=', $content); return $content; } private function getReviewsForWidgetHtml($isDemoReviews = false, $isForceDemoReviews = false, $isPreview = false) { global $wpdb; $filter = $this->getWidgetOption('filter', false, $isPreview); $onlyRatings = isset($filter['only-ratings']) && $filter['only-ratings'] ? 1 : 0; if (isset($filter['stars']) && count($filter['stars']) === 1 && (int)$filter['stars'][0] === 5) { if ($this->is_ten_scale_rating_platform()) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $reviews = $wpdb->get_results($wpdb->prepare('SELECT *, rating AS original_rating, ROUND(rating / 2, 0) AS rating FROM %i WHERE hidden = 0 AND ROUND(rating / 2, 0) = 5 ORDER BY date DESC', $this->get_tablename('reviews'))); } else { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $reviews = $wpdb->get_results($wpdb->prepare('SELECT *, rating AS original_rating FROM %i WHERE hidden = 0 AND (rating IS NULL OR rating = 5) ORDER BY date DESC', $this->get_tablename('reviews'))); } } else if (isset($filter['stars']) && count($filter['stars']) === 2) { if ($this->is_ten_scale_rating_platform()) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $reviews = $wpdb->get_results($wpdb->prepare('SELECT *, rating AS original_rating, ROUND(rating / 2, 0) AS rating FROM %i WHERE hidden = 0 AND ROUND(rating / 2, 0) IN (4,5) ORDER BY date DESC', $this->get_tablename('reviews'))); } else { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $reviews = $wpdb->get_results($wpdb->prepare('SELECT *, rating AS original_rating FROM %i WHERE hidden = 0 AND (rating IS NULL OR rating IN (4,5)) ORDER BY date DESC', $this->get_tablename('reviews'))); } } else { if ($this->is_ten_scale_rating_platform()) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $reviews = $wpdb->get_results($wpdb->prepare('SELECT *, rating AS original_rating, ROUND(rating / 2, 0) AS rating FROM %i WHERE hidden = 0 ORDER BY date DESC', $this->get_tablename('reviews'))); } else { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $reviews = $wpdb->get_results($wpdb->prepare('SELECT *, rating AS original_rating FROM %i WHERE hidden = 0 ORDER BY date DESC', $this->get_tablename('reviews'))); } } if ($onlyRatings) { for ($i = 0; $i < count($reviews); $i++) { if (!$reviews[$i]->text || !trim($reviews[$i]->text)) { array_splice($reviews, $i, 1); $i--; } } } if ($isDemoReviews && ($isForceDemoReviews || !$reviews)) { if (!$reviews && !$isForceDemoReviews && $this->getReviews()) { return []; } $pageDetails = $this->getPageDetails(); $lang = substr(get_locale(), 0, 2); if (!isset(self::$widget_languages[$lang])) { $lang = 'en'; } if (!$pageDetails) { $pageDetails = []; } if (!isset($pageDetails['avatar_url'])) { $pageDetails['avatar_url'] = 'https://cdn.trustindex.io/companies/default_avatar.jpg'; } $ratingNum = 127; $pageDetails['rating_number'] = $ratingNum; $scoreTmp = round((($ratingNum - 1) * 5 + 4) / ($ratingNum * 5) * 10, 1); if ($this->is_ten_scale_rating_platform()) { $pageDetails['rating_score'] = number_format($scoreTmp, 1); } else { $pageDetails['rating_score'] = number_format($scoreTmp / 2, 1); } if (!isset($pageDetails['id'])) { $pageDetails['id'] = 'hu'; } if (!isset($pageDetails['name'])) { $pageDetails['name'] = get_bloginfo('name'); } $this->pageDetails = $pageDetails; $reviews = $this->getRandomReviews(10); } return $reviews; } public function getReviews() { global $wpdb; if (!$this->is_noreg_linked()) { return []; } $result = wp_cache_get('ti-reviews-cache-'.$this->getShortName()); if ($result === false) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $result = $wpdb->get_results($wpdb->prepare('SELECT * FROM %i ORDER BY date DESC', $this->get_tablename('reviews'))); wp_cache_set('ti-reviews-cache-'.$this->getShortName(), $result, '', 3600); } return $result; } private function parseWidgetHtml($reviews, $content, $isPreview = false, $isAdmin = false) { $pageDetails = $this->getPageDetails(); $styleId = (int)$this->getWidgetOption('style-id'); $setId = $this->getWidgetOption('scss-set'); $language = $this->getWidgetOption('lang', false, $isPreview); $widgetTemplate = self::$widget_templates['templates'][$styleId]; $showStars = $this->getWidgetOption('show-stars', false, $isPreview); if (self::$widget_styles[$setId]['hide-stars'] === 'custom') { $showStars = 'custom'; } preg_match('/(.*)/', $content, $matches); if (isset($matches[1])) { $reviewContent = ""; if ($reviews) { foreach ($reviews as $r) { $customAttributes = 'data-empty="'. (empty($r->text) ? 1 : 0) .'"'; $date = " "; if ($r->date && $r->date !== '0000-00-00') { $dateformat = $this->getWidgetOption('dateformat', false, $isPreview); if (in_array($dateformat, [ 'hide', 'modern' ])) { $date = ''; if ($dateformat === 'modern') { $customAttributes .= ' data-time="'. strtotime($r->date) .'"'; } } else { $date = str_replace(self::$widget_month_names['en'], self::$widget_month_names[$language], gmdate($dateformat, strtotime($r->date))); } } $ratingContent = $this->get_rating_stars($r->rating, $showStars); if ($showStars === true) { if ($this->is_ten_scale_rating_platform()) { $ratingContent .= ''. $this->formatTenRating($r->original_rating, $language) .''; } } $platformName = ucfirst($this->getShortName()); if ($this->getWidgetOption('verified-icon', false, $isPreview)) { $verifiedIconTooltipText = self::$widget_verified_texts[$language]; $verifiedIconClass = 'ti-verified-review'; if (!in_array($platformName, self::$verified_platforms)) { $verifiedIconClass = 'ti-verified-review ti-verified-platform'; $verifiedIconTooltipText = str_replace('%platform%', 'PLATFORM_NAME', self::$widget_verified_platform_texts[$language]); } if (self::$widget_styles[$setId]['verified-icon-color'] !== 'blue') { $verifiedIconClass .= ' ti-color-'.self::$widget_styles[$setId]['verified-icon-color']; } $ratingContent .= ''.$verifiedIconTooltipText.''; } if (!$this->getWidgetOption('show-reviewers-photo', false, $isPreview)) { $matches[1] = preg_replace('/
.+<\/div>/U', '', $matches[1]); } $text = $this->getReviewHtml($r); if ($r->reply && $this->getWidgetOption('show-review-replies', false, $isPreview)) { $text .= '

'.self::$widget_reply_by_texts[$language].'
'.$this->parseReviewText($r->reply); } $reviewContent .= str_replace([ '%platform%', '%reviewer_photo% 2x', '%reviewer_photo%', '%reviewer_name%', '%created_at%', '%text%', '%rating_score%', 'class="ti-review-item', '', ], [ $platformName, $this->getProfileImageUrl($r->user_photo, $styleId, 2).' 2x', $this->getProfileImageUrl($r->user_photo, $styleId), $this->renderNameFormat($r->user), $date, $text, round($r->original_rating), $customAttributes . ' class="ti-review-item', $ratingContent, ], $matches[1]); $reviewContent = str_replace('
', '', $reviewContent); } } $content = str_replace($matches[0], $reviewContent, $content); } $ratingCount = $pageDetails['rating_number']; $ratingScore = $pageDetails['rating_score']; if (empty($ratingCount)) { $ratingCount = count($reviews); } if (empty($ratingScore)) { $ratingSum = 0.0; foreach ($reviews as $review) { $ratingSum += (float)$review->rating; } $c = count($reviews); $ratingScore = $c ? $ratingSum / $c : 0; } $ratingText = $this->get_rating_text($ratingScore, $language); $ratingTextUcfirst = ucfirst(strtolower($ratingText)); if (function_exists('mb_strtolower')) { $ratingTextUcfirst = mb_substr($ratingText, 0, 1, 'UTF-8') . mb_strtolower(mb_substr($ratingText, 1, null, 'UTF-8')); } $imageUrl = isset($pageDetails['avatar_url']) && $pageDetails['avatar_url'] ? $pageDetails['avatar_url'] : $this->getDefaultCompanyAvatarUrl(); $image2xUrl = $imageUrl; $size = $this->getHeaderProfileImageSize($styleId); $imageUrl = preg_replace('/([=-])(s\d+|w\d+-h\d+)/', "$1w$size-h$size", $imageUrl); $size *= 2; $image2xUrl = preg_replace('/([=-])(s\d+|w\d+-h\d+)/', "$1w$size-h$size", $imageUrl); $profileImageListForButton = ""; if ($reviews) { $max = $widgetTemplate['type'] === 'fomo' ? 3 : 5; for ($i = 0; $i < min(count($reviews), $max); $i++) { $profileImageListForButton .= '
'.esc_attr($reviews[$i]->user).'
'; } } if ($widgetTemplate['type'] === 'fomo') { $ratingText = $ratingTextUcfirst; } $fiveStarRatingNumber = 0; if (isset($pageDetails['rating_numbers'])) { $fiveStarRatingNumber = $pageDetails['rating_numbers'][5]; } $fiveStarRatingNumberLast = 0; if (isset($pageDetails['rating_numbers_last'])) { $fiveStarRatingNumberLast = $pageDetails['rating_numbers_last'][5]; } $content = str_replace([ '%platform%', '%site_name%', "5STAR_RATING_NUMBER_LAST", "5STAR_RATING_NUMBER", "RATING_NUMBER", "RATING_SCORE", "RATING_SCALE", "RATING_TEXT", "RATING_TEXT", "Rating_Text", "PLATFORM_URL_LOGO 2x", "PLATFORM_URL_LOGO", "PLATFORM_NAME", '', 'PLATFORM_SMALL_LOGO', 'PLATFORM_SMALL_ICON', '
', ], [ ucfirst($this->getShortName()), $pageDetails['name'], $fiveStarRatingNumberLast, $fiveStarRatingNumber, $ratingCount, number_format((float)$ratingScore, 1), $this->is_ten_scale_rating_platform() ? 10 : 5, $this->get_rating_text_long($ratingScore, $language), $ratingText, $ratingTextUcfirst, $image2xUrl.' 2x', $imageUrl, $this->get_platform_name($this->getShortName(), $pageDetails['id']), $this->get_rating_stars($this->is_ten_scale_rating_platform() ? $ratingScore / 2 : $ratingScore, $showStars), '', ''.ucfirst($this->getShortName()).'', '
'.$profileImageListForButton.'
', ], $content); if (!in_array($widgetTemplate['type'], [ 'button', 'badge', 'top-rated-badge', 'fomo' ]) && !$this->getWidgetOption('show-logos', false, $isPreview)) { $content = preg_replace('//U', '', $content); } if ($this->is_ten_scale_rating_platform() && $styleId === 11) { $content = str_replace(''. $ratingScore .' ', '', $content); } if (in_array($styleId, [8, 10, 11, 12, 13, 14, 20, 22, 24, 25, 26, 27, 28, 29, 35, 55, 56, 57, 58, 59, 60, 61, 62, 106, 107, 109, 110, 111, 113, 115]) || $widgetTemplate['type'] === 'fomo') { if ($widgetTemplate['type'] === 'fomo' && !$this->getWidgetOption('fomo-link', false, $isPreview)) { $content = preg_replace('/]*>(.+)<\/a>/mU', '
$1
', $content); } else { if (!$this->getWidgetOption('show-header-button', false, $isPreview)) { $content = preg_replace('//s', '', $content); } $content = str_replace([''], '', $content); $footerUrl = $this->getPageUrl(); $footerUrl = in_array($styleId, [8, 13, 14, 26]) ? $this->getReviewWriteUrl() : $this->getReviewPageUrl(); if ($widgetTemplate['type'] === 'fomo') { $footerUrl = $this->getWidgetOption('fomo-url', false, $isPreview); } $content = str_replace('%footer_link%', $footerUrl, $content); } } else { $content = preg_replace('/
]*>(.+)<\/a>/mU', '$1', $content); } if ($widgetTemplate['type'] === 'fomo') { if (!$this->getWidgetOption('fomo-open', false, $isPreview)) { $content = str_replace('class="ti-widget-container"', 'class="ti-widget-container ti-header-closed"', $content); } $iconType = $this->getWidgetOption('fomo-icon', false, $isPreview); $iconHtml = '
'; $platformIconHtml = ''.ucfirst($this->getShortName()).''; if ('hide' === $iconType) { $iconHtml = ''; } else if ('profile-images' === $iconType) { $iconHtml = '
'.$profileImageListForButton.'
'; } else if ('platform' === $iconType) { $iconHtml = $platformIconHtml; } $content = preg_replace('/
\s*<\/div>/', '
'.$iconHtml.'
', $content); $platformBlockText = ''; if (isset($widgetTemplate['params']['fomo-platform-block']) && $widgetTemplate['params']['fomo-platform-block'] && 'platform' !== $iconType) { $platformBlockText = $platformIconHtml; } $content = str_replace('', $platformBlockText, $content); if ($this->isFomoCustomWidget() || $this->getFomoSubtitleTextChoices()) { if ($text = $this->getWidgetOption('fomo-title', false, $isPreview)) { $content = preg_replace( '/
(.+)<\/div>/U', '
'.$text.'
', $content ); } if ($text = $this->getWidgetOption('fomo-text', false, $isPreview)) { if ('hide' === $text) { $content = preg_replace('/
(.+)<\/div>/U','', $content); } else { if ( isset($widgetTemplate['params']['trans']) && isset($widgetTemplate['params']['trans'][$language]) && isset($widgetTemplate['params']['trans'][$language][$text]) ) { $text = $widgetTemplate['params']['trans'][$language][$text]; } $content = preg_replace( '/
(.+)<\/div>/U', '
'.$text.'
', $content ); } } } if (isset($widgetTemplate['params']['fomo-days'])) { $days = (int)$this->getWidgetOption('fomo-day', false, $isPreview); if (strpos($content, '%registrations%') !== false) { $count = $this->getRegistrationCount($days); $content = str_replace('%registrations%', $count, $content); } else if (strpos($content, '%visitors%') !== false) { $count = $this->getViewsByDays($days); $content = str_replace('%visitors%', $count, $content); } if (isset($count) && !$isPreview && !$isAdmin && $count < $this->getWidgetOption('fomo-hide-count', false, $isPreview)) { $content = ""; } else { $timeunitText = self::$widget_last_timeunit_texts[$language][1]; if ($days === 1) { $timeunitText = self::$widget_last_timeunit_texts[$language][0]; $days = 24; } $content = str_replace('IN-LAST-TIMEUNIT', sprintf($timeunitText, $days), $content); } } } if (!$this->getWidgetOption('reviews-load-more', false, $isPreview)) { $content = preg_replace('/
]*>.+<\/div>\s*<\/div>/U', '', $content); } if (in_array($styleId, [4, 6, 7, 15, 16, 19, 31, 33, 36, 37, 38, 39, 44]) && $this->getWidgetOption('no-rating-text', false, $isPreview)) { if (in_array($styleId, [6, 7])) { $content = preg_replace('/