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 */ 7 8if(!defined('DOKU_INC')) die(); 9require_once 'printer.php'; 10require_once 'rendererXhtmlHelper.php'; 11 12class nspages_printerNice extends nspages_printer { 13 private $nbCols; 14 private $anchorName; 15 16 function __construct($plugin, $mode, $renderer, $nbCols, $anchorName, $data){ 17 parent::__construct($plugin, $mode, $renderer, $data); 18 if ( $this->mode !== 'xhtml' ){ 19 throw Exception('nspages_printerNice can only work in xhtml mode'); 20 } 21 $this->nbCols = $this->_computeActualNbCols($nbCols); 22 $this->anchorName = $anchorName; 23 } 24 25 private function _computeActualNbCols($nbCols){ 26 $nbCols = (int) $nbCols; 27 if(!isset($nbCols) || is_null($nbCols) || $nbCols < 1) { 28 $nbCols = 3; 29 } 30 return $nbCols; 31 } 32 33 function _print($tab, $type) { 34 $nbItemsPrinted = 0; 35 36 $nbItemPerColumns = $this->_computeNbItemPerColumns(sizeof($tab)); 37 $actualNbCols = count($nbItemPerColumns); 38 $helper = new rendererXhtmlHelper($this->renderer, $actualNbCols, $this->plugin, $this->anchorName); 39 40 $helper->openColumn(); 41 $firstCharOfLastAddedPage = $this->_firstChar($tab[0]); 42 43 $helper->printHeaderChar($firstCharOfLastAddedPage); 44 $helper->openListOfItems(); 45 46 $idxCol = 0; 47 foreach($tab as $item) { 48 //change to the next column if necessary 49 if($nbItemsPrinted == $nbItemPerColumns[$idxCol]) { 50 $idxCol++; 51 $helper->closeListOfItems(); 52 $helper->closeColumn(); 53 $helper->openColumn(); 54 55 $newLetter = $this->_firstChar($item); 56 if($newLetter != $firstCharOfLastAddedPage) { 57 $firstCharOfLastAddedPage = $newLetter; 58 $helper->printHeaderChar($firstCharOfLastAddedPage); 59 } else { 60 $helper->printHeaderChar($firstCharOfLastAddedPage, true); 61 } 62 $helper->openListOfItems(); 63 } 64 65 $newLetter = $this->_firstChar($item); 66 if($newLetter != $firstCharOfLastAddedPage) { 67 $firstCharOfLastAddedPage = $newLetter; 68 $helper->closeListOfItems(); 69 $helper->printHeaderChar($firstCharOfLastAddedPage); 70 $helper->openListOfItems(); 71 } 72 73 $this->_printElement($item); 74 $nbItemsPrinted++; 75 } 76 $helper->closeListOfItems(); 77 $helper->closeColumn(); 78 } 79 80 private function _firstChar($item) { 81 $return_char = utf8_strtoupper(utf8_substr($item['sort'], 0, 1)); 82 $uniord_char = $this->_uniord($return_char); 83 84 // korean support. See #111 for more context 85 if ($uniord_char > 44031 && $uniord_char < 55204) { 86 $return_char = ['ㄱ','ㄱ','ㄴ','ㄷ','ㄷ','ㄹ','ㅁ','ㅂ','ㅂ','ㅅ','ㅅ','ㅇ','ㅈ','ㅈ','ㅊ','ㅋ','ㅌ','ㅍ','ㅎ'][($uniord_char-44032)/588]; 87 } 88 89 return $return_char; 90 } 91 92 /** 93 * This code is from: 94 * https://stackoverflow.com/questions/9361303/ 95 */ 96 private function _uniord($c) { 97 if (ord($c[0]) >=0 && ord($c[0]) <= 127) 98 return ord($c[0]); 99 if (ord($c[0]) >= 192 && ord($c[0]) <= 223) 100 return (ord($c[0])-192)*64 + (ord($c[1])-128); 101 if (ord($c[0]) >= 224 && ord($c[0]) <= 239) 102 return (ord($c[0])-224)*4096 + (ord($c[1])-128)*64 + (ord($c[2])-128); 103 if (ord($c[0]) >= 240 && ord($c[0]) <= 247) 104 return (ord($c[0])-240)*262144 + (ord($c[1])-128)*4096 + (ord($c[2])-128)*64 + (ord($c[3])-128); 105 if (ord($c[0]) >= 248 && ord($c[0]) <= 251) 106 return (ord($c[0])-248)*16777216 + (ord($c[1])-128)*262144 + (ord($c[2])-128)*4096 + (ord($c[3])-128)*64 + (ord($c[4])-128); 107 if (ord($c[0]) >= 252 && ord($c[0]) <= 253) 108 return (ord($c[0])-252)*1073741824 + (ord($c[1])-128)*16777216 + (ord($c[2])-128)*262144 + (ord($c[3])-128)*4096 + (ord($c[4])-128)*64 + (ord($c[5])-128); 109 if (ord($c[0]) >= 254 && ord($c[0]) <= 255) 110 return false; 111 return false; 112 } 113 114 /** 115 * Compute the number of element to display per column 116 * When $nbItems / $nbCols isn't an int, we make sure, for aesthetic reasons, 117 * that the first are the ones which have the more items 118 * Moreover, if we don't have enought items to display, we may choose to display less than the number of columns wanted 119 * 120 * @param int $nbItems The total number of items to display 121 * @return an array which contains $nbCols int. 122 */ 123 private function _computeNbItemPerColumns($nbItems) { 124 $result = array(); 125 126 if($nbItems < $this->nbCols) { 127 for($idx = 0; $idx < $nbItems; $idx++) { 128 $result[] = $idx + 1; 129 } 130 return $result; 131 } 132 133 $collength = $nbItems / $this->nbCols; 134 $nbItemPerCol = array(); 135 for($idx = 0; $idx < $this->nbCols; $idx++) { 136 $nbItemPerCol[] = ceil(($idx + 1) * $collength) - ceil($idx * $collength); 137 } 138 rsort($nbItemPerCol); 139 140 $result[] = $nbItemPerCol[0]; 141 for($idx = 1; $idx < $this->nbCols; $idx++) { 142 $result[] = end($result) + $nbItemPerCol[$idx]; 143 } 144 145 return $result; 146 } 147} 148