~quam-plures-core/quam-plures/qp5_colls-blogs_chaps-cats

« back to all changes in this revision

Viewing changes to qp_inc/_main.inc.php

  • Committer: EdB
  • Date: 2013-03-12 06:26:03 UTC
  • Revision ID: 1912webworks@gmail.com-20130312062603-tnlb5zco5mglydqj
lots of changes in this branch. tested and functional, but not going into merge just yet ...

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/**
3
3
 * This file initializes everything BUT the blog!
4
4
 *
5
 
 * It is useful when you want to do very customized templates!
6
 
 * It is also called by more complete initializers.
7
 
 *
8
 
 * This file is part of Quam Plures - {@link http://quamplures.net/}
9
 
 * See also {@link https://launchpad.net/quam-plures}.
10
 
 *
11
 
 * @copyright (c) 2009 - 2011 by the Quam Plures developers - {@link http://quamplures.net/}
12
 
 * @copyright (c)2003-2009 by Francois PLANQUE - {@link http://fplanque.net/}
13
 
 * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
14
 
 * Parts of this file are copyright (c)2005-2006 by PROGIDISTRI - {@link http://progidistri.com/}.
15
 
 *
16
 
 * {@internal License choice
17
 
 * - If you have received this file as part of a package, please find the license.txt file in
18
 
 *   the same folder or the closest folder above for complete license terms.
19
 
 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
20
 
 *   then you must choose one of the following licenses before using the file:
21
 
 *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
22
 
 *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
23
 
 * }}
24
 
 *
25
 
 * {@internal Open Source relicensing agreement:
26
 
 * Daniel HAHLER grants Francois PLANQUE the right to license
27
 
 * Daniel HAHLER's contributions to this file and the b2evolution project
28
 
 * under any OSI approved OSS license (http://www.opensource.org/licenses/).
29
 
 *
30
 
 * PROGIDISTRI S.A.S. grants Francois PLANQUE the right to license
31
 
 * PROGIDISTRI S.A.S.'s contributions to this file and the b2evolution project
32
 
 * under any OSI approved OSS license (http://www.opensource.org/licenses/).
33
 
 *
34
 
 * Matt FOLLETT grants Francois PLANQUE the right to license
35
 
 * Matt FOLLETT's contributions to this file and the b2evolution project
36
 
 * under any OSI approved OSS license (http://www.opensource.org/licenses/).
37
 
 * }}
38
 
 *
39
 
 * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
40
 
 * @author fplanque: Francois PLANQUE
41
 
 * @author blueyed: Daniel HAHLER
42
 
 * @author mfollett: Matt FOLLETT.
43
 
 * @author mbruneau: Marc BRUNEAU / PROGIDISTRI
44
 
 *
45
 
 * @package pond
 
5
 * It is useful when you want to do very customized templates! It is also
 
6
 * called by more complete initializers.
 
7
 *
 
8
 * @author {@link http://wonderwinds.com/ Ed Bennett}
 
9
 * @author {@link http://fplanque.net/ Francois PLANQUE}
 
10
 * @author {@link http://daniel.hahler.de/ Daniel HAHLER}
 
11
 * @author {@link http://www.mfollett.com/ Matt FOLLETT}
 
12
 * @author {@link http://progidistri.com/ PROGIDISTRI}
 
13
 * @copyright (c) 2009 by {@link http://quamplures.net/ the Quam Plures project}
 
14
 * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3
 
15
 * @package core
46
16
 */
47
 
if( !defined('QP_CONFIG_LOADED') ) die( 'Please, do not access this page directly.' );
 
17
if(!defined('QP_CONFIG_LOADED')) die('fail');
48
18
 
49
19
if( $maintenance_mode )
50
20
{
53
23
        die( 'The site is temporarily down for maintenance.' );
54
24
}
55
25
 
56
 
 
57
 
/**
58
 
 * Prevent double loading since require_once won't work in all situations
59
 
 * on windows when some subfolders have caps :(
60
 
 * (Check it out on static page generation)
61
 
 */
 
26
// Prevent double loading since require_once won't work in all situations on windows
 
27
// when some subfolders have caps :( (Check it out on static page generation)
62
28
if( defined( 'QP_MAIN_INIT' ) )
63
29
{
64
30
        return;
65
31
}
66
32
define( 'QP_MAIN_INIT', true );
67
33
 
68
 
 
69
34
/**
70
35
 * Security check for older PHP versions
71
36
 * Contributed by counterpoint / MAMBO team
77
42
        $protects = array( '_REQUEST', '_GET', '_POST', '_COOKIE', '_FILES', '_SERVER', '_ENV', 'GLOBALS', '_SESSION' );
78
43
        foreach( $protects as $protect )
79
44
        {
80
 
                if(  in_array( $protect, array_keys($_REQUEST) )
81
 
                        || in_array( $protect, array_keys($_GET) )
82
 
                        || in_array( $protect, array_keys($_POST) )
83
 
                        || in_array( $protect, array_keys($_COOKIE) )
84
 
                        || in_array( $protect, array_keys($_FILES) ) )
 
45
                if( in_array( $protect, array_keys( $_REQUEST ) )
 
46
                        || in_array( $protect, array_keys( $_GET ) )
 
47
                        || in_array( $protect, array_keys( $_POST ) )
 
48
                        || in_array( $protect, array_keys( $_COOKIE ) )
 
49
                        || in_array( $protect, array_keys( $_FILES ) ) )
85
50
                {
86
51
                        require_once $inc_path.'/_core/_misc.funcs.php';
87
52
                        bad_request_die( 'Unacceptable params.' );
89
54
        }
90
55
}
91
56
 
92
 
/*
93
 
 * fp> We might want to kill all auto registered globals this way:
94
 
 * TODO: testing
95
 
 *
96
 
$superglobals = array($_SERVER, $_ENV, $_FILES, $_COOKIE, $_POST, $_GET);
97
 
if (isset( $_SESSION )) array_unshift ( $superglobals , $_SESSION );
98
 
if (ini_get('register_globals') && !$this->mosConfig_register_globals)
99
 
{
100
 
        foreach ( $superglobals as $superglobal )
101
 
        {
102
 
                foreach ( $superglobal as $key => $value)
103
 
                {
104
 
                        unset( $GLOBALS[$key]);
105
 
                }
106
 
        }
107
 
}
108
 
*/
109
 
 
110
 
 
111
57
/**
112
 
 * Class loader.
 
58
 * Class loader
113
59
 */
114
 
require_once $inc_path.'_core/_class'.floor(PHP_VERSION).'.funcs.php';
115
 
 
 
60
require_once $inc_path.'_core/_class.funcs.php';
116
61
 
117
62
/**
118
63
 * Miscellaneous functions
119
64
 */
120
65
require_once $inc_path.'/_core/_misc.funcs.php';
121
66
 
122
 
 
123
 
/**
124
 
 * Load logging class
125
 
 */
126
 
load_class('_core/model/_log.class.php');
127
 
/**
128
 
 * Debug message log for debugging only (initialized here).
129
 
 *
130
 
 * @global Log|Log_noop $Debuglog
131
 
 */
 
67
// Debug message log for debugging only (initialized here).
132
68
if( $debug )
133
69
{
134
70
        $Debuglog = new Log( 'note' );
138
74
        $Debuglog = new Log_noop( 'note' );
139
75
}
140
76
 
141
 
 
142
77
/**
143
78
 * Info & error message log for end user (initialized here)
144
79
 * @global Log $Messages
147
82
 
148
83
 
149
84
/**
150
 
 * Start timer:
 
85
 * Start timer
 
86
 * @global Timer $Timer
151
87
 */
152
 
load_class('_core/model/_timer.class.php');
153
88
$Timer = new Timer('total');
154
 
 
155
89
$Timer->resume( '_main.inc' );
156
90
 
157
 
 
158
91
/**
159
92
 * Sets various arrays and vars, also $app_name!
160
93
 *
162
95
 */
163
96
require_once dirname(__FILE__).'/_vars.inc.php';
164
97
 
165
 
 
166
 
if( !$app_config_is_done )
167
 
{ // base config is not done!
 
98
if( ! $app_config_is_done )
 
99
{
 
100
        // base config is not done!
168
101
        $error_message = 'Base configuration is not done! (see /qp_config/_main_config.php)';
169
102
}
170
 
elseif( !isset( $locales[$default_locale] ) )
 
103
elseif( ! isset( $locales[$default_locale] ) )
171
104
{
172
105
        $error_message = 'The default locale '.var_export( $default_locale, true ).' does not exist! (see /qp_config/_locales.php)';
173
106
}
174
107
if( isset( $error_message ) )
175
 
{ // error & exit
 
108
{
 
109
        /**
 
110
         * error & exit
 
111
         */
176
112
        require dirname(__FILE__).'/../qp_view_admin/conf_error.main.php';
177
113
}
178
114
 
179
 
 
180
115
/**
181
116
 * Connect to DB
182
117
 */
183
118
require_once dirname(__FILE__).'/_connect_db.inc.php';
184
119
 
185
 
 
186
 
/**
187
 
 * Load settings class
188
 
 */
189
 
load_class('settings/model/_generalsettings.class.php');
190
 
load_class('users/model/_usersettings.class.php');
191
120
/**
192
121
 * Interface to general settings
193
122
 *
194
123
 * Keep this below the creation of the {@link $DB DB object}, because it checks for the
195
124
 * correct db_version and catches "table does not exist" errors, providing a link to the
196
125
 * install script.
197
 
 *
198
126
 * @global GeneralSettings $Settings
199
127
 */
200
128
$Settings = new GeneralSettings();
 
129
 
201
130
/**
202
131
 * Interface to user settings
203
 
 *
204
132
 * @global UserSettings $UserSettings
205
133
 */
206
134
$UserSettings = new UserSettings();
207
135
 
208
 
 
209
136
/**
210
137
 * Absolute Unix timestamp for server
211
 
 * @global int $servertimenow
 
138
 * @global integer $servertimenow
212
139
 */
213
140
$servertimenow = time();
214
141
 
215
 
$time_difference = $Settings->get('time_difference');
 
142
$time_difference = $Settings->get( 'time_difference' );
216
143
 
217
144
/**
218
145
 * Corrected Unix timestamp to match server timezone
219
 
 * @global int $localtimenow
 
146
 * @global integer $localtimenow
220
147
 */
221
148
$localtimenow = $servertimenow + $time_difference;
222
149
 
223
 
 
224
 
/**
225
 
 * The Hit class
226
 
 */
227
 
load_class('sessions/model/_hit.class.php');
 
150
// The Hit class
228
151
// fp> The following constructor requires these right now:
229
 
load_funcs('_core/_param.funcs.php');
230
 
load_funcs('_core/_url.funcs.php');
231
 
 
232
 
 
233
 
/**
234
 
 * Locale selection:
235
 
 * We need to do this as early as possible in order to set DB connection charset below
236
 
 * fp> that does not explain why it needs to be here!! Why do we need to set the Db charset HERE? BEFORE WHAT?
237
 
 *
238
 
 * sam2kb> ideally we should set the right DB charset at the time when we connect to the database. The reason is until we do it all data pulled out from DB is in wrong encoding. I put the code here because it depends on _param.funcs, so if move the _param.funcs higher we can also move this code right under _connect_db
239
 
 * See also http://forums.b2evolution.net//viewtopic.php?p=95100
240
 
 *
241
 
 */
242
 
$Debuglog->add( 'default_locale from conf: '.$default_locale, 'locale' );
243
 
 
 
152
load_funcs( '_core/_param.funcs.php' );
 
153
load_funcs( '_core/_url.funcs.php' );
 
154
 
 
155
// Locale selection
 
156
// We need to do this as early as possible in order to set DB connection charset below
 
157
// fp> that does not explain why it needs to be here!! Why do we need to set the Db
 
158
// charset HERE? BEFORE WHAT? sam2kb> ideally we should set the right DB charset at
 
159
// the time when we connect to the database. The reason is until we do it all data
 
160
// pulled out from DB is in wrong encoding. I put the code here because it depends on
 
161
// _param.funcs, so if move the _param.funcs higher we can also move this code right
 
162
// under _connect_db
244
163
locale_overwritefromDB();
245
 
$Debuglog->add( 'default_locale from DB: '.$default_locale, 'locale' );
246
 
 
247
164
$default_locale = locale_from_httpaccept(); // set default locale by autodetect
248
 
$Debuglog->add( 'default_locale from HTTP_ACCEPT: '.$default_locale, 'locale' );
249
165
 
250
 
if( ($locale_from_get = param( 'locale', 'string', NULL, true )) )
 
166
if( ( $locale_from_get = param( 'locale', 'string', NULL, true ) ) )
251
167
{
252
168
        if( $locale_from_get != $default_locale )
253
169
        {
254
170
                if( isset( $locales[$locale_from_get] ) )
255
171
                {
256
172
                        $default_locale = $locale_from_get;
257
 
                        $Debuglog->add('Overriding locale from REQUEST: '.$default_locale, 'locale');
258
173
                }
259
174
                else
260
175
                {
261
 
                        $Debuglog->add('$locale_from_get ('.$locale_from_get.') is not set. Available locales: '.implode(', ', array_keys($locales)), 'locale');
262
176
                        $locale_from_get = false;
263
177
                }
264
178
        }
265
 
        else
266
 
        {
267
 
                $Debuglog->add('$locale_from_get == $default_locale ('.$locale_from_get.').', 'locale');
268
 
        }
269
179
 
270
180
}
271
181
 
272
 
 
273
 
/**
274
 
 * Activate default locale:
275
 
 */
 
182
// Activate default locale
276
183
locale_activate( $default_locale );
277
184
 
278
 
// Set encoding for MySQL connection:
 
185
// Set encoding for MySQL connection
279
186
$DB->set_connection_charset( $current_charset );
280
187
 
281
 
 
282
188
/**
283
189
 * @global Hit The Hit object
284
190
 */
285
191
$Hit = new Hit(); // This may INSERT a basedomain and a useragent but NOT the HIT itself!
286
192
 
287
 
 
288
 
/**
289
 
 * The Session class.
290
 
 */
291
 
load_class('sessions/model/_session.class.php');
292
 
/**
293
 
 * The Session object.
 
193
/**
 
194
 * The Session object
 
195
 *
294
196
 * It has to be instantiated before the "SessionLoaded" hook.
 
197
 * @todo (0000) This needs the same "SET NAMES" MySQL-setup as with Session::dbsave() -
 
198
 * see the "TODO" with unserialize() in Session::Session()
295
199
 * @global Session
296
 
 * @todo dh> This needs the same "SET NAMES" MySQL-setup as with Session::dbsave() - see the "TODO" with unserialize() in Session::Session()
297
 
 * @todo dh> makes no sense in CLI mode (no cookie); Add isset() checks to calls on the $Session object, e.g. below?
298
 
 *       fp> We might want to use a special session for CLI. And for cron jobs through http as well.
299
200
 */
300
201
$Session = new Session(); // IF this can't pull asesion from the DB it will always INSERT a new one!
301
202
 
304
205
 */
305
206
register_shutdown_function( 'shutdown' );
306
207
 
307
 
 
308
 
/**
309
 
 * @global AbstractSettings
310
 
 */
311
 
$global_Cache = new AbstractSettings( 'T_global__cache', array( 'cach_name' ), 'cach_cache', 0 /* load all */ );
312
 
 
313
 
 
314
 
/**
315
 
 * Plugins init.
316
 
 * This is done quite early here to give an early hook ("SessionLoaded") to plugins (though it might also be moved just after $DB init when there is reason for a hook there).
317
 
 * The {@link dnsbl_antispam_plugin} is an example that uses this to check the user's IP against a list of DNS blacklists.
318
 
 */
319
 
load_class('plugins/model/_plugins.class.php');
320
208
/**
321
209
 * @global Plugins The Plugin management object
322
210
 */
323
211
$Plugins = new Plugins();
324
212
 
325
 
 
326
 
// NOTE: it might be faster (though more bandwidth intensive) to spit cached pages (CachePageContent event) than to look into blocking the request (SessionLoaded event).
 
213
// NOTE: it might be faster (though more bandwidth intensive) to spit cached pages
 
214
// (CachePageContent event) than to look into blocking the request (SessionLoaded event).
327
215
$Plugins->trigger_event( 'SessionLoaded' );
328
216
 
329
 
 
330
217
// Trigger a page content caching plugin. This would either return the
331
218
// cached content here or start output buffering.
332
219
if( $Session->get( 'core.no_CachePageContent' ) )
333
 
{ // The event is disabled for this request:
 
220
{
 
221
        // The event is disabled for this request
334
222
        $Session->delete('core.no_CachePageContent');
335
 
        $Debuglog->add( 'Skipping CachePageContent event, because of core.no_CachePageContent setting.', 'plugins' );
336
223
}
337
224
elseif( ( $get_return = $Plugins->trigger_event_first_true( 'CachePageContent' ) ) // Plugin responded to the event
338
 
                && ( isset($get_return['data']) ) ) // cached content returned
 
225
        && ( isset($get_return['data']) ) ) // cached content returned
339
226
{
340
227
        echo $get_return['data'];
341
228
        // Note: we should not use debug_info() here, because the plugin has probably sent a Content-Length header.
342
229
        exit(0);
343
230
}
344
231
 
345
 
 
346
 
// TODO: we need an event hook here for the transport_optimizer_plugin, which must get called, AFTER another plugin might have started an output buffer for caching already.
347
 
//       Plugin priority is no option, because CachePageContent is a trigger_event_first_true event, for obvious reasons.
348
 
//       Name?
349
 
//       This must not be exactly here, but before any output.
350
 
 
351
 
 
352
 
/**
353
 
 * Includes:
354
 
 */
355
 
$Timer->resume('_main.inc:requires');
356
 
load_class('_core/model/dataobjects/_dataobjectcache.class.php');
357
 
load_class('generic/model/_genericelement.class.php');
358
 
load_class('generic/model/_genericcache.class.php');
359
 
load_class('collections/model/_blog.class.php');
360
 
load_funcs('collections/model/_blog.funcs.php');
361
 
load_funcs('collections/model/_category.funcs.php');
362
 
load_funcs('items/model/_item.funcs.php');
363
 
load_funcs('users/model/_user.funcs.php');
364
 
load_funcs('_core/_template.funcs.php');
365
 
load_class('files/model/_file.class.php');
366
 
load_class('files/model/_filetype.class.php');
367
 
load_class('files/model/_filetypecache.class.php');
368
 
load_class('items/model/_itemtype.class.php');
369
 
load_class('items/model/_link.class.php');
370
 
load_funcs('comments/model/_comment.funcs.php');
371
 
load_funcs('items/model/_item.funcs.php');
372
 
load_class('comments/model/_commentlist.class.php');
373
 
load_funcs('_core/ui/forms/_form.funcs.php');
374
 
load_class('_core/ui/forms/_form.class.php');
375
 
load_class('items/model/_itemquery.class.php');
 
232
// Includes
 
233
$Timer->resume( '_main.inc:requires' );
 
234
load_funcs( 'blogs/model/_blog.funcs.php' );
 
235
load_funcs( 'categories/model/_category.funcs.php' );
 
236
load_funcs( 'items/model/_item.funcs.php' );
 
237
load_funcs( 'users/model/_user.funcs.php' );
 
238
load_funcs( '_core/_template.funcs.php' );
 
239
load_funcs( 'comments/model/_comment.funcs.php' );
 
240
load_funcs( 'items/model/_item.funcs.php' );
 
241
load_funcs( '_core/ui/forms/_form.funcs.php' );
376
242
$Timer->pause( '_main.inc:requires' );
377
243
 
378
 
 
379
 
/*
380
 
 * Login procedure: {{{
381
 
 * TODO: dh> the meat of this login procedure should be moved to an extra file,
382
 
 *           so that if a "logged in"-session exists (in most cases) it does not
383
 
 *           trigger parsing the meat of this code.
384
 
 * fp> ming you, most hits will be on the font end and will not be loggedin sessions
385
 
 *     However, I agree that the login stuff should only be included when the user is actually attempting to log in.
386
 
 */
387
 
if( !isset($login_required) )
 
244
if( ! isset( $login_required ) )
388
245
{
389
246
        $login_required = false;
390
247
}
391
248
 
392
 
 
393
249
$login = NULL;
394
250
$pass = NULL;
395
251
$pass_md5 = NULL;
396
252
 
397
 
if( isset($_POST['login'] ) && isset($_POST['pwd'] ) )
398
 
{ // Trying to log in with a POST
 
253
if( isset( $_POST['login'] ) && isset( $_POST['pwd'] ) )
 
254
{
 
255
        // Trying to log in with a POST
399
256
        $login = $_POST['login'];
400
257
        $pass = $_POST['pwd'];
401
 
        unset($_POST['pwd']); // password will be hashed below
 
258
        unset( $_POST['pwd'] ); // password will be hashed below
402
259
}
403
 
elseif( isset($_GET['login'] ) )
404
 
{ // Trying to log in with a GET; we might only provide a user here.
 
260
elseif( isset( $_GET['login'] ) )
 
261
{
 
262
        // Trying to log in with a GET; we might only provide a user here.
405
263
        $login = $_GET['login'];
406
264
        $pass = isset($_GET['pwd']) ? $_GET['pwd'] : '';
407
265
        unset($_GET['pwd']); // password will be hashed below
408
266
}
409
267
 
410
 
$Debuglog->add( 'login: '.var_export($login, true), 'login' );
411
 
$Debuglog->add( 'pass: '.( empty($pass) ? '' : 'not' ).' empty', 'login' );
412
 
 
413
 
// either 'login' (normal) or 'redirect_to_backoffice' may be set here. This also helps to display the login form again, if either login or pass were empty.
 
268
// either 'login' (normal) or 'redirect_to_backoffice' may be set here.
 
269
// This also helps to display the login form again, if either login or pass were empty.
414
270
$login_action = param_arrayindex( 'login_action' );
415
271
 
416
272
$UserCache = & get_Cache( 'UserCache' );
417
273
 
418
 
if( ! empty($login_action) || (! empty($login) && ! empty($pass)) )
419
 
{ // User is trying to login right now
420
 
        $Debuglog->add( 'User is trying to log in.', 'login' );
421
 
 
 
274
if( ! empty( $login_action ) || (! empty( $login ) && ! empty( $pass ) ) )
 
275
{
 
276
        // User is trying to login right now
422
277
        header_nocache();
423
 
 
424
278
        // Note: login and password cannot include '<' !
425
 
        $login = strtolower(strip_tags(remove_magic_quotes($login)));
426
 
        $pass = strip_tags(remove_magic_quotes($pass));
 
279
        $login = strtolower( strip_tags( remove_magic_quotes( $login ) ) );
 
280
        $pass = strip_tags( remove_magic_quotes( $pass ) );
427
281
        $pass_md5 = md5( $pass );
428
282
 
429
 
 
430
 
        /*
431
 
         * Handle javascript-hashed password:
432
 
         * If possible, the login form will hash the entered password with a salt that changes everytime.
433
 
         */
 
283
        // Handle javascript-hashed password: If possible, the login form will hash the
 
284
        // entered password with a salt that changes everytime.
434
285
        param('pwd_salt', 'string', ''); // just for comparison with the one from Session
435
 
        $pwd_salt_sess = $Session->get('core.pwd_salt');
436
 
 
437
 
        // $Debuglog->add( 'salt: '.var_export($pwd_salt, true).', session salt: '.var_export($pwd_salt_sess, true) );
438
 
 
439
 
        $transmit_hashed_password = (bool)$Settings->get('js_passwd_hashing') && !(bool)$Plugins->trigger_event_first_true('LoginAttemptNeedsRawPassword');
 
286
        $pwd_salt_sess = $Session->get( 'core.pwd_salt' );
 
287
 
 
288
        $transmit_hashed_password = (bool)$Settings->get( 'js_passwd_hashing' )
 
289
                && !(bool)$Plugins->trigger_event_first_true('LoginAttemptNeedsRawPassword');
440
290
        if( $transmit_hashed_password )
441
291
        {
442
292
                param( 'pwd_hashed', 'string', '' );
443
293
        }
444
294
        else
445
 
        { // at least one plugin requests the password un-hashed:
 
295
        {
 
296
                // at least one plugin requests the password un-hashed
446
297
                $pwd_hashed = '';
447
298
        }
448
299
 
449
 
        // $Debuglog->add( 'pwd_hashed: '.var_export($pwd_hashed, true).', pass: '.var_export($pass, true) );
450
 
 
451
300
        $pass_ok = false;
452
 
        // Trigger Plugin event, which could create the user, according to another database:
 
301
        // Trigger Plugin event, which could create the user, according to another database
453
302
        if( $Plugins->trigger_event( 'LoginAttempt', array(
454
303
                        'login' => & $login,
455
304
                        'pass' => & $pass,
457
306
                        'pass_salt' => & $pwd_salt_sess,
458
307
                        'pass_hashed' => & $pwd_hashed,
459
308
                        'pass_ok' => & $pass_ok ) ) )
460
 
        { // clear the UserCache, if a plugin has been called - it may have changed user(s)
 
309
        {
 
310
                // clear the UserCache, if a plugin has been called - it may have changed user(s)
461
311
                $UserCache->clear();
462
312
        }
463
313
 
464
314
        if( $Messages->count('login_error') )
465
 
        { // A plugin has thrown a login error..
466
 
                // Do nothing, the error will get displayed in the login form..
467
 
 
468
 
                // TODO: dh> make sure that the user gets logged out?! (a Plugin might have logged him in and another one thrown an error)
 
315
        {
 
316
                // A plugin has thrown a login error; do nothing, the error will get displayed in the login form.
 
317
                // @todo (0000) dh> make sure that the user gets logged out?! (a
 
318
                // Plugin might have logged him in and another one thrown an error)
469
319
        }
470
320
        else
471
 
        { // Check login and password
472
 
 
 
321
        {
 
322
                // Check login and password
473
323
                // Make sure that we can load the user:
474
 
                $User = & $UserCache->get_by_login($login);
 
324
                $User = & $UserCache->get_by_login( $login );
475
325
 
476
326
                if( $User && ! $pass_ok )
477
 
                { // check the password, if no plugin has said "it's ok":
478
 
                        if( ! empty($pwd_hashed) )
479
 
                        { // password hashed by JavaScript:
480
 
 
481
 
                                $Debuglog->add( 'Hashed password available.', 'login' );
482
 
 
483
 
                                if( empty($pwd_salt_sess) )
484
 
                                { // no salt stored in session: either cookie problem or the user had already tried logging in (from another window for example)
485
 
                                        $Debuglog->add( 'Empty salt_sess!', 'login' );
486
 
                                        if( ($pos = strpos( $pass, '_hashed_' ) ) && substr($pass, $pos+8) == $Session->ID )
487
 
                                        { // session ID matches, no cookie problem
 
327
                {
 
328
                        // check the password, if no plugin has said "it's ok"
 
329
                        if( ! empty( $pwd_hashed ) )
 
330
                        {
 
331
                                // password hashed by JavaScript
 
332
                                if( empty( $pwd_salt_sess ) )
 
333
                                {
 
334
                                        // no salt stored in session: either cookie problem or the user had already tried logging in (from another window for example)
 
335
                                        if( ( $pos = strpos( $pass, '_hashed_' ) ) && substr( $pass, $pos+8 ) == $Session->ID )
 
336
                                        {
 
337
                                                // session ID matches, no cookie problem
488
338
                                                $Messages->add( T_('The login window has expired. Please try again.'), 'login_error' );
489
 
                                                $Debuglog->add( 'Session ID matches.', 'login' );
490
339
                                        }
491
340
                                        else
492
 
                                        { // more general error:
 
341
                                        {
 
342
                                                // more general error:
493
343
                                                $Messages->add( T_('Either you have not enabled cookies or this login window has expired.'), 'login_error' );
494
 
                                                $Debuglog->add( 'Session ID does not match.', 'login' );
495
344
                                        }
496
345
                                }
497
346
                                elseif( $pwd_salt != $pwd_salt_sess )
498
 
                                { // submitted salt differs from the one stored in the session
 
347
                                {
 
348
                                        // submitted salt differs from the one stored in the session
499
349
                                        $Messages->add( T_('The login window has expired. Please try again.'), 'login_error' );
500
 
                                        $Debuglog->add( 'Submitted salt and salt from Session do not match.', 'login' );
501
350
                                }
502
351
                                else
503
 
                                { // compare the password, using the salt stored in the Session:
504
 
                                        #pre_dump( sha1($User->pass.$pwd_salt), $pwd_hashed );
505
 
                                        $pass_ok = sha1($User->pass.$pwd_salt) == $pwd_hashed;
 
352
                                {
 
353
                                        // compare the password, using the salt stored in the Session:
 
354
                                        $pass_ok = sha1( $User->pass.$pwd_salt ) == $pwd_hashed;
506
355
                                        $Session->delete('core.pwd_salt');
507
 
                                        $Debuglog->add( 'Compared hashed passwords. Result: '.(int)$pass_ok, 'login' );
508
356
                                }
509
357
                        }
510
358
                        else
511
359
                        {
512
 
                                $pass_ok = $User->check_password( $pass_md5, true );
513
 
                                $Debuglog->add( 'Compared raw passwords. Result: '.(int)$pass_ok, 'login' );
 
360
                                $pass_ok = ( $User->pass == $pass_md5 );
514
361
                        }
515
362
                }
516
363
        }
517
364
 
518
365
        if( $pass_ok )
519
 
        { // Login succeeded, set cookies
520
 
                $Debuglog->add( 'User successfully logged in with username and password...', 'login');
 
366
        {
 
367
                // Login succeeded, set cookies
521
368
                // set the user from the login that succeeded
522
 
                $current_User = & $UserCache->get_by_login($login);
 
369
                $current_User = & $UserCache->get_by_login( $login );
523
370
                // save the user for later hits
524
371
                $Session->set_User( $current_User );
525
372
        }
526
373
        elseif( ! $Messages->count('login_error') )
527
 
        { // if there's no login_error message yet, add the default one:
 
374
        {
 
375
                // if there's no login_error message yet, add the default one:
528
376
                // This will cause the login screen to "popup" (again)
529
377
                $Messages->add( T_('Wrong login/password.'), 'login_error' );
530
378
        }
532
380
}
533
381
elseif( $Session->has_User() /* logged in */
534
382
        && /* No login param given or the same as current user: */
535
 
        ( empty($login) || ( ( $tmp_User = & $UserCache->get_by_ID($Session->user_ID) ) && $login == $tmp_User->login ) ) )
 
383
        ( empty( $login ) || ( ( $tmp_User = & $UserCache->get_by_ID( $Session->user_ID ) ) && $login == $tmp_User->login ) ) )
536
384
{ /* if the session has a user assigned to it:
537
385
         * User was not trying to log in, but he was already logged in:
538
386
         */
539
387
        // get the user ID from the session and set up the user again
540
388
        $current_User = & $UserCache->get_by_ID( $Session->user_ID );
541
 
 
542
 
        $Debuglog->add( 'Was already logged in... ['.$current_User->get('login').']', 'login' );
543
389
}
544
390
else
545
 
{ // The Session has no user or $login is given (and differs from current user), allow alternate authentication through Plugin:
546
 
        if( ($event_return = $Plugins->trigger_event_first_true( 'AlternateAuthentication' ))
547
 
            && $Session->has_User()  # the plugin should have attached the user to $Session
 
391
{
 
392
        // The Session has no user or $login is given (and differs from current user), allow alternate authentication through Plugin:
 
393
        if( ( $event_return = $Plugins->trigger_event_first_true( 'AlternateAuthentication' ) )
 
394
                && $Session->has_User() # the plugin should have attached the user to $Session
548
395
        )
549
396
        {
550
 
                $Debuglog->add( 'User has been authenticated through plugin #'.$event_return['plugin_ID'].' (AlternateAuthentication)', 'login' );
551
397
                $current_User = & $UserCache->get_by_ID( $Session->user_ID );
552
398
        }
553
399
        elseif( $login_required )
554
 
        { // User was not logged in at all, but login is required
555
 
                $Debuglog->add( 'NOT logged in... (did not try)', 'login' );
556
 
 
 
400
        {
 
401
                // User was not logged in at all, but login is required
557
402
                $Messages->add( T_('You must log in!'), 'login_error' );
558
403
        }
559
404
}
560
 
unset($pass);
 
405
unset( $pass );
561
406
 
562
407
// Check if the user needs to be validated, but is not yet:
563
 
// TODO: dh> this block prevents registration, if you are logged in already, but not validated!
564
 
//       (e.g. when registered as "foo", you cannot register as "bar" until you logout (but there's no link in sight)
565
 
//        or validate the "foo" account)
566
 
if( ! empty($current_User)
 
408
// @todo (0000) dh> this block prevents registration, if you are logged in already, but not
 
409
// validated! (e.g. when registered as "foo", you cannot register as "bar" until you logout
 
410
// (but there's no link in sight) or validate the "foo" account)
 
411
if( ! empty( $current_User )
567
412
                && ! $current_User->validated
568
 
                && $Settings->get('newusers_mustvalidate') // same check as in login.php
 
413
                && $Settings->get( 'newusers_mustvalidate' ) // same check as in login.php
569
414
                && param('action', 'string', '') != 'logout' ) // fp> TODO: non validated users should be automatically logged out
570
415
{
571
416
        if( $action != 'req_validatemail' && $action != 'validatemail' )
572
 
        { // we're not in that action already:
 
417
        {
 
418
                // we're not in that action already:
573
419
                $action = 'req_validatemail'; // for login.php
574
420
                $Messages->add( T_('You must validate your email address before you can log in.'), 'login_error' );
575
421
        }
576
422
}
577
423
else
578
 
{ // Trigger plugin event that allows the plugins to re-act on the login event:
579
 
        if( empty($current_User) )
 
424
{
 
425
        // Trigger plugin event that allows the plugins to re-act on the login event:
 
426
        if( empty( $current_User ) )
580
427
        {
581
428
                $Plugins->trigger_event( 'AfterLoginAnonymousUser', array() );
582
429
        }
584
431
        {
585
432
                $Plugins->trigger_event( 'AfterLoginRegisteredUser', array() );
586
433
 
587
 
                if( ! empty($login_action) )
588
 
                { // We're coming from the Login form and need to redirect to the requested page:
 
434
                if( ! empty( $login_action ) )
 
435
                {
 
436
                        // We're coming from the Login form and need to redirect to the requested page:
589
437
                        if( $login_action == 'redirect_to_backoffice' )
590
 
                        { // user pressed the "Log into backoffice!" button
 
438
                        {
 
439
                                // user pressed the "Log into backoffice!" button
591
440
                                $redirect_to = $admin_url;
592
441
                        }
593
442
                        else
603
452
 
604
453
// If there are "login_error" messages, they trigger the login form at the end of this file.
605
454
 
606
 
/* Login procedure }}} */
607
 
 
608
 
 
609
 
/**
610
 
 * User locale selection:
611
 
 */
612
 
if( is_logged_in() && $current_User->get('locale') != $current_locale
613
 
                && !$locale_from_get )
614
 
{ // change locale to users preference
615
 
        /*
616
 
         * User locale selection:
617
 
         * TODO: this should get done before instantiating $current_User, because we already use T_() there...
618
 
         */
619
 
        locale_activate( $current_User->get('locale') );
620
 
        if( $current_locale == $current_User->get('locale') )
 
455
// Login procedure ...
 
456
 
 
457
// User locale selection
 
458
if( is_logged_in() && $current_User->get( 'locale' ) != $current_locale && ! $locale_from_get )
 
459
{
 
460
        // User locale selection: change locale to users preference
 
461
        // @todo (0000) this should get done before instantiating $current_User, because we already use T_() there...
 
462
        locale_activate( $current_User->get( 'locale' ) );
 
463
        if( $current_locale == $current_User->get( 'locale' ) )
621
464
        {
622
465
                $default_locale = $current_locale;
623
 
                $Debuglog->add( 'default_locale from user profile: '.$default_locale, 'locale' );
624
 
        }
625
 
        else
626
 
        {
627
 
                $Debuglog->add( 'locale from user profile could not be activated: '.$current_User->get('locale'), 'locale' );
628
466
        }
629
467
}
630
468
 
631
 
 
632
 
// Init charset handling:
633
 
// TODO: dh> anything translated before this call might have encoding issues (e.g. the login form!)
 
469
// Init charset handling
 
470
// @todo (0000) dh> anything translated before this call might have encoding issues (e.g. the login form!)
634
471
init_charsets( $current_charset );
635
472
 
636
 
 
637
473
// Display login errors (and form). This uses $io_charset, so it's at the end.
638
474
 
639
475
if( $Messages->count( 'login_error' ) )
644
480
 
645
481
$Timer->pause( '_main.inc');
646
482
 
647
 
 
648
 
/**
649
 
 * Load hacks file if it exists
650
 
 */
651
 
if( file_exists($conf_path.'hacks.php') )
 
483
if( file_exists( $conf_path.'hacks.php' ) )
652
484
{
653
485
        $Timer->resume( 'hacks.php' );
 
486
        /**
 
487
         * Load hacks file if it exists
 
488
         */
654
489
        include_once $conf_path.'hacks.php';
655
490
        $Timer->pause( 'hacks.php' );
656
491
}
657
492
 
658
 
 
659
493
?>