X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FOembed%2FOembedPlugin.php;h=44e4ac93180679d1baccba90fb6bb66bc74a25b8;hb=80f7a5f025654c88bde16acfce40bda2af8c4526;hp=c014b65cfb28148be4535502170a4cb7f673b7f7;hpb=f094918cf69fec48aa501b8ec0cfa4af87d11266;p=quix0rs-gnu-social.git diff --git a/plugins/Oembed/OembedPlugin.php b/plugins/Oembed/OembedPlugin.php index c014b65cfb..44e4ac9318 100644 --- a/plugins/Oembed/OembedPlugin.php +++ b/plugins/Oembed/OembedPlugin.php @@ -35,6 +35,62 @@ class OembedPlugin extends Plugin $m->connect('main/oembed', array('action' => 'oembed')); } + public function onGetRemoteUrlMetadataFromDom($url, DOMDocument $dom, stdClass &$metadata) + { + try { + common_log(LOG_INFO, 'Trying to discover an oEmbed endpoint using link headers.'); + $api = oEmbedHelper::oEmbedEndpointFromHTML($dom); + common_log(LOG_INFO, 'Found oEmbed API endpoint ' . $api . ' for URL ' . $url); + $params = array( + 'maxwidth' => common_config('thumbnail', 'width'), + 'maxheight' => common_config('thumbnail', 'height'), + ); + $metadata = oEmbedHelper::getOembedFrom($api, $url, $params); + + // Facebook just gives us javascript in its oembed html, + // so use the content of the title element instead + if(strpos($url,'https://www.facebook.com/') === 0) { + $metadata->html = @$dom->getElementsByTagName('title')->item(0)->nodeValue; + } + + // Wordpress sometimes also just gives us javascript, use og:description if it is available + $xpath = new DomXpath($dom); + $generatorNode = @$xpath->query('//meta[@name="generator"][1]')->item(0); + if ($generatorNode instanceof DomElement) { + // when wordpress only gives us javascript, the html stripped from tags + // is the same as the title, so this helps us to identify this (common) case + if(strpos($generatorNode->getAttribute('content'),'WordPress') === 0 + && trim(strip_tags($metadata->html)) == trim($metadata->title)) { + $propertyNode = @$xpath->query('//meta[@property="og:description"][1]')->item(0); + if ($propertyNode instanceof DomElement) { + $metadata->html = $propertyNode->getAttribute('content'); + } + } + } + } catch (Exception $e) { + common_log(LOG_INFO, 'Could not find an oEmbed endpoint using link headers, trying OpenGraph from HTML.'); + // Just ignore it! + $metadata = OpenGraphHelper::ogFromHtml($dom); + } + + if (isset($metadata->thumbnail_url)) { + // sometimes sites serve the path, not the full URL, for images + // let's "be liberal in what you accept from others"! + // add protocol and host if the thumbnail_url starts with / + if(substr($metadata->thumbnail_url,0,1) == '/') { + $thumbnail_url_parsed = parse_url($metadata->url); + $metadata->thumbnail_url = $thumbnail_url_parsed['scheme']."://".$thumbnail_url_parsed['host'].$metadata->thumbnail_url; + } + + // some wordpress opengraph implementations sometimes return a white blank image + // no need for us to save that! + if($metadata->thumbnail_url == 'https://s0.wp.com/i/blank.jpg') { + unset($metadata->thumbnail_url); + } + } + + } + public function onEndShowHeadElements(Action $action) { switch ($action->getActionName()) { @@ -59,6 +115,9 @@ class OembedPlugin extends Plugin 'title'=>'oEmbed'),null); break; case 'shownotice': + if (!$action->notice->isLocal()) { + break; + } try { $action->element('link',array('rel'=>'alternate', 'type'=>'application/json+oembed', @@ -90,28 +149,23 @@ class OembedPlugin extends Plugin * Normally this event is called through File::saveNew() * * @param File $file The newly inserted File object. - * @param array $redir_data lookup data eg from File_redirection::where() - * @param string $given_url * * @return boolean success */ - public function onEndFileSaveNew(File $file, array $redir_data, $given_url) + public function onEndFileSaveNew(File $file) { $fo = File_oembed::getKV('file_id', $file->id); if ($fo instanceof File_oembed) { - common_log(LOG_WARNING, "Strangely, a File_oembed object exists for new file $file_id", __FILE__); - return true; + common_log(LOG_WARNING, "Strangely, a File_oembed object exists for new file {$file->id}", __FILE__); + return true; } - if (isset($redir_data['oembed']['json']) - && !empty($redir_data['oembed']['json'])) { - File_oembed::saveNew($redir_data['oembed']['json'], $file->id); - } elseif (isset($redir_data['type']) - && (('text/html' === substr($redir_data['type'], 0, 9) - || 'application/xhtml+xml' === substr($redir_data['type'], 0, 21)))) { + if (isset($file->mimetype) + && (('text/html' === substr($file->mimetype, 0, 9) + || 'application/xhtml+xml' === substr($file->mimetype, 0, 21)))) { try { - $oembed_data = File_oembed::_getOembed($given_url); + $oembed_data = File_oembed::_getOembed($file->url); if ($oembed_data === false) { throw new Exception('Did not get oEmbed data from URL'); } @@ -163,41 +217,38 @@ class OembedPlugin extends Plugin return true; } - foreach (array('mimetype', 'url', 'title', 'modified') as $key) { - if (!empty($oembed->{$key})) { + foreach (array('mimetype', 'url', 'title', 'modified', 'width', 'height') as $key) { + if (isset($oembed->{$key}) && !empty($oembed->{$key})) { $enclosure->{$key} = $oembed->{$key}; } } return true; } - public function onStartShowAttachmentRepresentation(HTMLOutputter $out, File $file) + public function onShowUnsupportedAttachmentRepresentation(HTMLOutputter $out, File $file) { - $oembed = File_oembed::getKV('file_id', $file->id); - if (empty($oembed->type)) { + try { + $oembed = File_oembed::getByFile($file); + } catch (NoResultException $e) { return true; } + + // the 'photo' type is shown through ordinary means, using StartShowAttachmentRepresentation! switch ($oembed->type) { - case 'rich': case 'video': case 'link': if (!empty($oembed->html) && (GNUsocial::isAjax() || common_config('attachments', 'show_html'))) { - require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php'; - $config = array( - 'safe'=>1, - 'elements'=>'*+object+embed'); - $out->raw(htmLawed($oembed->html,$config)); + require_once INSTALLDIR.'/extlib/HTMLPurifier/HTMLPurifier.auto.php'; + $purifier = new HTMLPurifier(); + // FIXME: do we allow and here? we did that when we used htmLawed, but I'm not sure anymore... + $out->raw($purifier->purify($oembed->html)); } + return false; break; - - case 'photo': - $out->element('img', array('src' => $oembed->url, 'width' => $oembed->width, 'height' => $oembed->height, 'alt' => 'alt')); - break; - - default: - Event::handle('ShowUnsupportedAttachmentRepresentation', array($out, $file)); } + + return true; } public function onCreateFileImageThumbnailSource(File $file, &$imgPath, $media=null) @@ -209,16 +260,16 @@ class OembedPlugin extends Plugin } // All our remote Oembed images lack a local filename property in the File object - if ($file->filename !== null) { + if (!is_null($file->filename)) { return true; } try { // If we have proper oEmbed data, there should be an entry in the File_oembed // and File_thumbnail tables respectively. If not, we're not going to do anything. - $file_oembed = File_oembed::byFile($file); + $file_oembed = File_oembed::getByFile($file); $thumbnail = File_thumbnail::byFile($file); - } catch (Exception $e) { + } catch (NoResultException $e) { // Not Oembed data, or at least nothing we either can or want to use. return true; } @@ -274,8 +325,8 @@ class OembedPlugin extends Plugin throw new UnsupportedMediaException(_('Image file had impossible geometry (0 width or height)')); } - // We'll trust sha256 not to have collision issues any time soon :) - $filename = hash('sha256', $imgData) . '.' . common_supported_mime_to_ext($info['mime']); + // We'll trust sha256 (File::FILEHASH_ALG) not to have collision issues any time soon :) + $filename = hash(File::FILEHASH_ALG, $imgData) . '.' . common_supported_mime_to_ext($info['mime']); $fullpath = File_thumbnail::path($filename); // Write the file to disk. Throw Exception on failure if (!file_exists($fullpath) && file_put_contents($fullpath, $imgData) === false) { @@ -290,7 +341,7 @@ class OembedPlugin extends Plugin $thumbnail->width = $info[0]; // array indexes documented on php.net: $thumbnail->height = $info[1]; // https://php.net/manual/en/function.getimagesize.php // Throws exception on failure. - $thumbnail->updateWithKeys($orig, 'file_id'); + $thumbnail->updateWithKeys($orig); } public function onPluginVersion(array &$versions)