Config.php 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098
  1. <?php
  2. /**
  3. * PEAR_Config, customized configuration handling for the PEAR Installer
  4. *
  5. * PHP versions 4 and 5
  6. *
  7. * @category pear
  8. * @package PEAR
  9. * @author Stig Bakken <ssb@php.net>
  10. * @author Greg Beaver <cellog@php.net>
  11. * @copyright 1997-2009 The Authors
  12. * @license http://opensource.org/licenses/bsd-license.php New BSD License
  13. * @version CVS: $Id: Config.php 313023 2011-07-06 19:17:11Z dufuz $
  14. * @link http://pear.php.net/package/PEAR
  15. * @since File available since Release 0.1
  16. */
  17. /**
  18. * Required for error handling
  19. */
  20. require_once 'PEAR.php';
  21. require_once 'PEAR/Registry.php';
  22. require_once 'PEAR/Installer/Role.php';
  23. require_once 'System.php';
  24. /**
  25. * Last created PEAR_Config instance.
  26. * @var object
  27. */
  28. $GLOBALS['_PEAR_Config_instance'] = null;
  29. if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) {
  30. $PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear';
  31. } else {
  32. $PEAR_INSTALL_DIR = PEAR_INSTALL_DIR;
  33. }
  34. // Below we define constants with default values for all configuration
  35. // parameters except username/password. All of them can have their
  36. // defaults set through environment variables. The reason we use the
  37. // PHP_ prefix is for some security, PHP protects environment
  38. // variables starting with PHP_*.
  39. // default channel and preferred mirror is based on whether we are invoked through
  40. // the "pear" or the "pecl" command
  41. if (!defined('PEAR_RUNTYPE')) {
  42. define('PEAR_RUNTYPE', 'pear');
  43. }
  44. if (PEAR_RUNTYPE == 'pear') {
  45. define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net');
  46. } else {
  47. define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net');
  48. }
  49. if (getenv('PHP_PEAR_SYSCONF_DIR')) {
  50. define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR'));
  51. } elseif (getenv('SystemRoot')) {
  52. define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot'));
  53. } else {
  54. define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR);
  55. }
  56. // Default for master_server
  57. if (getenv('PHP_PEAR_MASTER_SERVER')) {
  58. define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER'));
  59. } else {
  60. define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net');
  61. }
  62. // Default for http_proxy
  63. if (getenv('PHP_PEAR_HTTP_PROXY')) {
  64. define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY'));
  65. } elseif (getenv('http_proxy')) {
  66. define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy'));
  67. } else {
  68. define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', '');
  69. }
  70. // Default for php_dir
  71. if (getenv('PHP_PEAR_INSTALL_DIR')) {
  72. define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR'));
  73. } else {
  74. if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) {
  75. define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
  76. } else {
  77. define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
  78. }
  79. }
  80. // Default for ext_dir
  81. if (getenv('PHP_PEAR_EXTENSION_DIR')) {
  82. define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR'));
  83. } else {
  84. if (ini_get('extension_dir')) {
  85. define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir'));
  86. } elseif (defined('PEAR_EXTENSION_DIR') &&
  87. file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) {
  88. define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR);
  89. } elseif (defined('PHP_EXTENSION_DIR')) {
  90. define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR);
  91. } else {
  92. define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.');
  93. }
  94. }
  95. // Default for doc_dir
  96. if (getenv('PHP_PEAR_DOC_DIR')) {
  97. define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR'));
  98. } else {
  99. define('PEAR_CONFIG_DEFAULT_DOC_DIR',
  100. $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs');
  101. }
  102. // Default for bin_dir
  103. if (getenv('PHP_PEAR_BIN_DIR')) {
  104. define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR'));
  105. } else {
  106. define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR);
  107. }
  108. // Default for data_dir
  109. if (getenv('PHP_PEAR_DATA_DIR')) {
  110. define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR'));
  111. } else {
  112. define('PEAR_CONFIG_DEFAULT_DATA_DIR',
  113. $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data');
  114. }
  115. // Default for cfg_dir
  116. if (getenv('PHP_PEAR_CFG_DIR')) {
  117. define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR'));
  118. } else {
  119. define('PEAR_CONFIG_DEFAULT_CFG_DIR',
  120. $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg');
  121. }
  122. // Default for www_dir
  123. if (getenv('PHP_PEAR_WWW_DIR')) {
  124. define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR'));
  125. } else {
  126. define('PEAR_CONFIG_DEFAULT_WWW_DIR',
  127. $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www');
  128. }
  129. // Default for test_dir
  130. if (getenv('PHP_PEAR_TEST_DIR')) {
  131. define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR'));
  132. } else {
  133. define('PEAR_CONFIG_DEFAULT_TEST_DIR',
  134. $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests');
  135. }
  136. // Default for temp_dir
  137. if (getenv('PHP_PEAR_TEMP_DIR')) {
  138. define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR'));
  139. } else {
  140. define('PEAR_CONFIG_DEFAULT_TEMP_DIR',
  141. System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
  142. DIRECTORY_SEPARATOR . 'temp');
  143. }
  144. // Default for cache_dir
  145. if (getenv('PHP_PEAR_CACHE_DIR')) {
  146. define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR'));
  147. } else {
  148. define('PEAR_CONFIG_DEFAULT_CACHE_DIR',
  149. System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
  150. DIRECTORY_SEPARATOR . 'cache');
  151. }
  152. // Default for download_dir
  153. if (getenv('PHP_PEAR_DOWNLOAD_DIR')) {
  154. define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR'));
  155. } else {
  156. define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR',
  157. System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
  158. DIRECTORY_SEPARATOR . 'download');
  159. }
  160. // Default for php_bin
  161. if (getenv('PHP_PEAR_PHP_BIN')) {
  162. define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN'));
  163. } else {
  164. define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR.
  165. DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : ''));
  166. }
  167. // Default for verbose
  168. if (getenv('PHP_PEAR_VERBOSE')) {
  169. define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE'));
  170. } else {
  171. define('PEAR_CONFIG_DEFAULT_VERBOSE', 1);
  172. }
  173. // Default for preferred_state
  174. if (getenv('PHP_PEAR_PREFERRED_STATE')) {
  175. define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE'));
  176. } else {
  177. define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable');
  178. }
  179. // Default for umask
  180. if (getenv('PHP_PEAR_UMASK')) {
  181. define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK'));
  182. } else {
  183. define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask()));
  184. }
  185. // Default for cache_ttl
  186. if (getenv('PHP_PEAR_CACHE_TTL')) {
  187. define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL'));
  188. } else {
  189. define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600);
  190. }
  191. // Default for sig_type
  192. if (getenv('PHP_PEAR_SIG_TYPE')) {
  193. define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE'));
  194. } else {
  195. define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg');
  196. }
  197. // Default for sig_bin
  198. if (getenv('PHP_PEAR_SIG_BIN')) {
  199. define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN'));
  200. } else {
  201. define('PEAR_CONFIG_DEFAULT_SIG_BIN',
  202. System::which(
  203. 'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg'));
  204. }
  205. // Default for sig_keydir
  206. if (getenv('PHP_PEAR_SIG_KEYDIR')) {
  207. define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR'));
  208. } else {
  209. define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR',
  210. PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys');
  211. }
  212. /**
  213. * This is a class for storing configuration data, keeping track of
  214. * which are system-defined, user-defined or defaulted.
  215. * @category pear
  216. * @package PEAR
  217. * @author Stig Bakken <ssb@php.net>
  218. * @author Greg Beaver <cellog@php.net>
  219. * @copyright 1997-2009 The Authors
  220. * @license http://opensource.org/licenses/bsd-license.php New BSD License
  221. * @version Release: 1.9.4
  222. * @link http://pear.php.net/package/PEAR
  223. * @since Class available since Release 0.1
  224. */
  225. class PEAR_Config extends PEAR
  226. {
  227. /**
  228. * Array of config files used.
  229. *
  230. * @var array layer => config file
  231. */
  232. var $files = array(
  233. 'system' => '',
  234. 'user' => '',
  235. );
  236. var $layers = array();
  237. /**
  238. * Configuration data, two-dimensional array where the first
  239. * dimension is the config layer ('user', 'system' and 'default'),
  240. * and the second dimension is keyname => value.
  241. *
  242. * The order in the first dimension is important! Earlier
  243. * layers will shadow later ones when a config value is
  244. * requested (if a 'user' value exists, it will be returned first,
  245. * then 'system' and finally 'default').
  246. *
  247. * @var array layer => array(keyname => value, ...)
  248. */
  249. var $configuration = array(
  250. 'user' => array(),
  251. 'system' => array(),
  252. 'default' => array(),
  253. );
  254. /**
  255. * Configuration values that can be set for a channel
  256. *
  257. * All other configuration values can only have a global value
  258. * @var array
  259. * @access private
  260. */
  261. var $_channelConfigInfo = array(
  262. 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir',
  263. 'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username',
  264. 'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini'
  265. );
  266. /**
  267. * Channels that can be accessed
  268. * @see setChannels()
  269. * @var array
  270. * @access private
  271. */
  272. var $_channels = array('pear.php.net', 'pecl.php.net', '__uri');
  273. /**
  274. * This variable is used to control the directory values returned
  275. * @see setInstallRoot();
  276. * @var string|false
  277. * @access private
  278. */
  279. var $_installRoot = false;
  280. /**
  281. * If requested, this will always refer to the registry
  282. * contained in php_dir
  283. * @var PEAR_Registry
  284. */
  285. var $_registry = array();
  286. /**
  287. * @var array
  288. * @access private
  289. */
  290. var $_regInitialized = array();
  291. /**
  292. * @var bool
  293. * @access private
  294. */
  295. var $_noRegistry = false;
  296. /**
  297. * amount of errors found while parsing config
  298. * @var integer
  299. * @access private
  300. */
  301. var $_errorsFound = 0;
  302. var $_lastError = null;
  303. /**
  304. * Information about the configuration data. Stores the type,
  305. * default value and a documentation string for each configuration
  306. * value.
  307. *
  308. * @var array layer => array(infotype => value, ...)
  309. */
  310. var $configuration_info = array(
  311. // Channels/Internet Access
  312. 'default_channel' => array(
  313. 'type' => 'string',
  314. 'default' => PEAR_CONFIG_DEFAULT_CHANNEL,
  315. 'doc' => 'the default channel to use for all non explicit commands',
  316. 'prompt' => 'Default Channel',
  317. 'group' => 'Internet Access',
  318. ),
  319. 'preferred_mirror' => array(
  320. 'type' => 'string',
  321. 'default' => PEAR_CONFIG_DEFAULT_CHANNEL,
  322. 'doc' => 'the default server or mirror to use for channel actions',
  323. 'prompt' => 'Default Channel Mirror',
  324. 'group' => 'Internet Access',
  325. ),
  326. 'remote_config' => array(
  327. 'type' => 'password',
  328. 'default' => '',
  329. 'doc' => 'ftp url of remote configuration file to use for synchronized install',
  330. 'prompt' => 'Remote Configuration File',
  331. 'group' => 'Internet Access',
  332. ),
  333. 'auto_discover' => array(
  334. 'type' => 'integer',
  335. 'default' => 0,
  336. 'doc' => 'whether to automatically discover new channels',
  337. 'prompt' => 'Auto-discover new Channels',
  338. 'group' => 'Internet Access',
  339. ),
  340. // Internet Access
  341. 'master_server' => array(
  342. 'type' => 'string',
  343. 'default' => 'pear.php.net',
  344. 'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]',
  345. 'prompt' => 'PEAR server [DEPRECATED]',
  346. 'group' => 'Internet Access',
  347. ),
  348. 'http_proxy' => array(
  349. 'type' => 'string',
  350. 'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY,
  351. 'doc' => 'HTTP proxy (host:port) to use when downloading packages',
  352. 'prompt' => 'HTTP Proxy Server Address',
  353. 'group' => 'Internet Access',
  354. ),
  355. // File Locations
  356. 'php_dir' => array(
  357. 'type' => 'directory',
  358. 'default' => PEAR_CONFIG_DEFAULT_PHP_DIR,
  359. 'doc' => 'directory where .php files are installed',
  360. 'prompt' => 'PEAR directory',
  361. 'group' => 'File Locations',
  362. ),
  363. 'ext_dir' => array(
  364. 'type' => 'directory',
  365. 'default' => PEAR_CONFIG_DEFAULT_EXT_DIR,
  366. 'doc' => 'directory where loadable extensions are installed',
  367. 'prompt' => 'PHP extension directory',
  368. 'group' => 'File Locations',
  369. ),
  370. 'doc_dir' => array(
  371. 'type' => 'directory',
  372. 'default' => PEAR_CONFIG_DEFAULT_DOC_DIR,
  373. 'doc' => 'directory where documentation is installed',
  374. 'prompt' => 'PEAR documentation directory',
  375. 'group' => 'File Locations',
  376. ),
  377. 'bin_dir' => array(
  378. 'type' => 'directory',
  379. 'default' => PEAR_CONFIG_DEFAULT_BIN_DIR,
  380. 'doc' => 'directory where executables are installed',
  381. 'prompt' => 'PEAR executables directory',
  382. 'group' => 'File Locations',
  383. ),
  384. 'data_dir' => array(
  385. 'type' => 'directory',
  386. 'default' => PEAR_CONFIG_DEFAULT_DATA_DIR,
  387. 'doc' => 'directory where data files are installed',
  388. 'prompt' => 'PEAR data directory',
  389. 'group' => 'File Locations (Advanced)',
  390. ),
  391. 'cfg_dir' => array(
  392. 'type' => 'directory',
  393. 'default' => PEAR_CONFIG_DEFAULT_CFG_DIR,
  394. 'doc' => 'directory where modifiable configuration files are installed',
  395. 'prompt' => 'PEAR configuration file directory',
  396. 'group' => 'File Locations (Advanced)',
  397. ),
  398. 'www_dir' => array(
  399. 'type' => 'directory',
  400. 'default' => PEAR_CONFIG_DEFAULT_WWW_DIR,
  401. 'doc' => 'directory where www frontend files (html/js) are installed',
  402. 'prompt' => 'PEAR www files directory',
  403. 'group' => 'File Locations (Advanced)',
  404. ),
  405. 'test_dir' => array(
  406. 'type' => 'directory',
  407. 'default' => PEAR_CONFIG_DEFAULT_TEST_DIR,
  408. 'doc' => 'directory where regression tests are installed',
  409. 'prompt' => 'PEAR test directory',
  410. 'group' => 'File Locations (Advanced)',
  411. ),
  412. 'cache_dir' => array(
  413. 'type' => 'directory',
  414. 'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR,
  415. 'doc' => 'directory which is used for web service cache',
  416. 'prompt' => 'PEAR Installer cache directory',
  417. 'group' => 'File Locations (Advanced)',
  418. ),
  419. 'temp_dir' => array(
  420. 'type' => 'directory',
  421. 'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR,
  422. 'doc' => 'directory which is used for all temp files',
  423. 'prompt' => 'PEAR Installer temp directory',
  424. 'group' => 'File Locations (Advanced)',
  425. ),
  426. 'download_dir' => array(
  427. 'type' => 'directory',
  428. 'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR,
  429. 'doc' => 'directory which is used for all downloaded files',
  430. 'prompt' => 'PEAR Installer download directory',
  431. 'group' => 'File Locations (Advanced)',
  432. ),
  433. 'php_bin' => array(
  434. 'type' => 'file',
  435. 'default' => PEAR_CONFIG_DEFAULT_PHP_BIN,
  436. 'doc' => 'PHP CLI/CGI binary for executing scripts',
  437. 'prompt' => 'PHP CLI/CGI binary',
  438. 'group' => 'File Locations (Advanced)',
  439. ),
  440. 'php_prefix' => array(
  441. 'type' => 'string',
  442. 'default' => '',
  443. 'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs',
  444. 'prompt' => '--program-prefix passed to PHP\'s ./configure',
  445. 'group' => 'File Locations (Advanced)',
  446. ),
  447. 'php_suffix' => array(
  448. 'type' => 'string',
  449. 'default' => '',
  450. 'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs',
  451. 'prompt' => '--program-suffix passed to PHP\'s ./configure',
  452. 'group' => 'File Locations (Advanced)',
  453. ),
  454. 'php_ini' => array(
  455. 'type' => 'file',
  456. 'default' => '',
  457. 'doc' => 'location of php.ini in which to enable PECL extensions on install',
  458. 'prompt' => 'php.ini location',
  459. 'group' => 'File Locations (Advanced)',
  460. ),
  461. // Maintainers
  462. 'username' => array(
  463. 'type' => 'string',
  464. 'default' => '',
  465. 'doc' => '(maintainers) your PEAR account name',
  466. 'prompt' => 'PEAR username (for maintainers)',
  467. 'group' => 'Maintainers',
  468. ),
  469. 'password' => array(
  470. 'type' => 'password',
  471. 'default' => '',
  472. 'doc' => '(maintainers) your PEAR account password',
  473. 'prompt' => 'PEAR password (for maintainers)',
  474. 'group' => 'Maintainers',
  475. ),
  476. // Advanced
  477. 'verbose' => array(
  478. 'type' => 'integer',
  479. 'default' => PEAR_CONFIG_DEFAULT_VERBOSE,
  480. 'doc' => 'verbosity level
  481. 0: really quiet
  482. 1: somewhat quiet
  483. 2: verbose
  484. 3: debug',
  485. 'prompt' => 'Debug Log Level',
  486. 'group' => 'Advanced',
  487. ),
  488. 'preferred_state' => array(
  489. 'type' => 'set',
  490. 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE,
  491. 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified',
  492. 'valid_set' => array(
  493. 'stable', 'beta', 'alpha', 'devel', 'snapshot'),
  494. 'prompt' => 'Preferred Package State',
  495. 'group' => 'Advanced',
  496. ),
  497. 'umask' => array(
  498. 'type' => 'mask',
  499. 'default' => PEAR_CONFIG_DEFAULT_UMASK,
  500. 'doc' => 'umask used when creating files (Unix-like systems only)',
  501. 'prompt' => 'Unix file mask',
  502. 'group' => 'Advanced',
  503. ),
  504. 'cache_ttl' => array(
  505. 'type' => 'integer',
  506. 'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL,
  507. 'doc' => 'amount of secs where the local cache is used and not updated',
  508. 'prompt' => 'Cache TimeToLive',
  509. 'group' => 'Advanced',
  510. ),
  511. 'sig_type' => array(
  512. 'type' => 'set',
  513. 'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE,
  514. 'doc' => 'which package signature mechanism to use',
  515. 'valid_set' => array('gpg'),
  516. 'prompt' => 'Package Signature Type',
  517. 'group' => 'Maintainers',
  518. ),
  519. 'sig_bin' => array(
  520. 'type' => 'string',
  521. 'default' => PEAR_CONFIG_DEFAULT_SIG_BIN,
  522. 'doc' => 'which package signature mechanism to use',
  523. 'prompt' => 'Signature Handling Program',
  524. 'group' => 'Maintainers',
  525. ),
  526. 'sig_keyid' => array(
  527. 'type' => 'string',
  528. 'default' => '',
  529. 'doc' => 'which key to use for signing with',
  530. 'prompt' => 'Signature Key Id',
  531. 'group' => 'Maintainers',
  532. ),
  533. 'sig_keydir' => array(
  534. 'type' => 'directory',
  535. 'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR,
  536. 'doc' => 'directory where signature keys are located',
  537. 'prompt' => 'Signature Key Directory',
  538. 'group' => 'Maintainers',
  539. ),
  540. // __channels is reserved - used for channel-specific configuration
  541. );
  542. /**
  543. * Constructor.
  544. *
  545. * @param string file to read user-defined options from
  546. * @param string file to read system-wide defaults from
  547. * @param bool determines whether a registry object "follows"
  548. * the value of php_dir (is automatically created
  549. * and moved when php_dir is changed)
  550. * @param bool if true, fails if configuration files cannot be loaded
  551. *
  552. * @access public
  553. *
  554. * @see PEAR_Config::singleton
  555. */
  556. function PEAR_Config($user_file = '', $system_file = '', $ftp_file = false,
  557. $strict = true)
  558. {
  559. $this->PEAR();
  560. PEAR_Installer_Role::initializeConfig($this);
  561. $sl = DIRECTORY_SEPARATOR;
  562. if (empty($user_file)) {
  563. if (OS_WINDOWS) {
  564. $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini';
  565. } else {
  566. $user_file = getenv('HOME') . $sl . '.pearrc';
  567. }
  568. }
  569. if (empty($system_file)) {
  570. $system_file = PEAR_CONFIG_SYSCONFDIR . $sl;
  571. if (OS_WINDOWS) {
  572. $system_file .= 'pearsys.ini';
  573. } else {
  574. $system_file .= 'pear.conf';
  575. }
  576. }
  577. $this->layers = array_keys($this->configuration);
  578. $this->files['user'] = $user_file;
  579. $this->files['system'] = $system_file;
  580. if ($user_file && file_exists($user_file)) {
  581. $this->pushErrorHandling(PEAR_ERROR_RETURN);
  582. $this->readConfigFile($user_file, 'user', $strict);
  583. $this->popErrorHandling();
  584. if ($this->_errorsFound > 0) {
  585. return;
  586. }
  587. }
  588. if ($system_file && @file_exists($system_file)) {
  589. $this->mergeConfigFile($system_file, false, 'system', $strict);
  590. if ($this->_errorsFound > 0) {
  591. return;
  592. }
  593. }
  594. if (!$ftp_file) {
  595. $ftp_file = $this->get('remote_config');
  596. }
  597. if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) {
  598. $this->readFTPConfigFile($ftp_file);
  599. }
  600. foreach ($this->configuration_info as $key => $info) {
  601. $this->configuration['default'][$key] = $info['default'];
  602. }
  603. $this->_registry['default'] = &new PEAR_Registry($this->configuration['default']['php_dir']);
  604. $this->_registry['default']->setConfig($this, false);
  605. $this->_regInitialized['default'] = false;
  606. //$GLOBALS['_PEAR_Config_instance'] = &$this;
  607. }
  608. /**
  609. * Return the default locations of user and system configuration files
  610. * @static
  611. */
  612. function getDefaultConfigFiles()
  613. {
  614. $sl = DIRECTORY_SEPARATOR;
  615. if (OS_WINDOWS) {
  616. return array(
  617. 'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini',
  618. 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini'
  619. );
  620. }
  621. return array(
  622. 'user' => getenv('HOME') . $sl . '.pearrc',
  623. 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf'
  624. );
  625. }
  626. /**
  627. * Static singleton method. If you want to keep only one instance
  628. * of this class in use, this method will give you a reference to
  629. * the last created PEAR_Config object if one exists, or create a
  630. * new object.
  631. *
  632. * @param string (optional) file to read user-defined options from
  633. * @param string (optional) file to read system-wide defaults from
  634. *
  635. * @return object an existing or new PEAR_Config instance
  636. *
  637. * @access public
  638. *
  639. * @see PEAR_Config::PEAR_Config
  640. */
  641. function &singleton($user_file = '', $system_file = '', $strict = true)
  642. {
  643. if (is_object($GLOBALS['_PEAR_Config_instance'])) {
  644. return $GLOBALS['_PEAR_Config_instance'];
  645. }
  646. $t_conf = &new PEAR_Config($user_file, $system_file, false, $strict);
  647. if ($t_conf->_errorsFound > 0) {
  648. return $t_conf->lastError;
  649. }
  650. $GLOBALS['_PEAR_Config_instance'] = &$t_conf;
  651. return $GLOBALS['_PEAR_Config_instance'];
  652. }
  653. /**
  654. * Determine whether any configuration files have been detected, and whether a
  655. * registry object can be retrieved from this configuration.
  656. * @return bool
  657. * @since PEAR 1.4.0a1
  658. */
  659. function validConfiguration()
  660. {
  661. if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) {
  662. return true;
  663. }
  664. return false;
  665. }
  666. /**
  667. * Reads configuration data from a file. All existing values in
  668. * the config layer are discarded and replaced with data from the
  669. * file.
  670. * @param string file to read from, if NULL or not specified, the
  671. * last-used file for the same layer (second param) is used
  672. * @param string config layer to insert data into ('user' or 'system')
  673. * @return bool TRUE on success or a PEAR error on failure
  674. */
  675. function readConfigFile($file = null, $layer = 'user', $strict = true)
  676. {
  677. if (empty($this->files[$layer])) {
  678. return $this->raiseError("unknown config layer `$layer'");
  679. }
  680. if ($file === null) {
  681. $file = $this->files[$layer];
  682. }
  683. $data = $this->_readConfigDataFrom($file);
  684. if (PEAR::isError($data)) {
  685. if (!$strict) {
  686. return true;
  687. }
  688. $this->_errorsFound++;
  689. $this->lastError = $data;
  690. return $data;
  691. }
  692. $this->files[$layer] = $file;
  693. $this->_decodeInput($data);
  694. $this->configuration[$layer] = $data;
  695. $this->_setupChannels();
  696. if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) {
  697. $this->_registry[$layer] = &new PEAR_Registry($phpdir);
  698. $this->_registry[$layer]->setConfig($this, false);
  699. $this->_regInitialized[$layer] = false;
  700. } else {
  701. unset($this->_registry[$layer]);
  702. }
  703. return true;
  704. }
  705. /**
  706. * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini
  707. * @return true|PEAR_Error
  708. */
  709. function readFTPConfigFile($path)
  710. {
  711. do { // poor man's try
  712. if (!class_exists('PEAR_FTP')) {
  713. if (!class_exists('PEAR_Common')) {
  714. require_once 'PEAR/Common.php';
  715. }
  716. if (PEAR_Common::isIncludeable('PEAR/FTP.php')) {
  717. require_once 'PEAR/FTP.php';
  718. }
  719. }
  720. if (!class_exists('PEAR_FTP')) {
  721. return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config');
  722. }
  723. $this->_ftp = &new PEAR_FTP;
  724. $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN);
  725. $e = $this->_ftp->init($path);
  726. if (PEAR::isError($e)) {
  727. $this->_ftp->popErrorHandling();
  728. return $e;
  729. }
  730. $tmp = System::mktemp('-d');
  731. PEAR_Common::addTempFile($tmp);
  732. $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR .
  733. 'pear.ini', false, FTP_BINARY);
  734. if (PEAR::isError($e)) {
  735. $this->_ftp->popErrorHandling();
  736. return $e;
  737. }
  738. PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini');
  739. $this->_ftp->disconnect();
  740. $this->_ftp->popErrorHandling();
  741. $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini';
  742. $e = $this->readConfigFile(null, 'ftp');
  743. if (PEAR::isError($e)) {
  744. return $e;
  745. }
  746. $fail = array();
  747. foreach ($this->configuration_info as $key => $val) {
  748. if (in_array($this->getGroup($key),
  749. array('File Locations', 'File Locations (Advanced)')) &&
  750. $this->getType($key) == 'directory') {
  751. // any directory configs must be set for this to work
  752. if (!isset($this->configuration['ftp'][$key])) {
  753. $fail[] = $key;
  754. }
  755. }
  756. }
  757. if (!count($fail)) {
  758. return true;
  759. }
  760. $fail = '"' . implode('", "', $fail) . '"';
  761. unset($this->files['ftp']);
  762. unset($this->configuration['ftp']);
  763. return PEAR::raiseError('ERROR: Ftp configuration file must set all ' .
  764. 'directory configuration variables. These variables were not set: ' .
  765. $fail);
  766. } while (false); // poor man's catch
  767. unset($this->files['ftp']);
  768. return PEAR::raiseError('no remote host specified');
  769. }
  770. /**
  771. * Reads the existing configurations and creates the _channels array from it
  772. */
  773. function _setupChannels()
  774. {
  775. $set = array_flip(array_values($this->_channels));
  776. foreach ($this->configuration as $layer => $data) {
  777. $i = 1000;
  778. if (isset($data['__channels']) && is_array($data['__channels'])) {
  779. foreach ($data['__channels'] as $channel => $info) {
  780. $set[$channel] = $i++;
  781. }
  782. }
  783. }
  784. $this->_channels = array_values(array_flip($set));
  785. $this->setChannels($this->_channels);
  786. }
  787. function deleteChannel($channel)
  788. {
  789. $ch = strtolower($channel);
  790. foreach ($this->configuration as $layer => $data) {
  791. if (isset($data['__channels']) && isset($data['__channels'][$ch])) {
  792. unset($this->configuration[$layer]['__channels'][$ch]);
  793. }
  794. }
  795. $this->_channels = array_flip($this->_channels);
  796. unset($this->_channels[$ch]);
  797. $this->_channels = array_flip($this->_channels);
  798. }
  799. /**
  800. * Merges data into a config layer from a file. Does the same
  801. * thing as readConfigFile, except it does not replace all
  802. * existing values in the config layer.
  803. * @param string file to read from
  804. * @param bool whether to overwrite existing data (default TRUE)
  805. * @param string config layer to insert data into ('user' or 'system')
  806. * @param string if true, errors are returned if file opening fails
  807. * @return bool TRUE on success or a PEAR error on failure
  808. */
  809. function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true)
  810. {
  811. if (empty($this->files[$layer])) {
  812. return $this->raiseError("unknown config layer `$layer'");
  813. }
  814. if ($file === null) {
  815. $file = $this->files[$layer];
  816. }
  817. $data = $this->_readConfigDataFrom($file);
  818. if (PEAR::isError($data)) {
  819. if (!$strict) {
  820. return true;
  821. }
  822. $this->_errorsFound++;
  823. $this->lastError = $data;
  824. return $data;
  825. }
  826. $this->_decodeInput($data);
  827. if ($override) {
  828. $this->configuration[$layer] =
  829. PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data);
  830. } else {
  831. $this->configuration[$layer] =
  832. PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]);
  833. }
  834. $this->_setupChannels();
  835. if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) {
  836. $this->_registry[$layer] = &new PEAR_Registry($phpdir);
  837. $this->_registry[$layer]->setConfig($this, false);
  838. $this->_regInitialized[$layer] = false;
  839. } else {
  840. unset($this->_registry[$layer]);
  841. }
  842. return true;
  843. }
  844. /**
  845. * @param array
  846. * @param array
  847. * @return array
  848. * @static
  849. */
  850. function arrayMergeRecursive($arr2, $arr1)
  851. {
  852. $ret = array();
  853. foreach ($arr2 as $key => $data) {
  854. if (!isset($arr1[$key])) {
  855. $ret[$key] = $data;
  856. unset($arr1[$key]);
  857. continue;
  858. }
  859. if (is_array($data)) {
  860. if (!is_array($arr1[$key])) {
  861. $ret[$key] = $arr1[$key];
  862. unset($arr1[$key]);
  863. continue;
  864. }
  865. $ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]);
  866. unset($arr1[$key]);
  867. }
  868. }
  869. return array_merge($ret, $arr1);
  870. }
  871. /**
  872. * Writes data into a config layer from a file.
  873. *
  874. * @param string|null file to read from, or null for default
  875. * @param string config layer to insert data into ('user' or
  876. * 'system')
  877. * @param string|null data to write to config file or null for internal data [DEPRECATED]
  878. * @return bool TRUE on success or a PEAR error on failure
  879. */
  880. function writeConfigFile($file = null, $layer = 'user', $data = null)
  881. {
  882. $this->_lazyChannelSetup($layer);
  883. if ($layer == 'both' || $layer == 'all') {
  884. foreach ($this->files as $type => $file) {
  885. $err = $this->writeConfigFile($file, $type, $data);
  886. if (PEAR::isError($err)) {
  887. return $err;
  888. }
  889. }
  890. return true;
  891. }
  892. if (empty($this->files[$layer])) {
  893. return $this->raiseError("unknown config file type `$layer'");
  894. }
  895. if ($file === null) {
  896. $file = $this->files[$layer];
  897. }
  898. $data = ($data === null) ? $this->configuration[$layer] : $data;
  899. $this->_encodeOutput($data);
  900. $opt = array('-p', dirname($file));
  901. if (!@System::mkDir($opt)) {
  902. return $this->raiseError("could not create directory: " . dirname($file));
  903. }
  904. if (file_exists($file) && is_file($file) && !is_writeable($file)) {
  905. return $this->raiseError("no write access to $file!");
  906. }
  907. $fp = @fopen($file, "w");
  908. if (!$fp) {
  909. return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)");
  910. }
  911. $contents = "#PEAR_Config 0.9\n" . serialize($data);
  912. if (!@fwrite($fp, $contents)) {
  913. return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)");
  914. }
  915. return true;
  916. }
  917. /**
  918. * Reads configuration data from a file and returns the parsed data
  919. * in an array.
  920. *
  921. * @param string file to read from
  922. * @return array configuration data or a PEAR error on failure
  923. * @access private
  924. */
  925. function _readConfigDataFrom($file)
  926. {
  927. $fp = false;
  928. if (file_exists($file)) {
  929. $fp = @fopen($file, "r");
  930. }
  931. if (!$fp) {
  932. return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed");
  933. }
  934. $size = filesize($file);
  935. $rt = get_magic_quotes_runtime();
  936. set_magic_quotes_runtime(0);
  937. fclose($fp);
  938. $contents = file_get_contents($file);
  939. if (empty($contents)) {
  940. return $this->raiseError('Configuration file "' . $file . '" is empty');
  941. }
  942. set_magic_quotes_runtime($rt);
  943. $version = false;
  944. if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) {
  945. $version = $matches[1];
  946. $contents = substr($contents, strlen($matches[0]));
  947. } else {
  948. // Museum config file
  949. if (substr($contents,0,2) == 'a:') {
  950. $version = '0.1';
  951. }
  952. }
  953. if ($version && version_compare("$version", '1', '<')) {
  954. // no '@', it is possible that unserialize
  955. // raises a notice but it seems to block IO to
  956. // STDOUT if a '@' is used and a notice is raise
  957. $data = unserialize($contents);
  958. if (!is_array($data) && !$data) {
  959. if ($contents == serialize(false)) {
  960. $data = array();
  961. } else {
  962. $err = $this->raiseError("PEAR_Config: bad data in $file");
  963. return $err;
  964. }
  965. }
  966. if (!is_array($data)) {
  967. if (strlen(trim($contents)) > 0) {
  968. $error = "PEAR_Config: bad data in $file";
  969. $err = $this->raiseError($error);
  970. return $err;
  971. }
  972. $data = array();
  973. }
  974. // add parsing of newer formats here...
  975. } else {
  976. $err = $this->raiseError("$file: unknown version `$version'");
  977. return $err;
  978. }
  979. return $data;
  980. }
  981. /**
  982. * Gets the file used for storing the config for a layer
  983. *
  984. * @param string $layer 'user' or 'system'
  985. */
  986. function getConfFile($layer)
  987. {
  988. return $this->files[$layer];
  989. }
  990. /**
  991. * @param string Configuration class name, used for detecting duplicate calls
  992. * @param array information on a role as parsed from its xml file
  993. * @return true|PEAR_Error
  994. * @access private
  995. */
  996. function _addConfigVars($class, $vars)
  997. {
  998. static $called = array();
  999. if (isset($called[$class])) {
  1000. return;
  1001. }
  1002. $called[$class] = 1;
  1003. if (count($vars) > 3) {
  1004. return $this->raiseError('Roles can only define 3 new config variables or less');
  1005. }
  1006. foreach ($vars as $name => $var) {
  1007. if (!is_array($var)) {
  1008. return $this->raiseError('Configuration information must be an array');
  1009. }
  1010. if (!isset($var['type'])) {
  1011. return $this->raiseError('Configuration information must contain a type');
  1012. } elseif (!in_array($var['type'],
  1013. array('string', 'mask', 'password', 'directory', 'file', 'set'))) {
  1014. return $this->raiseError(
  1015. 'Configuration type must be one of directory, file, string, ' .
  1016. 'mask, set, or password');
  1017. }
  1018. if (!isset($var['default'])) {
  1019. return $this->raiseError(
  1020. 'Configuration information must contain a default value ("default" index)');
  1021. }
  1022. if (is_array($var['default'])) {
  1023. $real_default = '';
  1024. foreach ($var['default'] as $config_var => $val) {
  1025. if (strpos($config_var, 'text') === 0) {
  1026. $real_default .= $val;
  1027. } elseif (strpos($config_var, 'constant') === 0) {
  1028. if (!defined($val)) {
  1029. return $this->raiseError(
  1030. 'Unknown constant "' . $val . '" requested in ' .
  1031. 'default value for configuration variable "' .
  1032. $name . '"');
  1033. }
  1034. $real_default .= constant($val);
  1035. } elseif (isset($this->configuration_info[$config_var])) {
  1036. $real_default .=
  1037. $this->configuration_info[$config_var]['default'];
  1038. } else {
  1039. return $this->raiseError(
  1040. 'Unknown request for "' . $config_var . '" value in ' .
  1041. 'default value for configuration variable "' .
  1042. $name . '"');
  1043. }
  1044. }
  1045. $var['default'] = $real_default;
  1046. }
  1047. if ($var['type'] == 'integer') {
  1048. $var['default'] = (integer) $var['default'];
  1049. }
  1050. if (!isset($var['doc'])) {
  1051. return $this->raiseError(
  1052. 'Configuration information must contain a summary ("doc" index)');
  1053. }
  1054. if (!isset($var['prompt'])) {
  1055. return $this->raiseError(
  1056. 'Configuration information must contain a simple prompt ("prompt" index)');
  1057. }
  1058. if (!isset($var['group'])) {
  1059. return $this->raiseError(
  1060. 'Configuration information must contain a simple group ("group" index)');
  1061. }
  1062. if (isset($this->configuration_info[$name])) {
  1063. return $this->raiseError('Configuration variable "' . $name .
  1064. '" already exists');
  1065. }
  1066. $this->configuration_info[$name] = $var;
  1067. // fix bug #7351: setting custom config variable in a channel fails
  1068. $this->_channelConfigInfo[] = $name;
  1069. }
  1070. return true;
  1071. }
  1072. /**
  1073. * Encodes/scrambles configuration data before writing to files.
  1074. * Currently, 'password' values will be base64-encoded as to avoid
  1075. * that people spot cleartext passwords by accident.
  1076. *
  1077. * @param array (reference) array to encode values in
  1078. * @return bool TRUE on success
  1079. * @access private
  1080. */
  1081. function _encodeOutput(&$data)
  1082. {
  1083. foreach ($data as $key => $value) {
  1084. if ($key == '__channels') {
  1085. foreach ($data['__channels'] as $channel => $blah) {
  1086. $this->_encodeOutput($data['__channels'][$channel]);
  1087. }
  1088. }
  1089. if (!isset($this->configuration_info[$key])) {
  1090. continue;
  1091. }
  1092. $type = $this->configuration_info[$key]['type'];
  1093. switch ($type) {
  1094. // we base64-encode passwords so they are at least
  1095. // not shown in plain by accident
  1096. case 'password': {
  1097. $data[$key] = base64_encode($data[$key]);
  1098. break;
  1099. }
  1100. case 'mask': {
  1101. $data[$key] = octdec($data[$key]);
  1102. break;
  1103. }
  1104. }
  1105. }
  1106. return true;
  1107. }
  1108. /**
  1109. * Decodes/unscrambles configuration data after reading from files.
  1110. *
  1111. * @param array (reference) array to encode values in
  1112. * @return bool TRUE on success
  1113. * @access private
  1114. *
  1115. * @see PEAR_Config::_encodeOutput
  1116. */
  1117. function _decodeInput(&$data)
  1118. {
  1119. if (!is_array($data)) {
  1120. return true;
  1121. }
  1122. foreach ($data as $key => $value) {
  1123. if ($key == '__channels') {
  1124. foreach ($data['__channels'] as $channel => $blah) {
  1125. $this->_decodeInput($data['__channels'][$channel]);
  1126. }
  1127. }
  1128. if (!isset($this->configuration_info[$key])) {
  1129. continue;
  1130. }
  1131. $type = $this->configuration_info[$key]['type'];
  1132. switch ($type) {
  1133. case 'password': {
  1134. $data[$key] = base64_decode($data[$key]);
  1135. break;
  1136. }
  1137. case 'mask': {
  1138. $data[$key] = decoct($data[$key]);
  1139. break;
  1140. }
  1141. }
  1142. }
  1143. return true;
  1144. }
  1145. /**
  1146. * Retrieve the default channel.
  1147. *
  1148. * On startup, channels are not initialized, so if the default channel is not
  1149. * pear.php.net, then initialize the config.
  1150. * @param string registry layer
  1151. * @return string|false
  1152. */
  1153. function getDefaultChannel($layer = null)
  1154. {
  1155. $ret = false;
  1156. if ($layer === null) {
  1157. foreach ($this->layers as $layer) {
  1158. if (isset($this->configuration[$layer]['default_channel'])) {
  1159. $ret = $this->configuration[$layer]['default_channel'];
  1160. break;
  1161. }
  1162. }
  1163. } elseif (isset($this->configuration[$layer]['default_channel'])) {
  1164. $ret = $this->configuration[$layer]['default_channel'];
  1165. }
  1166. if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') {
  1167. $ret = 'pecl.php.net';
  1168. }
  1169. if ($ret) {
  1170. if ($ret != 'pear.php.net') {
  1171. $this->_lazyChannelSetup();
  1172. }
  1173. return $ret;
  1174. }
  1175. return PEAR_CONFIG_DEFAULT_CHANNEL;
  1176. }
  1177. /**
  1178. * Returns a configuration value, prioritizing layers as per the
  1179. * layers property.
  1180. *
  1181. * @param string config key
  1182. * @return mixed the config value, or NULL if not found
  1183. * @access public
  1184. */
  1185. function get($key, $layer = null, $channel = false)
  1186. {
  1187. if (!isset($this->configuration_info[$key])) {
  1188. return null;
  1189. }
  1190. if ($key == '__channels') {
  1191. return null;
  1192. }
  1193. if ($key == 'default_channel') {
  1194. return $this->getDefaultChannel($layer);
  1195. }
  1196. if (!$channel) {
  1197. $channel = $this->getDefaultChannel();
  1198. } elseif ($channel != 'pear.php.net') {
  1199. $this->_lazyChannelSetup();
  1200. }
  1201. $channel = strtolower($channel);
  1202. $test = (in_array($key, $this->_channelConfigInfo)) ?
  1203. $this->_getChannelValue($key, $layer, $channel) :
  1204. null;
  1205. if ($test !== null) {
  1206. if ($this->_installRoot) {
  1207. if (in_array($this->getGroup($key),
  1208. array('File Locations', 'File Locations (Advanced)')) &&
  1209. $this->getType($key) == 'directory') {
  1210. return $this->_prependPath($test, $this->_installRoot);
  1211. }
  1212. }
  1213. return $test;
  1214. }
  1215. if ($layer === null) {
  1216. foreach ($this->layers as $layer) {
  1217. if (isset($this->configuration[$layer][$key])) {
  1218. $test = $this->configuration[$layer][$key];
  1219. if ($this->_installRoot) {
  1220. if (in_array($this->getGroup($key),
  1221. array('File Locations', 'File Locations (Advanced)')) &&
  1222. $this->getType($key) == 'directory') {
  1223. return $this->_prependPath($test, $this->_installRoot);
  1224. }
  1225. }
  1226. if ($key == 'preferred_mirror') {
  1227. $reg = &$this->getRegistry();
  1228. if (is_object($reg)) {
  1229. $chan = &$reg->getChannel($channel);
  1230. if (PEAR::isError($chan)) {
  1231. return $channel;
  1232. }
  1233. if (!$chan->getMirror($test) && $chan->getName() != $test) {
  1234. return $channel; // mirror does not exist
  1235. }
  1236. }
  1237. }
  1238. return $test;
  1239. }
  1240. }
  1241. } elseif (isset($this->configuration[$layer][$key])) {
  1242. $test = $this->configuration[$layer][$key];
  1243. if ($this->_installRoot) {
  1244. if (in_array($this->getGroup($key),
  1245. array('File Locations', 'File Locations (Advanced)')) &&
  1246. $this->getType($key) == 'directory') {
  1247. return $this->_prependPath($test, $this->_installRoot);
  1248. }
  1249. }
  1250. if ($key == 'preferred_mirror') {
  1251. $reg = &$this->getRegistry();
  1252. if (is_object($reg)) {
  1253. $chan = &$reg->getChannel($channel);
  1254. if (PEAR::isError($chan)) {
  1255. return $channel;
  1256. }
  1257. if (!$chan->getMirror($test) && $chan->getName() != $test) {
  1258. return $channel; // mirror does not exist
  1259. }
  1260. }
  1261. }
  1262. return $test;
  1263. }
  1264. return null;
  1265. }
  1266. /**
  1267. * Returns a channel-specific configuration value, prioritizing layers as per the
  1268. * layers property.
  1269. *
  1270. * @param string config key
  1271. * @return mixed the config value, or NULL if not found
  1272. * @access private
  1273. */
  1274. function _getChannelValue($key, $layer, $channel)
  1275. {
  1276. if ($key == '__channels' || $channel == 'pear.php.net') {
  1277. return null;
  1278. }
  1279. $ret = null;
  1280. if ($layer === null) {
  1281. foreach ($this->layers as $ilayer) {
  1282. if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) {
  1283. $ret = $this->configuration[$ilayer]['__channels'][$channel][$key];
  1284. break;
  1285. }
  1286. }
  1287. } elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
  1288. $ret = $this->configuration[$layer]['__channels'][$channel][$key];
  1289. }
  1290. if ($key != 'preferred_mirror') {
  1291. return $ret;
  1292. }
  1293. if ($ret !== null) {
  1294. $reg = &$this->getRegistry($layer);
  1295. if (is_object($reg)) {
  1296. $chan = &$reg->getChannel($channel);
  1297. if (PEAR::isError($chan)) {
  1298. return $channel;
  1299. }
  1300. if (!$chan->getMirror($ret) && $chan->getName() != $ret) {
  1301. return $channel; // mirror does not exist
  1302. }
  1303. }
  1304. return $ret;
  1305. }
  1306. if ($channel != $this->getDefaultChannel($layer)) {
  1307. return $channel; // we must use the channel name as the preferred mirror
  1308. // if the user has not chosen an alternate
  1309. }
  1310. return $this->getDefaultChannel($layer);
  1311. }
  1312. /**
  1313. * Set a config value in a specific layer (defaults to 'user').
  1314. * Enforces the types defined in the configuration_info array. An
  1315. * integer config variable will be cast to int, and a set config
  1316. * variable will be validated against its legal values.
  1317. *
  1318. * @param string config key
  1319. * @param string config value
  1320. * @param string (optional) config layer
  1321. * @param string channel to set this value for, or null for global value
  1322. * @return bool TRUE on success, FALSE on failure
  1323. */
  1324. function set($key, $value, $layer = 'user', $channel = false)
  1325. {
  1326. if ($key == '__channels') {
  1327. return false;
  1328. }
  1329. if (!isset($this->configuration[$layer])) {
  1330. return false;
  1331. }
  1332. if ($key == 'default_channel') {
  1333. // can only set this value globally
  1334. $channel = 'pear.php.net';
  1335. if ($value != 'pear.php.net') {
  1336. $this->_lazyChannelSetup($layer);
  1337. }
  1338. }
  1339. if ($key == 'preferred_mirror') {
  1340. if ($channel == '__uri') {
  1341. return false; // can't set the __uri pseudo-channel's mirror
  1342. }
  1343. $reg = &$this->getRegistry($layer);
  1344. if (is_object($reg)) {
  1345. $chan = &$reg->getChannel($channel ? $channel : 'pear.php.net');
  1346. if (PEAR::isError($chan)) {
  1347. return false;
  1348. }
  1349. if (!$chan->getMirror($value) && $chan->getName() != $value) {
  1350. return false; // mirror does not exist
  1351. }
  1352. }
  1353. }
  1354. if (!isset($this->configuration_info[$key])) {
  1355. return false;
  1356. }
  1357. extract($this->configuration_info[$key]);
  1358. switch ($type) {
  1359. case 'integer':
  1360. $value = (int)$value;
  1361. break;
  1362. case 'set': {
  1363. // If a valid_set is specified, require the value to
  1364. // be in the set. If there is no valid_set, accept
  1365. // any value.
  1366. if ($valid_set) {
  1367. reset($valid_set);
  1368. if ((key($valid_set) === 0 && !in_array($value, $valid_set)) ||
  1369. (key($valid_set) !== 0 && empty($valid_set[$value])))
  1370. {
  1371. return false;
  1372. }
  1373. }
  1374. break;
  1375. }
  1376. }
  1377. if (!$channel) {
  1378. $channel = $this->get('default_channel', null, 'pear.php.net');
  1379. }
  1380. if (!in_array($channel, $this->_channels)) {
  1381. $this->_lazyChannelSetup($layer);
  1382. $reg = &$this->getRegistry($layer);
  1383. if ($reg) {
  1384. $channel = $reg->channelName($channel);
  1385. }
  1386. if (!in_array($channel, $this->_channels)) {
  1387. return false;
  1388. }
  1389. }
  1390. if ($channel != 'pear.php.net') {
  1391. if (in_array($key, $this->_channelConfigInfo)) {
  1392. $this->configuration[$layer]['__channels'][$channel][$key] = $value;
  1393. return true;
  1394. }
  1395. return false;
  1396. }
  1397. if ($key == 'default_channel') {
  1398. if (!isset($reg)) {
  1399. $reg = &$this->getRegistry($layer);
  1400. if (!$reg) {
  1401. $reg = &$this->getRegistry();
  1402. }
  1403. }
  1404. if ($reg) {
  1405. $value = $reg->channelName($value);
  1406. }
  1407. if (!$value) {
  1408. return false;
  1409. }
  1410. }
  1411. $this->configuration[$layer][$key] = $value;
  1412. if ($key == 'php_dir' && !$this->_noRegistry) {
  1413. if (!isset($this->_registry[$layer]) ||
  1414. $value != $this->_registry[$layer]->install_dir) {
  1415. $this->_registry[$layer] = &new PEAR_Registry($value);
  1416. $this->_regInitialized[$layer] = false;
  1417. $this->_registry[$layer]->setConfig($this, false);
  1418. }
  1419. }
  1420. return true;
  1421. }
  1422. function _lazyChannelSetup($uselayer = false)
  1423. {
  1424. if ($this->_noRegistry) {
  1425. return;
  1426. }
  1427. $merge = false;
  1428. foreach ($this->_registry as $layer => $p) {
  1429. if ($uselayer && $uselayer != $layer) {
  1430. continue;
  1431. }
  1432. if (!$this->_regInitialized[$layer]) {
  1433. if ($layer == 'default' && isset($this->_registry['user']) ||
  1434. isset($this->_registry['system'])) {
  1435. // only use the default registry if there are no alternatives
  1436. continue;
  1437. }
  1438. if (!is_object($this->_registry[$layer])) {
  1439. if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) {
  1440. $this->_registry[$layer] = &new PEAR_Registry($phpdir);
  1441. $this->_registry[$layer]->setConfig($this, false);
  1442. $this->_regInitialized[$layer] = false;
  1443. } else {
  1444. unset($this->_registry[$layer]);
  1445. return;
  1446. }
  1447. }
  1448. $this->setChannels($this->_registry[$layer]->listChannels(), $merge);
  1449. $this->_regInitialized[$layer] = true;
  1450. $merge = true;
  1451. }
  1452. }
  1453. }
  1454. /**
  1455. * Set the list of channels.
  1456. *
  1457. * This should be set via a call to {@link PEAR_Registry::listChannels()}
  1458. * @param array
  1459. * @param bool
  1460. * @return bool success of operation
  1461. */
  1462. function setChannels($channels, $merge = false)
  1463. {
  1464. if (!is_array($channels)) {
  1465. return false;
  1466. }
  1467. if ($merge) {
  1468. $this->_channels = array_merge($this->_channels, $channels);
  1469. } else {
  1470. $this->_channels = $channels;
  1471. }
  1472. foreach ($channels as $channel) {
  1473. $channel = strtolower($channel);
  1474. if ($channel == 'pear.php.net') {
  1475. continue;
  1476. }
  1477. foreach ($this->layers as $layer) {
  1478. if (!isset($this->configuration[$layer]['__channels'])) {
  1479. $this->configuration[$layer]['__channels'] = array();
  1480. }
  1481. if (!isset($this->configuration[$layer]['__channels'][$channel])
  1482. || !is_array($this->configuration[$layer]['__channels'][$channel])) {
  1483. $this->configuration[$layer]['__channels'][$channel] = array();
  1484. }
  1485. }
  1486. }
  1487. return true;
  1488. }
  1489. /**
  1490. * Get the type of a config value.
  1491. *
  1492. * @param string config key
  1493. *
  1494. * @return string type, one of "string", "integer", "file",
  1495. * "directory", "set" or "password".
  1496. *
  1497. * @access public
  1498. *
  1499. */
  1500. function getType($key)
  1501. {
  1502. if (isset($this->configuration_info[$key])) {
  1503. return $this->configuration_info[$key]['type'];
  1504. }
  1505. return false;
  1506. }
  1507. /**
  1508. * Get the documentation for a config value.
  1509. *
  1510. * @param string config key
  1511. * @return string documentation string
  1512. *
  1513. * @access public
  1514. *
  1515. */
  1516. function getDocs($key)
  1517. {
  1518. if (isset($this->configuration_info[$key])) {
  1519. return $this->configuration_info[$key]['doc'];
  1520. }
  1521. return false;
  1522. }
  1523. /**
  1524. * Get the short documentation for a config value.
  1525. *
  1526. * @param string config key
  1527. * @return string short documentation string
  1528. *
  1529. * @access public
  1530. *
  1531. */
  1532. function getPrompt($key)
  1533. {
  1534. if (isset($this->configuration_info[$key])) {
  1535. return $this->configuration_info[$key]['prompt'];
  1536. }
  1537. return false;
  1538. }
  1539. /**
  1540. * Get the parameter group for a config key.
  1541. *
  1542. * @param string config key
  1543. * @return string parameter group
  1544. *
  1545. * @access public
  1546. *
  1547. */
  1548. function getGroup($key)
  1549. {
  1550. if (isset($this->configuration_info[$key])) {
  1551. return $this->configuration_info[$key]['group'];
  1552. }
  1553. return false;
  1554. }
  1555. /**
  1556. * Get the list of parameter groups.
  1557. *
  1558. * @return array list of parameter groups
  1559. *
  1560. * @access public
  1561. *
  1562. */
  1563. function getGroups()
  1564. {
  1565. $tmp = array();
  1566. foreach ($this->configuration_info as $key => $info) {
  1567. $tmp[$info['group']] = 1;
  1568. }
  1569. return array_keys($tmp);
  1570. }
  1571. /**
  1572. * Get the list of the parameters in a group.
  1573. *
  1574. * @param string $group parameter group
  1575. * @return array list of parameters in $group
  1576. *
  1577. * @access public
  1578. *
  1579. */
  1580. function getGroupKeys($group)
  1581. {
  1582. $keys = array();
  1583. foreach ($this->configuration_info as $key => $info) {
  1584. if ($info['group'] == $group) {
  1585. $keys[] = $key;
  1586. }
  1587. }
  1588. return $keys;
  1589. }
  1590. /**
  1591. * Get the list of allowed set values for a config value. Returns
  1592. * NULL for config values that are not sets.
  1593. *
  1594. * @param string config key
  1595. * @return array enumerated array of set values, or NULL if the
  1596. * config key is unknown or not a set
  1597. *
  1598. * @access public
  1599. *
  1600. */
  1601. function getSetValues($key)
  1602. {
  1603. if (isset($this->configuration_info[$key]) &&
  1604. isset($this->configuration_info[$key]['type']) &&
  1605. $this->configuration_info[$key]['type'] == 'set')
  1606. {
  1607. $valid_set = $this->configuration_info[$key]['valid_set'];
  1608. reset($valid_set);
  1609. if (key($valid_set) === 0) {
  1610. return $valid_set;
  1611. }
  1612. return array_keys($valid_set);
  1613. }
  1614. return null;
  1615. }
  1616. /**
  1617. * Get all the current config keys.
  1618. *
  1619. * @return array simple array of config keys
  1620. *
  1621. * @access public
  1622. */
  1623. function getKeys()
  1624. {
  1625. $keys = array();
  1626. foreach ($this->layers as $layer) {
  1627. $test = $this->configuration[$layer];
  1628. if (isset($test['__channels'])) {
  1629. foreach ($test['__channels'] as $channel => $configs) {
  1630. $keys = array_merge($keys, $configs);
  1631. }
  1632. }
  1633. unset($test['__channels']);
  1634. $keys = array_merge($keys, $test);
  1635. }
  1636. return array_keys($keys);
  1637. }
  1638. /**
  1639. * Remove the a config key from a specific config layer.
  1640. *
  1641. * @param string config key
  1642. * @param string (optional) config layer
  1643. * @param string (optional) channel (defaults to default channel)
  1644. * @return bool TRUE on success, FALSE on failure
  1645. *
  1646. * @access public
  1647. */
  1648. function remove($key, $layer = 'user', $channel = null)
  1649. {
  1650. if ($channel === null) {
  1651. $channel = $this->getDefaultChannel();
  1652. }
  1653. if ($channel !== 'pear.php.net') {
  1654. if (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
  1655. unset($this->configuration[$layer]['__channels'][$channel][$key]);
  1656. return true;
  1657. }
  1658. }
  1659. if (isset($this->configuration[$layer][$key])) {
  1660. unset($this->configuration[$layer][$key]);
  1661. return true;
  1662. }
  1663. return false;
  1664. }
  1665. /**
  1666. * Temporarily remove an entire config layer. USE WITH CARE!
  1667. *
  1668. * @param string config key
  1669. * @param string (optional) config layer
  1670. * @return bool TRUE on success, FALSE on failure
  1671. *
  1672. * @access public
  1673. */
  1674. function removeLayer($layer)
  1675. {
  1676. if (isset($this->configuration[$layer])) {
  1677. $this->configuration[$layer] = array();
  1678. return true;
  1679. }
  1680. return false;
  1681. }
  1682. /**
  1683. * Stores configuration data in a layer.
  1684. *
  1685. * @param string config layer to store
  1686. * @return bool TRUE on success, or PEAR error on failure
  1687. *
  1688. * @access public
  1689. */
  1690. function store($layer = 'user', $data = null)
  1691. {
  1692. return $this->writeConfigFile(null, $layer, $data);
  1693. }
  1694. /**
  1695. * Tells what config layer that gets to define a key.
  1696. *
  1697. * @param string config key
  1698. * @param boolean return the defining channel
  1699. *
  1700. * @return string|array the config layer, or an empty string if not found.
  1701. *
  1702. * if $returnchannel, the return is an array array('layer' => layername,
  1703. * 'channel' => channelname), or an empty string if not found
  1704. *
  1705. * @access public
  1706. */
  1707. function definedBy($key, $returnchannel = false)
  1708. {
  1709. foreach ($this->layers as $layer) {
  1710. $channel = $this->getDefaultChannel();
  1711. if ($channel !== 'pear.php.net') {
  1712. if (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
  1713. if ($returnchannel) {
  1714. return array('layer' => $layer, 'channel' => $channel);
  1715. }
  1716. return $layer;
  1717. }
  1718. }
  1719. if (isset($this->configuration[$layer][$key])) {
  1720. if ($returnchannel) {
  1721. return array('layer' => $layer, 'channel' => 'pear.php.net');
  1722. }
  1723. return $layer;
  1724. }
  1725. }
  1726. return '';
  1727. }
  1728. /**
  1729. * Tells whether a given key exists as a config value.
  1730. *
  1731. * @param string config key
  1732. * @return bool whether <config key> exists in this object
  1733. *
  1734. * @access public
  1735. */
  1736. function isDefined($key)
  1737. {
  1738. foreach ($this->layers as $layer) {
  1739. if (isset($this->configuration[$layer][$key])) {
  1740. return true;
  1741. }
  1742. }
  1743. return false;
  1744. }
  1745. /**
  1746. * Tells whether a given config layer exists.
  1747. *
  1748. * @param string config layer
  1749. * @return bool whether <config layer> exists in this object
  1750. *
  1751. * @access public
  1752. */
  1753. function isDefinedLayer($layer)
  1754. {
  1755. return isset($this->configuration[$layer]);
  1756. }
  1757. /**
  1758. * Returns the layers defined (except the 'default' one)
  1759. *
  1760. * @return array of the defined layers
  1761. */
  1762. function getLayers()
  1763. {
  1764. $cf = $this->configuration;
  1765. unset($cf['default']);
  1766. return array_keys($cf);
  1767. }
  1768. function apiVersion()
  1769. {
  1770. return '1.1';
  1771. }
  1772. /**
  1773. * @return PEAR_Registry
  1774. */
  1775. function &getRegistry($use = null)
  1776. {
  1777. $layer = $use === null ? 'user' : $use;
  1778. if (isset($this->_registry[$layer])) {
  1779. return $this->_registry[$layer];
  1780. } elseif ($use === null && isset($this->_registry['system'])) {
  1781. return $this->_registry['system'];
  1782. } elseif ($use === null && isset($this->_registry['default'])) {
  1783. return $this->_registry['default'];
  1784. } elseif ($use) {
  1785. $a = false;
  1786. return $a;
  1787. }
  1788. // only go here if null was passed in
  1789. echo "CRITICAL ERROR: Registry could not be initialized from any value";
  1790. exit(1);
  1791. }
  1792. /**
  1793. * This is to allow customization like the use of installroot
  1794. * @param PEAR_Registry
  1795. * @return bool
  1796. */
  1797. function setRegistry(&$reg, $layer = 'user')
  1798. {
  1799. if ($this->_noRegistry) {
  1800. return false;
  1801. }
  1802. if (!in_array($layer, array('user', 'system'))) {
  1803. return false;
  1804. }
  1805. $this->_registry[$layer] = &$reg;
  1806. if (is_object($reg)) {
  1807. $this->_registry[$layer]->setConfig($this, false);
  1808. }
  1809. return true;
  1810. }
  1811. function noRegistry()
  1812. {
  1813. $this->_noRegistry = true;
  1814. }
  1815. /**
  1816. * @return PEAR_REST
  1817. */
  1818. function &getREST($version, $options = array())
  1819. {
  1820. $version = str_replace('.', '', $version);
  1821. if (!class_exists($class = 'PEAR_REST_' . $version)) {
  1822. require_once 'PEAR/REST/' . $version . '.php';
  1823. }
  1824. $remote = &new $class($this, $options);
  1825. return $remote;
  1826. }
  1827. /**
  1828. * The ftp server is set in {@link readFTPConfigFile()}. It exists only if a
  1829. * remote configuration file has been specified
  1830. * @return PEAR_FTP|false
  1831. */
  1832. function &getFTP()
  1833. {
  1834. if (isset($this->_ftp)) {
  1835. return $this->_ftp;
  1836. }
  1837. $a = false;
  1838. return $a;
  1839. }
  1840. function _prependPath($path, $prepend)
  1841. {
  1842. if (strlen($prepend) > 0) {
  1843. if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) {
  1844. if (preg_match('/^[a-z]:/i', $prepend)) {
  1845. $prepend = substr($prepend, 2);
  1846. } elseif ($prepend{0} != '\\') {
  1847. $prepend = "\\$prepend";
  1848. }
  1849. $path = substr($path, 0, 2) . $prepend . substr($path, 2);
  1850. } else {
  1851. $path = $prepend . $path;
  1852. }
  1853. }
  1854. return $path;
  1855. }
  1856. /**
  1857. * @param string|false installation directory to prepend to all _dir variables, or false to
  1858. * disable
  1859. */
  1860. function setInstallRoot($root)
  1861. {
  1862. if (substr($root, -1) == DIRECTORY_SEPARATOR) {
  1863. $root = substr($root, 0, -1);
  1864. }
  1865. $old = $this->_installRoot;
  1866. $this->_installRoot = $root;
  1867. if (($old != $root) && !$this->_noRegistry) {
  1868. foreach (array_keys($this->_registry) as $layer) {
  1869. if ($layer == 'ftp' || !isset($this->_registry[$layer])) {
  1870. continue;
  1871. }
  1872. $this->_registry[$layer] =
  1873. &new PEAR_Registry($this->get('php_dir', $layer, 'pear.php.net'));
  1874. $this->_registry[$layer]->setConfig($this, false);
  1875. $this->_regInitialized[$layer] = false;
  1876. }
  1877. }
  1878. }
  1879. }