· 8 years ago · Aug 24, 2018, 06:02 AM
1<?php
2
3/**
4 * Simple Machines Forum (SMF)
5 *
6 * @package SMF
7 * @author Simple Machines
8 * @copyright 2017 Simple Machines
9 * @license http://www.simplemachines.org/about/smf/license.php BSD
10 *
11 * @version 2.1
12 * @updated 2017-02-08
13 */
14
15// We need the Settings.php info for database stuff.
16if (file_exists(dirname(__FILE__) . '/Settings.php'))
17 require_once(dirname(__FILE__) . '/Settings.php');
18
19// Initialize everything and load the language files.
20initialize_inputs();
21
22$txt['smf_repair_settings'] = 'SMF %1$s Settings Repair Tool';
23$txt['smf11_repair_settings'] = 'SMF 1.x Settings Repair Tool';
24$txt['no_value'] = '<em style="font-weight: normal; color: red;">Value not found!</em>';
25$txt['default_value'] = 'Recommended value';
26$txt['other_possible_value'] = 'Other possible value';
27$txt['no_default_value'] = 'No recommended value';
28$txt['save_settings'] = 'Save Settings';
29$txt['remove_file'] = 'Remove this file. Careful, it may not work in all servers!';
30$txt['restore_all_settings'] = 'Restore all settings';
31$txt['not_writable'] = 'Settings.php cannot be written to by your webserver. Please modify the permissions on this file to allow write access.';
32$txt['recommend_blank'] = '<em>(blank)</em>';
33$txt['database_settings_hidden'] = 'Some settings are not being shown because the database connection information is incorrect.<br />Check your database login details, table prefix and that the database actually contains your SMF tables.';
34$txt['no_sources'] = 'We were unable to detect your Sources folder. This is crucial for this tool to work. Please be sure it exists.';
35$txt['settings_saved'] = 'Your settings were saved. Please confirm all the paths and URLs below, and that your forum works.<br /><b>Make sure you remove this file!</b>';
36
37$txt['remove_hooks'] = 'Remove all hooks';
38$txt['disable_hooks'] = 'Disable all hooks';
39$txt['hooks_removed'] = 'All your existing hooks were removed from the database. Do note that existing MODs that rely on hooks will not work anymore.<br /><b>Make sure you remove this file!</b>';
40$txt['hooks_disabled'] = 'All your existing hooks were disabled. Do note that existing MODs that rely on hooks will not work anymore. You can enable these again from Forum Maintenance<br /><b>Make sure you remove this file!</b>';
41
42$txt['critical_settings'] = 'Critical Settings';
43$txt['critical_settings_info'] = 'These are the settings most likely to be screwing up your board, but try the things below (especially the path and URL ones) if these don\'t help. You can click on the recommended value to use it.';
44$txt['maintenance'] = 'Maintenance Mode';
45$txt['maintenance0'] = 'Off (recommended)';
46$txt['maintenance1'] = 'Enabled';
47$txt['maintenance2'] = 'Unusable <em>(not recommended!)</em>';
48$txt['language'] = 'Language File';
49$txt['cookiename'] = 'Cookie Name';
50$txt['queryless_urls'] = 'Queryless URLs';
51$txt['queryless_urls0'] = 'Off (recommended)';
52$txt['queryless_urls1'] = 'On';
53$txt['enableCompressedOutput'] = 'Output Compression';
54$txt['enableCompressedOutput0'] = 'Off (recommended if you have problems)';
55$txt['enableCompressedOutput1'] = 'On (saves a lot of bandwidth)';
56$txt['databaseSession_enable'] = 'Database driven sessions';
57$txt['databaseSession_enable0'] = 'Off (not recommended)';
58$txt['databaseSession_enable1'] = 'On (recommended)';
59$txt['theme_default'] = 'Set SMF Default theme as overall forum default<br />for all users';
60$txt['theme_default0'] = 'No (keep the current users\' theme settings)';
61$txt['theme_default1'] = 'Yes (recommended if you have problems)';
62
63$txt['database_settings'] = 'Database Info';
64$txt['database_settings_info'] = 'This is the server, username, password, and database for your server.';
65$txt['db_type'] = 'Database Engine';
66$txt['db_server'] = 'Server';
67$txt['db_name'] = 'Database name';
68$txt['db_user'] = 'Username';
69$txt['db_passwd'] = 'Password';
70$txt['ssi_db_user'] = 'SSI Username';
71$txt['ssi_db_passwd'] = 'SSI Password';
72$txt['ssi_db_user_desc'] = '(Optional)';
73$txt['ssi_db_passwd_desc'] = '(Optional)';
74$txt['db_prefix'] = 'Table prefix';
75$txt['db_persist'] = 'Connection type';
76$txt['db_persist0'] = 'Standard (recommended)';
77$txt['db_persist1'] = 'Persistent (might cause problems)';
78$txt['db_mysql'] = 'MySQL';
79$txt['db_postgresql'] = 'PostgreSQL';
80$txt['db_sqlite'] = 'SQLite';
81
82$txt['cache_settings'] = 'Cache Settings';
83$txt['cache_settings_info'] = 'These are the cache settings to your SMF installation, and can cause big problems when they are wrong.';
84$txt['cache_accelerator'] = 'Cache System';
85$txt['cache_accelerator_help'] = 'Choose: apc, eaccelerator, memcache, mmcache, output_cache, smf, or xcache';
86$txt['cache_enable'] = 'Enable Caching';
87$txt['cache_enable0'] = 'Off';
88$txt['cache_enable1'] = 'On (recommended)';
89$txt['cachedir'] = 'Cache Directory';
90$txt['cache_memcached'] = 'Memcache Servers';
91
92$txt['path_url_settings'] = 'Paths & URLs';
93$txt['path_url_settings_info'] = 'These are the paths and URLs to your SMF installation, and can cause big problems when they are wrong. Sorry, there are a lot of them.';
94$txt['boardurl'] = 'Forum URL';
95$txt['boarddir'] = 'Forum Directory';
96$txt['sourcedir'] = 'Sources Directory';
97$txt['tasksdir'] = 'Tasks Directory';
98$txt['packagesdir'] = 'Packages Directory';
99$txt['attachmentUploadDir'] = 'Attachment Directory';
100$txt['avatar_url'] = 'Avatar URL';
101$txt['avatar_directory'] = 'Avatar Directory';
102$txt['custom_avatar_url'] = 'Custom Avatar URL';
103$txt['custom_avatar_dir'] = 'Custom Avatar Directory';
104$txt['smileys_url'] = 'Smileys URL';
105$txt['smileys_dir'] = 'Smileys Directory';
106$txt['theme_url'] = 'Default Theme URL';
107$txt['images_url'] = 'Default Theme Images URL';
108$txt['theme_dir'] = 'Default Theme Directory';
109
110$txt['theme_path_url_settings'] = 'Paths & URLs For Themes';
111$txt['theme_path_url_settings_info'] = 'These are the paths and URLs to your SMF themes.';
112
113// Fix Database title to use $db_type if available
114if (!empty($db_type) && isset($txt['db_' . $db_type]))
115 $txt['database_settings'] = $txt['db_' . $db_type] . ' ' . $txt['database_settings'];
116
117if (isset($_POST['submit']))
118 set_settings();
119
120if (isset($_POST['remove_hooks']))
121 remove_hooks();
122
123// try to find the smflogo: could be a .gif or a .png
124$smflogo = "Themes/default/images/smflogo.png";
125if (!file_exists(dirname(__FILE__) . "/" . $smflogo))
126 $smflogo = "Themes/default/images/smflogo.gif";
127
128// Note that we're using the default URLs because we aren't even going to try to use Settings.php's settings.
129echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
130<html xmlns="http://www.w3.org/1999/xhtml">
131 <head>
132 <meta name="robots" content="noindex" />
133 <title>', isset($context['smfVersion']) ? sprintf($txt['smf_repair_settings'], $context['smfVersion']) :
134$txt['smf11_repair_settings'], '</title>
135 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
136 <script type="text/javascript" src="Themes/default/scripts/script.js"></script>
137 <style type="text/css">
138 body
139 {
140 background-color: #e5e5e8;
141 margin: 0px;
142 padding: 0px;
143 }
144 body, td
145 {
146 color: #000000;
147 font-size: small;
148 font-family: verdana, sans-serif;
149 }
150 div#header
151 {
152 background-color: #88a6c0;
153 padding: 22px 4% 12px 4%;
154 color: white;
155 font-family: Georgia, serif;
156 font-size: xx-large;
157 border-bottom: 1px solid black;
158 height: 40px;
159 }
160 div#content
161 {
162 padding: 20px 30px;
163 }
164 div.error_message
165 {
166 border: 2px dashed red;
167 background-color: #e1e1e1;
168 margin: 1ex 4ex;
169 padding: 1.5ex;
170 }
171 div.success_message
172 {
173 border: 2px dashed green;
174 background-color: #e1e1e1;
175 margin: 1ex 4ex;
176 padding: 1.5ex;
177 }
178 div.panel
179 {
180 border: 1px solid gray;
181 background-color: #f6f6f6;
182 margin: 1ex 0;
183 padding: 1.2ex;
184 }
185 div.panel h2
186 {
187 margin: 0;
188 margin-bottom: 0.5ex;
189 padding-bottom: 3px;
190 border-bottom: 1px dashed black;
191 font-size: 14pt;
192 font-weight: normal;
193 }
194 div.panel h3
195 {
196 margin: 0;
197 margin-bottom: 2ex;
198 font-size: 10pt;
199 font-weight: normal;
200 }
201 form
202 {
203 margin: 0;
204 }
205 td.textbox
206 {
207 padding-top: 2px;
208 font-weight: bold;
209 white-space: nowrap;
210 padding-', empty($txt['lang_rtl']) ? 'right' : 'left', ': 2ex;
211 }
212 .smalltext
213 {
214 font-size: 0.8em;
215 font-weight: normal;
216 }
217 .centertext
218 {
219 margin: 0 auto;
220 text-align: center;
221 }
222 .righttext
223 {
224 margin-left: auto;
225 margin-right: 0;
226 text-align: right;
227 }
228 .lefttext
229 {
230 margin-left: 0;
231 margin-right: auto;
232 text-align: left;
233 }
234 .changed td
235 {
236 color: red;
237 }
238 </style>
239 </head>
240 <body>
241 <div id="header">
242 <a href="http://www.simplemachines.org/" target="_blank"><img src="' . $smflogo . '" style="width: 250px; float: right;" alt="Simple Machines" border="0" /></a>
243 <div>', isset($context['smfVersion']) ? sprintf($txt['smf_repair_settings'], $context['smfVersion']) :
244$txt['smf11_repair_settings'], '</div>
245 </div>
246 <div id="content">';
247
248 show_settings();
249
250echo '
251 </div>
252 </body>
253</html>';
254
255function initialize_inputs()
256{
257 global $smcFunc, $db_connection, $sourcedir, $db_server, $db_name, $db_user, $db_passwd, $db_prefix, $db_type, $context, $sources_exist, $sources_found_path, $db_type_options;
258
259 // Turn off magic quotes runtime and enable error reporting.
260 if (function_exists('set_magic_quotes_runtime') && strnatcmp(phpversion(),'5.3.0') < 0)
261 @set_magic_quotes_runtime(0);
262 error_reporting(E_ALL);
263 if (ini_get('session.save_handler') == 'user')
264 ini_set('session.save_handler', 'files');
265 @session_start();
266
267 if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc() != 0)
268 {
269 foreach ($_POST as $k => $v)
270 if (is_array($v))
271 foreach ($v as $k2 => $v2)
272 $_POST[$k][$k2] = stripslashes($v2);
273 else
274 $_POST[$k] = stripslashes($v);
275 }
276
277 foreach ($_POST as $k => $v)
278 {
279 if (is_array($v))
280 foreach ($v as $k2 => $v2)
281 $_POST[$k][$k2] = addcslashes($v2, '\'\\');
282 else
283 $_POST[$k] = addcslashes($v, '\'\\');
284 }
285
286 // Https?
287 $context['schema'] = isset($_SERVER['HTTPS']) || (isset($_SERVER['REQUEST_SCHEME']) && strtolower($_SERVER['REQUEST_SCHEME']) == 'https') ? 'https' : 'http';
288
289 // This is really quite simple; if ?delete is on the URL, delete the installer...
290 if (isset($_GET['delete']) || isset($_POST['remove_file']))
291 {
292 @unlink(__FILE__);
293
294 // Now just redirect to a blank.gif...
295 header('Location: ' . $context['schema'] . '://' . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT']) . dirname($_SERVER['PHP_SELF']) . '/index.php');
296 exit;
297 }
298
299 $db_connection = false;
300 $sources_exist = false;
301 $context['smfVersion'] = 'N/A';
302 $sources_found_path = '';
303 if (isset($sourcedir) && (file_exists(dirname(__FILE__) . '/Sources/Load.php')))
304 $sources_exist = true;
305 else
306 {
307 //Find Sources folder!
308 $sourcedir = findSources();
309 $sources_found_path = $sourcedir;
310 $sources_exist = !empty($sourcedir);
311 }
312
313 if ($sources_exist)
314 {
315 if (!defined('SMF'))
316 define('SMF', 1);
317
318 if (empty($smcFunc))
319 $smcFunc = array();
320
321 // Default the database type to MySQL. In 2.1 Beta 3, mysqli was removed, this will put it back to mysql.
322 $db_type_options = array('default' => 'mysql', 'options' => array('mysql' => 'MySQL'));
323 if (empty($db_type) || !file_exists($sourcedir . '/Subs-Db-' . $db_type . '.php'))
324 $db_type = 'mysql';
325
326 //require_once($sourcedir . '/Load.php');
327 //require_once($sourcedir . '/Subs-Auth.php');
328
329 // compat mode. Active!
330 $context['is_legacy'] = true;
331
332 // Try to detect if we even have the database functions..
333 if (
334 ($db_type == 'mysql' && !function_exists('mysql_connect') && !function_exists('mysqli_connect')) ||
335 ($db_type == 'mysqli' && !function_exists('mysqli_connect')) ||
336 ($db_type == 'postgresql' && !function_exists('pg_pconnect'))
337 )
338 $db_connection = null;
339 // This is SMF 1.x as far as we can tell, as we don't know/have any database files.
340 elseif (!file_exists($sourcedir . '/Subs-Db-' . $db_type . '.php') && $db_type == 'mysql')
341 {
342 $context['smfVersion'] = '1.1';
343 $db_connection = smc_compat_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix, array('non_fatal' => true));
344 }
345 else
346 {
347 // Far as I know, this is 2.0.
348 $context['is_legacy'] = false;
349 $context['smfVersion'] = '2.0';
350
351 // Try to see if this is 2.1. Maybe include more checks.
352 if (file_exists($sourcedir . '/Class-TOTP.php'))
353 $context['smfVersion'] = '2.1';
354
355 // We should try to use the proper extension function if at all possible.
356 require_once($sourcedir . '/Subs-Db-' . $db_type . '.php');
357 if (function_exists('db_extend'))
358 db_extend('extra');
359 else
360 require_once($sourcedir . '/DbExtra-' . $db_type . '.php');
361
362 $db_connection = smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix, array('non_fatal' => true));
363 db_extra_init();
364 //Fixes error with $db_connection not false if database name is incorrect. This is because the connection is established
365 //without this parameter, thus performing incorrectly.
366 if ($db_connection == true)
367 {
368 if (!$smcFunc['db_select_db'] ($db_name, $db_connection))
369 $db_connection = null;
370 else
371 {
372 $tables=$smcFunc['db_list_tables']($db_name);
373 if (!(is_array($tables) && in_array($db_prefix . 'settings' , $tables)))
374 $db_connection = null;
375 }
376 }
377 else
378 $db_connection = null;
379 }
380
381 // See if we have PostgreSQL files, we should.
382 if (file_exists($sourcedir . '/Subs-Db-postgresql.php'))
383 {
384 $db_type_options['options']['postgresql'] = 'PostgreSQL';
385
386 // If we are currently postgresql, it should be the default.
387 if ($db_type == 'postgresql')
388 $db_type_options['default'] = $db_type;
389 }
390
391 // 2.1 Beta 1 and 2 supported mysqli, this was removed and merged into mysql in Beta 3.
392 if (file_exists($sourcedir . '/Subs-Db-mysqli.php'))
393 {
394 $db_type_options['options']['mysqli'] = 'MySQLi';
395
396 // Suggest that we move back to mysql.
397 if ($db_type == 'mysqli')
398 $db_type_options['default'] = 'mysql';
399 }
400
401 // 2.0 supports sqlite.
402 if (file_exists($sourcedir . '/Subs-Db-sqlite.php') && (empty($context['smfVersion']) || $context['smfVersion'] == '2.0'))
403 {
404 $db_type_options['options']['sqlite'] = 'SQLite';
405
406 if ($db_type == 'sqlite')
407 $db_type_options['default'] = $db_type;
408 }
409 }
410}
411
412function show_settings()
413{
414 global $txt, $smcFunc, $db_connection, $db_type, $db_name, $db_prefix, $context, $sources_exist, $sources_found_path, $db_type_options;
415
416 // Check to make sure Settings.php exists!
417 if (file_exists(dirname(__FILE__) . '/Settings.php'))
418 $settingsArray = file(dirname(__FILE__) . '/Settings.php');
419 else
420 $settingsArray = array();
421
422 if (count($settingsArray) == 1)
423 $settingsArray = preg_split('~[\r\n]~', $settingsArray[0]);
424
425 $settings = array();
426 for ($i = 0, $n = count($settingsArray); $i < $n; $i++)
427 {
428 $settingsArray[$i] = rtrim(stripslashes($settingsArray[$i]));
429
430 if (isset($settingsArray[$i][0]) && $settingsArray[$i][0] != '.')
431 {
432 preg_match('~^[$]([a-zA-Z_]+)\s*=\s*(?:(["\'])(?:(.*?)["\'])(?:\\2)?|(.*?)(?:\\2)?);~', $settingsArray[$i], $match);
433 if (isset($match[3]))
434 {
435 if ($match[3] == 'dirname(__FILE__)')
436 $settings[$match[1]] = dirname(__FILE__);
437 elseif ($match[3] == 'dirname(__FILE__) . \'/Sources\'')
438 $settings[$match[1]] = dirname(__FILE__) . '/Sources';
439 elseif ($match[3] == '$boarddir . \'/Sources\'')
440 $settings[$match[1]] = $settings['boarddir'] . '/Sources';
441 elseif ($match[3] == 'dirname(__FILE__) . \'/cache\'')
442 $settings[$match[1]] = dirname(__FILE__) . '/cache';
443 // Values of 1, true and false seem to create a $mach[4]. This gets around this until a better regex can be found.
444 elseif (isset($match[4]) && in_array($match[4], array('0', '1', '2', 'false', 'true')))
445 $settings[$match[1]] = $match[4];
446 else
447 $settings[$match[1]] = $match[3];
448 }
449 }
450 }
451
452 if ($db_connection == true)
453 {
454 $request = $smcFunc['db_query'](true, '
455 SELECT DISTINCT variable, value
456 FROM {db_prefix}settings',
457 array(
458 'db_error_skip' => true
459 ),
460 $db_connection
461 );
462 while ($row = $smcFunc['db_fetch_assoc']($request))
463 {
464 // Skip this setting on 2.1.
465 if ($context['smfVersion'] == '2.1' && $row['variable'] == 'cache_enable')
466 continue;
467
468 $settings[$row['variable']] = $row['value'];
469 }
470 $smcFunc['db_free_result']($request);
471
472 // Load all the themes.
473 $request = $smcFunc['db_query'](true, '
474 SELECT variable, value, id_theme
475 FROM {db_prefix}themes
476 WHERE id_member = 0
477 AND variable IN ({array_string:variables})',
478 array(
479 'variables' => array('theme_dir', 'theme_url', 'images_url', 'name'),
480 'db_error_skip' => true
481 )
482 );
483
484 $theme_settings = array();
485 while ($row = $smcFunc['db_fetch_row']($request))
486 $theme_settings[$row[2]][$row[0]] = $row[1];
487 $smcFunc['db_free_result']($request);
488
489 $show_db_settings = $request;
490 }
491 else
492 $show_db_settings = false;
493
494 $known_settings = array(
495 'critical_settings' => array(
496 'maintenance' => array('flat', 'int', 2),
497 'language' => array('flat', 'string', 'english'),
498 'cookiename' => array('flat', 'string', 'SMFCookie' . (!empty($db_name) ? abs(crc32($db_name . preg_replace('~[^A-Za-z0-9_$]~', '', $db_prefix)) % 1000) : '20')),
499 'queryless_urls' => array('db', 'int', 1),
500 'enableCompressedOutput' => array('db', 'int', 1),
501 'databaseSession_enable' => array('db', 'int', 1),
502 'theme_default' => array('db', 'int', 1),
503 ),
504 'database_settings' => array(
505 'db_type' => array('flat', 'select', $db_type_options['default'], $db_type_options['options']),
506 'db_server' => array('flat', 'string', 'localhost'),
507 'db_name' => array('flat', 'string'),
508 'db_user' => array($db_type == 'sqlite' ? 'hidden' : 'flat', 'string'),
509 'db_passwd' => array($db_type == 'sqlite' ? 'hidden' : 'flat', 'string'),
510 'ssi_db_user' => array($db_type == 'sqlite' ? 'hidden' : 'flat', 'string'),
511 'ssi_db_passwd' => array($db_type == 'sqlite' ? 'hidden' : 'flat', 'string'),
512 'db_prefix' => array('flat', 'string'),
513 'db_persist' => array('flat', 'int', 1),
514 ),
515 'path_url_settings' => array(
516 'boardurl' => array('flat', 'string'),
517 'boarddir' => array('flat', 'string'),
518 'sourcedir' => array('flat', 'string'),
519 'tasksdir' => array('flat', 'string'),
520 'packagesdir' => array('flat', 'string'),
521 'attachmentUploadDir' => array('db', 'array_string'),
522 'avatar_url' => array('db', 'string'),
523 'avatar_directory' => array('db', 'string'),
524 'custom_avatar_url' => array('db', 'string'),
525 'custom_avatar_dir' => array('db', 'string'),
526 'smileys_url' => array('db', 'string'),
527 'smileys_dir' => array('db', 'string'),
528 ),
529 'cache_settings' => array(
530 'cache_accelerator' => array('flat', 'string'),
531 'cache_enable' => array('flat', 'int', 1),
532 'cachedir' => array('flat', 'string'),
533 'cache_memcached' => array('flat', 'string')
534 ),
535 'theme_path_url_settings' => array(),
536 );
537
538 // 1.x didn't have ssi_x, nor cachedir
539 if ($context['is_legacy'])
540 unset($known_settings['database_settings']['ssi_db_user'], $known_settings['database_settings']['ssi_db_passwd'], $known_settings['cache_settings']['cachedir'], $known_settings['path_url_settings']['custom_avatar_url'], $known_settings['path_url_settings']['custom_avatar_dir']);
541
542 // These settings didn't exist in 2.0 or 1.1
543 if ($context['smfVersion'] == '2.0' || $context['smfVersion'] == '1.1')
544 unset($known_settings['cache_settings']['cache_accelerator'], $known_settings['cache_settings']['cache_enable'], $known_settings['cache_settings']['cache_memcached'], $known_settings['path_url_settings']['tasksdir'], $known_settings['path_url_settings']['packagesdir']);
545
546 // Let's assume we don't want to change the current theme
547 $settings['theme_default'] = 0;
548
549 $host = empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] . (empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == '80' || ($_SERVER['SERVER_PORT'] == '443' && $context['schema'] == 'https') ? '' : ':' . $_SERVER['SERVER_PORT']) : $_SERVER['HTTP_HOST'];
550 $url = $context['schema'] . '://' . $host . substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'));
551 $known_settings['path_url_settings']['boardurl'][2] = $url;
552 $known_settings['path_url_settings']['boarddir'][2] = dirname(__FILE__);
553
554 if (file_exists(dirname(__FILE__) . '/Sources'))
555 $known_settings['path_url_settings']['sourcedir'][2] = realpath(dirname(__FILE__) . '/Sources');
556 elseif (!empty($sources_found_path))
557 $known_settings['path_url_settings']['sourcedir'][2] = realpath($sources_found_path);
558
559 if ($context['smfVersion'] == '2.1' && file_exists(dirname(__FILE__) . '/Sources/tasks'))
560 $known_settings['path_url_settings']['tasksdir'][2] = realpath(dirname(__FILE__) . '/Sources/tasks');
561
562 if (file_exists(dirname(__FILE__) . '/cache') && isset($known_settings['cache_settings']['cachedir']))
563 $known_settings['cache_settings']['cachedir'][2] = realpath(dirname(__FILE__) . '/cache');
564
565 if (file_exists(dirname(__FILE__) . '/avatars'))
566 {
567 $known_settings['path_url_settings']['avatar_url'][2] = $url . '/avatars';
568 $known_settings['path_url_settings']['avatar_directory'][2] = realpath(dirname(__FILE__) . '/avatars');
569 }
570
571 if (!$context['is_legacy'] && file_exists(dirname(__FILE__) . '/custom_avatar'))
572 {
573 $known_settings['path_url_settings']['custom_avatar_url'][2] = $url . '/custom_avatar';
574 $known_settings['path_url_settings']['custom_avatar_dir'][2] = realpath(dirname(__FILE__) . '/custom_avatar');
575 }
576
577 if (file_exists(dirname(__FILE__) . '/Smileys'))
578 {
579 $known_settings['path_url_settings']['smileys_url'][2] = $url . '/Smileys';
580 $known_settings['path_url_settings']['smileys_dir'][2] = realpath(dirname(__FILE__) . '/Smileys');
581 }
582
583 if ($context['smfVersion'] == '2.1' && file_exists(dirname(__FILE__) . '/Packages'))
584 {
585 $known_settings['path_url_settings']['packagesdir'][2] = realpath(dirname(__FILE__) . '/Packages');
586 }
587
588/* if (file_exists(dirname(__FILE__) . '/Themes/default'))
589 {
590 $known_settings['path_url_settings']['theme_url'][2] = $url . '/Themes/default';
591 $known_settings['path_url_settings']['images_url'][2] = $url . '/Themes/default/images';
592 $known_settings['path_url_settings']['theme_dir'][2] = realpath(dirname(__FILE__) . '/Themes/default');
593 }
594*/
595
596 if (!empty($theme_settings))
597 {
598 // Create the values for the themes.
599 foreach ($theme_settings as $id => $theme)
600 {
601 $this_theme = ($pos = strpos($theme['theme_url'], '/Themes/')) !== false ? substr($theme['theme_url'], $pos+8) : '';
602 if (!empty($this_theme))
603 $exist = file_exists(dirname(__FILE__) . '/Themes/' . $this_theme);
604 else
605 $exist = false;
606
607 $known_settings['theme_path_url_settings'] += array(
608 'theme_'. $id.'_theme_url'=>array('theme', 'string', $exist && !empty($this_theme) ? $url . '/Themes/' . $this_theme : null),
609 'theme_'. $id.'_images_url'=>array('theme', 'string', $exist && !empty($this_theme) ? $url . '/Themes/' . $this_theme . '/images' : null),
610 'theme_' . $id . '_theme_dir' => array('theme', 'string', $exist && !empty($this_theme) ? realpath(dirname(__FILE__) . '/Themes/' . $this_theme) : null),
611 );
612 $settings += array(
613 'theme_' . $id . '_theme_url' => $theme['theme_url'],
614 'theme_' . $id . '_images_url' => $theme['images_url'],
615 'theme_' . $id . '_theme_dir' => $theme['theme_dir'],
616 );
617
618 $txt['theme_' . $id . '_theme_url'] = $theme['name'] . ' URL';
619 $txt['theme_' . $id . '_images_url'] = $theme['name'] . ' Images URL';
620 $txt['theme_' . $id . '_theme_dir'] = $theme['name'] . ' Directory';
621 }
622 }
623
624 if (!$sources_exist)
625 {
626 echo '
627 <div class="error_message" style="margin-bottom: 2ex;">
628 ', $txt['no_sources'], '
629 </div>';
630 }
631
632 if ($db_connection == true)
633 {
634 $request = $smcFunc['db_list_tables']('', '
635 {db_prefix}log_topics',
636 array(
637 'db_error_skip' => true,
638 )
639 );
640 if ($request == true)
641 {
642 if ($smcFunc['db_num_rows']($request) == 1)
643 list ($known_settings['database_settings']['db_prefix'][2]) = preg_replace('~log_topics$~', '', $smcFunc['db_fetch_row']($request));
644 $smcFunc['db_free_result']($request);
645 }
646 if (!empty($context['settings_saved']))
647 {
648 echo '
649 <div class="success_message" style="margin-bottom: 2ex;">
650 ', $txt['settings_saved'], '
651 </div>';
652 }
653 if (!empty($context['hooks_removed']))
654 {
655 echo '
656 <div class="success_message" style="margin-bottom: 2ex;">
657 ', $txt['hooks_' . ($context['smfVersion'] == '2.1' ? 'disabled' : 'removed')], '
658 </div>';
659 }
660
661 }
662 elseif (empty($show_db_settings))
663 {
664 echo '
665 <div class="error_message" style="margin-bottom: 2ex;">
666 ', $txt['database_settings_hidden'], '
667 </div>';
668 }
669
670 echo '
671 <script type="text/javascript"><!-- // --><![CDATA[
672 // Get the inner HTML of an element.
673 var resetSettings = new Array();
674 var settingsCounter = 0;
675 function getInnerHTML(element)
676 {
677 return element.innerHTML;
678 }
679
680 function restoreAll()
681 {
682 for (var i=0;i<resetSettings.length;i++)
683 {
684 var elem = document.getElementById(resetSettings[i]);
685 var val = elem.value;
686
687 if ($(elem).attr("class") == "input_select")
688 {
689 $("#" + resetSettings[i] + "_default").trigger("click");
690 }
691 else
692 {
693 elem.value = getInnerHTML(document.getElementById(resetSettings[i] + \'_default\'));
694 if (val != elem.value)
695 elem.parentNode.parentNode.className += " changed";
696 }
697 }
698 }
699 // ]]></script>
700
701 <form action="', $_SERVER['PHP_SELF'], '" method="post">
702 <div class="panel">';
703
704 foreach ($known_settings as $settings_section => $section)
705 {
706 echo '
707 <h2>', $txt[$settings_section], '</h2>
708 <h3>', $txt[$settings_section . '_info'], '</h3>
709
710 <table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin-bottom: 3ex;">
711 <tr>';
712
713 foreach ($section as $setting => $info)
714 {
715 if ($info[0] == 'hidden')
716 continue;
717
718 if ($info[0] != 'flat' && empty($show_db_settings))
719 continue;
720
721 echo '
722 <td width="20%" valign="top" class="textbox" style="padding-bottom: 1ex;">
723 <label', $info[1] != 'int' ? ' for="' . $setting . '"' : '', '>', $txt[$setting], ': '.
724 ( isset($txt[$setting . '_desc']) ? '<span class="smalltext">' . $txt[$setting . '_desc'] . '</span>' : '' ).'
725 </label>', !isset($settings[$setting]) && $info[1] != 'check' ? '<br />
726 ' . $txt['no_value'] : '', '
727 </td>
728 <td style="padding-bottom: 1ex;">';
729
730 if ($info[1] == 'int' || $info[1] == 'check')
731 {
732 for ($i = 0; $i <= $info[2]; $i++)
733 echo '
734 <label for="', $setting, $i, '"><input type="radio" name="', $info[0], 'settings[', $setting, ']" id="', $setting, $i, '" value="', $i, '"', isset($settings[$setting]) && $settings[$setting] == $i ? ' checked="checked"' : '', ' class="input_radio" /> ', $txt[$setting . $i], '</label><br />';
735 }
736 elseif ($info[1] == 'string')
737 {
738 echo '
739 <input type="text" name="', $info[0], 'settings[', $setting, ']" id="', $setting, '" value="', isset($settings[$setting]) ? htmlspecialchars($settings[$setting]) : '', '" size="', $settings_section == 'path_url_settings' || $settings_section == 'theme_path_url_settings' ? '60" style="width: 80%;' : '30', '" class="input_text" />';
740
741 if (isset($txt[$setting . '_help']))
742 echo '<div style="font-size: smaller;">', $txt[$setting . '_help'], '</div>';
743
744 if (isset($info[2]))
745 echo '
746 <div style="font-size: smaller;">', $txt['default_value'], ': "<strong><a href="javascript:void(0);" id="', $setting, '_default" onclick="document.getElementById(\'', $setting, '\').value = ', $info[2] == '' ? '\'\';">' . $txt['recommend_blank'] : 'getInnerHTML(this);">' . $info[2], '</a></strong>".</div>',
747 $info[2] == '' ? '' : ($setting != 'language' && $setting != 'cookiename' ? '
748 <script type="text/javascript"><!-- // --><![CDATA[
749 resetSettings[settingsCounter++] = "' . $setting . '"; // ]]></script>' : '');
750 }
751 elseif ($info[1] == 'array_string')
752 {
753 if (!is_array($settings[$setting]) && $context['smfVersion'] == '2.1')
754 $array_settings = json_decode($settings[$setting], true);
755 // Maybe its a seraialized array, we only support those, so test for it in a simple way.
756 if (!(isset($array_settings) && is_array($array_settings)) && !is_array($settings[$setting]))
757 $array_settings = @unserialize($settings[$setting]);
758 if (!isset($array_settings) || !is_array($array_settings))
759 $array_settings = array($settings[$setting]);
760
761 $item = 1;
762 foreach ($array_settings as $array_setting)
763 {
764 $suggested = false;
765 echo '
766 <input type="text" name="', $info[0], 'settings[', $setting, '_', $item, ']" id="', $setting, $item, '" value="', $array_setting, '" size="', $settings_section == 'path_url_settings' || $settings_section == 'theme_path_url_settings' ? '60" style="width: 80%;' : '30', '" class="input_text" />';
767
768 $suggested = guess_attachments_directories($item, $array_setting);
769
770 if (!empty($suggested))
771 {
772 echo '
773 <div style="font-size: smaller;">', $txt['default_value'], ': "<strong><a href="javascript:void(0);" id="', $setting, $item, '_default" onclick="document.getElementById(\'', $setting, $item, '\').value = ', $suggested[0] == '' ? '\'\';">' . $txt['recommend_blank'] : 'getInnerHTML(this);">' . $suggested[0], '</a></strong>".</div>',
774 $suggested[0] == '' ? '' : '
775 <script type="text/javascript"><!-- // --><![CDATA[
776 resetSettings[settingsCounter++] = "' . $setting . $item . '"; // ]]></script>';
777
778 for ($i = 1; $i < count($suggested); $i++)
779 echo '
780 <div style="font-size: smaller;">', $txt['other_possible_value'], ': "<strong><a href="javascript:void(0);" id="', $setting, $item, '_default" onclick="document.getElementById(\'', $setting, $item, '\').value = ', $suggested[$i] == '' ? '\'\';">' . $txt['recommend_blank'] : 'getInnerHTML(this);">' . $suggested[$i], '</a></strong>".</div>';
781 }
782 else
783 echo '
784 <div style="font-size: smaller;">', $txt['no_default_value'], '</div>';
785
786 $item++;
787 }
788 }
789 elseif ($info[1] == 'select' && !empty($info[3]))
790 {
791 echo '
792 <select name="', $info[0], 'settings[', $setting, ']" id="', $setting, '" class="input_select">';
793
794 foreach ($info[3] as $infoId => $infoTitle)
795 echo '
796 <option value="', $infoId, '"', isset($settings[$setting]) && $settings[$setting] == $infoId ? ' selected="selected"' : '', '>', $infoTitle, '</option>';
797
798 echo '
799 </select>';
800
801 if (isset($txt[$setting . '_help']))
802 echo '<div style="font-size: smaller;">', $txt[$setting . '_help'], '</div>';
803
804 if (!is_null($info[2]))
805 echo '
806 <div style="font-size: smaller;">', $txt['default_value'], ': "<strong><a href="javascript:void(0);" id="', $setting, '_default" onclick="$(\'#', $setting, '\').val(\'', $info[2], '\').change();">' . $info[3][$info[2]], '</a></strong>".</div>',
807 $info[2] == '' ? '' : ($setting != 'language' && $setting != 'cookiename' ? '
808 <script type="text/javascript"><!-- // --><![CDATA[
809 resetSettings[settingsCounter++] = "' . $setting . '"; // ]]></script>' : '');
810 }
811
812 echo '
813 </td>
814 </tr><tr>';
815 }
816
817 echo '
818 <td colspan="2"></td>
819 </tr>
820 </table>';
821 }
822
823 echo '
824
825 <div class="righttext" style="margin: 1ex;">';
826
827 $failure = false;
828 if (strpos(__FILE__, ':\\') !== 1)
829 {
830 // On linux, it's easy - just use is_writable!
831 $failure |= !is_writable('Settings.php') && !chmod('Settings.php', 0777);
832 }
833 // Windows is trickier. Let's try opening for r+...
834 else
835 {
836 // Funny enough, chmod actually does do something on windows - it removes the read only attribute.
837 chmod(dirname(__FILE__) . '/' . 'Settings.php', 0777);
838 $fp = @fopen(dirname(__FILE__) . '/' . 'Settings.php', 'r+');
839
840 // Hmm, okay, try just for write in that case...
841 if (!$fp)
842 $fp = @fopen(dirname(__FILE__) . '/' . 'Settings.php', 'w');
843
844 $failure |= !$fp;
845 fclose($fp);
846 }
847
848 if ($failure)
849 echo '
850 <input type="submit" name="submit" value="', $txt['save_settings'], '" disabled="disabled" class="button_submit" /><br />', $txt['not_writable'];
851 else
852 {
853 echo '
854 [<a href="javascript:restoreAll();">', $txt['restore_all_settings'], '</a>]
855 <input type="submit" name="submit" value="', $txt['save_settings'], '" class="button_submit" />';
856
857 if (!$context['is_legacy'])
858 echo '
859 <input type="submit" name="remove_hooks" value="' . $txt[($context['smfVersion'] == '2.1' ? 'disable' : 'remove') . '_hooks'] . '" class="button_submit" />';
860 }
861
862 //In either case, an easy remove button? This has a long name in it, so let's break a line
863 echo '<br /><input type="submit" name="remove_file" value="' . $txt['remove_file'] . '" class="button_submit" />';
864
865 echo '
866 </div>
867 </div>
868 </form>';
869}
870
871function guess_attachments_directories($id, $array_setting)
872{
873 global $smcFunc, $context;
874 static $usedDirs;
875
876 if (empty($userdDirs))
877 {
878 $usedDirs = array();
879 $request = $smcFunc['db_query'](true, '
880 SELECT {raw:select_tables}, file_hash
881 FROM {db_prefix}attachments
882 {raw:smf1_limit}',
883 array(
884 'select_tables' => $context['is_legacy'] ? ($id . ' as id_folder, ID_ATTACH as id_attach') : 'DISTINCT(id_folder), id_attach',
885 // If it's SMF 1.x then check only the last attachment loaded
886 'smf1_limit' => $context['is_legacy'] ? ' ORDER BY ID_ATTACH DESC LIMIT 1' : '',
887 )
888 );
889
890 if ($smcFunc['db_num_rows']($request) > 0)
891 {
892 while ($row = $smcFunc['db_fetch_assoc']($request))
893 $usedDirs[$row['id_folder']] = $row;
894 $smcFunc['db_free_result']($request);
895 }
896 }
897
898 if ($basedir = opendir(dirname(__FILE__)))
899 {
900 $availableDirs = array();
901 while (false !== ($file = readdir($basedir)))
902 if ($file != '.' && $file != '..' && is_dir($file) && $file != 'Sources' && $file != 'Packages' && $file != 'Themes' && $file != 'cache' && $file != 'avatars' && $file != 'Smileys')
903 $availableDirs[] = $file;
904 }
905
906 // 1st guess: let's see if we can find a file...if there is at least one.
907 if (isset($usedDirs[$id]) || ($context['is_legacy'] && isset($usedDirs[$id])))
908 foreach ($availableDirs as $aDir)
909 if (file_exists(dirname(__FILE__) . '/' . $aDir . '/' . $usedDirs[$id]['id_attach'] . '_' . $usedDirs[$id]['file_hash']))
910 return array(dirname(__FILE__) . '/' . $aDir);
911
912 // 2nd guess: directory name
913 if (!empty($availableDirs))
914 foreach ($availableDirs as $dirname)
915 if (strrpos($array_setting, $dirname) == (strlen($array_setting) - strlen($dirname)))
916 return array(dirname(__FILE__) . '/' . $dirname);
917
918 // Doing it later saves in case the attached files have been deleted from the file system
919 if (empty($usedDirs) && empty($availableDirs))
920 return false;
921 elseif (empty($usedDirs) && !empty($availableDirs))
922 {
923 $guesses = array();
924 // attachments is the first guess
925 foreach ($availableDirs as $dir)
926 if ($dir == 'attachments')
927 $guesses[] = dirname(__FILE__) . '/' . $dir;
928
929 // all the others
930 foreach ($availableDirs as $dir)
931 if ($dir != 'attachments')
932 $guesses[] = dirname(__FILE__) . '/' . $dir;
933 return $guesses;
934 }
935}
936
937function set_settings()
938{
939 global $smcFunc, $context, $db_connection, $db_server, $db_name, $db_user, $db_passwd, $db_prefix, $db_type;
940
941 $db_updates = isset($_POST['dbsettings']) ? $_POST['dbsettings'] : array();
942 $theme_updates = isset($_POST['themesettings']) ? $_POST['themesettings'] : array();
943 $file_updates = isset($_POST['flatsettings']) ? $_POST['flatsettings'] : array();
944 $attach_dirs = array();
945
946 if (empty($db_updates['theme_default']))
947 unset($db_updates['theme_default']);
948 else
949 {
950 $db_updates['theme_guests'] = 1;
951 $smcFunc['db_query'](true, '
952 UPDATE {db_prefix}members
953 SET {raw:theme_column} = 0',
954 array(
955 'theme_column' => $context['is_legacy'] ? 'ID_THEME' : 'id_theme',
956 )
957 );
958 }
959
960 $settingsArray = file(dirname(__FILE__) . '/Settings.php');
961 $settings = array();
962 for ($i = 0, $n = count($settingsArray); $i < $n; $i++)
963 {
964 $settingsArray[$i] = rtrim($settingsArray[$i]);
965
966 // Remove the redirect...
967 if ($settingsArray[$i] == 'if (file_exists(dirname(__FILE__) . \'/install.php\'))')
968 {
969 $settingsArray[$i] = '';
970 $settingsArray[$i++] = '';
971 $settingsArray[$i++] = '';
972 $settingsArray[$i++] = '';
973 $settingsArray[$i++] = '';
974 $settingsArray[$i++] = '';
975 continue;
976 }
977
978 if (isset($settingsArray[$i][0]) && $settingsArray[$i][0] != '.' && preg_match('~^[$]([a-zA-Z_]+)\s*=\s*(?:(["\'])(.*?["\'])(?:\\2)?|(.*?)(?:\\2)?);~', $settingsArray[$i], $match) == 1)
979 $settings[$match[1]] = stripslashes($match[3]);
980
981 foreach ($file_updates as $var => $val)
982 {
983 if (strncasecmp($settingsArray[$i], '$' . $var, 1 + strlen($var)) == 0)
984 {
985 $comment = strstr($settingsArray[$i], '#');
986
987 // Ints, should be ints, not strings. Bools too.
988 if (in_array($val, array('0', '1', '2', 'true', 'false')))
989 $settingsArray[$i] = '$' . $var . ' = ' . $val . ';' . ($comment != '' ? "\t\t" . $comment : '');
990 else
991 $settingsArray[$i] = '$' . $var . ' = \'' . $val . '\';' . ($comment != '' ? "\t\t" . $comment : '');
992 }
993 }
994 }
995
996 // Blank out the file - done to fix a oddity with some servers.
997 $fp = @fopen(dirname(__FILE__) . '/Settings.php', 'w');
998 fclose($fp);
999
1000 $fp = fopen(dirname(__FILE__) . '/Settings.php', 'r+');
1001 $lines = count($settingsArray);
1002 for ($i = 0; $i < $lines - 1; $i++)
1003 {
1004 // Don't just write a bunch of blank lines.
1005 if ($settingsArray[$i] != '' || $settingsArray[$i - 1] != '')
1006 fwrite($fp, $settingsArray[$i] . "\n");
1007 }
1008 fwrite($fp, $settingsArray[$i]);
1009 fclose($fp);
1010
1011 // Make sure it works.
1012 require(dirname(__FILE__) . '/Settings.php');
1013
1014 //We need to re-try the database settings, right?
1015 $context['settings_test'] = 1;
1016 initialize_inputs();
1017 //if database settings are wrong, we will not try anything else!
1018 if ($db_connection != true)
1019 return;
1020
1021 $setString = array();
1022 foreach ($db_updates as $var => $val)
1023 $setString[] = array($var, stripslashes($val));
1024
1025 // Attachments dirs
1026 if ($context['is_legacy'])
1027 {
1028 foreach ($setString as $key => $value)
1029 if (strpos($value[0], 'attachmentUploadDir') == 0 && strpos($value[0], 'attachmentUploadDir') !== false)
1030 {
1031 $attach_dirs[0] = $value[1];
1032 unset($setString[$key]);
1033 }
1034 }
1035 else
1036 {
1037 $attach_count = 1;
1038 foreach ($setString as $key => $value)
1039 if (strpos($value[0], 'attachmentUploadDir') == 0 && strpos($value[0], 'attachmentUploadDir') !== false)
1040 {
1041 $attach_dirs[$attach_count++] = $value[1];
1042 unset($setString[$key]);
1043 }
1044 }
1045
1046 // In SMF 2.1, its always an array.
1047 if ($context['smfVersion'] == '2.1')
1048 {
1049 $setString[] = array('attachmentUploadDir', json_encode($attach_dirs));
1050 }
1051 // Only one dir...or maybe nothing at all
1052 elseif (count($attach_dirs) > 1)
1053 {
1054 $setString[] = array('attachmentUploadDir', @serialize($attach_dirs));
1055 // If we want to (re)set currentAttachmentUploadDir here is a good place
1056// foreach ($attach_dirs as $id => $attach_dir)
1057// if (is_dir($attach_dir) && is_writable($attach_dir))
1058// $setString[] = array('currentAttachmentUploadDir', $id + 1);
1059 }
1060 elseif (!$context['is_legacy'] && isset($attach_dirs[1]))
1061 {
1062 $setString[] = array('attachmentUploadDir', $attach_dirs[1]);
1063 $setString[] = array('currentAttachmentUploadDir', 0);
1064 }
1065 elseif ($context['is_legacy'] && isset($attach_dirs[0]))
1066 {
1067 $setString[] = array('attachmentUploadDir', $attach_dirs[0]);
1068 }
1069 else
1070 {
1071 $setString[] = array('attachmentUploadDir', '');
1072 $setString[] = array('currentAttachmentUploadDir', 0);
1073 }
1074
1075 if (!empty($setString))
1076 $smcFunc['db_insert']('replace',
1077 '{db_prefix}settings',
1078 array('variable' => 'string', 'value' => 'string-65534'),
1079 $setString,
1080 array('variable')
1081 );
1082
1083 $setString = array();
1084 foreach ($theme_updates as $var => $val)
1085 {
1086 // Extract the data
1087 preg_match('~theme_([\d]+)_(.+)~', $var, $match);
1088 if (empty($match[0]))
1089 continue;
1090
1091 $setString[] = array($match[1], 0, $match[2], stripslashes($val));
1092 }
1093
1094 if (!empty($setString))
1095 $smcFunc['db_insert']('replace',
1096 '{db_prefix}themes',
1097 array('id_theme' => 'int', 'id_member' => 'int', 'variable' => 'string', 'value' => 'string-65534'),
1098 $setString,
1099 array('id_theme', 'id_member', 'variable')
1100 );
1101 //If we got here, all is good :)
1102 $context['settings_saved'] = 1;
1103}
1104
1105function remove_hooks()
1106{
1107 global $smcFunc, $sourcedir, $context;
1108
1109 // For SMF 2.1, we can just disable them.
1110 if ($context['smfVersion'] == '2.1')
1111 $smcFunc['db_query']('', '
1112 UPDATE {db_prefix}settings
1113 SET value = CONCAT(value, {string:disable})
1114 WHERE variable LIKE {string:variable}
1115 AND value NOT LIKE {string:disableMatch}',
1116 array(
1117 'disable' => '!',
1118 'variable' => 'integrate_%',
1119 'disableMatch' => '%!',
1120 )
1121 );
1122 else
1123 $smcFunc['db_query']('', '
1124 DELETE FROM {db_prefix}settings
1125 WHERE variable LIKE {string:variable}',
1126 array(
1127 'variable' => 'integrate_%'
1128 )
1129 );
1130
1131 // Now fixing the cache...
1132 require_once($sourcedir . '/Load.php');
1133 cache_put_data('modsettings', null, 0);
1134
1135 //Let's say we did it
1136 $context['hooks_removed'] = 1;
1137}
1138
1139// Compat mode!
1140function smc_compat_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix, $db_options = array())
1141{
1142 global $mysql_set_mod, $sourcedir, $db_connection, $db_prefix, $smcFunc;
1143
1144 if (!empty($db_options['persist']))
1145 $db_connection = @mysql_pconnect($db_server, $db_user, $db_passwd);
1146 else
1147 $db_connection = @mysql_connect($db_server, $db_user, $db_passwd);
1148
1149 // Something's wrong, show an error if its fatal (which we assume it is)
1150 if (!$db_connection)
1151 {
1152 if (!empty($db_options['non_fatal']))
1153 return null;
1154 else
1155 {
1156 if (file_exists($sourcedir . '/Errors.php'))
1157 {
1158 require_once($sourcedir . '/Errors.php');
1159 display_db_error();
1160 }
1161 exit('Sorry, SMF was unable to connect to database.');
1162 }
1163 }
1164
1165 // Select the database, unless told not to
1166 if (empty($db_options['dont_select_db']) && !@mysql_select_db($db_name, $connection) && empty($db_options['non_fatal']))
1167 {
1168 if (file_exists($sourcedir . '/Errors.php'))
1169 {
1170 require_once($sourcedir . '/Errors.php');
1171 display_db_error();
1172 }
1173 exit('Sorry, SMF was unable to connect to database.');
1174 }
1175 else
1176 $db_prefix = is_numeric(substr($db_prefix, 0, 1)) ? $db_name . '.' . $db_prefix : '`' . $db_name . '`.' . $db_prefix;
1177
1178 // Some core functions, but only once, yes?
1179 if (!function_exists('smf_db_replacement__callback'))
1180 {
1181 function smf_db_replacement__callback($matches)
1182 {
1183 global $db_callback, $user_info, $db_prefix;
1184
1185 list ($values, $connection) = $db_callback;
1186
1187 if ($matches[1] === 'db_prefix')
1188 return $db_prefix;
1189
1190 if ($matches[1] === 'query_see_board')
1191 return $user_info['query_see_board'];
1192
1193 if ($matches[1] === 'query_wanna_see_board')
1194 return $user_info['query_wanna_see_board'];
1195
1196 if (!isset($matches[2]))
1197 smf_db_error_backtrace('Invalid value inserted or no type specified.', '', E_USER_ERROR, __FILE__, __LINE__);
1198
1199 if (!isset($values[$matches[2]]))
1200 smf_db_error_backtrace('The database value you\'re trying to insert does not exist: ' . htmlspecialchars($matches[2]), '', E_USER_ERROR, __FILE__, __LINE__);
1201
1202 $replacement = $values[$matches[2]];
1203
1204 switch ($matches[1])
1205 {
1206 case 'int':
1207 if (!is_numeric($replacement) || (string) $replacement !== (string) (int) $replacement)
1208 smf_db_error_backtrace('Wrong value type sent to the database. Integer expected. (' . $matches[2] . ')', '', E_USER_ERROR, __FILE__, __LINE__);
1209 return (string) (int) $replacement;
1210 break;
1211
1212 case 'string':
1213 case 'text':
1214 return sprintf('\'%1$s\'', mysql_real_escape_string($replacement, $connection));
1215 break;
1216
1217 case 'array_int':
1218 if (is_array($replacement))
1219 {
1220 if (empty($replacement))
1221 smf_db_error_backtrace('Database error, given array of integer values is empty. (' . $matches[2] . ')', '', E_USER_ERROR, __FILE__, __LINE__);
1222
1223 foreach ($replacement as $key => $value)
1224 {
1225 if (!is_numeric($value) || (string) $value !== (string) (int) $value)
1226 smf_db_error_backtrace('Wrong value type sent to the database. Array of integers expected. (' . $matches[2] . ')', '', E_USER_ERROR, __FILE__, __LINE__);
1227
1228 $replacement[$key] = (string) (int) $value;
1229 }
1230
1231 return implode(', ', $replacement);
1232 }
1233 else
1234 smf_db_error_backtrace('Wrong value type sent to the database. Array of integers expected. (' . $matches[2] . ')', '', E_USER_ERROR, __FILE__, __LINE__);
1235
1236 break;
1237
1238 case 'array_string':
1239 if (is_array($replacement))
1240 {
1241 if (empty($replacement))
1242 smf_db_error_backtrace('Database error, given array of string values is empty. (' . $matches[2] . ')', '', E_USER_ERROR, __FILE__, __LINE__);
1243
1244 foreach ($replacement as $key => $value)
1245 $replacement[$key] = sprintf('\'%1$s\'', mysql_real_escape_string($value, $connection));
1246
1247 return implode(', ', $replacement);
1248 }
1249 else
1250 smf_db_error_backtrace('Wrong value type sent to the database. Array of strings expected. (' . $matches[2] . ')', '', E_USER_ERROR, __FILE__, __LINE__);
1251 break;
1252
1253 case 'date':
1254 if (preg_match('~^(\d{4})-([0-1]?\d)-([0-3]?\d)$~', $replacement, $date_matches) === 1)
1255 return sprintf('\'%04d-%02d-%02d\'', $date_matches[1], $date_matches[2], $date_matches[3]);
1256 else
1257 smf_db_error_backtrace('Wrong value type sent to the database. Date expected. (' . $matches[2] . ')', '', E_USER_ERROR, __FILE__, __LINE__);
1258 break;
1259
1260 case 'float':
1261 if (!is_numeric($replacement))
1262 smf_db_error_backtrace('Wrong value type sent to the database. Floating point number expected. (' . $matches[2] . ')', '', E_USER_ERROR, __FILE__, __LINE__);
1263 return (string) (float) $replacement;
1264 break;
1265
1266 case 'identifier':
1267 // Backticks inside identifiers are supported as of MySQL 4.1. We don't need them for SMF.
1268 return '`' . strtr($replacement, array('`' => '', '.' => '')) . '`';
1269 break;
1270
1271 case 'raw':
1272 return $replacement;
1273 break;
1274
1275 default:
1276 smf_db_error_backtrace('Undefined type used in the database query. (' . $matches[1] . ':' . $matches[2] . ')', '', false, __FILE__, __LINE__);
1277 break;
1278 }
1279 }
1280 }
1281
1282 // Because this is just compat mode, this is good enough.
1283 if (!function_exists('smf_db_query'))
1284 {
1285 function smf_db_query($execute = true, $db_string, $db_values)
1286 {
1287 global $db_callback, $db_connection;
1288
1289 // Only bother if there's something to replace.
1290 if (strpos($db_string, '{') !== false)
1291 {
1292 // This is needed by the callback function.
1293 $db_callback = array($db_values, $db_connection);
1294
1295 // Do the quoting and escaping
1296 $db_string = preg_replace_callback('~{([a-z_]+)(?::([a-zA-Z0-9_-]+))?}~', 'smf_db_replacement__callback', $db_string);
1297
1298 // Clear this global variable.
1299 $db_callback = array();
1300 }
1301
1302 // We actually make the query in compat mode.
1303 if ($execute === false)
1304 return $db_string;
1305 return mysql_query($db_string, $db_connection);
1306 }
1307 }
1308
1309 // Insert some data...
1310 if (!function_exists('smf_db_insert'))
1311 {
1312 function smf_db_insert($method = 'replace', $table, $columns, $data, $keys, $disable_trans = false)
1313 {
1314 global $smcFunc, $db_connection, $db_prefix;
1315
1316 // With nothing to insert, simply return.
1317 if (empty($data))
1318 return;
1319
1320 // Replace the prefix holder with the actual prefix.
1321 $table = str_replace('{db_prefix}', $db_prefix, $table);
1322
1323 // Inserting data as a single row can be done as a single array.
1324 if (!is_array($data[array_rand($data)]))
1325 $data = array($data);
1326
1327 // Create the mold for a single row insert.
1328 $insertData = '(';
1329 foreach ($columns as $columnName => $type)
1330 {
1331 // Are we restricting the length?
1332 if (strpos($type, 'string-') !== false)
1333 $insertData .= sprintf('SUBSTRING({string:%1$s}, 1, ' . substr($type, 7) . '), ', $columnName);
1334 else
1335 $insertData .= sprintf('{%1$s:%2$s}, ', $type, $columnName);
1336 }
1337 $insertData = substr($insertData, 0, -2) . ')';
1338
1339 // Create an array consisting of only the columns.
1340 $indexed_columns = array_keys($columns);
1341
1342 // Here's where the variables are injected to the query.
1343 $insertRows = array();
1344 foreach ($data as $dataRow)
1345 $insertRows[] = smf_db_query(false, $insertData, array_combine($indexed_columns, $dataRow));
1346
1347 // Determine the method of insertion.
1348 $queryTitle = ($method == 'replace') ? 'REPLACE' : (($method == 'ignore') ? 'INSERT IGNORE' : 'INSERT');
1349
1350 // Do the insert.
1351 $smcFunc['db_query'](true, '
1352 ' . $queryTitle . ' INTO ' . $table . '(`' . implode('`, `', $indexed_columns) . '`)
1353 VALUES
1354 ' . implode(',
1355 ', $insertRows),
1356 array(
1357 'security_override' => true,
1358 )
1359 );
1360 }
1361 }
1362
1363 // This function tries to work out additional error information from a back trace.
1364 if (!function_exists('smf_db_error_backtrace'))
1365 {
1366 function smf_db_error_backtrace($error_message, $log_message = '', $error_type = false, $file = null, $line = null)
1367 {
1368 if (empty($log_message))
1369 $log_message = $error_message;
1370
1371 // A special case - we want the file and line numbers for debugging.
1372 if ($error_type == 'return')
1373 return array($file, $line);
1374
1375 // Is always a critical error.
1376 if (function_exists('log_error'))
1377 log_error($log_message, 'critical', $file, $line);
1378
1379 if ($error_type)
1380 trigger_error($error_message . ($line !== null ? '<em>(' . basename($file) . '-' . $line . ')</em>' : ''), $error_type);
1381 else
1382 trigger_error($error_message . ($line !== null ? '<em>(' . basename($file) . '-' . $line . ')</em>' : ''));
1383 }
1384 }
1385
1386 // Returns all tables
1387 if (!function_exists('smf_db_list_tables'))
1388 {
1389 function smf_db_list_tables($db = false, $filter = false)
1390 {
1391 global $db_name, $smcFunc;
1392
1393 $db = $db == false ? $db_name : $db;
1394 $db = trim($db);
1395 $filter = $filter == false ? '' : ' LIKE \'' . $filter . '\'';
1396
1397 $request = $smcFunc['db_query'](true, '
1398 SHOW TABLES
1399 FROM `{raw:db}`
1400 {raw:filter}',
1401 array(
1402 'db' => $db[0] == '`' ? strtr($db, array('`' => '')) : $db,
1403 'filter' => $filter,
1404 )
1405 );
1406 $tables = array();
1407 while ($row = $smcFunc['db_fetch_row']($request))
1408 $tables[] = $row[0];
1409 $smcFunc['db_free_result']($request);
1410
1411 return $tables;
1412 }
1413 }
1414
1415 // Now, go functions, spread your love.
1416 $smcFunc['db_free_result'] = 'mysql_free_result';
1417 $smcFunc['db_fetch_row'] = 'mysql_fetch_row';
1418 $smcFunc['db_fetch_assoc'] = 'mysql_fetch_assoc';
1419 $smcFunc['db_num_rows'] = 'mysql_num_rows';
1420 $smcFunc['db_insert'] = 'smf_db_insert';
1421 $smcFunc['db_query'] = 'smf_db_query';
1422 $smcFunc['db_quote'] = 'smf_db_query';
1423 $smcFunc['db_error_backtrace'] = 'smf_db_error_backtrace';
1424 $smcFunc['db_list_tables'] = 'smf_db_list_tables';
1425
1426 return $db_connection;
1427}
1428
1429//Function to find Sources automatically. If it's here, we find it :)
1430function findSources()
1431{
1432 $basedir = dirname(__FILE__); //Our location :)
1433 $dirs = array();
1434 $dir = dir($basedir);
1435
1436 //All our folders
1437 while ($line = $dir->read())
1438 {
1439 if (in_array($line, array('.', '..', 'blank.gif', 'index', '.htaccess')))
1440 continue;
1441 if (is_dir($line))
1442 $dirs[] = $line;
1443 else
1444 $files[] = $line;
1445 }
1446 $dir->close();
1447
1448 foreach ($dirs as $key => $value) //Let's find Load.php!!!
1449 {
1450 //Files in this folder
1451 $current_folder = $basedir . '/' . $value;
1452 $dir = dir($current_folder);
1453 while ($line = $dir->read())
1454 {
1455 if (in_array($line, array('.', '..', 'blank.gif', 'index', '.htaccess')))
1456 continue;
1457 //We are looking for Load.php. As good as any other :)
1458 if (!is_dir($line) && ($line == 'Load.php'))
1459 return $current_folder;
1460 }
1461 $dir->close();
1462 }
1463 //If we get to the end, well, we didn't find it...
1464 return null;
1465}