]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - lib/attachmentlistitem.php
Wups, $poster could be undefined
[quix0rs-gnu-social.git] / lib / attachmentlistitem.php
index 5de61d17c512a1d0912b75baece5a8d4942a6e36..2d484fb6a8e1de797c572305edec477a850d2d6d 100644 (file)
@@ -63,7 +63,7 @@ class AttachmentListItem extends Widget
     }
 
     function title() {
-        return $this->attachment->title ?: $this->attachment->filename;
+        return $this->attachment->getTitle();
     }
 
     function linkTitle() {
@@ -87,7 +87,7 @@ class AttachmentListItem extends Widget
 
     function linkAttr() {
         return array('class' => 'attachment',
-                     'href' => $this->attachment->url,
+                     'href' => $this->attachment->getUrl(false),
                      'id' => 'attachment-' . $this->attachment->id,
                      'title' => $this->linkTitle());
     }
@@ -105,12 +105,134 @@ class AttachmentListItem extends Widget
     }
 
     function showRepresentation() {
-        try {
-            $thumb = $this->attachment->getThumbnail();
-            $this->out->element('img', array('alt' => '', 'src' => $thumb->getUrl(), 'width' => $thumb->width, 'height' => $thumb->height));
-        } catch (UnsupportedMediaException $e) {
-            // Image representation unavailable
+        $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;
         }
+
+        // Remove <script>s or htmlawed will dump their contents into output!
+        // Note: removing child nodes while iterating seems to mess things up,
+        // hence the double loop.
+        $scripts = array();
+        foreach ($dom->getElementsByTagName('script') as $script) {
+            $scripts[] = $script;
+        }
+        foreach ($scripts as $script) {
+            common_log(LOG_DEBUG, $script->textContent);
+            $script->parentNode->removeChild($script);
+        }
+
+        // Trim out everything outside the body...
+        $body = $dom->saveHTML();
+        $body = preg_replace('/^.*<body[^>]*>/is', '', $body);
+        $body = preg_replace('/<\/body[^>]*>.*$/is', '', $body);
+
+        require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
+        $config = array('safe' => 1,
+                        'deny_attribute' => 'id,style,on*',
+                        'comment' => 1); // remove comments
+        $scrubbed = htmLawed($body, $config);
+
+        return $scrubbed;
     }
 
     /**