websiteWebsite
codingteam CodingTeam
A free forge, lightweight and extensible.

 

Browse the code

Revision log Information on the revision
Revision: 511 (differences)
Author: xbright
Log message: * Enhanced roadmap
Change revision:
<?php
//   This file is a part of CodingTeam. Take a look at <http://codingteam.org>.
//   Copyright © 2007-2012 Erwan Briand <erwan@codingteam.net>
//
//   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 <http://www.gnu.org/licenses/>.
 
/**
 * @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);
 
        // 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);
 
        // 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');
 
        // 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
        $locale = getClass('locales');
        $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 and Type headers
        Header('Content-Language: '.$visitor_locale);
        Header('Content-Type: text/html; charset=UTF-8');
 
        // 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);
    }
}
?>