]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - install.php
Merge branch 'testing' of git@gitorious.org:statusnet/mainline into testing
[quix0rs-gnu-social.git] / install.php
1
2 <?php
3 /**
4  * StatusNet - the distributed open-source microblogging tool
5  * Copyright (C) 2009, StatusNet, Inc.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  * @category Installation
21  * @package  Installation
22  *
23  * @author   Adrian Lang <mail@adrianlang.de>
24  * @author   Brenda Wallace <shiny@cpan.org>
25  * @author   Brett Taylor <brett@webfroot.co.nz>
26  * @author   Brion Vibber <brion@pobox.com>
27  * @author   CiaranG <ciaran@ciarang.com>
28  * @author   Craig Andrews <candrews@integralblue.com>
29  * @author   Eric Helgeson <helfire@Erics-MBP.local>
30  * @author   Evan Prodromou <evan@status.net>
31  * @author   Robin Millette <millette@controlyourself.ca>
32  * @author   Sarven Capadisli <csarven@status.net>
33  * @author   Tom Adams <tom@holizz.com>
34  * @license  GNU Affero General Public License http://www.gnu.org/licenses/
35  * @version  0.9.x
36  * @link     http://status.net
37  */
38
39 define('INSTALLDIR', dirname(__FILE__));
40
41 $external_libraries=array(
42     array(
43         'name'=>'gettext',
44         'url'=>'http://us.php.net/manual/en/book.gettext.php',
45         'check_function'=>'gettext'
46     ),
47     array(
48         'name'=>'PEAR',
49         'url'=>'http://pear.php.net/',
50         'deb'=>'php-pear',
51         'include'=>'PEAR.php',
52         'check_class'=>'PEAR'
53     ),
54     array(
55         'name'=>'DB',
56         'pear'=>'DB',
57         'url'=>'http://pear.php.net/package/DB',
58         'deb'=>'php-db',
59         'include'=>'DB/common.php',
60         'check_class'=>'DB_common'
61     ),
62     array(
63         'name'=>'DB_DataObject',
64         'pear'=>'DB_DataObject',
65         'url'=>'http://pear.php.net/package/DB_DataObject',
66         'include'=>'DB/DataObject.php',
67         'check_class'=>'DB_DataObject'
68     ),
69     array(
70         'name'=>'Console_Getopt',
71         'pear'=>'Console_Getopt',
72         'url'=>'http://pear.php.net/package/Console_Getopt',
73         'include'=>'Console/Getopt.php',
74         'check_class'=>'Console_Getopt'
75     ),
76     array(
77         'name'=>'Facebook API',
78         'url'=>'http://developers.facebook.com/',
79         'include'=>'facebook/facebook.php',
80         'check_class'=>'Facebook'
81     ),
82     array(
83         'name'=>'htmLawed',
84         'url'=>'http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed',
85         'include'=>'htmLawed/htmLawed.php',
86         'check_function'=>'htmLawed'
87     ),
88     array(
89         'name'=>'HTTP_Request',
90         'pear'=>'HTTP_Request',
91         'url'=>'http://pear.php.net/package/HTTP_Request',
92         'deb'=>'php-http-request',
93         'include'=>'HTTP/Request.php',
94         'check_class'=>'HTTP_Request'
95     ),
96     array(
97         'name'=>'HTTP_Request2',
98         'pear'=>'HTTP_Request2',
99         'url'=>'http://pear.php.net/package/HTTP_Request2',
100         'include'=>'HTTP/Request2.php',
101         'check_class'=>'HTTP_Request2'
102     ),
103     array(
104         'name'=>'Mail',
105         'pear'=>'Mail',
106         'url'=>'http://pear.php.net/package/Mail',
107         'deb'=>'php-mail',
108         'include'=>'Mail.php',
109         'check_class'=>'Mail'
110     ),
111     array(
112         'name'=>'Mail_mimeDecode',
113         'pear'=>'Mail_mimeDecode',
114         'url'=>'http://pear.php.net/package/Mail_mimeDecode',
115         'deb'=>'php-mail-mimedecode',
116         'include'=>'Mail/mimeDecode.php',
117         'check_class'=>'Mail_mimeDecode'
118     ),
119     array(
120         'name'=>'Mime_Type',
121         'pear'=>'Mime_Type',
122         'url'=>'http://pear.php.net/package/Mime_Type',
123         'include'=>'MIME/Type.php',
124         'check_class'=>'Mime_Type'
125     ),
126     array(
127         'name'=>'Net_URL_Mapper',
128         'pear'=>'Net_URL_Mapper',
129         'url'=>'http://pear.php.net/package/Net_URL_Mapper',
130         'include'=>'Net/URL/Mapper.php',
131         'check_class'=>'Net_URL_Mapper'
132     ),
133     array(
134         'name'=>'Net_LDAP2',
135         'pear'=>'Net_LDAP2',
136         'url'=>'http://pear.php.net/package/Net_LDAP2',
137         'deb'=>'php-net-ldap2',
138         'include'=>'Net/LDAP2.php',
139         'check_class'=>'Net_LDAP2'
140     ),
141     array(
142         'name'=>'Net_Socket',
143         'pear'=>'Net_Socket',
144         'url'=>'http://pear.php.net/package/Net_Socket',
145         'deb'=>'php-net-socket',
146         'include'=>'Net/Socket.php',
147         'check_class'=>'Net_Socket'
148     ),
149     array(
150         'name'=>'Net_SMTP',
151         'pear'=>'Net_SMTP',
152         'url'=>'http://pear.php.net/package/Net_SMTP',
153         'deb'=>'php-net-smtp',
154         'include'=>'Net/SMTP.php',
155         'check_class'=>'Net_SMTP'
156     ),
157     array(
158         'name'=>'Net_URL',
159         'pear'=>'Net_URL',
160         'url'=>'http://pear.php.net/package/Net_URL',
161         'deb'=>'php-net-url',
162         'include'=>'Net/URL.php',
163         'check_class'=>'Net_URL'
164     ),
165     array(
166         'name'=>'Net_URL2',
167         'pear'=>'Net_URL2',
168         'url'=>'http://pear.php.net/package/Net_URL2',
169         'include'=>'Net/URL2.php',
170         'check_class'=>'Net_URL2'
171     ),
172     array(
173         'name'=>'Services_oEmbed',
174         'pear'=>'Services_oEmbed',
175         'url'=>'http://pear.php.net/package/Services_oEmbed',
176         'include'=>'Services/oEmbed.php',
177         'check_class'=>'Services_oEmbed'
178     ),
179     array(
180         'name'=>'Stomp',
181         'url'=>'http://stomp.codehaus.org/PHP',
182         'include'=>'Stomp.php',
183         'check_class'=>'Stomp'
184     ),
185     array(
186         'name'=>'System_Command',
187         'pear'=>'System_Command',
188         'url'=>'http://pear.php.net/package/System_Command',
189         'include'=>'System/Command.php',
190         'check_class'=>'System_Command'
191     ),
192     array(
193         'name'=>'XMPPHP',
194         'url'=>'http://code.google.com/p/xmpphp',
195         'include'=>'XMPPHP/XMPP.php',
196         'check_class'=>'XMPPHP_XMPP'
197     ),
198     array(
199         'name'=>'PHP Markdown',
200         'url'=>'http://www.michelf.com/projects/php-markdown/',
201         'include'=>'markdown.php',
202         'check_class'=>'Markdown_Parser'
203     ),
204     array(
205         'name'=>'OAuth',
206         'url'=>'http://code.google.com/p/oauth-php',
207         'include'=>'OAuth.php',
208         'check_class'=>'OAuthRequest'
209     ),
210     array(
211         'name'=>'Validate',
212         'pear'=>'Validate',
213         'url'=>'http://pear.php.net/package/Validate',
214         'include'=>'Validate.php',
215         'check_class'=>'Validate'
216     )
217 );
218 $dbModules = array(
219     'mysql' => array(
220         'name' => 'MySQL',
221         'check_module' => 'mysql', // mysqli?
222         'installer' => 'mysql_db_installer',
223     ),
224     'pgsql' => array(
225         'name' => 'PostgreSQL',
226         'check_module' => 'pgsql',
227         'installer' => 'pgsql_db_installer',
228     ),
229 );
230
231 /**
232  * the actual installation.
233  * If call libraries are present, then install
234  *
235  * @return void
236  */
237 function main()
238 {
239     if (!checkPrereqs()) {
240         return;
241     }
242
243     if (!empty($_GET['checklibs'])) {
244         showLibs();
245     } else {
246         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
247             handlePost();
248         } else {
249             showForm();
250         }
251     }
252 }
253
254 /**
255  * checks if an external libary is present
256  *
257  * @param string $external_library Name of library
258  *
259  * @return boolean indicates if library present
260  */
261 function haveExternalLibrary($external_library)
262 {
263     if (isset($external_library['include']) && !haveIncludeFile($external_library['include'])) {
264         return false;
265     }
266     if (isset($external_library['check_function']) && ! function_exists($external_library['check_function'])) {
267         return false;
268     }
269     if (isset($external_library['check_class']) && ! class_exists($external_library['check_class'])) {
270         return false;
271     }
272     return true;
273 }
274
275 // Attempt to include a PHP file and report if it worked, while
276 // suppressing the annoying warning messages on failure.
277 function haveIncludeFile($filename) {
278     $old = error_reporting(error_reporting() & ~E_WARNING);
279     $ok = include_once($filename);
280     error_reporting($old);
281     return $ok;
282 }
283
284 /**
285  * Check if all is ready for installation
286  *
287  * @return void
288  */
289 function checkPrereqs()
290 {
291     $pass = true;
292
293     if (file_exists(INSTALLDIR.'/config.php')) {
294          printf('<p class="error">Config file &quot;config.php&quot; already exists.</p>');
295         $pass = false;
296     }
297
298     if (version_compare(PHP_VERSION, '5.2.3', '<')) {
299         printf('<p class="error">Require PHP version 5.2.3 or greater.</p>');
300         $pass = false;
301     }
302
303     $reqs = array('gd', 'curl',
304                   'xmlwriter', 'mbstring', 'xml', 'dom', 'simplexml');
305
306     foreach ($reqs as $req) {
307         if (!checkExtension($req)) {
308             printf('<p class="error">Cannot load required extension: <code>%s</code></p>', $req);
309             $pass = false;
310         }
311     }
312     // Make sure we have at least one database module available
313     global $dbModules;
314     $missingExtensions = array();
315     foreach ($dbModules as $type => $info) {
316         if (!checkExtension($info['check_module'])) {
317             $missingExtensions[] = $info['check_module'];
318         }
319     }
320
321     if (count($missingExtensions) == count($dbModules)) {
322         $req = implode(', ', $missingExtensions);
323         printf('<p class="error">Cannot find mysql or pgsql extension. You need one or the other.');
324         $pass = false;
325     }
326
327     if (!is_writable(INSTALLDIR)) {
328         printf('<p class="error">Cannot write config file to: <code>%s</code></p>', INSTALLDIR);
329         printf('<p>On your server, try this command: <code>chmod a+w %s</code>', INSTALLDIR);
330         $pass = false;
331     }
332
333     // Check the subdirs used for file uploads
334     $fileSubdirs = array('avatar', 'background', 'file');
335     foreach ($fileSubdirs as $fileSubdir) {
336         $fileFullPath = INSTALLDIR."/$fileSubdir/";
337         if (!is_writable($fileFullPath)) {
338             printf('<p class="error">Cannot write to %s directory: <code>%s</code></p>', $fileSubdir, $fileFullPath);
339             printf('<p>On your server, try this command: <code>chmod a+w %s</code></p>', $fileFullPath);
340             $pass = false;
341         }
342     }
343
344     return $pass;
345 }
346
347 /**
348  * Checks if a php extension is both installed and loaded
349  *
350  * @param string $name of extension to check
351  *
352  * @return boolean whether extension is installed and loaded
353  */
354 function checkExtension($name)
355 {
356     if (extension_loaded($name)) {
357         return true;
358     } elseif (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode')) {
359         // dl will throw a fatal error if it's disabled or we're in safe mode.
360         // More fun, it may not even exist under some SAPIs in 5.3.0 or later...
361         $soname = $name . '.' . PHP_SHLIB_SUFFIX;
362         if (PHP_SHLIB_SUFFIX == 'dll') {
363             $soname = "php_" . $soname;
364         }
365         return @dl($soname);
366     } else {
367         return false;
368     }
369 }
370
371 /**
372  * Show list of libraries
373  *
374  * @return void
375  */
376 function showLibs()
377 {
378     global $external_libraries;
379     $present_libraries=array();
380     $absent_libraries=array();
381     foreach ($external_libraries as $external_library) {
382         if (haveExternalLibrary($external_library)) {
383             $present_libraries[]=$external_library;
384         } else {
385             $absent_libraries[]=$external_library;
386         }
387     }
388     echo<<<E_O_T
389     <div class="instructions">
390         <p>StatusNet comes bundled with a number of libraries required for the application to work. However, it is best that you use PEAR or you distribution to manage
391         libraries instead, as they tend to provide security updates faster, and may offer improved performance.</p>
392         <p>On Debian based distributions, such as Ubuntu, use a package manager (such as &quot;aptitude&quot;, &quot;apt-get&quot;, and &quot;synaptic&quot;) to install the package listed.</p>
393         <p>On RPM based distributions, such as Red Hat, Fedora, CentOS, Scientific Linux, Yellow Dog Linux and Oracle Enterprise Linux, use a package manager (such as &quot;yum&quot;, &quot;apt-rpm&quot;, and &quot;up2date&quot;) to install the package listed.</p>
394         <p>On servers without a package manager (such as Windows), or if the library is not packaged for your distribution, you can use PHP's PEAR to install the library. Simply run &quot;pear install &lt;name&gt;&quot;.</p>
395     </div>
396     <h2>Absent Libraries</h2>
397     <ul id="absent_libraries">
398 E_O_T;
399     foreach ($absent_libraries as $library) {
400         echo '<li>';
401         if (isset($library['url'])) {
402             echo '<a href="'.$library['url'].'">'.htmlentities($library['name']).'</a>';
403         } else {
404             echo htmlentities($library['name']);
405         }
406         echo '<ul>';
407         if (isset($library['deb'])) {
408             echo '<li class="deb package">deb: <a href="apt:' . urlencode($library['deb']) . '">' . htmlentities($library['deb']) . '</a></li>';
409         }
410         if (isset($library['rpm'])) {
411             echo '<li class="rpm package">rpm: ' . htmlentities($library['rpm']) . '</li>';
412         }
413         if (isset($library['pear'])) {
414             echo '<li class="pear package">pear: ' . htmlentities($library['pear']) . '</li>';
415         }
416         echo '</ul>';
417     }
418     echo<<<E_O_T
419     </ul>
420     <h2>Installed Libraries</h2>
421     <ul id="present_libraries">
422 E_O_T;
423     foreach ($present_libraries as $library) {
424         echo '<li>';
425         if (isset($library['url'])) {
426             echo '<a href="'.$library['url'].'">'.htmlentities($library['name']).'</a>';
427         } else {
428             echo htmlentities($library['name']);
429         }
430         echo '</li>';
431     }
432     echo<<<E_O_T
433     </ul>
434 E_O_T;
435 }
436
437 function showForm()
438 {
439     global $dbModules;
440     $dbRadios = '';
441     $checked = 'checked="checked" '; // Check the first one which exists
442     foreach ($dbModules as $type => $info) {
443         if (checkExtension($info['check_module'])) {
444             $dbRadios .= "<input type=\"radio\" name=\"dbtype\" id=\"dbtype-$type\" value=\"$type\" $checked/> $info[name]<br />\n";
445             $checked = '';
446         }
447     }
448     echo<<<E_O_T
449         </ul>
450     </dd>
451 </dl>
452 <dl id="page_notice" class="system_notice">
453     <dt>Page notice</dt>
454     <dd>
455         <div class="instructions">
456             <p>Enter your database connection information below to initialize the database.</p>
457         </div>
458     </dd>
459 </dl>
460 <form method="post" action="install.php" class="form_settings" id="form_install">
461     <fieldset>
462         <legend>Connection settings</legend>
463         <ul class="form_data">
464             <li>
465                 <label for="sitename">Site name</label>
466                 <input type="text" id="sitename" name="sitename" />
467                 <p class="form_guide">The name of your site</p>
468             </li>
469             <li>
470                 <label for="fancy-enable">Fancy URLs</label>
471                 <input type="radio" name="fancy" id="fancy-enable" value="enable" checked='checked' /> enable<br />
472                 <input type="radio" name="fancy" id="fancy-disable" value="" /> disable<br />
473                 <p class="form_guide" id='fancy-form_guide'>Enable fancy (pretty) URLs. Auto-detection failed, it depends on Javascript.</p>
474             </li>
475             <li>
476                 <label for="host">Hostname</label>
477                 <input type="text" id="host" name="host" />
478                 <p class="form_guide">Database hostname</p>
479             </li>
480             <li>
481
482                 <label for="dbtype">Type</label>
483                 $dbRadios
484                 <p class="form_guide">Database type</p>
485             </li>
486
487             <li>
488                 <label for="database">Name</label>
489                 <input type="text" id="database" name="database" />
490                 <p class="form_guide">Database name</p>
491             </li>
492             <li>
493                 <label for="username">Username</label>
494                 <input type="text" id="username" name="username" />
495                 <p class="form_guide">Database username</p>
496             </li>
497             <li>
498                 <label for="password">Password</label>
499                 <input type="password" id="password" name="password" />
500                 <p class="form_guide">Database password (optional)</p>
501             </li>
502         </ul>
503         <input type="submit" name="submit" class="submit" value="Submit" />
504     </fieldset>
505 </form>
506
507 E_O_T;
508 }
509
510 function updateStatus($status, $error=false)
511 {
512     echo '<li' . ($error ? ' class="error"': '' ) . ">$status</li>";
513 }
514
515 function handlePost()
516 {
517     $host     = $_POST['host'];
518     $dbtype   = $_POST['dbtype'];
519     $database = $_POST['database'];
520     $username = $_POST['username'];
521     $password = $_POST['password'];
522     $sitename = $_POST['sitename'];
523     $fancy    = !empty($_POST['fancy']);
524     $server = $_SERVER['HTTP_HOST'];
525     $path = substr(dirname($_SERVER['PHP_SELF']), 1);
526
527     echo <<<STR
528     <dl class="system_notice">
529         <dt>Page notice</dt>
530         <dd>
531             <ul>
532 STR;
533     $fail = false;
534
535     if (empty($host)) {
536         updateStatus("No hostname specified.", true);
537         $fail = true;
538     }
539
540     if (empty($database)) {
541         updateStatus("No database specified.", true);
542         $fail = true;
543     }
544
545     if (empty($username)) {
546         updateStatus("No username specified.", true);
547         $fail = true;
548     }
549
550     if (empty($sitename)) {
551         updateStatus("No sitename specified.", true);
552         $fail = true;
553     }
554
555     if ($fail) {
556         showForm();
557         return;
558     }
559
560     global $dbModules;
561     $db = call_user_func($dbModules[$dbtype]['installer'], $host, $database, $username, $password);
562
563     if (!$db) {
564         // database connection failed, do not move on to create config file.
565         return false;
566     }
567
568     updateStatus("Writing config file...");
569     $res = writeConf($sitename, $server, $path, $fancy, $db);
570
571     if (!$res) {
572         updateStatus("Can't write config file.", true);
573         showForm();
574         return;
575     }
576
577     /*
578         TODO https needs to be considered
579     */
580     $link = "http://".$server.'/'.$path;
581
582     updateStatus("StatusNet has been installed at $link");
583     updateStatus("You can visit your <a href='$link'>new StatusNet site</a>.");
584 }
585
586 function Pgsql_Db_installer($host, $database, $username, $password)
587 {
588     $connstring = "dbname=$database host=$host user=$username";
589
590     //No password would mean trust authentication used.
591     if (!empty($password)) {
592         $connstring .= " password=$password";
593     }
594     updateStatus("Starting installation...");
595     updateStatus("Checking database...");
596     $conn = pg_connect($connstring);
597
598     if ($conn ===false) {
599         updateStatus("Failed to connect to database: $connstring");
600         showForm();
601         return false;
602     }
603
604     //ensure database encoding is UTF8
605     $record = pg_fetch_object(pg_query($conn, 'SHOW server_encoding'));
606     if ($record->server_encoding != 'UTF8') {
607         updateStatus("StatusNet requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding));
608         showForm();
609         return false;
610     }
611
612     updateStatus("Running database script...");
613     //wrap in transaction;
614     pg_query($conn, 'BEGIN');
615     $res = runDbScript(INSTALLDIR.'/db/statusnet_pg.sql', $conn, 'pgsql');
616
617     if ($res === false) {
618         updateStatus("Can't run database script.", true);
619         showForm();
620         return false;
621     }
622     foreach (array('sms_carrier' => 'SMS carrier',
623                 'notice_source' => 'notice source',
624                 'foreign_services' => 'foreign service')
625           as $scr => $name) {
626         updateStatus(sprintf("Adding %s data to database...", $name));
627         $res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn, 'pgsql');
628         if ($res === false) {
629             updateStatus(sprintf("Can't run %d script.", $name), true);
630             showForm();
631             return false;
632         }
633     }
634     pg_query($conn, 'COMMIT');
635
636     if (empty($password)) {
637         $sqlUrl = "pgsql://$username@$host/$database";
638     } else {
639         $sqlUrl = "pgsql://$username:$password@$host/$database";
640     }
641
642     $db = array('type' => 'pgsql', 'database' => $sqlUrl);
643
644     return $db;
645 }
646
647 function Mysql_Db_installer($host, $database, $username, $password)
648 {
649     updateStatus("Starting installation...");
650     updateStatus("Checking database...");
651
652     $conn = mysql_connect($host, $username, $password);
653     if (!$conn) {
654         updateStatus("Can't connect to server '$host' as '$username'.", true);
655         showForm();
656         return false;
657     }
658     updateStatus("Changing to database...");
659     $res = mysql_select_db($database, $conn);
660     if (!$res) {
661         updateStatus("Can't change to database.", true);
662         showForm();
663         return false;
664     }
665     updateStatus("Running database script...");
666     $res = runDbScript(INSTALLDIR.'/db/statusnet.sql', $conn);
667     if ($res === false) {
668         updateStatus("Can't run database script.", true);
669         showForm();
670         return false;
671     }
672     foreach (array('sms_carrier' => 'SMS carrier',
673                 'notice_source' => 'notice source',
674                 'foreign_services' => 'foreign service')
675           as $scr => $name) {
676         updateStatus(sprintf("Adding %s data to database...", $name));
677         $res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn);
678         if ($res === false) {
679             updateStatus(sprintf("Can't run %d script.", $name), true);
680             showForm();
681             return false;
682         }
683     }
684
685     $sqlUrl = "mysqli://$username:$password@$host/$database";
686     $db = array('type' => 'mysql', 'database' => $sqlUrl);
687     return $db;
688 }
689
690 function writeConf($sitename, $server, $path, $fancy, $db)
691 {
692     // assemble configuration file in a string
693     $cfg =  "<?php\n".
694             "if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }\n\n".
695
696             // site name
697             "\$config['site']['name'] = '$sitename';\n\n".
698
699             // site location
700             "\$config['site']['server'] = '$server';\n".
701             "\$config['site']['path'] = '$path'; \n\n".
702
703             // checks if fancy URLs are enabled
704             ($fancy ? "\$config['site']['fancy'] = true;\n\n":'').
705
706             // database
707             "\$config['db']['database'] = '{$db['database']}';\n\n".
708             ($db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":'').
709             "\$config['db']['type'] = '{$db['type']}';\n\n";
710     // write configuration file out to install directory
711     $res = file_put_contents(INSTALLDIR.'/config.php', $cfg);
712
713     return $res;
714 }
715
716 /**
717  * Install schema into the database
718  *
719  * @param string $filename location of database schema file
720  * @param dbconn $conn     connection to database
721  * @param string $type     type of database, currently mysql or pgsql
722  *
723  * @return boolean - indicating success or failure
724  */
725 function runDbScript($filename, $conn, $type = 'mysqli')
726 {
727     $sql = trim(file_get_contents($filename));
728     $stmts = explode(';', $sql);
729     foreach ($stmts as $stmt) {
730         $stmt = trim($stmt);
731         if (!mb_strlen($stmt)) {
732             continue;
733         }
734         // FIXME: use PEAR::DB or PDO instead of our own switch
735         switch ($type) {
736         case 'mysqli':
737             $res = mysql_query($stmt, $conn);
738             if ($res === false) {
739                 $error = mysql_error();
740             }
741             break;
742         case 'pgsql':
743             $res = pg_query($conn, $stmt);
744             if ($res === false) {
745                 $error = pg_last_error();
746             }
747             break;
748         default:
749             updateStatus("runDbScript() error: unknown database type ". $type ." provided.");
750         }
751         if ($res === false) {
752             updateStatus("ERROR ($error) for SQL '$stmt'");
753             return $res;
754         }
755     }
756     return true;
757 }
758
759 ?>
760 <?php echo"<?"; ?> xml version="1.0" encoding="UTF-8" <?php echo "?>"; ?>
761 <!DOCTYPE html
762 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
763        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
764 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
765     <head>
766         <title>Install StatusNet</title>
767         <link rel="shortcut icon" href="favicon.ico"/>
768         <link rel="stylesheet" type="text/css" href="theme/default/css/display.css?version=0.8" media="screen, projection, tv"/>
769         <!--[if IE]><link rel="stylesheet" type="text/css" href="theme/base/css/ie.css?version=0.8" /><![endif]-->
770         <!--[if lte IE 6]><link rel="stylesheet" type="text/css" theme/base/css/ie6.css?version=0.8" /><![endif]-->
771         <!--[if IE]><link rel="stylesheet" type="text/css" href="theme/default/css/ie.css?version=0.8" /><![endif]-->
772         <script src="js/jquery.min.js"></script>
773         <script src="js/install.js"></script>
774     </head>
775     <body id="install">
776         <div id="wrap">
777             <div id="header">
778                 <address id="site_contact" class="vcard">
779                     <a class="url home bookmark" href=".">
780                         <img class="logo photo" src="theme/default/logo.png" alt="StatusNet"/>
781                         <span class="fn org">StatusNet</span>
782                     </a>
783                 </address>
784             </div>
785             <div id="core">
786                 <div id="content">
787                     <h1>Install StatusNet</h1>
788 <?php main(); ?>
789                 </div>
790             </div>
791         </div>
792     </body>
793 </html>