14fd6a1d7SAndreas Gohr<?php 24fd6a1d7SAndreas Gohr 34fd6a1d7SAndreas Gohrnamespace dokuwiki\plugin\extension; 44fd6a1d7SAndreas Gohr 54fd6a1d7SAndreas Gohrclass GuiExtension extends Gui 64fd6a1d7SAndreas Gohr{ 74fd6a1d7SAndreas Gohr const THUMB_WIDTH = 120; 84fd6a1d7SAndreas Gohr const THUMB_HEIGHT = 70; 94fd6a1d7SAndreas Gohr 104fd6a1d7SAndreas Gohr 114fd6a1d7SAndreas Gohr protected Extension $extension; 124fd6a1d7SAndreas Gohr 134fd6a1d7SAndreas Gohr public function __construct(Extension $extension) 144fd6a1d7SAndreas Gohr { 154fd6a1d7SAndreas Gohr parent::__construct(); 164fd6a1d7SAndreas Gohr $this->extension = $extension; 174fd6a1d7SAndreas Gohr } 184fd6a1d7SAndreas Gohr 194fd6a1d7SAndreas Gohr 204fd6a1d7SAndreas Gohr public function render() 214fd6a1d7SAndreas Gohr { 224fd6a1d7SAndreas Gohr 234fd6a1d7SAndreas Gohr $classes = $this->getClasses(); 244fd6a1d7SAndreas Gohr 25*5732c960SAndreas Gohr $html = "<section class=\"$classes\" data-ext=\"{$this->extension->getId()}\">"; 2620db0ca9SAndreas Gohr 2720db0ca9SAndreas Gohr $html .= '<div class="screenshot">'; 284fd6a1d7SAndreas Gohr $html .= $this->thumbnail(); 29652715ccSAndreas Gohr $html .= '<span class="id" title="' . hsc($this->extension->getBase()) . '">' . 30652715ccSAndreas Gohr hsc($this->extension->getBase()) . '</span>'; 3100929f2eSAndreas Gohr $html .= $this->popularity(); 3220db0ca9SAndreas Gohr $html .= '</div>'; 3320db0ca9SAndreas Gohr 3420db0ca9SAndreas Gohr $html .= '<div class="main">'; 35981e70caSAndreas Gohr $html .= $this->main(); 3620db0ca9SAndreas Gohr $html .= '</div>'; 3720db0ca9SAndreas Gohr 38981e70caSAndreas Gohr $html .= '<div class="notices">'; 39981e70caSAndreas Gohr $html .= $this->notices(); 40981e70caSAndreas Gohr $html .= '</div>'; 4120db0ca9SAndreas Gohr 4220db0ca9SAndreas Gohr $html .= '<div class="details">'; 434fd6a1d7SAndreas Gohr $html .= $this->details(); 4420db0ca9SAndreas Gohr $html .= '</div>'; 4520db0ca9SAndreas Gohr 46981e70caSAndreas Gohr $html .= '<div class="actions">'; 4700929f2eSAndreas Gohr // show the available update if there is one 4800929f2eSAndreas Gohr if ($this->extension->isUpdateAvailable()) { 4920db0ca9SAndreas Gohr $html .= ' <div class="version">' . $this->getLang('available_version') . ' ' . 5020db0ca9SAndreas Gohr hsc($this->extension->getLastUpdate()) . '</div>'; 5120db0ca9SAndreas Gohr } 5220db0ca9SAndreas Gohr 534fd6a1d7SAndreas Gohr $html .= $this->actions(); 5420db0ca9SAndreas Gohr $html .= '</div>'; 554fd6a1d7SAndreas Gohr 564fd6a1d7SAndreas Gohr 574fd6a1d7SAndreas Gohr $html .= '</section>'; 584fd6a1d7SAndreas Gohr 594fd6a1d7SAndreas Gohr return $html; 604fd6a1d7SAndreas Gohr } 614fd6a1d7SAndreas Gohr 624fd6a1d7SAndreas Gohr // region sections 634fd6a1d7SAndreas Gohr 644fd6a1d7SAndreas Gohr /** 654fd6a1d7SAndreas Gohr * Get the link and image tag for the screenshot/thumbnail 664fd6a1d7SAndreas Gohr * 674fd6a1d7SAndreas Gohr * @return string The HTML code 684fd6a1d7SAndreas Gohr */ 694fd6a1d7SAndreas Gohr protected function thumbnail() 704fd6a1d7SAndreas Gohr { 714fd6a1d7SAndreas Gohr $screen = $this->extension->getScreenshotURL(); 724fd6a1d7SAndreas Gohr $thumb = $this->extension->getThumbnailURL(); 734fd6a1d7SAndreas Gohr 744fd6a1d7SAndreas Gohr $link = []; 754fd6a1d7SAndreas Gohr $img = [ 764fd6a1d7SAndreas Gohr 'width' => self::THUMB_WIDTH, 774fd6a1d7SAndreas Gohr 'height' => self::THUMB_HEIGHT, 784fd6a1d7SAndreas Gohr 'alt' => '', 794fd6a1d7SAndreas Gohr ]; 804fd6a1d7SAndreas Gohr 814fd6a1d7SAndreas Gohr if ($screen) { 824fd6a1d7SAndreas Gohr $link = [ 834fd6a1d7SAndreas Gohr 'href' => $screen, 844fd6a1d7SAndreas Gohr 'target' => '_blank', 854fd6a1d7SAndreas Gohr 'class' => 'extension_screenshot', 864fd6a1d7SAndreas Gohr 'title' => sprintf($this->getLang('screenshot'), $this->extension->getDisplayName()) 874fd6a1d7SAndreas Gohr ]; 884fd6a1d7SAndreas Gohr 894fd6a1d7SAndreas Gohr $img['src'] = $thumb; 904fd6a1d7SAndreas Gohr $img['alt'] = $link['title']; 914fd6a1d7SAndreas Gohr } elseif ($this->extension->isTemplate()) { 924fd6a1d7SAndreas Gohr $img['src'] = DOKU_BASE . 'lib/plugins/extension/images/template.png'; 934fd6a1d7SAndreas Gohr } else { 944fd6a1d7SAndreas Gohr $img['src'] = DOKU_BASE . 'lib/plugins/extension/images/plugin.png'; 954fd6a1d7SAndreas Gohr } 964fd6a1d7SAndreas Gohr 9720db0ca9SAndreas Gohr $html = ''; 984fd6a1d7SAndreas Gohr if ($link) $html .= '<a ' . buildAttributes($link) . '>'; 994fd6a1d7SAndreas Gohr $html .= '<img ' . buildAttributes($img) . ' />'; 1004fd6a1d7SAndreas Gohr if ($link) $html .= '</a>'; 1014fd6a1d7SAndreas Gohr 1024fd6a1d7SAndreas Gohr return $html; 1034fd6a1d7SAndreas Gohr 1044fd6a1d7SAndreas Gohr } 1054fd6a1d7SAndreas Gohr 1064fd6a1d7SAndreas Gohr /** 1074fd6a1d7SAndreas Gohr * The main information about the extension 1084fd6a1d7SAndreas Gohr * 1094fd6a1d7SAndreas Gohr * @return string 1104fd6a1d7SAndreas Gohr */ 111981e70caSAndreas Gohr protected function main() 1124fd6a1d7SAndreas Gohr { 113981e70caSAndreas Gohr $html = ''; 114981e70caSAndreas Gohr $html .= '<h2>'; 115981e70caSAndreas Gohr $html .= '<div>'; 11600929f2eSAndreas Gohr $html .= sprintf($this->getLang('extensionby'), hsc($this->extension->getDisplayName()), $this->author()); 117981e70caSAndreas Gohr $html .= '</div>'; 1184fd6a1d7SAndreas Gohr 119981e70caSAndreas Gohr $html .= '<div class="version">'; 120981e70caSAndreas Gohr if ($this->extension->isBundled()) { 121981e70caSAndreas Gohr $html .= hsc('<' . $this->getLang('status_bundled') . '>'); 122981e70caSAndreas Gohr } elseif ($this->extension->getInstalledVersion()) { 123981e70caSAndreas Gohr $html .= hsc($this->extension->getInstalledVersion()); 124981e70caSAndreas Gohr } 125981e70caSAndreas Gohr $html .= '</div>'; 126981e70caSAndreas Gohr $html .= '</h2>'; 1274fd6a1d7SAndreas Gohr 128981e70caSAndreas Gohr $html .= '<p>' . hsc($this->extension->getDescription()) . '</p>'; 129981e70caSAndreas Gohr $html .= $this->mainLinks(); 1304fd6a1d7SAndreas Gohr 1314fd6a1d7SAndreas Gohr return $html; 1324fd6a1d7SAndreas Gohr } 1334fd6a1d7SAndreas Gohr 1344fd6a1d7SAndreas Gohr /** 1354fd6a1d7SAndreas Gohr * Display the available notices for the extension 1364fd6a1d7SAndreas Gohr * 1374fd6a1d7SAndreas Gohr * @return string 1384fd6a1d7SAndreas Gohr */ 1394fd6a1d7SAndreas Gohr protected function notices() 1404fd6a1d7SAndreas Gohr { 1414fd6a1d7SAndreas Gohr $notices = Notice::list($this->extension); 1424fd6a1d7SAndreas Gohr 143981e70caSAndreas Gohr $html = '<ul>'; 1444fd6a1d7SAndreas Gohr foreach ($notices as $type => $messages) { 1454fd6a1d7SAndreas Gohr foreach ($messages as $message) { 1464fd6a1d7SAndreas Gohr $message = hsc($message); 14780bc92fbSAndreas Gohr $message = nl2br($message); 14880bc92fbSAndreas Gohr $message = '<span>' . Notice::ICONS[$type] . '</span> ' . $message; 1494fd6a1d7SAndreas Gohr $message = preg_replace('/`([^`]+)`/', '<bdi>$1</bdi>', $message); 150981e70caSAndreas Gohr $html .= '<li class="' . $type . '"><div class="li">' . $message . '</div></li>'; 1514fd6a1d7SAndreas Gohr } 1524fd6a1d7SAndreas Gohr } 153981e70caSAndreas Gohr $html .= '</ul>'; 1544fd6a1d7SAndreas Gohr return $html; 1554fd6a1d7SAndreas Gohr } 1564fd6a1d7SAndreas Gohr 1574fd6a1d7SAndreas Gohr /** 1584fd6a1d7SAndreas Gohr * Generate the link bar HTML code 1594fd6a1d7SAndreas Gohr * 1604fd6a1d7SAndreas Gohr * @return string The HTML code 1614fd6a1d7SAndreas Gohr */ 1624fd6a1d7SAndreas Gohr public function mainLinks() 1634fd6a1d7SAndreas Gohr { 1644fd6a1d7SAndreas Gohr $html = '<div class="linkbar">'; 1654fd6a1d7SAndreas Gohr 1664fd6a1d7SAndreas Gohr 1674fd6a1d7SAndreas Gohr $homepage = $this->extension->getURL(); 1684fd6a1d7SAndreas Gohr if ($homepage) { 1694fd6a1d7SAndreas Gohr $params = $this->prepareLinkAttributes($homepage, 'homepage'); 1704fd6a1d7SAndreas Gohr $html .= ' <a ' . buildAttributes($params, true) . '>' . $this->getLang('homepage_link') . '</a>'; 1714fd6a1d7SAndreas Gohr } 1724fd6a1d7SAndreas Gohr 1734fd6a1d7SAndreas Gohr $bugtracker = $this->extension->getBugtrackerURL(); 1744fd6a1d7SAndreas Gohr if ($bugtracker) { 1754fd6a1d7SAndreas Gohr $params = $this->prepareLinkAttributes($bugtracker, 'bugs'); 1764fd6a1d7SAndreas Gohr $html .= ' <a ' . buildAttributes($params, true) . '>' . $this->getLang('bugs_features') . '</a>'; 1774fd6a1d7SAndreas Gohr } 1784fd6a1d7SAndreas Gohr 1794fd6a1d7SAndreas Gohr if ($this->extension->getDonationURL()) { 1804fd6a1d7SAndreas Gohr $params = $this->prepareLinkAttributes($this->extension->getDonationURL(), 'donate'); 1814fd6a1d7SAndreas Gohr $html .= ' <a ' . buildAttributes($params, true) . '>' . $this->getLang('donate_action') . '</a>'; 1824fd6a1d7SAndreas Gohr } 1834fd6a1d7SAndreas Gohr 1844fd6a1d7SAndreas Gohr 1854fd6a1d7SAndreas Gohr $html .= '</div>'; 1864fd6a1d7SAndreas Gohr 1874fd6a1d7SAndreas Gohr return $html; 1884fd6a1d7SAndreas Gohr } 1894fd6a1d7SAndreas Gohr 1904fd6a1d7SAndreas Gohr /** 1914fd6a1d7SAndreas Gohr * Create the details section 1924fd6a1d7SAndreas Gohr * 1934fd6a1d7SAndreas Gohr * @return string 1944fd6a1d7SAndreas Gohr */ 1954fd6a1d7SAndreas Gohr protected function details() 1964fd6a1d7SAndreas Gohr { 1974fd6a1d7SAndreas Gohr $html = '<details>'; 198981e70caSAndreas Gohr $html .= '<summary>' . $this->getLang('details') . '</summary>'; 1994fd6a1d7SAndreas Gohr 2004fd6a1d7SAndreas Gohr 2014fd6a1d7SAndreas Gohr $default = $this->getLang('unknown'); 2024fd6a1d7SAndreas Gohr $list = []; 2034fd6a1d7SAndreas Gohr 2044fd6a1d7SAndreas Gohr if (!$this->extension->isBundled()) { 2054fd6a1d7SAndreas Gohr $list['downloadurl'] = $this->shortlink($this->extension->getDownloadURL(), 'download', $default); 2064fd6a1d7SAndreas Gohr $list['repository'] = $this->shortlink($this->extension->getSourcerepoURL(), 'repo', $default); 2074fd6a1d7SAndreas Gohr } 2084fd6a1d7SAndreas Gohr 2094fd6a1d7SAndreas Gohr if ($this->extension->isInstalled()) { 2104fd6a1d7SAndreas Gohr if ($this->extension->isBundled()) { 2114fd6a1d7SAndreas Gohr $list['installed_version'] = $this->getLang('status_bundled'); 2124fd6a1d7SAndreas Gohr } else { 2134fd6a1d7SAndreas Gohr if ($this->extension->getInstalledVersion()) { 2144fd6a1d7SAndreas Gohr $list['installed_version'] = hsc($this->extension->getInstalledVersion()); 2154fd6a1d7SAndreas Gohr } 2164fd6a1d7SAndreas Gohr if (!$this->extension->isBundled()) { 2174fd6a1d7SAndreas Gohr $updateDate = $this->extension->getManager()->getLastUpdate(); 2184fd6a1d7SAndreas Gohr $list['install_date'] = $updateDate ? hsc($updateDate) : $default; 2194fd6a1d7SAndreas Gohr } 2204fd6a1d7SAndreas Gohr } 2214fd6a1d7SAndreas Gohr } 2224fd6a1d7SAndreas Gohr 2234fd6a1d7SAndreas Gohr if (!$this->extension->isInstalled() || $this->extension->isUpdateAvailable()) { 2244fd6a1d7SAndreas Gohr $list['available_version'] = $this->extension->getLastUpdate() 2254fd6a1d7SAndreas Gohr ? hsc($this->extension->getLastUpdate()) 2264fd6a1d7SAndreas Gohr : $default; 2274fd6a1d7SAndreas Gohr } 2284fd6a1d7SAndreas Gohr 2294fd6a1d7SAndreas Gohr 2304fd6a1d7SAndreas Gohr if (!$this->extension->isBundled() && $this->extension->getCompatibleVersions()) { 2314fd6a1d7SAndreas Gohr $list['compatible'] = join(', ', array_map( 2324fd6a1d7SAndreas Gohr function ($date, $version) { 2334fd6a1d7SAndreas Gohr return '<bdi>' . $version['label'] . ' (' . $date . ')</bdi>'; 2344fd6a1d7SAndreas Gohr }, 2354fd6a1d7SAndreas Gohr array_keys($this->extension->getCompatibleVersions()), 2364fd6a1d7SAndreas Gohr array_values($this->extension->getCompatibleVersions()) 2374fd6a1d7SAndreas Gohr )); 2384fd6a1d7SAndreas Gohr } 2394fd6a1d7SAndreas Gohr 2404fd6a1d7SAndreas Gohr $tags = $this->extension->getTags(); 2414fd6a1d7SAndreas Gohr if ($tags) { 2424fd6a1d7SAndreas Gohr $list['tags'] = join(', ', array_map(function ($tag) { 2434fd6a1d7SAndreas Gohr $url = $this->tabURL('search', ['q' => 'tag:' . $tag]); 2444fd6a1d7SAndreas Gohr return '<bdi><a href="' . $url . '">' . hsc($tag) . '</a></bdi>'; 2454fd6a1d7SAndreas Gohr }, $tags)); 2464fd6a1d7SAndreas Gohr } 2474fd6a1d7SAndreas Gohr 2484fd6a1d7SAndreas Gohr if ($this->extension->getDependencyList()) { 2494fd6a1d7SAndreas Gohr $list['depends'] = $this->linkExtensions($this->extension->getDependencyList()); 2504fd6a1d7SAndreas Gohr } 2514fd6a1d7SAndreas Gohr 2524fd6a1d7SAndreas Gohr if ($this->extension->getSimilarList()) { 2534fd6a1d7SAndreas Gohr $list['similar'] = $this->linkExtensions($this->extension->getSimilarList()); 2544fd6a1d7SAndreas Gohr } 2554fd6a1d7SAndreas Gohr 2564fd6a1d7SAndreas Gohr if ($this->extension->getConflictList()) { 2574fd6a1d7SAndreas Gohr $list['conflicts'] = $this->linkExtensions($this->extension->getConflictList()); 2584fd6a1d7SAndreas Gohr } 2594fd6a1d7SAndreas Gohr 26020db0ca9SAndreas Gohr $html .= '<dl>'; 2614fd6a1d7SAndreas Gohr foreach ($list as $key => $value) { 2624fd6a1d7SAndreas Gohr $html .= '<dt>' . $this->getLang($key) . '</dt>'; 2634fd6a1d7SAndreas Gohr $html .= '<dd>' . $value . '</dd>'; 2644fd6a1d7SAndreas Gohr } 26520db0ca9SAndreas Gohr $html .= '</dl>'; 2664fd6a1d7SAndreas Gohr 2674fd6a1d7SAndreas Gohr $html .= '</details>'; 2684fd6a1d7SAndreas Gohr return $html; 2694fd6a1d7SAndreas Gohr } 2704fd6a1d7SAndreas Gohr 2714fd6a1d7SAndreas Gohr /** 2724fd6a1d7SAndreas Gohr * Generate a link to the author of the extension 2734fd6a1d7SAndreas Gohr * 2744fd6a1d7SAndreas Gohr * @return string The HTML code of the link 2754fd6a1d7SAndreas Gohr */ 2764fd6a1d7SAndreas Gohr protected function author() 2774fd6a1d7SAndreas Gohr { 2784fd6a1d7SAndreas Gohr if (!$this->extension->getAuthor()) { 2794fd6a1d7SAndreas Gohr return '<em class="author">' . $this->getLang('unknown_author') . '</em>'; 2804fd6a1d7SAndreas Gohr } 2814fd6a1d7SAndreas Gohr 282981e70caSAndreas Gohr $names = explode(',', $this->extension->getAuthor()); 283981e70caSAndreas Gohr $names = array_map('trim', $names); 284981e70caSAndreas Gohr if (count($names) > 2) { 285981e70caSAndreas Gohr $names = array_slice($names, 0, 2); 286981e70caSAndreas Gohr $names[] = '…'; 287981e70caSAndreas Gohr } 288981e70caSAndreas Gohr $name = join(', ', $names); 289981e70caSAndreas Gohr 2904fd6a1d7SAndreas Gohr $mailid = $this->extension->getEmailID(); 2914fd6a1d7SAndreas Gohr if ($mailid) { 2924fd6a1d7SAndreas Gohr $url = $this->tabURL('search', ['q' => 'authorid:' . $mailid]); 2934fd6a1d7SAndreas Gohr $html = '<a href="' . $url . '" class="author" title="' . $this->getLang('author_hint') . '" >' . 2944fd6a1d7SAndreas Gohr '<img src="//www.gravatar.com/avatar/' . $mailid . 2954fd6a1d7SAndreas Gohr '?s=60&d=mm" width="20" height="20" alt="" /> ' . 296981e70caSAndreas Gohr hsc($name) . '</a>'; 2974fd6a1d7SAndreas Gohr } else { 2984fd6a1d7SAndreas Gohr $html = '<span class="author">' . hsc($this->extension->getAuthor()) . '</span>'; 2994fd6a1d7SAndreas Gohr } 3004fd6a1d7SAndreas Gohr return '<bdi>' . $html . '</bdi>'; 3014fd6a1d7SAndreas Gohr } 3024fd6a1d7SAndreas Gohr 3034fd6a1d7SAndreas Gohr /** 3044fd6a1d7SAndreas Gohr * The popularity bar 3054fd6a1d7SAndreas Gohr * 3064fd6a1d7SAndreas Gohr * @return string 3074fd6a1d7SAndreas Gohr */ 3084fd6a1d7SAndreas Gohr protected function popularity() 3094fd6a1d7SAndreas Gohr { 3104fd6a1d7SAndreas Gohr $popularity = $this->extension->getPopularity(); 3114fd6a1d7SAndreas Gohr if (!$popularity) return ''; 3124fd6a1d7SAndreas Gohr if ($this->extension->isBundled()) return ''; 3134fd6a1d7SAndreas Gohr 314981e70caSAndreas Gohr if ($popularity > 0.25) { 315981e70caSAndreas Gohr $title = $this->getLang('popularity_high'); 316981e70caSAndreas Gohr $emoji = ''; 317981e70caSAndreas Gohr } else if ($popularity > 0.15) { 318981e70caSAndreas Gohr $title = $this->getLang('popularity_medium'); 319981e70caSAndreas Gohr $emoji = ''; 320981e70caSAndreas Gohr } else if ($popularity > 0.05) { 321981e70caSAndreas Gohr $title = $this->getLang('popularity_low'); 322981e70caSAndreas Gohr $emoji = ''; 323981e70caSAndreas Gohr } else { 324981e70caSAndreas Gohr return ''; 325981e70caSAndreas Gohr } 326981e70caSAndreas Gohr $title .= ' (' . round($popularity * 100) . '%)'; 327981e70caSAndreas Gohr 328981e70caSAndreas Gohr return '<span class="popularity" title="' . $title . '">' . $emoji . '</span>'; 3294fd6a1d7SAndreas Gohr 3304fd6a1d7SAndreas Gohr } 3314fd6a1d7SAndreas Gohr 332*5732c960SAndreas Gohr /** 333*5732c960SAndreas Gohr * Generate the action buttons 334*5732c960SAndreas Gohr * 335*5732c960SAndreas Gohr * @return string 336*5732c960SAndreas Gohr */ 3374fd6a1d7SAndreas Gohr protected function actions() 3384fd6a1d7SAndreas Gohr { 3394fd6a1d7SAndreas Gohr $html = ''; 3404fd6a1d7SAndreas Gohr $actions = []; 3414fd6a1d7SAndreas Gohr 342*5732c960SAndreas Gohr // check permissions 3434fd6a1d7SAndreas Gohr try { 3444fd6a1d7SAndreas Gohr Installer::ensurePermissions($this->extension); 345*5732c960SAndreas Gohr } catch (\Exception $e) { 346*5732c960SAndreas Gohr return ''; 347*5732c960SAndreas Gohr } 3484fd6a1d7SAndreas Gohr 349*5732c960SAndreas Gohr // gather available actions 3504fd6a1d7SAndreas Gohr if ($this->extension->isInstalled()) { 3514fd6a1d7SAndreas Gohr if (!$this->extension->isProtected()) $actions[] = 'uninstall'; 3524fd6a1d7SAndreas Gohr if ($this->extension->getDownloadURL()) { 3534fd6a1d7SAndreas Gohr $actions[] = $this->extension->isUpdateAvailable() ? 'update' : 'reinstall'; 3544fd6a1d7SAndreas Gohr } 3554fd6a1d7SAndreas Gohr 3564fd6a1d7SAndreas Gohr if (!$this->extension->isProtected() && !$this->extension->isTemplate()) { // no enable/disable for templates 3574fd6a1d7SAndreas Gohr $actions[] = $this->extension->isEnabled() ? 'disable' : 'enable'; 3584fd6a1d7SAndreas Gohr } 3594fd6a1d7SAndreas Gohr } else { 3604fd6a1d7SAndreas Gohr if ($this->extension->getDownloadURL()) { 3614fd6a1d7SAndreas Gohr $actions[] = 'install'; 3624fd6a1d7SAndreas Gohr } 3634fd6a1d7SAndreas Gohr } 3644fd6a1d7SAndreas Gohr 365*5732c960SAndreas Gohr // output the buttons 3664fd6a1d7SAndreas Gohr foreach ($actions as $action) { 367*5732c960SAndreas Gohr $attr = [ 368*5732c960SAndreas Gohr 'class' => 'button ' . $action, 369*5732c960SAndreas Gohr 'type' => 'submit', 370*5732c960SAndreas Gohr 'name' => 'fn[' . $action . '][' . $this->extension->getID() . ']', 371*5732c960SAndreas Gohr ]; 372*5732c960SAndreas Gohr $html .= '<button ' . buildAttributes($attr) . '>' . $this->getLang('btn_' . $action) . '</button>'; 3734fd6a1d7SAndreas Gohr } 3744fd6a1d7SAndreas Gohr 3754fd6a1d7SAndreas Gohr return $html; 3764fd6a1d7SAndreas Gohr } 3774fd6a1d7SAndreas Gohr 3784fd6a1d7SAndreas Gohr 3794fd6a1d7SAndreas Gohr // endregion 3804fd6a1d7SAndreas Gohr // region utility functions 3814fd6a1d7SAndreas Gohr 3824fd6a1d7SAndreas Gohr /** 3834fd6a1d7SAndreas Gohr * Create the classes representing the state of the extension 3844fd6a1d7SAndreas Gohr * 3854fd6a1d7SAndreas Gohr * @return string 3864fd6a1d7SAndreas Gohr */ 3874fd6a1d7SAndreas Gohr protected function getClasses() 3884fd6a1d7SAndreas Gohr { 3894fd6a1d7SAndreas Gohr $classes = ['extension', $this->extension->getType()]; 3904fd6a1d7SAndreas Gohr if ($this->extension->isInstalled()) $classes[] = 'installed'; 3914fd6a1d7SAndreas Gohr if ($this->extension->isUpdateAvailable()) $classes[] = 'update'; 3924fd6a1d7SAndreas Gohr $classes[] = $this->extension->isEnabled() ? 'enabled' : 'disabled'; 3934fd6a1d7SAndreas Gohr return implode(' ', $classes); 3944fd6a1d7SAndreas Gohr } 3954fd6a1d7SAndreas Gohr 3964fd6a1d7SAndreas Gohr /** 3974fd6a1d7SAndreas Gohr * Create an attributes array for a link 3984fd6a1d7SAndreas Gohr * 3994fd6a1d7SAndreas Gohr * Handles interwiki links to dokuwiki.org 4004fd6a1d7SAndreas Gohr * 4014fd6a1d7SAndreas Gohr * @param string $url The URL to link to 4024fd6a1d7SAndreas Gohr * @param string $class Additional classes to add 4034fd6a1d7SAndreas Gohr * @return array 4044fd6a1d7SAndreas Gohr */ 4054fd6a1d7SAndreas Gohr protected function prepareLinkAttributes($url, $class) 4064fd6a1d7SAndreas Gohr { 4074fd6a1d7SAndreas Gohr global $conf; 4084fd6a1d7SAndreas Gohr 4094fd6a1d7SAndreas Gohr $attributes = [ 4104fd6a1d7SAndreas Gohr 'href' => $url, 4114fd6a1d7SAndreas Gohr 'class' => 'urlextern', 4124fd6a1d7SAndreas Gohr 'target' => $conf['target']['extern'], 4134fd6a1d7SAndreas Gohr 'rel' => 'noopener', 4144fd6a1d7SAndreas Gohr 'title' => $url, 4154fd6a1d7SAndreas Gohr ]; 4164fd6a1d7SAndreas Gohr 4174fd6a1d7SAndreas Gohr if ($conf['relnofollow']) { 4184fd6a1d7SAndreas Gohr $attributes['rel'] .= ' ugc nofollow'; 4194fd6a1d7SAndreas Gohr } 4204fd6a1d7SAndreas Gohr 4214fd6a1d7SAndreas Gohr if (preg_match('/^https?:\/\/(www\.)?dokuwiki\.org\//i', $url)) { 4224fd6a1d7SAndreas Gohr $attributes['class'] = 'interwiki iw_doku'; 4234fd6a1d7SAndreas Gohr $attributes['target'] = $conf['target']['interwiki']; 4244fd6a1d7SAndreas Gohr $attributes['rel'] = ''; 4254fd6a1d7SAndreas Gohr } 4264fd6a1d7SAndreas Gohr 4274fd6a1d7SAndreas Gohr $attributes['class'] .= ' ' . $class; 4284fd6a1d7SAndreas Gohr return $attributes; 4294fd6a1d7SAndreas Gohr } 4304fd6a1d7SAndreas Gohr 4314fd6a1d7SAndreas Gohr /** 4324fd6a1d7SAndreas Gohr * Create a link from the given URL 4334fd6a1d7SAndreas Gohr * 4344fd6a1d7SAndreas Gohr * Shortens the URL for display 4354fd6a1d7SAndreas Gohr * 4364fd6a1d7SAndreas Gohr * @param string $url 4374fd6a1d7SAndreas Gohr * @param string $class Additional classes to add 43800929f2eSAndreas Gohr * @param string $fallback If URL is empty return this fallback (raw HTML) 4394fd6a1d7SAndreas Gohr * @return string HTML link 4404fd6a1d7SAndreas Gohr */ 4414fd6a1d7SAndreas Gohr protected function shortlink($url, $class, $fallback = '') 4424fd6a1d7SAndreas Gohr { 44300929f2eSAndreas Gohr if (!$url) return $fallback; 4444fd6a1d7SAndreas Gohr 4454fd6a1d7SAndreas Gohr $link = parse_url($url); 4464fd6a1d7SAndreas Gohr $base = $link['host']; 4474fd6a1d7SAndreas Gohr if (!empty($link['port'])) $base .= $base . ':' . $link['port']; 4484fd6a1d7SAndreas Gohr $long = $link['path']; 4494fd6a1d7SAndreas Gohr if (!empty($link['query'])) $long .= $link['query']; 4504fd6a1d7SAndreas Gohr 4514fd6a1d7SAndreas Gohr $name = shorten($base, $long, 55); 4524fd6a1d7SAndreas Gohr 4534fd6a1d7SAndreas Gohr $params = $this->prepareLinkAttributes($url, $class); 4544fd6a1d7SAndreas Gohr $html = '<a ' . buildAttributes($params, true) . '>' . hsc($name) . '</a>'; 4554fd6a1d7SAndreas Gohr return $html; 4564fd6a1d7SAndreas Gohr } 4574fd6a1d7SAndreas Gohr 4584fd6a1d7SAndreas Gohr /** 4594fd6a1d7SAndreas Gohr * Generate a list of links for extensions 4604fd6a1d7SAndreas Gohr * 4614fd6a1d7SAndreas Gohr * Links to the search tab with the extension name 4624fd6a1d7SAndreas Gohr * 4634fd6a1d7SAndreas Gohr * @param array $extensions The extension names 4644fd6a1d7SAndreas Gohr * @return string The HTML code 4654fd6a1d7SAndreas Gohr */ 4664fd6a1d7SAndreas Gohr public function linkExtensions($extensions) 4674fd6a1d7SAndreas Gohr { 4684fd6a1d7SAndreas Gohr $html = ''; 4694fd6a1d7SAndreas Gohr foreach ($extensions as $link) { 4704fd6a1d7SAndreas Gohr $html .= '<bdi><a href="' . 4714fd6a1d7SAndreas Gohr $this->tabURL('search', ['q' => 'ext:' . $link]) . '">' . 4724fd6a1d7SAndreas Gohr hsc($link) . '</a></bdi>, '; 4734fd6a1d7SAndreas Gohr } 4744fd6a1d7SAndreas Gohr return rtrim($html, ', '); 4754fd6a1d7SAndreas Gohr } 4764fd6a1d7SAndreas Gohr 4774fd6a1d7SAndreas Gohr // endregion 4784fd6a1d7SAndreas Gohr} 479