1<?php 2/** 3 * Pagetemplate action plugin 4 * 5 * @author Luke Howson <mail@lukehowson.com> 6 */ 7 8if(!defined('DOKU_INC')) die(); 9if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 10require_once(DOKU_PLUGIN.'action.php'); 11require_once(DOKU_INC.'inc/parserutils.php'); 12require_once(DOKU_INC.'inc/search.php'); 13require_once(DOKU_INC.'inc/parser/parser.php'); 14require_once('pagetemplate_backlinks.php'); 15 16class action_plugin_pagetemplate extends DokuWiki_Action_Plugin { 17 18 /** 19 * return some info 20 */ 21 function getInfo(){ 22 return array( 23 'author' => 'Luke Howson', 24 'email' => 'mail@lukehowson.com', 25 'date' => '2007-07-25', 26 'name' => 'Page Template', 27 'desc' => 'Generates a template when Create this Page is clicked.', 28 ); 29 } 30 31 /* 32 * Register its handlers with the dokuwiki's event controller 33 */ 34 function register(Doku_Event_Handler $controller) { 35 $controller->register_hook('HTML_PAGE_FROMTEMPLATE', 'BEFORE', $this, '_generateTemplate'); 36 $controller->register_hook('HTML_PAGE_FROMTEMPLATE', 'AFTER', $this, '_removeTemplate'); 37 } 38 39 function _removeTemplate(&$event, $param) { 40 $page = getID(); 41 $theTemplate = _templateFN($page); 42 if (file_exists($theTemplate)) { 43 unlink($theTemplate); 44 io_sweepNS($page); 45 } 46 $backup = $theTemplate.'.bak'; 47 if (file_exists($backup) ) { 48 io_rename($backup,$theTemplate); 49 } 50 return; 51 } 52 53 /** 54 * Hooked into a newly created page (as editor boots up). 55 */ 56 function _generateTemplate(&$event, $param) { 57 // page already exists? 58 $page = getID(); 59 $pageFile = wikiFN($page); 60 if(file_exists($pageFile) ) { 61 return; 62 } 63 global $conf; 64 $ID = getID(); 65 //$ID = $event->data[0]; 66 $backlinks = array(); 67 $lib = new PageTemplateBacklink; 68 $backlinks = $lib->getBacklinks($ID); 69 if (!sizeof($backlinks)) return; 70 $firstLink = $backlinks[0]; 71 $templatePage = $firstLink[2]; 72 $context = $firstLink[4]; 73 $templatePage = resolve_id(getNS($context),$templatePage); 74 // $displayName = $firstLink[3]; 75 $pageName = $firstLink[1]; 76 $pageName = resolve_id(getNS($context),$pageName); 77 $fp = wikiFN($pageName); 78 $templateFile = wikiFN($templatePage); 79 $newTemplate = _templateFN($pageName); 80 $backup = $newTemplate.'.bak'; 81 if (file_exists($newTemplate) ) { 82 io_rename($newTemplate,$backup); 83 } 84 85 io_makeFileDir($newTemplate); 86 copy($templateFile, $newTemplate); 87 return; 88 } 89} 90 91function _templateFN($pageName) { 92 $newTemplate = resolve_id(getNS($pageName),'template'); 93 $newTemplate = wikiFN($newTemplate); 94 $newTemplate = preg_replace('/(?<=\\/)(?=template.txt$)/','_',$newTemplate); 95 // hack for page / subpage model 96 $newTemplate = preg_replace('/(?<=\\/)template\\/page.txt$/','_template.txt',$newTemplate); 97 return $newTemplate; 98} 99 100function _pt_search_backlinks(&$data,$base,$file,$type,$lvl,$opts){ 101 //we do nothing with directories 102 if($type == 'd') return true;; 103 //only search txt files 104 if(!preg_match('#\.txt$#',$file)) return true;; 105 106 //absolute search id 107 $sid = parentNS(cleanID($opts['ns'].':'.$opts['name'])); 108 109 //current id and namespace 110 $cid = pathID($file); 111 $cns = parentNS($cid); 112 113 //check ACL 114 if(auth_quickaclcheck($cid) < AUTH_READ){ 115 return false; 116 } 117 118 //fetch instructions 119 $instructions = _pt_get_instructions(io_readfile($base.$file)); 120 if(is_null($instructions)) return false; 121 $ret = false; 122 123 //check all links for match 124 foreach($instructions as $ins){ 125 if($ins[0] == 'plugin' && $ins[1][0] == 'pagetemplate' && strlen($ins[1][1][0]) > 0) { 126 $mid = $ins[1][1][1]; 127 resolve_pageid($cns,$mid,$exists); //exists is not used 128 if($mid == $sid){ 129 //we have a match - finish 130 $ins[1][1][1] = resolve_id($cns,$ins[1][1][1]); 131 $ins[1][1][2] = resolve_id($cns,$ins[1][1][2]); 132 $data[]['id'] = $ins[1][1]; 133 break; 134 } 135 } 136 } 137 return false; 138} 139 140function _pt_get_instructions($text) { 141 // get the instructions 142 // Create the parser 143 $Parser = & new Doku_Parser(); 144 145 // Add the Handler 146 $Parser->Handler = & new Doku_Handler(); 147 148 //add modes to parser 149 $pagetemplate_obj =& plugin_load('syntax','pagetemplate'); 150 $std_modes = array('listblock','preformatted','notoc','nocache', 151 'header','table','linebreak','footnote','hr', 152 'unformatted','php','html','code','file','quote', 153 'internallink','rss','media','externallink', 154 'emaillink','windowssharelink','eol'); 155 foreach($std_modes as $m){ 156 $class = "Doku_Parser_Mode_$m"; 157 $obj = new $class(); 158 $mode = array( 159 'sort' => $obj->getSort(), 160 'mode' => $m, 161 'obj' => $obj 162 ); 163 $Parser->addMode($m,$obj); 164 } 165 $Parser->addMode('plugin_pagetemplate',$pagetemplate_obj); 166 // Do the parsing 167 $p = $Parser->parse($text); 168 return $p; 169}