1<?php 2/** 3 * DokuWiki Plugin farmer (Admin Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Michael Große <grosse@cosmocode.de> 7 */ 8 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12class admin_plugin_farmer_new extends DokuWiki_Admin_Plugin { 13 14 /** @var helper_plugin_farmer $helper */ 15 protected $helper; 16 17 /** 18 * @return bool true if only access for superuser, false is for superusers and moderators 19 */ 20 public function forAdminOnly() { 21 return true; 22 } 23 24 /** 25 * admin_plugin_farmer_new constructor. 26 */ 27 public function __construct() { 28 $this->helper = plugin_load('helper', 'farmer'); 29 } 30 31 /** 32 * Should carry out any processing required by the plugin. 33 */ 34 public function handle() { 35 global $INPUT; 36 global $ID; 37 if(!$INPUT->has('farmer__submit')) return; 38 39 $data = $this->validateAnimalData(); 40 if(!$data) return; 41 if($this->createNewAnimal($data['name'], $data['admin'], $data['pass'], $data['template'])) { 42 $url = $this->helper->getAnimalURL($data['name']); 43 $link = '<a href="' . $url . '">' . hsc($data['name']) . '</a>'; 44 45 msg(sprintf($this->getLang('animal creation success'), $link), 1); 46 $link = wl($ID, array('do' => 'admin', 'page' => 'farmer', 'sub' => 'new'), true, '&'); 47 send_redirect($link); 48 } 49 } 50 51 /** 52 * Render HTML output, e.g. helpful text and a form 53 */ 54 public function html() { 55 $farmconfig = $this->helper->getConfig(); 56 57 $form = new \dokuwiki\Form\Form(); 58 $form->addClass('plugin_farmer')->id('farmer__create_animal_form'); 59 60 $form->addFieldsetOpen($this->getLang('animal configuration')); 61 $form->addTextInput('animalname', $this->getLang('animal')); 62 $form->addFieldsetClose(); 63 64 $animals = $this->helper->getAllAnimals(); 65 array_unshift($animals, ''); 66 $form->addFieldsetOpen($this->getLang('animal template')); 67 $form->addDropdown('animaltemplate', $animals)->addClass('farmer_choosen_animals'); 68 $form->addFieldsetClose(); 69 70 $form->addFieldsetOpen($this->getLang('animal administrator')); 71 $btn = $form->addRadioButton('adminsetup', $this->getLang('noUsers'))->val('noUsers'); 72 if($farmconfig['inherit']['users']) { 73 $btn->attr('checked', 'checked'); // default when inherit available 74 } else { 75 // no user copying when inheriting 76 $form->addRadioButton('adminsetup', $this->getLang('importUsers'))->val('importUsers'); 77 $form->addRadioButton('adminsetup', $this->getLang('currentAdmin'))->val('currentAdmin'); 78 } 79 $btn = $form->addRadioButton('adminsetup', $this->getLang('newAdmin'))->val('newAdmin'); 80 if(!$farmconfig['inherit']['users']) { 81 $btn->attr('checked', 'checked'); // default when inherit not available 82 } 83 $form->addPasswordInput('adminPassword', $this->getLang('admin password')); 84 $form->addFieldsetClose(); 85 86 $form->addButton('farmer__submit', $this->getLang('submit'))->attr('type', 'submit')->val('newAnimal'); 87 echo $form->toHTML(); 88 } 89 90 /** 91 * Validate the data for a new animal 92 * 93 * @return array|bool false on errors, clean data otherwise 94 */ 95 protected function validateAnimalData() { 96 global $INPUT; 97 98 $animalname = $INPUT->filter('trim')->str('animalname'); 99 $adminsetup = $INPUT->str('adminsetup'); 100 $adminpass = $INPUT->filter('trim')->str('adminPassword'); 101 $template = $INPUT->filter('trim')->str('animaltemplate'); 102 103 $errors = array(); 104 105 if($animalname === '') { 106 $errors[] = $this->getLang('animalname_missing'); 107 } elseif(!$this->helper->validateAnimalName($animalname)) { 108 $errors[] = $this->getLang('animalname_invalid'); 109 } 110 111 if($adminsetup === 'newAdmin' && $adminpass === '') { 112 $errors[] = $this->getLang('adminPassword_empty'); 113 } 114 115 if($animalname !== '' && file_exists(DOKU_FARMDIR . '/' . $animalname)) { 116 $errors[] = $this->getLang('animalname_preexisting'); 117 } 118 119 if($errors) { 120 foreach($errors as $error) { 121 msg($error, -1); 122 } 123 return false; 124 } 125 126 if(!is_dir(DOKU_FARMDIR . $template)) { 127 $template = ''; 128 } 129 130 return array( 131 'name' => $animalname, 132 'admin' => $adminsetup, 133 'pass' => $adminpass, 134 'template' => $template 135 ); 136 } 137 138 /** 139 * Create a new animal 140 * 141 * @param string $name name/title of the animal, will be the directory name for htaccess setup 142 * @param string $adminSetup newAdmin, currentAdmin or importUsers 143 * @param string $adminPassword required if $adminSetup is newAdmin 144 * @param string $template name of animal to copy 145 * @return bool true if successful 146 */ 147 protected function createNewAnimal($name, $adminSetup, $adminPassword, $template) { 148 $animaldir = DOKU_FARMDIR . $name; 149 150 // copy basic template 151 $ok = $this->helper->io_copyDir(__DIR__ . '/../_animal', $animaldir); 152 if(!$ok) { 153 msg($this->getLang('animal creation error'), -1); 154 return false; 155 } 156 157 // copy animal template 158 if($template != '') { 159 foreach(array('conf', 'data/pages', 'data/media', 'data/meta', 'data/media_meta', 'index') as $dir) { 160 $templatedir = DOKU_FARMDIR . $template . '/' . $dir; 161 if(!is_dir($templatedir)) continue; 162 // do not copy changelogs in meta 163 if(substr($dir, -4) == 'meta') { 164 $exclude = '/\.changes$/'; 165 } else { 166 $exclude = ''; 167 } 168 if(!$this->helper->io_copyDir($templatedir, $animaldir . '/' . $dir, $exclude)) { 169 msg(sprintf($this->getLang('animal template copy error'), $dir), -1); 170 // we go on anyway 171 } 172 } 173 } 174 175 // append title to local config 176 $ok &= io_saveFile($animaldir . '/conf/local.php', "\n" . '$conf[\'title\'] = \'' . $name . '\';' . "\n", true); 177 178 // create a random logo and favicon 179 if(!class_exists('\splitbrain\RingIcon\RingIcon', false)) { 180 require(__DIR__ . '/../3rdparty/RingIcon.php'); 181 } 182 if(!class_exists('\chrisbliss18\phpico\PHPIco', false)) { 183 require(__DIR__ . '/../3rdparty/PHPIco.php'); 184 } 185 try { 186 $ringicon = new \splitbrain\RingIcon\RingIcon(64); 187 $ringicon->createImage($animaldir, $animaldir . '/data/media/wiki/logo.png'); 188 $icongen = new \chrisbliss18\phpico\PHPIco($animaldir . '/data/media/wiki/logo.png'); 189 $icongen->save_ico($animaldir . '/data/media/wiki/favicon.ico'); 190 } catch(\Exception $ignore) { 191 // something went wrong, but we don't care. this is a nice to have feature only 192 } 193 194 // create admin user 195 if($adminSetup === 'newAdmin') { 196 $users = "# <?php exit()?>\n" . $this->makeAdminLine($adminPassword) . "\n"; 197 } elseif($adminSetup === 'currentAdmin') { 198 $users = "# <?php exit()?>\n" . $this->getAdminLine() . "\n"; 199 } elseif($adminSetup === 'noUsers') { 200 if(file_exists($animaldir . '/conf/users.auth.php')) { 201 // a user file exists already, probably from animal template - don't overwrite 202 $users = ''; 203 } else { 204 // create empty user file 205 $users = "# <?php exit()?>\n"; 206 } 207 } else { 208 $users = io_readFile(DOKU_CONF . 'users.auth.php'); 209 } 210 if($users) { 211 $ok &= io_saveFile($animaldir . '/conf/users.auth.php', $users); 212 } 213 214 // deactivate plugins by default FIXME this should be nicer 215 $deactivatedPluginsList = explode(',', $this->getConf('deactivated plugins')); 216 $deactivatedPluginsList = array_map('trim', $deactivatedPluginsList); 217 $deactivatedPluginsList = array_unique($deactivatedPluginsList); 218 $deactivatedPluginsList = array_filter($deactivatedPluginsList); 219 foreach($deactivatedPluginsList as $plugin) { 220 $this->helper->setPluginState(trim($plugin), $name, 0); 221 } 222 223 return $ok; 224 } 225 226 /** 227 * Creates a new user line 228 * 229 * @param $password 230 * @return string 231 */ 232 protected function makeAdminLine($password) { 233 $pass = auth_cryptPassword($password); 234 $line = join( 235 ':', array( 236 'admin', 237 $pass, 238 'Administrator', 239 'admin@example.org', 240 'admin,user' 241 ) 242 ); 243 return $line; 244 } 245 246 /** 247 * Copies the current user as new admin line 248 * 249 * @return string 250 */ 251 protected function getAdminLine() { 252 $currentAdmin = $_SERVER['REMOTE_USER']; 253 $masterUsers = file_get_contents(DOKU_CONF . 'users.auth.php'); 254 $masterUsers = ltrim(strstr($masterUsers, "\n" . $currentAdmin . ":")); 255 $newAdmin = substr($masterUsers, 0, strpos($masterUsers, "\n") + 1); 256 return $newAdmin; 257 } 258 259} 260 261// vim:ts=4:sw=4:et: 262