Use a nice fancy deep-merge function for merging arrays in SiteConfiguration (newly...
[lhc/web/wiklou.git] / includes / SiteConfiguration.php
1 <?php
2
3 /**
4 * The include paths change after this file is included from commandLine.inc,
5 * meaning that require_once() fails to detect that it is including the same
6 * file again. We use DIY C-style protection as a workaround.
7 */
8
9 // Hide this pattern from Doxygen, which spazzes out at it
10 /// @cond
11 if (!defined('SITE_CONFIGURATION')) {
12 define('SITE_CONFIGURATION', 1);
13 /// @endcond
14
15 /**
16 * This is a class used to hold configuration settings, particularly for multi-wiki sites.
17 *
18 */
19 class SiteConfiguration {
20 var $suffixes = array();
21 var $wikis = array();
22 var $settings = array();
23 var $localVHosts = array();
24
25 /**
26 * Retrieves a configuration setting for a given wiki.
27 * @param $settingName String ID of the setting name to retrieve
28 * @param $wiki String Wiki ID of the wiki in question.
29 * @param $suffix String The suffix of the wiki in question.
30 * @param $params Array List of parameters. $.'key' is replaced by $value in all returned data.
31 * @param $wikiTags Array The tags assigned to the wiki.
32 * @return Mixed the value of the setting requested.
33 */
34 function get( $settingName, $wiki, $suffix, $params = array(), $wikiTags = array() ) {
35 $append = false;
36 $var = $settingName;
37 if ( substr( $varname, 0, 1 ) == '+' ) {
38 $append = true;
39 $var = substr( $settingName, 1 );
40 }
41
42 if ( array_key_exists( $settingName, $this->settings ) ) {
43 $thisSetting =& $this->settings[$settingName];
44 do {
45 // Do individual wiki settings
46 if ( array_key_exists( $wiki, $thisSetting ) ) {
47 $retval = $thisSetting[$wiki];
48 break;
49 } elseif ( array_key_exists( "+$wiki", $thisSetting ) && is_array($thisSetting["+$wiki"]) ) {
50 $retval = $thisSetting["+$wiki"];
51 }
52
53 // Do tag settings
54 foreach ( $wikiTags as $tag ) {
55 if ( array_key_exists( $tag, $thisSetting ) ) {
56 if ( isset($retval) && is_array($retval) && is_array($thisSetting[$tag]) ) {
57 $retval = wfArrayDeepMerge( $retval, $thisSetting[$tag] );
58 } else {
59 $retval = $thisSetting[$tag];
60 }
61 break 2;
62 } elseif ( array_key_exists( "+$tag", $thisSetting ) && is_array($thisSetting["+$tag"]) ) {
63 if (!isset($retval))
64 $retval = array();
65 $retval = wfArrayDeepMerge( $retval, $thisSetting["+$tag"] );
66 }
67 }
68
69 // Do suffix settings
70 if ( array_key_exists( $suffix, $thisSetting ) ) {
71 if ( isset($retval) && is_array($retval) && is_array($thisSetting[$suffix]) ) {
72 $retval = wfArrayDeepMerge( $retval, $thisSetting[$suffix] );
73 } else {
74 $retval = $thisSetting[$suffix];
75 }
76 break;
77 } elseif ( array_key_exists( "+$suffix", $thisSetting ) && is_array($thisSetting["+$suffix"]) ) {
78 if (!isset($retval))
79 $retval = array();
80 $retval = wfArrayDeepMerge( $retval, $thisSetting["+$suffix"] );
81 }
82
83 // Fall back to default.
84 if ( array_key_exists( 'default', $thisSetting ) ) {
85 if ( isset($retval) && is_array($retval) && is_array($thisSetting['default']) ) {
86 $retval = wfArrayDeepMerge( $retval, $thisSetting['default'] );
87 } else {
88 $retval = $thisSetting['default'];
89 }
90 break;
91 }
92 $retval = null;
93 } while ( false );
94 } else {
95 $retval = NULL;
96 }
97
98 if ( !is_null( $retval ) && count( $params ) ) {
99 foreach ( $params as $key => $value ) {
100 $retval = $this->doReplace( '$' . $key, $value, $retval );
101 }
102 }
103
104 if ( $append && is_array($value) && is_array( $GLOBALS[$var] ) )
105 $value = wfArrayDeepMerge( $value, $GLOBALS[$var] );
106
107 return $retval;
108 }
109
110 /** Type-safe string replace; won't do replacements on non-strings */
111 function doReplace( $from, $to, $in ) {
112 if( is_string( $in ) ) {
113 return str_replace( $from, $to, $in );
114 } elseif( is_array( $in ) ) {
115 foreach( $in as $key => $val ) {
116 $in[$key] = $this->doReplace( $from, $to, $val );
117 }
118 return $in;
119 } else {
120 return $in;
121 }
122 }
123
124 /**
125 * Gets all settings for a wiki
126 * @param $wiki String Wiki ID of the wiki in question.
127 * @param $suffix String The suffix of the wiki in question.
128 * @param $params Array List of parameters. $.'key' is replaced by $value in all returned data.
129 * @param $wikiTags Array The tags assigned to the wiki.
130 * @return Array Array of settings requested.
131 */
132 function getAll( $wiki, $suffix, $params, $wikiTags = array() ) {
133 $localSettings = array();
134 foreach ( $this->settings as $varname => $stuff ) {
135 $value = $this->get( $varname, $wiki, $suffix, $params, $wikiTags );
136
137 if ( !is_null( $value ) ) {
138 $localSettings[$var] = $value;
139 }
140 }
141 return $localSettings;
142 }
143
144 /**
145 * Retrieves a configuration setting for a given wiki, forced to a boolean.
146 * @param $settingName String ID of the setting name to retrieve
147 * @param $wiki String Wiki ID of the wiki in question.
148 * @param $suffix String The suffix of the wiki in question.
149 * @param $params Array List of parameters. $.'key' is replaced by $value in all returned data.
150 * @param $wikiTags Array The tags assigned to the wiki.
151 * @return bool The value of the setting requested.
152 */
153 function getBool( $setting, $wiki, $suffix, $wikiTags = array() ) {
154 return (bool)($this->get( $setting, $wiki, $suffix, array(), $wikiTags ) );
155 }
156
157 /** Retrieves an array of local databases */
158 function &getLocalDatabases() {
159 return $this->wikis;
160 }
161
162 /** A no-op */
163 function initialise() {
164 }
165
166 /**
167 * Retrieves the value of a given setting, and places it in a variable passed by reference.
168 * @param $settingName String ID of the setting name to retrieve
169 * @param $wiki String Wiki ID of the wiki in question.
170 * @param $suffix String The suffix of the wiki in question.
171 * @param $var Reference The variable to insert the value into.
172 * @param $params Array List of parameters. $.'key' is replaced by $value in all returned data.
173 * @param $wikiTags Array The tags assigned to the wiki.
174 */
175 function extractVar( $setting, $wiki, $suffix, &$var, $params, $wikiTags = array() ) {
176 $value = $this->get( $setting, $wiki, $suffix, $params, $wikiTags );
177 if ( !is_null( $value ) ) {
178 $var = $value;
179 }
180 }
181
182 /**
183 * Retrieves the value of a given setting, and places it in its corresponding global variable.
184 * @param $settingName String ID of the setting name to retrieve
185 * @param $wiki String Wiki ID of the wiki in question.
186 * @param $suffix String The suffix of the wiki in question.
187 * @param $params Array List of parameters. $.'key' is replaced by $value in all returned data.
188 * @param $wikiTags Array The tags assigned to the wiki.
189 */
190 function extractGlobal( $setting, $wiki, $suffix, $params, $wikiTags = array() ) {
191 $value = $this->get( $setting, $wiki, $suffix, $params, $wikiTags );
192 if ( !is_null( $value ) ) {
193 $GLOBALS[$setting] = $value;
194 }
195 }
196
197 /**
198 * Retrieves the values of all settings, and places them in their corresponding global variables.
199 * @param $wiki String Wiki ID of the wiki in question.
200 * @param $suffix String The suffix of the wiki in question.
201 * @param $params Array List of parameters. $.'key' is replaced by $value in all returned data.
202 * @param $wikiTags Array The tags assigned to the wiki.
203 */
204 function extractAllGlobals( $wiki, $suffix, $params, $wikiTags = array() ) {
205 foreach ( $this->settings as $varName => $setting ) {
206 $this->extractGlobal( $varName, $wiki, $suffix, $params, $wikiTags );
207 }
208 }
209
210 /**
211 * Work out the site and language name from a database name
212 * @param $db
213 */
214 function siteFromDB( $db ) {
215 $site = NULL;
216 $lang = NULL;
217 foreach ( $this->suffixes as $suffix ) {
218 if ( $suffix === '' ) {
219 $site = '';
220 $lang = $db;
221 break;
222 } elseif ( substr( $db, -strlen( $suffix ) ) == $suffix ) {
223 $site = $suffix == 'wiki' ? 'wikipedia' : $suffix;
224 $lang = substr( $db, 0, strlen( $db ) - strlen( $suffix ) );
225 break;
226 }
227 }
228 $lang = str_replace( '_', '-', $lang );
229 return array( $site, $lang );
230 }
231
232 /** Returns true if the given vhost is handled locally. */
233 function isLocalVHost( $vhost ) {
234 return in_array( $vhost, $this->localVHosts );
235 }
236 }
237 }