]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - install.php
OStatus: fix exception thrown on HTTP error during feed discovery
[quix0rs-gnu-social.git] / install.php
index c2a5bb29ee394f392abe062ebf355f6d64b5fecc..7fece8999fe7bcf3ee644086c5543e114d807f69 100644 (file)
@@ -1,3 +1,4 @@
+
 <?php
 /**
  * StatusNet - the distributed open-source microblogging tool
@@ -30,8 +31,9 @@
  * @author   Robin Millette <millette@controlyourself.ca>
  * @author   Sarven Capadisli <csarven@status.net>
  * @author   Tom Adams <tom@holizz.com>
+ * @author   Zach Copley <zach@status.net>
  * @license  GNU Affero General Public License http://www.gnu.org/licenses/
- * @version  0.9
+ * @version  0.9.x
  * @link     http://status.net
  */
 
@@ -92,6 +94,13 @@ $external_libraries=array(
         'include'=>'HTTP/Request.php',
         'check_class'=>'HTTP_Request'
     ),
+    array(
+        'name'=>'HTTP_Request2',
+        'pear'=>'HTTP_Request2',
+        'url'=>'http://pear.php.net/package/HTTP_Request2',
+        'include'=>'HTTP/Request2.php',
+        'check_class'=>'HTTP_Request2'
+    ),
     array(
         'name'=>'Mail',
         'pear'=>'Mail',
@@ -122,6 +131,14 @@ $external_libraries=array(
         'include'=>'Net/URL/Mapper.php',
         'check_class'=>'Net_URL_Mapper'
     ),
+    array(
+        'name'=>'Net_LDAP2',
+        'pear'=>'Net_LDAP2',
+        'url'=>'http://pear.php.net/package/Net_LDAP2',
+        'deb'=>'php-net-ldap2',
+        'include'=>'Net/LDAP2.php',
+        'check_class'=>'Net_LDAP2'
+    ),
     array(
         'name'=>'Net_Socket',
         'pear'=>'Net_Socket',
@@ -284,8 +301,21 @@ function checkPrereqs()
         $pass = false;
     }
 
+    // Look for known library bugs
+    $str = "abcdefghijklmnopqrstuvwxyz";
+    $replaced = preg_replace('/[\p{Cc}\p{Cs}]/u', '*', $str);
+    if ($str != $replaced) {
+        printf('<p class="error">PHP is linked to a version of the PCRE library ' .
+               'that does not support Unicode properties. ' .
+               'If you are running Red Hat Enterprise Linux / ' .
+               'CentOS 5.3 or earlier, see <a href="' .
+               'http://status.net/wiki/Red_Hat_Enterprise_Linux#PCRE_library' .
+               '">our documentation page</a> on fixing this.</p>');
+        $pass = false;
+    }
+
     $reqs = array('gd', 'curl',
-                  'xmlwriter', 'mbstring','tidy');
+                  'xmlwriter', 'mbstring', 'xml', 'dom', 'simplexml');
 
     foreach ($reqs as $req) {
         if (!checkExtension($req)) {
@@ -340,13 +370,13 @@ function checkExtension($name)
     if (extension_loaded($name)) {
         return true;
     } elseif (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode')) {
-       // dl will throw a fatal error if it's disabled or we're in safe mode.
-       // More fun, it may not even exist under some SAPIs in 5.3.0 or later...
-       $soname = $name . '.' . PHP_SHLIB_SUFFIX;
-       if (PHP_SHLIB_SUFFIX == 'dll') {
-               $soname = "php_" . $soname;
-       }
-       return @dl($soname);
+        // dl will throw a fatal error if it's disabled or we're in safe mode.
+        // More fun, it may not even exist under some SAPIs in 5.3.0 or later...
+        $soname = $name . '.' . PHP_SHLIB_SUFFIX;
+        if (PHP_SHLIB_SUFFIX == 'dll') {
+            $soname = "php_" . $soname;
+        }
+        return @dl($soname);
     } else {
         return false;
     }
@@ -371,7 +401,7 @@ function showLibs()
     }
     echo<<<E_O_T
     <div class="instructions">
-        <p>Laconica 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
+        <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
         libraries instead, as they tend to provide security updates faster, and may offer improved performance.</p>
         <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>
         <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>
@@ -383,7 +413,7 @@ E_O_T;
     foreach ($absent_libraries as $library) {
         echo '<li>';
         if (isset($library['url'])) {
-            echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>';
+            echo '<a href="'.$library['url'].'">'.htmlentities($library['name']).'</a>';
         } else {
             echo htmlentities($library['name']);
         }
@@ -407,7 +437,7 @@ E_O_T;
     foreach ($present_libraries as $library) {
         echo '<li>';
         if (isset($library['url'])) {
-            echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>';
+            echo '<a href="'.$library['url'].'">'.htmlentities($library['name']).'</a>';
         } else {
             echo htmlentities($library['name']);
         }
@@ -418,73 +448,119 @@ E_O_T;
 E_O_T;
 }
 
+/**
+ * Helper class for building form
+ */
+class Posted {
+    function value($name)
+    {
+        if (isset($_POST[$name])) {
+            return htmlspecialchars(strval($_POST[$name]));
+        } else {
+            return '';
+        }
+    }
+}
+
 function showForm()
 {
     global $dbModules;
+    $post = new Posted();
     $dbRadios = '';
-    $checked = 'checked="checked" '; // Check the first one which exists
+    if (isset($_POST['dbtype'])) {
+        $dbtype = $_POST['dbtype'];
+    } else {
+        $dbtype = null;
+    }
     foreach ($dbModules as $type => $info) {
         if (checkExtension($info['check_module'])) {
+            if ($dbtype == null || $dbtype == $type) {
+                $checked = 'checked="checked" ';
+                $dbtype = $type; // if we didn't have one checked, hit the first
+            } else {
+                $checked = '';
+            }
             $dbRadios .= "<input type=\"radio\" name=\"dbtype\" id=\"dbtype-$type\" value=\"$type\" $checked/> $info[name]<br />\n";
-            $checked = '';
         }
     }
     echo<<<E_O_T
         </ul>
     </dd>
 </dl>
-<dl id="page_notice" class="system_notice">
-    <dt>Page notice</dt>
-    <dd>
-        <div class="instructions">
-            <p>Enter your database connection information below to initialize the database.</p>
-            <p>Laconica bundles a number of libraries for ease of installation. <a href="?checklibs=true">You can see what bundled libraries you are using, versus what libraries are installed on your server.</a>
-        </div>
-    </dd>
-</dl>
 <form method="post" action="install.php" class="form_settings" id="form_install">
     <fieldset>
-        <legend>Connection settings</legend>
-        <ul class="form_data">
-            <li>
-                <label for="sitename">Site name</label>
-                <input type="text" id="sitename" name="sitename" />
-                <p class="form_guide">The name of your site</p>
-            </li>
-            <li>
-                <label for="fancy-enable">Fancy URLs</label>
-                <input type="radio" name="fancy" id="fancy-enable" value="enable" checked='checked' /> enable<br />
-                <input type="radio" name="fancy" id="fancy-disable" value="" /> disable<br />
-                <p class="form_guide" id='fancy-form_guide'>Enable fancy (pretty) URLs. Auto-detection failed, it depends on Javascript.</p>
-            </li>
-            <li>
-                <label for="host">Hostname</label>
-                <input type="text" id="host" name="host" />
-                <p class="form_guide">Database hostname</p>
-            </li>
-            <li>
-
-                <label for="dbtype">Type</label>
-                $dbRadios
-                <p class="form_guide">Database type</p>
-            </li>
-
-            <li>
-                <label for="database">Name</label>
-                <input type="text" id="database" name="database" />
-                <p class="form_guide">Database name</p>
-            </li>
-            <li>
-                <label for="username">Username</label>
-                <input type="text" id="username" name="username" />
-                <p class="form_guide">Database username</p>
-            </li>
-            <li>
-                <label for="password">Password</label>
-                <input type="password" id="password" name="password" />
-                <p class="form_guide">Database password (optional)</p>
-            </li>
-        </ul>
+        <fieldset id="settings_site">
+            <legend>Site settings</legend>
+            <ul class="form_data">
+                <li>
+                    <label for="sitename">Site name</label>
+                    <input type="text" id="sitename" name="sitename" value="{$post->value('sitename')}" />
+                    <p class="form_guide">The name of your site</p>
+                </li>
+                <li>
+                    <label for="fancy-enable">Fancy URLs</label>
+                    <input type="radio" name="fancy" id="fancy-enable" value="enable" checked='checked' /> enable<br />
+                    <input type="radio" name="fancy" id="fancy-disable" value="" /> disable<br />
+                    <p class="form_guide" id='fancy-form_guide'>Enable fancy (pretty) URLs. Auto-detection failed, it depends on Javascript.</p>
+                </li>
+            </ul>
+        </fieldset>
+
+        <fieldset id="settings_db">
+            <legend>Database settings</legend>
+            <ul class="form_data">
+                <li>
+                    <label for="host">Hostname</label>
+                    <input type="text" id="host" name="host" value="{$post->value('host')}" />
+                    <p class="form_guide">Database hostname</p>
+                </li>
+                <li>
+                    <label for="dbtype">Type</label>
+                    $dbRadios
+                    <p class="form_guide">Database type</p>
+                </li>
+                <li>
+                    <label for="database">Name</label>
+                    <input type="text" id="database" name="database" value="{$post->value('database')}" />
+                    <p class="form_guide">Database name</p>
+                </li>
+                <li>
+                    <label for="dbusername">DB username</label>
+                    <input type="text" id="dbusername" name="dbusername" value="{$post->value('dbusername')}" />
+                    <p class="form_guide">Database username</p>
+                </li>
+                <li>
+                    <label for="dbpassword">DB password</label>
+                    <input type="password" id="dbpassword" name="dbpassword" value="{$post->value('dbpassword')}" />
+                    <p class="form_guide">Database password (optional)</p>
+                </li>
+            </ul>
+        </fieldset>
+
+        <fieldset id="settings_admin">
+            <legend>Administrator settings</legend>
+            <ul class="form_data">
+                <li>
+                    <label for="admin_nickname">Administrator nickname</label>
+                    <input type="text" id="admin_nickname" name="admin_nickname" value="{$post->value('admin_nickname')}" />
+                    <p class="form_guide">Nickname for the initial StatusNet user (administrator)</p>
+                </li>
+                <li>
+                    <label for="admin_password">Administrator password</label>
+                    <input type="password" id="admin_password" name="admin_password" value="{$post->value('admin_password')}" />
+                    <p class="form_guide">Password for the initial StatusNet user (administrator)</p>
+                </li>
+                <li>
+                    <label for="admin_password2">Confirm password</label>
+                    <input type="password" id="admin_password2" name="admin_password2" value="{$post->value('admin_password2')}" />
+                </li>
+                <li>
+                    <label for="admin_email">Administrator e-mail</label>
+                    <input id="admin_email" name="admin_email" value="{$post->value('admin_email')}" />
+                    <p class="form_guide">Optional email address for the initial StatusNet user (administrator)</p>
+                </li>
+            </ul>
+        </fieldset>
         <input type="submit" name="submit" class="submit" value="Submit" />
     </fieldset>
 </form>
@@ -502,10 +578,16 @@ function handlePost()
     $host     = $_POST['host'];
     $dbtype   = $_POST['dbtype'];
     $database = $_POST['database'];
-    $username = $_POST['username'];
-    $password = $_POST['password'];
+    $username = $_POST['dbusername'];
+    $password = $_POST['dbpassword'];
     $sitename = $_POST['sitename'];
     $fancy    = !empty($_POST['fancy']);
+
+    $adminNick = $_POST['admin_nickname'];
+    $adminPass = $_POST['admin_password'];
+    $adminPass2 = $_POST['admin_password2'];
+    $adminEmail = $_POST['admin_email'];
+
     $server = $_SERVER['HTTP_HOST'];
     $path = substr(dirname($_SERVER['PHP_SELF']), 1);
 
@@ -537,6 +619,21 @@ STR;
         $fail = true;
     }
 
+    if (empty($adminNick)) {
+        updateStatus("No initial StatusNet user nickname specified.", true);
+        $fail = true;
+    }
+
+    if (empty($adminPass)) {
+        updateStatus("No initial StatusNet user password specified.", true);
+        $fail = true;
+    }
+    
+    if ($adminPass != $adminPass2) {
+        updateStatus("Administrator passwords do not match. Did you mistype?", true);
+        $fail = true;
+    }
+
     if ($fail) {
         showForm();
         return;
@@ -559,13 +656,29 @@ STR;
         return;
     }
 
+    // Okay, cross fingers and try to register an initial user
+    if (registerInitialUser($adminNick, $adminPass, $adminEmail)) {
+        updateStatus(
+            "An initial user with the administrator role has been created."
+        );
+    } else {
+        updateStatus(
+            "Could not create initial StatusNet user (administrator).",
+            true
+        );
+        showForm();
+        return;
+    }
+
     /*
         TODO https needs to be considered
     */
     $link = "http://".$server.'/'.$path;
 
     updateStatus("StatusNet has been installed at $link");
-    updateStatus("You can visit your <a href='$link'>new StatusNet site</a>.");
+    updateStatus(
+        "<strong>DONE!</strong> You can visit your <a href='$link'>new StatusNet site</a> (login as '$adminNick'). If this is your first StatusNet install, you may want to poke around our <a href='http://status.net/wiki/Getting_started'>Getting Started guide</a>."
+    );
 }
 
 function Pgsql_Db_installer($host, $database, $username, $password)
@@ -691,9 +804,7 @@ function writeConf($sitename, $server, $path, $fancy, $db)
             // database
             "\$config['db']['database'] = '{$db['database']}';\n\n".
             ($db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":'').
-            "\$config['db']['type'] = '{$db['type']}';\n\n".
-
-            "?>";
+            "\$config['db']['type'] = '{$db['type']}';\n\n";
     // write configuration file out to install directory
     $res = file_put_contents(INSTALLDIR.'/config.php', $cfg);
 
@@ -743,6 +854,47 @@ function runDbScript($filename, $conn, $type = 'mysqli')
     return true;
 }
 
+function registerInitialUser($nickname, $password, $email)
+{
+    define('STATUSNET', true);
+    define('LACONICA', true); // compatibility
+
+    require_once INSTALLDIR . '/lib/common.php';
+
+    $data = array('nickname' => $nickname,
+                  'password' => $password,
+                  'fullname' => $nickname);
+    if ($email) {
+        $data['email'] = $email;
+    }
+    $user = User::register($data);
+
+    if (empty($user)) {
+        return false;
+    }
+
+    // give initial user carte blanche
+
+    $user->grantRole('owner');
+    $user->grantRole('moderator');
+    $user->grantRole('administrator');
+    
+    // Attempt to do a remote subscribe to update@status.net
+    // Will fail if instance is on a private network.
+
+    if (class_exists('Ostatus_profile')) {
+        try {
+            $oprofile = Ostatus_profile::ensureProfile('http://update.status.net/');
+            Subscription::start($user->getProfile(), $oprofile->localProfile());
+            updateStatus("Set up subscription to <a href='http://update.status.net/'>update@status.net</a>.");
+        } catch (Exception $e) {
+            updateStatus("Could not set up subscription to <a href='http://update.status.net/'>update@status.net</a>.");
+        }
+    }
+
+    return true;
+}
+
 ?>
 <?php echo"<?"; ?> xml version="1.0" encoding="UTF-8" <?php echo "?>"; ?>
 <!DOCTYPE html
@@ -752,10 +904,10 @@ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     <head>
         <title>Install StatusNet</title>
        <link rel="shortcut icon" href="favicon.ico"/>
-        <link rel="stylesheet" type="text/css" href="theme/default/css/display.css?version=0.8" media="screen, projection, tv"/>
-        <!--[if IE]><link rel="stylesheet" type="text/css" href="theme/base/css/ie.css?version=0.8" /><![endif]-->
-        <!--[if lte IE 6]><link rel="stylesheet" type="text/css" theme/base/css/ie6.css?version=0.8" /><![endif]-->
-        <!--[if IE]><link rel="stylesheet" type="text/css" href="theme/default/css/ie.css?version=0.8" /><![endif]-->
+        <link rel="stylesheet" type="text/css" href="theme/default/css/display.css" media="screen, projection, tv"/>
+        <!--[if IE]><link rel="stylesheet" type="text/css" href="theme/base/css/ie.css" /><![endif]-->
+        <!--[if lte IE 6]><link rel="stylesheet" type="text/css" theme/base/css/ie6.css" /><![endif]-->
+        <!--[if IE]><link rel="stylesheet" type="text/css" href="theme/default/css/ie.css" /><![endif]-->
         <script src="js/jquery.min.js"></script>
         <script src="js/install.js"></script>
     </head>
@@ -771,8 +923,10 @@ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
             </div>
             <div id="core">
                 <div id="content">
-                    <h1>Install StatusNet</h1>
+                     <div id="content_inner">
+                        <h1>Install StatusNet</h1>
 <?php main(); ?>
+                   </div>
                 </div>
             </div>
         </div>