1<?php 2 3use dokuwiki\Extension\Event; 4 5/** 6 * DokuWiki Plugin userpagecreate (Action Component) 7 * 8 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 9 * @author Adrian Lang <lang@cosmocode.de> 10 */ 11class action_plugin_userpagecreate extends DokuWiki_Action_Plugin 12{ 13 /** @inheritDoc */ 14 public function register(Doku_Event_Handler $controller) 15 { 16 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_action_act_preprocess'); 17 18 if ($this->getConf('delete')) { 19 $controller->register_hook('AUTH_USER_CHANGE', 'AFTER', $this, 'handleUserDeletion'); 20 } 21 } 22 23 /** 24 * Check and if necessary trigger the page creation 25 * 26 * @triggers USERPAGECREATE_PAGE_CREATE 27 * @param Doku_Event $event 28 * @param $param 29 */ 30 public function handle_action_act_preprocess(Doku_Event $event, $param) 31 { 32 global $INPUT; 33 global $conf; 34 35 $user = $INPUT->server->str('REMOTE_USER'); 36 if (!$user) return; 37 38 $data = $this->userSpaceData($user); 39 if ($data === null) return; 40 if ($data['exists']) return; 41 42 // trigger custom Event 43 Event::createAndTrigger( 44 'USERPAGECREATE_PAGE_CREATE', 45 $data, 46 array($this, 'createUserSpace'), 47 true 48 ); 49 } 50 51 /** 52 * @param $user 53 * @return array|null The appropriate data or null if configuration failed 54 */ 55 protected function userSpaceData($user) 56 { 57 global $conf; 58 59 // prepare info 60 $res = $this->getConf('target') . $user; 61 $tpl = $this->getConf('template'); 62 $do_ns = (strlen($tpl) > 0) && substr($tpl, -1, 1) === ':'; 63 64 // no ressource, nothing to do 65 if ($res === '') return null; 66 67 // Check if userpage or usernamespace already exists. 68 $exists = page_exists($res . ($do_ns ? (':' . $conf['start']) : '')); 69 70 // prepare Event Data 71 return array( 72 'do_ns' => $do_ns, 73 'tpl' => $tpl, 74 'res' => $res, 75 'exists' => $exists, 76 ); 77 } 78 79 /** 80 * @param $data 81 */ 82 public function createUserSpace($data) 83 { 84 global $conf; 85 86 $do_ns = $data['do_ns']; 87 $tpl = $data['tpl']; 88 $res = $data['res']; 89 90 // Get templates and target page names. 91 $parsed = false; 92 $pages = array(); 93 if ($do_ns) { 94 $t_pages = array(); 95 search($t_pages, $conf['datadir'], 'search_universal', 96 array('depth' => 0, 'listfiles' => true), 97 str_replace(':', '/', getNS($tpl))); 98 foreach ($t_pages as $t_page) { 99 $tpl_name = cleanID($t_page['id']); 100 $pages[$res . ':' . substr($tpl_name, strlen(getNS($tpl)) + 1)] = rawWiki($tpl_name); 101 } 102 } else { 103 if ($tpl === '') { 104 $pages[$res] = pageTemplate($res); 105 $parsed = true; 106 } elseif (page_exists($tpl)) { 107 $pages[$res] = rawWiki($tpl); 108 } 109 } 110 111 if (count($pages) === 0) { 112 return; 113 } 114 115 // Get additional user data from auth backend. 116 global $USERINFO; 117 $auth_replaces = $USERINFO; 118 foreach (array( 119 'grps', 120 'pass', // Secret data 121 'name', 122 'mail' // Already replaced by parsePageTemplate 123 ) as $hidden) { 124 if (isset($auth_replaces[$hidden])) { 125 unset($auth_replaces[$hidden]); 126 } 127 } 128 129 // Parse templates and write pages. 130 foreach ($pages as $name => &$content) { 131 if (!$parsed) { 132 $byref_data = array('tpl' => $content, 'id' => $name); 133 $content = parsePageTemplate($byref_data); 134 } 135 foreach ($auth_replaces as $k => $v) { 136 $content = str_replace('@' . strtoupper($k) . '@', $v, $content); 137 } 138 139 saveWikiText($name, $content, $this->getConf('create_summary')); 140 } 141 } 142 143 /** 144 * Handle the deletion of the user page when the user is deleted 145 * 146 * @param Doku_Event $event 147 * @param $param 148 */ 149 public function handleUserDeletion(Doku_Event $event, $param) 150 { 151 if ($event->data['type'] !== 'delete') return; 152 153 foreach ($event->data['params'] as $info) { 154 $user = $info[0]; 155 $data = $this->userSpaceData($user); 156 if ($data === null) continue; 157 if (!$data['exists']) continue; 158 if ($data['do_ns']) { 159 $this->deleteNamespace($data['res']); 160 } else { 161 $this->deletePage($data['res']); 162 } 163 } 164 } 165 166 /** 167 * Delete the given namespace and all old revisions 168 * 169 * @param string $ns 170 */ 171 protected function deleteNamespace($ns) 172 { 173 global $conf; 174 175 $ns = str_replace(':', '/', $ns); 176 177 // pages 178 $dir = $conf['datadir'] . '/' . utf8_encodeFN($ns); 179 if (is_dir($dir)) { 180 io_rmdir($dir, true); 181 } 182 183 // attic 184 $dir = $conf['olddir'] . '/' . utf8_encodeFN($ns); 185 if (is_dir($dir)) { 186 io_rmdir($dir, true); 187 } 188 } 189 190 /** 191 * Delete the given page and all old revisions 192 * 193 * @param string $page 194 */ 195 protected function deletePage($page) 196 { 197 global $conf; 198 199 $page = str_replace(':', '/', $page); 200 201 // page 202 $file = $conf['datadir'] . '/' . utf8_encodeFN($page) . '.txt'; 203 if (is_file($file)) { 204 unlink($file); 205 } 206 207 // attic 208 $files = glob($conf['olddir'] . '/' . utf8_encodeFN($page) . '.*.txt.*'); 209 foreach ($files as $file) { 210 if (is_file($file)) { 211 unlink($file); 212 } 213 } 214 } 215} 216