Completed
Branch develop (451d3e)
by
unknown
27:33
created

main.inc.php ➔ printSearchForm()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 23
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 18
nc 8
nop 9
dl 0
loc 23
rs 8.7972
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* Copyright (C) 2002-2007  Rodolphe Quiedeville    <[email protected]>
3
 * Copyright (C) 2003       Xavier Dutoit           <[email protected]>
4
 * Copyright (C) 2004-2015  Laurent Destailleur     <[email protected]>
5
 * Copyright (C) 2004       Sebastien Di Cintio     <[email protected]>
6
 * Copyright (C) 2004       Benoit Mortier          <[email protected]>
7
 * Copyright (C) 2005-2015  Regis Houssin           <[email protected]>
8
 * Copyright (C) 2011-2014  Philippe Grand          <[email protected]>
9
 * Copyright (C) 2008       Matteli
10
 * Copyright (C) 2011-2016  Juanjo Menent           <[email protected]>
11
 * Copyright (C) 2012       Christophe Battarel     <[email protected]>
12
 * Copyright (C) 2014-2015  Marcos García           <[email protected]>
13
 * Copyright (C) 2015       Raphaël Doursenaud      <[email protected]>
14
 *
15
 * This program is free software; you can redistribute it and/or modify
16
 * it under the terms of the GNU General Public License as published by
17
 * the Free Software Foundation; either version 3 of the License, or
18
 * (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27
 */
28
29
/**
30
 *	\file       htdocs/main.inc.php
31
 *	\ingroup	core
32
 *	\brief      File that defines environment for Dolibarr GUI pages only (file not required by scripts)
33
 */
34
35
//@ini_set('memory_limit', '128M');	// This may be useless if memory is hard limited by your PHP
36
37
// For optional tuning. Enabled if environment variable MAIN_SHOW_TUNING_INFO is defined.
38
$micro_start_time=0;
39
if (! empty($_SERVER['MAIN_SHOW_TUNING_INFO']))
40
{
41
	list($usec, $sec) = explode(" ", microtime());
42
	$micro_start_time=((float) $usec + (float) $sec);
43
	// Add Xdebug code coverage
44
	//define('XDEBUGCOVERAGE',1);
45
	if (defined('XDEBUGCOVERAGE')) {
46
		xdebug_start_code_coverage();
47
	}
48
}
49
50
// Removed magic_quotes
51
if (function_exists('get_magic_quotes_gpc'))	// magic_quotes_* deprecated in PHP 5.0 and removed in PHP 5.5
52
{
53
	if (get_magic_quotes_gpc())
54
	{
55
		// Forcing parameter setting magic_quotes_gpc and cleaning parameters
56
		// (Otherwise he would have for each position, condition
57
		// Reading stripslashes variable according to state get_magic_quotes_gpc).
58
		// Off mode recommended (just do $db->escape for insert / update).
59
		function stripslashes_deep($value)
0 ignored issues
show
Best Practice introduced by
The function stripslashes_deep() has been defined more than once; this definition is ignored, only the first definition in htdocs/install/inc.php (L255-258) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
60
		{
61
			return (is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value));
62
		}
63
		$_GET     = array_map('stripslashes_deep', $_GET);
64
		$_POST    = array_map('stripslashes_deep', $_POST);
65
		$_FILES   = array_map('stripslashes_deep', $_FILES);
66
		//$_COOKIE  = array_map('stripslashes_deep', $_COOKIE); // Useless because a cookie should never be outputed on screen nor used into sql
67
		@set_magic_quotes_runtime(0);
68
	}
69
}
70
71
/**
72
 * Security: SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF).
73
 *
74
 * @param		string		$val		Value
75
 * @param		string		$type		1=GET, 0=POST, 2=PHP_SELF
76
 * @return		int						>0 if there is an injection
77
 */
78
function test_sql_and_script_inject($val, $type)
79
{
80
	$inj = 0;
81
	// For SQL Injection (only GET and POST are used to be included into bad escaped SQL requests)
82
	if ($type != 2)
83
	{
84
		$inj += preg_match('/delete\s+from/i',	 $val);
85
		$inj += preg_match('/create\s+table/i',	 $val);
86
		$inj += preg_match('/update.+set.+=/i',  $val);
87
		$inj += preg_match('/insert\s+into/i', 	 $val);
88
		$inj += preg_match('/select.+from/i', 	 $val);
89
		$inj += preg_match('/union.+select/i', 	 $val);
90
		$inj += preg_match('/into\s+(outfile|dumpfile)/i',  $val);
91
		$inj += preg_match('/(\.\.%2f)+/i',		 $val);
92
	}
93
	// For XSS Injection done by adding javascript with script
94
	// This is all cases a browser consider text is javascript:
95
	// When it found '<script', 'javascript:', '<style', 'onload\s=' on body tag, '="&' on a tag size with old browsers
96
	// All examples on page: http://ha.ckers.org/xss.html#XSScalc
97
	// More on https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
98
	$inj += preg_match('/<script/i', $val);
99
	$inj += preg_match('/<iframe/i', $val);
100
	$inj += preg_match('/Set\.constructor/i', $val);	// ECMA script 6
101
	if (! defined('NOSTYLECHECK')) $inj += preg_match('/<style/i', $val);
102
	$inj += preg_match('/base[\s]+href/si', $val);
103
	$inj += preg_match('/<.*onmouse/si', $val);       // onmousexxx can be set on img or any html tag like <img title='...' onmouseover=alert(1)>
104
	$inj += preg_match('/onerror\s*=/i', $val);       // onerror can be set on img or any html tag like <img title='...' onerror = alert(1)>
105
	$inj += preg_match('/onfocus\s*=/i', $val);       // onfocus can be set on input text html tag like <input type='text' value='...' onfocus = alert(1)>
106
	$inj += preg_match('/onload\s*=/i', $val);        // onload can be set on svg tag <svg/onload=alert(1)> or other tag like body <body onload=alert(1)>
107
	//$inj += preg_match('/on[A-Z][a-z]+\*=/', $val);   // To lock event handlers onAbort(), ...
108
	$inj += preg_match('/&#58;|&#0000058|&#x3A/i', $val);		// refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...'
109
	//if ($type == 1)
110
	//{
111
		$inj += preg_match('/javascript:/i', $val);
112
		$inj += preg_match('/vbscript:/i', $val);
113
	//}
114
	// For XSS Injection done by adding javascript closing html tags like with onmousemove, etc... (closing a src or href tag with not cleaned param)
115
	if ($type == 1) $inj += preg_match('/"/i', $val);		// We refused " in GET parameters value
116
	if ($type == 2) $inj += preg_match('/[;"]/', $val);		// PHP_SELF is a file system path. It can contains spaces.
117
	return $inj;
118
}
119
120
/**
121
 * Return true if security check on parameters are OK, false otherwise.
122
 *
123
 * @param		string			$var		Variable name
124
 * @param		string			$type		1=GET, 0=POST, 2=PHP_SELF
125
 * @return		boolean||null				true if there is an injection. Stop code if injection found.
126
 */
127
function analyseVarsForSqlAndScriptsInjection(&$var, $type)
128
{
129
	if (is_array($var))
130
	{
131
		foreach ($var as $key => $value)
132
		{
133
			if (analyseVarsForSqlAndScriptsInjection($value,$type))
134
			{
135
				$var[$key] = $value;
136
			}
137
			else
138
			{
139
				print 'Access refused by SQL/Script injection protection in main.inc.php (type='.htmlentities($type).' key='.htmlentities($key).' value='.htmlentities($value).' page='.htmlentities($_SERVER["REQUEST_URI"]).')';
140
				exit;
141
			}
142
		}
143
		return true;
144
	}
145
	else
146
	{
147
		return (test_sql_and_script_inject($var,$type) <= 0);
148
	}
149
}
150
151
152
// Check consistency of NOREQUIREXXX DEFINES
153
if ((defined('NOREQUIREDB') || defined('NOREQUIRETRAN')) && ! defined('NOREQUIREMENU')) dol_print_error('','If define NOREQUIREDB or NOREQUIRETRAN are set, you must also set NOREQUIREMENU or not use them');
154
155
// Sanity check on URL
156
if (! empty($_SERVER["PHP_SELF"]))
157
{
158
	$morevaltochecklikepost=array($_SERVER["PHP_SELF"]);
159
	analyseVarsForSqlAndScriptsInjection($morevaltochecklikepost,2);
160
}
161
// Sanity check on GET parameters
162
if (! defined('NOSCANGETFORINJECTION') && ! empty($_SERVER["QUERY_STRING"]))
163
{
164
	$morevaltochecklikeget=array($_SERVER["QUERY_STRING"]);
165
	analyseVarsForSqlAndScriptsInjection($morevaltochecklikeget,1);
166
}
167
// Sanity check on POST
168
if (! defined('NOSCANPOSTFORINJECTION'))
169
{
170
	analyseVarsForSqlAndScriptsInjection($_POST,0);
171
}
172
173
// This is to make Dolibarr working with Plesk
174
if (! empty($_SERVER['DOCUMENT_ROOT']) && substr($_SERVER['DOCUMENT_ROOT'], -6) !== 'htdocs')
175
{
176
	set_include_path($_SERVER['DOCUMENT_ROOT'] . '/htdocs');
177
}
178
179
// Include the conf.php and functions.lib.php
180
require_once 'filefunc.inc.php';
181
182
// If there is a POST parameter to tell to save automatically some POST parameters into cookies, we do it.
183
// This is used for example by form of boxes to save personalization of some options.
184
// DOL_AUTOSET_COOKIE=cookiename:val1,val2 and  cookiename_val1=aaa cookiename_val2=bbb will set cookie_name with value json_encode(array('val1'=> , ))
185
if (! empty($_POST["DOL_AUTOSET_COOKIE"]))
186
{
187
	$tmpautoset=explode(':',$_POST["DOL_AUTOSET_COOKIE"],2);
188
	$tmplist=explode(',',$tmpautoset[1]);
189
	$cookiearrayvalue='';
190
	foreach ($tmplist as $tmpkey)
191
	{
192
		$postkey=$tmpautoset[0].'_'.$tmpkey;
193
		//var_dump('tmpkey='.$tmpkey.' postkey='.$postkey.' value='.$_POST[$postkey]);
194
		if (! empty($_POST[$postkey])) $cookiearrayvalue[$tmpkey]=$_POST[$postkey];
195
	}
196
	$cookiename=$tmpautoset[0];
197
	$cookievalue=json_encode($cookiearrayvalue);
198
	//var_dump('setcookie cookiename='.$cookiename.' cookievalue='.$cookievalue);
199
	setcookie($cookiename, empty($cookievalue)?'':$cookievalue, empty($cookievalue)?0:(time()+(86400*354)), '/', null, false, true);	// keep cookie 1 year and add tag httponly
200
	if (empty($cookievalue)) unset($_COOKIE[$cookiename]);
201
}
202
203
// Init session. Name of session is specific to Dolibarr instance.
204
$prefix=dol_getprefix();
205
$sessionname='DOLSESSID_'.$prefix;
206
$sessiontimeout='DOLSESSTIMEOUT_'.$prefix;
207
if (! empty($_COOKIE[$sessiontimeout])) ini_set('session.gc_maxlifetime',$_COOKIE[$sessiontimeout]);
208
session_name($sessionname);
209
session_set_cookie_params(0, '/', null, false, true);   // Add tag httponly on session cookie (same as setting session.cookie_httponly into php.ini). Must be called before the session_start.
210
// This create lock released until session_write_close() or end of page.
211
// We need this lock as long as we read/write $_SESSION ['vars']. We can close released when finished.
212
if (! defined('NOSESSION'))
213
{
214
	session_start();
215
	if (ini_get('register_globals'))    // Deprecated in 5.3 and removed in 5.4. To solve bug in using $_SESSION
216
	{
217
		foreach ($_SESSION as $key=>$value)
218
		{
219
			if (isset($GLOBALS[$key])) unset($GLOBALS[$key]);
220
		}
221
	}
222
}
223
224
// Init the 5 global objects, this include will make the new and set properties for: $conf, $db, $langs, $user, $mysoc
225
require_once 'master.inc.php';
226
227
// Activate end of page function
228
register_shutdown_function('dol_shutdown');
229
230
// Detection browser
231
if (isset($_SERVER["HTTP_USER_AGENT"]))
232
{
233
	$tmp=getBrowserInfo($_SERVER["HTTP_USER_AGENT"]);
234
	$conf->browser->name=$tmp['browsername'];
235
	$conf->browser->os=$tmp['browseros'];
236
	$conf->browser->version=$tmp['browserversion'];
237
	$conf->browser->layout=$tmp['layout'];     // 'classic', 'phone', 'tablet'
238
	$conf->browser->phone=$tmp['phone'];	   // TODO deprecated, use ->layout
239
	$conf->browser->tablet=$tmp['tablet'];	   // TODO deprecated, use ->layout
240
	//var_dump($conf->browser);
241
242
	if ($conf->browser->layout == 'phone') $conf->dol_no_mouse_hover=1;
243
	if ($conf->browser->layout == 'phone') $conf->global->MAIN_TESTMENUHIDER=1;
244
}
245
246
// Force HTTPS if required ($conf->file->main_force_https is 0/1 or https dolibarr root url)
247
// $_SERVER["HTTPS"] is 'on' when link is https, otherwise $_SERVER["HTTPS"] is empty or 'off'
248
if (! empty($conf->file->main_force_https) && (empty($_SERVER["HTTPS"]) || $_SERVER["HTTPS"] != 'on'))
249
{
250
	$newurl='';
251
	if (is_numeric($conf->file->main_force_https))
252
	{
253
		if ($conf->file->main_force_https == '1' && ! empty($_SERVER["SCRIPT_URI"]))	// If SCRIPT_URI supported by server
254
		{
255
			if (preg_match('/^http:/i',$_SERVER["SCRIPT_URI"]) && ! preg_match('/^https:/i',$_SERVER["SCRIPT_URI"]))	// If link is http
256
			{
257
				$newurl=preg_replace('/^http:/i','https:',$_SERVER["SCRIPT_URI"]);
258
			}
259
		}
260
		else	// Check HTTPS environment variable (Apache/mod_ssl only)
261
		{
262
			$newurl=preg_replace('/^http:/i','https:',DOL_MAIN_URL_ROOT).$_SERVER["REQUEST_URI"];
263
		}
264
	}
265
	else
266
	{
267
		// Check HTTPS environment variable (Apache/mod_ssl only)
268
		$newurl=$conf->file->main_force_https.$_SERVER["REQUEST_URI"];
269
	}
270
	// Start redirect
271
	if ($newurl)
272
	{
273
		dol_syslog("main.inc: dolibarr_main_force_https is on, we make a redirect to ".$newurl);
274
		header("Location: ".$newurl);
275
		exit;
276
	}
277
	else
278
	{
279
		dol_syslog("main.inc: dolibarr_main_force_https is on but we failed to forge new https url so no redirect is done", LOG_WARNING);
280
	}
281
}
282
283
284
// Loading of additional presentation includes
285
if (! defined('NOREQUIREHTML')) require_once DOL_DOCUMENT_ROOT .'/core/class/html.form.class.php';	    // Need 660ko memory (800ko in 2.2)
286
if (! defined('NOREQUIREAJAX') && $conf->use_javascript_ajax) require_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';	// Need 22ko memory
287
288
// If install or upgrade process not done or not completely finished, we call the install page.
289
if (! empty($conf->global->MAIN_NOT_INSTALLED) || ! empty($conf->global->MAIN_NOT_UPGRADED))
290
{
291
	dol_syslog("main.inc: A previous install or upgrade was not complete. Redirect to install page.", LOG_WARNING);
292
	header("Location: ".DOL_URL_ROOT."/install/index.php");
293
	exit;
294
}
295
// If an upgrade process is required, we call the install page.
296
if ((! empty($conf->global->MAIN_VERSION_LAST_UPGRADE) && ($conf->global->MAIN_VERSION_LAST_UPGRADE != DOL_VERSION))
297
|| (empty($conf->global->MAIN_VERSION_LAST_UPGRADE) && ! empty($conf->global->MAIN_VERSION_LAST_INSTALL) && ($conf->global->MAIN_VERSION_LAST_INSTALL != DOL_VERSION)))
298
{
299
	$versiontocompare=empty($conf->global->MAIN_VERSION_LAST_UPGRADE)?$conf->global->MAIN_VERSION_LAST_INSTALL:$conf->global->MAIN_VERSION_LAST_UPGRADE;
300
	require_once DOL_DOCUMENT_ROOT .'/core/lib/admin.lib.php';
301
	$dolibarrversionlastupgrade=preg_split('/[.-]/',$versiontocompare);
302
	$dolibarrversionprogram=preg_split('/[.-]/',DOL_VERSION);
303
	$rescomp=versioncompare($dolibarrversionprogram,$dolibarrversionlastupgrade);
304
	if ($rescomp > 0)   // Programs have a version higher than database. We did not add "&& $rescomp < 3" because we want upgrade process for build upgrades
305
	{
306
		dol_syslog("main.inc: database version ".$versiontocompare." is lower than programs version ".DOL_VERSION.". Redirect to install page.", LOG_WARNING);
307
		header("Location: ".DOL_URL_ROOT."/install/index.php");
308
		exit;
309
	}
310
}
311
312
// Creation of a token against CSRF vulnerabilities
313
if (! defined('NOTOKENRENEWAL'))
314
{
315
	// roulement des jetons car cree a chaque appel
316
	if (isset($_SESSION['newtoken'])) $_SESSION['token'] = $_SESSION['newtoken'];
317
318
	// Save in $_SESSION['newtoken'] what will be next token. Into forms, we will add param token = $_SESSION['newtoken']
319
	$token = dol_hash(uniqid(mt_rand(),TRUE)); // Generates a hash of a random number
320
	$_SESSION['newtoken'] = $token;
321
}
322
if (! defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && ! empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN))	// Check validity of token, only if option enabled (this option breaks some features sometimes)
323
{
324
	if ($_SERVER['REQUEST_METHOD'] == 'POST' && ! GETPOST('token','alpha')) // Note, offender can still send request by GET
325
	{
326
		print "Access refused by CSRF protection in main.inc.php. Token not provided.\n";
327
		print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file).\n";
328
		die;
329
	}
330
	if ($_SERVER['REQUEST_METHOD'] === 'POST')  // This test must be after loading $_SESSION['token'].
331
	{
332
		if (GETPOST('token', 'alpha') != $_SESSION['token'])
333
		{
334
			dol_syslog("Invalid token in ".$_SERVER['HTTP_REFERER'].", action=".GETPOST('action','aZ09').", _POST['token']=".GETPOST('token','alpha').", _SESSION['token']=".$_SESSION['token'], LOG_WARNING);
335
			//print 'Unset POST by CSRF protection in main.inc.php.';	// Do not output anything because this create problems when using the BACK button on browsers.
336
			unset($_POST);
337
		}
338
	}
339
}
340
341
// Disable modules (this must be after session_start and after conf has been loaded)
342
if (GETPOST('disablemodules','alpha'))  $_SESSION["disablemodules"]=GETPOST('disablemodules','alpha');
343
if (! empty($_SESSION["disablemodules"]))
344
{
345
	$disabled_modules=explode(',',$_SESSION["disablemodules"]);
346
	foreach($disabled_modules as $module)
347
	{
348
		if ($module)
349
		{
350
			if (empty($conf->$module)) $conf->$module=new stdClass();
351
			$conf->$module->enabled=false;
352
			if ($module == 'fournisseur')		// Special case
353
			{
354
				$conf->supplier_order->enabled=0;
355
				$conf->supplier_invoice->enabled=0;
356
			}
357
		}
358
	}
359
}
360
361
362
/*
363
 * Phase authentication / login
364
 */
365
$login='';
366
if (! defined('NOLOGIN'))
367
{
368
	// $authmode lists the different means of identification to be tested in order of preference.
369
	// Example: 'http', 'dolibarr', 'ldap', 'http,forceuser'
370
371
	// Authentication mode
372
	if (empty($dolibarr_main_authentication)) $dolibarr_main_authentication='http,dolibarr';
373
	// Authentication mode: forceuser
374
	if ($dolibarr_main_authentication == 'forceuser' && empty($dolibarr_auto_user)) $dolibarr_auto_user='auto';
375
	// Set authmode
376
	$authmode=explode(',',$dolibarr_main_authentication);
377
378
	// No authentication mode
379
	if (! count($authmode))
380
	{
381
		$langs->load('main');
382
		dol_print_error('',$langs->trans("ErrorConfigParameterNotDefined",'dolibarr_main_authentication'));
383
		exit;
384
	}
385
386
	// If login request was already post, we retrieve login from the session
387
	// Call module if not realized that his request.
388
	// At the end of this phase, the variable $login is defined.
389
	$resultFetchUser='';
390
	$test=true;
391
	if (! isset($_SESSION["dol_login"]))
392
	{
393
		// It is not already authenticated and it requests the login / password
394
		include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
395
396
		$dol_dst_observed=GETPOST("dst_observed",'int',3);
397
		$dol_dst_first=GETPOST("dst_first",'int',3);
398
		$dol_dst_second=GETPOST("dst_second",'int',3);
399
		$dol_screenwidth=GETPOST("screenwidth",'int',3);
400
		$dol_screenheight=GETPOST("screenheight",'int',3);
401
		$dol_hide_topmenu=GETPOST('dol_hide_topmenu','int',3);
402
		$dol_hide_leftmenu=GETPOST('dol_hide_leftmenu','int',3);
403
		$dol_optimize_smallscreen=GETPOST('dol_optimize_smallscreen','int',3);
404
		$dol_no_mouse_hover=GETPOST('dol_no_mouse_hover','int',3);
405
		$dol_use_jmobile=GETPOST('dol_use_jmobile','int',3);
406
		//dol_syslog("POST key=".join(array_keys($_POST),',').' value='.join($_POST,','));
407
408
		// If in demo mode, we check we go to home page through the public/demo/index.php page
409
		if (! empty($dolibarr_main_demo) && $_SERVER['PHP_SELF'] == DOL_URL_ROOT.'/index.php')  // We ask index page
410
		{
411
			if (empty($_SERVER['HTTP_REFERER']) || ! preg_match('/public/',$_SERVER['HTTP_REFERER']))
412
			{
413
				dol_syslog("Call index page from another url than demo page (call is done from page ".$_SERVER['HTTP_REFERER'].")");
414
				$url='';
415
				$url.=($url?'&':'').($dol_hide_topmenu?'dol_hide_topmenu='.$dol_hide_topmenu:'');
416
				$url.=($url?'&':'').($dol_hide_leftmenu?'dol_hide_leftmenu='.$dol_hide_leftmenu:'');
417
				$url.=($url?'&':'').($dol_optimize_smallscreen?'dol_optimize_smallscreen='.$dol_optimize_smallscreen:'');
418
				$url.=($url?'&':'').($dol_no_mouse_hover?'dol_no_mouse_hover='.$dol_no_mouse_hover:'');
419
				$url.=($url?'&':'').($dol_use_jmobile?'dol_use_jmobile='.$dol_use_jmobile:'');
420
				$url=DOL_URL_ROOT.'/public/demo/index.php'.($url?'?'.$url:'');
421
				header("Location: ".$url);
422
				exit;
423
			}
424
		}
425
426
		// Verification security graphic code
427
		if (GETPOST("username","alpha",2) && ! empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA))
428
		{
429
			$sessionkey = 'dol_antispam_value';
430
			$ok=(array_key_exists($sessionkey, $_SESSION) === TRUE && (strtolower($_SESSION[$sessionkey]) == strtolower($_POST['code'])));
431
432
			// Check code
433
			if (! $ok)
434
			{
435
				dol_syslog('Bad value for code, connexion refused');
436
				$langs->load('main');
437
				$langs->load('errors');
438
439
				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadValueForCode");
440
				$test=false;
441
442
				// TODO @deprecated Remove this. Hook must be used, not this trigger.
443
				$user->trigger_mesg='ErrorBadValueForCode - login='.GETPOST("username","alpha",2);
444
				// Call of triggers
445
				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
446
				$interface=new Interfaces($db);
447
				$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf);
448
				if ($result < 0) {
449
					$error++;
450
				}
451
				// End Call of triggers
452
453
				// Hooks on failed login
454
				$action='';
455
				$hookmanager->initHooks(array('login'));
456
				$parameters=array('dol_authmode'=>$dol_authmode, 'dol_loginmesg'=>$_SESSION["dol_loginmesg"]);
457
				$reshook=$hookmanager->executeHooks('afterLoginFailed',$parameters,$user,$action);    // Note that $action and $object may have been modified by some hooks
458
				if ($reshook < 0) $error++;
459
460
				// Note: exit is done later
461
			}
462
		}
463
464
		$usertotest		= (! empty($_COOKIE['login_dolibarr']) ? $_COOKIE['login_dolibarr'] : GETPOST("username","alpha",2));
465
		$passwordtotest	= GETPOST('password','none',2);
466
		$entitytotest	= (GETPOST('entity','int') ? GETPOST('entity','int') : (!empty($conf->entity) ? $conf->entity : 1));
467
468
		// Define if we received data to test the login.
469
		$goontestloop=false;
470
		if (isset($_SERVER["REMOTE_USER"]) && in_array('http',$authmode)) $goontestloop=true;
471
		if ($dolibarr_main_authentication == 'forceuser' && ! empty($dolibarr_auto_user)) $goontestloop=true;
472
		if (GETPOST("username","alpha",2) || ! empty($_COOKIE['login_dolibarr']) || GETPOST('openid_mode','alpha',1)) $goontestloop=true;
473
474
		if (! is_object($langs)) // This can occurs when calling page with NOREQUIRETRAN defined, however we need langs for error messages.
475
		{
476
			include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php';
477
			$langs=new Translate("",$conf);
478
			$langcode=(GETPOST('lang','aZ09',1)?GETPOST('lang','aZ09',1):(empty($conf->global->MAIN_LANG_DEFAULT)?'auto':$conf->global->MAIN_LANG_DEFAULT));
479
			$langs->setDefaultLang($langcode);
480
		}
481
482
		// Validation of login/pass/entity
483
		// If ok, the variable login will be returned
484
		// If error, we will put error message in session under the name dol_loginmesg
485
		if ($test && $goontestloop)
486
		{
487
			$login = checkLoginPassEntity($usertotest,$passwordtotest,$entitytotest,$authmode);
488
			if ($login)
489
			{
490
				$dol_authmode=$conf->authmode;	// This properties is defined only when logged, to say what mode was successfully used
491
				$dol_tz=$_POST["tz"];
492
				$dol_tz_string=$_POST["tz_string"];
493
				$dol_tz_string=preg_replace('/\s*\(.+\)$/','',$dol_tz_string);
494
				$dol_tz_string=preg_replace('/,/','/',$dol_tz_string);
495
				$dol_tz_string=preg_replace('/\s/','_',$dol_tz_string);
496
				$dol_dst=0;
497
				if (isset($_POST["dst_first"]) && isset($_POST["dst_second"]))
498
				{
499
					include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
500
					$datenow=dol_now();
501
					$datefirst=dol_stringtotime($_POST["dst_first"]);
502
					$datesecond=dol_stringtotime($_POST["dst_second"]);
503
					if ($datenow >= $datefirst && $datenow < $datesecond) $dol_dst=1;
504
				}
505
				//print $datefirst.'-'.$datesecond.'-'.$datenow.'-'.$dol_tz.'-'.$dol_tzstring.'-'.$dol_dst; exit;
506
			}
507
508
			if (! $login)
509
			{
510
				dol_syslog('Bad password, connexion refused',LOG_DEBUG);
511
				$langs->load('main');
512
				$langs->load('errors');
513
514
				// Bad password. No authmode has found a good password.
515
				// We set a generic message if not defined inside function checkLoginPassEntity or subfunctions
516
				if (empty($_SESSION["dol_loginmesg"])) $_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
517
518
				// TODO @deprecated Remove this. Hook must be used, not this trigger.
519
				$user->trigger_mesg=$langs->trans("ErrorBadLoginPassword").' - login='.GETPOST("username","alpha",2);
520
				// Call of triggers
521
				include_once DOL_DOCUMENT_ROOT.'/core/class/interfaces.class.php';
522
				$interface=new Interfaces($db);
523
				$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf,GETPOST("username","alpha",2));
524
				if ($result < 0) {
525
					$error++;
526
				}
527
				// End Call of triggers
528
529
				// Hooks on failed login
530
				$action='';
531
				$hookmanager->initHooks(array('login'));
532
				$parameters=array('dol_authmode'=>$dol_authmode, 'dol_loginmesg'=>$_SESSION["dol_loginmesg"]);
533
				$reshook=$hookmanager->executeHooks('afterLoginFailed',$parameters,$user,$action);    // Note that $action and $object may have been modified by some hooks
534
				if ($reshook < 0) $error++;
535
536
				// Note: exit is done in next chapter
537
			}
538
		}
539
540
		// End test login / passwords
541
		if (! $login || (in_array('ldap',$authmode) && empty($passwordtotest)))	// With LDAP we refused empty password because some LDAP are "opened" for anonymous access so connexion is a success.
542
		{
543
			// No data to test login, so we show the login page
544
			dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." showing the login form and exit");
545
			if (defined('NOREDIRECTBYMAINTOLOGIN')) return 'ERROR_NOT_LOGGED';
546
			else dol_loginfunction($langs,$conf,(! empty($mysoc)?$mysoc:''));
547
			exit;
548
		}
549
550
		$resultFetchUser=$user->fetch('', $login, '', 1, ($entitytotest > 0 ? $entitytotest : -1));
551
		if ($resultFetchUser <= 0)
552
		{
553
			dol_syslog('User not found, connexion refused');
554
			session_destroy();
555
			session_name($sessionname);
556
			session_set_cookie_params(0, '/', null, false, true);   // Add tag httponly on session cookie
557
			session_start();    // Fixing the bug of register_globals here is useless since session is empty
558
559
			if ($resultFetchUser == 0)
560
			{
561
				$langs->load('main');
562
				$langs->load('errors');
563
564
				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login);
565
566
				// TODO @deprecated Remove this. Hook must be used, not this trigger.
567
				$user->trigger_mesg='ErrorCantLoadUserFromDolibarrDatabase - login='.$login;
568
			}
569
			if ($resultFetchUser < 0)
570
			{
571
				$_SESSION["dol_loginmesg"]=$user->error;
572
573
				// TODO @deprecated Remove this. Hook must be used, not this trigger.
574
				$user->trigger_mesg=$user->error;
575
			}
576
577
			// Call triggers
578
			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
579
			$interface=new Interfaces($db);
580
			$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf);
581
			if ($result < 0) {
582
				$error++;
583
			}
584
			// End call triggers
585
586
			// Hooks on failed login
587
			$action='';
588
			$hookmanager->initHooks(array('login'));
589
			$parameters=array('dol_authmode'=>$dol_authmode, 'dol_loginmesg'=>$_SESSION["dol_loginmesg"]);
590
			$reshook=$hookmanager->executeHooks('afterLoginFailed',$parameters,$user,$action);    // Note that $action and $object may have been modified by some hooks
591
			if ($reshook < 0) $error++;
592
593
			$paramsurl=array();
594
			if (GETPOST('textbrowser','int')) $paramsurl[]='textbrowser='.GETPOST('textbrowser','int');
595
			if (GETPOST('nojs','int'))        $paramsurl[]='nojs='.GETPOST('nojs','int');
596
			if (GETPOST('lang','aZ09'))       $paramsurl[]='lang='.GETPOST('lang','aZ09');
597
			header('Location: '.DOL_URL_ROOT.'/index.php'.(count($paramsurl)?'?'.implode('&',$paramsurl):''));
598
			exit;
599
		}
600
	}
601
	else
602
	{
603
		// We are already into an authenticated session
604
		$login=$_SESSION["dol_login"];
605
		$entity=$_SESSION["dol_entity"];
606
		dol_syslog("- This is an already logged session. _SESSION['dol_login']=".$login." _SESSION['dol_entity']=".$entity, LOG_DEBUG);
607
608
		$resultFetchUser=$user->fetch('', $login, '', 1, ($entity > 0 ? $entity : -1));
609
		if ($resultFetchUser <= 0)
610
		{
611
			// Account has been removed after login
612
			dol_syslog("Can't load user even if session logged. _SESSION['dol_login']=".$login, LOG_WARNING);
613
			session_destroy();
614
			session_name($sessionname);
615
			session_set_cookie_params(0, '/', null, false, true);   // Add tag httponly on session cookie
616
			session_start();    // Fixing the bug of register_globals here is useless since session is empty
617
618
			if ($resultFetchUser == 0)
619
			{
620
				$langs->load('main');
621
				$langs->load('errors');
622
623
				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login);
624
625
				// TODO @deprecated Remove this. Hook must be used, not this trigger.
626
				$user->trigger_mesg='ErrorCantLoadUserFromDolibarrDatabase - login='.$login;
627
			}
628
			if ($resultFetchUser < 0)
629
			{
630
				$_SESSION["dol_loginmesg"]=$user->error;
631
632
				// TODO @deprecated Remove this. Hook must be used, not this trigger.
633
				$user->trigger_mesg=$user->error;
634
			}
635
636
			// TODO @deprecated Remove this. Hook must be used, not this trigger.
637
			// Call triggers
638
			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
639
			$interface=new Interfaces($db);
640
			$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf);
641
			if ($result < 0) {
642
				$error++;
643
			}
644
			// End call triggers
645
646
			// Hooks on failed login
647
			$action='';
648
			$hookmanager->initHooks(array('login'));
649
			$parameters=array('dol_authmode'=>$dol_authmode, 'dol_loginmesg'=>$_SESSION["dol_loginmesg"]);
650
			$reshook=$hookmanager->executeHooks('afterLoginFailed',$parameters,$user,$action);    // Note that $action and $object may have been modified by some hooks
651
			if ($reshook < 0) $error++;
652
653
			$paramsurl=array();
654
			if (GETPOST('textbrowser','int')) $paramsurl[]='textbrowser='.GETPOST('textbrowser','int');
655
			if (GETPOST('nojs','int'))        $paramsurl[]='nojs='.GETPOST('nojs','int');
656
			if (GETPOST('lang','aZ09'))       $paramsurl[]='lang='.GETPOST('lang','aZ09');
657
			header('Location: '.DOL_URL_ROOT.'/index.php'.(count($paramsurl)?'?'.implode('&',$paramsurl):''));
658
			exit;
659
		}
660
		else
661
		{
662
		   // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
663
		   $hookmanager->initHooks(array('main'));
664
665
		   // Code for search criteria persistence.
666
		   if (! empty($_GET['save_lastsearch_values']))    // Keep $_GET here
667
		   {
668
			   $relativepathstring = preg_replace('/\?.*$/','',$_SERVER["HTTP_REFERER"]);
669
			   $relativepathstring = preg_replace('/^https?:\/\/[^\/]*/','',$relativepathstring);     // Get full path except host server
670
			   // Clean $relativepathstring
671
   			   if (constant('DOL_URL_ROOT')) $relativepathstring = preg_replace('/^'.preg_quote(constant('DOL_URL_ROOT'),'/').'/', '', $relativepathstring);
672
			   $relativepathstring = preg_replace('/^\//', '', $relativepathstring);
673
			   $relativepathstring = preg_replace('/^custom\//', '', $relativepathstring);
674
			   //var_dump($relativepathstring);
675
676
			   if (! empty($_SESSION['lastsearch_values_tmp_'.$relativepathstring]))
677
			   {
678
				   $_SESSION['lastsearch_values_'.$relativepathstring]=$_SESSION['lastsearch_values_tmp_'.$relativepathstring];
679
				   unset($_SESSION['lastsearch_values_tmp_'.$relativepathstring]);
680
			   }
681
		   }
682
683
		   $action = '';
684
		   $reshook = $hookmanager->executeHooks('updateSession', array(), $user, $action);
685
		   if ($reshook < 0) {
686
			   setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
687
		   }
688
		}
689
	}
690
691
	// Is it a new session that has started ?
692
	// If we are here, this means authentication was successfull.
693
	if (! isset($_SESSION["dol_login"]))
694
	{
695
		// New session for this login has started.
696
		$error=0;
697
698
		// Store value into session (values always stored)
699
		$_SESSION["dol_login"]=$user->login;
700
		$_SESSION["dol_authmode"]=isset($dol_authmode)?$dol_authmode:'';
701
		$_SESSION["dol_tz"]=isset($dol_tz)?$dol_tz:'';
702
		$_SESSION["dol_tz_string"]=isset($dol_tz_string)?$dol_tz_string:'';
703
		$_SESSION["dol_dst"]=isset($dol_dst)?$dol_dst:'';
704
		$_SESSION["dol_dst_observed"]=isset($dol_dst_observed)?$dol_dst_observed:'';
705
		$_SESSION["dol_dst_first"]=isset($dol_dst_first)?$dol_dst_first:'';
706
		$_SESSION["dol_dst_second"]=isset($dol_dst_second)?$dol_dst_second:'';
707
		$_SESSION["dol_screenwidth"]=isset($dol_screenwidth)?$dol_screenwidth:'';
708
		$_SESSION["dol_screenheight"]=isset($dol_screenheight)?$dol_screenheight:'';
709
		$_SESSION["dol_company"]=$conf->global->MAIN_INFO_SOCIETE_NOM;
710
		$_SESSION["dol_entity"]=$conf->entity;
711
		// Store value into session (values stored only if defined)
712
		if (! empty($dol_hide_topmenu))         $_SESSION['dol_hide_topmenu']=$dol_hide_topmenu;
713
		if (! empty($dol_hide_leftmenu))        $_SESSION['dol_hide_leftmenu']=$dol_hide_leftmenu;
714
		if (! empty($dol_optimize_smallscreen)) $_SESSION['dol_optimize_smallscreen']=$dol_optimize_smallscreen;
715
		if (! empty($dol_no_mouse_hover))       $_SESSION['dol_no_mouse_hover']=$dol_no_mouse_hover;
716
		if (! empty($dol_use_jmobile))          $_SESSION['dol_use_jmobile']=$dol_use_jmobile;
717
718
		dol_syslog("This is a new started user session. _SESSION['dol_login']=".$_SESSION["dol_login"]." Session id=".session_id());
719
720
		$db->begin();
721
722
		$user->update_last_login_date();
723
724
		$loginfo = 'TZ='.$_SESSION["dol_tz"].';TZString='.$_SESSION["dol_tz_string"].';Screen='.$_SESSION["dol_screenwidth"].'x'.$_SESSION["dol_screenheight"];
725
726
		// TODO @deprecated Remove this. Hook must be used, not this trigger.
727
		$user->trigger_mesg = $loginfo;
728
		// Call triggers
729
		include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
730
		$interface=new Interfaces($db);
731
		$result=$interface->run_triggers('USER_LOGIN',$user,$user,$langs,$conf);
732
		if ($result < 0) {
733
			$error++;
734
		}
735
		// End call triggers
736
737
		// Hooks on successfull login
738
		$action='';
739
		$hookmanager->initHooks(array('login'));
740
		$parameters=array('dol_authmode'=>$dol_authmode, 'dol_loginfo'=>$loginfo);
741
		$reshook=$hookmanager->executeHooks('afterLogin',$parameters,$user,$action);    // Note that $action and $object may have been modified by some hooks
742
		if ($reshook < 0) $error++;
743
744
		if ($error)
745
		{
746
			$db->rollback();
747
			session_destroy();
748
			dol_print_error($db,'Error in some hooks afterLogin (or old trigger USER_LOGIN)');
749
			exit;
750
		}
751
		else
752
		{
753
			$db->commit();
754
		}
755
756
		// Change landing page if defined.
757
		$landingpage=(empty($user->conf->MAIN_LANDING_PAGE)?(empty($conf->global->MAIN_LANDING_PAGE)?'':$conf->global->MAIN_LANDING_PAGE):$user->conf->MAIN_LANDING_PAGE);
758
		if (! empty($landingpage))    // Example: /index.php
759
		{
760
			$newpath=dol_buildpath($landingpage, 1);
761
			if ($_SERVER["PHP_SELF"] != $newpath)   // not already on landing page (avoid infinite loop)
762
			{
763
				header('Location: '.$newpath);
764
				exit;
765
			}
766
		}
767
	}
768
769
770
	// If user admin, we force the rights-based modules
771
	if ($user->admin)
772
	{
773
		$user->rights->user->user->lire=1;
774
		$user->rights->user->user->creer=1;
775
		$user->rights->user->user->password=1;
776
		$user->rights->user->user->supprimer=1;
777
		$user->rights->user->self->creer=1;
778
		$user->rights->user->self->password=1;
779
	}
780
781
	/*
782
     * Overwrite some configs globals (try to avoid this and have code to use instead $user->conf->xxx)
783
     */
784
785
	// Set liste_limit
786
	if (isset($user->conf->MAIN_SIZE_LISTE_LIMIT))	$conf->liste_limit = $user->conf->MAIN_SIZE_LISTE_LIMIT;	// Can be 0
787
	if (isset($user->conf->PRODUIT_LIMIT_SIZE))	$conf->product->limit_size = $user->conf->PRODUIT_LIMIT_SIZE;	// Can be 0
788
789
	// Replace conf->css by personalized value if theme not forced
790
	if (empty($conf->global->MAIN_FORCETHEME) && ! empty($user->conf->MAIN_THEME))
791
	{
792
		$conf->theme=$user->conf->MAIN_THEME;
793
		$conf->css  = "/theme/".$conf->theme."/style.css.php";
794
	}
795
}
796
797
// Case forcing style from url
798
if (GETPOST('theme','alpha'))
799
{
800
	$conf->theme=GETPOST('theme','alpha',1);
801
	$conf->css  = "/theme/".$conf->theme."/style.css.php";
802
}
803
804
805
// Set javascript option
806
if (! GETPOST('nojs','int'))   // If javascript was not disabled on URL
807
{
808
	if (! empty($user->conf->MAIN_DISABLE_JAVASCRIPT))
809
	{
810
		$conf->use_javascript_ajax=! $user->conf->MAIN_DISABLE_JAVASCRIPT;
811
	}
812
}
813
else $conf->use_javascript_ajax=0;
814
// Set MAIN_OPTIMIZEFORTEXTBROWSER
815
if (GETPOST('textbrowser','int') || (! empty($conf->browser->name) && $conf->browser->name == 'lynxlinks') || ! empty($user->conf->MAIN_OPTIMIZEFORTEXTBROWSER))   // If we must enable text browser
816
{
817
	$conf->global->MAIN_OPTIMIZEFORTEXTBROWSER=1;
818
}
819
elseif (! empty($user->conf->MAIN_OPTIMIZEFORTEXTBROWSER))
820
{
821
	$conf->global->MAIN_OPTIMIZEFORTEXTBROWSER=$user->conf->MAIN_OPTIMIZEFORTEXTBROWSER;
822
}
823
824
// Set terminal output option according to conf->browser.
825
if (GETPOST('dol_hide_leftmenu','int') || ! empty($_SESSION['dol_hide_leftmenu']))               $conf->dol_hide_leftmenu=1;
826
if (GETPOST('dol_hide_topmenu','int') || ! empty($_SESSION['dol_hide_topmenu']))                 $conf->dol_hide_topmenu=1;
827
if (GETPOST('dol_optimize_smallscreen','int') || ! empty($_SESSION['dol_optimize_smallscreen'])) $conf->dol_optimize_smallscreen=1;
828
if (GETPOST('dol_no_mouse_hover','int') || ! empty($_SESSION['dol_no_mouse_hover']))             $conf->dol_no_mouse_hover=1;
829
if (GETPOST('dol_use_jmobile','int') || ! empty($_SESSION['dol_use_jmobile']))                   $conf->dol_use_jmobile=1;
830
if (! empty($conf->browser->layout) && $conf->browser->layout != 'classic') $conf->dol_no_mouse_hover=1;
831
if ((! empty($conf->browser->layout) && $conf->browser->layout == 'phone')
832
	|| (! empty($_SESSION['dol_screenwidth']) && $_SESSION['dol_screenwidth'] < 400)
833
	|| (! empty($_SESSION['dol_screenheight']) && $_SESSION['dol_screenheight'] < 400)
834
)
835
{
836
	$conf->dol_optimize_smallscreen=1;
837
}
838
// If we force to use jmobile, then we reenable javascript
839
if (! empty($conf->dol_use_jmobile)) $conf->use_javascript_ajax=1;
840
// Replace themes bugged with jmobile with eldy
841
if (! empty($conf->dol_use_jmobile) && in_array($conf->theme,array('bureau2crea','cameleo','amarok')))
842
{
843
	$conf->theme='eldy';
844
	$conf->css  =  "/theme/".$conf->theme."/style.css.php";
845
}
846
//var_dump($conf->browser->phone);
847
848
if (! defined('NOREQUIRETRAN'))
849
{
850
	if (! GETPOST('lang','aZ09'))	// If language was not forced on URL
851
	{
852
		// If user has chosen its own language
853
		if (! empty($user->conf->MAIN_LANG_DEFAULT))
854
		{
855
			// If different than current language
856
			//print ">>>".$langs->getDefaultLang()."-".$user->conf->MAIN_LANG_DEFAULT;
857
			if ($langs->getDefaultLang() != $user->conf->MAIN_LANG_DEFAULT)
858
			{
859
				$langs->setDefaultLang($user->conf->MAIN_LANG_DEFAULT);
860
			}
861
		}
862
	}
863
}
864
865
if (! defined('NOLOGIN'))
866
{
867
	// If the login is not recovered, it is identified with an account that does not exist.
868
	// Hacking attempt?
869
	if (! $user->login) accessforbidden();
870
871
	// Check if user is active
872
	if ($user->statut < 1)
873
	{
874
		// If not active, we refuse the user
875
		$langs->load("other");
876
		dol_syslog("Authentification ko as login is disabled");
877
		accessforbidden($langs->trans("ErrorLoginDisabled"));
878
		exit;
879
	}
880
881
	// Load permissions
882
	$user->getrights();
883
}
884
885
886
dol_syslog("--- Access to ".$_SERVER["PHP_SELF"].' - action='.GETPOST('action','az09').', massaction='.GETPOST('massaction','az09'));
887
//Another call for easy debugg
888
//dol_syslog("Access to ".$_SERVER["PHP_SELF"].' GET='.join(',',array_keys($_GET)).'->'.join(',',$_GET).' POST:'.join(',',array_keys($_POST)).'->'.join(',',$_POST));
889
890
// Load main languages files
891
if (! defined('NOREQUIRETRAN'))
892
{
893
	$langs->load("main");
894
	$langs->load("dict");
895
}
896
897
// Define some constants used for style of arrays
898
$bc=array(0=>'class="impair"',1=>'class="pair"');
899
$bcdd=array(0=>'class="drag drop oddeven"',1=>'class="drag drop oddeven"');
900
$bcnd=array(0=>'class="nodrag nodrop nohover"',1=>'class="nodrag nodrop nohoverpair"');		// Used for tr to add new lines
901
$bctag=array(0=>'class="impair tagtr"',1=>'class="pair tagtr"');
902
903
// Define messages variables
904
$mesg=''; $warning=''; $error=0;
905
// deprecated, see setEventMessages() and dol_htmloutput_events()
906
$mesgs=array(); $warnings=array(); $errors=array();
907
908
// Constants used to defined number of lines in textarea
909
if (empty($conf->browser->firefox))
910
{
911
	define('ROWS_1',1);
912
	define('ROWS_2',2);
913
	define('ROWS_3',3);
914
	define('ROWS_4',4);
915
	define('ROWS_5',5);
916
	define('ROWS_6',6);
917
	define('ROWS_7',7);
918
	define('ROWS_8',8);
919
	define('ROWS_9',9);
920
}
921
else
922
{
923
	define('ROWS_1',0);
924
	define('ROWS_2',1);
925
	define('ROWS_3',2);
926
	define('ROWS_4',3);
927
	define('ROWS_5',4);
928
	define('ROWS_6',5);
929
	define('ROWS_7',6);
930
	define('ROWS_8',7);
931
	define('ROWS_9',8);
932
}
933
934
$heightforframes=48;
935
936
// Init menu manager
937
if (! defined('NOREQUIREMENU'))
938
{
939
	if (empty($user->societe_id))    // If internal user or not defined
940
	{
941
		$conf->standard_menu=(empty($conf->global->MAIN_MENU_STANDARD_FORCED)?(empty($conf->global->MAIN_MENU_STANDARD)?'eldy_menu.php':$conf->global->MAIN_MENU_STANDARD):$conf->global->MAIN_MENU_STANDARD_FORCED);
942
	}
943
	else                        // If external user
944
	{
945
		$conf->standard_menu=(empty($conf->global->MAIN_MENUFRONT_STANDARD_FORCED)?(empty($conf->global->MAIN_MENUFRONT_STANDARD)?'eldy_menu.php':$conf->global->MAIN_MENUFRONT_STANDARD):$conf->global->MAIN_MENUFRONT_STANDARD_FORCED);
946
	}
947
948
	// Load the menu manager (only if not already done)
949
	$file_menu=$conf->standard_menu;
950
	if (GETPOST('menu','alpha')) $file_menu=GETPOST('menu','alpha');     // example: menu=eldy_menu.php
951
	if (! class_exists('MenuManager'))
952
	{
953
		$menufound=0;
954
		$dirmenus=array_merge(array("/core/menus/"),(array) $conf->modules_parts['menus']);
955
		foreach($dirmenus as $dirmenu)
956
		{
957
			$menufound=dol_include_once($dirmenu."standard/".$file_menu);
958
			if (class_exists('MenuManager')) break;
959
		}
960
		if (! class_exists('MenuManager'))	// If failed to include, we try with standard eldy_menu.php
961
		{
962
			dol_syslog("You define a menu manager '".$file_menu."' that can not be loaded.", LOG_WARNING);
963
			$file_menu='eldy_menu.php';
964
			include_once DOL_DOCUMENT_ROOT."/core/menus/standard/".$file_menu;
965
		}
966
	}
967
	$menumanager = new MenuManager($db, empty($user->societe_id)?0:1);
968
	$menumanager->loadMenu();
969
}
970
971
972
973
// Functions
974
975
if (! function_exists("llxHeader"))
976
{
977
	/**
978
	 *	Show HTML header HTML + BODY + Top menu + left menu + DIV
979
	 *
980
	 * @param 	string 	$head				Optionnal head lines
981
	 * @param 	string 	$title				HTML title
982
	 * @param	string	$help_url			Url links to help page
983
	 * 		                            	Syntax is: For a wiki page: EN:EnglishPage|FR:FrenchPage|ES:SpanishPage
984
	 *                                  	For other external page: http://server/url
985
	 * @param	string	$target				Target to use on links
986
	 * @param 	int    	$disablejs			More content into html header
987
	 * @param 	int    	$disablehead		More content into html header
988
	 * @param 	array  	$arrayofjs			Array of complementary js files
989
	 * @param 	array  	$arrayofcss			Array of complementary css files
990
	 * @param	string	$morequerystring	Query string to add to the link "print" to get same parameters (use only if autodetect fails)
991
	 * @param   string  $morecssonbody      More CSS on body tag.
992
	 * @param	string	$replacemainareaby	Replace call to main_area() by a print of this string
993
	 * @return	void
994
	 */
995
	function llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='')
0 ignored issues
show
Best Practice introduced by
The function llxHeader() has been defined more than once; this definition is ignored, only the first definition in htdocs/asterisk/wrapper.php (L46-52) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
996
	{
997
		global $conf;
998
999
		// html header
1000
		top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
1001
1002
		print '<body id="mainbody"'.($morecssonbody?' class="'.$morecssonbody.'"':'').'>' . "\n";
1003
1004
		// top menu and left menu area
1005
		if (empty($conf->dol_hide_topmenu))
1006
		{
1007
			top_menu($head, $title, $target, $disablejs, $disablehead, $arrayofjs, $arrayofcss, $morequerystring, $help_url);
1008
		}
1009
1010
		if (empty($conf->dol_hide_leftmenu))
1011
		{
1012
			left_menu('', $help_url, '', '', 1, $title, 1);
1013
		}
1014
1015
		// main area
1016
		if ($replacemainareaby)
1017
		{
1018
			print $replacemainareaby;
1019
			return;
1020
		}
1021
		main_area($title);
1022
	}
1023
}
1024
1025
1026
/**
1027
 *  Show HTTP header
1028
 *
1029
 *  @param  string  $contenttype    Content type. For example, 'text/html'
1030
 *  @return	void
1031
 */
1032
function top_httphead($contenttype='text/html')
1033
{
1034
	global $conf;
1035
1036
	if ($contenttype == 'text/html' ) header("Content-Type: text/html; charset=".$conf->file->character_set_client);
1037
	else header("Content-Type: ".$contenttype);
1038
	// Security options
1039
	header("X-Content-Type-Options: nosniff");  // With the nosniff option, if the server says the content is text/html, the browser will render it as text/html (note that most browsers now force this option to on)
1040
	header("X-Frame-Options: SAMEORIGIN");      // Frames allowed only if on same domain (stop some XSS attacks)
1041
	if (! empty($conf->global->MAIN_HTTP_CONTENT_SECURITY_POLICY))
1042
	{
1043
		// For example, to restrict script, object, frames or img to some domains
1044
		// script-src https://api.google.com https://anotherhost.com; object-src https://youtube.com; child-src https://youtube.com; img-src: https://static.example.com
1045
		// For example, to restrict everything to one domain, except object, ...
1046
		// default-src https://cdn.example.net; object-src 'none'
1047
		header("Content-Security-Policy: ".$conf->global->MAIN_HTTP_CONTENT_SECURITY_POLICY);
1048
	}
1049
1050
1051
	// On the fly GZIP compression for all pages (if browser support it). Must set the bit 3 of constant to 1.
1052
	/*if (isset($conf->global->MAIN_OPTIMIZE_SPEED) && ($conf->global->MAIN_OPTIMIZE_SPEED & 0x04)) {
1053
        ob_start("ob_gzhandler");
1054
    }*/
1055
}
1056
1057
/**
1058
 * Ouput html header of a page.
1059
 * This code is also duplicated into security2.lib.php::dol_loginfunction
1060
 *
1061
 * @param 	string 	$head			 Optionnal head lines
1062
 * @param 	string 	$title			 HTML title
1063
 * @param 	int    	$disablejs		 Disable js output
1064
 * @param 	int    	$disablehead	 Disable head output
1065
 * @param 	array  	$arrayofjs		 Array of complementary js files
1066
 * @param 	array  	$arrayofcss		 Array of complementary css files
1067
 * @param 	int    	$disablejmobile	 Disable jmobile (No more used)
1068
 * @param   int     $disablenofollow Disable no follow tag
1069
 * @return	void
1070
 */
1071
function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $disablejmobile=0, $disablenofollow=0)
1072
{
1073
	global $user, $conf, $langs, $db;
1074
1075
	top_httphead();
1076
1077
	if (empty($conf->css)) $conf->css = '/theme/eldy/style.css.php';	// If not defined, eldy by default
1078
1079
	if (! empty($conf->global->MAIN_ACTIVATE_HTML4)) {
1080
		$doctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
1081
	}else {
1082
		$doctype = '<!doctype html>';
1083
	}
1084
	print $doctype."\n";
1085
	if (! empty($conf->global->MAIN_USE_CACHE_MANIFEST)) print '<html lang="'.substr($langs->defaultlang,0,2).'" manifest="'.DOL_URL_ROOT.'/cache.manifest">'."\n";
1086
	else print '<html lang="'.substr($langs->defaultlang,0,2).'">'."\n";
1087
	//print '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">'."\n";
1088
	if (empty($disablehead))
1089
	{
1090
		$ext='version='.urlencode(DOL_VERSION);
1091
1092
		print "<head>\n";
1093
		if (GETPOST('dol_basehref','alpha')) print '<base href="'.dol_escape_htmltag(GETPOST('dol_basehref','alpha')).'">'."\n";
1094
		// Displays meta
1095
		print '<meta name="robots" content="noindex'.($disablenofollow?'':',nofollow').'">'."\n";	// Do not index
1096
		print '<meta name="viewport" content="width=device-width, initial-scale=1.0">'."\n";		// Scale for mobile device
1097
		print '<meta name="author" content="Dolibarr Development Team">'."\n";
1098
		// Favicon
1099
		$favicon=dol_buildpath('/theme/'.$conf->theme.'/img/favicon.ico',1);
1100
		if (! empty($conf->global->MAIN_FAVICON_URL)) $favicon=$conf->global->MAIN_FAVICON_URL;
1101
		if (empty($conf->dol_use_jmobile)) print '<link rel="shortcut icon" type="image/x-icon" href="'.$favicon.'"/>'."\n";	// Not required into an Android webview
1102
		//if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) print '<link rel="top" title="'.$langs->trans("Home").'" href="'.(DOL_URL_ROOT?DOL_URL_ROOT:'/').'">'."\n";
1103
		//if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) print '<link rel="copyright" title="GNU General Public License" href="http://www.gnu.org/copyleft/gpl.html#SEC1">'."\n";
1104
		//if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) print '<link rel="author" title="Dolibarr Development Team" href="https://www.dolibarr.org">'."\n";
1105
1106
		// Displays title
1107
		$appli=constant('DOL_APPLICATION_TITLE');
1108
		if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE;
1109
1110
		if ($title && ! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/noapp/',$conf->global->MAIN_HTML_TITLE)) print '<title>'.dol_htmlentities($title).'</title>';
1111
		else if ($title) print '<title>'.dol_htmlentities($appli.' - '.$title).'</title>';
1112
		else print "<title>".dol_htmlentities($appli)."</title>";
1113
		print "\n";
1114
1115
		if (GETPOST('version','int')) $ext='version='.GETPOST('version','int');	// usefull to force no cache on css/js
1116
		if (GETPOST('testmenuhider','int') || ! empty($conf->global->MAIN_TESTMENUHIDER)) $ext.='&testmenuhider='.(GETPOST('testmenuhider','int')?GETPOST('testmenuhider','int'):$conf->global->MAIN_TESTMENUHIDER);
1117
1118
		$themeparam='?lang='.$langs->defaultlang.'&amp;theme='.$conf->theme.(GETPOST('optioncss','aZ09')?'&amp;optioncss='.GETPOST('optioncss','aZ09',1):'').'&amp;userid='.$user->id.'&amp;entity='.$conf->entity;
1119
		$themeparam.=($ext?'&amp;'.$ext:'');
1120
		if (! empty($_SESSION['dol_resetcache'])) $themeparam.='&amp;dol_resetcache='.$_SESSION['dol_resetcache'];
1121
		if (GETPOST('dol_hide_topmenu','int'))           { $themeparam.='&amp;dol_hide_topmenu='.GETPOST('dol_hide_topmenu','int'); }
1122
		if (GETPOST('dol_hide_leftmenu','int'))          { $themeparam.='&amp;dol_hide_leftmenu='.GETPOST('dol_hide_leftmenu','int'); }
1123
		if (GETPOST('dol_optimize_smallscreen','int'))   { $themeparam.='&amp;dol_optimize_smallscreen='.GETPOST('dol_optimize_smallscreen','int'); }
1124
		if (GETPOST('dol_no_mouse_hover','int'))         { $themeparam.='&amp;dol_no_mouse_hover='.GETPOST('dol_no_mouse_hover','int'); }
1125
		if (GETPOST('dol_use_jmobile','int'))            { $themeparam.='&amp;dol_use_jmobile='.GETPOST('dol_use_jmobile','int'); $conf->dol_use_jmobile=GETPOST('dol_use_jmobile','int'); }
1126
1127
		if (! defined('DISABLE_JQUERY') && ! $disablejs && $conf->use_javascript_ajax)
1128
		{
1129
			print '<!-- Includes CSS for JQuery (Ajax library) -->'."\n";
1130
			$jquerytheme = 'smoothness';
1131
			if (!empty($conf->global->MAIN_USE_JQUERY_THEME)) $jquerytheme = $conf->global->MAIN_USE_JQUERY_THEME;
1132
			if (constant('JS_JQUERY_UI')) print '<link rel="stylesheet" type="text/css" href="'.JS_JQUERY_UI.'css/'.$jquerytheme.'/jquery-ui.min.css'.($ext?'?'.$ext:'').'">'."\n";  // JQuery
1133
			else print '<link rel="stylesheet" type="text/css" href="'.DOL_URL_ROOT.'/includes/jquery/css/'.$jquerytheme.'/jquery-ui.css'.($ext?'?'.$ext:'').'">'."\n";    // JQuery
1134
			if (! defined('DISABLE_JQUERY_JNOTIFY')) print '<link rel="stylesheet" type="text/css" href="'.DOL_URL_ROOT.'/includes/jquery/plugins/jnotify/jquery.jnotify-alt.min.css'.($ext?'?'.$ext:'').'">'."\n";          // JNotify
1135
			if (! defined('DISABLE_SELECT2') && (! empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) || defined('REQUIRE_JQUERY_MULTISELECT')))     // jQuery plugin "mutiselect", "multiple-select", "select2"...
1136
			{
1137
				$tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT;
1138
				print '<link rel="stylesheet" type="text/css" href="'.DOL_URL_ROOT.'/includes/jquery/plugins/'.$tmpplugin.'/dist/css/'.$tmpplugin.'.css'.($ext?'?'.$ext:'').'">'."\n";
1139
			}
1140
		}
1141
1142
		if (! defined('DISABLE_FONT_AWSOME'))
1143
		{
1144
			print '<!-- Includes CSS for font awesome -->'."\n";
1145
			print '<link rel="stylesheet" type="text/css" href="'.DOL_URL_ROOT.'/theme/common/fontawesome/css/font-awesome.min.css'.($ext?'?'.$ext:'').'">'."\n";
1146
		}
1147
1148
		print '<!-- Includes CSS for Dolibarr theme -->'."\n";
1149
		// Output style sheets (optioncss='print' or ''). Note: $conf->css looks like '/theme/eldy/style.css.php'
1150
		$themepath=dol_buildpath($conf->css,1);
1151
		$themesubdir='';
1152
		if (! empty($conf->modules_parts['theme']))	// This slow down
1153
		{
1154
			foreach($conf->modules_parts['theme'] as $reldir)
1155
			{
1156
				if (file_exists(dol_buildpath($reldir.$conf->css, 0)))
1157
				{
1158
					$themepath=dol_buildpath($reldir.$conf->css, 1);
1159
					$themesubdir=$reldir;
1160
					break;
1161
				}
1162
			}
1163
		}
1164
		//print 'themepath='.$themepath.' themeparam='.$themeparam;exit;
1165
		print '<link rel="stylesheet" type="text/css" href="'.$themepath.$themeparam.'">'."\n";
1166
		if (! empty($conf->global->MAIN_FIX_FLASH_ON_CHROME)) print '<!-- Includes CSS that does not exists as a workaround of flash bug of chrome -->'."\n".'<link rel="stylesheet" type="text/css" href="filethatdoesnotexiststosolvechromeflashbug">'."\n";
1167
1168
		// CSS forced by modules (relative url starting with /)
1169
		if (! empty($conf->modules_parts['css']))
1170
		{
1171
			$arraycss=(array) $conf->modules_parts['css'];
1172
			foreach($arraycss as $modcss => $filescss)
1173
			{
1174
				$filescss=(array) $filescss;	// To be sure filecss is an array
1175
				foreach($filescss as $cssfile)
1176
				{
1177
					if (empty($cssfile)) dol_syslog("Warning: module ".$modcss." declared a css path file into its descriptor that is empty.", LOG_WARNING);
1178
					// cssfile is a relative path
1179
					print '<!-- Includes CSS added by module '.$modcss. ' -->'."\n".'<link rel="stylesheet" type="text/css" href="'.dol_buildpath($cssfile,1);
1180
					// We add params only if page is not static, because some web server setup does not return content type text/css if url has parameters, so browser cache is not used.
1181
					if (!preg_match('/\.css$/i',$cssfile)) print $themeparam;
1182
					print '">'."\n";
1183
				}
1184
			}
1185
		}
1186
		// CSS forced by page in top_htmlhead call (relative url starting with /)
1187
		if (is_array($arrayofcss))
1188
		{
1189
			foreach($arrayofcss as $cssfile)
1190
			{
1191
				print '<!-- Includes CSS added by page -->'."\n".'<link rel="stylesheet" type="text/css" title="default" href="'.dol_buildpath($cssfile,1);
1192
				// We add params only if page is not static, because some web server setup does not return content type text/css if url has parameters and browser cache is not used.
1193
				if (!preg_match('/\.css$/i',$cssfile)) print $themeparam;
1194
				print '">'."\n";
1195
			}
1196
		}
1197
1198
		// Output standard javascript links
1199
		if (! defined('DISABLE_JQUERY') && ! $disablejs && ! empty($conf->use_javascript_ajax))
1200
		{
1201
			// JQuery. Must be before other includes
1202
			print '<!-- Includes JS for JQuery -->'."\n";
1203
			if (defined('JS_JQUERY') && constant('JS_JQUERY')) print '<script type="text/javascript" src="'.JS_JQUERY.'jquery.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1204
			else print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/js/jquery.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1205
			if (! empty($conf->global->MAIN_FEATURES_LEVEL) && ! defined('JS_JQUERY_MIGRATE_DISABLED'))
1206
			{
1207
				if (defined('JS_JQUERY_MIGRATE') && constant('JS_JQUERY_MIGRATE')) print '<script type="text/javascript" src="'.JS_JQUERY_MIGRATE.'jquery-migrate.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1208
				else print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/js/jquery-migrate.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1209
			}
1210
			if (defined('JS_JQUERY_UI') && constant('JS_JQUERY_UI')) print '<script type="text/javascript" src="'.JS_JQUERY_UI.'jquery-ui.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1211
			else print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/js/jquery-ui.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1212
			if (! defined('DISABLE_JQUERY_TABLEDND')) print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/tablednd/jquery.tablednd.0.6.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1213
			// jQuery jnotify
1214
			if (empty($conf->global->MAIN_DISABLE_JQUERY_JNOTIFY) && ! defined('DISABLE_JQUERY_JNOTIFY'))
1215
			{
1216
				print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jnotify/jquery.jnotify.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1217
				print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/core/js/jnotify.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1218
			}
1219
			// Flot
1220
			if (empty($conf->global->MAIN_DISABLE_JQUERY_FLOT) && ! defined('DISABLE_JQUERY_FLOT'))
1221
			{
1222
				if (constant('JS_JQUERY_FLOT'))
1223
				{
1224
					print '<script type="text/javascript" src="'.JS_JQUERY_FLOT.'jquery.flot.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1225
					print '<script type="text/javascript" src="'.JS_JQUERY_FLOT.'jquery.flot.pie.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1226
					print '<script type="text/javascript" src="'.JS_JQUERY_FLOT.'jquery.flot.stack.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1227
				}
1228
				else
1229
				{
1230
					print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/flot/jquery.flot.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1231
					print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/flot/jquery.flot.pie.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1232
					print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/flot/jquery.flot.stack.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1233
				}
1234
			}
1235
			// jQuery jeditable
1236
			if (! empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && ! defined('DISABLE_JQUERY_JEDITABLE'))
1237
			{
1238
				print '<!-- JS to manage editInPlace feature -->'."\n";
1239
				print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jeditable/jquery.jeditable.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1240
				print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jeditable/jquery.jeditable.ui-datepicker.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1241
				print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jeditable/jquery.jeditable.ui-autocomplete.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1242
				print '<script type="text/javascript">'."\n";
1243
				print 'var urlSaveInPlace = \''.DOL_URL_ROOT.'/core/ajax/saveinplace.php\';'."\n";
1244
				print 'var urlLoadInPlace = \''.DOL_URL_ROOT.'/core/ajax/loadinplace.php\';'."\n";
1245
				print 'var tooltipInPlace = \''.$langs->transnoentities('ClickToEdit').'\';'."\n";	// Added in title attribute of span
1246
				print 'var placeholderInPlace = \'&nbsp;\';'."\n";	// If we put another string than $langs->trans("ClickToEdit") here, nothing is shown. If we put empty string, there is error, Why ?
1247
				print 'var cancelInPlace = \''.$langs->trans('Cancel').'\';'."\n";
1248
				print 'var submitInPlace = \''.$langs->trans('Ok').'\';'."\n";
1249
				print 'var indicatorInPlace = \'<img src="'.DOL_URL_ROOT."/theme/".$conf->theme."/img/working.gif".'">\';'."\n";
1250
				print 'var withInPlace = 300;';		// width in pixel for default string edit
1251
				print '</script>'."\n";
1252
				print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/core/js/editinplace.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1253
				print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jeditable/jquery.jeditable.ckeditor.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1254
			}
1255
			// jQuery DataTables
1256
			/* Removed a old hidden problematic feature never used in Dolibarr. If an external module need datatable, the module must provide all lib it needs and manage version problems with other dolibarr components
1257
            if (! empty($conf->global->MAIN_USE_JQUERY_DATATABLES) || (defined('REQUIRE_JQUERY_DATATABLES') && constant('REQUIRE_JQUERY_DATATABLES')))
1258
            {
1259
                print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/datatables/media/js/jquery.dataTables.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1260
                print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/datatables/extensions/Buttons/js/dataTables.buttons.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1261
                print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/datatables/extensions/Buttons/js/buttons.colVis.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1262
                print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/datatables/extensions/Buttons/js/buttons.html5.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1263
                print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/datatables/extensions/Buttons/js/buttons.flash.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1264
                print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/datatables/extensions/Buttons/js/buttons.print.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1265
                print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/datatables/extensions/ColReorder/js/dataTables.colReorder.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1266
                print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jszip/jszip.min.js"></script>'."\n";
1267
            }*/
1268
            // jQuery Timepicker
1269
            if (! empty($conf->global->MAIN_USE_JQUERY_TIMEPICKER) || defined('REQUIRE_JQUERY_TIMEPICKER'))
1270
            {
1271
            	print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/timepicker/jquery-ui-timepicker-addon.js'.($ext?'?'.$ext:'').'"></script>'."\n";
1272
            	print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/core/js/timepicker.js.php?lang='.$langs->defaultlang.($ext?'&amp;'.$ext:'').'"></script>'."\n";
1273
            }
1274
            if (! defined('DISABLE_SELECT2') && (! empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) || defined('REQUIRE_JQUERY_MULTISELECT')))     // jQuery plugin "mutiselect", "multiple-select", "select2", ...
1275
            {
1276
            	$tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT;
1277
            	print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/'.$tmpplugin.'/dist/js/'.$tmpplugin.'.full.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";	// We include full because we need the support of containerCssClass
1278
            }
1279
        }
1280
1281
        if (! $disablejs && ! empty($conf->use_javascript_ajax))
1282
        {
1283
            // CKEditor
1284
            if (! empty($conf->fckeditor->enabled) && (empty($conf->global->FCKEDITOR_EDITORNAME) || $conf->global->FCKEDITOR_EDITORNAME == 'ckeditor') && ! defined('DISABLE_CKEDITOR'))
1285
            {
1286
                print '<!-- Includes JS for CKEditor -->'."\n";
1287
                $pathckeditor = DOL_URL_ROOT . '/includes/ckeditor/ckeditor/';
1288
                $jsckeditor='ckeditor.js';
1289
                if (constant('JS_CKEDITOR'))	// To use external ckeditor 4 js lib
1290
                {
1291
                	$pathckeditor=constant('JS_CKEDITOR');
1292
                }
1293
                print '<script type="text/javascript">';
1294
                print 'var CKEDITOR_BASEPATH = \''.$pathckeditor.'\';'."\n";
1295
                print 'var ckeditorConfig = \''.dol_buildpath($themesubdir.'/theme/'.$conf->theme.'/ckeditor/config.js'.($ext?'?'.$ext:''),1).'\';'."\n";		// $themesubdir='' in standard usage
1296
                print 'var ckeditorFilebrowserBrowseUrl = \''.DOL_URL_ROOT.'/core/filemanagerdol/browser/default/browser.php?Connector='.DOL_URL_ROOT.'/core/filemanagerdol/connectors/php/connector.php\';'."\n";
1297
                print 'var ckeditorFilebrowserImageBrowseUrl = \''.DOL_URL_ROOT.'/core/filemanagerdol/browser/default/browser.php?Type=Image&Connector='.DOL_URL_ROOT.'/core/filemanagerdol/connectors/php/connector.php\';'."\n";
1298
                print '</script>'."\n";
1299
                print '<script type="text/javascript" src="'.$pathckeditor.$jsckeditor.($ext?'?'.$ext:'').'"></script>'."\n";
1300
            }
1301
1302
            // Browser notifications
1303
            if (! defined('DISABLE_BROWSER_NOTIF'))
1304
            {
1305
                $enablebrowsernotif=false;
1306
                if (! empty($conf->agenda->enabled) && ! empty($conf->global->AGENDA_REMINDER_BROWSER)) $enablebrowsernotif=true;
1307
                if ($conf->browser->layout == 'phone') $enablebrowsernotif=false;
1308
                if ($enablebrowsernotif)
1309
                {
1310
                    print '<!-- Includes JS of Dolibarr (brwoser layout = '.$conf->browser->layout.')-->'."\n";
1311
                    print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/core/js/lib_notification.js.php'.($ext?'?'.$ext:'').'"></script>'."\n";
1312
                }
1313
            }
1314
1315
            // Global js function
1316
            print '<!-- Includes JS of Dolibarr -->'."\n";
1317
            print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/core/js/lib_head.js.php?lang='.$langs->defaultlang.($ext?'&amp;'.$ext:'').'"></script>'."\n";
1318
1319
            // JS forced by modules (relative url starting with /)
1320
            if (! empty($conf->modules_parts['js']))		// $conf->modules_parts['js'] is array('module'=>array('file1','file2'))
1321
        	{
1322
        		$arrayjs=(array) $conf->modules_parts['js'];
1323
	            foreach($arrayjs as $modjs => $filesjs)
1324
	            {
1325
        			$filesjs=(array) $filesjs;	// To be sure filejs is an array
1326
		            foreach($filesjs as $jsfile)
1327
		            {
1328
	    	    		// jsfile is a relative path
1329
	        	    	print '<!-- Include JS added by module '.$modjs. '-->'."\n".'<script type="text/javascript" src="'.dol_buildpath($jsfile,1).'"></script>'."\n";
1330
		            }
1331
	            }
1332
        	}
1333
            // JS forced by page in top_htmlhead (relative url starting with /)
1334
            if (is_array($arrayofjs))
1335
            {
1336
                print '<!-- Includes JS added by page -->'."\n";
1337
                foreach($arrayofjs as $jsfile)
1338
                {
1339
                    if (preg_match('/^http/i',$jsfile))
1340
                    {
1341
                        print '<script type="text/javascript" src="'.$jsfile.'"></script>'."\n";
1342
                    }
1343
                    else
1344
                    {
1345
                        if (! preg_match('/^\//',$jsfile)) $jsfile='/'.$jsfile;	// For backward compatibility
1346
                        print '<script type="text/javascript" src="'.dol_buildpath($jsfile,1).'"></script>'."\n";
1347
                    }
1348
                }
1349
            }
1350
        }
1351
1352
        if (! empty($head)) print $head."\n";
1353
        if (! empty($conf->global->MAIN_HTML_HEADER)) print $conf->global->MAIN_HTML_HEADER."\n";
1354
1355
        print "</head>\n\n";
1356
    }
1357
1358
    $conf->headerdone=1;	// To tell header was output
1359
}
1360
1361
1362
/**
1363
 *  Show an HTML header + a BODY + The top menu bar
1364
 *
1365
 *  @param      string	$head    			Lines in the HEAD
1366
 *  @param      string	$title   			Title of web page
1367
 *  @param      string	$target  			Target to use in menu links (Example: '' or '_top')
1368
 *	@param		int		$disablejs			Do not output links to js (Ex: qd fonction utilisee par sous formulaire Ajax)
1369
 *	@param		int		$disablehead		Do not output head section
1370
 *	@param		array	$arrayofjs			Array of js files to add in header
1371
 *	@param		array	$arrayofcss			Array of css files to add in header
1372
 *  @param		string	$morequerystring	Query string to add to the link "print" to get same parameters (use only if autodetect fails)
1373
 *  @param      string	$helppagename    	Name of wiki page for help ('' by default).
1374
 * 				     		                Syntax is: For a wiki page: EN:EnglishPage|FR:FrenchPage|ES:SpanishPage
1375
 * 									                   For other external page: http://server/url
1376
 *  @return		void
1377
 */
1378
function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $helppagename='')
1379
{
1380
	global $user, $conf, $langs, $db;
1381
	global $dolibarr_main_authentication, $dolibarr_main_demo;
1382
	global $hookmanager,$menumanager;
1383
1384
	$searchform='';
1385
	$bookmarks='';
1386
1387
	// Instantiate hooks of thirdparty module
1388
	$hookmanager->initHooks(array('toprightmenu'));
1389
1390
	$toprightmenu='';
1391
1392
	// For backward compatibility with old modules
1393
	if (empty($conf->headerdone))
1394
	{
1395
		top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
1396
		print '<body id="mainbody">';
1397
	}
1398
1399
	/*
1400
     * Top menu
1401
     */
1402
	if (empty($conf->dol_hide_topmenu) && (! defined('NOREQUIREMENU') || ! constant('NOREQUIREMENU')))
1403
	{
1404
		print "\n".'<!-- Start top horizontal -->'."\n";
1405
1406
		print '<div class="side-nav-vert"><div id="id-top">';
1407
1408
		// Show menu entries
1409
		print '<div id="tmenu_tooltip'.(empty($conf->global->MAIN_MENU_INVERT)?'':'invert').'" class="tmenu">'."\n";
1410
		$menumanager->atarget=$target;
1411
		$menumanager->showmenu('top', array('searchform'=>$searchform, 'bookmarks'=>$bookmarks));      // This contains a \n
1412
		print "</div>\n";
1413
1414
		// Define link to login card
1415
		$appli=constant('DOL_APPLICATION_TITLE');
1416
		if (! empty($conf->global->MAIN_APPLICATION_TITLE))
1417
		{
1418
			$appli=$conf->global->MAIN_APPLICATION_TITLE;
1419
			if (preg_match('/\d\.\d/', $appli))
1420
			{
1421
				if (! preg_match('/'.preg_quote(DOL_VERSION).'/', $appli)) $appli.=" (".DOL_VERSION.")";	// If new title contains a version that is different than core
1422
			}
1423
			else $appli.=" ".DOL_VERSION;
1424
		}
1425
		else $appli.=" ".DOL_VERSION;
1426
1427
		if (! empty($conf->global->MAIN_FEATURES_LEVEL)) $appli.="<br>".$langs->trans("LevelOfFeature").': '.$conf->global->MAIN_FEATURES_LEVEL;
1428
1429
		$logouttext='';
1430
		if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
1431
		{
1432
			//$logouthtmltext=$appli.'<br>';
1433
			if ($_SESSION["dol_authmode"] != 'forceuser' && $_SESSION["dol_authmode"] != 'http')
1434
			{
1435
				$logouthtmltext.=$langs->trans("Logout").'<br>';
0 ignored issues
show
Bug introduced by
The variable $logouthtmltext does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
1436
1437
				$logouttext .='<a href="'.DOL_URL_ROOT.'/user/logout.php">';
1438
				//$logouttext .= img_picto($langs->trans('Logout').":".$langs->trans('Logout'), 'logout_top.png', 'class="login"', 0, 0, 1);
1439
				$logouttext .='<span class="fa fa-sign-out atoplogin"></span>';
1440
				$logouttext .='</a>';
1441
			}
1442
			else
1443
			{
1444
				$logouthtmltext.=$langs->trans("NoLogoutProcessWithAuthMode",$_SESSION["dol_authmode"]);
1445
				$logouttext .= img_picto($langs->trans('Logout').":".$langs->trans('Logout'), 'logout_top.png', 'class="login"', 0, 0, 1);
1446
			}
1447
		}
1448
1449
		print '<div class="login_block">'."\n";
1450
1451
		// Add login user link
1452
		$toprightmenu.='<div class="login_block_user">';
1453
1454
		// Login name with photo and tooltip
1455
		$mode=-1;
1456
		$toprightmenu.='<div class="inline-block nowrap"><div class="inline-block login_block_elem login_block_elem_name" style="padding: 0px;">';
1457
		$toprightmenu.=$user->getNomUrl($mode, '', 1, 0, 11, 0, ($user->firstname ? 'firstname' : -1),'atoplogin');
1458
		$toprightmenu.='</div></div>';
1459
1460
		$toprightmenu.='</div>'."\n";
1461
1462
		$toprightmenu.='<div class="login_block_other">';
1463
1464
		// Execute hook printTopRightMenu (hooks should output string like '<div class="login"><a href="">mylink</a></div>')
1465
		$parameters=array();
1466
		$result=$hookmanager->executeHooks('printTopRightMenu',$parameters);    // Note that $action and $object may have been modified by some hooks
1467
		if (is_numeric($result))
1468
		{
1469
			if (empty($result)) $toprightmenu.=$hookmanager->resPrint;		// add
1470
			else  $toprightmenu=$hookmanager->resPrint;						// replace
1471
		}
1472
		else $toprightmenu.=$result;	// For backward compatibility
1473
1474
		// Link to module builder
1475
		if (! empty($conf->modulebuilder->enabled))
1476
		{
1477
			$text ='<a href="'.DOL_URL_ROOT.'/modulebuilder/index.php?mainmenu=home&leftmenu=admintools" target="_modulebuilder">';
1478
			//$text.= img_picto(":".$langs->trans("ModuleBuilder"), 'printer_top.png', 'class="printer"');
1479
			$text.='<span class="fa fa-bug atoplogin"></span>';
1480
			$text.='</a>';
1481
			$toprightmenu.=@Form::textwithtooltip('',$langs->trans("ModuleBuilder"),2,1,$text,'login_block_elem',2);
1482
		}
1483
1484
		// Link to print main content area
1485
		if (empty($conf->global->MAIN_PRINT_DISABLELINK) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && empty($conf->browser->phone))
1486
		{
1487
			$qs=dol_escape_htmltag($_SERVER["QUERY_STRING"]);
1488
1489
			if (is_array($_POST))
1490
			{
1491
				foreach($_POST as $key=>$value) {
1492
					if ($key!=='action' && !is_array($value)) $qs.='&'.$key.'='.urlencode($value);
1493
				}
1494
			}
1495
			$qs.=(($qs && $morequerystring)?'&':'').$morequerystring;
1496
			$text ='<a href="'.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.$qs.($qs?'&':'').'optioncss=print" target="_blank">';
1497
			//$text.= img_picto(":".$langs->trans("PrintContentArea"), 'printer_top.png', 'class="printer"');
1498
			$text.='<span class="fa fa-print atoplogin"></span>';
1499
			$text.='</a>';
1500
			$toprightmenu.=@Form::textwithtooltip('',$langs->trans("PrintContentArea"),2,1,$text,'login_block_elem',2);
1501
		}
1502
1503
		// Link to Dolibarr wiki pages
1504
		if (empty($conf->global->MAIN_HELP_DISABLELINK) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
1505
		{
1506
			$langs->load("help");
1507
1508
			$helpbaseurl='';
1509
			$helppage='';
1510
			$mode='';
1511
1512
			if (empty($helppagename)) $helppagename='EN:User_documentation|FR:Documentation_utilisateur|ES:Documentación_usuarios';
1513
1514
			// Get helpbaseurl, helppage and mode from helppagename and langs
1515
			$arrayres=getHelpParamFor($helppagename,$langs);
1516
			$helpbaseurl=$arrayres['helpbaseurl'];
1517
			$helppage=$arrayres['helppage'];
1518
			$mode=$arrayres['mode'];
1519
1520
			// Link to help pages
1521
			if ($helpbaseurl && $helppage)
1522
			{
1523
				$text='';
1524
				$title=$appli.'<br>';
1525
				$title.=$langs->trans($mode == 'wiki' ? 'GoToWikiHelpPage': 'GoToHelpPage');
1526
				if ($mode == 'wiki') $title.=' - '.$langs->trans("PageWiki").' &quot;'.dol_escape_htmltag(strtr($helppage,'_',' ')).'&quot;';
1527
				$text.='<a class="help" target="_blank" href="';
1528
				if ($mode == 'wiki') $text.=sprintf($helpbaseurl,urlencode(html_entity_decode($helppage)));
1529
				else $text.=sprintf($helpbaseurl,$helppage);
1530
				$text.='">';
1531
				//$text.=img_picto('', 'helpdoc_top').' ';
1532
				$text.='<span class="fa fa-question-circle atoplogin"></span>';
1533
				//$toprightmenu.=$langs->trans($mode == 'wiki' ? 'OnlineHelp': 'Help');
1534
				//if ($mode == 'wiki') $text.=' ('.dol_trunc(strtr($helppage,'_',' '),8).')';
1535
				$text.='</a>';
1536
				//$toprightmenu.='</div>'."\n";
1537
				$toprightmenu.=@Form::textwithtooltip('',$title,2,1,$text,'login_block_elem',2);
1538
			}
1539
		}
1540
1541
		// Logout link
1542
		$toprightmenu.=@Form::textwithtooltip('',$logouthtmltext,2,1,$logouttext,'login_block_elem',2);
1543
1544
		$toprightmenu.='</div>';
1545
1546
		print $toprightmenu;
1547
1548
		print "</div>\n";
1549
		print '</div></div>';
1550
1551
		//unset($form);
1552
1553
		print '<div style="clear: both;"></div>';
1554
		print "<!-- End top horizontal menu -->\n\n";
1555
	}
1556
1557
	if (empty($conf->dol_hide_leftmenu) && empty($conf->dol_use_jmobile)) print '<!-- Begin div id-container --><div id="id-container" class="id-container'.($morecss?' '.$morecss:'').'">';
0 ignored issues
show
Bug introduced by
The variable $morecss does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
1558
}
1559
1560
1561
/**
1562
 *  Show left menu bar
1563
 *
1564
 *  @param  array	$menu_array_before 	       	Table of menu entries to show before entries of menu handler. This param is deprectaed and must be provided to ''.
1565
 *  @param  string	$helppagename    	       	Name of wiki page for help ('' by default).
1566
 * 				     		                   	Syntax is: For a wiki page: EN:EnglishPage|FR:FrenchPage|ES:SpanishPage
1567
 * 									         		       For other external page: http://server/url
1568
 *  @param  string	$notused             		Deprecated. Used in past to add content into left menu. Hooks can be used now.
1569
 *  @param  array	$menu_array_after           Table of menu entries to show after entries of menu handler
1570
 *  @param  int		$leftmenuwithoutmainarea    Must be set to 1. 0 by default for backward compatibility with old modules.
1571
 *  @param  string	$title                      Title of web page
1572
 *  @param  string  $acceptdelayedhtml          1 if caller request to have html delayed content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect)
1573
 *  @return	void
1574
 */
1575
function left_menu($menu_array_before, $helppagename='', $notused='', $menu_array_after='', $leftmenuwithoutmainarea=0, $title='', $acceptdelayedhtml=0)
1576
{
1577
	global $user, $conf, $langs, $db, $form;
1578
	global $hookmanager, $menumanager;
1579
1580
	$searchform='';
1581
	$bookmarks='';
1582
1583
	if (! empty($menu_array_before)) dol_syslog("Deprecated parameter menu_array_before was used when calling main::left_menu function. Menu entries of module should now be defined into module descriptor and not provided when calling left_menu.", LOG_WARNING);
1584
1585
	if (empty($conf->dol_hide_leftmenu) && (! defined('NOREQUIREMENU') || ! constant('NOREQUIREMENU')))
1586
	{
1587
		// Instantiate hooks of thirdparty module
1588
		$hookmanager->initHooks(array('searchform','leftblock'));
1589
1590
		print "\n".'<!-- Begin side-nav id-left -->'."\n".'<div class="side-nav"><div id="id-left">'."\n";
1591
1592
		if ($conf->browser->layout == 'phone') $conf->global->MAIN_USE_OLD_SEARCH_FORM=1;	// Select into select2 is awfull on smartphone. TODO Is this still true with select2 v4 ?
1593
1594
		print "\n";
1595
		if ($conf->use_javascript_ajax && empty($conf->global->MAIN_USE_OLD_SEARCH_FORM))
1596
		{
1597
			if (! is_object($form)) $form=new Form($db);
1598
			$selected=-1;
1599
			$searchform.=$form->selectArrayAjax('searchselectcombo', DOL_URL_ROOT.'/core/ajax/selectsearchbox.php', $selected, '', '', 0, 1, 'vmenusearchselectcombo', 1, $langs->trans("Search"), 1);
1600
		}
1601
		else
1602
		{
1603
			if (! is_object($form)) $form=new Form($db);
1604
			$selected=-1;
1605
			$usedbyinclude=1;
1606
			include_once DOL_DOCUMENT_ROOT.'/core/ajax/selectsearchbox.php';
1607
1608
			foreach($arrayresult as $key => $val)
0 ignored issues
show
Bug introduced by
The variable $arrayresult does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
1609
			{
1610
				//$searchform.=printSearchForm($val['url'], $val['url'], $val['label'], 'maxwidth100', 'sall', $val['shortcut'], 'searchleftt', img_picto('',$val['img']));
1611
				$searchform.=printSearchForm($val['url'], $val['url'], $val['label'], 'maxwidth125', 'sall', $val['shortcut'], 'searchleftt', img_picto('', $val['img'], '', false, 1, 1));
1612
			}
1613
		}
1614
1615
		// Execute hook printSearchForm
1616
		$parameters=array('searchform'=>$searchform);
1617
		$reshook=$hookmanager->executeHooks('printSearchForm',$parameters);    // Note that $action and $object may have been modified by some hooks
1618
		if (empty($reshook))
1619
		{
1620
			$searchform.=$hookmanager->resPrint;
1621
		}
1622
		else $searchform=$hookmanager->resPrint;
1623
1624
		// Force special value for $searchform
1625
		if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) || empty($conf->use_javascript_ajax))
1626
		{
1627
			$urltosearch=DOL_URL_ROOT.'/core/search_page.php?showtitlebefore=1';
1628
			$searchform='<div class="blockvmenuimpair blockvmenusearchphone"><div id="divsearchforms1"><a href="'.$urltosearch.'" alt="'.dol_escape_htmltag($langs->trans("ShowSearchFields")).'">'.$langs->trans("Search").'...</a></div></div>';
1629
		}
1630
		elseif ($conf->use_javascript_ajax && ! empty($conf->global->MAIN_USE_OLD_SEARCH_FORM))
1631
		{
1632
			$searchform='<div class="blockvmenuimpair blockvmenusearchphone"><div id="divsearchforms1"><a href="#" alt="'.dol_escape_htmltag($langs->trans("ShowSearchFields")).'">'.$langs->trans("Search").'...</a></div><div id="divsearchforms2" style="display: none">'.$searchform.'</div>';
1633
			$searchform.='<script type="text/javascript">
1634
            	jQuery(document).ready(function () {
1635
            		jQuery("#divsearchforms1").click(function(){
1636
	                   jQuery("#divsearchforms2").toggle();
1637
	               });
1638
            	});
1639
                </script>' . "\n";
1640
			$searchform.='</div>';
1641
		}
1642
1643
		// Define $bookmarks
1644
		if (! empty($conf->bookmark->enabled) && $user->rights->bookmark->lire)
1645
		{
1646
			include_once (DOL_DOCUMENT_ROOT.'/bookmarks/bookmarks.lib.php');
1647
			$langs->load("bookmarks");
1648
1649
			$bookmarks=printBookmarksList($db, $langs);
1650
		}
1651
1652
		// Left column
1653
		print '<!-- Begin left menu -->'."\n";
1654
1655
		print '<div class="vmenu"'.(empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)?'':' title="Left menu"').'>'."\n\n";
1656
1657
		// Show left menu with other forms
1658
		$menumanager->menu_array = $menu_array_before;
1659
		$menumanager->menu_array_after = $menu_array_after;
1660
		$menumanager->showmenu('left', array('searchform'=>$searchform, 'bookmarks'=>$bookmarks)); // output menu_array and menu found in database
1661
1662
		// Dolibarr version + help + bug report link
1663
		print "\n";
1664
		print "<!-- Begin Help Block-->\n";
1665
		print '<div id="blockvmenuhelp" class="blockvmenuhelp">'."\n";
1666
1667
		// Version
1668
		if (empty($conf->global->MAIN_HIDE_VERSION))    // Version is already on help picto and on login page.
1669
		{
1670
			$doliurl='https://www.dolibarr.org';
1671
			//local communities
1672
			if (preg_match('/fr/i',$langs->defaultlang)) $doliurl='https://www.dolibarr.fr';
1673
			if (preg_match('/es/i',$langs->defaultlang)) $doliurl='https://www.dolibarr.es';
1674
			if (preg_match('/de/i',$langs->defaultlang)) $doliurl='https://www.dolibarr.de';
1675
			if (preg_match('/it/i',$langs->defaultlang)) $doliurl='https://www.dolibarr.it';
1676
			if (preg_match('/gr/i',$langs->defaultlang)) $doliurl='https://www.dolibarr.gr';
1677
1678
			$appli=constant('DOL_APPLICATION_TITLE');
1679
			if (! empty($conf->global->MAIN_APPLICATION_TITLE))
1680
			{
1681
				$appli=$conf->global->MAIN_APPLICATION_TITLE; $doliurl='';
1682
				if (preg_match('/\d\.\d/', $appli))
1683
				{
1684
					if (! preg_match('/'.preg_quote(DOL_VERSION).'/', $appli)) $appli.=" (".DOL_VERSION.")";	// If new title contains a version that is different than core
1685
				}
1686
				else $appli.=" ".DOL_VERSION;
1687
			}
1688
			else $appli.=" ".DOL_VERSION;
1689
			print '<div id="blockvmenuhelpapp" class="blockvmenuhelp">';
1690
			if ($doliurl) print '<a class="help" target="_blank" href="'.$doliurl.'">';
1691
			else print '<span class="help">';
1692
			print $appli;
1693
			if ($doliurl) print '</a>';
1694
			else print '</span>';
1695
			print '</div>'."\n";
1696
		}
1697
1698
		// Link to bugtrack
1699
		if (! empty($conf->global->MAIN_BUGTRACK_ENABLELINK))
1700
		{
1701
			require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1702
1703
			$bugbaseurl = 'https://github.com/Dolibarr/dolibarr/issues/new';
1704
			$bugbaseurl.= '?title=';
1705
			$bugbaseurl.= urlencode("Bug: ");
1706
			$bugbaseurl.= '&body=';
1707
			// TODO use .github/ISSUE_TEMPLATE.md to generate?
1708
			$bugbaseurl .= urlencode("# Bug\n");
1709
			$bugbaseurl .= urlencode("\n");
1710
			$bugbaseurl.= urlencode("## Environment\n");
1711
			$bugbaseurl.= urlencode("- **Version**: " . DOL_VERSION . "\n");
1712
			$bugbaseurl.= urlencode("- **OS**: " . php_uname('s') . "\n");
1713
			$bugbaseurl.= urlencode("- **Web server**: " . $_SERVER["SERVER_SOFTWARE"] . "\n");
1714
			$bugbaseurl.= urlencode("- **PHP**: " . php_sapi_name() . ' ' . phpversion() . "\n");
1715
			$bugbaseurl.= urlencode("- **Database**: " . $db::LABEL . ' ' . $db->getVersion() . "\n");
1716
			$bugbaseurl.= urlencode("- **URL**: " . $_SERVER["REQUEST_URI"] . "\n");
1717
			$bugbaseurl.= urlencode("\n");
1718
			$bugbaseurl.= urlencode("## Report\n");
1719
			print '<div id="blockvmenuhelpbugreport" class="blockvmenuhelp">';
1720
			print '<a class="help" target="_blank" href="'.$bugbaseurl.'">'.$langs->trans("FindBug").'</a>';
1721
			print '</div>';
1722
		}
1723
1724
		print "</div>\n";
1725
		print "<!-- End Help Block-->\n";
1726
		print "\n";
1727
1728
		print "</div>\n";
1729
		print "<!-- End left menu -->\n";
1730
		print "\n";
1731
1732
		// Execute hook printLeftBlock
1733
		$parameters=array();
1734
		$reshook=$hookmanager->executeHooks('printLeftBlock',$parameters);    // Note that $action and $object may have been modified by some hooks
1735
		print $hookmanager->resPrint;
1736
1737
		print '</div></div> <!-- End side-nav id-left -->';	// End div id="side-nav" div id="id-left"
1738
	}
1739
1740
	print "\n";
1741
	print '<!-- Begin right area -->'."\n";
1742
1743
	if (empty($leftmenuwithoutmainarea)) main_area($title);
1744
}
1745
1746
1747
/**
1748
 *  Begin main area
1749
 *
1750
 *  @param	string	$title		Title
1751
 *  @return	void
1752
 */
1753
function main_area($title='')
1754
{
1755
	global $conf, $langs;
1756
1757
	if (empty($conf->dol_hide_leftmenu)) print '<div id="id-right">';
1758
1759
	print "\n";
1760
1761
	print '<!-- Begin div class="fiche" -->'."\n".'<div class="fiche">'."\n";
1762
1763
	if (! empty($conf->global->MAIN_ONLY_LOGIN_ALLOWED)) print info_admin($langs->trans("WarningYouAreInMaintenanceMode",$conf->global->MAIN_ONLY_LOGIN_ALLOWED));
1764
}
1765
1766
1767
/**
1768
 *  Return helpbaseurl, helppage and mode
1769
 *
1770
 *  @param	string		$helppagename		Page name ('EN:xxx,ES:eee,FR:fff...' or 'http://localpage')
1771
 *  @param  Translate	$langs				Language
1772
 *  @return	array		Array of help urls
1773
 */
1774
function getHelpParamFor($helppagename,$langs)
1775
{
1776
	$helpbaseurl='';
1777
	$helppage='';
1778
	$mode='';
1779
1780
	if (preg_match('/^http/i',$helppagename))
1781
	{
1782
		// If complete URL
1783
		$helpbaseurl='%s';
1784
		$helppage=$helppagename;
1785
		$mode='local';
1786
	}
1787
	else
1788
	{
1789
		// If WIKI URL
1790
		if (preg_match('/^es/i',$langs->defaultlang))
1791
		{
1792
			$helpbaseurl='http://wiki.dolibarr.org/index.php/%s';
1793
			if (preg_match('/ES:([^|]+)/i',$helppagename,$reg)) $helppage=$reg[1];
1794
		}
1795
		if (preg_match('/^fr/i',$langs->defaultlang))
1796
		{
1797
			$helpbaseurl='http://wiki.dolibarr.org/index.php/%s';
1798
			if (preg_match('/FR:([^|]+)/i',$helppagename,$reg)) $helppage=$reg[1];
1799
		}
1800
		if (empty($helppage))	// If help page not already found
1801
		{
1802
			$helpbaseurl='http://wiki.dolibarr.org/index.php/%s';
1803
			if (preg_match('/EN:([^|]+)/i',$helppagename,$reg)) $helppage=$reg[1];
1804
		}
1805
		$mode='wiki';
1806
	}
1807
	return array('helpbaseurl'=>$helpbaseurl,'helppage'=>$helppage,'mode'=>$mode);
1808
}
1809
1810
1811
/**
1812
 *  Show a search area.
1813
 *  Used when the javascript quick search is not used.
1814
 *
1815
 *  @param  string	$urlaction          Url post
1816
 *  @param  string	$urlobject          Url of the link under the search box
1817
 *  @param  string	$title              Title search area
1818
 *  @param  string	$htmlmorecss        Add more css
1819
 *  @param  string	$htmlinputname      Field Name input form
1820
 *  @param	string	$accesskey			Accesskey
1821
 *  @param  string  $prefhtmlinputname  Complement for id to avoid multiple same id in the page
1822
 *  @param	string	$img				Image to use
1823
 *  @param	string	$showtitlebefore	Show title before input text instead of into placeholder. This can be set when output is dedicated for text browsers.
1824
 *  @return	string
1825
 */
1826
function printSearchForm($urlaction, $urlobject, $title, $htmlmorecss, $htmlinputname, $accesskey='', $prefhtmlinputname='',$img='', $showtitlebefore=0)
1827
{
1828
	global $conf,$langs,$user;
1829
1830
	if (empty($htmlinputid)) {
0 ignored issues
show
Bug introduced by
The variable $htmlinputid seems only to be defined at a later point. As such the call to empty() seems to always evaluate to true.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
1831
		$htmlinputid = $htmlinputname;
1832
	}
1833
1834
	$ret='';
1835
	$ret.='<form action="'.$urlaction.'" method="post" class="searchform">';
1836
	$ret.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1837
	$ret.='<input type="hidden" name="mode" value="search">';
1838
	$ret.='<input type="hidden" name="savelogin" value="'.dol_escape_htmltag($user->login).'">';
1839
	if ($showtitlebefore) $ret.=$title.' ';
1840
	$ret.='<input type="text" class="flat '.$htmlmorecss.'"';
1841
	$ret.=' style="text-indent: 22px; background-image: url(\''.$img.'\'); background-repeat: no-repeat; background-position: 3px;"';
1842
	$ret.=($accesskey?' accesskey="'.$accesskey.'"':'');
1843
	$ret.=' placeholder="'.strip_tags($title).'"';
1844
	$ret.=' name="'.$htmlinputname.'" id="'.$prefhtmlinputname.$htmlinputname.'" />';
1845
	$ret.='<input type="submit" class="button" style="padding-top: 4px; padding-bottom: 4px; padding-left: 6px; padding-right: 6px" value="'.$langs->trans("Go").'">';
1846
	$ret.="</form>\n";
1847
	return $ret;
1848
}
1849
1850
1851
if (! function_exists("llxFooter"))
1852
{
1853
	/**
1854
	 * Show HTML footer
1855
	 * Close div /DIV class=fiche + /DIV id-right + /DIV id-container + /BODY + /HTML.
1856
	 * If global var $delayedhtmlcontent was filled, we output it just before closing the body.
1857
	 *
1858
	 * @param	string	$comment    				A text to add as HTML comment into HTML generated page
1859
	 * @param	string	$zone						'private' (for private pages) or 'public' (for public pages)
1860
	 * @param	int		$disabledoutputofmessages	Clear all messages stored into session without diplaying them
1861
	 * @return	void
1862
	 */
1863
	function llxFooter($comment='',$zone='private', $disabledoutputofmessages=0)
1864
	{
1865
		global $conf, $langs, $user, $object;
1866
		global $delayedhtmlcontent;
1867
1868
		$ext='version='.urlencode(DOL_VERSION);
1869
1870
		// Global html output events ($mesgs, $errors, $warnings)
1871
		dol_htmloutput_events($disabledoutputofmessages);
1872
1873
		// Code for search criteria persistence.
1874
		// Save $user->lastsearch_values if defined (define on list pages when a form field search_xxx exists)
1875
		if (is_object($user) && ! empty($user->lastsearch_values_tmp) && is_array($user->lastsearch_values_tmp))
1876
		{
1877
			// Clean data
1878
			foreach($user->lastsearch_values_tmp as $key => $val)
1879
			{
1880
				unset($_SESSION['lastsearch_values_tmp_'.$key]);
1881
				if (count($val))
1882
				{
1883
					if (empty($val['sortfield'])) unset($val['sortfield']);
1884
					if (empty($val['sortorder'])) unset($val['sortorder']);
1885
					dol_syslog('Save lastsearch_values_tmp_'.$key.'='.json_encode($val, 0)." (systematic recording of last search criteria)");
1886
					$_SESSION['lastsearch_values_tmp_'.$key]=json_encode($val);
1887
					unset($_SESSION['lastsearch_values_'.$key]);
1888
				}
1889
			}
1890
		}
1891
1892
		// Core error message
1893
		if (! empty($conf->global->MAIN_CORE_ERROR))
1894
		{
1895
			// Ajax version
1896
			if ($conf->use_javascript_ajax)
1897
			{
1898
				$title = img_warning().' '.$langs->trans('CoreErrorTitle');
1899
				print ajax_dialog($title, $langs->trans('CoreErrorMessage'));
1900
			}
1901
			// html version
1902
			else
1903
			{
1904
				$msg = img_warning().' '.$langs->trans('CoreErrorMessage');
1905
				print '<div class="error">'.$msg.'</div>';
1906
			}
1907
1908
			//define("MAIN_CORE_ERROR",0);      // Constant was defined and we can't change value of a constant
1909
		}
1910
1911
		print "\n\n";
1912
1913
		print '</div> <!-- End div class="fiche" -->'."\n"; // End div fiche
1914
1915
		if (empty($conf->dol_hide_leftmenu)) print '</div> <!-- End div id-right -->'."\n"; // End div id-right
1916
1917
		if (empty($conf->dol_hide_leftmenu) && empty($conf->dol_use_jmobile)) print '</div> <!-- End div id-container -->'."\n";	// End div container
1918
1919
		print "\n";
1920
		if ($comment) print '<!-- '.$comment.' -->'."\n";
1921
1922
		printCommonFooter($zone);
1923
1924
		if (! empty($delayedhtmlcontent)) print $delayedhtmlcontent;
1925
1926
		if (! empty($conf->use_javascript_ajax))
1927
		{
1928
			print "\n".'<!-- Includes JS Footer of Dolibarr -->'."\n";
1929
			print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/core/js/lib_foot.js.php?lang='.$langs->defaultlang.($ext?'&amp;'.$ext:'').'"></script>'."\n";
1930
		}
1931
1932
		// Wrapper to add log when clicking on download or preview
1933
		if (! empty($conf->blockedlog->enabled) && is_object($object) && $object->id > 0 && $object->statut > 0)
1934
		{
1935
			if (in_array($object->element, array('facture')))       // Restrict for the moment to element 'facture'
1936
			{
1937
				print "\n<!-- JS CODE TO ENABLE log when making a download or a preview of a document -->\n";
1938
				?>
1939
    			<script type="text/javascript">
1940
    			jQuery(document).ready(function () {
1941
    				$('a.documentpreview').click(function() {
1942
    					$.post('<?php echo DOL_URL_ROOT."/blockedlog/ajax/block-add.php" ?>'
1943
    							, {
1944
    								id:<?php echo $object->id; ?>
1945
    								, element:'<?php echo $object->element ?>'
1946
    								, action:'DOC_PREVIEW'
1947
    							}
1948
    					);
1949
    				});
1950
    				$('a.documentdownload').click(function() {
1951
    					$.post('<?php echo DOL_URL_ROOT."/blockedlog/ajax/block-add.php" ?>'
1952
    							, {
1953
    								id:<?php echo $object->id; ?>
1954
    								, element:'<?php echo $object->element ?>'
1955
    								, action:'DOC_DOWNLOAD'
1956
    							}
1957
    					);
1958
    				});
1959
    			});
1960
    			</script>
1961
				<?php
1962
			}
1963
	   	}
1964
1965
		// A div for the address popup
1966
		print "\n<!-- A div to allow dialog popup -->\n";
1967
		print '<div id="dialogforpopup" style="display: none;"></div>'."\n";
1968
1969
		print "</body>\n";
1970
		print "</html>\n";
1971
	}
1972
}
1973
1974