1da0ae2c0SAndreas Gohr<?php 2da0ae2c0SAndreas Gohr 31da41c8bSAndreas Gohr// phpcs:disable PSR1.Files.SideEffects 4a646d519SAndreas Gohr/** 5a646d519SAndreas Gohr * Core Manager for the Farm functionality 6a646d519SAndreas Gohr * 7a646d519SAndreas Gohr * This class is initialized before any other DokuWiki code runs. Therefore it is 8a646d519SAndreas Gohr * completely selfcontained and does not use any of DokuWiki's utility functions. 9a646d519SAndreas Gohr * 10b96c66ccSAndreas Gohr * It's registered as a global $FARMCORE variable but you should not interact with 11b96c66ccSAndreas Gohr * it directly. Instead use the Farmer plugin's helper component. 120a5d2da2SAndreas Gohr * 130a5d2da2SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 140a5d2da2SAndreas Gohr * @author Andreas Gohr <gohr@cosmocode.de> 15a646d519SAndreas Gohr */ 161da41c8bSAndreas Gohrclass DokuWikiFarmCore 171da41c8bSAndreas Gohr{ 18da0ae2c0SAndreas Gohr /** 19da0ae2c0SAndreas Gohr * @var array The default config - changed by loadConfig 20da0ae2c0SAndreas Gohr */ 211da41c8bSAndreas Gohr protected $config = [ 221da41c8bSAndreas Gohr 'base' => [ 23a646d519SAndreas Gohr 'farmdir' => '', 24c4c8e953SAndreas Gohr 'farmhost' => '', 251da41c8bSAndreas Gohr 'basedomain' => '' 261da41c8bSAndreas Gohr ], 271da41c8bSAndreas Gohr 'notfound' => [ 28da0ae2c0SAndreas Gohr 'show' => 'farmer', 29da0ae2c0SAndreas Gohr 'url' => '' 301da41c8bSAndreas Gohr ], 311da41c8bSAndreas Gohr 'inherit' => [ 32da0ae2c0SAndreas Gohr 'main' => 1, 33da0ae2c0SAndreas Gohr 'acronyms' => 1, 34da0ae2c0SAndreas Gohr 'entities' => 1, 35da0ae2c0SAndreas Gohr 'interwiki' => 1, 36da0ae2c0SAndreas Gohr 'license' => 1, 37da0ae2c0SAndreas Gohr 'mime' => 1, 38da0ae2c0SAndreas Gohr 'scheme' => 1, 39da0ae2c0SAndreas Gohr 'smileys' => 1, 40da0ae2c0SAndreas Gohr 'wordblock' => 1, 411272da0cSAndreas Gohr 'users' => 0, 42af1c6dd8SAndreas Gohr 'plugins' => 0, 43da0ae2c0SAndreas Gohr 'userstyle' => 0, 4405ea7625SAnna Dabrowska 'userscript' => 0, 453cee9885SAnna Dabrowska 'styleini' => 0 461da41c8bSAndreas Gohr ] 471da41c8bSAndreas Gohr ]; 48da0ae2c0SAndreas Gohr 49a646d519SAndreas Gohr /** @var string|false The current animal, false for farmer */ 50a646d519SAndreas Gohr protected $animal = false; 51a646d519SAndreas Gohr /** @var bool true if an animal was requested but was not found */ 52a646d519SAndreas Gohr protected $notfound = false; 53a646d519SAndreas Gohr /** @var bool true if the current animal was requested by host */ 54a646d519SAndreas Gohr protected $hostbased = false; 55a646d519SAndreas Gohr 56da0ae2c0SAndreas Gohr /** 57da0ae2c0SAndreas Gohr * DokuWikiFarmCore constructor. 58da0ae2c0SAndreas Gohr * 59a646d519SAndreas Gohr * This initializes the whole farm by loading the configuration and setting 60a646d519SAndreas Gohr * DOKU_CONF depending on the requested animal 61da0ae2c0SAndreas Gohr */ 621da41c8bSAndreas Gohr public function __construct() 631da41c8bSAndreas Gohr { 64da0ae2c0SAndreas Gohr $this->loadConfig(); 65a646d519SAndreas Gohr if ($this->config['base']['farmdir'] === '') return; // farm setup not complete 668262a4cbSAndreas Gohr $this->config['base']['farmdir'] = rtrim($this->config['base']['farmdir'], '/') . '/'; // trailing slash always 6749f2871cSAndreas Gohr define('DOKU_FARMDIR', $this->config['base']['farmdir']); 68a646d519SAndreas Gohr 69a646d519SAndreas Gohr // animal? 70a646d519SAndreas Gohr $this->detectAnimal(); 71a646d519SAndreas Gohr 72a646d519SAndreas Gohr // setup defines 73a646d519SAndreas Gohr define('DOKU_FARM_ANIMAL', $this->animal); 74a646d519SAndreas Gohr if ($this->animal) { 758262a4cbSAndreas Gohr define('DOKU_CONF', DOKU_FARMDIR . $this->animal . '/conf/'); 76a646d519SAndreas Gohr } else { 77a646d519SAndreas Gohr define('DOKU_CONF', DOKU_INC . '/conf/'); 78a646d519SAndreas Gohr } 79a646d519SAndreas Gohr 80a646d519SAndreas Gohr $this->setupCascade(); 81a646d519SAndreas Gohr $this->adjustCascade(); 82da0ae2c0SAndreas Gohr } 83da0ae2c0SAndreas Gohr 84da0ae2c0SAndreas Gohr /** 85da0ae2c0SAndreas Gohr * @return array the current farm configuration 86da0ae2c0SAndreas Gohr */ 871da41c8bSAndreas Gohr public function getConfig() 881da41c8bSAndreas Gohr { 89da0ae2c0SAndreas Gohr return $this->config; 90da0ae2c0SAndreas Gohr } 91da0ae2c0SAndreas Gohr 92da0ae2c0SAndreas Gohr /** 93a646d519SAndreas Gohr * @return false|string 94a646d519SAndreas Gohr */ 951da41c8bSAndreas Gohr public function getAnimal() 961da41c8bSAndreas Gohr { 97a646d519SAndreas Gohr return $this->animal; 98a646d519SAndreas Gohr } 99a646d519SAndreas Gohr 100a646d519SAndreas Gohr /** 101a646d519SAndreas Gohr * @return boolean 102a646d519SAndreas Gohr */ 1031da41c8bSAndreas Gohr public function isHostbased() 1041da41c8bSAndreas Gohr { 105a646d519SAndreas Gohr return $this->hostbased; 106a646d519SAndreas Gohr } 107a646d519SAndreas Gohr 108a646d519SAndreas Gohr /** 109a646d519SAndreas Gohr * @return boolean 110a646d519SAndreas Gohr */ 1111da41c8bSAndreas Gohr public function wasNotfound() 1121da41c8bSAndreas Gohr { 113a646d519SAndreas Gohr return $this->notfound; 114a646d519SAndreas Gohr } 115a646d519SAndreas Gohr 116a646d519SAndreas Gohr /** 117b330074aSAndreas Gohr * @return string 118b330074aSAndreas Gohr */ 1191da41c8bSAndreas Gohr public function getAnimalDataDir() 1201da41c8bSAndreas Gohr { 1218262a4cbSAndreas Gohr return DOKU_FARMDIR . $this->getAnimal() . '/data/'; 122b330074aSAndreas Gohr } 123b330074aSAndreas Gohr 124b330074aSAndreas Gohr /** 125b330074aSAndreas Gohr * @return string 126b330074aSAndreas Gohr */ 1271da41c8bSAndreas Gohr public function getAnimalBaseDir() 1281da41c8bSAndreas Gohr { 12904dc6bd5SSzymon Olewniczak if ($this->isHostbased()) return '/'; 130b330074aSAndreas Gohr return getBaseURL() . '!' . $this->getAnimal(); 131b330074aSAndreas Gohr } 132b330074aSAndreas Gohr 133b330074aSAndreas Gohr /** 134a646d519SAndreas Gohr * Detect the current animal 135a646d519SAndreas Gohr * 136a646d519SAndreas Gohr * Sets internal members $animal, $notfound and $hostbased 137a646d519SAndreas Gohr * 138a646d519SAndreas Gohr * This borrows form DokuWiki's inc/farm.php but does not support a default conf dir 139a646d519SAndreas Gohr */ 1401da41c8bSAndreas Gohr protected function detectAnimal() 1411da41c8bSAndreas Gohr { 142a646d519SAndreas Gohr $farmdir = $this->config['base']['farmdir']; 143a646d519SAndreas Gohr $farmhost = $this->config['base']['farmhost']; 144a646d519SAndreas Gohr 145917a67f0SAndreas Gohr // check if animal was set via rewrite parameter 146a646d519SAndreas Gohr $animal = ''; 147917a67f0SAndreas Gohr if (isset($_GET['animal'])) { 148917a67f0SAndreas Gohr $animal = $_GET['animal']; 149917a67f0SAndreas Gohr // now unset the parameter to not leak into new queries 150917a67f0SAndreas Gohr unset($_GET['animal']); 151917a67f0SAndreas Gohr $params = []; 152917a67f0SAndreas Gohr parse_str($_SERVER['QUERY_STRING'], $params); 153917a67f0SAndreas Gohr if (isset($params['animal'])) unset($params['animal']); 154917a67f0SAndreas Gohr $_SERVER['QUERY_STRING'] = http_build_query($params); 155917a67f0SAndreas Gohr } 156917a67f0SAndreas Gohr // get animal from CLI parameter 1571da41c8bSAndreas Gohr if ('cli' == PHP_SAPI && isset($_SERVER['animal'])) $animal = $_SERVER['animal']; 158a646d519SAndreas Gohr if ($animal) { 159a646d519SAndreas Gohr // check that $animal is a string and just a directory name and not a path 160a646d519SAndreas Gohr if (!is_string($animal) || strpbrk($animal, '\\/') !== false) { 161a646d519SAndreas Gohr $this->notfound = true; 162a646d519SAndreas Gohr return; 163a646d519SAndreas Gohr }; 164a646d519SAndreas Gohr $animal = strtolower($animal); 165a646d519SAndreas Gohr 166a646d519SAndreas Gohr // check if animal exists 167a646d519SAndreas Gohr if (is_dir("$farmdir/$animal/conf")) { 168a646d519SAndreas Gohr $this->animal = $animal; 169a646d519SAndreas Gohr return; 170a646d519SAndreas Gohr } else { 171a646d519SAndreas Gohr $this->notfound = true; 172a646d519SAndreas Gohr return; 173a646d519SAndreas Gohr } 174a646d519SAndreas Gohr } 175a646d519SAndreas Gohr 17636282384SAndreas Gohr // no host - no host based setup. if we're still here then it's the farmer 17736282384SAndreas Gohr if (!isset($_SERVER['HTTP_HOST'])) return; 17836282384SAndreas Gohr 179a646d519SAndreas Gohr // is this the farmer? 180a646d519SAndreas Gohr if (strtolower($_SERVER['HTTP_HOST']) == $farmhost) { 181a646d519SAndreas Gohr return; 182a646d519SAndreas Gohr } 183a646d519SAndreas Gohr 18485becf1bSAndreas Gohr // still here? check for host based 185a646d519SAndreas Gohr $this->hostbased = true; 18685becf1bSAndreas Gohr $possible = $this->getAnimalNamesForHost($_SERVER['HTTP_HOST']); 18785becf1bSAndreas Gohr foreach ($possible as $animal) { 188a646d519SAndreas Gohr if (is_dir("$farmdir/$animal/conf/")) { 189a646d519SAndreas Gohr $this->animal = $animal; 190a646d519SAndreas Gohr return; 191a646d519SAndreas Gohr } 192a646d519SAndreas Gohr } 193a646d519SAndreas Gohr 194a646d519SAndreas Gohr // no hit 195a646d519SAndreas Gohr $this->notfound = true; 196a646d519SAndreas Gohr } 197a646d519SAndreas Gohr 198a646d519SAndreas Gohr /** 19985becf1bSAndreas Gohr * Return a list of possible animal names for the given host 20085becf1bSAndreas Gohr * 20185becf1bSAndreas Gohr * @param string $host the HTTP_HOST header 20285becf1bSAndreas Gohr * @return array 20385becf1bSAndreas Gohr */ 2041da41c8bSAndreas Gohr protected function getAnimalNamesForHost($host) 2051da41c8bSAndreas Gohr { 2061da41c8bSAndreas Gohr $animals = []; 20785becf1bSAndreas Gohr $parts = explode('.', implode('.', explode(':', rtrim($host, '.')))); 20885becf1bSAndreas Gohr for ($j = count($parts); $j > 0; $j--) { 20985becf1bSAndreas Gohr // strip from the end 21085becf1bSAndreas Gohr $animals[] = implode('.', array_slice($parts, 0, $j)); 21185becf1bSAndreas Gohr // strip from the end without host part 21285becf1bSAndreas Gohr $animals[] = implode('.', array_slice($parts, 1, $j)); 21385becf1bSAndreas Gohr } 21485becf1bSAndreas Gohr $animals = array_unique($animals); 21585becf1bSAndreas Gohr $animals = array_filter($animals); 2160a5d2da2SAndreas Gohr usort( 217bfecda9bSAndreas Gohr $animals, 218bfecda9bSAndreas Gohr // compare by length, then alphabet 219bfecda9bSAndreas Gohr function ($a, $b) { 220bfecda9bSAndreas Gohr $ret = strlen($b) - strlen($a); 221bfecda9bSAndreas Gohr if ($ret != 0) return $ret; 222a2a8c90bSAndreas Gohr return $a <=> $b; 2230a5d2da2SAndreas Gohr } 2240a5d2da2SAndreas Gohr ); 22585becf1bSAndreas Gohr return $animals; 22685becf1bSAndreas Gohr } 22785becf1bSAndreas Gohr 22885becf1bSAndreas Gohr /** 229a646d519SAndreas Gohr * This sets up the default farming config cascade 230a646d519SAndreas Gohr */ 2311da41c8bSAndreas Gohr protected function setupCascade() 2321da41c8bSAndreas Gohr { 233a646d519SAndreas Gohr global $config_cascade; 2341da41c8bSAndreas Gohr $config_cascade = [ 2351da41c8bSAndreas Gohr 'main' => [ 2361da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/dokuwiki.php'], 2371da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'local.php'], 2381da41c8bSAndreas Gohr 'protected' => [DOKU_CONF . 'local.protected.php'] 2391da41c8bSAndreas Gohr ], 2401da41c8bSAndreas Gohr 'acronyms' => [ 2411da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/acronyms.conf'], 2421da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'acronyms.local.conf'] 2431da41c8bSAndreas Gohr ], 2441da41c8bSAndreas Gohr 'entities' => [ 2451da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/entities.conf'], 2461da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'entities.local.conf'] 2471da41c8bSAndreas Gohr ], 2481da41c8bSAndreas Gohr 'interwiki' => [ 2491da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/interwiki.conf'], 2501da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'interwiki.local.conf'] 2511da41c8bSAndreas Gohr ], 2521da41c8bSAndreas Gohr 'license' => [ 2531da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/license.php'], 2541da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'license.local.php'] 2551da41c8bSAndreas Gohr ], 2561da41c8bSAndreas Gohr 'manifest' => [ 2571da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/manifest.json'], 2581da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'manifest.local.json'] 2591da41c8bSAndreas Gohr ], 2601da41c8bSAndreas Gohr 'mediameta' => [ 2611da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/mediameta.php'], 2621da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'mediameta.local.php'] 2631da41c8bSAndreas Gohr ], 2641da41c8bSAndreas Gohr 'mime' => [ 2651da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/mime.conf'], 2661da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'mime.local.conf'] 2671da41c8bSAndreas Gohr ], 2681da41c8bSAndreas Gohr 'scheme' => [ 2691da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/scheme.conf'], 2701da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'scheme.local.conf'] 2711da41c8bSAndreas Gohr ], 2721da41c8bSAndreas Gohr 'smileys' => [ 2731da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/smileys.conf'], 2741da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'smileys.local.conf'] 2751da41c8bSAndreas Gohr ], 2761da41c8bSAndreas Gohr 'wordblock' => [ 2771da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/wordblock.conf'], 2781da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'wordblock.local.conf'] 2791da41c8bSAndreas Gohr ], 2801da41c8bSAndreas Gohr 'acl' => [ 2811da41c8bSAndreas Gohr 'default' => DOKU_CONF . 'acl.auth.php' 2821da41c8bSAndreas Gohr ], 2831da41c8bSAndreas Gohr 'plainauth.users' => [ 2841da41c8bSAndreas Gohr 'default' => DOKU_CONF . 'users.auth.php' 2851da41c8bSAndreas Gohr ], 2861da41c8bSAndreas Gohr 'plugins' => [ 2871da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/plugins.php'], 2881da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'plugins.local.php'], 2891da41c8bSAndreas Gohr 'protected' => [ 290a646d519SAndreas Gohr DOKU_INC . 'conf/plugins.required.php', 2911da41c8bSAndreas Gohr DOKU_CONF . 'plugins.protected.php' 2921da41c8bSAndreas Gohr ] 2931da41c8bSAndreas Gohr ], 2941da41c8bSAndreas Gohr 'userstyle' => [ 2951da41c8bSAndreas Gohr 'screen' => [ 2961da41c8bSAndreas Gohr DOKU_CONF . 'userstyle.css', 2971da41c8bSAndreas Gohr DOKU_CONF . 'userstyle.less' 2981da41c8bSAndreas Gohr ], 2991da41c8bSAndreas Gohr 'print' => [ 3001da41c8bSAndreas Gohr DOKU_CONF . 'userprint.css', 3011da41c8bSAndreas Gohr DOKU_CONF . 'userprint.less' 3021da41c8bSAndreas Gohr ], 3031da41c8bSAndreas Gohr 'feed' => [ 3041da41c8bSAndreas Gohr DOKU_CONF . 'userfeed.css', 3051da41c8bSAndreas Gohr DOKU_CONF . 'userfeed.less' 3061da41c8bSAndreas Gohr ], 3071da41c8bSAndreas Gohr 'all' => [ 3081da41c8bSAndreas Gohr DOKU_CONF . 'userall.css', 3091da41c8bSAndreas Gohr DOKU_CONF . 'userall.less' 3101da41c8bSAndreas Gohr ] 3111da41c8bSAndreas Gohr ], 3121da41c8bSAndreas Gohr 'userscript' => [ 3131da41c8bSAndreas Gohr 'default' => [DOKU_CONF . 'userscript.js'] 3141da41c8bSAndreas Gohr ], 3151da41c8bSAndreas Gohr 'styleini' => [ 3161da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'lib/tpl/%TEMPLATE%/' . 'style.ini'], 3171da41c8bSAndreas Gohr 'local' => [DOKU_CONF . 'tpl/%TEMPLATE%/' . 'style.ini'] 3181da41c8bSAndreas Gohr ] 3191da41c8bSAndreas Gohr ]; 320a646d519SAndreas Gohr } 321a646d519SAndreas Gohr 322a646d519SAndreas Gohr /** 323a646d519SAndreas Gohr * This adds additional files to the config cascade based on the inheritence settings 324a646d519SAndreas Gohr * 325a646d519SAndreas Gohr * These are only added for animals, not the farmer 326a646d519SAndreas Gohr */ 3271da41c8bSAndreas Gohr protected function adjustCascade() 3281da41c8bSAndreas Gohr { 329b330074aSAndreas Gohr // nothing to do when on the farmer: 330b330074aSAndreas Gohr if (!$this->animal) return; 331a646d519SAndreas Gohr 332b330074aSAndreas Gohr global $config_cascade; 333a646d519SAndreas Gohr foreach ($this->config['inherit'] as $key => $val) { 334a646d519SAndreas Gohr if (!$val) continue; 335a646d519SAndreas Gohr 336a646d519SAndreas Gohr // prepare what is to append or prepend 3371da41c8bSAndreas Gohr $append = []; 3381da41c8bSAndreas Gohr $prepend = []; 339a646d519SAndreas Gohr if ($key == 'main') { 3404b1aad07Satisne $prepend = [ 3414b1aad07Satisne 'protected' => [DOKU_INC . 'conf/local.protected.php'] 3424b1aad07Satisne ]; 3431da41c8bSAndreas Gohr $append = [ 3441da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/local.php'], 3451da41c8bSAndreas Gohr 'protected' => [DOKU_INC . 'lib/plugins/farmer/includes/config.php'] 3461da41c8bSAndreas Gohr ]; 347a646d519SAndreas Gohr } elseif ($key == 'license') { 3481da41c8bSAndreas Gohr $append = [ 3491da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/' . $key . '.local.php'] 3501da41c8bSAndreas Gohr ]; 351a646d519SAndreas Gohr } elseif ($key == 'userscript') { 3521da41c8bSAndreas Gohr $prepend = [ 3531da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/userscript.js'] 3541da41c8bSAndreas Gohr ]; 355a646d519SAndreas Gohr } elseif ($key == 'userstyle') { 3561da41c8bSAndreas Gohr $prepend = [ 3571da41c8bSAndreas Gohr 'screen' => [ 3581da41c8bSAndreas Gohr DOKU_INC . 'conf/userstyle.css', 3591da41c8bSAndreas Gohr DOKU_INC . 'conf/userstyle.less' 3601da41c8bSAndreas Gohr ], 3611da41c8bSAndreas Gohr 'print' => [ 3621da41c8bSAndreas Gohr DOKU_INC . 'conf/userprint.css', 3631da41c8bSAndreas Gohr DOKU_INC . 'conf/userprint.less' 3641da41c8bSAndreas Gohr ], 3651da41c8bSAndreas Gohr 'feed' => [ 3661da41c8bSAndreas Gohr DOKU_INC . 'conf/userfeed.css', 3671da41c8bSAndreas Gohr DOKU_INC . 'conf/userfeed.less' 3681da41c8bSAndreas Gohr ], 3691da41c8bSAndreas Gohr 'all' => [ 3701da41c8bSAndreas Gohr DOKU_INC . 'conf/userall.css', 3711da41c8bSAndreas Gohr DOKU_INC . 'conf/userall.less' 3721da41c8bSAndreas Gohr ] 3731da41c8bSAndreas Gohr ]; 37405ea7625SAnna Dabrowska } elseif ($key == 'styleini') { 3751da41c8bSAndreas Gohr $append = [ 3761da41c8bSAndreas Gohr 'local' => [DOKU_INC . 'conf/tpl/%TEMPLATE%/style.ini'] 3771da41c8bSAndreas Gohr ]; 3781272da0cSAndreas Gohr } elseif ($key == 'users') { 3791272da0cSAndreas Gohr $config_cascade['plainauth.users']['protected'] = DOKU_INC . 'conf/users.auth.php'; 380af1c6dd8SAndreas Gohr } elseif ($key == 'plugins') { 3814b1aad07Satisne $prepend = [ 3824b1aad07Satisne 'protected' => [DOKU_INC . 'conf/local.protected.php'] 3834b1aad07Satisne ]; 3841da41c8bSAndreas Gohr $append = [ 3851da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/plugins.local.php'] 3861da41c8bSAndreas Gohr ]; 387a646d519SAndreas Gohr } else { 3881da41c8bSAndreas Gohr $append = [ 3891da41c8bSAndreas Gohr 'default' => [DOKU_INC . 'conf/' . $key . '.local.conf'] 3901da41c8bSAndreas Gohr ]; 391a646d519SAndreas Gohr } 392a646d519SAndreas Gohr 393a646d519SAndreas Gohr // add to cascade 394a646d519SAndreas Gohr foreach ($prepend as $section => $data) { 395a646d519SAndreas Gohr $config_cascade[$key][$section] = array_merge($data, $config_cascade[$key][$section]); 396a646d519SAndreas Gohr } 397a646d519SAndreas Gohr foreach ($append as $section => $data) { 398a646d519SAndreas Gohr $config_cascade[$key][$section] = array_merge($config_cascade[$key][$section], $data); 399a646d519SAndreas Gohr } 400a646d519SAndreas Gohr } 401de156015SAndreas Gohr 402de156015SAndreas Gohr // add plugin overrides 403de156015SAndreas Gohr $config_cascade['plugins']['protected'][] = DOKU_INC . 'lib/plugins/farmer/includes/plugins.php'; 404a646d519SAndreas Gohr } 405a646d519SAndreas Gohr 406a646d519SAndreas Gohr /** 407da0ae2c0SAndreas Gohr * Loads the farm config 408da0ae2c0SAndreas Gohr */ 4091da41c8bSAndreas Gohr protected function loadConfig() 4101da41c8bSAndreas Gohr { 411da0ae2c0SAndreas Gohr $ini = DOKU_INC . 'conf/farm.ini'; 412*700b5633SAndreas Gohr if (file_exists($ini)) { 413da0ae2c0SAndreas Gohr $config = parse_ini_file($ini, true); 414da0ae2c0SAndreas Gohr foreach (array_keys($this->config) as $section) { 415da0ae2c0SAndreas Gohr if (isset($config[$section])) { 416da0ae2c0SAndreas Gohr $this->config[$section] = array_merge( 417da0ae2c0SAndreas Gohr $this->config[$section], 418da0ae2c0SAndreas Gohr $config[$section] 419da0ae2c0SAndreas Gohr ); 420da0ae2c0SAndreas Gohr } 421da0ae2c0SAndreas Gohr } 422*700b5633SAndreas Gohr } 423*700b5633SAndreas Gohr 424*700b5633SAndreas Gohr // farmdir setup can be done via environment 425*700b5633SAndreas Gohr if($this->config['base']['farmdir'] === '' && isset($_ENV['DOKU_FARMDIR'])) { 426*700b5633SAndreas Gohr $this->config['base']['farmdir'] = $_ENV['DOKU_FARMDIR']; 427*700b5633SAndreas Gohr } 428da0ae2c0SAndreas Gohr 429a646d519SAndreas Gohr $this->config['base']['farmdir'] = trim($this->config['base']['farmdir']); 430a646d519SAndreas Gohr $this->config['base']['farmhost'] = strtolower(trim($this->config['base']['farmhost'])); 431a646d519SAndreas Gohr } 432da0ae2c0SAndreas Gohr} 433da0ae2c0SAndreas Gohr 434da0ae2c0SAndreas Gohr// initialize it globally 43585becf1bSAndreas Gohrif (!defined('DOKU_UNITTEST')) { 436da0ae2c0SAndreas Gohr global $FARMCORE; 437da0ae2c0SAndreas Gohr $FARMCORE = new DokuWikiFarmCore(); 43885becf1bSAndreas Gohr} 439