Completed
Branch develop (f8a444)
by
unknown
32:44
created

Utils::executeCLI()   C

Complexity

Conditions 13
Paths 120

Size

Total Lines 62
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 36
nc 120
nop 3
dl 0
loc 62
rs 5.6277
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) 2016 Destailleur Laurent <[email protected]>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
 */
17
18
/**
19
 *   	\file       htdocs/core/class/utils.class.php
20
 *      \ingroup    core
21
 *		\brief      File for Utils class
22
 */
23
24
25
/**
26
 *		Class to manage utility methods
27
 */
28
class Utils
29
{
30
	var $db;
31
32
	var $output;   // Used by Cron method to return message
33
	var $result;   // Used by Cron method to return data
34
35
	/**
36
	 *	Constructor
37
	 *
38
	 *  @param	DoliDB	$db		Database handler
39
	 */
40
	function __construct($db)
41
	{
42
		$this->db = $db;
43
	}
44
45
46
	/**
47
	 *  Purge files into directory of data files.
48
	 *  CAN BE A CRON TASK
49
	 *
50
	 *  @param	string		$choice		Choice of purge mode ('tempfiles', 'tempfilesold' to purge temp older than 24h, 'allfiles', 'logfile')
51
	 *  @return	int						0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK)
52
	 */
53
	function purgeFiles($choice='tempfilesold')
54
	{
55
		global $conf, $langs, $dolibarr_main_data_root;
56
57
		$langs->load("admin");
58
59
		dol_syslog("Utils::purgeFiles choice=".$choice, LOG_DEBUG);
60
		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
61
62
		$filesarray=array();
63
		if (empty($choice)) $choice='tempfilesold';
64
65
		if ($choice=='tempfiles' || $choice=='tempfilesold')
66
		{
67
			// Delete temporary files
68
			if ($dolibarr_main_data_root)
69
			{
70
				$filesarray=dol_dir_list($dolibarr_main_data_root,"directories",1,'^temp$','','','',2);
71
				if ($choice == 'tempfilesold')
72
				{
73
					$now = dol_now();
74
					foreach($filesarray as $key => $val)
75
					{
76
						if ($val['date'] > ($now - (24 * 3600))) unset($filesarray[$key]);	// Discard files not older than 24h
77
					}
78
				}
79
			}
80
		}
81
82
		if ($choice=='allfiles')
83
		{
84
			// Delete all files (except install.lock)
85
			if ($dolibarr_main_data_root)
86
			{
87
				$filesarray=dol_dir_list($dolibarr_main_data_root,"all",0,'','install\.lock$');
88
			}
89
		}
90
91
		if ($choice=='logfile')
92
		{
93
		    // Define files log
94
			if ($dolibarr_main_data_root)
95
			{
96
                $filesarray=dol_dir_list($dolibarr_main_data_root, "files", 0, '.*\.log[\.0-9]*$', 'install\.lock$');
97
			}
98
99
			$filelog='';
100
			if (! empty($conf->syslog->enabled))
101
			{
102
				$filelog=$conf->global->SYSLOG_FILE;
103
				$filelog=preg_replace('/DOL_DATA_ROOT/i',DOL_DATA_ROOT,$filelog);
104
105
				$alreadyincluded=false;
106
				foreach ($filesarray as $tmpcursor)
107
				{
108
				    if ($tmpcursor['fullname'] == $filelog) { $alreadyincluded=true; }
109
				}
110
				if (! $alreadyincluded) $filesarray[]=array('fullname'=>$filelog,'type'=>'file');
111
			}
112
		}
113
114
		$count=0;
115
		$countdeleted=0;
116
		$counterror=0;
117
		if (count($filesarray))
118
		{
119
			foreach($filesarray as $key => $value)
120
			{
121
				//print "x ".$filesarray[$key]['fullname']."-".$filesarray[$key]['type']."<br>\n";
122
				if ($filesarray[$key]['type'] == 'dir')
123
				{
124
				    $startcount=0;
125
				    $tmpcountdeleted=0;
126
					$result=dol_delete_dir_recursive($filesarray[$key]['fullname'], $startcount, 1, 0, $tmpcountdeleted);
127
				    $count+=$result;
128
				    $countdeleted+=$tmpcountdeleted;
129
				}
130
				elseif ($filesarray[$key]['type'] == 'file')
131
				{
132
					// If (file that is not logfile) or (if logfile with option logfile)
133
					if ($filesarray[$key]['fullname'] != $filelog || $choice=='logfile')
0 ignored issues
show
Bug introduced by
The variable $filelog 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...
134
					{
135
					    $result=dol_delete_file($filesarray[$key]['fullname'], 1, 1);
136
					    if ($result)
137
					    {
138
					        $count++;
139
					        $countdeleted++;
140
					    }
141
					    else $counterror++;
142
					}
143
				}
144
			}
145
146
			// Update cachenbofdoc
147
			if (! empty($conf->ecm->enabled) && $choice=='allfiles')
148
			{
149
				require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
150
				$ecmdirstatic = new EcmDirectory($this->db);
151
				$result = $ecmdirstatic->refreshcachenboffile(1);
152
			}
153
		}
154
155
		if ($count > 0)
156
		{
157
		    $this->output=$langs->trans("PurgeNDirectoriesDeleted", $countdeleted);
158
		    if ($count > $countdeleted) $this->output.='<br>'.$langs->trans("PurgeNDirectoriesFailed", ($count - $countdeleted));
159
		}
160
		else $this->output=$langs->trans("PurgeNothingToDelete").($choice == 'tempfilesold' ? ' (older than 24h)':'');
161
162
		//return $count;
163
		return 0;     // This function can be called by cron so must return 0 if OK
164
	}
165
166
167
	/**
168
	 *  Make a backup of database
169
	 *  CAN BE A CRON TASK
170
	 *
171
	 *  @param	string		$compression	   'gz' or 'bz' or 'none'
172
	 *  @param  string      $type              'mysql', 'postgresql', ...
173
	 *  @param  int         $usedefault        1=Use default backup profile (Set this to 1 when used as cron)
174
	 *  @param  string      $file              'auto' or filename to build
175
	 *  @param  int         $keeplastnfiles    Keep only last n files (not used yet)
176
	 *  @return	int						       0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK)
177
	 */
178
	function dumpDatabase($compression='none', $type='auto', $usedefault=1, $file='auto', $keeplastnfiles=0)
179
	{
180
		global $db, $conf, $langs, $dolibarr_main_data_root;
181
		global $dolibarr_main_db_name, $dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_port, $dolibarr_main_db_pass;
182
183
184
		$langs->load("admin");
185
186
		dol_syslog("Utils::dumpDatabase type=".$type." compression=".$compression." file=".$file, LOG_DEBUG);
187
		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
188
189
		// Check compression parameter
190
		if (! in_array($compression, array('none', 'gz', 'bz', 'zip')))
191
		{
192
		    $langs->load("errors");
193
		    $this->error=$langs->transnoentitiesnoconv("ErrorBadValueForParameter", $compression, "Compression");
194
		    return -1;
195
		}
196
197
		// Check type parameter
198
		if ($type == 'auto') $type = $db->type;
199
		if (! in_array($type, array('pgsql', 'mysql', 'mysqli','mysqlnobin')))
200
		{
201
		    $langs->load("errors");
202
		    $this->error=$langs->transnoentitiesnoconv("ErrorBadValueForParameter", $type, "Basetype");
203
		    return -1;
204
		}
205
206
		// Check file parameter
207
		if ($file == 'auto')
208
		{
209
		    $prefix='dump';
210
		    $ext='.sql';
211
		    if (in_array($type, array('mysql', 'mysqli')))  { $prefix='mysqldump'; $ext='sql'; }
212
		    //if ($label == 'PostgreSQL') { $prefix='pg_dump'; $ext='dump'; }
213
		    if (in_array($type, array('pgsql'))) { $prefix='pg_dump'; $ext='sql'; }
214
		    $file=$prefix.'_'.$dolibarr_main_db_name.'_'.dol_sanitizeFileName(DOL_VERSION).'_'.strftime("%Y%m%d%H%M").'.'.$ext;
215
		}
216
217
		$outputdir  = $conf->admin->dir_output.'/backup';
218
		$result=dol_mkdir($outputdir);
219
220
221
		// MYSQL
222
		if ($type == 'mysql' || $type == 'mysqli')
223
		{
224
		    $cmddump=$conf->global->SYSTEMTOOLS_MYSQLDUMP;
225
226
227
		    $outputfile = $outputdir.'/'.$file;
228
		    // for compression format, we add extension
229
		    $compression=$compression ? $compression : 'none';
230
		    if ($compression == 'gz') $outputfile.='.gz';
231
		    if ($compression == 'bz') $outputfile.='.bz2';
232
		    $outputerror = $outputfile.'.err';
233
		    dol_mkdir($conf->admin->dir_output.'/backup');
234
235
		    // Parameteres execution
236
		    $command=$cmddump;
237
		    if (preg_match("/\s/",$command)) $command=escapeshellarg($command);	// Use quotes on command
238
239
		    //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass);
240
		    $param=$dolibarr_main_db_name." -h ".$dolibarr_main_db_host;
241
		    $param.=" -u ".$dolibarr_main_db_user;
242
		    if (! empty($dolibarr_main_db_port)) $param.=" -P ".$dolibarr_main_db_port;
243
		    if (! GETPOST("use_transaction"))    $param.=" -l --single-transaction";
244
		    if (GETPOST("disable_fk") || $usedefault) $param.=" -K";
245
		    if (GETPOST("sql_compat") && GETPOST("sql_compat") != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat","alpha"));
246
		    if (GETPOST("drop_database"))        $param.=" --add-drop-database";
247
		    if (GETPOST("sql_structure") || $usedefault)
248
		    {
249
		        if (GETPOST("drop") || $usedefault)	$param.=" --add-drop-table=TRUE";
250
		        else 							    $param.=" --add-drop-table=FALSE";
251
		    }
252
		    else
253
		    {
254
		        $param.=" -t";
255
		    }
256
		    if (GETPOST("disable-add-locks")) $param.=" --add-locks=FALSE";
257
		    if (GETPOST("sql_data") || $usedefault)
258
		    {
259
		        $param.=" --tables";
260
		        if (GETPOST("showcolumns") || $usedefault)	 $param.=" -c";
261
		        if (GETPOST("extended_ins") || $usedefault) $param.=" -e";
262
		        else $param.=" --skip-extended-insert";
263
		        if (GETPOST("delayed"))	 	 $param.=" --delayed-insert";
264
		        if (GETPOST("sql_ignore"))	 $param.=" --insert-ignore";
265
		        if (GETPOST("hexforbinary") || $usedefault) $param.=" --hex-blob";
266
		    }
267
		    else
268
		    {
269
		        $param.=" -d";    // No row information (no data)
270
		    }
271
		    $param.=" --default-character-set=utf8";    // We always save output into utf8 charset
272
		    $paramcrypted=$param;
273
		    $paramclear=$param;
274
		    if (! empty($dolibarr_main_db_pass))
275
		    {
276
		        $paramcrypted.=' -p"'.preg_replace('/./i','*',$dolibarr_main_db_pass).'"';
277
		        $paramclear.=' -p"'.str_replace(array('"','`'),array('\"','\`'),$dolibarr_main_db_pass).'"';
278
		    }
279
280
		    $errormsg='';
281
282
		    // Debut appel methode execution
283
		    $fullcommandcrypted=$command." ".$paramcrypted." 2>&1";
284
		    $fullcommandclear=$command." ".$paramclear." 2>&1";
285
		    if ($compression == 'none') $handle = fopen($outputfile, 'w');
286
		    if ($compression == 'gz')   $handle = gzopen($outputfile, 'w');
287
		    if ($compression == 'bz')   $handle = bzopen($outputfile, 'w');
288
289
		    if ($handle)
290
		    {
291
		        $ok=0;
292
		        dol_syslog("Run command ".$fullcommandcrypted);
293
		        $handlein = popen($fullcommandclear, 'r');
294
		        $i=0;
295
		        while (!feof($handlein))
296
		        {
297
		            $i++;   // output line number
298
		            $read = fgets($handlein);
299
		            // Exclude warning line we don't want
300
		            if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue;
301
		            fwrite($handle,$read);
0 ignored issues
show
Bug introduced by
The variable $handle 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...
302
		            if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1;
303
		            elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1;
304
		        }
305
		        pclose($handlein);
306
307
		        if ($compression == 'none') fclose($handle);
308
		        if ($compression == 'gz')   gzclose($handle);
309
		        if ($compression == 'bz')   bzclose($handle);
310
311
		        if (! empty($conf->global->MAIN_UMASK))
312
		            @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
313
		    }
314
		    else
315
		    {
316
		        $langs->load("errors");
317
		        dol_syslog("Failed to open file ".$outputfile,LOG_ERR);
318
		        $errormsg=$langs->trans("ErrorFailedToWriteInDir");
319
		    }
320
321
		    // Get errorstring
322
		    if ($compression == 'none') $handle = fopen($outputfile, 'r');
323
		    if ($compression == 'gz')   $handle = gzopen($outputfile, 'r');
324
		    if ($compression == 'bz')   $handle = bzopen($outputfile, 'r');
325
		    if ($handle)
326
		    {
327
		        // Get 2048 first chars of error message.
328
		        $errormsg = fgets($handle,2048);
329
		        // Close file
330
		        if ($compression == 'none') fclose($handle);
331
		        if ($compression == 'gz')   gzclose($handle);
332
		        if ($compression == 'bz')   bzclose($handle);
333
		        if ($ok && preg_match('/^-- MySql/i',$errormsg)) $errormsg='';	// Pas erreur
0 ignored issues
show
Bug introduced by
The variable $ok 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...
334
		        else
335
		        {
336
		            // Renommer fichier sortie en fichier erreur
337
		            //print "$outputfile -> $outputerror";
338
		            @dol_delete_file($outputerror,1);
339
		            @rename($outputfile,$outputerror);
340
		            // Si safe_mode on et command hors du parametre exec, on a un fichier out vide donc errormsg vide
341
		            if (! $errormsg)
342
		            {
343
		                $langs->load("errors");
344
		                $errormsg=$langs->trans("ErrorFailedToRunExternalCommand");
345
		            }
346
		        }
347
		    }
348
		    // Fin execution commande
349
350
		    $this->output = $errormsg;
351
		    $this->error = $errormsg;
352
		    $this->result = array("commandbackuplastdone" => $command." ".$paramcrypted, "commandbackuptorun" => "");
353
		    //if (empty($this->output)) $this->output=$this->result['commandbackuplastdone'];
354
		}
355
356
		// MYSQL NO BIN
357
		if ($type == 'mysqlnobin')
358
		{
359
		    $outputfile = $outputdir.'/'.$file;
360
		    $outputfiletemp = $outputfile.'-TMP.sql';
361
		    // for compression format, we add extension
362
		    $compression=$compression ? $compression : 'none';
363
		    if ($compression == 'gz') $outputfile.='.gz';
364
		    if ($compression == 'bz') $outputfile.='.bz2';
365
		    $outputerror = $outputfile.'.err';
366
		    dol_mkdir($conf->admin->dir_output.'/backup');
367
368
		    if ($compression == 'gz' or $compression == 'bz')
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
369
		    {
370
		        backup_tables($outputfiletemp);
371
		        dol_compress_file($outputfiletemp, $outputfile, $compression);
372
		        unlink($outputfiletemp);
373
		    }
374
		    else
375
		    {
376
		        backup_tables($outputfile);
377
		    }
378
379
		    $this->output = "";
380
		    $this->result = array("commandbackuplastdone" => "", "commandbackuptorun" => "");
381
		}
382
383
		// POSTGRESQL
384
		if ($type == 'postgresql')
385
		{
386
		    $cmddump=$conf->global->SYSTEMTOOLS_POSTGRESQLDUMP;
387
388
		    $outputfile = $outputdir.'/'.$file;
389
		    // for compression format, we add extension
390
		    $compression=$compression ? $compression : 'none';
391
		    if ($compression == 'gz') $outputfile.='.gz';
392
		    if ($compression == 'bz') $outputfile.='.bz2';
393
		    $outputerror = $outputfile.'.err';
394
		    dol_mkdir($conf->admin->dir_output.'/backup');
395
396
		    // Parameteres execution
397
		    $command=$cmddump;
398
		    if (preg_match("/\s/",$command)) $command=escapeshellarg($command);	// Use quotes on command
399
400
		    //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass);
401
		    //$param="-F c";
402
		    $param="-F p";
403
		    $param.=" --no-tablespaces --inserts -h ".$dolibarr_main_db_host;
404
		    $param.=" -U ".$dolibarr_main_db_user;
405
		    if (! empty($dolibarr_main_db_port)) $param.=" -p ".$dolibarr_main_db_port;
406
		    if (GETPOST("sql_compat") && GETPOST("sql_compat") == 'ANSI') $param.="  --disable-dollar-quoting";
407
		    if (GETPOST("drop_database"))        $param.=" -c -C";
408
		    if (GETPOST("sql_structure"))
409
		    {
410
		        if (GETPOST("drop"))			 $param.=" --add-drop-table";
411
		        if (! GETPOST("sql_data"))       $param.=" -s";
412
		    }
413
		    if (GETPOST("sql_data"))
414
		    {
415
		        if (! GETPOST("sql_structure"))	 $param.=" -a";
416
		        if (GETPOST("showcolumns"))	     $param.=" -c";
417
		    }
418
		    $param.=' -f "'.$outputfile.'"';
419
		    //if ($compression == 'none')
420
		    if ($compression == 'gz')   $param.=' -Z 9';
421
		    //if ($compression == 'bz')
422
		    $paramcrypted=$param;
423
		    $paramclear=$param;
424
		    /*if (! empty($dolibarr_main_db_pass))
425
		     {
426
		     $paramcrypted.=" -W".preg_replace('/./i','*',$dolibarr_main_db_pass);
427
		     $paramclear.=" -W".$dolibarr_main_db_pass;
428
		     }*/
429
		    $paramcrypted.=" -w ".$dolibarr_main_db_name;
430
		    $paramclear.=" -w ".$dolibarr_main_db_name;
431
432
		    $this->output = "";
433
		    $this->result = array("commandbackuplastdone" => "", "commandbackuptorun" => $command." ".$paramcrypted);
434
		}
435
436
		// Clean old files
437
		if ($keeplastnfiles > 0)
438
		{
439
		    $tmpfiles = dol_dir_list($conf->admin->dir_output.'/backup', 'files', 0, '', '(\.err|\.old|\.sav)$', 'date', SORT_DESC);
440
		    $i=0;
441
		    foreach($tmpfiles as $key => $val)
442
		    {
443
		        $i++;
444
		        if ($i <= $keeplastnfiles) continue;
445
		        dol_delete_file($val['fullname']);
446
		    }
447
		}
448
449
450
		return 0;
451
	}
452
453
454
455
	/**
456
	 * Execute a CLI command.
457
	 *
458
	 * @param 	string	$command		Command line to execute.
459
	 * @param 	string	$outputfile		Output file (used only when method is 2). For exemple $conf->admin->dir_temp.'/out.tmp';
460
	 * @param	int		$execmethod		0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method
461
	 * @return	array					array('result'=>...,'output'=>...,'error'=>...). result = 0 means OK.
462
	 */
463
	function executeCLI($command, $outputfile, $execmethod=0)
464
	{
465
		global $conf, $langs;
466
467
		$result = 0;
468
		$output = '';
469
		$error = '';
470
471
		$command=escapeshellcmd($command);
472
		$command.=" 2>&1";
473
474
		if (! empty($conf->global->MAIN_EXEC_USE_POPEN)) $execmethod=$conf->global->MAIN_EXEC_USE_POPEN;
475
		if (empty($execmethod)) $execmethod=1;
476
		//$execmethod=1;
477
478
		dol_syslog("Utils::executeCLI execmethod=".$execmethod." system:".$command, LOG_DEBUG);
479
		$output_arr=array();
480
481
		if ($execmethod == 1)
482
		{
483
			exec($command, $output_arr, $retval);
484
			$result = $retval;
485
			if ($retval != 0)
486
			{
487
				$langs->load("errors");
488
				dol_syslog("Utils::executeCLI retval after exec=".$retval, LOG_ERR);
489
				$error = 'Error '.$retval;
490
			}
491
		}
492
		if ($execmethod == 2)	// With this method, there is no way to get the return code, only output
493
		{
494
			$ok=0;
495
			$handle = fopen($outputfile, 'w+b');
496
			if ($handle)
497
			{
498
				dol_syslog("Utils::executeCLI run command ".$command);
499
				$handlein = popen($command, 'r');
500
				while (!feof($handlein))
501
				{
502
					$read = fgets($handlein);
503
					fwrite($handle,$read);
504
					$output_arr[]=$read;
505
				}
506
				pclose($handlein);
507
				fclose($handle);
508
			}
509
			if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
510
		}
511
512
		// Update with result
513
		if (is_array($output_arr) && count($output_arr)>0)
514
		{
515
			foreach($output_arr as $val)
516
			{
517
				$output.=$val.($execmethod == 2 ? '' : "\n");
518
			}
519
		}
520
521
		dol_syslog("Utils::executeCLI result=".$result." output=".$output." error=".$error, LOG_DEBUG);
522
523
		return array('result'=>$result, 'output'=>$output, 'error'=>$error);
524
	}
525
526
}
527