1bc461538SMichael Große<?php 2bc461538SMichael Große/** 3bc461538SMichael Große * DokuWiki Plugin farmer (Helper Component) 4bc461538SMichael Große * 5bc461538SMichael Große * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6bc461538SMichael Große * @author Michael Große <grosse@cosmocode.de> 7bc461538SMichael Große */ 8bc461538SMichael Große 9bc461538SMichael Große// must be run within Dokuwiki 10bc461538SMichael Großeif(!defined('DOKU_INC')) die(); 11bc461538SMichael Große 12bc461538SMichael Großeclass helper_plugin_farmer extends DokuWiki_Plugin { 13bc461538SMichael Große 14fcbe16a4SMichael Große private $allPlugins = array(); 15fcbe16a4SMichael Große 16bc461538SMichael Große /** 17632c5618SAndreas Gohr * Returns the name of the current animal if any, false otherwise 18632c5618SAndreas Gohr * 19632c5618SAndreas Gohr * @return string|false 20632c5618SAndreas Gohr */ 21632c5618SAndreas Gohr public function getAnimal() { 22*b96c66ccSAndreas Gohr if(!isset($GLOBALS['FARMCORE'])) return false; 23*b96c66ccSAndreas Gohr return $GLOBALS['FARMCORE']->getAnimal(); 24632c5618SAndreas Gohr } 25632c5618SAndreas Gohr 26632c5618SAndreas Gohr /** 27*b96c66ccSAndreas Gohr * Get the farm config 28*b96c66ccSAndreas Gohr * 29*b96c66ccSAndreas Gohr * @return array 30*b96c66ccSAndreas Gohr */ 31*b96c66ccSAndreas Gohr public function getConfig() { 32*b96c66ccSAndreas Gohr if(!isset($GLOBALS['FARMCORE'])) return array(); 33*b96c66ccSAndreas Gohr return $GLOBALS['FARMCORE']->getConfig(); 34*b96c66ccSAndreas Gohr } 35*b96c66ccSAndreas Gohr 36*b96c66ccSAndreas Gohr /** 37*b96c66ccSAndreas Gohr * Was the current animal requested by host? 38*b96c66ccSAndreas Gohr * 39*b96c66ccSAndreas Gohr * @return bool 40*b96c66ccSAndreas Gohr */ 41*b96c66ccSAndreas Gohr public function isHostbased() { 42*b96c66ccSAndreas Gohr if(!isset($GLOBALS['FARMCORE'])) return false; 43*b96c66ccSAndreas Gohr return $GLOBALS['FARMCORE']->isHostbased(); 44*b96c66ccSAndreas Gohr } 45*b96c66ccSAndreas Gohr 46*b96c66ccSAndreas Gohr /** 47*b96c66ccSAndreas Gohr * Was an animal requested that could not be found? 48*b96c66ccSAndreas Gohr * 49*b96c66ccSAndreas Gohr * @return bool 50*b96c66ccSAndreas Gohr */ 51*b96c66ccSAndreas Gohr public function wasNotfound() { 52*b96c66ccSAndreas Gohr if(!isset($GLOBALS['FARMCORE'])) return false; 53*b96c66ccSAndreas Gohr return $GLOBALS['FARMCORE']->wasNotfound(); 54*b96c66ccSAndreas Gohr } 55*b96c66ccSAndreas Gohr 56*b96c66ccSAndreas Gohr /** 57*b96c66ccSAndreas Gohr * List of all animals, i.e. directories within DOKU_FARMDIR without the template. 58*b96c66ccSAndreas Gohr * 59*b96c66ccSAndreas Gohr * @return array 60*b96c66ccSAndreas Gohr */ 61*b96c66ccSAndreas Gohr public function getAllAnimals() { 62*b96c66ccSAndreas Gohr $animals = array(); 63*b96c66ccSAndreas Gohr $list = glob(DOKU_FARMDIR . '/*/conf/', GLOB_ONLYDIR); 64*b96c66ccSAndreas Gohr foreach($list as $path) { 65*b96c66ccSAndreas Gohr $animal = basename(dirname($path)); 66*b96c66ccSAndreas Gohr if($animal == '_animal') continue; // old template 67*b96c66ccSAndreas Gohr $animals[] = $animal; 68*b96c66ccSAndreas Gohr } 69*b96c66ccSAndreas Gohr sort($animals); 70*b96c66ccSAndreas Gohr return $animals; 71*b96c66ccSAndreas Gohr } 72*b96c66ccSAndreas Gohr 73*b96c66ccSAndreas Gohr /** 74*b96c66ccSAndreas Gohr * checks wether $path is in under $container 75*b96c66ccSAndreas Gohr * 76*b96c66ccSAndreas Gohr * @param string $path 77*b96c66ccSAndreas Gohr * @param string $container 78*b96c66ccSAndreas Gohr * @return bool 79*b96c66ccSAndreas Gohr */ 80*b96c66ccSAndreas Gohr public function isInPath ($path, $container) { 81*b96c66ccSAndreas Gohr return (strpos(fullpath($path), fullpath($container)) === 0); 82*b96c66ccSAndreas Gohr } 83*b96c66ccSAndreas Gohr 84*b96c66ccSAndreas Gohr /** 85*b96c66ccSAndreas Gohr * Check if the farm is correctly configured for this farmer plugin 86*b96c66ccSAndreas Gohr * 87*b96c66ccSAndreas Gohr * @return bool 88*b96c66ccSAndreas Gohr */ 89*b96c66ccSAndreas Gohr public function checkFarmSetup () { 90*b96c66ccSAndreas Gohr return defined('DOKU_FARMDIR') && isset($GLOBALS['FARMCORE']); 91*b96c66ccSAndreas Gohr } 92*b96c66ccSAndreas Gohr 93*b96c66ccSAndreas Gohr 94*b96c66ccSAndreas Gohr 95*b96c66ccSAndreas Gohr 96*b96c66ccSAndreas Gohr 97*b96c66ccSAndreas Gohr 98*b96c66ccSAndreas Gohr 99*b96c66ccSAndreas Gohr 100*b96c66ccSAndreas Gohr /** 101bc461538SMichael Große * Copy a file, or recursively copy a folder and its contents. Adapted for DokuWiki. 102bc461538SMichael Große * 103bc461538SMichael Große * @todo: needs tests 104bc461538SMichael Große * 105bc461538SMichael Große * @author Aidan Lister <aidan@php.net> 106bc461538SMichael Große * @author Michael Große <grosse@cosmocode.de> 107bc461538SMichael Große * @version 1.0.1 108bc461538SMichael Große * @link http://aidanlister.com/2004/04/recursively-copying-directories-in-php/ 109bc461538SMichael Große * 110bc461538SMichael Große * @param string $source Source path 111bc461538SMichael Große * @param string $destination Destination path 112bc461538SMichael Große * 113bc461538SMichael Große * @return bool Returns TRUE on success, FALSE on failure 114bc461538SMichael Große */ 115bc461538SMichael Große function io_copyDir($source, $destination) { 116bc461538SMichael Große if (is_link($source)) { 117bc461538SMichael Große io_lock($destination); 118bc461538SMichael Große $result=symlink(readlink($source), $destination); 119bc461538SMichael Große io_unlock($destination); 120bc461538SMichael Große return $result; 121bc461538SMichael Große } 122bc461538SMichael Große 123bc461538SMichael Große if (is_file($source)) { 124bc461538SMichael Große io_lock($destination); 125bc461538SMichael Große $result=copy($source, $destination); 126bc461538SMichael Große io_unlock($destination); 127bc461538SMichael Große return $result; 128bc461538SMichael Große } 129bc461538SMichael Große 130bc461538SMichael Große if (!is_dir($destination)) { 131bc461538SMichael Große io_mkdir_p($destination); 132bc461538SMichael Große } 133bc461538SMichael Große 134bc461538SMichael Große $dir = dir($source); 135bc461538SMichael Große while (false !== ($entry = $dir->read())) { 136bc461538SMichael Große if ($entry == '.' || $entry == '..') { 137bc461538SMichael Große continue; 138bc461538SMichael Große } 139bc461538SMichael Große 140bc461538SMichael Große // recurse into directories 141bc461538SMichael Große $this->io_copyDir("$source/$entry", "$destination/$entry"); 142bc461538SMichael Große } 143bc461538SMichael Große 144bc461538SMichael Große $dir->close(); 145bc461538SMichael Große return true; 146bc461538SMichael Große } 147bc461538SMichael Große 14816bbfe4bSMichael Große /** 14916bbfe4bSMichael Große * get a list of all Plugins installed in the farmer wiki, regardless whether they are active or not. 15016bbfe4bSMichael Große * 15116bbfe4bSMichael Große * @return array 15216bbfe4bSMichael Große */ 1530b96e6d7SMichael Große public function getAllPlugins() { 1540b96e6d7SMichael Große $dir = dir(DOKU_PLUGIN); 1550b96e6d7SMichael Große $plugins = array(); 1560b96e6d7SMichael Große while (false !== ($entry = $dir->read())) { 1573949d8a1SMichael Große if($entry == '.' || $entry == '..' || $entry == 'testing' || $entry == 'farmer') { 1580b96e6d7SMichael Große continue; 1590b96e6d7SMichael Große } 1600b96e6d7SMichael Große if (!is_dir(DOKU_PLUGIN ."/$entry")) { 1610b96e6d7SMichael Große continue; 1620b96e6d7SMichael Große } 1630b96e6d7SMichael Große $plugins[] = $entry; 1640b96e6d7SMichael Große } 1656ec1ad8fSMichael Große sort($plugins); 1660b96e6d7SMichael Große return $plugins; 1670b96e6d7SMichael Große } 1680b96e6d7SMichael Große 1690b96e6d7SMichael Große 17016bbfe4bSMichael Große /** 17116bbfe4bSMichael Große * Actiate a specific plugin in a specific animal 17216bbfe4bSMichael Große * 17316bbfe4bSMichael Große * @param string $plugin Name of the plugin to be activated 17416bbfe4bSMichael Große * @param string $animal Directory of the animal within DOKU_FARMDIR 17516bbfe4bSMichael Große */ 176fcbe16a4SMichael Große public function activatePlugin($plugin, $animal) { 177fcbe16a4SMichael Große if (isset($this->allPlugins[$animal])) { 178fcbe16a4SMichael Große $plugins = $this->allPlugins[$animal]; 179fcbe16a4SMichael Große } else { 180fcbe16a4SMichael Große include(DOKU_FARMDIR . $animal . '/conf/plugins.local.php'); 181fcbe16a4SMichael Große } 182fcbe16a4SMichael Große if (isset($plugins[$plugin]) && $plugins[$plugin] === 0) { 183fcbe16a4SMichael Große unset($plugins[$plugin]); 184fcbe16a4SMichael Große $this->writePluginConf($plugins, $animal); 185fcbe16a4SMichael Große } 186fcbe16a4SMichael Große $this->allPlugins[$animal] = $plugins; 187fcbe16a4SMichael Große } 188fcbe16a4SMichael Große 189a0fc814bSMichael Große /** 19016bbfe4bSMichael Große * @param string $plugin Name of the plugin to be deactivated 19116bbfe4bSMichael Große * @param string $animal Directory of the animal within DOKU_FARMDIR 192a0fc814bSMichael Große */ 193fcbe16a4SMichael Große public function deactivatePlugin($plugin, $animal) { 194fcbe16a4SMichael Große if (isset($this->allPlugins[$animal])) { 195fcbe16a4SMichael Große $plugins = $this->allPlugins[$animal]; 196fcbe16a4SMichael Große } else { 197fcbe16a4SMichael Große include(DOKU_FARMDIR . $animal . '/conf/plugins.local.php'); 198fcbe16a4SMichael Große } 199fcbe16a4SMichael Große if (!isset($plugins[$plugin]) || $plugins[$plugin] !== 0) { 200fcbe16a4SMichael Große $plugins[$plugin] = 0; 201fcbe16a4SMichael Große $this->writePluginConf($plugins, $animal); 202fcbe16a4SMichael Große } 203fcbe16a4SMichael Große $this->allPlugins[$animal] = $plugins; 204fcbe16a4SMichael Große } 205fcbe16a4SMichael Große 20616bbfe4bSMichael Große /** 20716bbfe4bSMichael Große * Write the list of (deactivated) plugins as plugin configuration of an animal to file 20816bbfe4bSMichael Große * 20916bbfe4bSMichael Große * @param array $plugins associative array with the key being the plugin name and the value 0 or 1 21016bbfe4bSMichael Große * @param string $animal Directory of the animal within DOKU_FARMDIR 21116bbfe4bSMichael Große */ 212fcbe16a4SMichael Große public function writePluginConf($plugins, $animal) { 213fcbe16a4SMichael Große $pluginConf = '<?php' . "\n"; 214fcbe16a4SMichael Große foreach ($plugins as $plugin => $status) { 215fcbe16a4SMichael Große $pluginConf .= '$plugins["' . $plugin . '"] = ' . $status . ";\n"; 216fcbe16a4SMichael Große } 217fcbe16a4SMichael Große io_saveFile(DOKU_FARMDIR . $animal . '/conf/plugins.local.php', $pluginConf); 218fcbe16a4SMichael Große touch(DOKU_FARMDIR . $animal . '/conf/local.php'); 219fcbe16a4SMichael Große } 220fcbe16a4SMichael Große 22116bbfe4bSMichael Große /** 22216bbfe4bSMichael Große * Show a message for all errors which occured during form validation 22316bbfe4bSMichael Große * 22416bbfe4bSMichael Große * @param \dokuwiki\Form\Form $form The form to which the errors should be added. 22516bbfe4bSMichael Große * @param array $errorArray An associative array with the key being the name of the element at fault 22616bbfe4bSMichael Große * and the value being the associated error message. 22716bbfe4bSMichael Große */ 228a12b96c0SMichael Große public function addErrorsToForm(\dokuwiki\Form\Form &$form, $errorArray) { 229628ea26fSMichael Große foreach ($errorArray as $elementName => $errorMessage) { 230628ea26fSMichael Große $offset = 0; 231628ea26fSMichael Große msg($errorMessage, -1); 232628ea26fSMichael Große while ($form->findPositionByAttribute('name',$elementName, $offset)) { 233628ea26fSMichael Große $offset = $form->findPositionByAttribute('name',$elementName, $offset); 234628ea26fSMichael Große $form->getElementAt($offset)->addClass('error'); 235628ea26fSMichael Große ++$offset; 236a12b96c0SMichael Große } 237a12b96c0SMichael Große } 238a12b96c0SMichael Große } 239a12b96c0SMichael Große 24016bbfe4bSMichael Große /** 24116bbfe4bSMichael Große * @param string|null $page load adminpage $page, reload the current page if $page is ommited or null 24216bbfe4bSMichael Große */ 2434d120480SMichael Große public function reloadAdminPage($page = null) { 2444d120480SMichael Große global $ID; 2454d120480SMichael Große $get = $_GET; 2464d120480SMichael Große if(isset($get['id'])) unset($get['id']); 2474d120480SMichael Große if ($page !== null ) { 2484d120480SMichael Große $get['page'] = $page; 2494d120480SMichael Große } 2504d120480SMichael Große $self = wl($ID, $get, false, '&'); 2514d120480SMichael Große send_redirect($self); 2524d120480SMichael Große } 2534d120480SMichael Große 25416bbfe4bSMichael Große /** 25516bbfe4bSMichael Große * Download and extract the animal template 25616bbfe4bSMichael Große * 25716bbfe4bSMichael Große * @param string $animalpath 25816bbfe4bSMichael Große * 25916bbfe4bSMichael Große * @throws \splitbrain\PHPArchive\ArchiveIOException 26016bbfe4bSMichael Große */ 26179435a6fSMichael Große public function downloadTemplate($animalpath) { 26279435a6fSMichael Große file_put_contents($animalpath . '/_animal.zip',fopen('https://www.dokuwiki.org/_media/dokuwiki_farm_animal.zip','r')); 263c9fd7b89SMichael Große $zip = new splitbrain\PHPArchive\Zip(); 26479435a6fSMichael Große $zip->open($animalpath.'/_animal.zip'); 265c9fd7b89SMichael Große $zip->extract($animalpath); 26679435a6fSMichael Große $zip->close(); 26779435a6fSMichael Große unlink($animalpath.'/_animal.zip'); 26879435a6fSMichael Große } 26979435a6fSMichael Große 270d9ec4524SMichael Große 27180ef674eSMichael Große /** 27280ef674eSMichael Große * The subdomain must contain at least two dots 27380ef674eSMichael Große * 27480ef674eSMichael Große * @link http://stackoverflow.com/questions/17986371/regular-expression-to-validate-fqdn-in-c-sharp-and-javascript 27580ef674eSMichael Große * 27680ef674eSMichael Große * @param string $subdomain 27780ef674eSMichael Große * 27880ef674eSMichael Große * @return bool 27980ef674eSMichael Große */ 28080ef674eSMichael Große public function validateSubdomain ($subdomain) { 28180ef674eSMichael Große return preg_match("/^(?=.{1,254}$)((?=[a-z0-9-]{1,63}\.)(xn--+)?[a-z0-9]+(-[a-z0-9]+)*\.){2,}[a-z]{2,63}$/i",$subdomain) === 1; 28280ef674eSMichael Große } 28380ef674eSMichael Große 284909f2ff6SMichael Große /** 285909f2ff6SMichael Große * @param string $animalname 286909f2ff6SMichael Große * 287909f2ff6SMichael Große * @return bool 288909f2ff6SMichael Große */ 289909f2ff6SMichael Große public function validateAnimalName ($animalname) { 290909f2ff6SMichael Große return preg_match("/^[a-z0-9]+(-[a-z0-9]+)*$/i",$animalname) === 1; 291909f2ff6SMichael Große } 292909f2ff6SMichael Große 293c66a21e9SMichael Große /** 294c66a21e9SMichael Große * @return string 295c66a21e9SMichael Große */ 296c66a21e9SMichael Große public function getUserLine($currentAdmin) { 297c66a21e9SMichael Große $masterUsers = file_get_contents(DOKU_CONF . 'users.auth.php'); 298c66a21e9SMichael Große $masterUsers = ltrim(strstr($masterUsers, "\n" . $currentAdmin . ":")); 299c66a21e9SMichael Große $newAdmin = substr($masterUsers, 0, strpos($masterUsers, "\n") + 1); 300c66a21e9SMichael Große return $newAdmin; 301c66a21e9SMichael Große } 302c66a21e9SMichael Große 303bc461538SMichael Große} 304