1<?php 2/** 3 * Plugin nspages : Displays nicely a list of the pages of a namespace 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 */ 7if(!defined('DOKU_INC')) die(); 8require_once 'filePreparer.php'; 9 10class pagePreparer extends filePreparer { 11 12 private $customTitle; 13 private $customTitleAllowListMetadata; 14 private $sortByMetadata; 15 16 /** 17 * Boolean Whether the page being rendered should be exluded 18 */ 19 private $excludeSelfPage; 20 21 function __construct($excludedNs, $excludedFiles, $pregOn, $pregOff, $pregTitleOn, $pregTitleOff, $useTitle, 22 $sortPageById, $useIdAndTitle, $sortPageByDate, $sortByCreationDate, $customTitle, 23 $customTitleAllowListMetadata, $sortByMetadata, $excludeSelfPage) { 24 parent::__construct($excludedFiles, $pregOn, $pregOff, $pregTitleOn, $pregTitleOff, $useTitle, $sortPageById, 25 $useIdAndTitle, $sortPageByDate, $sortByCreationDate, $excludeSelfPage); 26 27 $this->excludedNs = $excludedNs; 28 $this->customTitle = $customTitle; 29 $this->customTitleAllowListMetadata = $customTitleAllowListMetadata; 30 $this->sortByMetadata = $sortByMetadata; 31 $this->excludeSelfPage = $excludeSelfPage; 32 } 33 34 function isFileWanted($file, $useTitle){ 35 global $ID; 36 return ($file['type'] != 'd') 37 && parent::isFileWanted($file, $useTitle) 38 && $this->passSubNsfilterInRecursiveMode($file) 39 && (!$this->excludeSelfPage || $ID !== $file['id']); 40 } 41 42 function prepareFileTitle(&$file){ 43 // Nothing to do: for pages the title is already set 44 } 45 46 private function passSubNsfilterInRecursiveMode($file){ 47 $subNss = explode(':', $file['id']); 48 if ( count($subNss) < 2 ){ //It means we're not in recursive mode 49 return true; 50 } 51 for ($i = 0; $i < count($subNss) - 1; $i++) { 52 if (in_array($subNss[$i], $this->excludedNs)) { 53 return false; 54 } 55 } 56 return true; 57 } 58 59 function prepareFile(&$page){ 60 $page['nameToDisplay'] = $this->buildNameToDisplay($page); 61 $page['sort'] = $this->buildSortAttribute($page['nameToDisplay'], $page['id'], $page['mtime']); 62 } 63 64 /** 65 * Get the a metadata value from a certain path. 66 * 67 * @param $metadata - The metadata object of a page. More details on https://www.dokuwiki.org/devel:metadata 68 * @param $path - The path. 69 * Examples: 70 * date.created 71 * contributor.0 72 * 73 * @return mixed - The metadata value from a certain path. 74 */ 75 76 private function getMetadataFromPath($metadata, $path) { 77 return array_reduce( 78 explode('.', $path), 79 function ($object, $property) { 80 return is_numeric($property) ? $object[$property] : $object[$property]; 81 }, 82 $metadata 83 ); 84 } 85 86 private function isPathInMetadataAllowList($path) { 87 $metadataAllowList = explode(',', preg_replace('/\s+/', '', $this->customTitleAllowListMetadata)); 88 return in_array($path, $metadataAllowList); 89 } 90 91 /** 92 * Get the page custom title from a template. 93 * 94 * @param $customTitle - The custom tile template. 95 * Examples: 96 * {title} ({data.created} by {user}) 97 * @param $metadata - The metadata object of a page. More details on https://www.dokuwiki.org/devel:metadata 98 * 99 * @return string - the custom title 100 */ 101 102 private function getCustomTitleFromTemplate($customTitle, $metadata) { 103 return preg_replace_callback( 104 '/{(.*?)}/', 105 function ($matches) use($metadata) { 106 $path = $matches[1]; 107 if ($this->isPathInMetadataAllowList($path)) { 108 return $this->getMetadataFromPath($metadata, $path); 109 } else { 110 return $path; 111 } 112 }, 113 $customTitle 114 ); 115 } 116 117 private function buildNameToDisplay($page){ 118 $title = $page['title']; 119 $pageId = $page['id']; 120 121 122 if ($this->customTitle !== null) { 123 $meta = p_get_metadata($pageId); 124 return $this->getCustomTitleFromTemplate($this->customTitle, $meta); 125 } 126 127 if($this->useIdAndTitle && $title !== null ){ 128 return noNS($pageId) . " - " . $title; 129 } 130 131 if(!$this->useTitle || $title === null) { 132 return noNS($pageId); 133 } 134 return $title; 135 } 136 137 private function buildSortAttribute($nameToDisplay, $pageId, $mtime){ 138 if ($this->sortByMetadata !== null) { 139 $meta = p_get_metadata($pageId); 140 return $this->getMetadataFromPath($meta, $this->sortByMetadata); 141 } else if($this->sortPageById) { 142 return noNS($pageId); 143 } else if ( $this->sortPageByDate) { 144 return $mtime; 145 } else if ($this->sortByCreationDate) { 146 $meta = p_get_metadata($pageId); 147 return $meta['date']['created']; 148 } else { 149 return $nameToDisplay; 150 } 151 152 } 153} 154