getOembed($url); if ($oEmbed) { return $oEmbed; } return self::$instance->getInfoFromRemoteUrl($url); } public function getOembed($url) { $data = (new \WP_oEmbed())->get_data($url); if (!$data || is_wp_error($data) || empty($data->provider_name)) { return null; } $data = (array)$data; return array_filter([ 'title' => Arr::get($data, 'title'), 'author_name' => Arr::get($data, 'author_name'), 'type' => 'oembed', 'provider' => strtolower(Arr::get($data, 'provider_name')), 'content_type' => Arr::get($data, 'type'), 'url' => $url, 'html' => Arr::get($data, 'html'), 'image' => Arr::get($data, 'thumbnail_url'), ]); } 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; } $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'), 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)); 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); $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.'), 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.'), array('status' => \WP_Http::NOT_FOUND) ); } return $remote_body; } private function getDocumentHead($html) { $head_html = $html; // Find the opening `
` tag. $head_start = strpos($html, '` tag. $head_end = strpos($head_html, ''); if (false === $head_end) { // Didn't find it. Find the opening `` tag. $head_end = strpos($head_html, '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 = '#