Completed
Branch develop (bb7c03)
by
unknown
34:20
created

admin.lib.php ➔ activateModulesRequiredByCountry()   C

Complexity

Conditions 17
Paths 29

Size

Total Lines 58
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 27
nc 29
nop 1
dl 0
loc 58
rs 6.4234
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* Copyright (C) 2008-2011  Laurent Destailleur     <[email protected]>
3
 * Copyright (C) 2005-2016  Regis Houssin           <[email protected]>
4
 * Copyright (C) 2012       J. Fernando Lagrange    <[email protected]>
5
 * Copyright (C) 2015       Raphaël Doursenaud      <[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
 * or see http://www.gnu.org/
20
 */
21
22
/**
23
 *	\file			htdocs/core/lib/admin.lib.php
24
 *  \brief			Library of admin functions
25
 */
26
27
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
28
29
/**
30
 *  Renvoi une version en chaine depuis une version en tableau
31
 *
32
 *  @param		array		$versionarray		Tableau de version (vermajeur,vermineur,autre)
33
 *  @return     string        			      	Chaine version
34
 */
35
function versiontostring($versionarray)
36
{
37
    $string='?';
38
    if (isset($versionarray[0])) $string=$versionarray[0];
39
    if (isset($versionarray[1])) $string.='.'.$versionarray[1];
40
    if (isset($versionarray[2])) $string.='.'.$versionarray[2];
41
    return $string;
42
}
43
44
/**
45
 *	Compare 2 versions (stored into 2 arrays).
46
 *  To check if Dolibarr version is lower than (x,y,z), do "if versioncompare(versiondolibarrarray(), array(x.y.z)) <= 0"
47
 *  For example: if (versioncompare(versiondolibarrarray(),array(4,0,-4)) >= 0) is true if version is 4.0 alpha or higher.
48
 *  For example: if (versioncompare(versiondolibarrarray(),array(4,0,0)) >= 0) is true if version is 4.0 final or higher.
49
 *  For example: if (versioncompare(versiondolibarrarray(),array(4,0,1)) >= 0) is true if version is 4.0.1 or higher.
50
 *  Alternative way to compare: if ((float) DOL_VERSION >= 4.0) is true if version is 4.0 alpha or higher (works only to compare first and second level)
51
 *
52
 *	@param      array		$versionarray1      Array of version (vermajor,verminor,patch)
53
 *	@param      array		$versionarray2		Array of version (vermajor,verminor,patch)
54
 *	@return     int          			       	-4,-3,-2,-1 if versionarray1<versionarray2 (value depends on level of difference)
55
 * 												0 if same
56
 * 												1,2,3,4 if versionarray1>versionarray2 (value depends on level of difference)
57
 */
58
function versioncompare($versionarray1,$versionarray2)
59
{
60
    $ret=0;
61
    $level=0;
62
    $count1=count($versionarray1);
63
    $count2=count($versionarray2);
64
    $maxcount=max($count1,$count2);
65
    while ($level < $maxcount)
66
    {
67
        $operande1=isset($versionarray1[$level])?$versionarray1[$level]:0;
68
        $operande2=isset($versionarray2[$level])?$versionarray2[$level]:0;
69
        if (preg_match('/alpha|dev/i',$operande1)) $operande1=-5;
70
        if (preg_match('/alpha|dev/i',$operande2)) $operande2=-5;
71
        if (preg_match('/beta$/i',$operande1)) $operande1=-4;
72
        if (preg_match('/beta$/i',$operande2)) $operande2=-4;
73
        if (preg_match('/beta([0-9])+/i',$operande1)) $operande1=-3;
74
        if (preg_match('/beta([0-9])+/i',$operande2)) $operande2=-3;
75
        if (preg_match('/rc$/i',$operande1)) $operande1=-2;
76
        if (preg_match('/rc$/i',$operande2)) $operande2=-2;
77
        if (preg_match('/rc([0-9])+/i',$operande1)) $operande1=-1;
78
        if (preg_match('/rc([0-9])+/i',$operande2)) $operande2=-1;
79
        $level++;
80
        //print 'level '.$level.' '.$operande1.'-'.$operande2.'<br>';
81
        if ($operande1 < $operande2) { $ret = -$level; break; }
82
        if ($operande1 > $operande2) { $ret = $level; break; }
83
    }
84
    //print join('.',$versionarray1).'('.count($versionarray1).') / '.join('.',$versionarray2).'('.count($versionarray2).') => '.$ret.'<br>'."\n";
85
    return $ret;
86
}
87
88
89
/**
90
 *	Return version PHP
91
 *
92
 *	@return     array               Tableau de version (vermajeur,vermineur,autre)
93
 */
94
function versionphparray()
95
{
96
    return explode('.',PHP_VERSION);
97
}
98
99
/**
100
 *	Return version Dolibarr
101
 *
102
 *	@return     array               Tableau de version (vermajeur,vermineur,autre)
103
 */
104
function versiondolibarrarray()
105
{
106
    return explode('.',DOL_VERSION);
107
}
108
109
110
/**
111
 *	Launch a sql file. Function used by:
112
 *  - Migrate process (dolibarr-xyz-abc.sql)
113
 *  - Loading sql menus (auguria)
114
 *  - Running specific Sql by a module init
115
 *  Install process however does not use it.
116
 *  Note that Sql files must have all comments at start of line.
117
 *
118
 *	@param		string	$sqlfile		Full path to sql file
119
 * 	@param		int		$silent			1=Do not output anything, 0=Output line for update page
120
 * 	@param		int		$entity			Entity targeted for multicompany module
121
 *	@param		int		$usesavepoint	1=Run a savepoint before each request and a rollback to savepoint if error (this allow to have some request with errors inside global transactions).
122
 *	@param		string	$handler		Handler targeted for menu
123
 *	@param 		string	$okerror		Family of errors we accept ('default', 'none')
124
 * 	@return		int						<=0 if KO, >0 if OK
125
 */
126
function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$okerror='default')
127
{
128
    global $db, $conf, $langs, $user;
129
130
    dol_syslog("Admin.lib::run_sql run sql file ".$sqlfile." silent=".$silent." entity=".$entity." usesavepoint=".$usesavepoint." handler=".$handler." okerror=".$okerror, LOG_DEBUG);
131
132
    $ok=0;
133
    $error=0;
134
    $i=0;
135
    $buffer = '';
136
    $arraysql = array();
137
138
    // Get version of database
139
    $versionarray=$db->getVersionArray();
140
141
    $fp = fopen($sqlfile,"r");
142
    if ($fp)
143
    {
144
        while (! feof($fp))
145
        {
146
            $buf = fgets($fp, 32768);
147
148
            // Test if request must be ran only for particular database or version (if yes, we must remove the -- comment)
149
            if (preg_match('/^--\sV(MYSQL|PGSQL)([^\s]*)/i',$buf,$reg))
150
            {
151
            	$qualified=1;
152
153
            	// restrict on database type
154
            	if (! empty($reg[1]))
155
            	{
156
            		if (! preg_match('/'.preg_quote($reg[1]).'/i',$db->type)) $qualified=0;
157
            	}
158
159
            	// restrict on version
160
            	if ($qualified)
161
            	{
162
            		if (! empty($reg[2]))
163
            		{
164
            			if (is_numeric($reg[2]))	// This is a version
165
            			{
166
			                $versionrequest=explode('.',$reg[2]);
167
			                //print var_dump($versionrequest);
168
			                //print var_dump($versionarray);
169
			                if (! count($versionrequest) || ! count($versionarray) || versioncompare($versionrequest,$versionarray) > 0)
170
			                {
171
			                	$qualified=0;
172
			                }
173
            			}
174
            			else						// This is a test on a constant. For example when we have -- VMYSQLUTF8UNICODE, we test constant $conf->global->UTF8UNICODE
175
            			{
176
            				$dbcollation = strtoupper(preg_replace('/_/', '', $conf->db->dolibarr_main_db_collation));
177
            				//var_dump($reg[2]);
178
            				//var_dump($dbcollation);
179
            				if (empty($conf->db->dolibarr_main_db_collation) || ($reg[2] != $dbcollation)) $qualified=0;
180
            				//var_dump($qualified);
181
            			}
182
            		}
183
            	}
184
185
                if ($qualified)
186
                {
187
                    // Version qualified, delete SQL comments
188
                    $buf=preg_replace('/^--\sV(MYSQL|PGSQL)([^\s]*)/i','',$buf);
189
                    //print "Ligne $i qualifi?e par version: ".$buf.'<br>';
190
                }
191
            }
192
193
            // Add line buf to buffer if not a comment
194
            if (! preg_match('/^\s*--/',$buf))
195
            {
196
                $buf=preg_replace('/([,;ERLT\)])\s*--.*$/i','\1',$buf); //remove comment from a line that not start with -- before add it to the buffer
197
                $buffer .= trim($buf);
198
            }
199
200
            //          print $buf.'<br>';
201
202
            if (preg_match('/;/',$buffer))	// If string contains ';', it's end of a request string, we save it in arraysql.
203
            {
204
                // Found new request
205
                if ($buffer) $arraysql[$i]=$buffer;
206
                $i++;
207
                $buffer='';
208
            }
209
        }
210
211
        if ($buffer) $arraysql[$i]=$buffer;
212
        fclose($fp);
213
    }
214
    else
215
    {
216
        dol_syslog("Admin.lib::run_sql failed to open file ".$sqlfile, LOG_ERR);
217
    }
218
219
    // Loop on each request to see if there is a __+MAX_table__ key
220
    $listofmaxrowid=array();	// This is a cache table
221
    foreach($arraysql as $i => $sql)
222
    {
223
        $newsql=$sql;
224
225
        // Replace __+MAX_table__ with max of table
226
        while (preg_match('/__\+MAX_([A-Za-z_]+)__/i',$newsql,$reg))
227
        {
228
            $table=$reg[1];
229
            if (! isset($listofmaxrowid[$table]))
230
            {
231
                //var_dump($db);
232
                $sqlgetrowid='SELECT MAX(rowid) as max from '.$table;
233
                $resql=$db->query($sqlgetrowid);
234
                if ($resql)
235
                {
236
                    $obj=$db->fetch_object($resql);
237
                    $listofmaxrowid[$table]=$obj->max;
238
                    if (empty($listofmaxrowid[$table])) $listofmaxrowid[$table]=0;
239
                }
240
                else
241
                {
242
                    if (! $silent) print '<tr><td valign="top" colspan="2">';
243
                    if (! $silent) print '<div class="error">'.$langs->trans("Failed to get max rowid for ".$table)."</div></td>";
244
                    if (! $silent) print '</tr>';
245
                    $error++;
246
                    break;
247
                }
248
            }
249
            $from='__+MAX_'.$table.'__';
250
            $to='+'.$listofmaxrowid[$table];
251
            $newsql=str_replace($from,$to,$newsql);
252
            dol_syslog('Admin.lib::run_sql New Request '.($i+1).' (replacing '.$from.' to '.$to.')', LOG_DEBUG);
253
254
            $arraysql[$i]=$newsql;
255
        }
256
    }
257
258
    // Loop on each request to execute request
259
    $cursorinsert=0;
260
    $listofinsertedrowid=array();
261
    foreach($arraysql as $i => $sql)
262
    {
263
        if ($sql)
264
        {
265
        	// Replace the prefix tables
266
        	if (MAIN_DB_PREFIX != 'llx_')
267
        	{
268
        		$sql=preg_replace('/llx_/i',MAIN_DB_PREFIX,$sql);
269
        	}
270
271
            if (!empty($handler)) $sql=preg_replace('/__HANDLER__/i',"'".$handler."'",$sql);
272
273
            $newsql=preg_replace('/__ENTITY__/i',(!empty($entity)?$entity:$conf->entity),$sql);
274
275
            // Ajout trace sur requete (eventuellement a commenter si beaucoup de requetes)
276
            if (! $silent) print '<tr><td class="tdtop">'.$langs->trans("Request").' '.($i+1)." sql='".dol_htmlentities($newsql,ENT_NOQUOTES)."'</td></tr>\n";
277
            dol_syslog('Admin.lib::run_sql Request '.($i+1), LOG_DEBUG);
278
			$sqlmodified=0;
279
280
            // Replace for encrypt data
281
            if (preg_match_all('/__ENCRYPT\(\'([^\']+)\'\)__/i',$newsql,$reg))
282
            {
283
                $num=count($reg[0]);
284
285
                for($j=0;$j<$num;$j++)
286
                {
287
                    $from 	= $reg[0][$j];
288
                    $to		= $db->encrypt($reg[1][$j],1);
289
                    $newsql	= str_replace($from,$to,$newsql);
290
                }
291
                $sqlmodified++;
292
            }
293
294
            // Replace for decrypt data
295
            if (preg_match_all('/__DECRYPT\(\'([A-Za-z0-9_]+)\'\)__/i',$newsql,$reg))
296
            {
297
                $num=count($reg[0]);
298
299
                for($j=0;$j<$num;$j++)
300
                {
301
                    $from 	= $reg[0][$j];
302
                    $to		= $db->decrypt($reg[1][$j]);
303
                    $newsql	= str_replace($from,$to,$newsql);
304
                }
305
                $sqlmodified++;
306
            }
307
308
            // Replace __x__ with rowid of insert nb x
309
            while (preg_match('/__([0-9]+)__/',$newsql,$reg))
310
            {
311
                $cursor=$reg[1];
312
                if (empty($listofinsertedrowid[$cursor]))
313
                {
314
                    if (! $silent) print '<tr><td valign="top" colspan="2">';
315
                    if (! $silent) print '<div class="error">'.$langs->trans("FileIsNotCorrect")."</div></td>";
316
                    if (! $silent) print '</tr>';
317
                    $error++;
318
                    break;
319
                }
320
                $from='__'.$cursor.'__';
321
                $to=$listofinsertedrowid[$cursor];
322
                $newsql=str_replace($from,$to,$newsql);
323
                $sqlmodified++;
324
            }
325
326
            if ($sqlmodified) dol_syslog('Admin.lib::run_sql New Request '.($i+1), LOG_DEBUG);
327
328
            $result=$db->query($newsql,$usesavepoint);
329
            if ($result)
330
            {
331
                if (! $silent) print '<!-- Result = OK -->'."\n";
332
333
                if (preg_replace('/insert into ([^\s]+)/i',$newsql,$reg))
334
                {
335
                    $cursorinsert++;
336
337
                    // It's an insert
338
                    $table=preg_replace('/([^a-zA-Z_]+)/i','',$reg[1]);
339
                    $insertedrowid=$db->last_insert_id($table);
340
                    $listofinsertedrowid[$cursorinsert]=$insertedrowid;
341
                    dol_syslog('Admin.lib::run_sql Insert nb '.$cursorinsert.', done in table '.$table.', rowid is '.$listofinsertedrowid[$cursorinsert], LOG_DEBUG);
342
                }
343
                // 	          print '<td align="right">OK</td>';
344
            }
345
            else
346
            {
347
                $errno=$db->errno();
348
                if (! $silent) print '<!-- Result = '.$errno.' -->'."\n";
349
350
				// Define list of errors we accept (array $okerrors)
351
            	$okerrors=array(	// By default
352
					'DB_ERROR_TABLE_ALREADY_EXISTS',
353
					'DB_ERROR_COLUMN_ALREADY_EXISTS',
354
					'DB_ERROR_KEY_NAME_ALREADY_EXISTS',
355
					'DB_ERROR_TABLE_OR_KEY_ALREADY_EXISTS',		// PgSql use same code for table and key already exist
356
					'DB_ERROR_RECORD_ALREADY_EXISTS',
357
					'DB_ERROR_NOSUCHTABLE',
358
					'DB_ERROR_NOSUCHFIELD',
359
					'DB_ERROR_NO_FOREIGN_KEY_TO_DROP',
360
					'DB_ERROR_NO_INDEX_TO_DROP',
361
					'DB_ERROR_CANNOT_CREATE',    		// Qd contrainte deja existante
362
					'DB_ERROR_CANT_DROP_PRIMARY_KEY',
363
					'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS',
364
            		'DB_ERROR_22P02'
365
				);
366
                if ($okerror == 'none') $okerrors=array();
367
368
                // Is it an error we accept
369
				if (! in_array($errno,$okerrors))
370
				{
371
				    if (! $silent) print '<tr><td valign="top" colspan="2">';
372
				    if (! $silent) print '<div class="error">'.$langs->trans("Error")." ".$db->errno().": ".$newsql."<br>".$db->error()."</div></td>";
373
				    if (! $silent) print '</tr>'."\n";
374
				    dol_syslog('Admin.lib::run_sql Request '.($i+1)." Error ".$db->errno()." ".$newsql."<br>".$db->error(), LOG_ERR);
375
				    $error++;
376
				}
377
            }
378
379
            if (! $silent) print '</tr>'."\n";
380
        }
381
    }
382
383
    if ($error == 0)
384
    {
385
        if (! $silent) print '<tr><td>'.$langs->trans("ProcessMigrateScript").'</td>';
386
        if (! $silent) print '<td align="right">'.$langs->trans("OK").'</td></tr>'."\n";
387
        $ok = 1;
388
    }
389
    else
390
    {
391
        if (! $silent) print '<tr><td>'.$langs->trans("ProcessMigrateScript").'</td>';
392
        if (! $silent) print '<td align="right"><font class="error">'.$langs->trans("KO").'</font></td></tr>'."\n";
393
        $ok = 0;
394
    }
395
396
    return $ok;
397
}
398
399
400
/**
401
 *	Effacement d'une constante dans la base de donnees
402
 *
403
 *	@param	    DoliDB		$db         Database handler
404
 *	@param	    string		$name		Name of constant or rowid of line
405
 *	@param	    int			$entity		Multi company id, -1 for all entities
406
 *	@return     int         			<0 if KO, >0 if OK
407
 *
408
 *	@see		dolibarr_get_const, dolibarr_set_const, dol_set_user_param
409
 */
410
function dolibarr_del_const($db, $name, $entity=1)
411
{
412
    global $conf;
413
414
    if (empty($name))
415
    {
416
    	dol_print_error('','Error call dolibar_del_const with parameter name empty');
417
    	return -1;
418
    }
419
420
    $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
421
    $sql.= " WHERE (".$db->decrypt('name')." = '".$db->escape($name)."'";
422
    if (is_numeric($name)) $sql.= " OR rowid = '".$db->escape($name)."'";
423
    $sql.= ")";
424
    if ($entity >= 0) $sql.= " AND entity = ".$entity;
425
426
    dol_syslog("admin.lib::dolibarr_del_const", LOG_DEBUG);
427
    $resql=$db->query($sql);
428
    if ($resql)
429
    {
430
        $conf->global->$name='';
431
        return 1;
432
    }
433
    else
434
    {
435
        dol_print_error($db);
436
        return -1;
437
    }
438
}
439
440
/**
441
 *	Recupere une constante depuis la base de donnees.
442
 *
443
 *	@param	    DoliDB		$db         Database handler
444
 *	@param	    string		$name		Nom de la constante
445
 *	@param	    int			$entity		Multi company id
446
 *	@return     string      			Valeur de la constante
447
 *
448
 *	@see		dolibarr_del_const, dolibarr_set_const, dol_set_user_param
449
 */
450
function dolibarr_get_const($db, $name, $entity=1)
451
{
452
    global $conf;
453
    $value='';
454
455
    $sql = "SELECT ".$db->decrypt('value')." as value";
456
    $sql.= " FROM ".MAIN_DB_PREFIX."const";
457
    $sql.= " WHERE name = ".$db->encrypt($name,1);
458
    $sql.= " AND entity = ".$entity;
459
460
    dol_syslog("admin.lib::dolibarr_get_const", LOG_DEBUG);
461
    $resql=$db->query($sql);
462
    if ($resql)
463
    {
464
        $obj=$db->fetch_object($resql);
465
        if ($obj) $value=$obj->value;
466
    }
467
    return $value;
468
}
469
470
471
/**
472
 *	Insert a parameter (key,value) into database (delete old key then insert it again).
473
 *
474
 *	@param	    DoliDB		$db         Database handler
475
 *	@param	    string		$name		Name of constant
476
 *	@param	    string		$value		Value of constant
477
 *	@param	    string		$type		Type of constante (chaine par defaut)
478
 *	@param	    int			$visible	Is constant visible in Setup->Other page (0 by default)
479
 *	@param	    string		$note		Note on parameter
480
 *	@param	    int			$entity		Multi company id (0 means all entities)
481
 *	@return     int         			-1 if KO, 1 if OK
482
 *
483
 *	@see		dolibarr_del_const, dolibarr_get_const, dol_set_user_param
484
 */
485
function dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
486
{
487
    global $conf;
488
489
    // Clean parameters
490
    $name=trim($name);
491
492
    // Check parameters
493
    if (empty($name))
494
    {
495
        dol_print_error($db,"Error: Call to function dolibarr_set_const with wrong parameters", LOG_ERR);
496
        exit;
497
    }
498
499
    //dol_syslog("dolibarr_set_const name=$name, value=$value type=$type, visible=$visible, note=$note entity=$entity");
500
501
    $db->begin();
502
503
    $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
504
    $sql.= " WHERE name = ".$db->encrypt($name,1);
505
    if ($entity >= 0) $sql.= " AND entity = ".$entity;
506
507
    dol_syslog("admin.lib::dolibarr_set_const", LOG_DEBUG);
508
    $resql=$db->query($sql);
509
510
    if (strcmp($value,''))	// true if different. Must work for $value='0' or $value=0
511
    {
512
        $sql = "INSERT INTO ".MAIN_DB_PREFIX."const(name,value,type,visible,note,entity)";
513
        $sql.= " VALUES (";
514
        $sql.= $db->encrypt($name,1);
515
        $sql.= ", ".$db->encrypt($value,1);
516
        $sql.= ",'".$type."',".$visible.",'".$db->escape($note)."',".$entity.")";
517
518
        //print "sql".$value."-".pg_escape_string($value)."-".$sql;exit;
519
        //print "xx".$db->escape($value);
520
        dol_syslog("admin.lib::dolibarr_set_const", LOG_DEBUG);
521
        $resql=$db->query($sql);
522
    }
523
524
    if ($resql)
525
    {
526
        $db->commit();
527
        $conf->global->$name=$value;
528
        return 1;
529
    }
530
    else
531
    {
532
        $error=$db->lasterror();
533
        $db->rollback();
534
        return -1;
535
    }
536
}
537
538
539
540
541
/**
542
 * Prepare array with list of tabs
543
 *
544
 * @return  array				Array of tabs to show
545
 */
546
function modules_prepare_head()
547
{
548
	global $langs, $conf, $user;
549
	$h = 0;
550
	$head = array();
551
552
	$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=common";
553
	$head[$h][1] = $langs->trans("AvailableModules");
554
	$head[$h][2] = 'common';
555
	$h++;
556
557
	$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=marketplace";
558
	$head[$h][1] = $langs->trans("ModulesMarketPlaces");
559
	$head[$h][2] = 'marketplace';
560
	$h++;
561
562
	$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=deploy";
563
	$head[$h][1] = $langs->trans("AddExtensionThemeModuleOrOther");
564
	$head[$h][2] = 'deploy';
565
	$h++;
566
567
	$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=develop";
568
	$head[$h][1] = $langs->trans("ModulesDevelopYourModule");
569
	$head[$h][2] = 'develop';
570
	$h++;
571
572
	return $head;
573
}
574
575
576
/**
577
 * Prepare array with list of tabs
578
 *
579
 * @return  array				Array of tabs to show
580
 */
581
function security_prepare_head()
582
{
583
    global $langs, $conf, $user;
584
    $h = 0;
585
    $head = array();
586
587
    $head[$h][0] = DOL_URL_ROOT."/admin/security_other.php";
588
    $head[$h][1] = $langs->trans("Miscellaneous");
589
    $head[$h][2] = 'misc';
590
    $h++;
591
592
    $head[$h][0] = DOL_URL_ROOT."/admin/security.php";
593
    $head[$h][1] = $langs->trans("Passwords");
594
    $head[$h][2] = 'passwords';
595
    $h++;
596
597
    $head[$h][0] = DOL_URL_ROOT."/admin/security_file.php";
598
    $head[$h][1] = $langs->trans("Files").' ('.$langs->trans("Upload").')';
599
    $head[$h][2] = 'file';
600
    $h++;
601
602
    /*
603
    $head[$h][0] = DOL_URL_ROOT."/admin/security_file_download.php";
604
    $head[$h][1] = $langs->trans("Files").' ('.$langs->trans("Download").')';
605
    $head[$h][2] = 'filedownload';
606
    $h++;
607
	*/
608
609
    $head[$h][0] = DOL_URL_ROOT."/admin/proxy.php";
610
    $head[$h][1] = $langs->trans("ExternalAccess");
611
    $head[$h][2] = 'proxy';
612
    $h++;
613
614
    $head[$h][0] = DOL_URL_ROOT."/admin/events.php";
615
    $head[$h][1] = $langs->trans("Audit");
616
    $head[$h][2] = 'audit';
617
    $h++;
618
619
    $head[$h][0] = DOL_URL_ROOT."/admin/perms.php";
620
    $head[$h][1] = $langs->trans("DefaultRights");
621
    $head[$h][2] = 'default';
622
    $h++;
623
624
    return $head;
625
}
626
627
628
/**
629
 * Prepare array with list of tabs
630
 *
631
 * @return  array				Array of tabs to show
632
 */
633
function translation_prepare_head()
634
{
635
    global $langs, $conf, $user;
636
    $h = 0;
637
    $head = array();
638
639
    $head[$h][0] = DOL_URL_ROOT."/admin/translation.php?mode=overwrite";
640
    $head[$h][1] = $langs->trans("TranslationOverwriteKey");
641
    $head[$h][2] = 'overwrite';
642
    $h++;
643
644
    $head[$h][0] = DOL_URL_ROOT."/admin/translation.php?mode=searchkey";
645
    $head[$h][1] = $langs->trans("TranslationKeySearch");
646
    $head[$h][2] = 'searchkey';
647
    $h++;
648
649
    complete_head_from_modules($conf,$langs,null,$head,$h,'translation_admin');
650
651
    complete_head_from_modules($conf,$langs,null,$head,$h,'translation_admin','remove');
652
653
654
    return $head;
655
}
656
657
658
/**
659
 * Prepare array with list of tabs
660
 *
661
 * @return  array				Array of tabs to show
662
 */
663
function defaultvalues_prepare_head()
664
{
665
    global $langs, $conf, $user;
666
    $h = 0;
667
    $head = array();
668
669
    $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=createform";
670
    $head[$h][1] = $langs->trans("DefaultCreateForm");
671
    $head[$h][2] = 'createform';
672
    $h++;
673
674
    $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=filters";
675
    $head[$h][1] = $langs->trans("DefaultSearchFilters");
676
    $head[$h][2] = 'filters';
677
    $h++;
678
679
    $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=sortorder";
680
    $head[$h][1] = $langs->trans("DefaultSortOrder");
681
    $head[$h][2] = 'sortorder';
682
    $h++;
683
684
    $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=focus";
685
    $head[$h][1] = $langs->trans("DefaultFocus");
686
    $head[$h][2] = 'focus';
687
    $h++;
688
689
    /*$head[$h][0] = DOL_URL_ROOT."/admin/translation.php?mode=searchkey";
690
    $head[$h][1] = $langs->trans("TranslationKeySearch");
691
    $head[$h][2] = 'searchkey';
692
    $h++;*/
693
694
    complete_head_from_modules($conf,$langs,null,$head,$h,'defaultvalues_admin');
695
696
    complete_head_from_modules($conf,$langs,null,$head,$h,'defaultvalues_admin','remove');
697
698
699
    return $head;
700
}
701
702
703
/**
704
 * 	Return list of session
705
 *
706
 *	@return		array			Array list of sessions
707
 */
708
function listOfSessions()
709
{
710
    global $conf;
711
712
    $arrayofSessions = array();
713
    // session.save_path can be returned empty so we set a default location and work from there
714
    $sessPath = '/tmp';
715
    $iniPath = ini_get("session.save_path");
716
    if ($iniPath) {
717
        $sessPath = $iniPath;
718
    }
719
    $sessPath .= '/'; // We need the trailing slash
720
    dol_syslog('admin.lib:listOfSessions sessPath='.$sessPath);
721
722
    $dh = @opendir(dol_osencode($sessPath));
723
    if ($dh)
724
    {
725
        while(($file = @readdir($dh)) !== false)
726
        {
727
            if (preg_match('/^sess_/i',$file) && $file != "." && $file != "..")
728
            {
729
                $fullpath = $sessPath.$file;
730
                if(! @is_dir($fullpath) && is_readable($fullpath))
731
                {
732
                    $sessValues = file_get_contents($fullpath);	// get raw session data
733
                    // Example of possible value
734
                    //$sessValues = 'newtoken|s:32:"1239f7a0c4b899200fe9ca5ea394f307";dol_loginmesg|s:0:"";newtoken|s:32:"1236457104f7ae0f328c2928973f3cb5";dol_loginmesg|s:0:"";token|s:32:"123615ad8d650c5cc4199b9a1a76783f";dol_login|s:5:"admin";dol_authmode|s:8:"dolibarr";dol_tz|s:1:"1";dol_tz_string|s:13:"Europe/Berlin";dol_dst|i:0;dol_dst_observed|s:1:"1";dol_dst_first|s:0:"";dol_dst_second|s:0:"";dol_screenwidth|s:4:"1920";dol_screenheight|s:3:"971";dol_company|s:12:"MyBigCompany";dol_entity|i:1;mainmenu|s:4:"home";leftmenuopened|s:10:"admintools";idmenu|s:0:"";leftmenu|s:10:"admintools";';
735
736
                    if (preg_match('/dol_login/i',$sessValues) && // limit to dolibarr session
737
                        (preg_match('/dol_entity\|i:'.$conf->entity.';/i',$sessValues) || preg_match('/dol_entity\|s:([0-9]+):"'.$conf->entity.'"/i',$sessValues)) && // limit to current entity
738
                    preg_match('/dol_company\|s:([0-9]+):"('.$conf->global->MAIN_INFO_SOCIETE_NOM.')"/i',$sessValues)) // limit to company name
739
                    {
740
                        $tmp=explode('_', $file);
741
                        $idsess=$tmp[1];
742
                        $login = preg_match('/dol_login\|s:[0-9]+:"([A-Za-z0-9]+)"/i',$sessValues,$regs);
743
                        $arrayofSessions[$idsess]["login"] = $regs[1];
744
                        $arrayofSessions[$idsess]["age"] = time()-filectime($fullpath);
745
                        $arrayofSessions[$idsess]["creation"] = filectime($fullpath);
746
                        $arrayofSessions[$idsess]["modification"] = filemtime($fullpath);
747
                        $arrayofSessions[$idsess]["raw"] = $sessValues;
748
                    }
749
                }
750
            }
751
        }
752
        @closedir($dh);
753
    }
754
755
    return $arrayofSessions;
756
}
757
758
/**
759
 * 	Purge existing sessions
760
 *
761
 * 	@param		int		$mysessionid		To avoid to try to delete my own session
762
 * 	@return		int							>0 if OK, <0 if KO
763
 */
764
function purgeSessions($mysessionid)
765
{
766
    global $conf;
767
768
    $arrayofSessions = array();
769
    $sessPath = ini_get("session.save_path")."/";
770
    dol_syslog('admin.lib:purgeSessions mysessionid='.$mysessionid.' sessPath='.$sessPath);
771
772
    $error=0;
773
    $dh = @opendir(dol_osencode($sessPath));
774
    while(($file = @readdir($dh)) !== false)
775
    {
776
        if ($file != "." && $file != "..")
777
        {
778
            $fullpath = $sessPath.$file;
779
            if(! @is_dir($fullpath))
780
            {
781
                $sessValues = file_get_contents($fullpath);	// get raw session data
782
783
                if (preg_match('/dol_login/i',$sessValues) && // limit to dolibarr session
784
                preg_match('/dol_entity\|s:([0-9]+):"('.$conf->entity.')"/i',$sessValues) && // limit to current entity
785
                preg_match('/dol_company\|s:([0-9]+):"('.$conf->global->MAIN_INFO_SOCIETE_NOM.')"/i',$sessValues)) // limit to company name
786
                {
787
                    $tmp=explode('_', $file);
788
                    $idsess=$tmp[1];
789
                    // We remove session if it's not ourself
790
                    if ($idsess != $mysessionid)
791
                    {
792
                        $res=@unlink($fullpath);
793
                        if (! $res) $error++;
794
                    }
795
                }
796
            }
797
        }
798
    }
799
    @closedir($dh);
800
801
    if (! $error) return 1;
802
    else return -$error;
803
}
804
805
806
807
/**
808
 *  Enable a module
809
 *
810
 *  @param      string		$value      Name of module to activate
811
 *  @param      int			$withdeps   Activate/Disable also all dependencies
812
 *  @return     array      			    array('nbmodules'=>nb modules activated with success, 'errors=>array of error messages, 'nbperms'=>Nb permission added);
813
 */
814
function activateModule($value,$withdeps=1)
815
{
816
    global $db, $modules, $langs, $conf, $mysoc;
817
818
	// Check parameters
819
	if (empty($value)) {
820
		$ret['errors'][] = 'ErrorBadParameter';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$ret was never initialized. Although not strictly required by PHP, it is generally a good practice to add $ret = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
821
		return $ret;
822
	}
823
824
    $ret=array('nbmodules'=>0, 'errors'=>array(), 'nbperms'=>0);
825
    $modName = $value;
826
    $modFile = $modName . ".class.php";
827
828
    // Loop on each directory to fill $modulesdir
829
    $modulesdir = dolGetModulesDirs();
830
831
    // Loop on each modulesdir directories
832
    $found=false;
833
    foreach ($modulesdir as $dir)
834
    {
835
        if (file_exists($dir.$modFile))
836
        {
837
            $found=@include_once $dir.$modFile;
838
            if ($found) break;
839
        }
840
    }
841
842
    $objMod = new $modName($db);
843
844
    // Test if PHP version ok
845
    $verphp=versionphparray();
846
    $vermin=isset($objMod->phpmin)?$objMod->phpmin:0;
847
	if (is_array($vermin) && versioncompare($verphp, $vermin) < 0) {
848
		$ret['errors'][] = $langs->trans("ErrorModuleRequirePHPVersion", versiontostring($vermin));
849
		return $ret;
850
	}
851
852
    // Test if Dolibarr version ok
853
    $verdol=versiondolibarrarray();
854
    $vermin=isset($objMod->need_dolibarr_version)?$objMod->need_dolibarr_version:0;
855
    //print 'eee '.versioncompare($verdol,$vermin).' - '.join(',',$verdol).' - '.join(',',$vermin);exit;
856
	if (is_array($vermin) && versioncompare($verdol, $vermin) < 0) {
857
		$ret['errors'][] = $langs->trans("ErrorModuleRequireDolibarrVersion", versiontostring($vermin));
858
		return $ret;
859
	}
860
861
	// Test if javascript requirement ok
862
	if (!empty($objMod->need_javascript_ajax) && empty($conf->use_javascript_ajax)) {
863
		$ret['errors'][] = $langs->trans("ErrorModuleRequireJavascript");
864
		return $ret;
865
	}
866
867
	$const_name = $objMod->const_name;
868
	if(!empty($conf->global->$const_name)){
869
        return $ret;
870
    }
871
872
    $result=$objMod->init();    // Enable module
873
    if ($result <= 0)
874
    {
875
        $ret['errors'][]=$objMod->error;
876
    }
877
    else
878
    {
879
        if ($withdeps)
880
        {
881
            if (isset($objMod->depends) && is_array($objMod->depends) && ! empty($objMod->depends))
882
            {
883
                // Activation of modules this module depends on
884
                // this->depends may be array('modModule1', 'mmodModule2') or array('always'=>"modModule1", 'FR'=>'modModule2')
885
                foreach ($objMod->depends as $key => $modulestring)
886
                {
887
                    if ((! is_numeric($key)) && $key != 'always' && $key != $mysoc->country_code)
888
                    {
889
                        dol_syslog("We are not concerned by dependency with key=".$key." because our country is ".$mysoc->country_code);
890
                        continue;
891
                    }
892
                	$activate = false;
893
                	foreach ($modulesdir as $dir)
894
                	{
895
                		if (file_exists($dir.$modulestring.".class.php"))
896
                		{
897
                			$resarray = activateModule($modulestring);
898
    						if (empty($resarray['errors'])){
899
    						    $activate = true;
900
                            }else{
901
    						    foreach ($resarray['errors'] as $errorMessage){
902
                                    dol_syslog($errorMessage, LOG_ERR);
903
                                }
904
                            }
905
    						break;
906
                		}
907
                	}
908
909
    				if ($activate)
910
    				{
911
    				    $ret['nbmodules']+=$resarray['nbmodules'];
0 ignored issues
show
Bug introduced by
The variable $resarray does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
912
    				    $ret['nbperms']+=$resarray['nbperms'];
913
    				}
914
    				else
915
    				{
916
    				    $ret['errors'][] = $langs->trans('activateModuleDependNotSatisfied', $objMod->name, $modulestring);
917
    				}
918
                }
919
            }
920
921
            if (isset($objMod->conflictwith) && is_array($objMod->conflictwith) && ! empty($objMod->conflictwith))
922
            {
923
                // Desactivation des modules qui entrent en conflit
924
                $num = count($objMod->conflictwith);
925
                for ($i = 0; $i < $num; $i++)
926
                {
927
                	foreach ($modulesdir as $dir)
928
                	{
929
                		if (file_exists($dir.$objMod->conflictwith[$i].".class.php"))
930
                		{
931
                			unActivateModule($objMod->conflictwith[$i],0);
932
                		}
933
                	}
934
                }
935
            }
936
        }
937
    }
938
939
    if (! count($ret['errors']))
940
    {
941
        $ret['nbmodules']++;
942
        $ret['nbperms']+=count($objMod->rights);
943
    }
944
945
    return $ret;
946
}
947
948
949
/**
950
 *  Disable a module
951
 *
952
 *  @param      string		$value               Nom du module a desactiver
953
 *  @param      int			$requiredby          1=Desactive aussi modules dependants
954
 *  @return     string     				         Error message or '';
955
 */
956
function unActivateModule($value, $requiredby=1)
957
{
958
    global $db, $modules, $conf;
959
960
    // Check parameters
961
    if (empty($value)) return 'ErrorBadParameter';
962
963
    $ret='';
964
    $modName = $value;
965
    $modFile = $modName . ".class.php";
966
967
    // Loop on each directory to fill $modulesdir
968
    $modulesdir = dolGetModulesDirs();
969
970
    // Loop on each modulesdir directories
971
    $found=false;
972
    foreach ($modulesdir as $dir)
973
    {
974
        if (file_exists($dir.$modFile))
975
        {
976
            $found=@include_once $dir.$modFile;
977
            if ($found) break;
978
        }
979
    }
980
981
    if ($found)
982
    {
983
        $objMod = new $modName($db);
984
        $result=$objMod->remove();
985
        if ($result <= 0) $ret=$objMod->error;
986
    }
987
    else
988
    {
989
        //print $dir.$modFile;
990
    	// TODO Replace this after DolibarrModules is moved as abstract class with a try catch to show module we try to disable has not been found or could not be loaded
991
        include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
992
    	$genericMod = new DolibarrModules($db);
993
        $genericMod->name=preg_replace('/^mod/i','',$modName);
994
        $genericMod->rights_class=strtolower(preg_replace('/^mod/i','',$modName));
995
        $genericMod->const_name='MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',$modName));
996
        dol_syslog("modules::unActivateModule Failed to find module file, we use generic function with name " . $modName);
997
        $genericMod->_remove(array());
998
    }
999
1000
    // Desactivation des modules qui dependent de lui
1001
    if (! $ret && $requiredby)
1002
    {
1003
        $countrb=count($objMod->requiredby);
0 ignored issues
show
Bug introduced by
The variable $objMod does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1004
        for ($i = 0; $i < $countrb; $i++)
1005
        {
1006
            //var_dump($objMod->requiredby[$i]);
1007
            unActivateModule($objMod->requiredby[$i]);
1008
        }
1009
    }
1010
1011
    return $ret;
1012
}
1013
1014
1015
/**
1016
 *  Add external modules to list of dictionaries
1017
 *
1018
 * 	@param		array		$taborder			Taborder
1019
 * 	@param		array		$tabname			Tabname
1020
 * 	@param		array		$tablib				Tablib
1021
 * 	@param		array		$tabsql				Tabsql
1022
 * 	@param		array		$tabsqlsort			Tabsqlsort
1023
 * 	@param		array		$tabfield			Tabfield
1024
 * 	@param		array		$tabfieldvalue		Tabfieldvalue
1025
 * 	@param		array		$tabfieldinsert		Tabfieldinsert
1026
 * 	@param		array		$tabrowid			Tabrowid
1027
 * 	@param		array		$tabcond			Tabcond
1028
 * 	@param		array		$tabhelp			Tabhelp
1029
 *  @param		array		$tabfieldcheck		Tabfieldcheck
1030
 * 	@return		int			1
1031
 */
1032
function complete_dictionary_with_modules(&$taborder,&$tabname,&$tablib,&$tabsql,&$tabsqlsort,&$tabfield,&$tabfieldvalue,&$tabfieldinsert,&$tabrowid,&$tabcond,&$tabhelp,&$tabfieldcheck)
1033
{
1034
    global $db, $modules, $conf, $langs;
1035
1036
    // Search modules
1037
	$modulesdir = dolGetModulesDirs();
1038
    $i = 0; // is a sequencer of modules found
1039
    $j = 0; // j is module number. Automatically affected if module number not defined.
1040
1041
    foreach ($modulesdir as $dir)
1042
    {
1043
    	// Load modules attributes in arrays (name, numero, orders) from dir directory
1044
    	//print $dir."\n<br>";
1045
    	dol_syslog("Scan directory ".$dir." for modules");
1046
        $handle=@opendir(dol_osencode($dir));
1047
        if (is_resource($handle))
1048
        {
1049
            while (($file = readdir($handle))!==false)
1050
            {
1051
                //print "$i ".$file."\n<br>";
1052
                if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod'  && substr($file, dol_strlen($file) - 10) == '.class.php')
1053
                {
1054
                    $modName = substr($file, 0, dol_strlen($file) - 10);
1055
1056
                    if ($modName)
1057
                    {
1058
                        include_once $dir.$file;
1059
                        $objMod = new $modName($db);
1060
1061
                        if ($objMod->numero > 0)
1062
                        {
1063
                            $j = $objMod->numero;
1064
                        }
1065
                        else
1066
                        {
1067
                            $j = 1000 + $i;
1068
                        }
1069
1070
                        $modulequalified=1;
1071
1072
                        // We discard modules according to features level (PS: if module is activated we always show it)
1073
                        $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod)));
1074
                        if ($objMod->version == 'development'  && $conf->global->MAIN_FEATURES_LEVEL < 2 && ! $conf->global->$const_name) $modulequalified=0;
1075
                        if ($objMod->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1 && ! $conf->global->$const_name) $modulequalified=0;
1076
                        //If module is not activated disqualified
1077
                        if (empty($conf->global->$const_name)) $modulequalified=0;
1078
1079
                        if ($modulequalified)
1080
                        {
1081
							// Load languages files of module
1082
                        	if (isset($objMod->langfiles) && is_array($objMod->langfiles))
1083
                            	{
1084
                             		foreach($objMod->langfiles as $langfile)
1085
                              		{
1086
	                               		$langs->load($langfile);
1087
        	                       	}
1088
              			}
1089
1090
                            // Complete arrays
1091
                            //&$tabname,&$tablib,&$tabsql,&$tabsqlsort,&$tabfield,&$tabfieldvalue,&$tabfieldinsert,&$tabrowid,&$tabcond
1092
                            if (empty($objMod->dictionaries) && ! empty($objMod->dictionnaries)) $objMod->dictionaries=$objMod->dictionnaries;		// For backward compatibility
1093
1094
                            if (! empty($objMod->dictionaries))
1095
                            {
1096
                                //var_dump($objMod->dictionaries['tabname']);
1097
                                $nbtabname=$nbtablib=$nbtabsql=$nbtabsqlsort=$nbtabfield=$nbtabfieldvalue=$nbtabfieldinsert=$nbtabrowid=$nbtabcond=$nbtabfieldcheck=$nbtabhelp=0;
1098
                                foreach($objMod->dictionaries['tabname'] as $val)        { $nbtabname++; $taborder[] = max($taborder)+1; $tabname[] = $val; }
1099
                                foreach($objMod->dictionaries['tablib'] as $val)         { $nbtablib++; $tablib[] = $val; }
1100
                                foreach($objMod->dictionaries['tabsql'] as $val)         { $nbtabsql++; $tabsql[] = $val; }
1101
                                foreach($objMod->dictionaries['tabsqlsort'] as $val)     { $nbtabsqlsort++; $tabsqlsort[] = $val; }
1102
                                foreach($objMod->dictionaries['tabfield'] as $val)       { $nbtabfield++; $tabfield[] = $val; }
1103
                                foreach($objMod->dictionaries['tabfieldvalue'] as $val)  { $nbtabfieldvalue++; $tabfieldvalue[] = $val; }
1104
                                foreach($objMod->dictionaries['tabfieldinsert'] as $val) { $nbtabfieldinsert++; $tabfieldinsert[] = $val; }
1105
                                foreach($objMod->dictionaries['tabrowid'] as $val)       { $nbtabrowid++; $tabrowid[] = $val; }
1106
                                foreach($objMod->dictionaries['tabcond'] as $val)        { $nbtabcond++; $tabcond[] = $val; }
1107
                                if (! empty($objMod->dictionaries['tabhelp']))       foreach($objMod->dictionaries['tabhelp'] as $val)       { $nbtabhelp++; $tabhelp[] = $val; }
1108
                                if (! empty($objMod->dictionaries['tabfieldcheck'])) foreach($objMod->dictionaries['tabfieldcheck'] as $val) { $nbtabfieldcheck++; $tabfieldcheck[] = $val; }
1109
1110
                                if ($nbtabname != $nbtablib || $nbtablib != $nbtabsql || $nbtabsql != $nbtabsqlsort)
1111
                                {
1112
                                    print 'Error in descriptor of module '.$const_name.'. Array ->dictionaries has not same number of record for key "tabname", "tablib", "tabsql" and "tabsqlsort"';
1113
                                    //print "$const_name: $nbtabname=$nbtablib=$nbtabsql=$nbtabsqlsort=$nbtabfield=$nbtabfieldvalue=$nbtabfieldinsert=$nbtabrowid=$nbtabcond=$nbtabfieldcheck=$nbtabhelp\n";
1114
                                }
1115
                            }
1116
1117
                            $j++;
1118
                            $i++;
1119
                        }
1120
                        else dol_syslog("Module ".get_class($objMod)." not qualified");
1121
                    }
1122
                }
1123
            }
1124
            closedir($handle);
1125
        }
1126
        else
1127
        {
1128
            dol_syslog("htdocs/admin/modules.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING);
1129
        }
1130
    }
1131
1132
    return 1;
1133
}
1134
1135
/**
1136
 *  Activate external modules mandatroy when country is country_code
1137
 *
1138
 * 	@param		string		$country_code	CountryCode
1139
 * 	@return		int			1
1140
 */
1141
function activateModulesRequiredByCountry($country_code)
1142
{
1143
	global $db, $conf, $langs;
1144
1145
	$modulesdir = dolGetModulesDirs();
1146
1147
	foreach ($modulesdir as $dir)
1148
	{
1149
		// Load modules attributes in arrays (name, numero, orders) from dir directory
1150
		dol_syslog("Scan directory ".$dir." for modules");
1151
		$handle=@opendir(dol_osencode($dir));
1152
		if (is_resource($handle))
1153
		{
1154
			while (($file = readdir($handle))!==false)
1155
			{
1156
				if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod'  && substr($file, dol_strlen($file) - 10) == '.class.php')
1157
				{
1158
					$modName = substr($file, 0, dol_strlen($file) - 10);
1159
1160
					if ($modName)
1161
					{
1162
						include_once $dir.$file;
1163
						$objMod = new $modName($db);
1164
1165
						$modulequalified=1;
1166
1167
						// We discard modules according to features level (PS: if module is activated we always show it)
1168
						$const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod)));
1169
1170
						if ($objMod->version == 'development'  && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0;
1171
						if ($objMod->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0;
1172
						if(!empty($conf->global->$const_name)) $modulequalified=0; // already activated
1173
1174
						if ($modulequalified)
1175
						{
1176
							// Load languages files of module
1177
							if (isset($objMod->automatic_activation) && is_array($objMod->automatic_activation) && isset($objMod->automatic_activation[$country_code]))
1178
							{
1179
								activateModule($modName);
1180
1181
								setEventMessage($objMod->automatic_activation[$country_code],'warnings');
1182
							}
1183
1184
						}
1185
						else dol_syslog("Module ".get_class($objMod)." not qualified");
1186
					}
1187
				}
1188
			}
1189
			closedir($handle);
1190
		}
1191
		else
1192
		{
1193
			dol_syslog("htdocs/admin/modules.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING);
1194
		}
1195
	}
1196
1197
	return 1;
1198
}
1199
1200
/**
1201
 *  Add external modules to list of contact element
1202
 *
1203
 * 	@param		array		$elementList			elementList
1204
 * 	@return		int			1
1205
 */
1206
function complete_elementList_with_modules(&$elementList)
1207
{
1208
    global $db, $modules, $conf, $langs;
1209
1210
    // Search modules
1211
    $filename = array();
1212
    $modules = array();
1213
    $orders = array();
1214
    $categ = array();
1215
    $dirmod = array();
1216
1217
    $i = 0; // is a sequencer of modules found
1218
    $j = 0; // j is module number. Automatically affected if module number not defined.
1219
1220
    $modulesdir = dolGetModulesDirs();
1221
1222
    foreach ($modulesdir as $dir)
1223
    {
1224
    	// Load modules attributes in arrays (name, numero, orders) from dir directory
1225
    	//print $dir."\n<br>";
1226
    	dol_syslog("Scan directory ".$dir." for modules");
1227
        $handle=@opendir(dol_osencode($dir));
1228
        if (is_resource($handle))
1229
        {
1230
            while (($file = readdir($handle))!==false)
1231
            {
1232
                //print "$i ".$file."\n<br>";
1233
                if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod'  && substr($file, dol_strlen($file) - 10) == '.class.php')
1234
                {
1235
                    $modName = substr($file, 0, dol_strlen($file) - 10);
1236
1237
                    if ($modName)
1238
                    {
1239
                        include_once $dir.$file;
1240
                        $objMod = new $modName($db);
1241
1242
                        if ($objMod->numero > 0)
1243
                        {
1244
                            $j = $objMod->numero;
1245
                        }
1246
                        else
1247
                        {
1248
                            $j = 1000 + $i;
1249
                        }
1250
1251
                        $modulequalified=1;
1252
1253
                        // We discard modules according to features level (PS: if module is activated we always show it)
1254
                        $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod)));
1255
                        if ($objMod->version == 'development'  && $conf->global->MAIN_FEATURES_LEVEL < 2 && ! $conf->global->$const_name) $modulequalified=0;
1256
                        if ($objMod->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1 && ! $conf->global->$const_name) $modulequalified=0;
1257
                        //If module is not activated disqualified
1258
                        if (empty($conf->global->$const_name)) $modulequalified=0;
1259
1260
                        if ($modulequalified)
1261
                        {
1262
							// Load languages files of module
1263
                            if (isset($objMod->langfiles) && is_array($objMod->langfiles))
1264
                            {
1265
                             	foreach($objMod->langfiles as $langfile)
1266
                              	{
1267
                               		$langs->load($langfile);
1268
                               	}
1269
                           	}
1270
1271
                            $modules[$i] = $objMod;
1272
                            $filename[$i]= $modName;
1273
                            $orders[$i]  = $objMod->family."_".$j;   // Tri par famille puis numero module
1274
                            //print "x".$modName." ".$orders[$i]."\n<br>";
1275
                            if (isset($categ[$objMod->special])) $categ[$objMod->special]++;                    // Array of all different modules categories
1276
                            else $categ[$objMod->special]=1;
1277
                            $dirmod[$i] = $dirroot;
0 ignored issues
show
Bug introduced by
The variable $dirroot 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...
1278
                            if (! empty($objMod->module_parts['contactelement']))
1279
                            {
1280
                            	$elementList[$objMod->name] = $langs->trans($objMod->name);
1281
                            }
1282
1283
                            $j++;
1284
                            $i++;
1285
                        }
1286
                        else dol_syslog("Module ".get_class($objMod)." not qualified");
1287
                    }
1288
                }
1289
            }
1290
            closedir($handle);
1291
        }
1292
        else
1293
        {
1294
            dol_syslog("htdocs/admin/modules.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING);
1295
        }
1296
    }
1297
1298
    return 1;
1299
}
1300
1301
/**
1302
 *	Show array with constants to edit
1303
 *
1304
 *	@param	array	$tableau		Array of constants
1305
 *	@param	int		$strictw3c		0=Include form into table (deprecated), 1=Form is outside table to respect W3C (no form into table), 2=No form nor button at all
1306
 *  @param  string  $helptext       Help
1307
 *	@return	void
1308
 */
1309
function form_constantes($tableau, $strictw3c=0, $helptext='')
1310
{
1311
    global $db,$bc,$langs,$conf,$_Avery_Labels;
1312
1313
    $form = new Form($db);
1314
1315
    if (! empty($strictw3c) && $strictw3c == 1) print "\n".'<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1316
1317
    print '<table class="noborder" width="100%">';
1318
    print '<tr class="liste_titre">';
1319
    print '<td class="titlefield">'.$langs->trans("Description").'</td>';
1320
    print '<td>';
1321
    $text = $langs->trans("Value");
1322
    print $form->textwithpicto($text, $helptext, 1, 'help', '', 0, 2, 'idhelptext');
1323
    print '</td>';
1324
    if (empty($strictw3c)) print '<td align="center" width="80">'.$langs->trans("Action").'</td>';
1325
    print "</tr>\n";
1326
    $var=true;
1327
1328
    $listofparam=array();
1329
    foreach($tableau as $const)	// Loop on each param
1330
    {
1331
        $sql = "SELECT ";
1332
        $sql.= "rowid";
1333
        $sql.= ", ".$db->decrypt('name')." as name";
1334
        $sql.= ", ".$db->decrypt('value')." as value";
1335
        $sql.= ", type";
1336
        $sql.= ", note";
1337
        $sql.= " FROM ".MAIN_DB_PREFIX."const";
1338
        $sql.= " WHERE ".$db->decrypt('name')." = '".$const."'";
1339
        $sql.= " AND entity IN (0, ".$conf->entity.")";
1340
        $sql.= " ORDER BY name ASC, entity DESC";
1341
        $result = $db->query($sql);
1342
1343
        dol_syslog("List params", LOG_DEBUG);
1344
        if ($result)
1345
        {
1346
            $obj = $db->fetch_object($result);	// Take first result of select
1347
1348
1349
            // For avoid warning in strict mode
1350
            if (empty($obj)) {
1351
            	$obj = (object) array('rowid'=>'','name'=>'','value'=>'','type'=>'','note'=>'');
1352
            }
1353
1354
            if (empty($strictw3c)) print "\n".'<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1355
1356
            print '<tr class="oddeven">';
1357
1358
            // Show constant
1359
            print '<td>';
1360
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1361
            print '<input type="hidden" name="action" value="update">';
1362
            print '<input type="hidden" name="rowid'.(empty($strictw3c)?'':'[]').'" value="'.$obj->rowid.'">';
1363
            print '<input type="hidden" name="constname'.(empty($strictw3c)?'':'[]').'" value="'.$const.'">';
1364
            print '<input type="hidden" name="constnote'.(empty($strictw3c)?'':'[]').'" value="'.nl2br(dol_escape_htmltag($obj->note)).'">';
1365
1366
            print $langs->trans('Desc'.$const);
1367
1368
            if ($const == 'ADHERENT_MAILMAN_URL')
1369
            {
1370
                print '. '.$langs->trans("Example").': <a href="#" id="exampleclick1">'.img_down().'</a><br>';
1371
                //print 'http://lists.exampe.com/cgi-bin/mailman/admin/%LISTE%/members?adminpw=%MAILMAN_ADMINPW%&subscribees=%EMAIL%&send_welcome_msg_to_this_batch=1';
1372
                print '<div id="example1" class="hidden">';
1373
                print 'http://lists.example.com/cgi-bin/mailman/admin/%LISTE%/members/add?subscribees_upload=%EMAIL%&amp;adminpw=%MAILMAN_ADMINPW%&amp;subscribe_or_invite=0&amp;send_welcome_msg_to_this_batch=0&amp;notification_to_list_owner=0';
1374
                print '</div>';
1375
            }
1376
            if ($const == 'ADHERENT_MAILMAN_UNSUB_URL')
1377
            {
1378
                print '. '.$langs->trans("Example").': <a href="#" id="exampleclick2">'.img_down().'</a><br>';
1379
                print '<div id="example2" class="hidden">';
1380
                print 'http://lists.example.com/cgi-bin/mailman/admin/%LISTE%/members/remove?unsubscribees_upload=%EMAIL%&amp;adminpw=%MAILMAN_ADMINPW%&amp;send_unsub_ack_to_this_batch=0&amp;send_unsub_notifications_to_list_owner=0';
1381
                print '</div>';
1382
                //print 'http://lists.example.com/cgi-bin/mailman/admin/%LISTE%/members/remove?adminpw=%MAILMAN_ADMINPW%&unsubscribees=%EMAIL%';
1383
            }
1384
            if ($const == 'ADHERENT_MAILMAN_LISTS')
1385
            {
1386
            	print '. '.$langs->trans("Example").': <a href="#" id="exampleclick3">'.img_down().'</a><br>';
1387
            	print '<div id="example3" class="hidden">';
1388
            	print 'mymailmanlist<br>';
1389
            	print 'mymailmanlist1,mymailmanlist2<br>';
1390
            	print 'TYPE:Type1:mymailmanlist1,TYPE:Type2:mymailmanlist2<br>';
1391
            	if ($conf->categorie->enabled) print 'CATEG:Categ1:mymailmanlist1,CATEG:Categ2:mymailmanlist2<br>';
1392
            	print '</div>';
1393
            	//print 'http://lists.example.com/cgi-bin/mailman/admin/%LISTE%/members/remove?adminpw=%MAILMAN_ADMINPW%&unsubscribees=%EMAIL%';
1394
            }
1395
1396
            print "</td>\n";
1397
1398
            // Value
1399
            if ($const == 'ADHERENT_CARD_TYPE' || $const == 'ADHERENT_ETIQUETTE_TYPE')
1400
            {
1401
                print '<td>';
1402
                // List of possible labels (defined into $_Avery_Labels variable set into format_cards.lib.php)
1403
                require_once DOL_DOCUMENT_ROOT.'/core/lib/format_cards.lib.php';
1404
                $arrayoflabels=array();
1405
                foreach(array_keys($_Avery_Labels) as $codecards)
1406
                {
1407
                    $arrayoflabels[$codecards]=$_Avery_Labels[$codecards]['name'];
1408
                }
1409
                print $form->selectarray('constvalue'.(empty($strictw3c)?'':'[]'),$arrayoflabels,($obj->value?$obj->value:'CARD'),1,0,0);
1410
                print '<input type="hidden" name="consttype" value="yesno">';
1411
                print '</td>';
1412
            }
1413
            else
1414
            {
1415
                print '<td>';
1416
                if (in_array($const,array('ADHERENT_CARD_TEXT','ADHERENT_CARD_TEXT_RIGHT','ADHERENT_ETIQUETTE_TEXT')))
1417
                {
1418
                    print '<textarea class="flat" name="constvalue'.(empty($strictw3c)?'':'[]').'" cols="50" rows="5" wrap="soft">'."\n";
1419
                    print $obj->value;
1420
                    print "</textarea>\n";
1421
                    print '<input type="hidden" name="consttype" value="texte">';
1422
                }
1423
                else if (in_array($const,array('ADHERENT_AUTOREGISTER_NOTIF_MAIL','ADHERENT_AUTOREGISTER_MAIL','ADHERENT_MAIL_VALID','ADHERENT_MAIL_COTIS','ADHERENT_MAIL_RESIL')))
1424
                {
1425
                    require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1426
                    $doleditor=new DolEditor('constvalue_'.$const.(empty($strictw3c)?'':'[]'),$obj->value,'',160,'dolibarr_notes','',false,false,$conf->fckeditor->enabled,ROWS_5,'90%');
1427
                    $doleditor->Create();
1428
                    print '<input type="hidden" name="consttype'.(empty($strictw3c)?'':'[]').'" value="texte">';
1429
                }
1430
                else if ($obj->type == 'yesno')
1431
                {
1432
                    print $form->selectyesno('constvalue'.(empty($strictw3c)?'':'[]'),$obj->value,1);
1433
                    print '<input type="hidden" name="consttype'.(empty($strictw3c)?'':'[]').'" value="yesno">';
1434
                }
1435
                else
1436
                {
1437
                    print '<input type="text" class="flat" size="48" name="constvalue'.(empty($strictw3c)?'':'[]').'" value="'.dol_escape_htmltag($obj->value).'">';
1438
                    print '<input type="hidden" name="consttype'.(empty($strictw3c)?'':'[]').'" value="chaine">';
1439
                }
1440
                print '</td>';
1441
            }
1442
            // Submit
1443
            if (empty($strictw3c))
1444
            {
1445
            	print '<td align="center">';
1446
            	print '<input type="submit" class="button" value="'.$langs->trans("Update").'" name="Button">';
1447
	            print "</td>";
1448
            }
1449
    	    print "</tr>\n";
1450
            if (empty($strictw3c)) print "</form>\n";
1451
        }
1452
    }
1453
    print '</table>';
1454
1455
    if (! empty($strictw3c) && $strictw3c == 1)
1456
    {
1457
    	print '<div align="center"><input type="submit" class="button" value="'.$langs->trans("Update").'" name="update"></div>';
1458
    	print "</form>\n";
1459
    }
1460
}
1461
1462
1463
/**
1464
 *	Show array with constants to edit
1465
 *
1466
 *	@param	array	$modules		Array of all modules
1467
 *	@return	string					HTML string with warning
1468
 */
1469
function showModulesExludedForExternal($modules)
1470
{
1471
	global $conf,$langs;
1472
1473
	$text=$langs->trans("OnlyFollowingModulesAreOpenedToExternalUsers");
1474
	$listofmodules=explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL);
1475
	$i=0;
1476
	if (!empty($modules)) {
1477
		foreach($modules as $module)
1478
		{
1479
			$moduleconst=$module->const_name;
1480
			$modulename=strtolower($module->name);
1481
			//print 'modulename='.$modulename;
1482
1483
			//if (empty($conf->global->$moduleconst)) continue;
1484
			if (! in_array($modulename,$listofmodules)) continue;
1485
			//var_dump($modulename.'eee'.$langs->trans('Module'.$module->numero.'Name'));
1486
1487
			if ($i > 0) $text.=', ';
1488
			else $text.=' ';
1489
			$i++;
1490
			$text .= $langs->trans('Module'.$module->numero.'Name');
1491
		}
1492
	}
1493
	return $text;
1494
}
1495
1496
1497
/**
1498
 *	Add document model used by doc generator
1499
 *
1500
 *	@param		string	$name			Model name
1501
 *	@param		string	$type			Model type
1502
 *	@param		string	$label			Model label
1503
 *	@param		string	$description	Model description
1504
 *	@return		int						<0 if KO, >0 if OK
1505
 */
1506
function addDocumentModel($name, $type, $label='', $description='')
1507
{
1508
	global $db, $conf;
1509
1510
	$db->begin();
1511
1512
    $sql = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity, libelle, description)";
1513
    $sql.= " VALUES ('".$db->escape($name)."','".$type."',".$conf->entity.", ";
1514
    $sql.= ($label?"'".$db->escape($label)."'":'null').", ";
1515
    $sql.= (! empty($description)?"'".$db->escape($description)."'":"null");
1516
    $sql.= ")";
1517
1518
    dol_syslog("admin.lib::addDocumentModel", LOG_DEBUG);
1519
	$resql=$db->query($sql);
1520
	if ($resql)
1521
	{
1522
		$db->commit();
1523
		return 1;
1524
	}
1525
	else
1526
	{
1527
		dol_print_error($db);
1528
		$db->rollback();
1529
		return -1;
1530
	}
1531
}
1532
1533
/**
1534
 *	Delete document model used by doc generator
1535
 *
1536
 *	@param		string	$name			Model name
1537
 *	@param		string	$type			Model type
1538
 *	@return		int						<0 if KO, >0 if OK
1539
 */
1540
function delDocumentModel($name, $type)
1541
{
1542
	global $db, $conf;
1543
1544
	$db->begin();
1545
1546
	$sql = "DELETE FROM ".MAIN_DB_PREFIX."document_model";
1547
	$sql.= " WHERE nom = '".$db->escape($name)."'";
1548
	$sql.= " AND type = '".$type."'";
1549
	$sql.= " AND entity = ".$conf->entity;
1550
1551
	dol_syslog("admin.lib::delDocumentModel", LOG_DEBUG);
1552
	$resql=$db->query($sql);
1553
	if ($resql)
1554
	{
1555
		$db->commit();
1556
		return 1;
1557
	}
1558
	else
1559
	{
1560
		dol_print_error($db);
1561
		$db->rollback();
1562
		return -1;
1563
	}
1564
}
1565
1566
1567
/**
1568
 *	Return the php_info into an array
1569
 *
1570
 *	@return		array		Array with PHP infos
1571
 */
1572
function phpinfo_array()
1573
{
1574
	ob_start();
1575
	phpinfo();
1576
	$info_arr = array();
1577
	$info_lines = explode("\n", strip_tags(ob_get_clean(), "<tr><td><h2>"));	// end of ob_start()
1578
	$cat = "General";
1579
	foreach($info_lines as $line)
1580
	{
1581
		// new cat?
1582
		preg_match("~<h2>(.*)</h2>~", $line, $title) ? $cat = $title[1] : null;
1583
		if(preg_match("~<tr><td[^>]+>([^<]*)</td><td[^>]+>([^<]*)</td></tr>~", $line, $val))
1584
		{
1585
			$info_arr[trim($cat)][trim($val[1])] = $val[2];
1586
		}
1587
		elseif(preg_match("~<tr><td[^>]+>([^<]*)</td><td[^>]+>([^<]*)</td><td[^>]+>([^<]*)</td></tr>~", $line, $val))
1588
		{
1589
			$info_arr[trim($cat)][trim($val[1])] = array("local" => $val[2], "master" => $val[3]);
1590
		}
1591
	}
1592
	return $info_arr;
1593
}
1594
1595
/**
1596
 *  Return array head with list of tabs to view object informations.
1597
 *
1598
 *  @return	array   	    		    head array with tabs
1599
 */
1600
function email_admin_prepare_head()
1601
{
1602
	global $langs, $conf, $user;
1603
1604
	$h = 0;
1605
	$head = array();
1606
1607
	if ($user->admin && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates'))
1608
	{
1609
		$head[$h][0] = DOL_URL_ROOT."/admin/mails.php";
1610
		$head[$h][1] = $langs->trans("OutGoingEmailSetup");
1611
		$head[$h][2] = 'common';
1612
		$h++;
1613
1614
		if ($conf->mailing->enabled)
1615
		{
1616
			$head[$h][0] = DOL_URL_ROOT."/admin/mails_emailing.php";
1617
			$head[$h][1] = $langs->trans("OutGoingEmailSetupForEmailing");
1618
			$head[$h][2] = 'common_emailing';
1619
			$h++;
1620
		}
1621
	}
1622
1623
	$head[$h][0] = DOL_URL_ROOT."/admin/mails_templates.php";
1624
	$head[$h][1] = $langs->trans("DictionaryEMailTemplates");
1625
	$head[$h][2] = 'templates';
1626
	$h++;
1627
1628
	if ($conf->global->MAIN_FEATURES_LEVEL >= 1)
1629
	{
1630
		$head[$h][0] = DOL_URL_ROOT."/admin/mails_senderprofile_list.php";
1631
		$head[$h][1] = $langs->trans("EmailSenderProfiles");
1632
		$head[$h][2] = 'senderprofiles';
1633
		$h++;
1634
	}
1635
1636
	complete_head_from_modules($conf,$langs,null,$head,$h,'email_admin','remove');
1637
1638
	return $head;
1639
}
1640
1641
1642