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>