item.php
61 lines
| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * Smash Balloon Reviews Feed Item Template |
| 5 | * Adds an image, link, and other data for each post in the feed |
| 6 | * |
| 7 | * @version 1.0 Reviews Feed by Smash Balloon |
| 8 | * |
| 9 | */ |
| 10 | |
| 11 | if (!defined('ABSPATH')) { |
| 12 | exit; // Exit if accessed directly |
| 13 | } |
| 14 | |
| 15 | $item_classes = $this->item_classes($post); |
| 16 | // Form-only providers (wpforms, formidable) never have a brand icon. EDD is |
| 17 | // dual-mode: form-collected (no business.id, written by |
| 18 | // SubmissionsManager::transform_to_review) preserves the legacy no-icon |
| 19 | // rendering; source-collected (business.id populated by the EDD source per |
| 20 | // class/Pro/Integrations/Providers/EDD.php:500,683) shows the EDD icon. |
| 21 | // Without this discriminator, removing 'edd' from $no_icon would visually |
| 22 | // regress existing form-collected EDD reviews in wp_sbr_reviews_posts. |
| 23 | $no_icon = ['wpforms', 'formidable', 'edd']; |
| 24 | $provider_name = $post['provider']['name'] ?? ''; |
| 25 | $is_edd_source = $provider_name === 'edd' && ! empty($post['business']['id'] ?? null); |
| 26 | $show_icon = $provider_name !== '' && $provider_name !== 'none' |
| 27 | && (! in_array($provider_name, $no_icon, true) || $is_edd_source); |
| 28 | ?> |
| 29 | <div class="sb-post-item-wrap sb-new <?php echo esc_attr($item_classes); ?>"<?php if (($settings['layout'] ?? '') !== 'carousel') : ?> role="listitem"<?php endif; ?>> |
| 30 | <div class="sb-post-item"> |
| 31 | <?php if ($show_icon) { ?> |
| 32 | <span class="sb-item-provider-icon"> |
| 33 | <img src="<?php echo esc_html($this->provider_icon_url($post, $settings)); ?>" alt="<?php echo esc_attr(sprintf(/* translators: %s: review provider, e.g. Google */ __('Review from %s', 'reviews-feed'), ucwords($provider_name))); ?>" /> |
| 34 | </span> |
| 35 | <?php } ?> |
| 36 | <?php $this->render_post_elements($post); ?> |
| 37 | <?php |
| 38 | // SMASH-782 Phase 2 — per-provider extras hook. After the standard |
| 39 | // element pipeline runs, include any provider-specific NEW elements |
| 40 | // (e.g. Airbnb host reply, Booking score badge + helpful count, |
| 41 | // AliExpress country flag + variants + translated + follow-up). |
| 42 | // The extras files live at templates/frontend/post-elements/extras/<provider>.php |
| 43 | // and contain ONLY the additive markup — they do NOT replace any |
| 44 | // of the legacy elements above. BC: providers without an extras |
| 45 | // file (Google, Yelp, EDD form-collected, etc.) render unchanged. |
| 46 | // Whitelist the provider slug before using it in a filesystem path. |
| 47 | // `$post['provider']['name']` is curated upstream (relay-controlled), |
| 48 | // but defense-in-depth: only allow lowercase ASCII letters/digits + |
| 49 | // `_` / `-` so a corrupted value can't reach `..` / absolute paths. |
| 50 | if ($provider_name !== '' && preg_match('/^[a-z][a-z0-9_-]*$/', $provider_name)) { |
| 51 | $provider_extras_path = trailingslashit(SBR_PLUGIN_DIR) |
| 52 | . 'templates/frontend/post-elements/extras/' |
| 53 | . $provider_name . '.php'; |
| 54 | if (file_exists($provider_extras_path)) { |
| 55 | include $provider_extras_path; |
| 56 | } |
| 57 | } |
| 58 | ?> |
| 59 | </div> |
| 60 | </div> |
| 61 |