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 /** 17*632c5618SAndreas Gohr * Returns the name of the current animal if any, false otherwise 18*632c5618SAndreas Gohr * 19*632c5618SAndreas Gohr * @return string|false 20*632c5618SAndreas Gohr */ 21*632c5618SAndreas Gohr public function getAnimal() { 22*632c5618SAndreas Gohr if(defined('DOKU_FARM_ANIMAL')) return DOKU_FARM_ANIMAL; 23*632c5618SAndreas Gohr return false; 24*632c5618SAndreas Gohr } 25*632c5618SAndreas Gohr 26*632c5618SAndreas Gohr /** 27bc461538SMichael Große * Copy a file, or recursively copy a folder and its contents. Adapted for DokuWiki. 28bc461538SMichael Große * 29bc461538SMichael Große * @todo: needs tests 30bc461538SMichael Große * 31bc461538SMichael Große * @author Aidan Lister <aidan@php.net> 32bc461538SMichael Große * @author Michael Große <grosse@cosmocode.de> 33bc461538SMichael Große * @version 1.0.1 34bc461538SMichael Große * @link http://aidanlister.com/2004/04/recursively-copying-directories-in-php/ 35bc461538SMichael Große * 36bc461538SMichael Große * @param string $source Source path 37bc461538SMichael Große * @param string $destination Destination path 38bc461538SMichael Große * 39bc461538SMichael Große * @return bool Returns TRUE on success, FALSE on failure 40bc461538SMichael Große */ 41bc461538SMichael Große function io_copyDir($source, $destination) { 42bc461538SMichael Große if (is_link($source)) { 43bc461538SMichael Große io_lock($destination); 44bc461538SMichael Große $result=symlink(readlink($source), $destination); 45bc461538SMichael Große io_unlock($destination); 46bc461538SMichael Große return $result; 47bc461538SMichael Große } 48bc461538SMichael Große 49bc461538SMichael Große if (is_file($source)) { 50bc461538SMichael Große io_lock($destination); 51bc461538SMichael Große $result=copy($source, $destination); 52bc461538SMichael Große io_unlock($destination); 53bc461538SMichael Große return $result; 54bc461538SMichael Große } 55bc461538SMichael Große 56bc461538SMichael Große if (!is_dir($destination)) { 57bc461538SMichael Große io_mkdir_p($destination); 58bc461538SMichael Große } 59bc461538SMichael Große 60bc461538SMichael Große $dir = dir($source); 61bc461538SMichael Große while (false !== ($entry = $dir->read())) { 62bc461538SMichael Große if ($entry == '.' || $entry == '..') { 63bc461538SMichael Große continue; 64bc461538SMichael Große } 65bc461538SMichael Große 66bc461538SMichael Große // recurse into directories 67bc461538SMichael Große $this->io_copyDir("$source/$entry", "$destination/$entry"); 68bc461538SMichael Große } 69bc461538SMichael Große 70bc461538SMichael Große $dir->close(); 71bc461538SMichael Große return true; 72bc461538SMichael Große } 73bc461538SMichael Große 7416bbfe4bSMichael Große /** 7516bbfe4bSMichael Große * get a list of all Plugins installed in the farmer wiki, regardless whether they are active or not. 7616bbfe4bSMichael Große * 7716bbfe4bSMichael Große * @return array 7816bbfe4bSMichael Große */ 790b96e6d7SMichael Große public function getAllPlugins() { 800b96e6d7SMichael Große $dir = dir(DOKU_PLUGIN); 810b96e6d7SMichael Große $plugins = array(); 820b96e6d7SMichael Große while (false !== ($entry = $dir->read())) { 833949d8a1SMichael Große if($entry == '.' || $entry == '..' || $entry == 'testing' || $entry == 'farmer') { 840b96e6d7SMichael Große continue; 850b96e6d7SMichael Große } 860b96e6d7SMichael Große if (!is_dir(DOKU_PLUGIN ."/$entry")) { 870b96e6d7SMichael Große continue; 880b96e6d7SMichael Große } 890b96e6d7SMichael Große $plugins[] = $entry; 900b96e6d7SMichael Große } 916ec1ad8fSMichael Große sort($plugins); 920b96e6d7SMichael Große return $plugins; 930b96e6d7SMichael Große } 940b96e6d7SMichael Große 9516bbfe4bSMichael Große /** 9616bbfe4bSMichael Große * List of all animals, i.e. directories within DOKU_FARMDIR without the template. 9716bbfe4bSMichael Große * 9816bbfe4bSMichael Große * @return array 9916bbfe4bSMichael Große */ 1000b96e6d7SMichael Große public function getAllAnimals() { 1010b96e6d7SMichael Große $animals = array(); 1020b96e6d7SMichael Große 1030b96e6d7SMichael Große $dir = dir(DOKU_FARMDIR); 1040b96e6d7SMichael Große while (false !== ($entry = $dir->read())) { 105a0fc814bSMichael Große if ($entry == '.' || $entry == '..' || $entry == '_animal' || $entry == '.htaccess') { 106a0fc814bSMichael Große continue; 107a0fc814bSMichael Große } 108a0fc814bSMichael Große if (!is_dir(DOKU_FARMDIR . $entry)) { 1090b96e6d7SMichael Große continue; 1100b96e6d7SMichael Große } 1110b96e6d7SMichael Große $animals[] = $entry; 1120b96e6d7SMichael Große } 1130b96e6d7SMichael Große $dir->close(); 1140b96e6d7SMichael Große return $animals; 1150b96e6d7SMichael Große } 1160b96e6d7SMichael Große 11716bbfe4bSMichael Große /** 11816bbfe4bSMichael Große * Actiate a specific plugin in a specific animal 11916bbfe4bSMichael Große * 12016bbfe4bSMichael Große * @param string $plugin Name of the plugin to be activated 12116bbfe4bSMichael Große * @param string $animal Directory of the animal within DOKU_FARMDIR 12216bbfe4bSMichael Große */ 123fcbe16a4SMichael Große public function activatePlugin($plugin, $animal) { 124fcbe16a4SMichael Große if (isset($this->allPlugins[$animal])) { 125fcbe16a4SMichael Große $plugins = $this->allPlugins[$animal]; 126fcbe16a4SMichael Große } else { 127fcbe16a4SMichael Große include(DOKU_FARMDIR . $animal . '/conf/plugins.local.php'); 128fcbe16a4SMichael Große } 129fcbe16a4SMichael Große if (isset($plugins[$plugin]) && $plugins[$plugin] === 0) { 130fcbe16a4SMichael Große unset($plugins[$plugin]); 131fcbe16a4SMichael Große $this->writePluginConf($plugins, $animal); 132fcbe16a4SMichael Große } 133fcbe16a4SMichael Große $this->allPlugins[$animal] = $plugins; 134fcbe16a4SMichael Große } 135fcbe16a4SMichael Große 136a0fc814bSMichael Große /** 13716bbfe4bSMichael Große * @param string $plugin Name of the plugin to be deactivated 13816bbfe4bSMichael Große * @param string $animal Directory of the animal within DOKU_FARMDIR 139a0fc814bSMichael Große */ 140fcbe16a4SMichael Große public function deactivatePlugin($plugin, $animal) { 141fcbe16a4SMichael Große if (isset($this->allPlugins[$animal])) { 142fcbe16a4SMichael Große $plugins = $this->allPlugins[$animal]; 143fcbe16a4SMichael Große } else { 144fcbe16a4SMichael Große include(DOKU_FARMDIR . $animal . '/conf/plugins.local.php'); 145fcbe16a4SMichael Große } 146fcbe16a4SMichael Große if (!isset($plugins[$plugin]) || $plugins[$plugin] !== 0) { 147fcbe16a4SMichael Große $plugins[$plugin] = 0; 148fcbe16a4SMichael Große $this->writePluginConf($plugins, $animal); 149fcbe16a4SMichael Große } 150fcbe16a4SMichael Große $this->allPlugins[$animal] = $plugins; 151fcbe16a4SMichael Große } 152fcbe16a4SMichael Große 15316bbfe4bSMichael Große /** 15416bbfe4bSMichael Große * Write the list of (deactivated) plugins as plugin configuration of an animal to file 15516bbfe4bSMichael Große * 15616bbfe4bSMichael Große * @param array $plugins associative array with the key being the plugin name and the value 0 or 1 15716bbfe4bSMichael Große * @param string $animal Directory of the animal within DOKU_FARMDIR 15816bbfe4bSMichael Große */ 159fcbe16a4SMichael Große public function writePluginConf($plugins, $animal) { 160fcbe16a4SMichael Große $pluginConf = '<?php' . "\n"; 161fcbe16a4SMichael Große foreach ($plugins as $plugin => $status) { 162fcbe16a4SMichael Große $pluginConf .= '$plugins["' . $plugin . '"] = ' . $status . ";\n"; 163fcbe16a4SMichael Große } 164fcbe16a4SMichael Große io_saveFile(DOKU_FARMDIR . $animal . '/conf/plugins.local.php', $pluginConf); 165fcbe16a4SMichael Große touch(DOKU_FARMDIR . $animal . '/conf/local.php'); 166fcbe16a4SMichael Große } 167fcbe16a4SMichael Große 16816bbfe4bSMichael Große /** 16916bbfe4bSMichael Große * Show a message for all errors which occured during form validation 17016bbfe4bSMichael Große * 17116bbfe4bSMichael Große * @param \dokuwiki\Form\Form $form The form to which the errors should be added. 17216bbfe4bSMichael Große * @param array $errorArray An associative array with the key being the name of the element at fault 17316bbfe4bSMichael Große * and the value being the associated error message. 17416bbfe4bSMichael Große */ 175a12b96c0SMichael Große public function addErrorsToForm(\dokuwiki\Form\Form &$form, $errorArray) { 176628ea26fSMichael Große foreach ($errorArray as $elementName => $errorMessage) { 177628ea26fSMichael Große $offset = 0; 178628ea26fSMichael Große msg($errorMessage, -1); 179628ea26fSMichael Große while ($form->findPositionByAttribute('name',$elementName, $offset)) { 180628ea26fSMichael Große $offset = $form->findPositionByAttribute('name',$elementName, $offset); 181628ea26fSMichael Große $form->getElementAt($offset)->addClass('error'); 182628ea26fSMichael Große ++$offset; 183a12b96c0SMichael Große } 184a12b96c0SMichael Große } 185a12b96c0SMichael Große } 186a12b96c0SMichael Große 18716bbfe4bSMichael Große /** 18816bbfe4bSMichael Große * @param string|null $page load adminpage $page, reload the current page if $page is ommited or null 18916bbfe4bSMichael Große */ 1904d120480SMichael Große public function reloadAdminPage($page = null) { 1914d120480SMichael Große global $ID; 1924d120480SMichael Große $get = $_GET; 1934d120480SMichael Große if(isset($get['id'])) unset($get['id']); 1944d120480SMichael Große if ($page !== null ) { 1954d120480SMichael Große $get['page'] = $page; 1964d120480SMichael Große } 1974d120480SMichael Große $self = wl($ID, $get, false, '&'); 1984d120480SMichael Große send_redirect($self); 1994d120480SMichael Große } 2004d120480SMichael Große 20116bbfe4bSMichael Große /** 20216bbfe4bSMichael Große * Download and extract the animal template 20316bbfe4bSMichael Große * 20416bbfe4bSMichael Große * @param string $animalpath 20516bbfe4bSMichael Große * 20616bbfe4bSMichael Große * @throws \splitbrain\PHPArchive\ArchiveIOException 20716bbfe4bSMichael Große */ 20879435a6fSMichael Große public function downloadTemplate($animalpath) { 20979435a6fSMichael Große file_put_contents($animalpath . '/_animal.zip',fopen('https://www.dokuwiki.org/_media/dokuwiki_farm_animal.zip','r')); 210c9fd7b89SMichael Große $zip = new splitbrain\PHPArchive\Zip(); 21179435a6fSMichael Große $zip->open($animalpath.'/_animal.zip'); 212c9fd7b89SMichael Große $zip->extract($animalpath); 21379435a6fSMichael Große $zip->close(); 21479435a6fSMichael Große unlink($animalpath.'/_animal.zip'); 21579435a6fSMichael Große } 21679435a6fSMichael Große 217efa7af45SMichael Große /** 218*632c5618SAndreas Gohr * checks wether $path is in under $container 219efa7af45SMichael Große * 220*632c5618SAndreas Gohr * @param string $path 221*632c5618SAndreas Gohr * @param string $container 222efa7af45SMichael Große * @return bool 223efa7af45SMichael Große */ 224efa7af45SMichael Große public function isInPath ($path, $container) { 225*632c5618SAndreas Gohr return (strpos(fullpath($path), fullpath($container)) === 0); 226efa7af45SMichael Große } 227efa7af45SMichael Große 228d9ec4524SMichael Große /** 22916bbfe4bSMichael Große * Check if the farm is correctly configured for this farmer plugin 23016bbfe4bSMichael Große * 231d9ec4524SMichael Große * @return bool 232d9ec4524SMichael Große */ 233d9ec4524SMichael Große public function checkFarmSetup () { 234*632c5618SAndreas Gohr return defined('DOKU_FARMDIR'); 235d9ec4524SMichael Große } 236d9ec4524SMichael Große 23780ef674eSMichael Große /** 23880ef674eSMichael Große * The subdomain must contain at least two dots 23980ef674eSMichael Große * 24080ef674eSMichael Große * @link http://stackoverflow.com/questions/17986371/regular-expression-to-validate-fqdn-in-c-sharp-and-javascript 24180ef674eSMichael Große * 24280ef674eSMichael Große * @param string $subdomain 24380ef674eSMichael Große * 24480ef674eSMichael Große * @return bool 24580ef674eSMichael Große */ 24680ef674eSMichael Große public function validateSubdomain ($subdomain) { 24780ef674eSMichael 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; 24880ef674eSMichael Große } 24980ef674eSMichael Große 250909f2ff6SMichael Große /** 251909f2ff6SMichael Große * @param string $animalname 252909f2ff6SMichael Große * 253909f2ff6SMichael Große * @return bool 254909f2ff6SMichael Große */ 255909f2ff6SMichael Große public function validateAnimalName ($animalname) { 256909f2ff6SMichael Große return preg_match("/^[a-z0-9]+(-[a-z0-9]+)*$/i",$animalname) === 1; 257909f2ff6SMichael Große } 258909f2ff6SMichael Große 259c66a21e9SMichael Große /** 260c66a21e9SMichael Große * @return string 261c66a21e9SMichael Große */ 262c66a21e9SMichael Große public function getUserLine($currentAdmin) { 263c66a21e9SMichael Große $masterUsers = file_get_contents(DOKU_CONF . 'users.auth.php'); 264c66a21e9SMichael Große $masterUsers = ltrim(strstr($masterUsers, "\n" . $currentAdmin . ":")); 265c66a21e9SMichael Große $newAdmin = substr($masterUsers, 0, strpos($masterUsers, "\n") + 1); 266c66a21e9SMichael Große return $newAdmin; 267c66a21e9SMichael Große } 268c66a21e9SMichael Große 269bc461538SMichael Große} 270