Completed
Push — master ( 2215c7...0db5fc )
by Damian
10s
created

SSPak::loadCsv()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 25
rs 8.5806
cc 4
eloc 17
nc 4
nop 1
1
<?php
2
3
use SilverStripe\SsPak\DataExtractor\DatabaseConnector;
4
use SilverStripe\SsPak\DataExtractor\CsvTableWriter;
5
use SilverStripe\SsPak\DataExtractor\CsvTableReader;
6
7
/**
8
 * SSPak handler
9
 */
10
class SSPak {
11
	protected $executor;
12
13
	/**
14
	 * Create a new handler
15
	 * @param Executor $executor The Executor object to handle command execution
16
	 */
17
	function __construct($executor) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
18
		$this->executor = $executor;
19
	}
20
21
	function getActions() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
22
		return array(
23
			"help" => array(
24
				"description" => "Show this help message.",
25
				"method" => "help",
26
			),
27
			"save" => array(
28
				"description" => "Save an .sspak file from a SilverStripe site.",
29
				"unnamedArgs" => array("webroot", "sspak file"),
30
				"namedArgs" => array("identity"),
31
				"method" => "save",
32
			),
33
			"load" => array(
34
				"description" => "Load an .sspak file into a SilverStripe site. Does not backup - be careful!",
35
				"unnamedArgs" => array("sspak file", "[webroot]"),
36
				"namedArgs" => array("identity"),
37
				"namedFlags" => array("drop-db"),
38
				"method" => "load",
39
			),
40
			"saveexisting" => array(
41
				"description" => "Create an .sspak file from database SQL dump and/or assets. Does not require a SilverStripe site.",
42
				"unnamedArgs" => array("sspak file"),
43
				"namedArgs" => array("db", "assets"),
44
				"method" => "saveexisting"
45
			),
46
			"extract" => array(
47
				"description" => "Extract an .sspak file into the current working directory. Does not require a SilverStripe site.",
48
				"unnamedArgs" => array("sspak file", "destination path"),
49
				"method" => "extract"
50
			),
51
			"listtables" => array(
52
				"description" => "List tables in the database",
53
				"unnamedArgs" => array("webroot"),
54
				"method" => "listTables"
55
			),
56
57
			"savecsv" => array(
58
				"description" => "Save tables in the database to a collection of CSV files",
59
				"unnamedArgs" => array("webroot", "output-path"),
60
				"method" => "saveCsv"
61
			),
62
63
			"loadcsv" => array(
64
				"description" => "Load tables from collection of CSV files to a webroot",
65
				"unnamedArgs" => array("input-path", "webroot"),
66
				"method" => "loadCsv"
67
			),
68
			/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% 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...
69
70
			"install" => array(
71
				"description" => "Install a .sspak file into a new environment.",
72
				"unnamedArgs" => array("sspak file", "new webroot"),
73
				"method" => "install",
74
			),
75
			"bundle" => array(
76
				"description" => "Bundle a .sspak file into a self-extracting executable .sspak.phar installer.",
77
				"unnamedArgs" => array("sspak file", "executable"),
78
				"method" => "bundle",
79
			),
80
			"transfer" => array(
81
				"description" => "Transfer db & assets from one site to another (not implemented yet).",
82
				"unnamedArgs" => array("src webroot", "dest webroot"),
83
				"method" => "transfer",
84
			),
85
			*/
86
		);
87
	}
88
89
	function help($args) {
0 ignored issues
show
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
90
		echo "SSPak: manage SilverStripe .sspak archives.\n\nUsage:\n";
91
		foreach($this->getActions() as $action => $info) {
92
			echo "sspak $action";
93
			if(!empty($info['unnamedArgs'])) {
94
				foreach($info['unnamedArgs'] as $arg) echo " ($arg)";
0 ignored issues
show
Bug introduced by
The expression $info['unnamedArgs'] of type string|array<integer,string,{"0":"string"}> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
95
			}
96
			if(!empty($info['namedFlags'])) {
97
				foreach($info['namedFlags'] as $arg) echo " (--$arg)";
0 ignored issues
show
Bug introduced by
The expression $info['namedFlags'] of type string|array<integer,string,{"0":"string"}> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
98
			}
99
			if(!empty($info['namedArgs'])) {
100
				foreach($info['namedArgs'] as $arg) echo " --$arg=\"$arg value\"";
0 ignored issues
show
Bug introduced by
The expression $info['namedArgs'] of type string|array<integer,string,{"0":"string"}> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
101
			}
102
			echo "\n  {$info['description']}\n\n";
103
		}
104
	}
105
106
	/**
107
	 * Save an existing database and/or assets into an .sspak.phar file.
108
	 * Does the same as {@link save()} but doesn't require an existing site.
109
	 */
110
	function saveexisting($args) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
111
		$executor = $this->executor;
112
113
		$args->requireUnnamed(array('sspak file'));
114
		$unnamedArgs = $args->getUnnamedArgs();
115
		$namedArgs = $args->getNamedArgs();
116
117
		$sspak = new SSPakFile($unnamedArgs[0], $executor);
118
119
		// Look up which parts of the sspak are going to be saved
120
		$pakParts = $args->pakParts();
121
122
		$filesystem = new FilesystemEntity(null, $executor);
123
124
		if($pakParts['db']) {
125
			$dbPath = escapeshellarg($namedArgs['db']);
126
			$process = $filesystem->createProcess("cat $dbPath | gzip -c");
127
			$sspak->writeFileFromProcess('database.sql.gz', $process);
128
		}
129
130
		if($pakParts['assets']) {
131
			$assetsParentArg = escapeshellarg(dirname($namedArgs['assets']));
132
			$assetsBaseArg = escapeshellarg(basename($namedArgs['assets']));
133
			$process = $filesystem->createProcess("cd $assetsParentArg && tar cfh - $assetsBaseArg | gzip -c");
134
			$sspak->writeFileFromProcess('assets.tar.gz', $process);
135
		}
136
	}
137
138
	/**
139
	 * Extracts an existing database and/or assets from a sspak into the given directory,
140
	 * defaulting the current working directory if the destination is not given.
141
	 */
142
	function extract($args) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
143
		$executor = $this->executor;
144
145
		$args->requireUnnamed(array('source sspak file'));
146
		$unnamedArgs = $args->getUnnamedArgs();
147
		$file = $unnamedArgs[0];
148
		$dest = !empty($unnamedArgs[1]) ? $unnamedArgs[1] : getcwd();
149
150
		$sspak = new SSPakFile($file, $executor);
151
152
		// Validation
153
		if(!$sspak->exists()) throw new Exception("File '$file' doesn't exist.");
154
155
		$phar = $sspak->getPhar();
156
		$phar->extractTo($dest);
157
	}
158
159
	function listTables($args) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
160
		$args->requireUnnamed(array('webroot'));
161
		$unnamedArgs = $args->getUnnamedArgs();
162
		$webroot = $unnamedArgs[0];
163
164
		$db = new DatabaseConnector($webroot);
165
166
		print_r($db->getTables());
167
	}
168
169
	function saveCsv($args) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
170
		$args->requireUnnamed(array('webroot', 'path'));
171
		$unnamedArgs = $args->getUnnamedArgs();
172
		$webroot = $unnamedArgs[0];
173
		$destPath = $unnamedArgs[1];
174
175
		if (!file_exists($destPath)) {
176
			mkdir($destPath) || die("Can't create $destPath");
177
		}
178
		if (!is_dir($destPath)) {
179
			die("$destPath isn't a directory");
180
		}
181
182
		$db = new DatabaseConnector($webroot);
183
184
		foreach($db->getTables() as $table) {
185
			$filename = $destPath . '/' . $table . '.csv';
186
			echo $filename . "...\n";
187
			touch($filename);
188
			$writer = new CsvTableWriter($filename);
189
			$db->saveTable($table, $writer);
190
		}
191
		echo "Done!";
192
	}
193
194
	function loadCsv($args) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
195
		$args->requireUnnamed(array('input-path', 'webroot'));
196
		$unnamedArgs = $args->getUnnamedArgs();
197
198
		$srcPath = $unnamedArgs[0];
199
		$webroot = $unnamedArgs[1];
200
201
		if (!is_dir($srcPath)) {
202
			die("$srcPath isn't a directory");
203
		}
204
205
		$db = new DatabaseConnector($webroot);
206
207
		foreach($db->getTables() as $table) {
208
			$filename = $srcPath . '/' . $table . '.csv';
209
			if(file_exists($filename)) {
210
				echo $filename . "...\n";
211
				$reader = new CsvTableReader($filename);
212
				$db->loadTable($table, $reader);
213
			} else {
214
				echo "$filename doesn't exist; skipping.\n";
215
			}
216
		}
217
		echo "Done!";
218
	}
219
	/**
220
	 * Save a .sspak.phar file
221
	 */
222
	function save($args) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
223
		$executor = $this->executor;
224
225
		$args->requireUnnamed(array('source webroot', 'dest sspak file'));
226
227
		$unnamedArgs = $args->getUnnamedArgs();
228
		$namedArgs = $args->getNamedArgs();
229
230
		$webroot = new Webroot($unnamedArgs[0], $executor);
231
		$file = $unnamedArgs[1];
232
		if(file_exists($file)) throw new Exception( "File '$file' already exists.");
233
234
		$sspak = new SSPakFile($file, $executor);
235
236
		if(!empty($namedArgs['identity'])) {
237
			// SSH private key
238
			$webroot->setSSHItentityFile($namedArgs['identity']);
239
		}
240
		if(!empty($namedArgs['from-sudo'])) $webroot->setSudo($namedArgs['from-sudo']);
241
		else if(!empty($namedArgs['sudo'])) $webroot->setSudo($namedArgs['sudo']);
242
243
		// Look up which parts of the sspak are going to be saved
244
		$pakParts = $args->pakParts();
245
246
		// Get the environment details
247
		$details = $webroot->sniff();
248
249
		// Create a build folder for the sspak file
250
		$buildFolder = "/tmp/sspak-" . rand(100000,999999);
251
		$webroot->exec(array('mkdir', $buildFolder));
0 ignored issues
show
Documentation introduced by
array('mkdir', $buildFolder) is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
252
253
		$dbFile = "$buildFolder/database.sql.gz";
254
		$assetsFile = "$buildFolder/assets.tar.gz";
255
		$gitRemoteFile = "$buildFolder/git-remote";
256
257
		// Files to include in the .sspak.phar file
258
		$fileList = array();
0 ignored issues
show
Unused Code introduced by
$fileList is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
259
260
		// Save DB
261
		if($pakParts['db']) {
262
			// Check the database type
263
			$dbFunction = 'getdb_'.$details['db_type'];
264 View Code Duplication
			if(!method_exists($this,$dbFunction)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
265
				throw new Exception("Can't process database type '" . $details['db_type'] . "'");
266
			}
267
			$this->$dbFunction($webroot, $details, $sspak, basename($dbFile));
268
		}
269
270
		// Save Assets
271
		if($pakParts['assets']) {
272
			$this->getassets($webroot, $details['assets_path'], $sspak, basename($assetsFile));
273
		}
274
275
		// Save git-remote
276
		if($pakParts['git-remote']) {
277
			$this->getgitremote($webroot, $sspak, basename($gitRemoteFile));
278
		}
279
280
		// Remove the build folder
281
		$webroot->unlink($buildFolder);
282
	}
283
284
	function getdb_MySQLPDODatabase($webroot, $conf, $sspak, $filename) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
285
		return $this->getdb_MySQLDatabase($webroot, $conf, $sspak, $filename);
286
	}
287
288
	function getdb_MySQLDatabase($webroot, $conf, $sspak, $filename) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
289
		$usernameArg = escapeshellarg("--user=".$conf['db_username']);
290
		$passwordArg = escapeshellarg("--password=".$conf['db_password']);
291
		$databaseArg = escapeshellarg($conf['db_database']);
292
293
		$hostArg = '';
294
		$portArg = '';
295 View Code Duplication
		if (!empty($conf['db_server']) && $conf['db_server'] != 'localhost') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
296
			if (strpos($conf['db_server'], ':')!==false) {
297
				// Handle "server:port" format.
298
				$server = explode(':', $conf['db_server'], 2);
299
				$hostArg = escapeshellarg("--host=".$server[0]);
300
				$portArg = escapeshellarg("--port=".$server[1]);
301
			} else {
302
				$hostArg = escapeshellarg("--host=".$conf['db_server']);
303
			}
304
		}
305
306
		$filenameArg = escapeshellarg($filename);
0 ignored issues
show
Unused Code introduced by
$filenameArg is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
307
308
		$process = $webroot->createProcess("mysqldump --skip-opt --add-drop-table --extended-insert --create-options --quick  --set-charset --default-character-set=utf8 $usernameArg $passwordArg $hostArg $portArg $databaseArg | gzip -c");
309
		$sspak->writeFileFromProcess($filename, $process);
310
		return true;
311
	}
312
313
	function getdb_PostgreSQLDatabase($webroot, $conf, $sspak, $filename) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
314
		$usernameArg = escapeshellarg("--username=".$conf['db_username']);
315
		$passwordArg = "PGPASSWORD=".escapeshellarg($conf['db_password']);
316
		$databaseArg = escapeshellarg($conf['db_database']);
317
		$hostArg = escapeshellarg("--host=".$conf['db_server']);
318
		$filenameArg = escapeshellarg($filename);
0 ignored issues
show
Unused Code introduced by
$filenameArg is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
319
320
		$process = $webroot->createProcess("$passwordArg pg_dump --clean --no-owner --no-tablespaces $usernameArg $hostArg $databaseArg | gzip -c");
321
		$sspak->writeFileFromProcess($filename, $process);
322
		return true;
323
	}
324
325
	function getassets($webroot, $assetsPath, $sspak, $filename) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
326
		$assetsParentArg = escapeshellarg(dirname($assetsPath));
327
		$assetsBaseArg = escapeshellarg(basename($assetsPath));
328
329
		$process = $webroot->createProcess("cd $assetsParentArg && tar cfh - $assetsBaseArg | gzip -c");
330
		$sspak->writeFileFromProcess($filename, $process);
331
	}
332
333
	function getgitremote($webroot, $sspak, $gitRemoteFile) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
334
		// Only do anything if we're copying from a git checkout
335
		$gitRepo = $webroot->getPath() .'/.git';
336
		if($webroot->exists($gitRepo)) {
337
			// Identify current branch
338
			$output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'branch'));
339
			if(preg_match("/\* ([^ \n]*)/", $output['output'], $matches) && strpos("(no branch)", $matches[1])===false) {
340
				// If there is a current branch, use that branch's remove
341
				$currentBranch = trim($matches[1]);
342
				$output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'config','--get',"branch.$currentBranch.remote"));
343
				$remoteName = trim($output['output']);
344
				if(!$remoteName) $remoteName = 'origin';
345
346
			// Default to origin
347
			} else {
348
				$currentBranch = null;
349
				$remoteName = 'origin';
350
			}
351
352
			// Determine the URL of that remote
353
			$output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'config','--get',"remote.$remoteName.url"));
354
			$remoteURL = trim($output['output']);
355
356
			// Determine the current SHA
357
			$output = $webroot->exec(array('git', '--git-dir='.$gitRepo, 'log','-1','--format=%H'));
358
			$sha = trim($output['output']);
359
360
			$content = "remote = $remoteURL\nbranch = $currentBranch\nsha = $sha\n";
361
362
			$sspak->writeFile($gitRemoteFile, $content);
363
364
			return true;
365
		}
366
		return false;
367
	}
368
369
	/**
370
	 * Load an .sspak into an environment.
371
	 * Does not backup - be careful! */
372
	function load($args) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
373
		$executor = $this->executor;
374
375
		$args->requireUnnamed(array('source sspak file'));
376
377
		// Set-up
378
		$file = $args->unnamed(0);
379
		$sspak = new SSPakFile($file, $executor);
380
		$webroot = new Webroot(($args->unnamed(1) ?: '.'), $executor);
381
		$webroot->setSudo($args->sudo('to'));
382
		$pakParts = $args->pakParts();
383
384
		$namedArgs = $args->getNamedArgs();
385
		if(!empty($namedArgs['identity'])) {
386
			// SSH private key
387
			$webroot->setSSHItentityFile($namedArgs['identity']);
388
		}
389
390
		// Validation
391
		if(!$sspak->exists()) throw new Exception( "File '$file' doesn't exist.");
392
393
		// Push database, if necessary
394
		$namedArgs = $args->getNamedArgs();
395
		if($pakParts['db'] && $sspak->contains('database.sql.gz')) {
396
			$webroot->putdb($sspak, isset($namedArgs['drop-db']));
397
		}
398
399
		// Push assets, if neccessary
400
		if($pakParts['assets'] && $sspak->contains('assets.tar.gz')) {
401
			$webroot->putassets($sspak);
402
		}
403
	}
404
405
	/**
406
	 * Install an .sspak into a new environment.
407
	 */
408
	function install($args) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
409
		$executor = $this->executor;
410
411
		$args->requireUnnamed(array('source sspak file', 'dest new webroot'));
412
413
		// Set-up
414
		$file = $args->unnamed(0);
415
		$webrootDir = $args->unnamed(1);
416
		$sspak = new SSPakFile($file, $executor);
417
		$webroot = new Webroot($webrootDir, $executor);
418
		$webroot->setSudo($args->sudo('to'));
419
		$pakParts = $args->pakParts();
420
421
		// Validation
422
		if($webroot->exists($webroot->getPath())) throw new Exception( "Webroot '$webrootDir' already exists.");
423
		if(!$sspak->exists()) throw new Exception( "File '$file' doesn't exist.");
424
425
		// Create new dir
426
		$webroot->exec(array('mkdir', $webroot->getPath()));
0 ignored issues
show
Documentation introduced by
array('mkdir', $webroot->getPath()) is of type array<integer,?,{"0":"string","1":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
427
428
		if($sspak->contains('git-remote')) {
429
			$details = $sspak->gitRemoteDetails();
430
			$webroot->putgit($details);
431
		}
432
433
		// TODO: composer install needed.
434
435
		// Push database, if necessary
436
		$namedArgs = $args->getNamedArgs();
437
		if($pakParts['db'] && $sspak->contains('database.sql.gz')) {
438
			$webroot->putdb($sspak, isset($namedArgs['drop-db']));
439
		}
440
441
		// Push assets, if neccessary
442
		if($pakParts['assets'] && $sspak->contains('assets.tar.gz')) {
443
			$webroot->putassets($sspak);
444
		}
445
	}
446
447
	/**
448
	 * Bundle a .sspak into a self-extracting executable installer.
449
	 */
450
	function bundle($args) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
451
		// TODO: throws require_once errors, fix before re-enabling.
452
453
		$executor = $this->executor;
454
455
		$args->requireUnnamed(array('source sspak file', 'dest executable file'));
456
457
		// Set-up
458
		$sourceFile = $args->unnamed(0);
459
		$destFile = $args->unnamed(1);
460
461
		$sspakScript = file_get_contents($_SERVER['argv'][0]);
462
		// Broken up to not get detected by our sed command
463
		$sspakScript .= "\n__halt_compiler();\n"."//"." TAR START?>\n";
464
465
		// Mark as self-extracting
466
		$sspakScript = str_replace('$isSelfExtracting = false;', '$isSelfExtracting = true;', $sspakScript);
467
468
		// Load the sniffer file
469
		$snifferFile = dirname(__FILE__) . '/sspak-sniffer.php';
470
		$sspakScript = str_replace("\$snifferFileContent = '';\n",
471
			"\$snifferFileContent = '"
472
			. str_replace(array("\\","'"),array("\\\\", "\\'"), file_get_contents($snifferFile)) . "';\n", $sspakScript);
473
474
		file_put_contents($destFile, $sspakScript);
475
		chmod($destFile, 0775);
476
477
		$executor->execLocal(array('cat', $sourceFile), array(
0 ignored issues
show
Documentation introduced by
array('cat', $sourceFile) is of type array<integer,?,{"0":"string","1":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
478
			'outputFile' => $destFile,
479
			'outputFileAppend' => true
480
		));
481
	}
482
483
	/**
484
	 * Transfer between environments without creating an sspak file
485
	 */
486
	function transfer($args) {
0 ignored issues
show
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
487
		echo "Not implemented yet.\n";
488
	}
489
}
490