3 /* Reminder: always indent with 4 spaces (no tabs). */
4 // +---------------------------------------------------------------------------+
6 // +---------------------------------------------------------------------------+
9 // | Additional functions for install script. |
10 // +---------------------------------------------------------------------------+
11 // | Copyright (C) 2008-2009 by the following authors: |
13 // | Authors: Matt West - matt.danger.west AT gmail DOT com |
14 // | Dirk Haun - dirk AT haun-online DOT de |
15 // +---------------------------------------------------------------------------+
17 // | This program is free software; you can redistribute it and/or |
18 // | modify it under the terms of the GNU General Public License |
19 // | as published by the Free Software Foundation; either version 2 |
20 // | of the License, or (at your option) any later version. |
22 // | This program is distributed in the hope that it will be useful, |
23 // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
24 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
25 // | GNU General Public License for more details. |
27 // | You should have received a copy of the GNU General Public License |
28 // | along with this program; if not, write to the Free Software Foundation, |
29 // | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
31 // +---------------------------------------------------------------------------+
34 * The functionality of many of these functions already exists in other
35 * Geeklog libraries. However, during the first few stages of the
36 * installation either those libraries cannot be accessed or dependency
37 * libraries cannot be accessed.
40 if (strpos(strtolower($_SERVER['PHP_SELF']), 'lib-install.php') !== false) {
41 die('This file can not be used on its own!');
44 // this should help expose parse errors even when
45 // display_errors is set to Off in php.ini
46 if (function_exists('ini_set')) {
47 ini_set('display_errors', '1');
49 error_reporting(E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR | E_NOTICE);
54 if (!defined('VERSION')) {
56 * This constant defines Geeklog's version number. It will be written to
57 * siteconfig.php and the database (in the latter case minus any suffix).
59 define('VERSION', '1.6.1rc1');
61 if (!defined('XHTML')) {
62 define('XHTML', ' /');
64 if (!defined('SUPPORTED_PHP_VER')) {
65 define('SUPPORTED_PHP_VER', '4.3.0');
67 if (!defined('SUPPORTED_MYSQL_VER')) {
68 define('SUPPORTED_MYSQL_VER', '3.23.2');
71 $_REQUEST = array_merge($_GET, $_POST);
73 if (empty($LANG_DIRECTION)) {
74 $LANG_DIRECTION = 'ltr';
76 if ($LANG_DIRECTION == 'rtl') {
77 $form_label_dir = 'form-label-right';
78 $perms_label_dir = 'perms-label-right';
80 $form_label_dir = 'form-label-left';
81 $perms_label_dir = 'perms-label-left';
84 $language = INST_getLanguage();
85 // Include the language file
86 require_once 'language/' . $language . '.php';
88 // Before we begin, check if an uploaded file exceeds PHP's post_max_size
89 if (isset($_SERVER['CONTENT_LENGTH'])) {
91 // This code is thanks to v3 AT sonic-world DOT ru via PHP.net
92 $POST_MAX_SIZE = ini_get('post_max_size');
93 $mul = substr($POST_MAX_SIZE, -1);
102 if (($_SERVER['CONTENT_LENGTH'] > ($mul*((int)$POST_MAX_SIZE))) && $POST_MAX_SIZE) {
104 // If it does, display an error message
105 $display = INST_getHeader($LANG_ERROR[8])
106 . INST_getAlertMsg($LANG_ERROR[7])
116 // +---------------------------------------------------------------------------+
118 // +---------------------------------------------------------------------------+
121 * Returns the beginning HTML for the installer theme.
123 * @param $mHeading Heading
124 * @return string Header HTML code
127 function INST_getHeader($mHeading)
129 global $LANG_CHARSET, $LANG_INSTALL, $LANG_DIRECTION;
131 return (defined('XHTML')
132 ? '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
133 . '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'
134 : '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'
137 <meta http-equiv="Content-Type" content="text/html;charset=' . $LANG_CHARSET . '"' . XHTML . '>
138 <meta name="robots" content="noindex,nofollow"' . XHTML . '>
139 <meta http-equiv="Cache-Control" content="no-cache/"/>
140 <meta http-equiv="Pragma" content="no-cache"/>
141 <meta http-equiv="Expires" content="-1"/>
142 <link rel="stylesheet" type="text/css" href="layout/style.css"' . XHTML . '>
143 <script language="javascript" type="text/javascript">
144 function INST_selectMigrationType()
146 var myType = document.migrate.migration_type.value;
147 var migrationSelect = document.getElementById("migration-select");
148 var migrationUpload = document.getElementById("migration-upload");
149 var migrationUploadWarning = document.getElementById("migration-upload-warning");
153 migrationSelect.style.display = "inline";
154 migrationUpload.style.display = "none";
155 migrationUploadWarning.style.display = "none";
158 migrationSelect.style.display = "none";
159 migrationUpload.style.display = "inline";
160 migrationUploadWarning.style.display = "block";
163 migrationSelect.style.display = "none";
164 migrationUpload.style.display = "none";
165 migrationUploadWarning.style.display = "none";
169 <title>' . $LANG_INSTALL[0] . '</title>
172 <body dir="' . $LANG_DIRECTION . '">
173 <div class="header-navigation-container">
174 <div class="header-navigation-line">
175 <a href="' . $LANG_INSTALL[87] . '" class="header-navigation">' . $LANG_INSTALL[1] . '</a>
178 <div class="header-logobg-container-inner">
179 <a class="header-logo" href="http://www.geeklog.net/">
180 <img src="layout/logo.png" width="151" height="56" alt="Geeklog"' . XHTML . '>
182 <div class="header-slogan">' . $LANG_INSTALL[2] . ' <br' . XHTML . '><br' . XHTML . '>
185 <div class="installation-container">
186 <div class="installation-body-container">
187 <h1 class="heading">' . $mHeading . '</h1>' . LB;
192 * Returns the ending HTML for the installer theme.
194 * @return string Footer HTML code
197 function INST_getFooter()
199 return '<br' . XHTML . '><br' . XHTML . '>' . LB
207 * Returns the PHP version
209 * Note: Removes appendices like 'rc1', etc.
211 * @return array the 3 separate parts of the PHP version number
216 $phpv = explode('.', phpversion());
218 return array($phpv[0], $phpv[1], (int) $phpv[2]);
222 * Check if the user's PHP version is supported by Geeklog
224 * @return bool True if supported, falsed if not supported
227 function INST_phpOutOfDate()
229 $minv = explode('.', SUPPORTED_PHP_VER);
232 if (($phpv[0] < $minv[0]) ||
233 (($phpv[0] == $minv[0]) && ($phpv[1] < $minv[1])) ||
234 (($phpv[0] == $minv[0]) && ($phpv[1] == $minv[1]) && ($phpv[2] < $minv[2]))) {
242 * Returns the MySQL version
244 * @return mixed array[0..2] of the parts of the version number or false
247 function mysql_v($_DB_host, $_DB_user, $_DB_pass)
249 $db_handle = @mysql_connect($_DB_host, $_DB_user, $_DB_pass);
250 if ($db_handle === false) {
254 $mysqlv = @mysql_get_server_info($db_handle);
256 if (!empty($mysqlv)) {
257 preg_match('/^([0-9]+).([0-9]+).([0-9]+)/', $mysqlv, $match);
258 $mysqlmajorv = $match[1];
259 $mysqlminorv = $match[2];
260 $mysqlrev = $match[3];
266 @mysql_close($db_handle);
268 return array($mysqlmajorv, $mysqlminorv, $mysqlrev);
272 * Check if the user's MySQL version is supported by Geeklog
274 * @param array $db Database information
275 * @return bool True if supported, falsed if not supported
278 function INST_mysqlOutOfDate($db)
280 $minv = explode('.', SUPPORTED_MYSQL_VER);
282 if ($db['type'] == 'mysql' || $db['type'] == 'mysql-innodb') {
283 $myv = mysql_v($db['host'], $db['user'], $db['pass']);
285 if (($myv[0] < $minv[0]) ||
286 (($myv[0] == $minv[0]) && ($myv[1] < $minv[1])) ||
287 (($myv[0] == $minv[0]) && ($myv[1] == $minv[1]) && ($myv[2] < $minv[2]))) {
297 * Written to aid in install script development
299 * NOTE: This code is a modified copy from PHP.net
301 * @param int $size Filesize
302 * @param int $dec_places Number of decimal places
303 * @return string Filesize string
306 function INST_formatSize($size, $dec_places = 0)
308 $sizes = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
309 for ($i=0; ($size > 1024 && isset($sizes[$i+1])) ; $i++) {
312 return round($size, $dec_places) . " " . $sizes[$i];
316 * Provide a link to the help page for an option
318 * @param string $var key of the label, used as an anchor on the help page
319 * @return string HTML for the link
322 function INST_helpLink($var)
326 return '(<a href="help.php?language=' . $language . '&label=' . $var
327 . '#' . $var . '" target="_blank">?</a>)';
331 * Make a nice display name from the language filename
333 * NOTE: This code is a straight copy from MBYTE_languageList()
335 * @param string $file filename without the extension
336 * @return string language name to display to the user
339 function INST_prettifyLanguageName($filename)
341 $langfile = str_replace('_utf-8', '', $filename);
342 $uscore = strpos($langfile, '_');
343 if ($uscore === false) {
344 $lngname = ucfirst($langfile);
346 $lngname = ucfirst(substr($langfile, 0, $uscore));
347 $lngadd = substr($langfile, $uscore + 1);
348 $lngadd = str_replace('utf-8', '', $lngadd);
349 $lngadd = str_replace('_', ', ', $lngadd);
350 $word = explode(' ', $lngadd);
352 foreach ($word as $w) {
353 if (preg_match('/[0-9]+/', $w)) {
354 $lngadd .= strtoupper($w) . ' ';
356 $lngadd .= ucfirst($w) . ' ';
359 $lngname .= ' (' . trim($lngadd) . ')';
366 * Modify db-config.php
368 * @param string $config_file Full path to db-config.php
369 * @param array $db Database information to save
370 * @return bool True if successful, false if not
373 function INST_writeConfig($config_file, $db)
375 // we may have included db-config.php elsewhere already, in which case
376 // all of these variables need to be imported from the global namespace
377 global $_DB_host, $_DB_name, $_DB_user, $_DB_pass, $_DB_table_prefix,
380 require_once $config_file; // Grab the current DB values
382 $db = array('host' => (isset($db['host']) ? $db['host'] : $_DB_host),
383 'name' => (isset($db['name']) ? $db['name'] : $_DB_name),
384 'user' => (isset($db['user']) ? $db['user'] : $_DB_user),
385 'pass' => (isset($db['pass']) ? $db['pass'] : $_DB_pass),
386 'table_prefix' => (isset($db['table_prefix']) ? $db['table_prefix'] : $_DB_table_prefix),
387 'type' => (isset($db['type']) ? $db['type'] : $_DB_dbms) );
388 if ($db['type'] == 'mysql-innodb') {
389 $db['type'] = 'mysql';
392 // Read in db-config.php so we can insert the DB information
393 $dbconfig_file = fopen($config_file, 'rb');
394 $dbconfig_data = fread($dbconfig_file, filesize($config_file));
395 fclose($dbconfig_file);
397 // Replace the values with the new ones
398 $dbconfig_data = str_replace("\$_DB_host = '" . $_DB_host . "';", "\$_DB_host = '" . $db['host'] . "';", $dbconfig_data); // Host
399 $dbconfig_data = str_replace("\$_DB_name = '" . $_DB_name . "';", "\$_DB_name = '" . $db['name'] . "';", $dbconfig_data); // Database
400 $dbconfig_data = str_replace("\$_DB_user = '" . $_DB_user . "';", "\$_DB_user = '" . $db['user'] . "';", $dbconfig_data); // Username
401 $dbconfig_data = str_replace("\$_DB_pass = '" . $_DB_pass . "';", "\$_DB_pass = '" . $db['pass'] . "';", $dbconfig_data); // Password
402 $dbconfig_data = str_replace("\$_DB_table_prefix = '" . $_DB_table_prefix . "';", "\$_DB_table_prefix = '" . $db['table_prefix'] . "';", $dbconfig_data); // Table prefix
403 $dbconfig_data = str_replace("\$_DB_dbms = '" . $_DB_dbms . "';", "\$_DB_dbms = '" . $db['type'] . "';", $dbconfig_data); // Database type ('mysql' or 'mssql')
405 // Write our changes to db-config.php
406 $dbconfig_file = fopen($config_file, 'wb');
407 if (!fwrite($dbconfig_file, $dbconfig_data)) {
410 fclose($dbconfig_file);
415 * Check if a table exists
416 * @see DB_checkTableExists
419 * @param string $table Table name
420 * @return boolean True if table exists, false if it does not
423 function INST_checkTableExists($table)
425 return DB_checkTableExists($table);
429 * Can the install script connect to the database?
431 * @param array $db Database information
432 * @return mixed Returns the DB handle if true, false if not
435 function INST_dbConnect($db)
437 if (empty($db['pass'])) {
441 switch ($db['type']) {
443 // deliberate fallthrough - no "break"
445 if ($db_handle = @mysql_connect($db['host'], $db['user'], $db['pass'])) {
450 if ($db_handle = @mssql_connect($db['host'], $db['user'], $db['pass'])) {
459 * Check if a Geeklog database exists
461 * @param array $db Array containing connection info
462 * @return bool True if a database exists, false if not
465 function INST_dbExists($db)
467 $db_handle = INST_dbConnect($db);
469 switch ($db['type']) {
471 // deliberate fallthrough - no "break"
473 if (@mysql_select_db($db['name'], $db_handle)) {
478 if (@mssql_select_db($db['name'], $db_handle)) {
487 * Check if URL exists
489 * NOTE: This code is a modified copy from marufit at gmail dot com
491 * @param string $url URL
492 * @return bool True if URL exists, false if not
495 function INST_urlExists($url)
498 $handle = curl_init($url);
499 if ($handle === false) {
502 curl_setopt($handle, CURLOPT_HEADER, false);
503 curl_setopt($handle, CURLOPT_FAILONERROR, true); // this works
504 curl_setopt($handle, CURLOPT_NOBODY, true);
505 curl_setopt($handle, CURLOPT_RETURNTRANSFER, false);
506 $response = curl_exec($handle);
514 * Check if an error occured while uploading a file
516 * @param array $mFile $_FILE['uploaded_file']
517 * @return mixed Returns the error string if an error occured,
518 * returns false if no error occured
521 function INST_getUploadError($mFile)
527 UPLOAD_ERR_INI_SIZE => $LANG_ERROR[0],
528 UPLOAD_ERR_FORM_SIZE => $LANG_ERROR[1],
529 UPLOAD_ERR_PARTIAL => $LANG_ERROR[2],
530 UPLOAD_ERR_NO_FILE => $LANG_ERROR[3],
531 UPLOAD_ERR_NO_TMP_DIR => $LANG_ERROR[4],
532 UPLOAD_ERR_CANT_WRITE => $LANG_ERROR[5],
533 UPLOAD_ERR_EXTENSION => $LANG_ERROR[6]);
535 if ($mFile['error'] !== UPLOAD_ERR_OK) { // If an error occured while uploading the file.
537 if ($mFile['error'] > count($mErrors)) { // If the error code isn't listed in $mErrors
539 $mRetval = 'An unknown error occured'; // Unknown error
543 $mRetval = $mErrors[$mFile['error']]; // Print the error
547 } else { // If no upload error occurred
557 * Check which plugins are actually installed and disable them if needed
559 * @return int number of plugins that were disabled
562 function INST_checkPlugins()
564 global $_CONF, $_TABLES;
567 $plugin_path = $_CONF['path'] . 'plugins/';
569 $result = DB_query("SELECT pi_name FROM {$_TABLES['plugins']} WHERE pi_enabled = 1");
570 $num_plugins = DB_numRows($result);
571 for ($i = 0; $i < $num_plugins; $i++) {
572 $A = DB_fetchArray($result);
573 if (!file_exists($plugin_path . $A['pi_name'] . '/functions.inc')) {
574 DB_query("UPDATE {$_TABLES['plugins']} SET pi_enabled = 0 WHERE pi_name = '{$A['pi_name']}'");
583 * Nicely formats the alert messages
585 * @param $mMessage Message string
586 * @param $mType 'error', 'warning', 'success', or 'notice'
587 * @return string HTML formatted dialog message
590 function INST_getAlertMsg($mMessage, $mType = 'notice')
592 global $LANG_INSTALL;
594 $mStyle = ($mType == 'success') ? 'success' : 'error';
596 switch (strtolower($mType)) {
598 $mType = $LANG_INSTALL[38]; break;
600 $mType = $LANG_INSTALL[20]; break;
602 $mType = $LANG_INSTALL[93]; break;
604 $mType = $LANG_INSTALL[59]; break;
607 return '<div class="notice"><span class="' . $mStyle . '">' . $mType .':</span> '
608 . $mMessage . '</div>' . LB;
613 * Check if we can skip upgrade steps (post-1.5.0)
615 * If we're doing an upgrade from 1.5.0 or later and we have the necessary
616 * DB credentials, skip the forms and upgrade directly.
618 * NOTE: Will not return if upgrading from 1.5.0 or later.
620 * @param string $dbconfig_path path to db-config.php
621 * @param string $siteconfig_path path to siteconfig.php
622 * @return string database version, if possible
625 function INST_checkPost150Upgrade($dbconfig_path, $siteconfig_path)
627 global $_CONF, $_TABLES, $_DB, $_DB_dbms, $_DB_host, $_DB_user, $_DB_pass,
630 require $dbconfig_path;
631 require $siteconfig_path;
638 $db_handle = @mysql_connect($_DB_host, $_DB_user, $_DB_pass);
640 $connected = @mysql_select_db($_DB_name, $db_handle);
645 $db_handle = @mssql_connect($_DB_host, $_DB_user, $_DB_pass);
647 $connected = @mssql_select_db($_DB_name, $db_handle);
657 require $_CONF['path_system'] . 'lib-database.php';
659 $version = INST_identifyGeeklogVersion();
663 @mysql_close($db_handle);
667 @mssql_close($db_handle);
671 if (!empty($version) && ($version != VERSION) &&
672 (version_compare($version, '1.5.0') >= 0)) {
674 // current version is at least 1.5.0, so upgrade directly
675 $req_string = 'index.php?mode=upgrade&step=3'
676 . '&dbconfig_path=' . $dbconfig_path
677 . '&language=' . $language
678 . '&version=' . $version;
680 header('Location: ' . $req_string);
690 * Get information about a plugin
692 * Only works for plugins that have a autoinstall.php file
694 * @param string $plugin plugin's directory name
695 * @return mixed array of plugin info or false: error
698 function INST_getPluginInfo($plugin)
700 global $_CONF, $_TABLES, $_DB_dbms, $_DB_table_prefix;
704 $autoinstall = $_CONF['path'] . 'plugins/' . $plugin . '/autoinstall.php';
705 if (! file_exists($autoinstall)) {
709 include $autoinstall;
711 $fn = 'plugin_autoinstall_' . $plugin;
712 if (function_exists($fn)) {
713 $inst_info = $fn($plugin);
714 if (isset($inst_info['info']) &&
715 !empty($inst_info['info']['pi_name'])) {
716 $info = $inst_info['info'];
724 * Do the actual plugin auto install
726 * @param string $plugin Plugin name
727 * @param array $inst_parm Installation parameters for the plugin
728 * @param boolean $verbose true: enable verbose logging
729 * @return boolean true on success, false otherwise
732 function INST_pluginAutoinstall($plugin, $inst_parms, $verbose = true)
734 global $_CONF, $_TABLES, $_USER, $_DB_dbms, $_DB_table_prefix;
737 if (!isset($_USER['uid'])) {
742 $base_path = $_CONF['path'] . 'plugins/' . $plugin . '/';
745 COM_errorLog("Attempting to install the '$plugin' plugin", 1);
748 // sanity checks for $inst_parms
749 if (isset($inst_parms['info'])) {
750 $pi_name = $inst_parms['info']['pi_name'];
751 $pi_version = $inst_parms['info']['pi_version'];
752 $pi_gl_version = $inst_parms['info']['pi_gl_version'];
753 $pi_homepage = $inst_parms['info']['pi_homepage'];
755 if (empty($pi_name) || ($pi_name != $plugin) || empty($pi_version) ||
756 empty($pi_gl_version) || empty($pi_homepage)) {
757 COM_errorLog('Incomplete plugin info', 1);
762 // add plugin tables, if any
763 if (! empty($inst_parms['tables'])) {
764 $tables = $inst_parms['tables'];
765 foreach ($tables as $table) {
766 $_TABLES[$table] = $_DB_table_prefix . $table;
770 // Create the plugin's group(s), if any
773 if (! empty($inst_parms['groups'])) {
774 $groups = $inst_parms['groups'];
775 foreach ($groups as $name => $desc) {
777 COM_errorLog("Attempting to create '$name' group", 1);
780 $grp_name = addslashes($name);
781 $grp_desc = addslashes($desc);
782 DB_query("INSERT INTO {$_TABLES['groups']} (grp_name, grp_descr) VALUES ('$grp_name', '$grp_desc')", 1);
784 COM_errorLog('Error creating plugin group', 1);
785 PLG_uninstall($plugin);
790 // keep the new group's ID for use in the mappings section (below)
791 $groups[$name] = DB_insertId();
793 // assume that the first group is the plugin's Admin group
794 if ($admin_group_id == 0) {
795 $admin_group_id = $groups[$name];
800 // Create the plugin's table(s)
802 $DEFVALUES = array();
803 if (file_exists($base_path . 'sql/' . $_DB_dbms . '_install.php')) {
804 require_once $base_path . 'sql/' . $_DB_dbms . '_install.php';
807 if (count($_SQL) > 0) {
809 if (($_DB_dbms == 'mysql') &&
810 (DB_getItem($_TABLES['vars'], 'value', "name = 'database_engine'")
815 foreach ($_SQL as $sql) {
816 $sql = str_replace('#group#', $admin_group_id, $sql);
818 $sql = str_replace('MyISAM', 'InnoDB', $sql);
822 COM_errorLog('Error creating plugin table', 1);
823 PLG_uninstall($plugin);
830 // Add the plugin's features
832 COM_errorLog("Attempting to add '$plugin' features", 1);
837 if (!empty($inst_parms['features'])) {
838 $features = $inst_parms['features'];
839 if (!empty($inst_parms['mappings'])) {
840 $mappings = $inst_parms['mappings'];
843 foreach ($features as $feature => $desc) {
844 $ft_name = addslashes($feature);
845 $ft_desc = addslashes($desc);
846 DB_query("INSERT INTO {$_TABLES['features']} (ft_name, ft_descr) "
847 . "VALUES ('$ft_name', '$ft_desc')", 1);
849 COM_errorLog('Error adding plugin feature', 1);
850 PLG_uninstall($plugin);
855 $feat_id = DB_insertId();
857 if (isset($mappings[$feature])) {
858 foreach ($mappings[$feature] as $group) {
860 COM_errorLog("Adding '$feature' feature to the '$group' group", 1);
863 DB_query("INSERT INTO {$_TABLES['access']} (acc_ft_id, acc_grp_id) VALUES ($feat_id, {$groups[$group]})");
865 COM_errorLog('Error mapping plugin feature', 1);
866 PLG_uninstall($plugin);
875 // Add plugin's Admin group to the Root user group
876 // (assumes that the Root group's ID is always 1)
877 if (count($groups) > 0) {
879 COM_errorLog("Attempting to give all users in the Root group access to the '$plugin' Admin group", 1);
882 foreach ($groups as $key => $value) {
883 DB_query("INSERT INTO {$_TABLES['group_assignments']} VALUES "
884 . "($admin_group_id, NULL, 1)");
886 COM_errorLog('Error adding plugin admin group to Root group', 1);
887 PLG_uninstall($plugin);
894 // Pre-populate tables or run any other SQL queries
895 if (count($DEFVALUES) > 0) {
897 COM_errorLog('Inserting default data', 1);
899 foreach ($DEFVALUES as $sql) {
900 $sql = str_replace('#group#', $admin_group_id, $sql);
903 COM_errorLog('Error adding plugin default data', 1);
904 PLG_uninstall($plugin);
911 // Load the online configuration records
912 $load_config = 'plugin_load_configuration_' . $plugin;
913 if (function_exists($load_config)) {
914 if (! $load_config($plugin)) {
915 COM_errorLog('Error loading plugin configuration', 1);
916 PLG_uninstall($plugin);
921 require_once $_CONF['path'] . 'system/classes/config.class.php';
922 $config =& config::get_instance();
923 $config->initConfig(); // force re-reading, including new plugin conf
926 // Finally, register the plugin with Geeklog
928 COM_errorLog("Registering '$plugin' plugin", 1);
931 // silently delete an existing entry
932 DB_delete($_TABLES['plugins'], 'pi_name', $plugin);
934 DB_query("INSERT INTO {$_TABLES['plugins']} (pi_name, pi_version, pi_gl_version, pi_homepage, pi_enabled) VALUES "
935 . "('$plugin', '$pi_version', '$pi_gl_version', '$pi_homepage', 1)");
938 COM_errorLog('Failed to register plugin', 1);
939 PLG_uninstall($plugin);
944 // give the plugin a chance to perform any post-install operations
945 $post_install = 'plugin_postinstall_' . $plugin;
946 if (function_exists($post_install)) {
947 if (! $post_install($plugin)) {
948 COM_errorLog('Plugin postinstall failed', 1);
949 PLG_uninstall($plugin);
956 COM_errorLog("Successfully installed the '$plugin' plugin!", 1);
960 unset($_USER['uid']);
968 * Do a sanity check on the paths and URLs
970 * This is somewhat speculative but should provide the user with a working
971 * site even if, for example, a site backup was installed elsewhere.
973 * @param string $path proper /path/to/Geeklog
974 * @param string $path_html path to public_html
975 * @param string $site_url The site's URL
976 * @param string $site_admin_url URL to the admin directory
979 function INST_fixPathsAndUrls($path, $path_html, $site_url, $site_admin_url)
981 // no "global $_CONF" here!
983 require_once $path . 'system/classes/config.class.php';
985 $config = config::get_instance();
986 $config->set_configfile($path . 'db-config.php');
987 $config->load_baseconfig();
988 $config->initConfig();
989 $_CONF = $config->get_config('Core');
991 if (! file_exists($_CONF['path_log'] . 'error.log')) {
992 $config->set('path_log', $path . 'logs/');
994 if (! file_exists($_CONF['path_language'] . $_CONF['language'] . '.php')) {
995 $config->set('path_language', $path . 'language/');
997 if (! file_exists($_CONF['backup_path'])) {
998 $config->set('backup_path', $path . 'backups/');
1000 if (! file_exists($_CONF['path_data'])) {
1001 $config->set('path_data', $path . 'data/');
1003 if ((! $_CONF['have_pear']) &&
1004 (! file_exists($_CONF['path_pear'] . 'PEAR.php'))) {
1005 $config->set('path_pear', $path . 'system/pear/');
1008 if (! file_exists($_CONF['path_html'] . 'lib-common.php')) {
1009 $config->set('path_html', $path_html);
1011 if (! file_exists($_CONF['path_themes'] . $_CONF['theme']
1012 . '/header.thtml')) {
1013 $config->set('path_themes', $path_html . 'layout/');
1015 if (! file_exists($path_html . 'layout/' . $_CONF['theme']
1016 . '/header.thtml')) {
1017 $config->set('theme', 'professional');
1020 if (! file_exists($_CONF['path_images'] . 'articles')) {
1021 $config->set('path_images', $path_html . 'images/');
1023 if (substr($_CONF['rdf_file'], strlen($path_html)) != $path_html) {
1024 // this may not be correct but neither was the old value apparently ...
1025 $config->set('rdf_file', $path_html . 'backend/geeklog.rss');
1028 if (! empty($site_url) && ($_CONF['site_url'] != $site_url)) {
1029 $config->set('site_url', $site_url);
1031 // if we had to fix the site's URL, chances are that cookie domain
1032 // and path are also wrong and the user won't be able to log in
1033 $config->set('cookiedomain', '');
1034 $config->set('cookie_path', '/');
1036 if (! empty($site_admin_url) &&
1037 ($_CONF['site_admin_url'] != $site_admin_url)) {
1038 $config->set('site_admin_url', $site_admin_url);
1043 * Helper function: Derive 'path_html' from __FILE__
1046 function INST_getHtmlPath()
1048 $path = str_replace('\\', '/', __FILE__);
1049 $path = str_replace('//', '/', $path);
1050 $parts = explode('/', $path);
1051 $num_parts = count($parts);
1052 if (($num_parts < 3) || ($parts[$num_parts - 1] != 'lib-install.php')) {
1053 die('Fatal error - can not figure out my own path');
1056 return implode('/', array_slice($parts, 0, $num_parts - 3)) . '/';
1060 * Helper function: Derive path of the 'admin' directory from __FILE__
1063 function INST_getAdminPath()
1065 $path = str_replace('\\', '/', __FILE__);
1066 $path = str_replace('//', '/', $path);
1067 $parts = explode('/', $path);
1068 $num_parts = count($parts);
1069 if (($num_parts < 3) || ($parts[$num_parts - 1] != 'lib-install.php')) {
1070 die('Fatal error - can not figure out my own path');
1073 return implode('/', array_slice($parts, 0, $num_parts - 2)) . '/';
1077 * Helper function: Derive 'site_url' from PHP_SELF
1080 function INST_getSiteUrl()
1082 $url = str_replace('//', '/', $_SERVER['PHP_SELF']);
1083 $parts = explode('/', $url);
1084 $num_parts = count($parts);
1085 if (($num_parts < 3) || (substr($parts[$num_parts - 1], -4) != '.php')) {
1086 die('Fatal error - can not figure out my own URL');
1089 $url = implode('/', array_slice($parts, 0, $num_parts - 3));
1091 return 'http://' . $_SERVER['HTTP_HOST'] . $url;
1095 * Helper function: Derive 'site_admin_url' from PHP_SELF
1098 function INST_getSiteAdminUrl()
1100 $url = str_replace('//', '/', $_SERVER['PHP_SELF']);
1101 $parts = explode('/', $url);
1102 $num_parts = count($parts);
1103 if (($num_parts < 3) || (substr($parts[$num_parts - 1], -4) != '.php')) {
1104 die('Fatal error - can not figure out my own URL');
1107 $url = implode('/', array_slice($parts, 0, $num_parts - 2));
1109 return 'http://' . $_SERVER['HTTP_HOST'] . $url;
1113 * Get name of the install language file to use
1115 * @return string language file name (without the extension)
1118 function INST_getLanguage()
1120 $language = 'english';
1121 if (isset($_POST['language'])) {
1122 $lng = $_POST['language'];
1123 } elseif (isset($_GET['language'])) {
1124 $lng = $_GET['language'];
1125 } elseif (isset($_COOKIE['language'])) {
1126 // Okay, so the name of the language cookie is configurable, so it
1127 // may not be named 'language' after all. Still worth a try ...
1128 $lng = $_COOKIE['language'];
1133 // sanitize value and check for file
1134 $lng = preg_replace('/[^a-z0-9\-_]/', '', $lng);
1135 if (!empty($lng) && is_file('language/' . $lng . '.php')) {
1143 * Set Geeklog version number in siteconfig.php and in the database
1145 * @param string $siteconfig_path path to siteconfig.php
1149 function INST_setVersion($siteconfig_path)
1151 global $_TABLES, $LANG_INSTALL;
1153 $siteconfig_file = fopen($siteconfig_path, 'rb');
1154 $siteconfig_data = fread($siteconfig_file, filesize($siteconfig_path));
1155 fclose($siteconfig_file);
1157 $siteconfig_data = preg_replace
1159 '/define\s*\(\'VERSION\',[^;]*;/',
1160 "define('VERSION', '" . VERSION . "');",
1164 $siteconfig_file = @fopen($siteconfig_path, 'wb');
1165 if (! fwrite($siteconfig_file, $siteconfig_data)) {
1166 exit($LANG_INSTALL[26] . ' ' . $LANG_INSTALL[28]);
1168 fclose($siteconfig_file);
1170 // for the database version, get rid of any appendices ('sr1' etc.)
1172 $v = explode('.', VERSION);
1173 if (count($v) == 3) {
1174 $v[2] = (int) $v[2];
1175 $version = implode('.', $v);
1177 $version = addslashes($version);
1179 DB_change($_TABLES['vars'], 'value', $version, 'name', 'database_version');
1183 * Filter path value for junk and injections
1185 * @param string $path a path on the file system
1186 * @return string filtered path value
1189 function INST_sanitizePath($path)
1191 $path = strip_tags($path);
1192 $path = str_replace(array('"', "'"), '', $path);
1193 $path = str_replace('..', '', $path);