1f9f65fc3Swikidesign<?php 2f9f65fc3Swikidesign/** 3f9f65fc3Swikidesign * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 4f9f65fc3Swikidesign * @author Esther Brunner <wikidesign@gmail.com> 5dbdadbd9SGina Haeussge * @author Christopher Smith <chris@jalakai.co.uk> 6dbdadbd9SGina Haeussge * @author Gina Häußge, Michael Klier <dokuwiki@chimeric.de> 7f9f65fc3Swikidesign */ 8f9f65fc3Swikidesign 9f9f65fc3Swikidesign// must be run within Dokuwiki 10f9f65fc3Swikidesignif (!defined('DOKU_INC')) die(); 11f9f65fc3Swikidesign 12f9f65fc3Swikidesignif (!defined('DOKU_LF')) define('DOKU_LF', "\n"); 13f9f65fc3Swikidesignif (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); 14f9f65fc3Swikidesignif (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/'); 15f9f65fc3Swikidesign 16f9f65fc3Swikidesignclass helper_plugin_include extends DokuWiki_Plugin { // DokuWiki_Helper_Plugin 17f9f65fc3Swikidesign 18b6337848Swikidesign var $pages = array(); // filechain of included pages 19f9f65fc3Swikidesign var $page = array(); // associative array with data about the page to include 20f9f65fc3Swikidesign var $ins = array(); // instructions array 21f9f65fc3Swikidesign var $doc = ''; // the final output XHTML string 22f9f65fc3Swikidesign var $mode = 'section'; // inclusion mode: 'page' or 'section' 23f9f65fc3Swikidesign var $clevel = 0; // current section level 24f9f65fc3Swikidesign var $firstsec = 0; // show first section only 256c836050Swikidesign var $editbtn = 1; // show edit button 266b088758Swikidesign var $footer = 1; // show metaline below page 27990ad87fSwikidesign var $noheader = 0; // omit header 2871ec1101SGina Haeussge var $permalink = 0; // make first headline permalink to included page 2939af1bf1Swikidesign var $header = array(); // included page / section header 3039af1bf1Swikidesign var $renderer = NULL; // DokuWiki renderer object 31f9f65fc3Swikidesign 32c01ce462SGina Haeussge var $INCLUDE_LIMIT = 12; 33c01ce462SGina Haeussge 34a58d2b0aSwikidesign // private variables 35a58d2b0aSwikidesign var $_offset = NULL; 36a58d2b0aSwikidesign 3752e31fceSwikidesign /** 38656a5d08Swikidesign * Constructor loads some config settings 3952e31fceSwikidesign */ 4052e31fceSwikidesign function helper_plugin_include() { 4152e31fceSwikidesign $this->firstsec = $this->getConf('firstseconly'); 426c836050Swikidesign $this->editbtn = $this->getConf('showeditbtn'); 436b088758Swikidesign $this->footer = $this->getConf('showfooter'); 44cf0272c0Swikidesign $this->noheader = 0; 4571ec1101SGina Haeussge $this->permalink = 0; 46cf0272c0Swikidesign $this->header = array(); 4752e31fceSwikidesign } 4852e31fceSwikidesign 49f9f65fc3Swikidesign function getInfo() { 50f9f65fc3Swikidesign return array( 5171ec1101SGina Haeussge 'author' => 'Gina Häußge, Michael Klier, Esther Brunner', 52dbdadbd9SGina Haeussge 'email' => 'dokuwiki@chimeric.de', 53*4052f233SGina Haeussge 'date' => @file_get_contents(DOKU_PLUGIN . 'blog/VERSION'), 54f9f65fc3Swikidesign 'name' => 'Include Plugin (helper class)', 55f9f65fc3Swikidesign 'desc' => 'Functions to include another page in a wiki page', 561f7a99c4SMichael Klier 'url' => 'http://wiki.splitbrain.org/plugin:include', 57f9f65fc3Swikidesign ); 58f9f65fc3Swikidesign } 59f9f65fc3Swikidesign 60f9f65fc3Swikidesign function getMethods() { 61f9f65fc3Swikidesign $result = array(); 62f9f65fc3Swikidesign $result[] = array( 63f9f65fc3Swikidesign 'name' => 'setPage', 64f9f65fc3Swikidesign 'desc' => 'sets the page to include', 65f9f65fc3Swikidesign 'params' => array("page attributes, 'id' required, 'section' for filtering" => 'array'), 66f9f65fc3Swikidesign 'return' => array('success' => 'boolean'), 67f9f65fc3Swikidesign ); 68f9f65fc3Swikidesign $result[] = array( 69f9f65fc3Swikidesign 'name' => 'setMode', 70f9f65fc3Swikidesign 'desc' => 'sets inclusion mode: should indention be merged?', 71f9f65fc3Swikidesign 'params' => array("'page' (original) or 'section' (merged indention)" => 'string'), 72f9f65fc3Swikidesign ); 73f9f65fc3Swikidesign $result[] = array( 74f9f65fc3Swikidesign 'name' => 'setLevel', 75f9f65fc3Swikidesign 'desc' => 'sets the indention for the current section level', 76f9f65fc3Swikidesign 'params' => array('level: 0 to 5' => 'integer'), 77f9f65fc3Swikidesign 'return' => array('success' => 'boolean'), 78f9f65fc3Swikidesign ); 79f9f65fc3Swikidesign $result[] = array( 80656a5d08Swikidesign 'name' => 'setFlags', 816b088758Swikidesign 'desc' => 'overrides standard values for showfooter and firstseconly settings', 82656a5d08Swikidesign 'params' => array('flags' => 'array'), 83656a5d08Swikidesign ); 84656a5d08Swikidesign $result[] = array( 85b6337848Swikidesign 'name' => 'renderXHTML', 86b6337848Swikidesign 'desc' => 'renders the XHTML output of the included page', 87f9f65fc3Swikidesign 'params' => array('DokuWiki renderer' => 'object'), 88b6337848Swikidesign 'return' => array('XHTML' => 'string'), 89f9f65fc3Swikidesign ); 90f9f65fc3Swikidesign return $result; 91f9f65fc3Swikidesign } 92f9f65fc3Swikidesign 93f9f65fc3Swikidesign /** 94f9f65fc3Swikidesign * Sets the page to include if it is not already included (prevent recursion) 95990ad87fSwikidesign * and the current user is allowed to read it 96f9f65fc3Swikidesign */ 97f9f65fc3Swikidesign function setPage($page) { 98f9f65fc3Swikidesign global $ID; 99f9f65fc3Swikidesign 100b6337848Swikidesign $id = $page['id']; 101b6337848Swikidesign $fullid = $id.'#'.$page['section']; 102f9f65fc3Swikidesign 103b6337848Swikidesign if (!$id) return false; // no page id given 104b6337848Swikidesign if ($id == $ID) return false; // page can't include itself 105f9f65fc3Swikidesign 106b6337848Swikidesign // prevent include recursion 107c01ce462SGina Haeussge if ($this->_in_filechain($id,$page['section']) || (count($this->pages) >= $this->INCLUDE_LIMIT)) return false; 108b6337848Swikidesign 109990ad87fSwikidesign // we need to make sure 'perm', 'file' and 'exists' are set 110990ad87fSwikidesign if (!isset($page['perm'])) $page['perm'] = auth_quickaclcheck($page['id']); 111990ad87fSwikidesign if (!isset($page['file'])) $page['file'] = wikiFN($page['id']); 112990ad87fSwikidesign if (!isset($page['exists'])) $page['exists'] = @file_exists($page['file']); 113990ad87fSwikidesign 114990ad87fSwikidesign // check permission 115f83ac5f7Swikidesign if ($page['perm'] < AUTH_READ) return false; 116990ad87fSwikidesign 117b6337848Swikidesign // add the page to the filechain 118c01ce462SGina Haeussge $this->page = $page; 119f9f65fc3Swikidesign return true; 120f9f65fc3Swikidesign } 121f9f65fc3Swikidesign 122c01ce462SGina Haeussge function _push_page($id,$section) { 123c01ce462SGina Haeussge global $ID; 124c01ce462SGina Haeussge if (empty($this->pages)) array_push($this->pages, $ID.'#'); 125c01ce462SGina Haeussge array_push($this->pages, $id.'#'.$section); 126c01ce462SGina Haeussge } 127c01ce462SGina Haeussge 128c01ce462SGina Haeussge function _pop_page() { 129c01ce462SGina Haeussge $page = array_pop($this->pages); 130c01ce462SGina Haeussge if (count($this->pages=1)) $this->pages = array(); 131c01ce462SGina Haeussge 132c01ce462SGina Haeussge return $page; 133c01ce462SGina Haeussge } 134c01ce462SGina Haeussge 135c01ce462SGina Haeussge function _in_filechain($id,$section) { 136c01ce462SGina Haeussge $pattern = $section ? "/^($id#$section|$id#)$/" : "/^$id#/"; 137c01ce462SGina Haeussge $match = preg_grep($pattern, $this->pages); 138c01ce462SGina Haeussge 139c01ce462SGina Haeussge return (!empty($match)); 140c01ce462SGina Haeussge } 141c01ce462SGina Haeussge 142f9f65fc3Swikidesign /** 143a3a7e530Swikidesign * Sets the inclusion mode: 'page' or 'section' 144f9f65fc3Swikidesign */ 145f9f65fc3Swikidesign function setMode($mode) { 146f9f65fc3Swikidesign $this->mode = $mode; 147f9f65fc3Swikidesign } 148f9f65fc3Swikidesign 149f9f65fc3Swikidesign /** 150f9f65fc3Swikidesign * Sets the right indention for a given section level 151f9f65fc3Swikidesign */ 152f9f65fc3Swikidesign function setLevel($level) { 153f9f65fc3Swikidesign if ((is_numeric($level)) && ($level >= 0) && ($level <= 5)) { 154f9f65fc3Swikidesign $this->clevel = $level; 155f9f65fc3Swikidesign return true; 156f9f65fc3Swikidesign } 157f9f65fc3Swikidesign return false; 158f9f65fc3Swikidesign } 159f9f65fc3Swikidesign 160f9f65fc3Swikidesign /** 1616b088758Swikidesign * Overrides standard values for showfooter and firstseconly settings 162656a5d08Swikidesign */ 163656a5d08Swikidesign function setFlags($flags) { 164656a5d08Swikidesign foreach ($flags as $flag) { 165656a5d08Swikidesign switch ($flag) { 1666b088758Swikidesign case 'footer': 1676b088758Swikidesign $this->footer = 1; 168656a5d08Swikidesign break; 1696b088758Swikidesign case 'nofooter': 1706b088758Swikidesign $this->footer = 0; 171656a5d08Swikidesign break; 172656a5d08Swikidesign case 'firstseconly': 17343dcb6deSwikidesign case 'firstsectiononly': 174656a5d08Swikidesign $this->firstsec = 1; 175656a5d08Swikidesign break; 176656a5d08Swikidesign case 'fullpage': 177656a5d08Swikidesign $this->firstsec = 0; 178656a5d08Swikidesign break; 179990ad87fSwikidesign case 'noheader': 180990ad87fSwikidesign $this->noheader = 1; 181990ad87fSwikidesign break; 18243dcb6deSwikidesign case 'editbtn': 183a3a7e530Swikidesign case 'editbutton': 1846c836050Swikidesign $this->editbtn = 1; 1856c836050Swikidesign break; 18643dcb6deSwikidesign case 'noeditbtn': 187a3a7e530Swikidesign case 'noeditbutton': 1886c836050Swikidesign $this->editbtn = 0; 1896c836050Swikidesign break; 19071ec1101SGina Haeussge case 'permalink': 19171ec1101SGina Haeussge $this->permalink = 1; 19271ec1101SGina Haeussge break; 19371ec1101SGina Haeussge case 'nopermalink': 19471ec1101SGina Haeussge $this->permalink = 0; 19571ec1101SGina Haeussge break; 196656a5d08Swikidesign } 197656a5d08Swikidesign } 198656a5d08Swikidesign } 199656a5d08Swikidesign 200656a5d08Swikidesign /** 201f9f65fc3Swikidesign * Builds the XHTML to embed the page to include 202f9f65fc3Swikidesign */ 203c01ce462SGina Haeussge function renderXHTML(&$renderer, &$info) { 20451b9ed81Swikidesign global $ID; 20551b9ed81Swikidesign 206b6337848Swikidesign if (!$this->page['id']) return ''; // page must be set first 20758de0a6fSwikidesign if (!$this->page['exists'] && ($this->page['perm'] < AUTH_CREATE)) return ''; 208f9f65fc3Swikidesign 209c01ce462SGina Haeussge $this->_push_page($this->page['id'],$this->page['section']); 210c01ce462SGina Haeussge 21152e31fceSwikidesign // prepare variables 212c01ce462SGina Haeussge $rdoc = $renderer->doc; 213c01ce462SGina Haeussge $doc = ''; 21439af1bf1Swikidesign $this->renderer =& $renderer; 215f9f65fc3Swikidesign 216c01ce462SGina Haeussge $page = $this->page; 217c01ce462SGina Haeussge $clevel = $this->clevel; 218c01ce462SGina Haeussge $mode = $this->mode; 219c01ce462SGina Haeussge 2208c434f1aSGina Haeussge // exchange page ID for included one 2218c434f1aSGina Haeussge $backupID = $ID; // store the current ID 2228c434f1aSGina Haeussge $ID = $this->page['id']; // change ID to the included page 2238c434f1aSGina Haeussge 224f9f65fc3Swikidesign // get instructions and render them on the fly 225f9f65fc3Swikidesign $this->ins = p_cached_instructions($this->page['file']); 226f9f65fc3Swikidesign 227f9f65fc3Swikidesign // show only a given section? 228656a5d08Swikidesign if ($this->page['section'] && $this->page['exists']) $this->_getSection(); 229f9f65fc3Swikidesign 230f9f65fc3Swikidesign // convert relative links 23139af1bf1Swikidesign $this->_convertInstructions(); 232f9f65fc3Swikidesign 233c01ce462SGina Haeussge $xhtml = p_render('xhtml', $this->ins, $info); 234c01ce462SGina Haeussge $ID = $backupID; // restore ID 235c01ce462SGina Haeussge 236c01ce462SGina Haeussge $this->mode = $mode; 237c01ce462SGina Haeussge $this->clevel = $clevel; 238c01ce462SGina Haeussge $this->page = $page; 239c01ce462SGina Haeussge 240f9f65fc3Swikidesign // render the included page 241990ad87fSwikidesign $content = '<div class="entry-content">'.DOKU_LF. 242c01ce462SGina Haeussge $this->_cleanXHTML($xhtml).DOKU_LF. 243c01ce462SGina Haeussge '</div><!-- .entry-content -->'.DOKU_LF; 2448c434f1aSGina Haeussge 2458c434f1aSGina Haeussge // restore ID 2468c434f1aSGina Haeussge $ID = $backupID; 247f9f65fc3Swikidesign 248f9f65fc3Swikidesign // embed the included page 249e62bb8f0Swikidesign $class = ($this->page['draft'] ? 'include draft' : 'include'); 250c01ce462SGina Haeussge 251c01ce462SGina Haeussge $doc .= DOKU_LF.'<!-- including '.$this->page['id'].' // '.$this->page['file'].' -->'.DOKU_LF; 252c01ce462SGina Haeussge $doc .= '<div class="'.$class.' hentry"'.$this->_showTagLogos().'>'.DOKU_LF; 25339af1bf1Swikidesign if (!$this->header && $this->clevel && ($this->mode == 'section')) 254c01ce462SGina Haeussge $doc .= '<div class="level'.$this->clevel.'">'.DOKU_LF; 255c01ce462SGina Haeussge 2568d99695dSwikidesign if ((@file_exists(DOKU_PLUGIN.'editsections/action.php')) 2578d99695dSwikidesign && (!plugin_isdisabled('editsections'))) { // for Edit Section Reorganizer Plugin 258c01ce462SGina Haeussge $doc .= $this->_editButton().$content; 2596cad866dSwikidesign } else { 260c01ce462SGina Haeussge $doc .= $content.$this->_editButton(); 2616cad866dSwikidesign } 262656a5d08Swikidesign 263ec00fca6Swikidesign // output meta line (if wanted) and remove page from filechain 264c01ce462SGina Haeussge $doc .= $this->_footer($this->page); 265ec00fca6Swikidesign 26639af1bf1Swikidesign if (!$this->header && $this->clevel && ($this->mode == 'section')) 267c01ce462SGina Haeussge $doc .= '</div>'.DOKU_LF; // class="level?" 268c01ce462SGina Haeussge $doc .= '</div>'.DOKU_LF; // class="include hentry" 269c01ce462SGina Haeussge $doc .= DOKU_LF.'<!-- /including '.$this->page['id'].' -->'.DOKU_LF; 270f9f65fc3Swikidesign 271ec00fca6Swikidesign // reset defaults 272656a5d08Swikidesign $this->helper_plugin_include(); 273c01ce462SGina Haeussge $this->_pop_page(); 274f9f65fc3Swikidesign 275ec00fca6Swikidesign // return XHTML 276c01ce462SGina Haeussge $renderer->doc = $rdoc.$doc; 277c01ce462SGina Haeussge return $doc; 278f9f65fc3Swikidesign } 279f9f65fc3Swikidesign 280f9f65fc3Swikidesign /* ---------- Private Methods ---------- */ 281f9f65fc3Swikidesign 282f9f65fc3Swikidesign /** 283f9f65fc3Swikidesign * Get a section including its subsections 284f9f65fc3Swikidesign */ 285f9f65fc3Swikidesign function _getSection() { 286f9f65fc3Swikidesign foreach ($this->ins as $ins) { 287f9f65fc3Swikidesign if ($ins[0] == 'header') { 288f9f65fc3Swikidesign 289f9f65fc3Swikidesign // found the right header 290f9f65fc3Swikidesign if (cleanID($ins[1][0]) == $this->page['section']) { 291f9f65fc3Swikidesign $level = $ins[1][1]; 292f9f65fc3Swikidesign $i[] = $ins; 293f9f65fc3Swikidesign 294f9f65fc3Swikidesign // next header of the same or higher level -> exit 295f9f65fc3Swikidesign } elseif ($ins[1][1] <= $level) { 296f9f65fc3Swikidesign $this->ins = $i; 297f9f65fc3Swikidesign return true; 298f9f65fc3Swikidesign } elseif (isset($level)) { 299f9f65fc3Swikidesign $i[] = $ins; 300f9f65fc3Swikidesign } 301f9f65fc3Swikidesign 302f9f65fc3Swikidesign // add instructions from our section 303f9f65fc3Swikidesign } elseif (isset($level)) { 304f9f65fc3Swikidesign $i[] = $ins; 305f9f65fc3Swikidesign } 306f9f65fc3Swikidesign } 307f9f65fc3Swikidesign $this->ins = $i; 308f9f65fc3Swikidesign return true; 309f9f65fc3Swikidesign } 310f9f65fc3Swikidesign 311f9f65fc3Swikidesign /** 312f9f65fc3Swikidesign * Corrects relative internal links and media and 313f9f65fc3Swikidesign * converts headers of included pages to subheaders of the current page 314f9f65fc3Swikidesign */ 31539af1bf1Swikidesign function _convertInstructions() { 31651b9ed81Swikidesign global $ID; 31751b9ed81Swikidesign 31858de0a6fSwikidesign if (!$this->page['exists']) return false; 31958de0a6fSwikidesign 320f9f65fc3Swikidesign // check if included page is in same namespace 3219a79957fSwikidesign $ns = getNS($this->page['id']); 32251b9ed81Swikidesign $convert = (getNS($ID) == $ns ? false : true); 323f9f65fc3Swikidesign 324f9f65fc3Swikidesign $n = count($this->ins); 325f9f65fc3Swikidesign for ($i = 0; $i < $n; $i++) { 326a58d2b0aSwikidesign $current = $this->ins[$i][0]; 327f9f65fc3Swikidesign 328f9f65fc3Swikidesign // convert internal links and media from relative to absolute 329a58d2b0aSwikidesign if ($convert && (substr($current, 0, 8) == 'internal')) { 3309a79957fSwikidesign $this->ins[$i][1][0] = $this->_convertInternalLink($this->ins[$i][1][0], $ns); 331a58d2b0aSwikidesign 332a58d2b0aSwikidesign // set header level to current section level + header level 333a58d2b0aSwikidesign } elseif ($current == 'header') { 3349a79957fSwikidesign $this->_convertHeader($i); 335a58d2b0aSwikidesign 336a58d2b0aSwikidesign // the same for sections 3379a79957fSwikidesign } elseif (($current == 'section_open') && ($this->mode == 'section')) { 338a58d2b0aSwikidesign $this->ins[$i][1][0] = $this->_convertSectionLevel($this->ins[$i][1][0]); 339a58d2b0aSwikidesign 340a58d2b0aSwikidesign // show only the first section? 341a58d2b0aSwikidesign } elseif ($this->firstsec && ($current == 'section_close') 342a58d2b0aSwikidesign && ($this->ins[$i-1][0] != 'section_open')) { 343a58d2b0aSwikidesign $this->_readMore($i); 344a58d2b0aSwikidesign return true; 345a58d2b0aSwikidesign } 346a58d2b0aSwikidesign } 347a58d2b0aSwikidesign $this->_finishConvert(); 348a58d2b0aSwikidesign return true; 349a58d2b0aSwikidesign } 350a58d2b0aSwikidesign 351a58d2b0aSwikidesign /** 352a58d2b0aSwikidesign * Convert relative internal links and media 353a58d2b0aSwikidesign * 354a58d2b0aSwikidesign * @param integer $i: counter for current instruction 355a58d2b0aSwikidesign * @param string $ns: namespace of included page 356a58d2b0aSwikidesign * @return string $link: converted, now absolute link 357a58d2b0aSwikidesign */ 3589a79957fSwikidesign function _convertInternalLink($link, $ns) { 359f9f65fc3Swikidesign 360f9f65fc3Swikidesign // relative subnamespace 3619a79957fSwikidesign if ($link{0} == '.') { 3629a79957fSwikidesign if ($link{1} == '.') return getNS($ns).':'.substr($link, 2); // parent namespace 3639a79957fSwikidesign else return $ns.':'.substr($link, 1); // current namespace 364f9f65fc3Swikidesign 365f9f65fc3Swikidesign // relative link 3669a79957fSwikidesign } elseif (strpos($link, ':') === false) { 3679a79957fSwikidesign return $ns.':'.$link; 3689a79957fSwikidesign 3699a79957fSwikidesign // absolute link - don't change 3709a79957fSwikidesign } else { 3719a79957fSwikidesign return $link; 372a58d2b0aSwikidesign } 373f9f65fc3Swikidesign } 374f9f65fc3Swikidesign 375a58d2b0aSwikidesign /** 376a58d2b0aSwikidesign * Convert header level and add header to TOC 377a58d2b0aSwikidesign * 378a58d2b0aSwikidesign * @param integer $i: counter for current instruction 379a58d2b0aSwikidesign * @return boolean true 380a58d2b0aSwikidesign */ 3819a79957fSwikidesign function _convertHeader($i) { 382cf0272c0Swikidesign global $conf; 383cf0272c0Swikidesign 384f9f65fc3Swikidesign $text = $this->ins[$i][1][0]; 38539af1bf1Swikidesign $hid = $this->renderer->_headerToLink($text, 'true'); 386b448b725Swikidesign if (empty($this->header)) { 387a58d2b0aSwikidesign $this->_offset = $this->clevel - $this->ins[$i][1][1] + 1; 388cf0272c0Swikidesign $level = $this->_convertSectionLevel(1); 389cf0272c0Swikidesign $this->header = array('hid' => $hid, 'title' => hsc($text), 'level' => $level); 390990ad87fSwikidesign if ($this->noheader) { 39139af1bf1Swikidesign unset($this->ins[$i]); 392990ad87fSwikidesign return true; 39371ec1101SGina Haeussge } else if ($this->permalink){ 3944eb6b7abSGina Haeussge $this->ins[$i] = $this->_permalinkHeader($text, $level, $this->ins[$i][1][2]); 395990ad87fSwikidesign } 396656a5d08Swikidesign } else { 397a58d2b0aSwikidesign $level = $this->_convertSectionLevel($this->ins[$i][1][1]); 39839af1bf1Swikidesign } 39971ec1101SGina Haeussge if ($this->mode == 'section') { 4004eb6b7abSGina Haeussge if (is_array($this->ins[$i][1][1])) { // permalink header 40171ec1101SGina Haeussge $this->ins[$i][1][1][1] = $level; 4024eb6b7abSGina Haeussge } else { // normal header 40371ec1101SGina Haeussge $this->ins[$i][1][1] = $level; 40471ec1101SGina Haeussge } 40571ec1101SGina Haeussge } 406990ad87fSwikidesign 407a58d2b0aSwikidesign // add TOC item 408656a5d08Swikidesign if (($level >= $conf['toptoclevel']) && ($level <= $conf['maxtoclevel'])) { 409656a5d08Swikidesign $this->renderer->toc[] = array( 410656a5d08Swikidesign 'hid' => $hid, 411656a5d08Swikidesign 'title' => $text, 412656a5d08Swikidesign 'type' => 'ul', 413656a5d08Swikidesign 'level' => $level - $conf['toptoclevel'] + 1 414656a5d08Swikidesign ); 415f9f65fc3Swikidesign } 416f9f65fc3Swikidesign return true; 417a58d2b0aSwikidesign } 418a58d2b0aSwikidesign 419a58d2b0aSwikidesign /** 42071ec1101SGina Haeussge * Create instruction item for a permalink header 42171ec1101SGina Haeussge * 42271ec1101SGina Haeussge * @param string $text: Headline text 42371ec1101SGina Haeussge * @param integer $level: Headline level 42471ec1101SGina Haeussge * @param integer $pos: I wish I knew what this is for... 42571ec1101SGina Haeussge * 42671ec1101SGina Haeussge * @author Gina Haeussge <osd@foosel.net> 42771ec1101SGina Haeussge */ 42871ec1101SGina Haeussge function _permalinkHeader($text, $level, $pos) { 42971ec1101SGina Haeussge $newIns = array( 43071ec1101SGina Haeussge 'plugin', 43171ec1101SGina Haeussge array( 43271ec1101SGina Haeussge 'include_header', 43371ec1101SGina Haeussge array( 43471ec1101SGina Haeussge $text, 4354eb6b7abSGina Haeussge $level 43671ec1101SGina Haeussge ), 43771ec1101SGina Haeussge ), 43871ec1101SGina Haeussge $pos 43971ec1101SGina Haeussge ); 44071ec1101SGina Haeussge 44171ec1101SGina Haeussge return $newIns; 44271ec1101SGina Haeussge } 44371ec1101SGina Haeussge 44471ec1101SGina Haeussge /** 445a58d2b0aSwikidesign * Convert the level of headers and sections 446a58d2b0aSwikidesign * 447a58d2b0aSwikidesign * @param integer $in: current level 448a58d2b0aSwikidesign * @return integer $out: converted level 449a58d2b0aSwikidesign */ 450a58d2b0aSwikidesign function _convertSectionLevel($in) { 451a58d2b0aSwikidesign $out = $in + $this->_offset; 452cf0272c0Swikidesign if ($out >= 5) return 5; 453cf0272c0Swikidesign if ($out <= $this->clevel + 1) return $this->clevel + 1; 454a58d2b0aSwikidesign return $out; 455a58d2b0aSwikidesign } 456a58d2b0aSwikidesign 457a58d2b0aSwikidesign /** 458a58d2b0aSwikidesign * Adds a read more... link at the bottom of the first section 459a58d2b0aSwikidesign * 460a58d2b0aSwikidesign * @param integer $i: counter for current instruction 461a58d2b0aSwikidesign * @return boolean true 462a58d2b0aSwikidesign */ 463a58d2b0aSwikidesign function _readMore($i) { 464a58d2b0aSwikidesign $more = ((is_array($this->ins[$i+1])) && ($this->ins[$i+1][0] != 'document_end')); 465a58d2b0aSwikidesign 466a58d2b0aSwikidesign if ($this->ins[0][0] == 'document_start') $this->ins = array_slice($this->ins, 1, $i); 467a58d2b0aSwikidesign else $this->ins = array_slice($this->ins, 0, $i); 468a58d2b0aSwikidesign 469a58d2b0aSwikidesign if ($more) { 470a58d2b0aSwikidesign array_unshift($this->ins, array('document_start', array(), 0)); 471a58d2b0aSwikidesign $last = array_pop($this->ins); 472a58d2b0aSwikidesign $this->ins[] = array('p_open', array(), $last[2]); 473a58d2b0aSwikidesign $this->ins[] = array('internallink',array($this->page['id'], $this->getLang('readmore')),$last[2]); 474a58d2b0aSwikidesign $this->ins[] = array('p_close', array(), $last[2]); 475a58d2b0aSwikidesign $this->ins[] = $last; 476a58d2b0aSwikidesign $this->ins[] = array('document_end', array(), $last[2]); 477f9f65fc3Swikidesign } else { 478a58d2b0aSwikidesign $this->_finishConvert(); 479a58d2b0aSwikidesign } 480f9f65fc3Swikidesign return true; 481f9f65fc3Swikidesign } 482a58d2b0aSwikidesign 483a58d2b0aSwikidesign /** 484a58d2b0aSwikidesign * Adds 'document_start' and 'document_end' instructions if not already there 485a58d2b0aSwikidesign */ 486a58d2b0aSwikidesign function _finishConvert() { 487b088012cSwikidesign if ($this->ins[0][0] != 'document_start') 48878f60e2aSwikidesign array_unshift($this->ins, array('document_start', array(), 0)); 489b088012cSwikidesign $c = count($this->ins) - 1; 490b088012cSwikidesign if ($this->ins[$c][0] != 'document_end') 49178f60e2aSwikidesign $this->ins[] = array('document_end', array(), 0); 49278f60e2aSwikidesign } 493f9f65fc3Swikidesign 494f9f65fc3Swikidesign /** 495f9f65fc3Swikidesign * Remove TOC, section edit buttons and tags 496f9f65fc3Swikidesign */ 497f9f65fc3Swikidesign function _cleanXHTML($xhtml) { 498f9f65fc3Swikidesign $replace = array( 499f9f65fc3Swikidesign '!<div class="toc">.*?(</div>\n</div>)!s' => '', // remove toc 500f9f65fc3Swikidesign '#<!-- SECTION "(.*?)" \[(\d+-\d*)\] -->#e' => '', // remove section edit buttons 501f9f65fc3Swikidesign '!<div class="tags">.*?(</div>)!s' => '', // remove category tags 502f9f65fc3Swikidesign ); 503b088012cSwikidesign if ($this->clevel) 504b088012cSwikidesign $replace['#<div class="footnotes">#s'] = '<div class="footnotes level'.$this->clevel.'">'; 505f9f65fc3Swikidesign $xhtml = preg_replace(array_keys($replace), array_values($replace), $xhtml); 506f9f65fc3Swikidesign return $xhtml; 507f9f65fc3Swikidesign } 508f9f65fc3Swikidesign 509f9f65fc3Swikidesign /** 510f9f65fc3Swikidesign * Optionally display logo for the first tag found in the included page 511f9f65fc3Swikidesign */ 512f9f65fc3Swikidesign function _showTagLogos() { 513fc5d061eSwikidesign if ((!$this->getConf('showtaglogos')) 514fc5d061eSwikidesign || (plugin_isdisabled('tag')) 515fc5d061eSwikidesign || (!$taghelper =& plugin_load('helper', 'tag'))) 516fc5d061eSwikidesign return ''; 517f9f65fc3Swikidesign 518fc5d061eSwikidesign $subject = p_get_metadata($this->page['id'], 'subject'); 519fc5d061eSwikidesign if (is_array($subject)) $tag = $subject[0]; 520fc5d061eSwikidesign else list($tag, $rest) = explode(' ', $subject, 2); 521fc5d061eSwikidesign $title = str_replace('_', ' ', noNS($tag)); 522fc5d061eSwikidesign resolve_pageid($taghelper->namespace, $tag, $exists); // resolve shortcuts 523fc5d061eSwikidesign 524f9f65fc3Swikidesign $logosrc = mediaFN($logoID); 525f9f65fc3Swikidesign $types = array('.png', '.jpg', '.gif'); // auto-detect filetype 526f9f65fc3Swikidesign foreach ($types as $type) { 527f9f65fc3Swikidesign if (!@file_exists($logosrc.$type)) continue; 528fc5d061eSwikidesign $logoID = $tag.$type; 529f9f65fc3Swikidesign $logosrc .= $type; 530f9f65fc3Swikidesign list($w, $h, $t, $a) = getimagesize($logosrc); 531f9f65fc3Swikidesign return ' style="min-height: '.$h.'px">'. 532fc5d061eSwikidesign '<img class="mediaright" src="'.ml($logoID).'" alt="'.$title.'"/'; 533f9f65fc3Swikidesign } 534f9f65fc3Swikidesign return ''; 535f9f65fc3Swikidesign } 536f9f65fc3Swikidesign 537f9f65fc3Swikidesign /** 538f9f65fc3Swikidesign * Display an edit button for the included page 539f9f65fc3Swikidesign */ 540f9f65fc3Swikidesign function _editButton() { 541990ad87fSwikidesign if ($this->page['exists']) { 542f9f65fc3Swikidesign if (($this->page['perm'] >= AUTH_EDIT) && (is_writable($this->page['file']))) 543f9f65fc3Swikidesign $action = 'edit'; 544f9f65fc3Swikidesign else return ''; 545f9f65fc3Swikidesign } elseif ($this->page['perm'] >= AUTH_CREATE) { 546f9f65fc3Swikidesign $action = 'create'; 547f9f65fc3Swikidesign } 5486c836050Swikidesign if ($this->editbtn) { 549f9f65fc3Swikidesign return '<div class="secedit">'.DOKU_LF.DOKU_TAB. 550f9f65fc3Swikidesign html_btn($action, $this->page['id'], '', array('do' => 'edit'), 'post').DOKU_LF. 551f9f65fc3Swikidesign '</div>'.DOKU_LF; 5523c01153cSwikidesign } else { 5533c01153cSwikidesign return ''; 5543c01153cSwikidesign } 555f9f65fc3Swikidesign } 556f9f65fc3Swikidesign 557f9f65fc3Swikidesign /** 558f9f65fc3Swikidesign * Returns the meta line below the included page 559f9f65fc3Swikidesign */ 5606b088758Swikidesign function _footer($page) { 561817828faSwikidesign global $conf, $ID; 562817828faSwikidesign 5636b088758Swikidesign if (!$this->footer) return ''; // '<div class="inclmeta"> </div>'.DOKU_LF; 564f9f65fc3Swikidesign 565b6337848Swikidesign $id = $page['id']; 566f9f65fc3Swikidesign $meta = p_get_metadata($id); 567f9f65fc3Swikidesign $ret = array(); 568f9f65fc3Swikidesign 569f9f65fc3Swikidesign // permalink 570f9f65fc3Swikidesign if ($this->getConf('showlink')) { 571b6337848Swikidesign $title = ($page['title'] ? $page['title'] : $meta['title']); 572f9f65fc3Swikidesign if (!$title) $title = str_replace('_', ' ', noNS($id)); 573656a5d08Swikidesign $class = ($page['exists'] ? 'wikilink1' : 'wikilink2'); 57439af1bf1Swikidesign $link = array( 57539af1bf1Swikidesign 'url' => wl($id), 57639af1bf1Swikidesign 'title' => $id, 57739af1bf1Swikidesign 'name' => hsc($title), 57839af1bf1Swikidesign 'target' => $conf['target']['wiki'], 579656a5d08Swikidesign 'class' => $class.' permalink', 58039af1bf1Swikidesign 'more' => 'rel="bookmark"', 58139af1bf1Swikidesign ); 58239af1bf1Swikidesign $ret[] = $this->renderer->_formatLink($link); 583f9f65fc3Swikidesign } 584f9f65fc3Swikidesign 585f9f65fc3Swikidesign // date 586f9f65fc3Swikidesign if ($this->getConf('showdate')) { 587b6337848Swikidesign $date = ($page['date'] ? $page['date'] : $meta['date']['created']); 58839af1bf1Swikidesign if ($date) 589ee335396SMichael Klier $ret[] = '<abbr class="published" title="'.strftime('%Y-%m-%dT%H:%M:%SZ', $date).'">'. 590ee335396SMichael Klier strftime($conf['dformat'], $date). 59139af1bf1Swikidesign '</abbr>'; 592f9f65fc3Swikidesign } 593f9f65fc3Swikidesign 594f9f65fc3Swikidesign // author 595f9f65fc3Swikidesign if ($this->getConf('showuser')) { 596b6337848Swikidesign $author = ($page['user'] ? $page['user'] : $meta['creator']); 597f9f65fc3Swikidesign if ($author) { 598f9f65fc3Swikidesign $userpage = cleanID($this->getConf('usernamespace').':'.$author); 59951b9ed81Swikidesign resolve_pageid(getNS($ID), $userpage, $exists); 60039af1bf1Swikidesign $class = ($exists ? 'wikilink1' : 'wikilink2'); 60139af1bf1Swikidesign $link = array( 60239af1bf1Swikidesign 'url' => wl($userpage), 60339af1bf1Swikidesign 'title' => $userpage, 60439af1bf1Swikidesign 'name' => hsc($author), 60539af1bf1Swikidesign 'target' => $conf['target']['wiki'], 60639af1bf1Swikidesign 'class' => $class.' url fn', 60739af1bf1Swikidesign 'pre' => '<span class="vcard author">', 60839af1bf1Swikidesign 'suf' => '</span>', 60939af1bf1Swikidesign ); 61039af1bf1Swikidesign $ret[] = $this->renderer->_formatLink($link); 611f9f65fc3Swikidesign } 612f9f65fc3Swikidesign } 613f9f65fc3Swikidesign 614f9f65fc3Swikidesign // comments - let Discussion Plugin do the work for us 615b6337848Swikidesign if (!$page['section'] && $this->getConf('showcomments') 616e4624397Swikidesign && (!plugin_isdisabled('discussion')) 617e4624397Swikidesign && ($discussion =& plugin_load('helper', 'discussion'))) { 618e4624397Swikidesign $disc = $discussion->td($id); 61939af1bf1Swikidesign if ($disc) $ret[] = '<span class="comment">'.$disc.'</span>'; 620f9f65fc3Swikidesign } 621f9f65fc3Swikidesign 622564e71f6Sraymond.scholz // linkbacks - let Linkback Plugin do the work for us 623564e71f6Sraymond.scholz if (!$page['section'] && $this->getConf('showlinkbacks') 624564e71f6Sraymond.scholz && (!plugin_isdisabled('linkback')) 625564e71f6Sraymond.scholz && ($linkback =& plugin_load('helper', 'linkback'))) { 626564e71f6Sraymond.scholz $link = $linkback->td($id); 627564e71f6Sraymond.scholz if ($link) $ret[] = '<span class="linkback">'.$link.'</span>'; 628564e71f6Sraymond.scholz } 629564e71f6Sraymond.scholz 630ec00fca6Swikidesign $ret = implode(DOKU_LF.DOKU_TAB.'· ', $ret); 631f9f65fc3Swikidesign 632fc5d061eSwikidesign // tags - let Tag Plugin do the work for us 633fc5d061eSwikidesign if (!$page['section'] && $this->getConf('showtags') 634fc5d061eSwikidesign && (!plugin_isdisabled('tag')) 635fc5d061eSwikidesign && ($tag =& plugin_load('helper', 'tag'))) { 636fc5d061eSwikidesign $page['tags'] = '<div class="tags"><span>'.DOKU_LF. 637fc5d061eSwikidesign DOKU_TAB.$tag->td($id).DOKU_LF. 638fc5d061eSwikidesign DOKU_TAB.'</span></div>'.DOKU_LF; 639fc5d061eSwikidesign $ret = $page['tags'].DOKU_TAB.$ret; 640f9f65fc3Swikidesign } 641f9f65fc3Swikidesign 642f9f65fc3Swikidesign if (!$ret) $ret = ' '; 643ec00fca6Swikidesign $class = 'inclmeta'; 644ec00fca6Swikidesign if ($this->header && $this->clevel && ($this->mode == 'section')) 645ec00fca6Swikidesign $class .= ' level'.$this->clevel; 646ec00fca6Swikidesign return '<div class="'.$class.'">'.DOKU_LF.DOKU_TAB.$ret.DOKU_LF.'</div>'.DOKU_LF; 647f9f65fc3Swikidesign } 648f9f65fc3Swikidesign 6491f7a99c4SMichael Klier /** 6501f7a99c4SMichael Klier * Builds the ODT to embed the page to include 6511f7a99c4SMichael Klier */ 6521f7a99c4SMichael Klier function renderODT(&$renderer) { 6531f7a99c4SMichael Klier global $ID; 6541f7a99c4SMichael Klier 6551f7a99c4SMichael Klier if (!$this->page['id']) return ''; // page must be set first 6561f7a99c4SMichael Klier if (!$this->page['exists'] && ($this->page['perm'] < AUTH_CREATE)) return ''; 6571f7a99c4SMichael Klier 6581f7a99c4SMichael Klier // prepare variable 6591f7a99c4SMichael Klier $this->renderer =& $renderer; 6601f7a99c4SMichael Klier 6611f7a99c4SMichael Klier // get instructions and render them on the fly 6621f7a99c4SMichael Klier $this->ins = p_cached_instructions($this->page['file']); 6631f7a99c4SMichael Klier 6641f7a99c4SMichael Klier // show only a given section? 6651f7a99c4SMichael Klier if ($this->page['section'] && $this->page['exists']) $this->_getSection(); 6661f7a99c4SMichael Klier 6671f7a99c4SMichael Klier // convert relative links 6681f7a99c4SMichael Klier $this->_convertInstructions(); 6691f7a99c4SMichael Klier 6701f7a99c4SMichael Klier // render the included page 6711f7a99c4SMichael Klier $backupID = $ID; // store the current ID 6721f7a99c4SMichael Klier $ID = $this->page['id']; // change ID to the included page 6731f7a99c4SMichael Klier // remove document_start and document_end to avoid zipping 6741f7a99c4SMichael Klier $this->ins = array_slice($this->ins, 1, -1); 6751f7a99c4SMichael Klier p_render('odt', $this->ins, $info); 6761f7a99c4SMichael Klier $ID = $backupID; // restore ID 6771f7a99c4SMichael Klier // reset defaults 6781f7a99c4SMichael Klier $this->helper_plugin_include(); 6791f7a99c4SMichael Klier } 680f9f65fc3Swikidesign} 681df4e907bSMichael Klier//vim:ts=4:sw=4:et:enc=utf-8: 682