Passed
Push — master ( a8cc99...7569bc )
by Morris
13:21 queued 20s
created

FTP::fopen()   C

Complexity

Conditions 17
Paths 39

Size

Total Lines 36
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 29
nc 39
nop 2
dl 0
loc 36
rs 5.2166
c 0
b 0
f 0

How to fix   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
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Björn Schießle <[email protected]>
6
 * @author Christoph Wurst <[email protected]>
7
 * @author Felix Moeller <[email protected]>
8
 * @author Jörn Friedrich Dreyer <[email protected]>
9
 * @author Michael Gapczynski <[email protected]>
10
 * @author Morris Jobke <[email protected]>
11
 * @author Philipp Kapfer <[email protected]>
12
 * @author Robin Appelman <[email protected]>
13
 * @author Robin McCorkell <[email protected]>
14
 * @author Roeland Jago Douma <[email protected]>
15
 * @author Senorsen <[email protected]>
16
 * @author Thomas Müller <[email protected]>
17
 * @author Vincent Petry <[email protected]>
18
 *
19
 * @license AGPL-3.0
20
 *
21
 * This code is free software: you can redistribute it and/or modify
22
 * it under the terms of the GNU Affero General Public License, version 3,
23
 * as published by the Free Software Foundation.
24
 *
25
 * This program is distributed in the hope that it will be useful,
26
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
 * GNU Affero General Public License for more details.
29
 *
30
 * You should have received a copy of the GNU Affero General Public License, version 3,
31
 * along with this program. If not, see <http://www.gnu.org/licenses/>
32
 *
33
 */
34
35
namespace OCA\Files_External\Lib\Storage;
36
37
use Icewind\Streams\CallbackWrapper;
38
use Icewind\Streams\IteratorDirectory;
39
use Icewind\Streams\RetryWrapper;
40
41
class FTP extends StreamWrapper {
42
	private $password;
43
	private $user;
44
	private $host;
45
	private $secure;
46
	private $root;
47
48
	public function __construct($params) {
49
		if (isset($params['host']) && isset($params['user']) && isset($params['password'])) {
50
			$this->host=$params['host'];
51
			$this->user=$params['user'];
52
			$this->password=$params['password'];
53
			if (isset($params['secure'])) {
54
				$this->secure = $params['secure'];
55
			} else {
56
				$this->secure = false;
57
			}
58
			$this->root=isset($params['root'])?$params['root']:'/';
59
			if (! $this->root || $this->root[0]!=='/') {
60
				$this->root='/'.$this->root;
61
			}
62
			if (substr($this->root, -1) !== '/') {
63
				$this->root .= '/';
64
			}
65
		} else {
66
			throw new \Exception('Creating FTP storage failed');
67
		}
68
	}
69
70
	public function getId() {
71
		return 'ftp::' . $this->user . '@' . $this->host . '/' . $this->root;
72
	}
73
74
	/**
75
	 * construct the ftp url
76
	 * @param string $path
77
	 * @return string
78
	 */
79
	public function constructUrl($path) {
80
		$url='ftp';
81
		if ($this->secure) {
82
			$url.='s';
83
		}
84
		$url.='://'.urlencode($this->user).':'.urlencode($this->password).'@'.$this->host.$this->root.$path;
85
		return $url;
86
	}
87
88
	/**
89
	 * Unlinks file or directory
90
	 * @param string $path
91
	 */
92
	public function unlink($path) {
93
		if ($this->is_dir($path)) {
94
			return $this->rmdir($path);
95
		} else {
96
			$url = $this->constructUrl($path);
97
			$result = unlink($url);
98
			clearstatcache(true, $url);
99
			return $result;
100
		}
101
	}
102
	public function fopen($path,$mode) {
103
		switch ($mode) {
104
			case 'r':
105
			case 'rb':
106
			case 'w':
107
			case 'wb':
108
			case 'a':
109
			case 'ab':
110
				//these are supported by the wrapper
111
				$context = stream_context_create(['ftp' => ['overwrite' => true]]);
112
				$handle = fopen($this->constructUrl($path), $mode, false, $context);
113
				return RetryWrapper::wrap($handle);
114
			case 'r+':
115
			case 'w+':
116
			case 'wb+':
117
			case 'a+':
118
			case 'x':
119
			case 'x+':
120
			case 'c':
121
			case 'c+':
122
				//emulate these
123
				if (strrpos($path, '.')!==false) {
124
					$ext=substr($path, strrpos($path, '.'));
0 ignored issues
show
Unused Code introduced by
The assignment to $ext is dead and can be removed.
Loading history...
125
				} else {
126
					$ext='';
127
				}
128
				$tmpFile = \OC::$server->getTempManager()->getTemporaryFile();
129
				if ($this->file_exists($path)) {
130
					$this->getFile($path, $tmpFile);
131
				}
132
				$handle = fopen($tmpFile, $mode);
133
				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
134
					$this->writeBack($tmpFile, $path);
135
				});
136
		}
137
		return false;
138
	}
139
140
	public function opendir($path) {
141
		$dh = parent::opendir($path);
142
		if (is_resource($dh)) {
143
			$files = [];
144
			while (($file = readdir($dh)) !== false) {
145
				if ($file != '.' && $file != '..' && strpos($file, '#') === false) {
146
					$files[] = $file;
147
				}
148
			}
149
			return IteratorDirectory::wrap($files);
150
		} else {
151
			return false;
152
		}
153
	}
154
155
156
	public function writeBack($tmpFile, $path) {
157
		$this->uploadFile($tmpFile, $path);
158
		unlink($tmpFile);
159
	}
160
161
	/**
162
	 * check if php-ftp is installed
163
	 */
164
	public static function checkDependencies() {
165
		if (function_exists('ftp_login')) {
166
			return true;
167
		} else {
168
			return ['ftp'];
169
		}
170
	}
171
}
172