# fluent-community/2.8.0/app/Services/RemoteUrlParser.php

FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS &amp; Online Courses, version 2.8.0. 447 lines.

- Page: https://pluginprobe.com/plugins/fluent-community/2.8.0/code/app/Services/RemoteUrlParser.php
- Raw: https://pluginprobe.com/plugins/fluent-community/2.8.0/raw/app/Services/RemoteUrlParser.php
- Modified: 2026-08-19T15:36:26+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/fluent-community/2.8.0/code/app/Services/RemoteUrlParser.php#L10-L20`.

```php
<?php

namespace FluentCommunity\App\Services;

use FluentCommunity\Framework\Support\Arr;

class RemoteUrlParser
{

    private static $instance;

    /*
     * Create a method to call the getInfoFromRemoteUrl static method as magic method
     */
    public static function parse($url)
    {
        if (!self::$instance) {
            self::$instance = new self();
        }

        $oEmbed = self::$instance->getOembed($url);

        if ($oEmbed) {
            return $oEmbed;
        }

        return self::$instance->getInfoFromRemoteUrl($url);
    }

    public static function extractIframeThumbnail(&$html)
    {
        if (!is_string($html)) {
            return '';
        }
        $html = self::sanitizeOembedHtml($html);
        if (!preg_match('/<iframe\s[^>]*\bsrc\s*=\s*([\'"])(.*?)\1/i', $html, $matches)) {
            return '';
        }

        $src = sanitize_url(html_entity_decode($matches[2], ENT_QUOTES | ENT_HTML5, 'UTF-8'));
        if (!$src) {
            return '';
        }

        if (preg_match('#^https?://(?:[\w-]+\.)?youtube\.com/embed/([^?/]+)#i', $src, $ytMatch)) {
            return self::bestYoutubeThumbnail($ytMatch[1]);
        }

        $providers = [
            '#^https?://player\.vimeo\.com/video/([^?/]+).*$#i'                                          => 'https://vumbnail.com/$1.jpg',
            '#^https?://fast\.wistia\.net/embed/iframe/([^?/]+).*$#i'                                    => 'https://fast.wistia.net/embed/medias/$1/swatch',
            '#^https?://(?:www\.)?dailymotion\.com/(?:embed/video|player\.html\?video=)/?([^?/&]+).*$#i' => 'https://www.dailymotion.com/thumbnail/video/$1',
        ];

        foreach ($providers as $pattern => $template) {
            $thumb = preg_replace($pattern, $template, $src, 1, $count);
            if ($count) {
                return $thumb;
            }
        }

        $parsed = self::parse($src);
        return (!is_wp_error($parsed) && !empty($parsed['image'])) ? $parsed['image'] : '';
    }

    /**
     * Pick the best YouTube thumbnail for a feed preview.
     *
     * Runs on the feed-save path, so it stays cheap: a single HEAD probe for
     * the HD WebP frame (~30-56% smaller than JPG, sharp 16:9), falling back
     * to hqdefault.jpg — the one universally present rung (maxres/sd and even
     * hqdefault.webp 404 for non-HD or legacy uploads). The result is stored
     * on the feed and cached, so the probe is paid once per video.
     */
    protected static function bestYoutubeThumbnail($videoId)
    {
        $videoId = sanitize_text_field($videoId);
        if (!$videoId) {
            return '';
        }

        $fallback = 'https://img.youtube.com/vi/' . $videoId . '/hqdefault.jpg';

        $cacheKey = 'fcom_yt_thumb_' . md5($videoId);
        $cached = get_transient($cacheKey);
        if ($cached !== false) {
            return $cached;
        }

        $maxRes = 'https://i.ytimg.com/vi_webp/' . $videoId . '/maxresdefault.webp';
        $response = wp_remote_head($maxRes, ['timeout' => 1.5, 'redirection' => 0]);
        if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
            set_transient($cacheKey, $maxRes, WEEK_IN_SECONDS);
            return $maxRes;
        }

        return $fallback;
    }

    public function getOembed($url)
    {
        $data = (new \WP_oEmbed())->get_data($url, [
            'discover' => Helper::isSiteAdmin()
        ]);

        if (empty($data) || is_wp_error($data) || empty($data->provider_name)) {
            return null;
        }

        $data = (array)$data;

        $provider = strtolower(Arr::get($data, 'provider_name'));

        $image = Arr::get($data, 'thumbnail_url');
        if ($provider === 'youtube') {
            $image = self::bestYoutubeThumbnail(self::getYoutubeVideoId($url)) ?: $image;
        }

        return array_filter([
            'title'        => Arr::get($data, 'title'),
            'author_name'  => Arr::get($data, 'author_name'),
            'type'         => 'oembed',
            'provider'     => $provider,
            'content_type' => Arr::get($data, 'type'),
            'url'          => $url,
            'html'         => self::sanitizeOembedHtml(Arr::get($data, 'html')),
            'image'        => $image,
        ]);
    }

    protected static function getYoutubeVideoId($url)
    {
        if (preg_match('#(?:youtu\.be/|youtube\.com/(?:embed/|v/|live/|shorts/|watch\?v=))([a-zA-Z0-9_-]+)#i', (string)$url, $match)) {
            return $match[1];
        }

        return '';
    }

    public static function sanitizeOembedHtml($html)
    {
        if (empty($html)) {
            return $html;
        }

        static $allowed = null;
        if ($allowed === null) {
            $allowed = wp_kses_allowed_html('post');
            $allowed['iframe'] = [
                'src'             => true,
                'width'           => true,
                'height'          => true,
                'frameborder'     => true,
                'allowfullscreen' => true,
                'title'           => true,
                'loading'         => true,
                'referrerpolicy'  => true,
                'sandbox'         => true,
            ];
        }

        // Strip <script>/<style> incl. contents; wp_kses keeps their inner text otherwise.
        $html = preg_replace('#<(script|style)\b[^>]*>.*?</\1>#is', '', $html);
        $html = preg_replace('#<(script|style)\b[^>]*/?>#i', '', $html);

        return wp_kses($html, $allowed, ['https']);
    }

    public function getInfoFromRemoteUrl($url)
    {
        $url = untrailingslashit($url);

        if (empty($url)) {
            return new \WP_Error('rest_invalid_url', __('Invalid URL', 'fluent-community'), array('status' => 404));
        }

        $cacheKey = 'fcom_url_details_meta_' . md5($url);
        $cachedReponse = wp_cache_get($cacheKey, 'fluent-community');

        if ($cachedReponse) {
            return $cachedReponse;
        }

        $preempted = apply_filters('fluent_community/preview_metadata_pre_fetch', null, $url);
        if ($preempted && is_array($preempted)) {
            wp_cache_set($cacheKey, $preempted, 'fluent-community', apply_filters('rest_url_details_cache_expiration', HOUR_IN_SECONDS)); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
            return $preempted;
        }

        $remote_url_response = $this->getRemoteBody($url);
        if (is_wp_error($remote_url_response) || empty($remote_url_response)) {
            return $remote_url_response;
        }

        $html_head = $this->getDocumentHead($remote_url_response);

        $title = $this->getTitle($html_head);
        if (!$title) {
            return new \WP_Error('rest_invalid_url', __('Invalid URL', 'fluent-community'), array('status' => 404));
        }

        $meta_elements = $this->getMetaWithContentElements($html_head);

        $data = array_filter([
            'title'       => $title,
            'image'       => $this->getImage($meta_elements, $url),
            'description' => $this->getDescription($meta_elements),
            'icon'        => $this->getIcon($html_head, $url),
            'type'        => 'meta_data',
            'url'         => $url
        ]);

        wp_cache_set($cacheKey, $data, 'fluent-community', apply_filters('rest_url_details_cache_expiration', HOUR_IN_SECONDS)); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound

        return $data;
    }

    private function getRemoteBody($url)
    {
        $modified_user_agent = 'WP-URLDetails/' . get_bloginfo('version') . ' (+' . get_bloginfo('url') . ')';

        $args = array(
            'limit_response_size' => 300 * KB_IN_BYTES,
            'user-agent'          => $modified_user_agent,
        );

        /**
         * Filters the HTTP request args for URL data retrieval.
         *
         * Can be used to adjust response size limit and other WP_Http::request() args.
         *
         * @param array $args Arguments used for the HTTP request.
         * @param string $url The attempted URL.
         * @since 5.9.0
         *
         */
        $args = apply_filters('rest_url_details_http_request_args', $args, $url); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound

        $response = wp_safe_remote_get($url, $args);

        if (\WP_Http::OK !== wp_remote_retrieve_response_code($response)) {
            // Not saving the error response to cache since the error might be temporary.
            return new \WP_Error(
                'no_response',
                __('URL not found. Response returned a non-200 status code for this URL.', 'fluent-community'),
                array('status' => \WP_Http::NOT_FOUND)
            );
        }

        $remote_body = wp_remote_retrieve_body($response);

        if (empty($remote_body)) {
            return new \WP_Error(
                'no_content',
                __('Unable to retrieve body from response at this URL.', 'fluent-community'),
                array('status' => \WP_Http::NOT_FOUND)
            );
        }

        return $remote_body;
    }

    private function getDocumentHead($html)
    {
        $head_html = $html;

        // Find the opening `<head>` tag.
        $head_start = strpos($html, '<head');
        if (false === $head_start) {
            // Didn't find it. Return the original HTML.
            return $html;
        }

        // Find the closing `</head>` tag.
        $head_end = strpos($head_html, '</head>');
        if (false === $head_end) {
            // Didn't find it. Find the opening `<body>` tag.
            $head_end = strpos($head_html, '<body');

            // Didn't find it. Return the original HTML.
            if (false === $head_end) {
                return $html;
            }
        }

        // Extract the HTML from opening tag to the closing tag. Then add the closing tag.
        $head_html = substr($head_html, $head_start, $head_end);
        $head_html .= '</head>';

        return $head_html;
    }

    private function getDescription($meta_elements)
    {
        // Bail out if there are no meta elements.
        if (empty($meta_elements[0])) {
            return '';
        }

        $description = $this->getMetadataFromMetaElement(
            $meta_elements,
            'name',
            '(?:description|og:description)'
        );

        // Bail out if description not found.
        if ('' === $description) {
            return '';
        }

        return $this->prepare_metadata_for_output($description);
    }

    private function getImage($meta_elements, $url)
    {
        $image = $this->getMetadataFromMetaElement(
            $meta_elements,
            'property',
            '(?:og:image|og:image:url)'
        );

        // Bail out if image not found.
        if ('' === $image) {
            return '';
        }

        // Attempt to convert relative URLs to absolute.
        $parsed_url = wp_parse_url($url);
        if (isset($parsed_url['scheme']) && isset($parsed_url['host'])) {
            $root_url = $parsed_url['scheme'] . '://' . $parsed_url['host'] . '/';
            $image = \WP_Http::make_absolute_url($image, $root_url);
        }

        if (!$image) {
            return $image;
        }

        return sanitize_url(html_entity_decode($image, ENT_QUOTES | ENT_HTML5, 'UTF-8'));
    }

    private function getTitle($html)
    {
        if (!$html) {
            return '';
        }

        $pattern = '#<title[^>]*>(.*?)<\s*/\s*title>#is';
        preg_match($pattern, $html, $match_title);

        if (empty($match_title[1]) || !is_string($match_title[1])) {
            return '';
        }

        $title = trim($match_title[1]);

        return $this->prepare_metadata_for_output($title);
    }

    private function getMetaWithContentElements($html)
    {
        $pattern = '#<meta\s' .
            '[^>]*' .
            'content=(["\']??)(.*)\1' .
            '[^>]*' .
            '\/?>#' .
            'isU';

        preg_match_all($pattern, $html, $elements);

        return $elements;
    }

    private function prepare_metadata_for_output($metadata)
    {
        $metadata = html_entity_decode($metadata, ENT_QUOTES, get_bloginfo('charset'));
        $metadata = wp_strip_all_tags($metadata);
        return $metadata;
    }

    private function getMetadataFromMetaElement($meta_elements, $attr, $attr_value)
    {
        // Bail out if there are no meta elements.
        if (empty($meta_elements[0])) {
            return '';
        }

        $metadata = '';
        $pattern = '#' .
            $attr . '=([\"\']??)\s*' . $attr_value . '\s*\1' .
            '#isU';

        foreach ($meta_elements[0] as $index => $element) {
            preg_match($pattern, $element, $match);

            if (empty($match)) {
                continue;
            }

            if (isset($meta_elements[2][$index]) && is_string($meta_elements[2][$index])) {
                $metadata = trim($meta_elements[2][$index]);
            }

            break;
        }

        return $metadata;
    }

    private function getIcon($html, $url)
    {
        // Grab the icon's link element.
        $pattern = '#<link\s[^>]*rel=(?:[\"\']??)\s*(?:icon|shortcut icon|icon shortcut)\s*(?:[\"\']??)[^>]*\/?>#isU';
        preg_match($pattern, $html, $element);
        if (empty($element[0]) || !is_string($element[0])) {
            return '';
        }
        $element = trim($element[0]);

        // Get the icon's href value.
        $pattern = '#href=([\"\']??)([^\" >]*?)\\1[^>]*#isU';
        preg_match($pattern, $element, $icon);
        if (empty($icon[2]) || !is_string($icon[2])) {
            return '';
        }
        $icon = trim($icon[2]);

        // If the icon is a data URL, return it.
        $parsed_icon = wp_parse_url($icon);
        if (isset($parsed_icon['scheme']) && 'data' === $parsed_icon['scheme']) {
            return $icon;
        }

        // Attempt to convert relative URLs to absolute.
        if (!is_string($url) || '' === $url) {
            return $icon;
        }

        $parsed_url = wp_parse_url($url);
        if (isset($parsed_url['scheme']) && isset($parsed_url['host'])) {
            $root_url = $parsed_url['scheme'] . '://' . $parsed_url['host'] . '/';
            $icon = \WP_Http::make_absolute_url($icon, $root_url);
        }

        return $icon;
    }
}

```
