. // Copyright © 2007-2014 Erwan Briand // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, version 3 only. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public // License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . /** * @file * This file contains the base class of CodingTeam * * Retrieve the configuration file and connect to the database. * Set the language for gettext translations. * Start error, session and template classes. */ // PHP options ini_set('session.gc_probability', 0); ini_set('session.use_trans_sid', FALSE); ini_set('short_open_tag', TRUE); ini_set('docref_root', 'http://www.php.net/'); // Store $basedir in a constant define('CT_BASEDIR', $basedir); // Require all global functions require(dirname(__FILE__).'/../globalFunctions.php'); /** * CodingTeam class */ class CodingTeam { function __construct($basedir, $start_time) { // Check if the configuration file exist if (!file_exists(CT_BASEDIR.'/inc/codingteam.cfg')) die ('There are no configuration file. CodingTeam cannot start.'); // Check if the configuration file is well formed $xml = new DOMDocument(); $xml->load(CT_BASEDIR.'/inc/codingteam.cfg'); if (!$xml->schemaValidate(CT_BASEDIR.'/inc/codingteam-conf.xsd')) die ('The configuration file is not well formed. '. 'CodingTeam cannot start.'); // Import configuration $xml = simplexml_load_file(CT_BASEDIR.'/inc/codingteam.cfg'); // Define constants for SCMs define('CT_SVN_SUBDOMAIN', $xml->svn->subdomain); define('CT_SVN_LOCATION', $xml->svn->location); define('CT_HG_SUBDOMAIN', $xml->hg->subdomain); define('CT_HG_LOCATION', $xml->hg->location); define('CT_GIT_SUBDOMAIN', $xml->git->subdomain); define('CT_GIT_LOCATION', $xml->git->location); // Set default datetime timezone date_default_timezone_set($xml->config->timezone); // Get subdomain for mailing-lists define('CT_ML_DOMAIN', $xml->config->mldomain); // Change the protocol if using HTTPS if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') $url_prefix = 'https'; else $url_prefix = 'http'; // Set the base URL of CodingTeam define('CT_BASEURL', $url_prefix.'://'.$_SERVER['SERVER_NAME'].'/'); // Set the template theme (CSS) define('CT_TEMPLATE_THEME', $xml->config->theme); define('CT_TEMPLATE_COLORPALETTE', $xml->config->colorpalette); // Request URI datas $ct_get_uri = $_SERVER['REQUEST_URI']; $pagetag = explode('/', $ct_get_uri); // Remove empty data foreach ($pagetag as $key => $value) if (empty($value) || $value != 0) unset($pagetag[$key]); // Redirect if no request if (count($pagetag) == 0) { Header ('Status: 301 Moved Permanently', false, 301); Header ('Location: '.CT_BASEURL.'index'); exit(); } // List all available language $langlist = array('en'); $langdir = opendir(CT_BASEDIR.'/i18n/'); while ($cdl = readdir($langdir)) if (mb_substr($cdl, 0, 1) != '.') array_push($langlist, $cdl); // Get the language of the client and select it // This choice can be changed by user configuration if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { $accept_language = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); foreach ($accept_language as $value) { // Get the language code $choice = mb_substr($value, 0, 2); // Check if the language is in the list if (in_array($choice, $langlist)) { $lang = $choice; break; } } // No language found, use english (default) if (empty($lang)) $lang = 'en'; } else $lang = 'en'; // Force i18n global $shutdown_i18n; $shutdown_i18n = FALSE; // Get the locale for this language $locale = getClass('locales'); $countries = $locale->getCountries($lang); foreach ($countries as $country) if ($lcall = $locale->isSupported($lang.'_'.$country)) $visitor_locale = $lcall; // Change locale setlocale(LC_ALL, $visitor_locale); // Start Gettext support bindtextdomain('codingteam', CT_BASEDIR.'/i18n'); textdomain('codingteam'); bind_textdomain_codeset('codingteam', 'UTF-8'); // Error class require (CT_BASEDIR.'/inc/classes/error.php'); global $error; $error = new ErrorHandler($lang, (int)$xml->errors->show_debug, (int)$xml->errors->log_errors, (int)$xml->errors->log_level, (int)$xml->errors->show_notice, (int)$xml->errors->catch_fatal); // Handler function function ecatch($errno, $errstr, $errfile, $errline, $errcontext) { global $error; $error->displayError(array($errno, $errstr, $errfile, $errline, $errcontext), 3); return $errno; } // Fatal errors handler function function fatal_error_handler() { global $error; if ($fatalerror = error_get_last()) $error->displayError(array($fatalerror['type'], $fatalerror['message'], $fatalerror['file'], $fatalerror['line'], ''), 3); } // Start errors handler set_error_handler('ecatch', E_ALL | E_STRICT); // Catch PHP fatal errors if ((int)$xml->errors->catch_fatal) register_shutdown_function('fatal_error_handler'); // Test if locales are well configured on the server if (!$locale->isConfigured()) $error->displayError(i18n('Locales are not configured to make'. ' CodingTeam works on this server. You'. ' should enable a locale for english'. ' language. See your system'. ' documentation for more informations'. ' about this procedure.'), 2); // Class: Database layer require(CT_BASEDIR.'/inc/classes/db.php'); $ct_db = new Database($xml->db->type, $xml->db->hostname, $xml->db->database, $xml->db->username, $xml->db->password, $error); // Get the forge configuration require(CT_BASEDIR.'/inc/classes/config.php'); global $ct_dbconfig; $ct_dbconfig = Config::listkeys($ct_db); // Store the authentification type $auth_type = $xml->auth->method; define('CT_AUTHENTIFICATION_METHOD', $auth_type); // Select an authentification method if ($auth_type == 'sql') // Default method: the user need nickname/password to login require(CT_BASEDIR.'/inc/classes/session.sql.php'); elseif ($auth_type == 'xmpp') // The user need a connected XMPP account to login require(CT_BASEDIR.'/inc/classes/session.xmpp.php'); else die ('Authentification method is not supported.'); // Class: Session $ct_session = new Session($ct_db, $error); $ct_session->init($_SERVER['REMOTE_ADDR']); // Get the SESSION.lang if the user force a lang if (!empty($_SESSION['lang'])) if (in_array($_SESSION['lang'], $langlist)) $lang = $_SESSION['lang']; else $lang = 'en'; // Again, get the locale for this language $countries = $locale->getCountries($lang); foreach ($countries as $country) if ($lcall = $locale->isSupported($lang.'_'.$country)) $visitor_locale = $lcall; // Change locale another time (registered users can force it) setlocale(LC_ALL, $visitor_locale); // Send Language headers Header('Content-Language: '.$visitor_locale); // Hey, wait a minute, is this forge public? $cfg = new Config($ct_db); $force_login = $cfg->get('global', 'force-login'); if ($force_login && !$ct_session->isLogged()) { if ($auth_type == 'sql') { if (mb_substr($ct_get_uri, 0, 4) == '/rss' || mb_substr($ct_get_uri, 0, 5) == '/atom') { if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { $nick = $_SERVER['PHP_AUTH_USER']; $pass = $_SERVER['PHP_AUTH_PW']; $ct_session->login($nick, $pass, FALSE, '!feed!'); } else { Header('WWW-Authenticate: Basic realm="Feed"'); Header('HTTP/1.0 401 Unauthorized'); exit(); } } } if (!$ct_session->isLogged()) if ($ct_get_uri != '/users/register' && $ct_get_uri != '/users/password') $error->displayError(array(i18n('Please log in.'), $ct_session, $ct_db), -1, '401 Unauthorized'); } // Class: Template require(CT_BASEDIR.'/inc/classes/template.php'); $ct_view = new Template(CT_BASEDIR.'/inc/templates/main.tpl', $ct_get_uri, $ct_session, $ct_db, $langlist, $visitor_locale, $error, $start_time); } } ?>