2011-03-28 14:21:28 +00:00
< ?
/*-- Script Start Class --------------------------------*/
/*------------------------------------------------------*/
2012-10-27 08:00:09 +00:00
/* This isnt really a class but a way to tie other */
2011-03-28 14:21:28 +00:00
/* classes and functions used all over the site to the */
2012-10-27 08:00:09 +00:00
/* page currently being displayed. */
2011-03-28 14:21:28 +00:00
/*------------------------------------------------------*/
/* The code that includes the main php files and */
/* generates the page are at the bottom. */
/*------------------------------------------------------*/
/********************************************************/
require 'config.php' ; //The config contains all site wide configuration information
//Deal with dumbasses
2012-10-11 08:00:15 +00:00
if ( isset ( $_REQUEST [ 'info_hash' ]) && isset ( $_REQUEST [ 'peer_id' ])) { die ( 'd14:failure reason40:Invalid .torrent, try downloading again.e' ); }
2011-03-28 14:21:28 +00:00
require ( SERVER_ROOT . '/classes/class_proxies.php' );
2012-10-11 08:00:15 +00:00
// Get the user's actual IP address if they're proxied.
if ( ! empty ( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ])
&& proxyCheck ( $_SERVER [ 'REMOTE_ADDR' ])
&& filter_var ( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ],
FILTER_VALIDATE_IP ,
FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE )) {
2011-03-28 14:21:28 +00:00
$_SERVER [ 'REMOTE_ADDR' ] = $_SERVER [ 'HTTP_X_FORWARDED_FOR' ];
}
2012-10-11 08:00:15 +00:00
$SSL = ( isset ( $_SERVER [ 'SERVER_PORT' ]) && $_SERVER [ 'SERVER_PORT' ] == 443 );
if ( ! isset ( $argv ) && ! empty ( $_SERVER [ 'HTTP_HOST' ])) {
//Skip this block if running from cli or if the browser is old and shitty
if ( ! $SSL && $_SERVER [ 'HTTP_HOST' ] == 'www.' . NONSSL_SITE_URL ) {
header ( 'Location: http://' . NONSSL_SITE_URL . $_SERVER [ 'REQUEST_URI' ]); die ();
}
if ( $SSL && $_SERVER [ 'HTTP_HOST' ] == 'www.' . NONSSL_SITE_URL ) {
header ( 'Location: https://' . SSL_SITE_URL . $_SERVER [ 'REQUEST_URI' ]); die ();
}
if ( SSL_SITE_URL != NONSSL_SITE_URL ) {
if ( ! $SSL && $_SERVER [ 'HTTP_HOST' ] == SSL_SITE_URL ) {
header ( 'Location: https://' . SSL_SITE_URL . $_SERVER [ 'REQUEST_URI' ]); die ();
}
if ( $SSL && $_SERVER [ 'HTTP_HOST' ] == NONSSL_SITE_URL ) {
header ( 'Location: https://' . SSL_SITE_URL . $_SERVER [ 'REQUEST_URI' ]); die ();
}
}
if ( $_SERVER [ 'HTTP_HOST' ] == 'www.m.' . NONSSL_SITE_URL ) {
header ( 'Location: http://m.' . NONSSL_SITE_URL . $_SERVER [ 'REQUEST_URI' ]); die ();
2011-03-28 14:21:28 +00:00
}
}
2012-10-30 08:00:18 +00:00
$ScriptStartTime = microtime ( true ); //To track how long a page takes to create
if ( ! defined ( 'PHP_WINDOWS_VERSION_MAJOR' )) {
$RUsage = getrusage ();
2012-11-03 08:00:19 +00:00
$CPUTimeStart = $RUsage [ 'ru_utime.tv_sec' ] * 1000000 + $RUsage [ 'ru_utime.tv_usec' ];
2012-10-30 08:00:18 +00:00
}
2011-03-28 14:21:28 +00:00
ob_start (); //Start a buffer, mainly in case there is a mysql error
require ( SERVER_ROOT . '/classes/class_debug.php' ); //Require the debug class
require ( SERVER_ROOT . '/classes/class_mysql.php' ); //Require the database wrapper
require ( SERVER_ROOT . '/classes/class_cache.php' ); //Require the caching class
require ( SERVER_ROOT . '/classes/class_encrypt.php' ); //Require the encryption class
require ( SERVER_ROOT . '/classes/class_useragent.php' ); //Require the useragent class
require ( SERVER_ROOT . '/classes/class_time.php' ); //Require the time class
require ( SERVER_ROOT . '/classes/class_search.php' ); //Require the searching class
require ( SERVER_ROOT . '/classes/class_paranoia.php' ); //Require the paranoia check_paranoia function
require ( SERVER_ROOT . '/classes/regex.php' );
2012-10-11 08:00:15 +00:00
require ( SERVER_ROOT . '/classes/util.php' );
2011-03-28 14:21:28 +00:00
$Debug = new DEBUG ;
$Debug -> handle_errors ();
2011-04-13 15:36:33 +00:00
$Debug -> set_flag ( 'Debug constructed' );
2011-03-28 14:21:28 +00:00
$DB = new DB_MYSQL ;
2012-10-03 08:00:16 +00:00
$Cache = new CACHE ( $MemcachedServers );
2011-03-28 14:21:28 +00:00
$Enc = new CRYPT ;
$UA = new USER_AGENT ;
$SS = new SPHINX_SEARCH ;
2012-10-11 08:00:15 +00:00
// Autoload classes.
spl_autoload_register ( function ( $ClassName ) {
$FileName = '' ;
switch ( $ClassName ) {
case 'Artists' :
$FileName = 'class_artists' ;
break ;
case 'Format' :
$FileName = 'class_format' ;
break ;
case 'Misc' :
$FileName = 'class_misc' ;
break ;
case 'Permissions' :
$FileName = 'class_permissions' ;
break ;
case 'Requests' :
$FileName = 'class_requests' ;
break ;
case 'SphinxQL' :
case 'SphinxQL_Query' :
case 'SphinxQL_Result' :
$FileName = 'class_sphinxql' ;
break ;
case 'Tracker' :
$FileName = 'class_tracker' ;
break ;
case 'Tools' :
$FileName = 'class_tools' ;
break ;
case 'Torrents' :
$FileName = 'class_torrents' ;
break ;
case 'Users' :
$FileName = 'class_users' ;
break ;
case 'View' :
$FileName = 'class_view' ;
break ;
2012-10-27 08:00:09 +00:00
case 'MASS_USER_TORRENTS_EDITOR' :
$FileName = 'class_mass_user_torrents_editor' ;
break ;
case 'MASS_USER_BOOKMARKS_EDITOR' :
$FileName = 'class_mass_user_bookmarks_editor' ;
break ;
case 'MASS_USER_TORRENTS_TABLE_VIEW' :
$FileName = 'class_mass_user_torrents_table_view' ;
break ;
case 'TEXTAREA_PREVIEW' :
$FileName = 'class_textarea_preview' ;
break ;
2012-11-02 08:00:18 +00:00
case 'Votes' :
$FileName = 'class_votes' ;
break ;
2012-11-14 08:00:19 +00:00
case 'LastFM' :
$FileName = 'class_lastfm' ;
break ;
2012-10-11 08:00:15 +00:00
default :
die ( " Couldn't import class " . $ClassName );
}
require_once ( SERVER_ROOT . '/classes/' . $FileName . '.php' );
});
2011-03-28 14:21:28 +00:00
//Begin browser identification
$Browser = $UA -> browser ( $_SERVER [ 'HTTP_USER_AGENT' ]);
$OperatingSystem = $UA -> operating_system ( $_SERVER [ 'HTTP_USER_AGENT' ]);
//$Mobile = $UA->mobile($_SERVER['HTTP_USER_AGENT']);
$Mobile = in_array ( $_SERVER [ 'HTTP_HOST' ], array ( 'm.' . NONSSL_SITE_URL , 'm.' . NONSSL_SITE_URL ));
$Debug -> set_flag ( 'start user handling' );
2012-10-11 08:00:15 +00:00
// Get classes
// TODO: Remove these globals, replace by calls into Users
list ( $Classes , $ClassLevels ) = Users :: get_classes ();
2011-03-28 14:21:28 +00:00
2012-10-11 08:00:15 +00:00
//-- Load user information
2011-03-28 14:21:28 +00:00
// User info is broken up into many sections
// Heavy - Things that the site never has to look at if the user isn't logged in (as opposed to things like the class, donor status, etc)
// Light - Things that appear in format_user
// Stats - Uploaded and downloaded - can be updated by a script if you want super speed
// Session data - Information about the specific session
// Enabled - if the user's enabled or not
// Permissions
if ( isset ( $_COOKIE [ 'session' ])) { $LoginCookie = $Enc -> decrypt ( $_COOKIE [ 'session' ]); }
2012-10-11 08:00:15 +00:00
if ( isset ( $LoginCookie )) {
2011-03-28 14:21:28 +00:00
list ( $SessionID , $LoggedUser [ 'ID' ]) = explode ( " |~| " , $Enc -> decrypt ( $LoginCookie ));
$LoggedUser [ 'ID' ] = ( int ) $LoggedUser [ 'ID' ];
$UserID = $LoggedUser [ 'ID' ]; //TODO: UserID should not be LoggedUser
if ( ! $LoggedUser [ 'ID' ] || ! $SessionID ) {
logout ();
}
2012-10-11 08:00:15 +00:00
2011-03-28 14:21:28 +00:00
$UserSessions = $Cache -> get_value ( 'users_sessions_' . $UserID );
2012-10-11 08:00:15 +00:00
if ( ! is_array ( $UserSessions )) {
2011-03-28 14:21:28 +00:00
$DB -> query ( " SELECT
SessionID ,
Browser ,
OperatingSystem ,
IP ,
LastUpdate
FROM users_sessions
WHERE UserID = '$UserID'
2011-10-20 08:00:12 +00:00
AND Active = 1
2011-03-28 14:21:28 +00:00
ORDER BY LastUpdate DESC " );
$UserSessions = $DB -> to_array ( 'SessionID' , MYSQLI_ASSOC );
$Cache -> cache_value ( 'users_sessions_' . $UserID , $UserSessions , 0 );
}
if ( ! array_key_exists ( $SessionID , $UserSessions )) {
logout ();
}
2012-10-11 08:00:15 +00:00
2011-03-28 14:21:28 +00:00
// Check if user is enabled
$Enabled = $Cache -> get_value ( 'enabled_' . $LoggedUser [ 'ID' ]);
2012-10-11 08:00:15 +00:00
if ( $Enabled === false ) {
2011-03-28 14:21:28 +00:00
$DB -> query ( " SELECT Enabled FROM users_main WHERE ID=' $LoggedUser[ID] ' " );
list ( $Enabled ) = $DB -> next_record ();
$Cache -> cache_value ( 'enabled_' . $LoggedUser [ 'ID' ], $Enabled , 0 );
}
if ( $Enabled == 2 ) {
logout ();
}
// Up/Down stats
$UserStats = $Cache -> get_value ( 'user_stats_' . $LoggedUser [ 'ID' ]);
2012-10-11 08:00:15 +00:00
if ( ! is_array ( $UserStats )) {
2011-03-28 14:21:28 +00:00
$DB -> query ( " SELECT Uploaded AS BytesUploaded, Downloaded AS BytesDownloaded, RequiredRatio FROM users_main WHERE ID=' $LoggedUser[ID] ' " );
$UserStats = $DB -> next_record ( MYSQLI_ASSOC );
$Cache -> cache_value ( 'user_stats_' . $LoggedUser [ 'ID' ], $UserStats , 3600 );
}
// Get info such as username
2012-10-11 08:00:15 +00:00
$LightInfo = Users :: user_info ( $LoggedUser [ 'ID' ]);
$HeavyInfo = Users :: user_heavy_info ( $LoggedUser [ 'ID' ]);
2011-03-28 14:21:28 +00:00
// Get user permissions
2012-10-11 08:00:15 +00:00
$Permissions = Permissions :: get_permissions ( $LightInfo [ 'PermissionID' ]);
2011-03-28 14:21:28 +00:00
// Create LoggedUser array
$LoggedUser = array_merge ( $HeavyInfo , $LightInfo , $Permissions , $UserStats );
$LoggedUser [ 'RSS_Auth' ] = md5 ( $LoggedUser [ 'ID' ] . RSS_HASH . $LoggedUser [ 'torrent_pass' ]);
//$LoggedUser['RatioWatch'] as a bool to disable things for users on Ratio Watch
$LoggedUser [ 'RatioWatch' ] = (
$LoggedUser [ 'RatioWatchEnds' ] != '0000-00-00 00:00:00' &&
time () < strtotime ( $LoggedUser [ 'RatioWatchEnds' ]) &&
( $LoggedUser [ 'BytesDownloaded' ] * $LoggedUser [ 'RequiredRatio' ]) > $LoggedUser [ 'BytesUploaded' ]
);
2012-10-11 08:00:15 +00:00
if ( ! isset ( $LoggedUser [ 'ID' ])) {
2011-10-31 08:00:12 +00:00
$Debug -> log_var ( $LightInfo , 'LightInfo' );
$Debug -> log_var ( $HeavyInfo , 'HeavyInfo' );
$Debug -> log_var ( $Permissions , 'Permissions' );
$Debug -> log_var ( $UserStats , 'UserStats' );
}
2011-03-28 14:21:28 +00:00
//Load in the permissions
2012-10-11 08:00:15 +00:00
$LoggedUser [ 'Permissions' ] = Permissions :: get_permissions_for_user ( $LoggedUser [ 'ID' ], $LoggedUser [ 'CustomPermissions' ]);
2011-03-28 14:21:28 +00:00
//Change necessary triggers in external components
$Cache -> CanClear = check_perms ( 'admin_clear_cache' );
2012-10-11 08:00:15 +00:00
2011-03-28 14:21:28 +00:00
// Because we <3 our staff
if ( check_perms ( 'site_disable_ip_history' )) { $_SERVER [ 'REMOTE_ADDR' ] = '127.0.0.1' ; }
// Update LastUpdate every 10 minutes
2012-10-11 08:00:15 +00:00
if ( strtotime ( $UserSessions [ $SessionID ][ 'LastUpdate' ]) + 600 < time ()) {
2011-03-28 14:21:28 +00:00
$DB -> query ( " UPDATE users_main SET LastAccess=' " . sqltime () . " ' WHERE ID=' $LoggedUser[ID] ' " );
$DB -> query ( " UPDATE users_sessions SET IP=' " . $_SERVER [ 'REMOTE_ADDR' ] . " ', Browser=' " . $Browser . " ', OperatingSystem=' " . $OperatingSystem . " ', LastUpdate=' " . sqltime () . " ' WHERE UserID=' $LoggedUser[ID] ' AND SessionID=' " . db_string ( $SessionID ) . " ' " );
$Cache -> begin_transaction ( 'users_sessions_' . $UserID );
$Cache -> delete_row ( $SessionID );
$Cache -> insert_front ( $SessionID , array (
'SessionID' => $SessionID ,
'Browser' => $Browser ,
'OperatingSystem' => $OperatingSystem ,
'IP' => $_SERVER [ 'REMOTE_ADDR' ],
'LastUpdate' => sqltime ()
));
$Cache -> commit_transaction ( 0 );
}
2012-10-11 08:00:15 +00:00
2011-03-28 14:21:28 +00:00
// Notifications
2012-10-11 08:00:15 +00:00
if ( isset ( $LoggedUser [ 'Permissions' ][ 'site_torrents_notify' ])) {
2011-03-28 14:21:28 +00:00
$LoggedUser [ 'Notify' ] = $Cache -> get_value ( 'notify_filters_' . $LoggedUser [ 'ID' ]);
2012-10-11 08:00:15 +00:00
if ( ! is_array ( $LoggedUser [ 'Notify' ])) {
2011-03-28 14:21:28 +00:00
$DB -> query ( " SELECT ID, Label FROM users_notify_filters WHERE UserID=' $LoggedUser[ID] ' " );
$LoggedUser [ 'Notify' ] = $DB -> to_array ( 'ID' );
$Cache -> cache_value ( 'notify_filters_' . $LoggedUser [ 'ID' ], $LoggedUser [ 'Notify' ], 2592000 );
}
}
2012-10-11 08:00:15 +00:00
2011-03-28 14:21:28 +00:00
// We've never had to disable the wiki privs of anyone.
if ( $LoggedUser [ 'DisableWiki' ]) {
unset ( $LoggedUser [ 'Permissions' ][ 'site_edit_wiki' ]);
}
2012-10-11 08:00:15 +00:00
2011-03-28 14:21:28 +00:00
// IP changed
2012-09-04 08:00:23 +00:00
2012-10-11 08:00:15 +00:00
if ( $LoggedUser [ 'IP' ] != $_SERVER [ 'REMOTE_ADDR' ] && ! check_perms ( 'site_disable_ip_history' )) {
2012-09-04 08:00:23 +00:00
2012-10-11 08:00:15 +00:00
if ( Tools :: site_ban_ip ( $_SERVER [ 'REMOTE_ADDR' ])) {
2011-03-28 14:21:28 +00:00
error ( 'Your IP has been banned.' );
}
2011-05-12 10:24:03 +00:00
$CurIP = db_string ( $LoggedUser [ 'IP' ]);
$NewIP = db_string ( $_SERVER [ 'REMOTE_ADDR' ]);
$DB -> query ( " UPDATE users_history_ips SET
EndTime = '".sqltime()."'
WHERE EndTime IS NULL
AND UserID = '$LoggedUser[ID]'
AND IP = '$CurIP' " );
$DB -> query ( " INSERT IGNORE INTO users_history_ips
( UserID , IP , StartTime ) VALUES
( '$LoggedUser[ID]' , '$NewIP' , '".sqltime()."' ) " );
2012-10-11 08:00:15 +00:00
$ipcc = Tools :: geoip ( $NewIP );
2011-05-12 10:24:03 +00:00
$DB -> query ( " UPDATE users_main SET IP=' $NewIP ', ipcc=' " . $ipcc . " ' WHERE ID=' $LoggedUser[ID] ' " );
$Cache -> begin_transaction ( 'user_info_heavy_' . $LoggedUser [ 'ID' ]);
$Cache -> update_row ( false , array ( 'IP' => $_SERVER [ 'REMOTE_ADDR' ]));
$Cache -> commit_transaction ( 0 );
2011-03-28 14:21:28 +00:00
}
2012-10-11 08:00:15 +00:00
2011-03-28 14:21:28 +00:00
2012-10-11 08:00:15 +00:00
2011-03-28 14:21:28 +00:00
// Get stylesheets
$Stylesheets = $Cache -> get_value ( 'stylesheets' );
if ( ! is_array ( $Stylesheets )) {
$DB -> query ( 'SELECT ID, LOWER(REPLACE(Name," ","_")) AS Name, Name AS ProperName FROM stylesheets' );
$Stylesheets = $DB -> to_array ( 'ID' , MYSQLI_BOTH );
$Cache -> cache_value ( 'stylesheets' , $Stylesheets , 600 );
}
//A9 TODO: Clean up this messy solution
$LoggedUser [ 'StyleName' ] = $Stylesheets [ $LoggedUser [ 'StyleID' ]][ 'Name' ];
2012-10-11 08:00:15 +00:00
if ( empty ( $LoggedUser [ 'Username' ])) {
2011-03-28 14:21:28 +00:00
logout (); // Ghost
}
}
$Debug -> set_flag ( 'end user handling' );
$Debug -> set_flag ( 'start function definitions' );
2012-04-03 08:00:22 +00:00
/**
* Log out the current session
*/
2011-03-28 14:21:28 +00:00
function logout () {
global $SessionID , $LoggedUser , $DB , $Cache ;
setcookie ( 'session' , '' , time () - 60 * 60 * 24 * 365 , '/' , '' , false );
setcookie ( 'keeplogged' , '' , time () - 60 * 60 * 24 * 365 , '/' , '' , false );
setcookie ( 'session' , '' , time () - 60 * 60 * 24 * 365 , '/' , '' , false );
2012-10-11 08:00:15 +00:00
if ( $SessionID ) {
2011-10-20 08:00:12 +00:00
2011-03-28 14:21:28 +00:00
$DB -> query ( " DELETE FROM users_sessions WHERE UserID=' $LoggedUser[ID] ' AND SessionID=' " . db_string ( $SessionID ) . " ' " );
2011-10-20 08:00:12 +00:00
2011-03-28 14:21:28 +00:00
$Cache -> begin_transaction ( 'users_sessions_' . $LoggedUser [ 'ID' ]);
$Cache -> delete_row ( $SessionID );
$Cache -> commit_transaction ( 0 );
}
$Cache -> delete_value ( 'user_info_' . $LoggedUser [ 'ID' ]);
$Cache -> delete_value ( 'user_stats_' . $LoggedUser [ 'ID' ]);
$Cache -> delete_value ( 'user_info_heavy_' . $LoggedUser [ 'ID' ]);
header ( 'Location: login.php' );
2012-10-11 08:00:15 +00:00
2011-03-28 14:21:28 +00:00
die ();
}
function enforce_login () {
global $SessionID , $LoggedUser ;
if ( ! $SessionID || ! $LoggedUser ) {
setcookie ( 'redirect' , $_SERVER [ 'REQUEST_URI' ], time () + 60 * 30 , '/' , '' , false );
logout ();
}
}
2012-04-03 08:00:22 +00:00
/**
* Make sure $_GET [ 'auth' ] is the same as the user ' s authorization key
* Should be used for any user action that relies solely on GET .
*
* @ param Are we using ajax ?
* @ return authorisation status . Prints an error message to LAB_CHAN on IRC on failure .
*/
2011-10-27 08:00:15 +00:00
function authorize ( $Ajax = false ) {
2011-03-28 14:21:28 +00:00
global $LoggedUser ;
2012-10-11 08:00:15 +00:00
if ( empty ( $_REQUEST [ 'auth' ]) || $_REQUEST [ 'auth' ] != $LoggedUser [ 'AuthKey' ]) {
2011-03-28 14:21:28 +00:00
send_irc ( " PRIVMSG " . LAB_CHAN . " : " . $LoggedUser [ 'Username' ] . " just failed authorize on " . $_SERVER [ 'REQUEST_URI' ] . " coming from " . $_SERVER [ 'HTTP_REFERER' ]);
2011-10-27 08:00:15 +00:00
error ( 'Invalid authorization key. Go back, refresh, and try again.' , $Ajax );
2011-03-28 14:21:28 +00:00
return false ;
}
return true ;
}
2012-10-09 08:00:17 +00:00
2011-03-28 14:21:28 +00:00
$Debug -> set_flag ( 'ending function definitions' );
//Include /sections/*/index.php
$Document = basename ( parse_url ( $_SERVER [ 'SCRIPT_FILENAME' ], PHP_URL_PATH ), '.php' );
2012-10-11 08:00:15 +00:00
if ( ! preg_match ( '/^[a-z0-9]+$/i' , $Document )) { error ( 404 ); }
2011-03-28 14:21:28 +00:00
require ( SERVER_ROOT . '/sections/' . $Document . '/index.php' );
$Debug -> set_flag ( 'completed module execution' );
2012-10-11 08:00:15 +00:00
/* Required in the absence of session_start () for providing that pages will change
2012-09-09 08:00:26 +00:00
upon hit rather than being browser cached for changing content .
2012-08-25 08:00:15 +00:00
2012-09-09 08:00:26 +00:00
Old versions of Internet Explorer choke when downloading binary files over HTTPS with disabled cache .
2012-08-25 08:00:15 +00:00
Define the following constant in files that handle file downloads */
2012-10-11 08:00:15 +00:00
if ( ! defined ( 'IE_WORKAROUND_NO_CACHE_HEADERS' )) {
2012-08-25 08:00:15 +00:00
header ( 'Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0' );
header ( 'Pragma: no-cache' );
}
2011-03-28 14:21:28 +00:00
//Flush to user
ob_end_flush ();
$Debug -> set_flag ( 'set headers and send to user' );
//Attribute profiling
$Debug -> profile ();