diff options
Diffstat (limited to 'inc/Ui')
-rw-r--r-- | inc/Ui/Admin.php | 10 | ||||
-rw-r--r-- | inc/Ui/Media/Display.php | 119 | ||||
-rw-r--r-- | inc/Ui/Media/DisplayRow.php | 93 | ||||
-rw-r--r-- | inc/Ui/Media/DisplayTile.php | 54 | ||||
-rw-r--r-- | inc/Ui/Revisions.php | 5 |
5 files changed, 275 insertions, 6 deletions
diff --git a/inc/Ui/Admin.php b/inc/Ui/Admin.php index 07146e598..d3bbc6503 100644 --- a/inc/Ui/Admin.php +++ b/inc/Ui/Admin.php @@ -28,9 +28,10 @@ class Admin extends Ui { $this->menu = $this->getPluginList(); echo '<div class="ui-admin">'; echo p_locale_xhtml('admin'); - $this->showSecurityCheck(); + $this->showMenu('admin'); $this->showMenu('manager'); + $this->showSecurityCheck(); $this->showVersion(); $this->showMenu('other'); echo '</div>'; @@ -75,16 +76,15 @@ class Admin extends Ui { * it verifies either: * 'savedir' has been moved elsewhere, or * has protection to prevent the webserver serving files from it + * + * The actual check is carried out via JavaScript. See behaviour.js */ protected function showSecurityCheck() { global $conf; if(substr($conf['savedir'], 0, 2) !== './') return; $img = DOKU_URL . $conf['savedir'] . '/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png'; - echo '<a style="border:none; float:right;" - href="http://www.dokuwiki.org/security#web_access_security"> - <img src="' . $img . '" alt="Your data directory seems to be protected properly." - onerror="this.parentNode.style.display=\'none\'" /></a>'; + echo '<div id="security__check" data-src="' . $img . '"></div>'; } /** diff --git a/inc/Ui/Media/Display.php b/inc/Ui/Media/Display.php new file mode 100644 index 000000000..16f2137b1 --- /dev/null +++ b/inc/Ui/Media/Display.php @@ -0,0 +1,119 @@ +<?php + +namespace dokuwiki\Ui\Media; + +use dokuwiki\File\MediaFile; + +class Display +{ + /** @var MediaFile */ + protected $mediaFile; + + /** @var string should IDs be shown relative to this namespace? Used in search results */ + protected $relativeDisplay = null; + + /** @var bool scroll to this file on display? */ + protected $scrollIntoView = false; + + /** + * Display constructor. + * @param MediaFile $mediaFile + */ + public function __construct(MediaFile $mediaFile) + { + $this->mediaFile = $mediaFile; + } + + /** + * Get the HTML to display a preview image if possible, otherwise show an icon + * + * @param int $w bounding box width to resize pixel based images to + * @param int $h bounding box height to resize pixel based images to + * @return string + */ + public function getPreviewHtml($w, $h) + { + if ($this->mediaFile->isImage()) { + $src = ml($this->mediaFile->getId(), ['w' => $w, 'h' => $h]); + } else { + $src = $this->getIconUrl(); + } + + return '<img src="' . $src . '" alt="' . hsc($this->mediaFile->getDisplayName()) . '" loading="lazy" />'; + } + + /** + * Return the URL to the icon for this file + * + * @return string + */ + public function getIconUrl() + { + $link = 'lib/images/fileicons/svg/' . $this->mediaFile->getIcoClass() . '.svg'; + if (!file_exists(DOKU_INC . $link)) $link = 'lib/images/fileicons/svg/file.svg'; + return DOKU_BASE . $link; + } + + /** + * Show IDs relative to this namespace + * + * @param string|null $ns Use null to disable + */ + public function relativeDisplay($ns) + { + $this->relativeDisplay = $ns; + } + + /** + * Scroll to this file on display? + * + * @param bool $set + */ + public function scrollIntoView($set = true) + { + $this->scrollIntoView = $set; + } + + /** @return string */ + protected function formatDate() + { + return dformat($this->mediaFile->getLastModified()); + } + + /** + * Output the image dimension if any + * + * @param string $empty what to show when no dimensions are available + * @return string + */ + protected function formatDimensions($empty = ' ') + { + $w = $this->mediaFile->getWidth(); + $h = $this->mediaFile->getHeight(); + if ($w && $h) { + return $w . '×' . $h; + } else { + return $empty; + } + } + + /** @return string */ + protected function formatFileSize() + { + return filesize_h($this->mediaFile->getFileSize()); + } + + /** @return string */ + protected function formatDisplayName() + { + if ($this->relativeDisplay !== null) { + $id = $this->mediaFile->getId(); + if (substr($id, 0, strlen($this->relativeDisplay)) == $this->relativeDisplay) { + $id = substr($id, strlen($this->relativeDisplay)); + } + return ltrim($id, ':'); + } else { + return $this->mediaFile->getDisplayName(); + } + } +} diff --git a/inc/Ui/Media/DisplayRow.php b/inc/Ui/Media/DisplayRow.php new file mode 100644 index 000000000..47feed088 --- /dev/null +++ b/inc/Ui/Media/DisplayRow.php @@ -0,0 +1,93 @@ +<?php + +namespace dokuwiki\Ui\Media; + +use dokuwiki\Utf8\PhpString; + +/** + * Display a MediaFile in the Media Popup + */ +class DisplayRow extends DisplayTile +{ + /** @inheritDoc */ + public function show() + { + global $lang; + // FIXME Zebra classes have been dropped and need to be readded via CSS + + $id = $this->mediaFile->getId(); + $class = 'select mediafile mf_' . $this->mediaFile->getIcoClass(); + $info = trim($this->formatDimensions('') . ' ' . $this->formatDate() . ' ' . $this->formatFileSize()); + $jump = $this->scrollIntoView ? 'id="scroll__here"' : ''; + + echo '<div title="' . $id . '" ' . $jump . '>'; + echo '<a id="h_:' . $id . '" class="' . $class . '">' . + $this->formatDisplayName() . + '</a> '; + echo '<span class="info">(' . $info . ')</span>' . NL; + + // view button + $link = ml($id, '', true); + echo ' <a href="' . $link . '" target="_blank"><img src="' . DOKU_BASE . 'lib/images/magnifier.png" ' . + 'alt="' . $lang['mediaview'] . '" title="' . $lang['mediaview'] . '" class="btn" /></a>'; + + // mediamanager button + $link = wl('', array('do' => 'media', 'image' => $id, 'ns' => getNS($id))); + echo ' <a href="' . $link . '" target="_blank"><img src="' . DOKU_BASE . 'lib/images/mediamanager.png" ' . + 'alt="' . $lang['btn_media'] . '" title="' . $lang['btn_media'] . '" class="btn" /></a>'; + + // delete button + if ($this->mediaFile->isWritable() && $this->mediaFile->userPermission() >= AUTH_DELETE) { + $link = DOKU_BASE . 'lib/exe/mediamanager.php?delete=' . rawurlencode($id) . + '&sectok=' . getSecurityToken(); + echo ' <a href="' . $link . '" class="btn_media_delete" title="' . $id . '">' . + '<img src="' . DOKU_BASE . 'lib/images/trash.png" alt="' . $lang['btn_delete'] . '" ' . + 'title="' . $lang['btn_delete'] . '" class="btn" /></a>'; + } + + echo '<div class="example" id="ex_' . str_replace(':', '_', $id) . '">'; + echo $lang['mediausage'] . ' <code>{{:' . $id . '}}</code>'; + echo '</div>'; + if ($this->mediaFile->getWidth()) $this->showDetails(); + echo '<div class="clearer"></div>' . NL; + echo '</div>' . NL; + + } + + /** + * Show Thumbnail and EXIF data + */ + protected function showDetails() + { + $id = $this->mediaFile->getId(); + + echo '<div class="detail">'; + echo '<div class="thumb">'; + echo '<a id="d_:' . $id . '" class="select">'; + echo $this->getPreviewHtml(120, 120); + echo '</a>'; + echo '</div>'; + + // read EXIF/IPTC data + $t = $this->mediaFile->getMeta()->getField(array('IPTC.Headline', 'xmp.dc:title')); + $d = $this->mediaFile->getMeta()->getField(array( + 'IPTC.Caption', + 'EXIF.UserComment', + 'EXIF.TIFFImageDescription', + 'EXIF.TIFFUserComment', + )); + if (PhpString::strlen($d) > 250) $d = PhpString::substr($d, 0, 250) . '...'; + $k = $this->mediaFile->getMeta()->getField(array('IPTC.Keywords', 'IPTC.Category', 'xmp.dc:subject')); + + // print EXIF/IPTC data + if ($t || $d || $k) { + echo '<p>'; + if ($t) echo '<strong>' . hsc($t) . '</strong><br />'; + if ($d) echo hsc($d) . '<br />'; + if ($t) echo '<em>' . hsc($k) . '</em>'; + echo '</p>'; + } + echo '</div>'; + } + +} diff --git a/inc/Ui/Media/DisplayTile.php b/inc/Ui/Media/DisplayTile.php new file mode 100644 index 000000000..aff294b9b --- /dev/null +++ b/inc/Ui/Media/DisplayTile.php @@ -0,0 +1,54 @@ +<?php + +namespace dokuwiki\Ui\Media; + +use dokuwiki\File\MediaFile; + +/** + * Display a MediaFile in the FullScreen MediaManager + */ +class DisplayTile extends Display +{ + /** @var string URL to open this file in the media manager */ + protected $mmUrl; + + /** @inheritDoc */ + public function __construct(MediaFile $mediaFile) + { + parent::__construct($mediaFile); + + // FIXME we may want to integrate this function here or in another class + $this->mmUrl = media_managerURL([ + 'image' => $this->mediaFile->getId(), + 'ns' => getNS($this->mediaFile->getId()), + 'tab_details' => 'view', + ]); + } + + /** + * Display the tile + */ + public function show() + { + $jump = $this->scrollIntoView ? 'id="scroll__here"' : ''; + + echo '<dl title="' . $this->mediaFile->getDisplayName() . '"' . $jump . '>'; + echo '<dt>'; + echo '<a id="l_:' . $this->mediaFile->getId() . '" class="image thumb" href="' . $this->mmUrl . '">'; + echo $this->getPreviewHtml(90, 90); + echo '</a>'; + echo '</dt>'; + + echo '<dd class="name">'; + echo '<a href="' . $this->mmUrl . '" id="h_:' . $this->mediaFile->getId() . '">' . + $this->formatDisplayName() . + '</a>'; + echo '</dd>'; + + echo '<dd class="size">' . $this->formatDimensions() . '</dd>'; + echo '<dd class="date">' . $this->formatDate() . '</dd>'; + echo '<dd class="filesize">' . $this->formatFileSize() . '</dd>'; + + echo '</dl>'; + } +} diff --git a/inc/Ui/Revisions.php b/inc/Ui/Revisions.php index 3385afab2..ca38a213a 100644 --- a/inc/Ui/Revisions.php +++ b/inc/Ui/Revisions.php @@ -17,7 +17,7 @@ abstract class Revisions extends Ui /* @var ChangeLog */ protected $changelog; // PageChangeLog or MediaChangeLog object - /** + /** * Revisions Ui constructor * * @param string $id page id or media id @@ -145,6 +145,9 @@ abstract class Revisions extends Ui public function __construct(array $info) { + if (!isset($info['current'])) { + $info['current'] = false; + } $this->info = $info; } |