Lexer->addSpecialPattern('\{\{images>.+?\}\}', $mode, 'plugin_luxtools_images'); } /** @inheritdoc */ public function handle($match, $state, $pos, Doku_Handler $handler) { global $INPUT; // do not allow the syntax in discussion plugin comments if (!$this->getConf('allow_in_comments') && $INPUT->has('comment')) { return false; } $match = substr($match, strlen('{{images>'), -2); [$path, $flags] = explode('&', $match, 2); // load default config options $flags = $this->getConf('defaults') . '&' . $flags; $flags = explode('&', $flags); $params = [ 'sort' => 'name', 'order' => 'asc', 'recursive' => 0, 'titlefile' => '_title.txt', 'cache' => 0, 'randlinks' => 0, ]; foreach ($flags as $flag) { [$name, $value] = sexplode('=', $flag, 2, ''); $params[trim($name)] = trim(trim($value), '"'); // quotes can be use to keep whitespace } // separate path and pattern $path = Path::cleanPath($path, false); $parts = explode('/', $path); $pattern = array_pop($parts); $base = implode('/', $parts) . '/'; return [$base, $pattern, $params]; } /** * Create output */ public function render($format, Doku_Renderer $renderer, $data) { [$base, $pattern, $params] = $data; if ($format != 'xhtml' && $format != 'odt') { return false; } // disable caching if ($params['cache'] === 0) { $renderer->nocache(); } try { $pathHelper = new Path($this->getConf('paths')); $pathInfo = $pathHelper->getPathInfo($base); } catch (Exception $e) { $renderer->cdata('[n/a: ' . $this->getLang('error_outsidejail') . ']'); return true; } $crawler = new Crawler($this->getConf('extensions')); $crawler->setSortBy($params['sort']); $crawler->setSortReverse($params['order'] === 'desc'); $result = $crawler->crawl( $pathInfo['root'], $pathInfo['local'], $pattern, $params['recursive'], $params['titlefile'] ); $items = $this->flattenResultTree($result); $items = $this->filterImages($items); // if we got nothing back, display a message if ($items == []) { $renderer->cdata('[n/a: ' . $this->getLang('error_nomatch') . ']'); return true; } $output = new Output($renderer, $pathInfo['root'], $pathInfo['web'], $items); if ($format == 'xhtml') { $output->renderAsGallery($params); return true; } // Fallback for non-XHTML formats: render as a list of links $params['style'] = 'list'; $params['showsize'] = 0; $params['showdate'] = 0; $params['listsep'] = ', '; $output->renderAsList($params); return true; } /** * Flattens the crawl result tree into a list of file items. * * @param array $items * @param string $prefix * @return array */ protected function flattenResultTree($items, $prefix = '') { $result = []; foreach ($items as $file) { if ($file['children'] !== false) { $result = array_merge( $result, $this->flattenResultTree($file['children'], $prefix . $file['name'] . '/') ); } else { $file['name'] = $prefix . $file['name']; $result[] = $file; } } return $result; } /** * Keep only image files. * * @param array $items * @return array */ protected function filterImages($items) { $images = []; foreach ($items as $item) { if (!isset($item['path']) || !is_string($item['path'])) continue; if (!is_file($item['path'])) continue; try { [, $mime,] = mimetype($item['path'], false); } catch (Throwable $e) { continue; } if (is_string($mime) && str_starts_with($mime, 'image/')) { $images[] = $item; } } return $images; } }