+ $enclosure = $this->attachment->getEnclosure();
+
+ if (Event::handle('StartShowAttachmentRepresentation', array($this->out, $this->attachment))) {
+ if (!empty($enclosure->mimetype)) {
+ // First, prepare a thumbnail if it exists.
+ $thumb = null;
+ try {
+ // Tell getThumbnail that we can show an animated image if it has one (4th arg, "force_still")
+ $thumb = $this->attachment->getThumbnail(null, null, false, false);
+ } catch (UseFileAsThumbnailException $e) {
+ $thumb = null;
+ } catch (UnsupportedMediaException $e) {
+ // FIXME: Show a good representation of unsupported/unshowable images
+ $thumb = null;
+ }
+
+ // Then get the kind of mediatype we're dealing with
+ $mediatype = common_get_mime_media($enclosure->mimetype);
+
+ // FIXME: Get proper mime recognition of Ogg files! If system has 'mediainfo', this should do it:
+ // $ mediainfo --inform='General;%InternetMediaType%'
+ if ($this->attachment->mimetype === 'application/ogg') {
+ $mediatype = 'video'; // because this element can handle Ogg/Vorbis etc. on its own
+ }
+ switch ($mediatype) {
+ // Anything we understand as an image, if we need special treatment, do it in StartShowAttachmentRepresentation
+ case 'image':
+ if ($thumb instanceof File_thumbnail) {
+ $this->out->element('img', $thumb->getHtmlAttrs(['class'=>'u-photo', 'alt' => '']));
+ } else {
+ $this->out->element('img', array('class'=>'u-photo', 'src' => $this->attachment->getUrl(), 'alt' => $this->attachment->getTitle()));
+ }
+ unset($thumb); // there's no need carrying this along after this
+ break;
+
+ // HTML5 media elements
+ case 'audio':
+ case 'video':
+ if ($thumb instanceof File_thumbnail) {
+ $poster = $thumb->getUrl();
+ unset($thumb); // there's no need carrying this along after this
+ } else {
+ $poster = null;
+ }
+
+ $this->out->elementStart($mediatype,
+ array('class'=>"attachment_player u-{$mediatype}",
+ 'poster'=>$poster,
+ 'controls'=>'controls'));
+ $this->out->element('source',
+ array('src'=>$this->attachment->getUrl(),
+ 'type'=>$this->attachment->mimetype));
+ $this->out->elementEnd($mediatype);
+ break;
+
+ default:
+ unset($thumb); // there's no need carrying this along
+ switch ($this->attachment->mimetype) {
+ case 'text/html':
+ if (!empty($this->attachment->filename)
+ && (GNUsocial::isAjax() || common_config('attachments', 'show_html'))) {
+ // Locally-uploaded HTML. Scrub and display inline.
+ $this->showHtmlFile($this->attachment);
+ break;
+ }
+ // Fall through to default if it wasn't a _local_ text/html File object
+ default:
+ Event::handle('ShowUnsupportedAttachmentRepresentation', array($this->out, $this->attachment));
+ }
+ }
+ } else {
+ Event::handle('ShowUnsupportedAttachmentRepresentation', array($this->out, $this->attachment));
+ }
+ }
+ Event::handle('EndShowAttachmentRepresentation', array($this->out, $this->attachment));
+ }
+
+ protected function showHtmlFile(File $attachment)
+ {
+ $body = $this->scrubHtmlFile($attachment);
+ if ($body) {
+ $this->out->raw($body);
+ }
+ }
+
+ /**
+ * @return mixed false on failure, HTML fragment string on success
+ */
+ protected function scrubHtmlFile(File $attachment)
+ {
+ $path = File::path($attachment->filename);
+ if (!file_exists($path) || !is_readable($path)) {
+ common_log(LOG_ERR, "Missing local HTML attachment $path");
+ return false;
+ }
+ $raw = file_get_contents($path);
+
+ // Normalize...
+ $dom = new DOMDocument();
+ if(!$dom->loadHTML($raw)) {
+ common_log(LOG_ERR, "Bad HTML in local HTML attachment $path");
+ return false;