GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( e65d67...dc9fa8 )
by Liuta
03:08
created

Xcloner_Database::__construct()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 14
nc 8
nop 5
dl 0
loc 24
rs 6.7272
c 0
b 0
f 0
1
<?php
2
/*
3
 *      class-xcloner-database.php
4
 *
5
 *      Copyright 2017 Ovidiu Liuta <[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 2 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, write to the Free Software
19
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
 *      MA 02110-1301, USA.
21
 */
22
23
24
class Xcloner_Database extends wpdb{
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
25
26
27
	public  $debug 						= 0;
28
	public  $recordsPerSession			= 10000;
29
	public  $dbCompatibility			= "";
30
	public  $dbDropSyntax				= 1;
31
	public  $countRecords				= 0;
32
33
	private  $link;
0 ignored issues
show
Unused Code introduced by
The property $link is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
34
	private  $db_selected;
0 ignored issues
show
Unused Code introduced by
The property $db_selected is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
35
	private  $logger;
36
	private  $fs;
37
38
	private   $TEMP_DBPROCESS_FILE = ".database";
39
	private   $TEMP_DUMP_FILE = "database-backup.sql";
40
	
41
	public function __construct(Xcloner $xcloner_container, $wp_user="", $wp_pass="", $wp_db="", $wp_host="")
42
	{
43
		$this->logger 					= $xcloner_container->get_xcloner_logger()->withName("xcloner_database");
44
		$this->xcloner_settings 		= $xcloner_container->get_xcloner_settings();
45
		$this->fs 						= $xcloner_container->get_xcloner_filesystem();
46
		
47
		if($this->xcloner_settings->get_xcloner_option('xcloner_database_records_per_request'))
48
			$this->recordsPerSession		= $this->xcloner_settings->get_xcloner_option('xcloner_database_records_per_request');
49
		
50
		if(!$this->recordsPerSession)
51
			$this->recordsPerSession = 100;
52
		
53
		if(!$wp_user && !$wp_pass && !$wp_host && !$wp_db )
54
		{
55
			$wp_host 	= $this->xcloner_settings->get_db_hostname();
56
			$wp_user 	= $this->xcloner_settings->get_db_username();
57
			$wp_pass 	= $this->xcloner_settings->get_db_password();
58
			$wp_db 		= $this->xcloner_settings->get_db_database();
59
		}
60
		
61
		parent::__construct($wp_user, $wp_pass, $wp_db, $wp_host);
62
		
63
		//$this->use_mysqli = true;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
64
	}
65
	/*
66
	 * Initialize the database connection
67
	 *
68
	 * name: init
69
	 * @param array $data {'dbHostname', 'dbUsername', 'dbPassword', 'dbDatabase'}
70
	 * @return
71
	 */
72
	public function init($data, $start = 0)
73
	{
74
		if($start and $this->fs->get_tmp_filesystem()->has($this->TEMP_DBPROCESS_FILE)){
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and 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...
75
				$this->fs->get_tmp_filesystem()->delete($this->TEMP_DBPROCESS_FILE);
76
		}
77
		
78
		$this->headers();
79
		
80
		$this->suppress_errors = true;
81
	}
82
	
83
	public function start_database_recursion($params, $extra_params, $init = 0)
84
	{
85
		$tables = array();
86
		$return['finished'] = 0;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = 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...
87
		$return['stats'] = array(
88
				"total_records"=>0,
89
				"tables_count"=>0,
90
				"database_count"=>0,
91
		);
92
		
93
		if(!$this->xcloner_settings->get_enable_mysql_backup())
94
		{
95
			$return['finished'] = 1;
96
			return $return;
97
		}
98
		
99
		$this->logger->debug(__("Starting database backup process"));
100
		
101
		$this->init($params, $init);
102
		
103
		if($init)
104
		{
105
			$db_count = 0;
106
			
107
			if(isset($params['#']))
108
			{
109
				foreach($params['#'] as $database)
110
				{
111
					if(!isset($params[$database]) or !is_array($params[$database]))
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...
112
						$params[$database] = array();
113
				}
114
				$db_count = -1;
115
			}
116
			
117
			if(isset($params) and is_array($params))
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and 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...
118
				foreach($params as $database=>$tables)
119
				{	
120
					if($database != "#")
121
					{
122
						$stats = $this->write_backup_process_list($database, $tables);	
123
						$return['stats']['tables_count'] 	+= $stats['tables_count'];
124
						$return['stats']['total_records'] 	+= $stats['total_records'];
125
					}
126
				}
127
128
			if(sizeof($params))
129
				$return['stats']['database_count'] = sizeof($params)+$db_count;
130
			else	
131
				$return['stats']['database_count'] = 0;
132
				
133
			return $return;
134
		}
135
		
136
		if(!isset($extra_params['startAtLine']))
137
			$extra_params['startAtLine'] = 0;
138
		if(!isset($extra_params['startAtRecord']))
139
			$extra_params['startAtRecord'] = 0;
140
		if(!isset($extra_params['dumpfile']))
141
			$extra_params['dumpfile'] = "";
142
		
143
		$return = $this->process_incremental($extra_params['startAtLine'], $extra_params['startAtRecord'], $extra_params['dumpfile']);
144
		
145
		return $return;
146
	}
147
	
148
	public function log($message = "")
149
	{
150
		
151
		if($message){
152
			$this->logger->info( $message, array(""));
153
		}else{	
154
			if($this->last_query)
155
				$this->logger->debug( $this->last_query, array(""));
156
			if($this->last_error)
157
				$this->logger->error( $this->last_error, array(""));
158
		}
159
		
160
		return;
161
	}
162
	
163
	/*
164
	 *Return any error
165
	 *
166
	 * name: error
167
	 * @param string $message
168
	 * @return
169
	*/
170
	public function error($message)
171
	{
172
		$this->logger->error( $message, array(""));
173
		
174
		return;
175
	}
176
177
	/*
178
	 * Send some special headers after the connection is initialized
179
	 *
180
	 * name: headers
181
	 * @param
182
	 * @return
183
	 */
184
	private function headers()
185
	{
186
		$this->logger->debug(__("Setting mysql headers"));
187
		
188
		$this->query("SET SQL_QUOTE_SHOW_CREATE=1;");
189
		//$this->log();
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
190
		$this->query("SET sql_mode = 0;");
191
		//$this->log();
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
192
		
193
		$this->set_charset($this->dbh, 'utf8');
194
		//$this->log();
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
195
	
196
197
	}
198
199
	public function get_database_num_tables($database)
200
	{
201
		$this->logger->debug(sprintf(__("Getting number of tables in %s"), $database));
202
		
203
		$query = "show tables in `".$database."`";
204
		
205
		$res =  $this->get_results($query);
206
		$this->log();
207
			
208
		return count($res);
209
	}
210
	
211
	public function get_all_databases()
212
	{
213
		$this->logger->debug(("Getting all databases"));
214
		
215
		$query = "SHOW DATABASES;";
216
		
217
		$databases = $this->get_results($query);
218
		$this->log();
219
		
220
		$databases_list = array();
221
		
222
		$i = 0;
223
		
224
		$databases_list[$i]['name'] = $this->dbname;
225
		$databases_list[$i]['num_tables'] = $this->get_database_num_tables($this->dbname);
226
		$i++;
227
		
228
		if(is_array($databases))
229
		foreach( $databases as $db){
230
			if($db->Database != $this->dbname)
231
			{
232
				$databases_list[$i]['name'] = $db->Database;
233
				$databases_list[$i]['num_tables'] = $this->get_database_num_tables($db->Database);
234
				$i++;
235
			}
236
		}
237
		
238
		return $databases_list;
239
	}
240
	
241
	/*
242
	 * Returns an array of tables from a database and mark $excluded ones
243
	 *
244
	 * name: list_tables
245
	 * @param string $database
246
	 * @param array $include
0 ignored issues
show
Documentation introduced by
There is no parameter named $include. Did you maybe mean $included?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
247
	 * @param int $get_num_records
248
	 * @return array $tablesList
249
	 */
250
	public function list_tables($database = "", $included = array(), $get_num_records = 0)
251
	{
252
		$tablesList[0] = array( );
0 ignored issues
show
Coding Style Comprehensibility introduced by
$tablesList was never initialized. Although not strictly required by PHP, it is generally a good practice to add $tablesList = 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...
253
		$inc = 0;
254
255
		if(!$database)
256
			$database = $this->dbname;
257
		
258
		$this->logger->debug(sprintf(("Listing tables in %s database"), $database));
259
		
260
		$tables = $this->get_results("SHOW TABLES in `".$database."`");
261
		$this->log();
262
263
		foreach ($tables as $table){
264
			
265
			$table = array_values((array)$table)[0];
266
			
267
			$tablesList[$inc]['name'] = $table;
268
			$tablesList[$inc]['database'] = $database;
269
270
			if($get_num_records)
271
			{
272
				$records_num_result = $this->get_var("SELECT count(*) FROM `".$database."`.`".$table."`");
273
				$this->log();
274
					
275
				$tablesList[$inc]['records'] = $records_num_result;
276
			}
277
			
278
			$tablesList[$inc]['excluded'] = 0;
279
						
280
			if(sizeof($included) and is_array($included))
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and 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...
281
				if(!in_array($table, $included) )
282
				{
283
					$tablesList[$inc]['excluded'] = 1;
284
					$this->log(sprintf(__("Excluding table %s.%s from backup"), $table, $database));
285
				}
286
			$inc++;
287
        }
288
289
		return $tablesList;
290
291
	}
292
293
	public function write_backup_process_list($dbname, $incl_tables)
294
	{
295
		$return['total_records'] = 0;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = 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...
296
		$return['tables_count'] = 0;
297
		
298
		$this->log(__("Preparing the database recursion file"));
299
		
300
		$tables = $this->list_tables($dbname, $incl_tables, 1);
301
		
302
		if($this->dbname != $dbname)
303
			$dumpfile = $dbname."-backup.sql";
304
		else
305
			$dumpfile = $this->TEMP_DUMP_FILE;
306
		
307
		$line = sprintf("###newdump###\t%s\t%s\n", $dbname, $dumpfile);
308
		$this->fs->get_tmp_filesystem_append()->write($this->TEMP_DBPROCESS_FILE, $line);
309
			
310
		// write this to the class and write to $TEMP_DBPROCESS_FILE file as database.table records
311
		foreach($tables as $key=>$table) 
312
		if($table!= "" and !$tables[$key]['excluded']){
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and 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...
313
314
			$line = sprintf("`%s`.`%s`\t%s\t%s\n", $dbname, $tables[$key]['name'], $tables[$key]['records'], $tables[$key]['excluded']);
315
			$this->fs->get_tmp_filesystem_append()->write($this->TEMP_DBPROCESS_FILE, $line);
316
			$return['tables_count']++;
317
			$return['total_records'] += $tables[$key]['records'];
318
		}
319
320
		$line = sprintf("###enddump###\t%s\t%s\n", $dbname, $dumpfile);
321
		$this->fs->get_tmp_filesystem_append()->write($this->TEMP_DBPROCESS_FILE, $line);
322
		
323
		return $return;
324
	}
325
326
	/*
327
	 * Returns the number of records from a table
328
	 *
329
	 * name: countRecords
330
	 * @param string $table - the source table
331
	 * @return int $count
332
	 */
333
	public function countRecords($table)
334
	{
335
336
			$table = "`".$this->dbname."`.`$table`";
337
338
			$result = $this->get_var("SELECT count(*) FROM $table;");
339
340
			return intval($result) ;// not max limit on 32 bit systems 2147483647; on 64 bit 9223372036854775807
341
342
	}
343
344
	/*
345
	 *	Processing the mysql backup incrementally
346
	 *
347
	 * name: processIncremental
348
	 * @param
349
	 * 		int $startAtLine - at which line from the perm.txt file to start reading
350
	 * 		int startAtRecord - at which record to start from the table found at $startAtLine
351
	 * 		string $dumpfie	- where to save the data
352
	 * 		string $dbCompatibility - MYSQL40, MYSQ32, none=default
353
	 * 		int $dbDropSyntax	- check if the DROP TABLE syntax should be added
354
	 * @return array $return
355
	 */
356
	public function process_incremental($startAtLine= 0, $startAtRecord = 0, $dumpfile = "", $dbCompatibility= ""){
357
358
		$count = 0;
359
		$return['finished'] = 0;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = 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...
360
		$lines = array();
361
		
362
		if($this->fs->get_tmp_filesystem()->has($this->TEMP_DBPROCESS_FILE))
363
			$lines = array_filter(explode("\n",$this->fs->get_tmp_filesystem()->read($this->TEMP_DBPROCESS_FILE)));
364
	
365
		foreach ($lines as $buffer){
366
			
367
			if($count == $startAtLine)
368
			{
369
	
370
				$tableInfo =explode("\t", $buffer);
371
				
372
				if($tableInfo[0] == "###newdump###"){
373
						// we create a new mysql dump file
374
						if($dumpfile != ""){
375
								// we finished a previous one and write the footers
376
								$return['dumpsize'] = $this->data_footers($dumpfile);
377
						}
378
	
379
						$dumpfile = $tableInfo[2];
380
						
381
						$this->log(sprintf(__("Starting new backup dump to file %s"), $dumpfile));
382
						
383
						$this->data_headers($dumpfile, $tableInfo[1]);
384
						$dumpfile = $tableInfo[2];
385
						$startAtLine++;
386
						$return['new_dump'] = 1;
387
						//break;
388
				}else{
389
						//we export the table
390
						if($tableInfo[0] == "###enddump###")
391
							$return['endDump'] = 1;
392
	
393
						//table is excluded
394
						if($tableInfo[2])
395
							continue;
396
							
397
						$next = $startAtRecord + $this->recordsPerSession;
398
						
399
						// $tableInfo[1] number of records in the table
400
						$table = explode("`.`", $tableInfo[0]);
401
						$tableName = str_replace("`", "", $table[1]);
402
						$databaseName = str_replace("`", "", $table[0]);
403
404
						//return something to the browser
405
						$return['databaseName'] 	= $databaseName;
406
						$return['tableName'] 		= $tableName;
407
						$return['totalRecords'] 	= $tableInfo[1];
408
409
						$processed_records = 0;
410
						
411
						if(trim($tableName) !=""  and !$tableInfo[2])
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and 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...
412
							$processed_records = $this->export_table($databaseName, $tableName, $startAtRecord, $this->recordsPerSession, $dumpfile);
413
						
414
						$return['processedRecords'] = $startAtRecord+$processed_records;
415
						
416
						if($next >= $tableInfo[1]) //we finished loading the records for next sessions, will go to the new record
417
						{
418
								$startAtLine ++;
419
								$startAtRecord = 0;
420
						}else{
421
								$startAtRecord = $startAtRecord + $this->recordsPerSession;
422
							}
423
424
						//$return['dbCompatibility'] 	= self::$dbCompatibility;
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
425
						
426
						$return['startAtLine']		= $startAtLine;
427
						$return['startAtRecord']	= $startAtRecord;
428
						$return['dumpfile']			= $dumpfile;
429
						$return['dumpsize']			= $this->fs->get_tmp_filesystem_append()->getSize($dumpfile);
430
431
						return $return;
432
						break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
433
	
434
						
435
					}
436
	
437
			}
438
	
439
			$count++;
440
	
441
	
442
		}
443
	
444
		//while is finished, lets go home...
445
		if($dumpfile != ""){
446
			// we finished a previous one and write the footers
447
			$return['dumpsize'] = $this->data_footers($dumpfile);
448
			$return['dumpfile'] = ($dumpfile);
449
		}
450
		$return['finished'] = 1;
451
		$return['startAtLine']	= $startAtLine;
452
		
453
		if($this->fs->get_tmp_filesystem()->has($this->TEMP_DBPROCESS_FILE))
454
			$this->fs->get_tmp_filesystem()->delete($this->TEMP_DBPROCESS_FILE);
455
		
456
		$this->logger->debug(sprintf(("Database backup finished!")));
457
		
458
		return $return;
459
460
461
	}
462
463
464
	/*
465
	 * Exporting the table records
466
	 *
467
	 * name: exportTable
468
	 * @param
469
	 * 		string $databaseName - database name of the table
470
	 * 		string tableName - table name
471
	 * 		int $start - where to start from
472
	 * 		int $limit - how many records
473
	 * 		handler $fd - file handler where to write the records
474
	 * @return
475
	 */
476
	public function export_table($databaseName, $tableName, $start, $limit, $dumpfile)
477
	{
478
		$this->logger->debug(sprintf(("Exporting table  %s.%s data"), $databaseName, $tableName));
479
		
480
		$records = 0;
481
		
482
		if($start == 0)
483
			$this->dump_structure($databaseName, $tableName, $dumpfile);
484
485
		$start = intval($start);
486
		$limit = intval($limit);
487
		//exporting the table content now
488
489
		$query = "SELECT * from `$databaseName`.`$tableName` Limit $start, $limit ;";
490
		if($this->use_mysqli)
491
		{
492
			$result = mysqli_query($this->dbh, $query);
493
			$mysql_fetch_function = "mysqli_fetch_array";
494
		
495
		}else{
496
			$result = mysql_query($query, $this->dbh);
497
			$mysql_fetch_function = "mysql_fetch_array";
498
		}
499
		//$result = $this->get_results($query, ARRAY_N);
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
500
		//print_r($result); exit;
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
501
		
502
		if($result){
503
			while($row = $mysql_fetch_function($result, MYSQLI_ASSOC)){
504
					
505
					$this->fs->get_tmp_filesystem_append()->write($dumpfile, "INSERT INTO `$tableName` VALUES (");
506
					$arr = $row;
507
					$buffer = "";
508
					$this->countRecords++;
509
510
	                foreach ($arr as $key => $value) {
511
						$value = $this->_real_escape($value);
512
						$buffer .= "'".$value."', ";
513
					}
514
					$buffer = rtrim($buffer, ', ') . ");\n";
515
					$this->fs->get_tmp_filesystem_append()->write($dumpfile, $buffer);
516
					unset($buffer);
517
					
518
					$records++;
519
520
				}
521
		}
522
		
523
		$this->log(sprintf(__("Dumping %s records starting position %s from %s.%s table"), $records, $start, $databaseName, $tableName));
524
		
525
		return $records;
526
527
	}
528
529
	public function dump_structure($databaseName, $tableName ,$dumpfile)
530
	{
531
		$this->log(sprintf(__("Dumping the structure for %s.%s table"), $databaseName, $tableName));
532
		
533
		$line = ("\n#\n# Table structure for table `$tableName`\n#\n\n");
534
		$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
535
536
        if ($this->dbDropSyntax)
537
        {
538
			$line = ("\nDROP table IF EXISTS `$tableName`;\n");
539
			$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
540
		}
541
542
		//$result = mysqli_query($this->dbh,"SHOW CREATE table `$databaseName`.`$tableName`;");
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
543
		$result = $this->get_row("SHOW CREATE table `$databaseName`.`$tableName`;", ARRAY_N);
544
		if($result){
545
			//$row = mysqli_fetch_row( $result);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
546
			$line = ($result[1].";\n");
547
			$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
548
		}
549
550
		$line = ( "\n#\n# End Structure for table `$tableName`\n#\n\n");
551
		$line .=("#\n# Dumping data for table `$tableName`\n#\n\n");
552
		$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
553
		
554
		return;
555
556
	}
557
558
	public function data_footers($dumpfile)
559
	{
560
		$this->logger->debug(sprintf(("Writing dump footers in file"), $dumpfile));
561
		// we finished the dump file, not return the size of it
562
		$this->fs->get_tmp_filesystem_append()->write($dumpfile, "\n#\n# Finished at: ".date("M j, Y \a\\t H:i")."\n#");
563
		$size = $this->fs->get_tmp_filesystem_append()->getSize($dumpfile);
564
		
565
		$metadata_dumpfile = $this->fs->get_tmp_filesystem()->getMetadata($dumpfile);
566
		
567
		//adding dump file to the included files list
568
		$this->fs->store_file($metadata_dumpfile, 'tmp_filesystem');
569
		
570
		return $size;
571
572
	}
573
574
	public function resetcountRecords(){
575
		
576
		$this->countRecords = 0;
577
578
		return $this->countRecords;
579
	
580
	}
581
582
	public function getcountRecords(){
583
		
584
		return $this->countRecords;
585
		
586
	}
587
588
589
	public function data_headers($file, $database)
590
	{
591
		$this->logger->debug(sprintf(("Writing dump header for %s database in file"), $database, $file));
592
		
593
		$return = "";
594
595
		$return .= "#\n";
596
		$return .= "# Powered by XCloner Site Backup\n";
597
		$return .= "# http://www.xcloner.com\n";
598
		$return .= "#\n";
599
		$return .= "# Host: " . get_site_url() . "\n";
600
		$return .= "# Generation Time: " . date("M j, Y \a\\t H:i") . "\n";
601
		$return .= "# PHP Version: " . phpversion() . "\n";
602
		$return .= "# Database Charset: ". $this->charset . "\n";
603
		
604
		$results = $this->get_results("SHOW VARIABLES LIKE \"%version%\";", ARRAY_N);
605
		if(isset($results)){
606
			foreach($results as $result){
607
608
					$return .= "# MYSQL ".$result[0].": ".$result[1]."\n";
609
610
				}
611
		}
612
		
613
		$results = $this->get_results("SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
614
					FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '".$database."';");
615
		
616
		if(isset($results[0])){
617
618
			$return .= "# MYSQL DEFAULT_CHARACTER_SET_NAME: ".$results[0]->DEFAULT_CHARACTER_SET_NAME."\n";
619
			$return .= "# MYSQL SCHEMA_NAME: ".$results[0]->DEFAULT_COLLATION_NAME."\n";
620
		}
621
622
		$return .= "#\n# Database : `" . $database . "`\n# --------------------------------------------------------\n\n";
623
		
624
		$this->log(sprintf(__("Writing %s database dump headers"), $database));
625
		
626
		$return = $this->fs->get_tmp_filesystem()->write($file, $return);
627
		return $return['size'];
628
629
	}
630
631
632
}
633