Test Failed
Push — master ( cd42b5...841446 )
by
unknown
16:44 queued 06:09
created
plugins/files/php/Files/Backend/class.backendstore.php 3 patches
Indentation   +164 added lines, -164 removed lines patch added patch discarded remove patch
@@ -7,174 +7,174 @@
 block discarded – undo
7 7
 
8 8
 // For backward compatibility we must check if the file exists
9 9
 if (file_exists(BASE_PATH . 'server/includes/core/class.encryptionstore.php')) {
10
-	require_once BASE_PATH . 'server/includes/core/class.encryptionstore.php';
10
+    require_once BASE_PATH . 'server/includes/core/class.encryptionstore.php';
11 11
 }
12 12
 
13 13
 use Files\Core\Util\Logger;
14 14
 use Files\Core\Util\StringUtil;
15 15
 
16 16
 class BackendStore {
17
-	public const EXTERNAL_BACKEND_PREFIX = "filesbackend"; // folder prefix for external backends
18
-	private $EXTERNAL_BACKEND_DIR = ""; // path to search for external plugins (should be grommunio-web/plugins)
19
-	public const BACKEND_DIR = "/"; // path to search for core backends, relative to current path
20
-	public const LOG_CONTEXT = "BackendStore"; // Context for the Logger
21
-
22
-	/**
23
-	 * Feature variables.
24
-	 */
25
-	public const FEATURE_QUOTA = "Quota";
26
-	public const FEATURE_VERSION = "VersionInfo";
27
-	public const FEATURE_SHARING = "Sharing";
28
-	public const FEATURE_STREAMING = "Streaming";
29
-	public const FEATURE_OAUTH = "OAUTH";
30
-
31
-	/**
32
-	 * @var AbstractBackend
33
-	 */
34
-	private $backends = [];
35
-	protected static $_instance;
36
-
37
-	// Make it a singleton
38
-	private function __construct() {
39
-		$this->EXTERNAL_BACKEND_DIR = BASE_PATH . PATH_PLUGIN_DIR . "/";
40
-
41
-		Logger::debug(self::LOG_CONTEXT, "Searching for external backends in " . $this->EXTERNAL_BACKEND_DIR);
42
-	}
43
-
44
-	/**
45
-	 * Call this method to get singleton.
46
-	 *
47
-	 * @return BackendStore
48
-	 */
49
-	public static function getInstance() {
50
-		if (self::$_instance === null) {
51
-			self::$_instance = new self();
52
-			self::$_instance->initialize();
53
-			self::$_instance->initializeExternal();
54
-		}
55
-
56
-		return self::$_instance;
57
-	}
58
-
59
-	/**
60
-	 * Search the backend folder for backends and register them.
61
-	 */
62
-	public function initialize() {
63
-		$list = [];    // this hold our plugin folders
64
-		$workdir = __DIR__ . self::BACKEND_DIR;
65
-
66
-		// Populate the list of directories to check against
67
-		if (($directoryHandle = opendir($workdir)) !== false) {
68
-			while (($file = readdir($directoryHandle)) !== false) {
69
-				// Make sure we're not dealing with a file or a link to the parent directory
70
-				if (is_dir($workdir . $file) && ($file == '.' || $file == '..') !== true) {
71
-					array_push($list, $file);
72
-				}
73
-			}
74
-		}
75
-		else {
76
-			Logger::error(self::LOG_CONTEXT, "Error opening the backend directory: " . $workdir);
77
-		}
78
-
79
-		// Register the backends
80
-		foreach ($list as $backend) {
81
-			Logger::debug(self::LOG_CONTEXT, "Registering backend: " . $backend);
82
-			$this->register($backend);
83
-		}
84
-	}
85
-
86
-	/**
87
-	 * Search the backend folder for external backends and register them.
88
-	 */
89
-	public function initializeExternal() {
90
-		$list = [];    // this hold our plugin folders
91
-		$workdir = $this->EXTERNAL_BACKEND_DIR;
92
-
93
-		// Populate the list of directories to check against
94
-		if (($directoryHandle = opendir($workdir)) !== false) {
95
-			while (($file = readdir($directoryHandle)) !== false) {
96
-				// Make sure we're not dealing with a file or a link to the parent directory
97
-				if (is_dir($workdir . $file) && ($file == '.' || $file == '..') !== true && StringUtil::startsWith($file, self::EXTERNAL_BACKEND_PREFIX)) {
98
-					$backendName = substr($file, strlen(self::EXTERNAL_BACKEND_PREFIX));
99
-					array_push($list, $backendName);
100
-				}
101
-			}
102
-		}
103
-		else {
104
-			Logger::error(self::LOG_CONTEXT, "Error opening the external backend directory: " . $workdir);
105
-		}
106
-
107
-		// Register the backends
108
-		foreach ($list as $backend) {
109
-			Logger::debug(self::LOG_CONTEXT, "Registering external backend: " . $backend);
110
-			$this->registerExternal($backend);
111
-		}
112
-	}
113
-
114
-	/**
115
-	 * Registration adds the backend to the list of plugins, and also
116
-	 * includes it's code into our runtime.
117
-	 *
118
-	 * @param $backend
119
-	 */
120
-	private function register($backend) {
121
-		require_once __DIR__ . self::BACKEND_DIR . $backend . "/class.backend.php";
122
-		array_push($this->backends, $backend);
123
-	}
124
-
125
-	/**
126
-	 * Registration adds the external backend to the list of plugins, and also
127
-	 * includes it's code into our runtime.
128
-	 *
129
-	 * @param $backend
130
-	 */
131
-	private function registerExternal($backend) {
132
-		require_once $this->EXTERNAL_BACKEND_DIR . self::EXTERNAL_BACKEND_PREFIX . $backend . "/php/class.backend.php";
133
-		array_push($this->backends, $backend);
134
-	}
135
-
136
-	/**
137
-	 * Check if a backend is registered.
138
-	 *
139
-	 * @param $backend
140
-	 *
141
-	 * @return bool
142
-	 */
143
-	public function backendExists($backend) {
144
-		foreach ($this->backends as $registeredbackend) {
145
-			if ($backend === $registeredbackend) {
146
-				return true;
147
-			}
148
-		}
149
-
150
-		Logger::log(self::LOG_CONTEXT, "Backend does not exist: " . $backend);
151
-
152
-		return false;
153
-	}
154
-
155
-	/**
156
-	 * Creates a new Instance of the given backendtype.
157
-	 *
158
-	 * @param $backend
159
-	 *
160
-	 * @return AbstractBackend
161
-	 */
162
-	public function getInstanceOfBackend($backend) {
163
-		if ($this->backendExists($backend)) {
164
-			$class = "\\Files\\Backend\\{$backend}\\Backend";
165
-
166
-			return new $class();
167
-		}
168
-
169
-		return false; // return false if the backend does not exist
170
-	}
171
-
172
-	/**
173
-	 * Return all registered backend internal names.
174
-	 *
175
-	 * @return array
176
-	 */
177
-	public function getRegisteredBackendNames() {
178
-		return $this->backends;
179
-	}
17
+    public const EXTERNAL_BACKEND_PREFIX = "filesbackend"; // folder prefix for external backends
18
+    private $EXTERNAL_BACKEND_DIR = ""; // path to search for external plugins (should be grommunio-web/plugins)
19
+    public const BACKEND_DIR = "/"; // path to search for core backends, relative to current path
20
+    public const LOG_CONTEXT = "BackendStore"; // Context for the Logger
21
+
22
+    /**
23
+     * Feature variables.
24
+     */
25
+    public const FEATURE_QUOTA = "Quota";
26
+    public const FEATURE_VERSION = "VersionInfo";
27
+    public const FEATURE_SHARING = "Sharing";
28
+    public const FEATURE_STREAMING = "Streaming";
29
+    public const FEATURE_OAUTH = "OAUTH";
30
+
31
+    /**
32
+     * @var AbstractBackend
33
+     */
34
+    private $backends = [];
35
+    protected static $_instance;
36
+
37
+    // Make it a singleton
38
+    private function __construct() {
39
+        $this->EXTERNAL_BACKEND_DIR = BASE_PATH . PATH_PLUGIN_DIR . "/";
40
+
41
+        Logger::debug(self::LOG_CONTEXT, "Searching for external backends in " . $this->EXTERNAL_BACKEND_DIR);
42
+    }
43
+
44
+    /**
45
+     * Call this method to get singleton.
46
+     *
47
+     * @return BackendStore
48
+     */
49
+    public static function getInstance() {
50
+        if (self::$_instance === null) {
51
+            self::$_instance = new self();
52
+            self::$_instance->initialize();
53
+            self::$_instance->initializeExternal();
54
+        }
55
+
56
+        return self::$_instance;
57
+    }
58
+
59
+    /**
60
+     * Search the backend folder for backends and register them.
61
+     */
62
+    public function initialize() {
63
+        $list = [];    // this hold our plugin folders
64
+        $workdir = __DIR__ . self::BACKEND_DIR;
65
+
66
+        // Populate the list of directories to check against
67
+        if (($directoryHandle = opendir($workdir)) !== false) {
68
+            while (($file = readdir($directoryHandle)) !== false) {
69
+                // Make sure we're not dealing with a file or a link to the parent directory
70
+                if (is_dir($workdir . $file) && ($file == '.' || $file == '..') !== true) {
71
+                    array_push($list, $file);
72
+                }
73
+            }
74
+        }
75
+        else {
76
+            Logger::error(self::LOG_CONTEXT, "Error opening the backend directory: " . $workdir);
77
+        }
78
+
79
+        // Register the backends
80
+        foreach ($list as $backend) {
81
+            Logger::debug(self::LOG_CONTEXT, "Registering backend: " . $backend);
82
+            $this->register($backend);
83
+        }
84
+    }
85
+
86
+    /**
87
+     * Search the backend folder for external backends and register them.
88
+     */
89
+    public function initializeExternal() {
90
+        $list = [];    // this hold our plugin folders
91
+        $workdir = $this->EXTERNAL_BACKEND_DIR;
92
+
93
+        // Populate the list of directories to check against
94
+        if (($directoryHandle = opendir($workdir)) !== false) {
95
+            while (($file = readdir($directoryHandle)) !== false) {
96
+                // Make sure we're not dealing with a file or a link to the parent directory
97
+                if (is_dir($workdir . $file) && ($file == '.' || $file == '..') !== true && StringUtil::startsWith($file, self::EXTERNAL_BACKEND_PREFIX)) {
98
+                    $backendName = substr($file, strlen(self::EXTERNAL_BACKEND_PREFIX));
99
+                    array_push($list, $backendName);
100
+                }
101
+            }
102
+        }
103
+        else {
104
+            Logger::error(self::LOG_CONTEXT, "Error opening the external backend directory: " . $workdir);
105
+        }
106
+
107
+        // Register the backends
108
+        foreach ($list as $backend) {
109
+            Logger::debug(self::LOG_CONTEXT, "Registering external backend: " . $backend);
110
+            $this->registerExternal($backend);
111
+        }
112
+    }
113
+
114
+    /**
115
+     * Registration adds the backend to the list of plugins, and also
116
+     * includes it's code into our runtime.
117
+     *
118
+     * @param $backend
119
+     */
120
+    private function register($backend) {
121
+        require_once __DIR__ . self::BACKEND_DIR . $backend . "/class.backend.php";
122
+        array_push($this->backends, $backend);
123
+    }
124
+
125
+    /**
126
+     * Registration adds the external backend to the list of plugins, and also
127
+     * includes it's code into our runtime.
128
+     *
129
+     * @param $backend
130
+     */
131
+    private function registerExternal($backend) {
132
+        require_once $this->EXTERNAL_BACKEND_DIR . self::EXTERNAL_BACKEND_PREFIX . $backend . "/php/class.backend.php";
133
+        array_push($this->backends, $backend);
134
+    }
135
+
136
+    /**
137
+     * Check if a backend is registered.
138
+     *
139
+     * @param $backend
140
+     *
141
+     * @return bool
142
+     */
143
+    public function backendExists($backend) {
144
+        foreach ($this->backends as $registeredbackend) {
145
+            if ($backend === $registeredbackend) {
146
+                return true;
147
+            }
148
+        }
149
+
150
+        Logger::log(self::LOG_CONTEXT, "Backend does not exist: " . $backend);
151
+
152
+        return false;
153
+    }
154
+
155
+    /**
156
+     * Creates a new Instance of the given backendtype.
157
+     *
158
+     * @param $backend
159
+     *
160
+     * @return AbstractBackend
161
+     */
162
+    public function getInstanceOfBackend($backend) {
163
+        if ($this->backendExists($backend)) {
164
+            $class = "\\Files\\Backend\\{$backend}\\Backend";
165
+
166
+            return new $class();
167
+        }
168
+
169
+        return false; // return false if the backend does not exist
170
+    }
171
+
172
+    /**
173
+     * Return all registered backend internal names.
174
+     *
175
+     * @return array
176
+     */
177
+    public function getRegisteredBackendNames() {
178
+        return $this->backends;
179
+    }
180 180
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -60,7 +60,7 @@  discard block
 block discarded – undo
60 60
 	 * Search the backend folder for backends and register them.
61 61
 	 */
62 62
 	public function initialize() {
63
-		$list = [];    // this hold our plugin folders
63
+		$list = []; // this hold our plugin folders
64 64
 		$workdir = __DIR__ . self::BACKEND_DIR;
65 65
 
66 66
 		// Populate the list of directories to check against
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
 	 * Search the backend folder for external backends and register them.
88 88
 	 */
89 89
 	public function initializeExternal() {
90
-		$list = [];    // this hold our plugin folders
90
+		$list = []; // this hold our plugin folders
91 91
 		$workdir = $this->EXTERNAL_BACKEND_DIR;
92 92
 
93 93
 		// Populate the list of directories to check against
Please login to merge, or discard this patch.
Braces   +2 added lines, -4 removed lines patch added patch discarded remove patch
@@ -71,8 +71,7 @@  discard block
 block discarded – undo
71 71
 					array_push($list, $file);
72 72
 				}
73 73
 			}
74
-		}
75
-		else {
74
+		} else {
76 75
 			Logger::error(self::LOG_CONTEXT, "Error opening the backend directory: " . $workdir);
77 76
 		}
78 77
 
@@ -99,8 +98,7 @@  discard block
 block discarded – undo
99 98
 					array_push($list, $backendName);
100 99
 				}
101 100
 			}
102
-		}
103
-		else {
101
+		} else {
104 102
 			Logger::error(self::LOG_CONTEXT, "Error opening the external backend directory: " . $workdir);
105 103
 		}
106 104
 
Please login to merge, or discard this patch.
plugins/files/php/Files/Backend/interface.quota.php 1 patch
Indentation   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -3,7 +3,7 @@
 block discarded – undo
3 3
 namespace Files\Backend;
4 4
 
5 5
 interface iFeatureQuota {
6
-	public function getQuotaBytesUsed($dir);
6
+    public function getQuotaBytesUsed($dir);
7 7
 
8
-	public function getQuotaBytesAvailable($dir);
8
+    public function getQuotaBytesAvailable($dir);
9 9
 }
Please login to merge, or discard this patch.
plugins/files/php/Files/Backend/Webdav/class.backend.php 3 patches
Indentation   +1084 added lines, -1084 removed lines patch added patch discarded remove patch
@@ -21,1088 +21,1088 @@
 block discarded – undo
21 21
  * @extends AbstractBackend
22 22
  */
23 23
 class Backend extends AbstractBackend implements iFeatureQuota, iFeatureVersionInfo {
24
-	/**
25
-	 * Error codes
26
-	 * see @parseErrorCodeToMessage for description.
27
-	 */
28
-	public const WD_ERR_UNAUTHORIZED = 401;
29
-	public const WD_ERR_FORBIDDEN = 403;
30
-	public const WD_ERR_NOTFOUND = 404;
31
-	public const WD_ERR_NOTALLOWED = 405;
32
-	public const WD_ERR_TIMEOUT = 408;
33
-	public const WD_ERR_LOCKED = 423;
34
-	public const WD_ERR_FAILED_DEPENDENCY = 423;
35
-	public const WD_ERR_INTERNAL = 500;
36
-	public const WD_ERR_UNREACHABLE = 800;
37
-	public const WD_ERR_TMP = 801;
38
-	public const WD_ERR_FEATURES = 802;
39
-	public const WD_ERR_NO_CURL = 803;
40
-
41
-	/**
42
-	 * Configuration data for the extjs metaform.
43
-	 */
44
-	protected $formConfig;
45
-	protected $formFields;
46
-	protected $metaConfig;
47
-
48
-	/**
49
-	 * @var bool debugging flag, if true, debugging is enabled
50
-	 */
51
-	public $debug = false;
52
-
53
-	/**
54
-	 * @var int webdav server port
55
-	 */
56
-	public $port = 80;
57
-
58
-	/**
59
-	 * @var string hostname or ip
60
-	 */
61
-	public $server = "localhost";
62
-
63
-	/**
64
-	 * @var string global path prefix for all requests
65
-	 */
66
-	public $path = "/webdav.php";
67
-
68
-	/**
69
-	 * @var bool if true, ssl is used
70
-	 */
71
-	public $ssl = false;
72
-
73
-	/**
74
-	 * @var bool allow self signed certificates
75
-	 */
76
-	public $allowselfsigned = true;
77
-
78
-	/**
79
-	 * @var string the username
80
-	 */
81
-	public $user = "";
82
-
83
-	/**
84
-	 * @var string the password
85
-	 */
86
-	public $pass = "";
87
-
88
-	/**
89
-	 * @var FilesWebDavClient the SabreDAV client object
90
-	 */
91
-	public $sabre_client;
92
-
93
-	/**
94
-	 * @constructor
95
-	 */
96
-	public function __construct() {
97
-		// initialization
98
-		$this->debug = PLUGIN_FILESBROWSER_LOGLEVEL === "DEBUG" ? true : false;
99
-
100
-		$this->init_form();
101
-
102
-		// set backend description
103
-		$this->backendDescription = _("With this backend, you can connect to any WebDAV server.");
104
-
105
-		// set backend display name
106
-		$this->backendDisplayName = "Webdav";
107
-
108
-		// set backend version
109
-		// TODO: this should be changed on every release
110
-		$this->backendVersion = "3.0";
111
-
112
-		// Backend name used in translations
113
-		$this->backendTransName = _('Files WebDAV Backend: ');
114
-	}
115
-
116
-	/**
117
-	 * Initialise form fields.
118
-	 */
119
-	private function init_form() {
120
-		$this->formConfig = [
121
-			"labelAlign" => "left",
122
-			"columnCount" => 1,
123
-			"labelWidth" => 80,
124
-			"defaults" => [
125
-				"width" => 292,
126
-			],
127
-		];
128
-
129
-		$this->formFields = [
130
-			[
131
-				"name" => "server_address",
132
-				"fieldLabel" => _('Server address'),
133
-				"editor" => [
134
-					"allowBlank" => false,
135
-				],
136
-			],
137
-			[
138
-				"name" => "server_port",
139
-				"fieldLabel" => _('Server port'),
140
-				"editor" => [
141
-					"ref" => "../../portField",
142
-					"allowBlank" => false,
143
-				],
144
-			],
145
-			[
146
-				"name" => "server_ssl",
147
-				"fieldLabel" => _('Use SSL'),
148
-				"editor" => [
149
-					"xtype" => "checkbox",
150
-					"listeners" => [
151
-						"check" => "Zarafa.plugins.files.data.Actions.onCheckSSL", // this javascript function will be called!
152
-					],
153
-				],
154
-			],
155
-			[
156
-				"name" => "server_path",
157
-				"fieldLabel" => _('Webdav base path'),
158
-				"editor" => [
159
-				],
160
-			],
161
-			[
162
-				"name" => "user",
163
-				"fieldLabel" => _('Username'),
164
-				"editor" => [
165
-					"ref" => "../../usernameField",
166
-				],
167
-			],
168
-			[
169
-				"name" => "password",
170
-				"fieldLabel" => _('Password'),
171
-				"editor" => [
172
-					"ref" => "../../passwordField",
173
-					"inputType" => "password",
174
-				],
175
-			],
176
-			[
177
-				"name" => "use_grommunio_credentials",
178
-				"fieldLabel" => _('Use grommunio credentials'),
179
-				"editor" => [
180
-					"xtype" => "checkbox",
181
-					"listeners" => [
182
-						"check" => "Zarafa.plugins.files.data.Actions.onCheckCredentials", // this javascript function will be called!
183
-					],
184
-				],
185
-			],
186
-		];
187
-
188
-		$this->metaConfig = [
189
-			"success" => true,
190
-			"metaData" => [
191
-				"fields" => $this->formFields,
192
-				"formConfig" => $this->formConfig,
193
-			],
194
-			"data" => [ // here we can specify the default values.
195
-				"server_address" => "files.demo.com",
196
-				"server_port" => "80",
197
-				"server_path" => "/remote.php/webdav",
198
-			],
199
-		];
200
-	}
201
-
202
-	/**
203
-	 * Initialize backend from $backend_config array.
204
-	 *
205
-	 * @param $backend_config
206
-	 */
207
-	public function init_backend($backend_config) {
208
-		$this->set_server($backend_config["server_address"]);
209
-		$this->set_port($backend_config["server_port"]);
210
-		$this->set_base($backend_config["server_path"]);
211
-		$this->set_ssl($backend_config["server_ssl"]);
212
-
213
-		// set user and password
214
-		if ($backend_config["use_grommunio_credentials"] === false) {
215
-			$this->set_user($backend_config["user"]);
216
-			$this->set_pass($backend_config["password"]);
217
-		}
218
-		else {
219
-			// For backward compatibility we will check if the Encryption store exists. If not,
220
-			// we will fall back to the old way of retrieving the password from the session.
221
-			if (class_exists('EncryptionStore')) {
222
-				// Get the username and password from the Encryption store
223
-				$encryptionStore = \EncryptionStore::getInstance();
224
-				$this->set_user($encryptionStore->get('username'));
225
-				$this->set_pass($encryptionStore->get('password'));
226
-			}
227
-			else {
228
-				$this->set_user($GLOBALS['mapisession']->getUserName());
229
-				$password = $_SESSION['password'];
230
-				if (function_exists('openssl_decrypt')) {
231
-					$this->set_pass(openssl_decrypt($password, "des-ede3-cbc", PASSWORD_KEY, 0, PASSWORD_IV));
232
-				}
233
-			}
234
-		}
235
-	}
236
-
237
-	/**
238
-	 * Set webdav server. FQN or IP address.
239
-	 *
240
-	 * @param string $server hostname or ip of the ftp server
241
-	 */
242
-	public function set_server($server) {
243
-		$this->server = $server;
244
-	}
245
-
246
-	/**
247
-	 * Set base path.
248
-	 *
249
-	 * @param string $pp the global path prefix
250
-	 */
251
-	public function set_base($pp) {
252
-		$this->path = $pp;
253
-		$this->log('Base path set to ' . $this->path);
254
-	}
255
-
256
-	/**
257
-	 * Set ssl.
258
-	 *
259
-	 * @param int /bool $ssl (1 = true, 0 = false)
260
-	 */
261
-	public function set_ssl($ssl) {
262
-		$this->ssl = $ssl ? true : false;
263
-		$this->log('SSL extension was set to ' . $this->ssl);
264
-	}
265
-
266
-	/**
267
-	 * Allow self signed certificates - unimplemented.
268
-	 *
269
-	 * @param bool $allowselfsigned Allow self signed certificates. Not yet implemented.
270
-	 */
271
-	public function set_selfsigned($allowselfsigned) {
272
-		$this->allowselfsigned = $allowselfsigned;
273
-	}
274
-
275
-	/**
276
-	 * Set tcp port of webdav server. Default is 80.
277
-	 *
278
-	 * @param int $port the port of the ftp server
279
-	 */
280
-	public function set_port($port) {
281
-		$this->port = $port;
282
-	}
283
-
284
-	/**
285
-	 * set user name for authentication.
286
-	 *
287
-	 * @param string $user username
288
-	 */
289
-	public function set_user($user) {
290
-		$this->user = $user;
291
-	}
292
-
293
-	/**
294
-	 * Set password for authentication.
295
-	 *
296
-	 * @param string $pass password
297
-	 */
298
-	public function set_pass($pass) {
299
-		$this->pass = $pass;
300
-	}
301
-
302
-	/**
303
-	 * set debug on (1) or off (0).
304
-	 * produces a lot of debug messages in webservers error log if set to on (1).
305
-	 *
306
-	 * @param bool $debug enable or disable debugging
307
-	 */
308
-	public function set_debug($debug) {
309
-		$this->debug = $debug;
310
-	}
311
-
312
-	/**
313
-	 * Opens the connection to the webdav server.
314
-	 *
315
-	 * @throws BackendException if connection is not successful
316
-	 *
317
-	 * @return bool true if action succeeded
318
-	 */
319
-	public function open() {
320
-		// check if curl is available
321
-		$serverHasCurl = function_exists('curl_version');
322
-		if (!$serverHasCurl) {
323
-			$e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_NO_CURL), 500);
324
-			$e->setTitle($this->backendTransName . _('PHP-CURL is not installed'));
325
-
326
-			throw $e;
327
-		}
328
-
329
-		$davsettings = [
330
-			'baseUri' => $this->webdavUrl(),
331
-			'userName' => $this->user,
332
-			'password' => $this->pass,
333
-			'authType' => \Sabre\DAV\Client::AUTH_BASIC,
334
-		];
335
-
336
-		try {
337
-			$this->sabre_client = new FilesWebDavClient($davsettings);
338
-			$this->sabre_client->addCurlSetting(CURLOPT_SSL_VERIFYPEER, !$this->allowselfsigned);
339
-
340
-			return true;
341
-		}
342
-		catch (Exception $e) {
343
-			$this->log('Failed to open: ' . $e->getMessage());
344
-			if (intval($e->getHTTPCode()) == 401) {
345
-				$e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_UNAUTHORIZED), $e->getHTTPCode());
346
-				$e->setTitle($this->backendTransName . _('Access denied'));
347
-
348
-				throw $e;
349
-			}
350
-			$e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_UNREACHABLE), $e->getHTTPCode());
351
-			$e->setTitle($this->backendTransName . _('Connection failed'));
352
-
353
-			throw $e;
354
-		}
355
-	}
356
-
357
-	/**
358
-	 * show content of a directory.
359
-	 *
360
-	 * @param string $path      directory path
361
-	 * @param bool   $hidefirst Optional parameter to hide the root entry. Default true
362
-	 * @param mixed  $dir
363
-	 *
364
-	 * @throws BackendException if request is not successful
365
-	 *
366
-	 * @return mixed array with directory content
367
-	 */
368
-	public function ls($dir, $hidefirst = true) {
369
-		$time_start = microtime(true);
370
-		$dir = $this->removeSlash($dir);
371
-		$lsdata = [];
372
-		$this->log("[LS] start for dir: {$dir}");
373
-
374
-		try {
375
-			$response = $this->sabre_client->propFind($dir, [
376
-				'{http://owncloud.org/ns}fileid',
377
-				'{DAV:}resourcetype',
378
-				'{DAV:}getcontentlength',
379
-				'{DAV:}getlastmodified',
380
-				'{DAV:}getcontenttype',
381
-				'{DAV:}quota-used-bytes',
382
-				'{DAV:}quota-available-bytes',
383
-			], 1);
384
-			$this->log("[LS] backend fetched in: " . (microtime(true) - $time_start) . " seconds.");
385
-
386
-			foreach ($response as $name => $fields) {
387
-				if ($hidefirst) {
388
-					$hidefirst = false; // skip the first line - its the requested dir itself
389
-
390
-					continue;
391
-				}
392
-
393
-				$name = substr($name, strlen($this->path)); // skip the webdav path
394
-				$name = urldecode($name);
395
-
396
-				// Always fallback to a file resourceType
397
-				$type = "file";
398
-				if (isset($fields['{DAV:}resourcetype'])) {
399
-					$value = $fields['{DAV:}resourcetype']->getValue();
400
-					if (!empty($value) && $value[0] === "{DAV:}collection") {
401
-						$type = "collection";
402
-					}
403
-				}
404
-
405
-				$lsdata[$name] = [
406
-					"fileid" => isset($fields["{http://owncloud.org/ns}fileid"]) ? $fields["{http://owncloud.org/ns}fileid"] : '-1',
407
-					"resourcetype" => $type,
408
-					"getcontentlength" => isset($fields["{DAV:}getcontentlength"]) ? $fields["{DAV:}getcontentlength"] : null,
409
-					"getlastmodified" => isset($fields["{DAV:}getlastmodified"]) ? $fields["{DAV:}getlastmodified"] : null,
410
-					"getcontenttype" => isset($fields["{DAV:}getcontenttype"]) ? $fields["{DAV:}getcontenttype"] : null,
411
-					"quota-used-bytes" => isset($fields["{DAV:}quota-used-bytes"]) ? $fields["{DAV:}quota-used-bytes"] : null,
412
-					"quota-available-bytes" => isset($fields["{DAV:}quota-available-bytes"]) ? $fields["{DAV:}quota-available-bytes"] : null,
413
-				];
414
-			}
415
-			$time_end = microtime(true);
416
-			$time = $time_end - $time_start;
417
-			$this->log("[LS] done in {$time} seconds");
418
-
419
-			return $lsdata;
420
-		}
421
-		catch (ClientException $e) {
422
-			$this->log('ls sabre ClientException: ' . $e->getMessage());
423
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
424
-			$e->setTitle($this->backendTransName . _('Sabre error'));
425
-
426
-			throw $e;
427
-		}
428
-		catch (Exception $e) {
429
-			$this->log('ls general exception: ' . $e->getMessage() . " [" . $e->getHTTPCode() . "]");
430
-			// THIS IS A FIX FOR OWNCLOUD - It does return 500 instead of 401...
431
-			$err_code = $e->getHTTPCode();
432
-			// check if code is 500 - then we should try to parse the error message
433
-			if ($err_code === 500) {
434
-				// message example: HTTP-Code: 401
435
-				$regx = '/[0-9]{3}/';
436
-				if (preg_match($regx, $e->getMessage(), $found)) {
437
-					$err_code = $found[0];
438
-				}
439
-			}
440
-			$e = new BackendException($this->parseErrorCodeToMessage($err_code), $err_code);
441
-			$e->setTitle($this->backendTransName . _('Connection failed'));
442
-
443
-			throw $e;
444
-		}
445
-	}
446
-
447
-	/**
448
-	 * create a new directory.
449
-	 *
450
-	 * @param string $dir directory path
451
-	 *
452
-	 * @throws BackendException if request is not successful
453
-	 *
454
-	 * @return bool true if action succeeded
455
-	 */
456
-	public function mkcol($dir) {
457
-		$time_start = microtime(true);
458
-		$dir = $this->removeSlash($dir);
459
-		$this->log("[MKCOL] start for dir: {$dir}");
460
-
461
-		try {
462
-			$response = $this->sabre_client->request("MKCOL", $dir, null);
463
-			$time_end = microtime(true);
464
-			$time = $time_end - $time_start;
465
-			$this->log("[MKCOL] done in {$time} seconds: " . $response['statusCode']);
466
-
467
-			return true;
468
-		}
469
-		catch (ClientException $e) {
470
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
471
-			$e->setTitle($this->backendTransName . _('Sabre error'));
472
-
473
-			throw $e;
474
-		}
475
-		catch (Exception $e) {
476
-			$this->log('[MKCOL] fatal: ' . $e->getMessage());
477
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
478
-			$e->setTitle($this->backendTransName . _('Directory creation failed'));
479
-
480
-			throw $e;
481
-		}
482
-	}
483
-
484
-	/**
485
-	 * delete a file or directory.
486
-	 *
487
-	 * @param string $path file/directory path
488
-	 *
489
-	 * @throws BackendException if request is not successful
490
-	 *
491
-	 * @return bool true if action succeeded
492
-	 */
493
-	public function delete($path) {
494
-		$time_start = microtime(true);
495
-		$path = $this->removeSlash($path);
496
-		$this->log("[DELETE] start for dir: {$path}");
497
-
498
-		try {
499
-			$response = $this->sabre_client->request("DELETE", $path, null);
500
-			$time_end = microtime(true);
501
-			$time = $time_end - $time_start;
502
-			$this->log("[DELETE] done in {$time} seconds: " . $response['statusCode']);
503
-
504
-			return true;
505
-		}
506
-		catch (ClientException $e) {
507
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
508
-			$e->setTitle($this->backendTransName . _('Sabre error'));
509
-
510
-			throw $e;
511
-		}
512
-		catch (Exception $e) {
513
-			$this->log('[DELETE] fatal: ' . $e->getMessage());
514
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
515
-			$e->setTitle($this->backendTransName . _('Deletion failed'));
516
-
517
-			throw $e;
518
-		}
519
-	}
520
-
521
-	/**
522
-	 * Move a file or collection on webdav server (serverside)
523
-	 * If you set param overwrite as true, the target will be overwritten.
524
-	 *
525
-	 * @param string $src_path  Source path
526
-	 * @param string $dest_path Destination path
527
-	 * @param bool   $overwrite Overwrite file if exists in $dest_path
528
-	 * @param mixed  $dst_path
529
-	 *
530
-	 * @throws BackendException if request is not successful
531
-	 *
532
-	 * @return bool true if action succeeded
533
-	 */
534
-	public function move($src_path, $dst_path, $overwrite = false) {
535
-		$time_start = microtime(true);
536
-		$src_path = $this->removeSlash($src_path);
537
-		$dst_path = $this->webdavUrl() . $this->removeSlash($dst_path);
538
-		$this->log("[MOVE] start for dir: {$src_path} -> {$dst_path}");
539
-		if ($overwrite) {
540
-			$overwrite = 'T';
541
-		}
542
-		else {
543
-			$overwrite = 'F';
544
-		}
545
-
546
-		try {
547
-			$response = $this->sabre_client->request("MOVE", $src_path, null, ["Destination" => $dst_path, 'Overwrite' => $overwrite]);
548
-			$time_end = microtime(true);
549
-			$time = $time_end - $time_start;
550
-			$this->log("[MOVE] done in {$time} seconds: " . $response['statusCode']);
551
-
552
-			return true;
553
-		}
554
-		catch (ClientException $e) {
555
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
556
-			$e->setTitle($this->backendTransName . _('Sabre error'));
557
-
558
-			throw $e;
559
-		}
560
-		catch (Exception $e) {
561
-			$this->log('[MOVE] fatal: ' . $e->getMessage());
562
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
563
-			$e->setTitle($this->backendTransName . _('Moving failed'));
564
-
565
-			throw $e;
566
-		}
567
-	}
568
-
569
-	/**
570
-	 * Puts a file into a collection.
571
-	 *
572
-	 * @param string $path Destination path
573
-	 * @param mixed  $data
574
-	 *
575
-	 * @string mixed $data Any kind of data
576
-	 *
577
-	 * @throws BackendException if request is not successful
578
-	 *
579
-	 * @return bool true if action succeeded
580
-	 */
581
-	public function put($path, $data) {
582
-		$time_start = microtime(true);
583
-		$path = $this->removeSlash($path);
584
-		$this->log("[PUT] start for dir: {$path} strlen: " . strlen($data));
585
-
586
-		try {
587
-			$response = $this->sabre_client->request("PUT", $path, $data);
588
-			$time_end = microtime(true);
589
-			$time = $time_end - $time_start;
590
-			$this->log("[PUT] done in {$time} seconds: " . $response['statusCode']);
591
-
592
-			return true;
593
-		}
594
-		catch (ClientException $e) {
595
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
596
-			$e->setTitle($this->backendTransName . _('Sabre error'));
597
-
598
-			throw $e;
599
-		}
600
-		catch (Exception $e) {
601
-			$this->log('[PUT] fatal: ' . $e->getMessage());
602
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
603
-			$e->setTitle($this->backendTransName . _('Connection failed'));
604
-
605
-			throw $e;
606
-		}
607
-	}
608
-
609
-	/**
610
-	 * Upload a local file.
611
-	 *
612
-	 * @param string $path     Destination path on the server
613
-	 * @param string $filename Local filename for the file that should be uploaded
614
-	 *
615
-	 * @throws BackendException if request is not successful
616
-	 *
617
-	 * @return bool true if action succeeded
618
-	 */
619
-	public function put_file($path, $filename) {
620
-		$buffer = file_get_contents($filename);
621
-
622
-		if ($buffer !== false) {
623
-			return $this->put($path, $buffer);
624
-		}
625
-		$e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_TMP), self::WD_ERR_TMP);
626
-		$e->setTitle($this->backendTransName . _('Temporary directory problems'));
627
-
628
-		throw $e;
629
-	}
630
-
631
-	/**
632
-	 * Gets a file from a webdav collection.
633
-	 *
634
-	 * @param string $path   The source path on the server
635
-	 * @param mixed  $buffer Buffer for the received data
636
-	 *
637
-	 * @throws BackendException if request is not successful
638
-	 *
639
-	 * @return bool true if action succeeded
640
-	 */
641
-	public function get($path, &$buffer) {
642
-		$tmpfile = tempnam(TMP_PATH, stripslashes(base64_encode($path)));
643
-
644
-		$this->log("[GET] buffer path: {$tmpfile}");
645
-		$this->get_file($path, $tmpfile);
646
-
647
-		$buffer = file_get_contents($tmpfile);
648
-		unlink($tmpfile);
649
-	}
650
-
651
-	/**
652
-	 * Gets a file from a collection into local filesystem.
653
-	 *
654
-	 * @param string $srcpath   Source path on server
655
-	 * @param string $localpath Destination path on local filesystem
656
-	 *
657
-	 * @throws BackendException if request is not successful
658
-	 *
659
-	 * @return bool true if action succeeded
660
-	 */
661
-	public function get_file($srcpath, $localpath) {
662
-		$time_start = microtime(true);
663
-		$path = $this->removeSlash($srcpath);
664
-		$this->log("[GET_FILE] start for dir: {$path}");
665
-		$this->log("[GET_FILE] local path (" . $localpath . ") writeable: " . is_writable($localpath));
666
-
667
-		try {
668
-			$response = $this->sabre_client->getFile($path, $localpath);
669
-			$time_end = microtime(true);
670
-			$time = $time_end - $time_start;
671
-			$this->log("[GET_FILE] done in {$time} seconds: " . $response['statusCode']);
672
-		}
673
-		catch (ClientException $e) {
674
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
675
-			$e->setTitle($this->backendTransName . _('Sabre error'));
676
-
677
-			throw $e;
678
-		}
679
-		catch (Exception $e) {
680
-			$this->log('[GET_FILE] - FATAL -' . $e->getMessage());
681
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
682
-			$e->setTitle($this->backendTransName . _('File or folder not found'));
683
-
684
-			throw $e;
685
-		}
686
-	}
687
-
688
-	/**
689
-	 * Public method copy_file.
690
-	 *
691
-	 * Copy a file on webdav server
692
-	 * Duplicates a file on the webdav server (serverside).
693
-	 * All work is done on the webdav server. If you set param overwrite as true,
694
-	 * the target will be overwritten.
695
-	 *
696
-	 * @param string $src_path  Source path
697
-	 * @param string $dest_path Destination path
698
-	 * @param bool   $overwrite Overwrite if file exists in $dst_path
699
-	 * @param mixed  $dst_path
700
-	 *
701
-	 * @throws BackendException if request is not successful
702
-	 *
703
-	 * @return bool true if action succeeded
704
-	 */
705
-	public function copy_file($src_path, $dst_path, $overwrite = false) {
706
-		return $this->copy($src_path, $dst_path, $overwrite, false);
707
-	}
708
-
709
-	/**
710
-	 * Public method copy_coll.
711
-	 *
712
-	 * Copy a collection on webdav server
713
-	 * Duplicates a collection on the webdav server (serverside).
714
-	 * All work is done on the webdav server. If you set param overwrite as true,
715
-	 * the target will be overwritten.
716
-	 *
717
-	 * @param string $src_path  Source path
718
-	 * @param string $dest_path Destination path
719
-	 * @param bool   $overwrite Overwrite if collection exists in $dst_path
720
-	 * @param mixed  $dst_path
721
-	 *
722
-	 * @throws BackendException if request is not successful
723
-	 *
724
-	 * @return bool true if action succeeded
725
-	 */
726
-	public function copy_coll($src_path, $dst_path, $overwrite = false) {
727
-		return $this->copy($src_path, $dst_path, $overwrite, true);
728
-	}
729
-
730
-	/**
731
-	 * Gets path information from webdav server for one element.
732
-	 *
733
-	 * @param string $path Path to file or folder
734
-	 *
735
-	 * @throws BackendException if request is not successful
736
-	 *
737
-	 * @return array directory info
738
-	 */
739
-	public function gpi($path) {
740
-		$path = $this->removeSlash($path);
741
-		$response = $this->sabre_client->propFind($path, [
742
-			'{http://owncloud.org/ns}fileid',
743
-			'{DAV:}resourcetype',
744
-			'{DAV:}getcontentlength',
745
-			'{DAV:}getlastmodified',
746
-			'{DAV:}getcontenttype',
747
-			'{DAV:}quota-used-bytes',
748
-			'{DAV:}quota-available-bytes',
749
-		]);
750
-
751
-		$type = $response["{DAV:}resourcetype"]->resourceType;
752
-		if (is_array($type) && !empty($type)) {
753
-			$type = $type[0] == "{DAV:}collection" ? "collection" : "file";
754
-		}
755
-		else {
756
-			$type = "file"; // fall back to file if detection fails... less harmful
757
-		}
758
-
759
-		return [
760
-			"fileid" => isset($response["{http://owncloud.org/ns}fileid"]) ? $response["{http://owncloud.org/ns}fileid"] : '-1',
761
-			"resourcetype" => $type,
762
-			"getcontentlength" => isset($response["{DAV:}getcontentlength"]) ? $response["{DAV:}getcontentlength"] : null,
763
-			"getlastmodified" => isset($response["{DAV:}getlastmodified"]) ? $response["{DAV:}getlastmodified"] : null,
764
-			"getcontenttype" => isset($response["{DAV:}getcontenttype"]) ? $response["{DAV:}getcontenttype"] : null,
765
-			"quota-used-bytes" => isset($response["{DAV:}quota-used-bytes"]) ? $response["{DAV:}quota-used-bytes"] : null,
766
-			"quota-available-bytes" => isset($response["{DAV:}quota-available-bytes"]) ? $response["{DAV:}quota-available-bytes"] : null,
767
-		];
768
-	}
769
-
770
-	/**
771
-	 * Gets server information.
772
-	 *
773
-	 * @throws BackendException if request is not successful
774
-	 *
775
-	 * @return array with all header fields returned from webdav server
776
-	 */
777
-	public function options() {
778
-		$features = $this->sabre_client->options();
779
-
780
-		// be sure it is an array
781
-		if (is_array($features)) {
782
-			return $features;
783
-		}
784
-
785
-		$this->log('[OPTIONS] - ERROR - Error getting server features');
786
-		$e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_FEATURES), self::WD_ERR_FEATURES);
787
-		$e->setTitle($this->backendTransName . _('Not implemented'));
788
-
789
-		throw $e;
790
-	}
791
-
792
-	/**
793
-	 * Gather whether a path points to a file or not.
794
-	 *
795
-	 * @param string $path Path to file or folder
796
-	 *
797
-	 * @return bool true if path points to a file, false otherwise
798
-	 */
799
-	public function is_file($path) {
800
-		$item = $this->gpi($path);
801
-
802
-		return $item === false ? false : ($item['resourcetype'] != 'collection');
803
-	}
804
-
805
-	/**
806
-	 * Gather whether a path points to a directory.
807
-	 *
808
-	 * @param string $path Path to file or folder
809
-	 *
810
-	 * @return bool true if path points to a directory, false otherwise
811
-	 */
812
-	public function is_dir($path) {
813
-		$item = $this->gpi($path);
814
-
815
-		return $item === false ? false : ($item['resourcetype'] == 'collection');
816
-	}
817
-
818
-	/**
819
-	 * check if file/directory exists.
820
-	 *
821
-	 * @param string $path Path to file or folder
822
-	 *
823
-	 * @return bool true if path exists, false otherwise
824
-	 */
825
-	public function exists($path) {
826
-		return $this->is_dir($path) || $this->is_file($path);
827
-	}
828
-
829
-	/**
830
-	 * Copy a collection on webdav server
831
-	 * Duplicates a collection on the webdav server (serverside).
832
-	 * All work is done on the webdav server. If you set param overwrite as true,
833
-	 * the target will be overwritten.
834
-	 *
835
-	 * @param string $src_path  Source path
836
-	 * @param string $dest_path Destination path
837
-	 * @param bool   $overwrite Overwrite if collection exists in $dst_path
838
-	 * @param bool   $coll      set this to true if you want to copy a folder
839
-	 * @param mixed  $dst_path
840
-	 *
841
-	 * @throws BackendException if request is not successful
842
-	 *
843
-	 * @return bool true if action succeeded
844
-	 */
845
-	private function copy($src_path, $dst_path, $overwrite, $coll) {
846
-		$time_start = microtime(true);
847
-		$src_path = $this->removeSlash($src_path);
848
-		$dst_path = $this->webdavUrl() . $this->removeSlash($dst_path);
849
-		$this->log("[COPY] start for dir: {$src_path} -> {$dst_path}");
850
-		if ($overwrite) {
851
-			$overwrite = 'T';
852
-		}
853
-		else {
854
-			$overwrite = 'F';
855
-		}
856
-
857
-		["Destination" => $dst_path, 'Overwrite' => $overwrite];
858
-		if ($coll) {
859
-			$settings = ["Destination" => $dst_path, 'Depth' => 'Infinity'];
860
-		}
861
-
862
-		try {
863
-			$response = $this->sabre_client->request("COPY", $src_path, null, $settings);
864
-			$time_end = microtime(true);
865
-			$time = $time_end - $time_start;
866
-			$this->log("[COPY] done in {$time} seconds: " . $response['statusCode']);
867
-
868
-			return true;
869
-		}
870
-		catch (ClientException $e) {
871
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
872
-			$e->setTitle($this->backendTransName . _('Sabre error'));
873
-
874
-			throw $e;
875
-		}
876
-		catch (Exception $e) {
877
-			$this->log('[COPY] - FATAL - ' . $e->getMessage());
878
-			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
879
-			$e->setTitle($this->backendTransName . _('Copying failed'));
880
-
881
-			throw $e;
882
-		}
883
-	}
884
-
885
-	/**
886
-	 * Create the base webdav url.
887
-	 *
888
-	 * @return string baseURL
889
-	 */
890
-	protected function webdavUrl() {
891
-		if ($this->ssl) {
892
-			$url = "https://";
893
-		}
894
-		else {
895
-			$url = "http://";
896
-		}
897
-
898
-		// make sure that we do not have any trailing / in our url
899
-		$server = rtrim($this->server, '/');
900
-		$path = rtrim($this->path, '/');
901
-
902
-		$url .= $server . ":" . $this->port . $path . "/";
903
-
904
-		return $url;
905
-	}
906
-
907
-	/**
908
-	 * Removes the leading slash from the folder path.
909
-	 *
910
-	 * @param string $dir directory path
911
-	 *
912
-	 * @return string trimmed directory path
913
-	 */
914
-	public function removeSlash($dir) {
915
-		if (strpos($dir, '/') === 0) {
916
-			$dir = substr($dir, 1);
917
-		}
918
-
919
-		// remove all html entities and urlencode the path...
920
-		$nohtml = html_entity_decode($dir);
921
-
922
-		return implode("/", array_map("rawurlencode", explode("/", $nohtml)));
923
-	}
924
-
925
-	/**
926
-	 * This function will return a user friendly error string.
927
-	 *
928
-	 * @param number $error_code A error code
929
-	 *
930
-	 * @return string userfriendly error message
931
-	 */
932
-	private function parseErrorCodeToMessage($error_code) {
933
-		$error = intval($error_code);
934
-
935
-		$msg = _('Unknown error');
936
-		$contactAdmin = _('Please contact your system administrator');
937
-
938
-		switch ($error) {
939
-			case CURLE_BAD_PASSWORD_ENTERED:
940
-			case self::WD_ERR_UNAUTHORIZED:
941
-				$msg = _('Unauthorized. Wrong username or password.');
942
-				break;
943
-
944
-			case CURLE_SSL_CONNECT_ERROR:
945
-			case CURLE_COULDNT_RESOLVE_HOST:
946
-			case CURLE_COULDNT_CONNECT:
947
-			case CURLE_OPERATION_TIMEOUTED:
948
-			case self::WD_ERR_UNREACHABLE:
949
-				$msg = _('File server is not reachable. Please verify the connection.');
950
-				break;
951
-
952
-			case self::WD_ERR_NOTALLOWED:
953
-				$msg = _('File server is not reachable. Please verify the file server URL.');
954
-				break;
955
-
956
-			case self::WD_ERR_FORBIDDEN:
957
-				$msg = _('You don\'t have enough permissions to view this file or folder.');
958
-				break;
959
-
960
-			case self::WD_ERR_NOTFOUND:
961
-				$msg = _('The file or folder is not available anymore.');
962
-				break;
963
-
964
-			case self::WD_ERR_TIMEOUT:
965
-				$msg = _('Connection to the file server timed out. Please check again later.');
966
-				break;
967
-
968
-			case self::WD_ERR_LOCKED:
969
-				$msg = _('This file is locked by another user. Please try again later.');
970
-				break;
971
-
972
-			case self::WD_ERR_FAILED_DEPENDENCY:
973
-				$msg = _('The request failed.') . ' ' . $contactAdmin;
974
-				break;
975
-
976
-			case self::WD_ERR_INTERNAL:
977
-				// This is a general error, might be thrown due to a wrong IP, but we don't know.
978
-				$msg = _('The file server encountered an internal problem.') . ' ' . $contactAdmin;
979
-				break;
980
-
981
-			case self::WD_ERR_TMP:
982
-				$msg = _('We could not write to temporary directory.') . ' ' . $contactAdmin;
983
-				break;
984
-
985
-			case self::WD_ERR_FEATURES:
986
-				$msg = _('We could not retrieve list of server features.') . ' ' . $contactAdmin;
987
-				break;
988
-
989
-			case self::WD_ERR_NO_CURL:
990
-				$msg = _('PHP-Curl is not available.') . ' ' . $contactAdmin;
991
-				break;
992
-		}
993
-
994
-		return $msg;
995
-	}
996
-
997
-	public function getFormConfig() {
998
-		$json = json_encode($this->metaConfig);
999
-
1000
-		if ($json === false) {
1001
-			error_log(json_last_error());
1002
-		}
1003
-
1004
-		return $json;
1005
-	}
1006
-
1007
-	public function getFormConfigWithData() {
1008
-		return json_encode($this->metaConfig);
1009
-	}
1010
-
1011
-	/**
1012
-	 * a simple php error_log wrapper.
1013
-	 *
1014
-	 * @param string $err_string error message
1015
-	 */
1016
-	private function log($err_string) {
1017
-		if ($this->debug) {
1018
-			error_log("[BACKEND_WEBDAV]: " . $err_string);
1019
-		}
1020
-	}
1021
-
1022
-	/**
1023
-	 * ============================ FEATURE FUNCTIONS ========================.
1024
-	 *
1025
-	 * @param mixed $dir
1026
-	 */
1027
-
1028
-	/**
1029
-	 * Returns the bytes that are currently used.
1030
-	 *
1031
-	 * @param string $dir directory to check
1032
-	 *
1033
-	 * @return int bytes that are used or -1 on error
1034
-	 */
1035
-	public function getQuotaBytesUsed($dir) {
1036
-		$lsdata = $this->ls($dir, false);
1037
-
1038
-		if (isset($lsdata) && is_array($lsdata)) {
1039
-			return $lsdata[$dir]["quota-used-bytes"];
1040
-		}
1041
-
1042
-		return -1;
1043
-	}
1044
-
1045
-	/**
1046
-	 * Returns the bytes that are currently available.
1047
-	 *
1048
-	 * @param string $dir directory to check
1049
-	 *
1050
-	 * @return int bytes that are available or -1 on error
1051
-	 */
1052
-	public function getQuotaBytesAvailable($dir) {
1053
-		$lsdata = $this->ls($dir, false);
1054
-
1055
-		if (isset($lsdata) && is_array($lsdata)) {
1056
-			return $lsdata[$dir]["quota-available-bytes"];
1057
-		}
1058
-
1059
-		return -1;
1060
-	}
1061
-
1062
-	/**
1063
-	 * Return the version string of the server backend.
1064
-	 *
1065
-	 * @throws BackendException
1066
-	 *
1067
-	 * @return string
1068
-	 */
1069
-	public function getServerVersion() {
1070
-		// check if curl is available
1071
-		$serverHasCurl = function_exists('curl_version');
1072
-		if (!$serverHasCurl) {
1073
-			$e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_NO_CURL), 500);
1074
-			$e->setTitle($this->backendTransName . _('PHP-CURL not installed'));
1075
-
1076
-			throw $e;
1077
-		}
1078
-
1079
-		$webdavurl = $this->webdavUrl();
1080
-
1081
-		$url = substr($webdavurl, 0, strlen($webdavurl) - strlen("remote.php/webdav/")) . "status.php";
1082
-
1083
-		// try to get the contents of the owncloud status page
1084
-		$ch = curl_init();
1085
-		curl_setopt($ch, CURLOPT_AUTOREFERER, true);
1086
-		curl_setopt($ch, CURLOPT_TIMEOUT, 3); // timeout of 3 seconds
1087
-		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1088
-		curl_setopt($ch, CURLOPT_URL, $url);
1089
-		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
1090
-		if ($this->allowselfsigned) {
1091
-			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
1092
-			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
1093
-		}
1094
-		$versiondata = curl_exec($ch);
1095
-		$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1096
-		curl_close($ch);
1097
-
1098
-		if ($httpcode && $httpcode == "200" && $versiondata) {
1099
-			$versions = json_decode($versiondata);
1100
-			$version = $versions->versionstring;
1101
-		}
1102
-		else {
1103
-			$version = "Undetected (no Owncloud?)";
1104
-		}
1105
-
1106
-		return $version;
1107
-	}
24
+    /**
25
+     * Error codes
26
+     * see @parseErrorCodeToMessage for description.
27
+     */
28
+    public const WD_ERR_UNAUTHORIZED = 401;
29
+    public const WD_ERR_FORBIDDEN = 403;
30
+    public const WD_ERR_NOTFOUND = 404;
31
+    public const WD_ERR_NOTALLOWED = 405;
32
+    public const WD_ERR_TIMEOUT = 408;
33
+    public const WD_ERR_LOCKED = 423;
34
+    public const WD_ERR_FAILED_DEPENDENCY = 423;
35
+    public const WD_ERR_INTERNAL = 500;
36
+    public const WD_ERR_UNREACHABLE = 800;
37
+    public const WD_ERR_TMP = 801;
38
+    public const WD_ERR_FEATURES = 802;
39
+    public const WD_ERR_NO_CURL = 803;
40
+
41
+    /**
42
+     * Configuration data for the extjs metaform.
43
+     */
44
+    protected $formConfig;
45
+    protected $formFields;
46
+    protected $metaConfig;
47
+
48
+    /**
49
+     * @var bool debugging flag, if true, debugging is enabled
50
+     */
51
+    public $debug = false;
52
+
53
+    /**
54
+     * @var int webdav server port
55
+     */
56
+    public $port = 80;
57
+
58
+    /**
59
+     * @var string hostname or ip
60
+     */
61
+    public $server = "localhost";
62
+
63
+    /**
64
+     * @var string global path prefix for all requests
65
+     */
66
+    public $path = "/webdav.php";
67
+
68
+    /**
69
+     * @var bool if true, ssl is used
70
+     */
71
+    public $ssl = false;
72
+
73
+    /**
74
+     * @var bool allow self signed certificates
75
+     */
76
+    public $allowselfsigned = true;
77
+
78
+    /**
79
+     * @var string the username
80
+     */
81
+    public $user = "";
82
+
83
+    /**
84
+     * @var string the password
85
+     */
86
+    public $pass = "";
87
+
88
+    /**
89
+     * @var FilesWebDavClient the SabreDAV client object
90
+     */
91
+    public $sabre_client;
92
+
93
+    /**
94
+     * @constructor
95
+     */
96
+    public function __construct() {
97
+        // initialization
98
+        $this->debug = PLUGIN_FILESBROWSER_LOGLEVEL === "DEBUG" ? true : false;
99
+
100
+        $this->init_form();
101
+
102
+        // set backend description
103
+        $this->backendDescription = _("With this backend, you can connect to any WebDAV server.");
104
+
105
+        // set backend display name
106
+        $this->backendDisplayName = "Webdav";
107
+
108
+        // set backend version
109
+        // TODO: this should be changed on every release
110
+        $this->backendVersion = "3.0";
111
+
112
+        // Backend name used in translations
113
+        $this->backendTransName = _('Files WebDAV Backend: ');
114
+    }
115
+
116
+    /**
117
+     * Initialise form fields.
118
+     */
119
+    private function init_form() {
120
+        $this->formConfig = [
121
+            "labelAlign" => "left",
122
+            "columnCount" => 1,
123
+            "labelWidth" => 80,
124
+            "defaults" => [
125
+                "width" => 292,
126
+            ],
127
+        ];
128
+
129
+        $this->formFields = [
130
+            [
131
+                "name" => "server_address",
132
+                "fieldLabel" => _('Server address'),
133
+                "editor" => [
134
+                    "allowBlank" => false,
135
+                ],
136
+            ],
137
+            [
138
+                "name" => "server_port",
139
+                "fieldLabel" => _('Server port'),
140
+                "editor" => [
141
+                    "ref" => "../../portField",
142
+                    "allowBlank" => false,
143
+                ],
144
+            ],
145
+            [
146
+                "name" => "server_ssl",
147
+                "fieldLabel" => _('Use SSL'),
148
+                "editor" => [
149
+                    "xtype" => "checkbox",
150
+                    "listeners" => [
151
+                        "check" => "Zarafa.plugins.files.data.Actions.onCheckSSL", // this javascript function will be called!
152
+                    ],
153
+                ],
154
+            ],
155
+            [
156
+                "name" => "server_path",
157
+                "fieldLabel" => _('Webdav base path'),
158
+                "editor" => [
159
+                ],
160
+            ],
161
+            [
162
+                "name" => "user",
163
+                "fieldLabel" => _('Username'),
164
+                "editor" => [
165
+                    "ref" => "../../usernameField",
166
+                ],
167
+            ],
168
+            [
169
+                "name" => "password",
170
+                "fieldLabel" => _('Password'),
171
+                "editor" => [
172
+                    "ref" => "../../passwordField",
173
+                    "inputType" => "password",
174
+                ],
175
+            ],
176
+            [
177
+                "name" => "use_grommunio_credentials",
178
+                "fieldLabel" => _('Use grommunio credentials'),
179
+                "editor" => [
180
+                    "xtype" => "checkbox",
181
+                    "listeners" => [
182
+                        "check" => "Zarafa.plugins.files.data.Actions.onCheckCredentials", // this javascript function will be called!
183
+                    ],
184
+                ],
185
+            ],
186
+        ];
187
+
188
+        $this->metaConfig = [
189
+            "success" => true,
190
+            "metaData" => [
191
+                "fields" => $this->formFields,
192
+                "formConfig" => $this->formConfig,
193
+            ],
194
+            "data" => [ // here we can specify the default values.
195
+                "server_address" => "files.demo.com",
196
+                "server_port" => "80",
197
+                "server_path" => "/remote.php/webdav",
198
+            ],
199
+        ];
200
+    }
201
+
202
+    /**
203
+     * Initialize backend from $backend_config array.
204
+     *
205
+     * @param $backend_config
206
+     */
207
+    public function init_backend($backend_config) {
208
+        $this->set_server($backend_config["server_address"]);
209
+        $this->set_port($backend_config["server_port"]);
210
+        $this->set_base($backend_config["server_path"]);
211
+        $this->set_ssl($backend_config["server_ssl"]);
212
+
213
+        // set user and password
214
+        if ($backend_config["use_grommunio_credentials"] === false) {
215
+            $this->set_user($backend_config["user"]);
216
+            $this->set_pass($backend_config["password"]);
217
+        }
218
+        else {
219
+            // For backward compatibility we will check if the Encryption store exists. If not,
220
+            // we will fall back to the old way of retrieving the password from the session.
221
+            if (class_exists('EncryptionStore')) {
222
+                // Get the username and password from the Encryption store
223
+                $encryptionStore = \EncryptionStore::getInstance();
224
+                $this->set_user($encryptionStore->get('username'));
225
+                $this->set_pass($encryptionStore->get('password'));
226
+            }
227
+            else {
228
+                $this->set_user($GLOBALS['mapisession']->getUserName());
229
+                $password = $_SESSION['password'];
230
+                if (function_exists('openssl_decrypt')) {
231
+                    $this->set_pass(openssl_decrypt($password, "des-ede3-cbc", PASSWORD_KEY, 0, PASSWORD_IV));
232
+                }
233
+            }
234
+        }
235
+    }
236
+
237
+    /**
238
+     * Set webdav server. FQN or IP address.
239
+     *
240
+     * @param string $server hostname or ip of the ftp server
241
+     */
242
+    public function set_server($server) {
243
+        $this->server = $server;
244
+    }
245
+
246
+    /**
247
+     * Set base path.
248
+     *
249
+     * @param string $pp the global path prefix
250
+     */
251
+    public function set_base($pp) {
252
+        $this->path = $pp;
253
+        $this->log('Base path set to ' . $this->path);
254
+    }
255
+
256
+    /**
257
+     * Set ssl.
258
+     *
259
+     * @param int /bool $ssl (1 = true, 0 = false)
260
+     */
261
+    public function set_ssl($ssl) {
262
+        $this->ssl = $ssl ? true : false;
263
+        $this->log('SSL extension was set to ' . $this->ssl);
264
+    }
265
+
266
+    /**
267
+     * Allow self signed certificates - unimplemented.
268
+     *
269
+     * @param bool $allowselfsigned Allow self signed certificates. Not yet implemented.
270
+     */
271
+    public function set_selfsigned($allowselfsigned) {
272
+        $this->allowselfsigned = $allowselfsigned;
273
+    }
274
+
275
+    /**
276
+     * Set tcp port of webdav server. Default is 80.
277
+     *
278
+     * @param int $port the port of the ftp server
279
+     */
280
+    public function set_port($port) {
281
+        $this->port = $port;
282
+    }
283
+
284
+    /**
285
+     * set user name for authentication.
286
+     *
287
+     * @param string $user username
288
+     */
289
+    public function set_user($user) {
290
+        $this->user = $user;
291
+    }
292
+
293
+    /**
294
+     * Set password for authentication.
295
+     *
296
+     * @param string $pass password
297
+     */
298
+    public function set_pass($pass) {
299
+        $this->pass = $pass;
300
+    }
301
+
302
+    /**
303
+     * set debug on (1) or off (0).
304
+     * produces a lot of debug messages in webservers error log if set to on (1).
305
+     *
306
+     * @param bool $debug enable or disable debugging
307
+     */
308
+    public function set_debug($debug) {
309
+        $this->debug = $debug;
310
+    }
311
+
312
+    /**
313
+     * Opens the connection to the webdav server.
314
+     *
315
+     * @throws BackendException if connection is not successful
316
+     *
317
+     * @return bool true if action succeeded
318
+     */
319
+    public function open() {
320
+        // check if curl is available
321
+        $serverHasCurl = function_exists('curl_version');
322
+        if (!$serverHasCurl) {
323
+            $e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_NO_CURL), 500);
324
+            $e->setTitle($this->backendTransName . _('PHP-CURL is not installed'));
325
+
326
+            throw $e;
327
+        }
328
+
329
+        $davsettings = [
330
+            'baseUri' => $this->webdavUrl(),
331
+            'userName' => $this->user,
332
+            'password' => $this->pass,
333
+            'authType' => \Sabre\DAV\Client::AUTH_BASIC,
334
+        ];
335
+
336
+        try {
337
+            $this->sabre_client = new FilesWebDavClient($davsettings);
338
+            $this->sabre_client->addCurlSetting(CURLOPT_SSL_VERIFYPEER, !$this->allowselfsigned);
339
+
340
+            return true;
341
+        }
342
+        catch (Exception $e) {
343
+            $this->log('Failed to open: ' . $e->getMessage());
344
+            if (intval($e->getHTTPCode()) == 401) {
345
+                $e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_UNAUTHORIZED), $e->getHTTPCode());
346
+                $e->setTitle($this->backendTransName . _('Access denied'));
347
+
348
+                throw $e;
349
+            }
350
+            $e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_UNREACHABLE), $e->getHTTPCode());
351
+            $e->setTitle($this->backendTransName . _('Connection failed'));
352
+
353
+            throw $e;
354
+        }
355
+    }
356
+
357
+    /**
358
+     * show content of a directory.
359
+     *
360
+     * @param string $path      directory path
361
+     * @param bool   $hidefirst Optional parameter to hide the root entry. Default true
362
+     * @param mixed  $dir
363
+     *
364
+     * @throws BackendException if request is not successful
365
+     *
366
+     * @return mixed array with directory content
367
+     */
368
+    public function ls($dir, $hidefirst = true) {
369
+        $time_start = microtime(true);
370
+        $dir = $this->removeSlash($dir);
371
+        $lsdata = [];
372
+        $this->log("[LS] start for dir: {$dir}");
373
+
374
+        try {
375
+            $response = $this->sabre_client->propFind($dir, [
376
+                '{http://owncloud.org/ns}fileid',
377
+                '{DAV:}resourcetype',
378
+                '{DAV:}getcontentlength',
379
+                '{DAV:}getlastmodified',
380
+                '{DAV:}getcontenttype',
381
+                '{DAV:}quota-used-bytes',
382
+                '{DAV:}quota-available-bytes',
383
+            ], 1);
384
+            $this->log("[LS] backend fetched in: " . (microtime(true) - $time_start) . " seconds.");
385
+
386
+            foreach ($response as $name => $fields) {
387
+                if ($hidefirst) {
388
+                    $hidefirst = false; // skip the first line - its the requested dir itself
389
+
390
+                    continue;
391
+                }
392
+
393
+                $name = substr($name, strlen($this->path)); // skip the webdav path
394
+                $name = urldecode($name);
395
+
396
+                // Always fallback to a file resourceType
397
+                $type = "file";
398
+                if (isset($fields['{DAV:}resourcetype'])) {
399
+                    $value = $fields['{DAV:}resourcetype']->getValue();
400
+                    if (!empty($value) && $value[0] === "{DAV:}collection") {
401
+                        $type = "collection";
402
+                    }
403
+                }
404
+
405
+                $lsdata[$name] = [
406
+                    "fileid" => isset($fields["{http://owncloud.org/ns}fileid"]) ? $fields["{http://owncloud.org/ns}fileid"] : '-1',
407
+                    "resourcetype" => $type,
408
+                    "getcontentlength" => isset($fields["{DAV:}getcontentlength"]) ? $fields["{DAV:}getcontentlength"] : null,
409
+                    "getlastmodified" => isset($fields["{DAV:}getlastmodified"]) ? $fields["{DAV:}getlastmodified"] : null,
410
+                    "getcontenttype" => isset($fields["{DAV:}getcontenttype"]) ? $fields["{DAV:}getcontenttype"] : null,
411
+                    "quota-used-bytes" => isset($fields["{DAV:}quota-used-bytes"]) ? $fields["{DAV:}quota-used-bytes"] : null,
412
+                    "quota-available-bytes" => isset($fields["{DAV:}quota-available-bytes"]) ? $fields["{DAV:}quota-available-bytes"] : null,
413
+                ];
414
+            }
415
+            $time_end = microtime(true);
416
+            $time = $time_end - $time_start;
417
+            $this->log("[LS] done in {$time} seconds");
418
+
419
+            return $lsdata;
420
+        }
421
+        catch (ClientException $e) {
422
+            $this->log('ls sabre ClientException: ' . $e->getMessage());
423
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
424
+            $e->setTitle($this->backendTransName . _('Sabre error'));
425
+
426
+            throw $e;
427
+        }
428
+        catch (Exception $e) {
429
+            $this->log('ls general exception: ' . $e->getMessage() . " [" . $e->getHTTPCode() . "]");
430
+            // THIS IS A FIX FOR OWNCLOUD - It does return 500 instead of 401...
431
+            $err_code = $e->getHTTPCode();
432
+            // check if code is 500 - then we should try to parse the error message
433
+            if ($err_code === 500) {
434
+                // message example: HTTP-Code: 401
435
+                $regx = '/[0-9]{3}/';
436
+                if (preg_match($regx, $e->getMessage(), $found)) {
437
+                    $err_code = $found[0];
438
+                }
439
+            }
440
+            $e = new BackendException($this->parseErrorCodeToMessage($err_code), $err_code);
441
+            $e->setTitle($this->backendTransName . _('Connection failed'));
442
+
443
+            throw $e;
444
+        }
445
+    }
446
+
447
+    /**
448
+     * create a new directory.
449
+     *
450
+     * @param string $dir directory path
451
+     *
452
+     * @throws BackendException if request is not successful
453
+     *
454
+     * @return bool true if action succeeded
455
+     */
456
+    public function mkcol($dir) {
457
+        $time_start = microtime(true);
458
+        $dir = $this->removeSlash($dir);
459
+        $this->log("[MKCOL] start for dir: {$dir}");
460
+
461
+        try {
462
+            $response = $this->sabre_client->request("MKCOL", $dir, null);
463
+            $time_end = microtime(true);
464
+            $time = $time_end - $time_start;
465
+            $this->log("[MKCOL] done in {$time} seconds: " . $response['statusCode']);
466
+
467
+            return true;
468
+        }
469
+        catch (ClientException $e) {
470
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
471
+            $e->setTitle($this->backendTransName . _('Sabre error'));
472
+
473
+            throw $e;
474
+        }
475
+        catch (Exception $e) {
476
+            $this->log('[MKCOL] fatal: ' . $e->getMessage());
477
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
478
+            $e->setTitle($this->backendTransName . _('Directory creation failed'));
479
+
480
+            throw $e;
481
+        }
482
+    }
483
+
484
+    /**
485
+     * delete a file or directory.
486
+     *
487
+     * @param string $path file/directory path
488
+     *
489
+     * @throws BackendException if request is not successful
490
+     *
491
+     * @return bool true if action succeeded
492
+     */
493
+    public function delete($path) {
494
+        $time_start = microtime(true);
495
+        $path = $this->removeSlash($path);
496
+        $this->log("[DELETE] start for dir: {$path}");
497
+
498
+        try {
499
+            $response = $this->sabre_client->request("DELETE", $path, null);
500
+            $time_end = microtime(true);
501
+            $time = $time_end - $time_start;
502
+            $this->log("[DELETE] done in {$time} seconds: " . $response['statusCode']);
503
+
504
+            return true;
505
+        }
506
+        catch (ClientException $e) {
507
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
508
+            $e->setTitle($this->backendTransName . _('Sabre error'));
509
+
510
+            throw $e;
511
+        }
512
+        catch (Exception $e) {
513
+            $this->log('[DELETE] fatal: ' . $e->getMessage());
514
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
515
+            $e->setTitle($this->backendTransName . _('Deletion failed'));
516
+
517
+            throw $e;
518
+        }
519
+    }
520
+
521
+    /**
522
+     * Move a file or collection on webdav server (serverside)
523
+     * If you set param overwrite as true, the target will be overwritten.
524
+     *
525
+     * @param string $src_path  Source path
526
+     * @param string $dest_path Destination path
527
+     * @param bool   $overwrite Overwrite file if exists in $dest_path
528
+     * @param mixed  $dst_path
529
+     *
530
+     * @throws BackendException if request is not successful
531
+     *
532
+     * @return bool true if action succeeded
533
+     */
534
+    public function move($src_path, $dst_path, $overwrite = false) {
535
+        $time_start = microtime(true);
536
+        $src_path = $this->removeSlash($src_path);
537
+        $dst_path = $this->webdavUrl() . $this->removeSlash($dst_path);
538
+        $this->log("[MOVE] start for dir: {$src_path} -> {$dst_path}");
539
+        if ($overwrite) {
540
+            $overwrite = 'T';
541
+        }
542
+        else {
543
+            $overwrite = 'F';
544
+        }
545
+
546
+        try {
547
+            $response = $this->sabre_client->request("MOVE", $src_path, null, ["Destination" => $dst_path, 'Overwrite' => $overwrite]);
548
+            $time_end = microtime(true);
549
+            $time = $time_end - $time_start;
550
+            $this->log("[MOVE] done in {$time} seconds: " . $response['statusCode']);
551
+
552
+            return true;
553
+        }
554
+        catch (ClientException $e) {
555
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
556
+            $e->setTitle($this->backendTransName . _('Sabre error'));
557
+
558
+            throw $e;
559
+        }
560
+        catch (Exception $e) {
561
+            $this->log('[MOVE] fatal: ' . $e->getMessage());
562
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
563
+            $e->setTitle($this->backendTransName . _('Moving failed'));
564
+
565
+            throw $e;
566
+        }
567
+    }
568
+
569
+    /**
570
+     * Puts a file into a collection.
571
+     *
572
+     * @param string $path Destination path
573
+     * @param mixed  $data
574
+     *
575
+     * @string mixed $data Any kind of data
576
+     *
577
+     * @throws BackendException if request is not successful
578
+     *
579
+     * @return bool true if action succeeded
580
+     */
581
+    public function put($path, $data) {
582
+        $time_start = microtime(true);
583
+        $path = $this->removeSlash($path);
584
+        $this->log("[PUT] start for dir: {$path} strlen: " . strlen($data));
585
+
586
+        try {
587
+            $response = $this->sabre_client->request("PUT", $path, $data);
588
+            $time_end = microtime(true);
589
+            $time = $time_end - $time_start;
590
+            $this->log("[PUT] done in {$time} seconds: " . $response['statusCode']);
591
+
592
+            return true;
593
+        }
594
+        catch (ClientException $e) {
595
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
596
+            $e->setTitle($this->backendTransName . _('Sabre error'));
597
+
598
+            throw $e;
599
+        }
600
+        catch (Exception $e) {
601
+            $this->log('[PUT] fatal: ' . $e->getMessage());
602
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
603
+            $e->setTitle($this->backendTransName . _('Connection failed'));
604
+
605
+            throw $e;
606
+        }
607
+    }
608
+
609
+    /**
610
+     * Upload a local file.
611
+     *
612
+     * @param string $path     Destination path on the server
613
+     * @param string $filename Local filename for the file that should be uploaded
614
+     *
615
+     * @throws BackendException if request is not successful
616
+     *
617
+     * @return bool true if action succeeded
618
+     */
619
+    public function put_file($path, $filename) {
620
+        $buffer = file_get_contents($filename);
621
+
622
+        if ($buffer !== false) {
623
+            return $this->put($path, $buffer);
624
+        }
625
+        $e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_TMP), self::WD_ERR_TMP);
626
+        $e->setTitle($this->backendTransName . _('Temporary directory problems'));
627
+
628
+        throw $e;
629
+    }
630
+
631
+    /**
632
+     * Gets a file from a webdav collection.
633
+     *
634
+     * @param string $path   The source path on the server
635
+     * @param mixed  $buffer Buffer for the received data
636
+     *
637
+     * @throws BackendException if request is not successful
638
+     *
639
+     * @return bool true if action succeeded
640
+     */
641
+    public function get($path, &$buffer) {
642
+        $tmpfile = tempnam(TMP_PATH, stripslashes(base64_encode($path)));
643
+
644
+        $this->log("[GET] buffer path: {$tmpfile}");
645
+        $this->get_file($path, $tmpfile);
646
+
647
+        $buffer = file_get_contents($tmpfile);
648
+        unlink($tmpfile);
649
+    }
650
+
651
+    /**
652
+     * Gets a file from a collection into local filesystem.
653
+     *
654
+     * @param string $srcpath   Source path on server
655
+     * @param string $localpath Destination path on local filesystem
656
+     *
657
+     * @throws BackendException if request is not successful
658
+     *
659
+     * @return bool true if action succeeded
660
+     */
661
+    public function get_file($srcpath, $localpath) {
662
+        $time_start = microtime(true);
663
+        $path = $this->removeSlash($srcpath);
664
+        $this->log("[GET_FILE] start for dir: {$path}");
665
+        $this->log("[GET_FILE] local path (" . $localpath . ") writeable: " . is_writable($localpath));
666
+
667
+        try {
668
+            $response = $this->sabre_client->getFile($path, $localpath);
669
+            $time_end = microtime(true);
670
+            $time = $time_end - $time_start;
671
+            $this->log("[GET_FILE] done in {$time} seconds: " . $response['statusCode']);
672
+        }
673
+        catch (ClientException $e) {
674
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
675
+            $e->setTitle($this->backendTransName . _('Sabre error'));
676
+
677
+            throw $e;
678
+        }
679
+        catch (Exception $e) {
680
+            $this->log('[GET_FILE] - FATAL -' . $e->getMessage());
681
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
682
+            $e->setTitle($this->backendTransName . _('File or folder not found'));
683
+
684
+            throw $e;
685
+        }
686
+    }
687
+
688
+    /**
689
+     * Public method copy_file.
690
+     *
691
+     * Copy a file on webdav server
692
+     * Duplicates a file on the webdav server (serverside).
693
+     * All work is done on the webdav server. If you set param overwrite as true,
694
+     * the target will be overwritten.
695
+     *
696
+     * @param string $src_path  Source path
697
+     * @param string $dest_path Destination path
698
+     * @param bool   $overwrite Overwrite if file exists in $dst_path
699
+     * @param mixed  $dst_path
700
+     *
701
+     * @throws BackendException if request is not successful
702
+     *
703
+     * @return bool true if action succeeded
704
+     */
705
+    public function copy_file($src_path, $dst_path, $overwrite = false) {
706
+        return $this->copy($src_path, $dst_path, $overwrite, false);
707
+    }
708
+
709
+    /**
710
+     * Public method copy_coll.
711
+     *
712
+     * Copy a collection on webdav server
713
+     * Duplicates a collection on the webdav server (serverside).
714
+     * All work is done on the webdav server. If you set param overwrite as true,
715
+     * the target will be overwritten.
716
+     *
717
+     * @param string $src_path  Source path
718
+     * @param string $dest_path Destination path
719
+     * @param bool   $overwrite Overwrite if collection exists in $dst_path
720
+     * @param mixed  $dst_path
721
+     *
722
+     * @throws BackendException if request is not successful
723
+     *
724
+     * @return bool true if action succeeded
725
+     */
726
+    public function copy_coll($src_path, $dst_path, $overwrite = false) {
727
+        return $this->copy($src_path, $dst_path, $overwrite, true);
728
+    }
729
+
730
+    /**
731
+     * Gets path information from webdav server for one element.
732
+     *
733
+     * @param string $path Path to file or folder
734
+     *
735
+     * @throws BackendException if request is not successful
736
+     *
737
+     * @return array directory info
738
+     */
739
+    public function gpi($path) {
740
+        $path = $this->removeSlash($path);
741
+        $response = $this->sabre_client->propFind($path, [
742
+            '{http://owncloud.org/ns}fileid',
743
+            '{DAV:}resourcetype',
744
+            '{DAV:}getcontentlength',
745
+            '{DAV:}getlastmodified',
746
+            '{DAV:}getcontenttype',
747
+            '{DAV:}quota-used-bytes',
748
+            '{DAV:}quota-available-bytes',
749
+        ]);
750
+
751
+        $type = $response["{DAV:}resourcetype"]->resourceType;
752
+        if (is_array($type) && !empty($type)) {
753
+            $type = $type[0] == "{DAV:}collection" ? "collection" : "file";
754
+        }
755
+        else {
756
+            $type = "file"; // fall back to file if detection fails... less harmful
757
+        }
758
+
759
+        return [
760
+            "fileid" => isset($response["{http://owncloud.org/ns}fileid"]) ? $response["{http://owncloud.org/ns}fileid"] : '-1',
761
+            "resourcetype" => $type,
762
+            "getcontentlength" => isset($response["{DAV:}getcontentlength"]) ? $response["{DAV:}getcontentlength"] : null,
763
+            "getlastmodified" => isset($response["{DAV:}getlastmodified"]) ? $response["{DAV:}getlastmodified"] : null,
764
+            "getcontenttype" => isset($response["{DAV:}getcontenttype"]) ? $response["{DAV:}getcontenttype"] : null,
765
+            "quota-used-bytes" => isset($response["{DAV:}quota-used-bytes"]) ? $response["{DAV:}quota-used-bytes"] : null,
766
+            "quota-available-bytes" => isset($response["{DAV:}quota-available-bytes"]) ? $response["{DAV:}quota-available-bytes"] : null,
767
+        ];
768
+    }
769
+
770
+    /**
771
+     * Gets server information.
772
+     *
773
+     * @throws BackendException if request is not successful
774
+     *
775
+     * @return array with all header fields returned from webdav server
776
+     */
777
+    public function options() {
778
+        $features = $this->sabre_client->options();
779
+
780
+        // be sure it is an array
781
+        if (is_array($features)) {
782
+            return $features;
783
+        }
784
+
785
+        $this->log('[OPTIONS] - ERROR - Error getting server features');
786
+        $e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_FEATURES), self::WD_ERR_FEATURES);
787
+        $e->setTitle($this->backendTransName . _('Not implemented'));
788
+
789
+        throw $e;
790
+    }
791
+
792
+    /**
793
+     * Gather whether a path points to a file or not.
794
+     *
795
+     * @param string $path Path to file or folder
796
+     *
797
+     * @return bool true if path points to a file, false otherwise
798
+     */
799
+    public function is_file($path) {
800
+        $item = $this->gpi($path);
801
+
802
+        return $item === false ? false : ($item['resourcetype'] != 'collection');
803
+    }
804
+
805
+    /**
806
+     * Gather whether a path points to a directory.
807
+     *
808
+     * @param string $path Path to file or folder
809
+     *
810
+     * @return bool true if path points to a directory, false otherwise
811
+     */
812
+    public function is_dir($path) {
813
+        $item = $this->gpi($path);
814
+
815
+        return $item === false ? false : ($item['resourcetype'] == 'collection');
816
+    }
817
+
818
+    /**
819
+     * check if file/directory exists.
820
+     *
821
+     * @param string $path Path to file or folder
822
+     *
823
+     * @return bool true if path exists, false otherwise
824
+     */
825
+    public function exists($path) {
826
+        return $this->is_dir($path) || $this->is_file($path);
827
+    }
828
+
829
+    /**
830
+     * Copy a collection on webdav server
831
+     * Duplicates a collection on the webdav server (serverside).
832
+     * All work is done on the webdav server. If you set param overwrite as true,
833
+     * the target will be overwritten.
834
+     *
835
+     * @param string $src_path  Source path
836
+     * @param string $dest_path Destination path
837
+     * @param bool   $overwrite Overwrite if collection exists in $dst_path
838
+     * @param bool   $coll      set this to true if you want to copy a folder
839
+     * @param mixed  $dst_path
840
+     *
841
+     * @throws BackendException if request is not successful
842
+     *
843
+     * @return bool true if action succeeded
844
+     */
845
+    private function copy($src_path, $dst_path, $overwrite, $coll) {
846
+        $time_start = microtime(true);
847
+        $src_path = $this->removeSlash($src_path);
848
+        $dst_path = $this->webdavUrl() . $this->removeSlash($dst_path);
849
+        $this->log("[COPY] start for dir: {$src_path} -> {$dst_path}");
850
+        if ($overwrite) {
851
+            $overwrite = 'T';
852
+        }
853
+        else {
854
+            $overwrite = 'F';
855
+        }
856
+
857
+        ["Destination" => $dst_path, 'Overwrite' => $overwrite];
858
+        if ($coll) {
859
+            $settings = ["Destination" => $dst_path, 'Depth' => 'Infinity'];
860
+        }
861
+
862
+        try {
863
+            $response = $this->sabre_client->request("COPY", $src_path, null, $settings);
864
+            $time_end = microtime(true);
865
+            $time = $time_end - $time_start;
866
+            $this->log("[COPY] done in {$time} seconds: " . $response['statusCode']);
867
+
868
+            return true;
869
+        }
870
+        catch (ClientException $e) {
871
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
872
+            $e->setTitle($this->backendTransName . _('Sabre error'));
873
+
874
+            throw $e;
875
+        }
876
+        catch (Exception $e) {
877
+            $this->log('[COPY] - FATAL - ' . $e->getMessage());
878
+            $e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
879
+            $e->setTitle($this->backendTransName . _('Copying failed'));
880
+
881
+            throw $e;
882
+        }
883
+    }
884
+
885
+    /**
886
+     * Create the base webdav url.
887
+     *
888
+     * @return string baseURL
889
+     */
890
+    protected function webdavUrl() {
891
+        if ($this->ssl) {
892
+            $url = "https://";
893
+        }
894
+        else {
895
+            $url = "http://";
896
+        }
897
+
898
+        // make sure that we do not have any trailing / in our url
899
+        $server = rtrim($this->server, '/');
900
+        $path = rtrim($this->path, '/');
901
+
902
+        $url .= $server . ":" . $this->port . $path . "/";
903
+
904
+        return $url;
905
+    }
906
+
907
+    /**
908
+     * Removes the leading slash from the folder path.
909
+     *
910
+     * @param string $dir directory path
911
+     *
912
+     * @return string trimmed directory path
913
+     */
914
+    public function removeSlash($dir) {
915
+        if (strpos($dir, '/') === 0) {
916
+            $dir = substr($dir, 1);
917
+        }
918
+
919
+        // remove all html entities and urlencode the path...
920
+        $nohtml = html_entity_decode($dir);
921
+
922
+        return implode("/", array_map("rawurlencode", explode("/", $nohtml)));
923
+    }
924
+
925
+    /**
926
+     * This function will return a user friendly error string.
927
+     *
928
+     * @param number $error_code A error code
929
+     *
930
+     * @return string userfriendly error message
931
+     */
932
+    private function parseErrorCodeToMessage($error_code) {
933
+        $error = intval($error_code);
934
+
935
+        $msg = _('Unknown error');
936
+        $contactAdmin = _('Please contact your system administrator');
937
+
938
+        switch ($error) {
939
+            case CURLE_BAD_PASSWORD_ENTERED:
940
+            case self::WD_ERR_UNAUTHORIZED:
941
+                $msg = _('Unauthorized. Wrong username or password.');
942
+                break;
943
+
944
+            case CURLE_SSL_CONNECT_ERROR:
945
+            case CURLE_COULDNT_RESOLVE_HOST:
946
+            case CURLE_COULDNT_CONNECT:
947
+            case CURLE_OPERATION_TIMEOUTED:
948
+            case self::WD_ERR_UNREACHABLE:
949
+                $msg = _('File server is not reachable. Please verify the connection.');
950
+                break;
951
+
952
+            case self::WD_ERR_NOTALLOWED:
953
+                $msg = _('File server is not reachable. Please verify the file server URL.');
954
+                break;
955
+
956
+            case self::WD_ERR_FORBIDDEN:
957
+                $msg = _('You don\'t have enough permissions to view this file or folder.');
958
+                break;
959
+
960
+            case self::WD_ERR_NOTFOUND:
961
+                $msg = _('The file or folder is not available anymore.');
962
+                break;
963
+
964
+            case self::WD_ERR_TIMEOUT:
965
+                $msg = _('Connection to the file server timed out. Please check again later.');
966
+                break;
967
+
968
+            case self::WD_ERR_LOCKED:
969
+                $msg = _('This file is locked by another user. Please try again later.');
970
+                break;
971
+
972
+            case self::WD_ERR_FAILED_DEPENDENCY:
973
+                $msg = _('The request failed.') . ' ' . $contactAdmin;
974
+                break;
975
+
976
+            case self::WD_ERR_INTERNAL:
977
+                // This is a general error, might be thrown due to a wrong IP, but we don't know.
978
+                $msg = _('The file server encountered an internal problem.') . ' ' . $contactAdmin;
979
+                break;
980
+
981
+            case self::WD_ERR_TMP:
982
+                $msg = _('We could not write to temporary directory.') . ' ' . $contactAdmin;
983
+                break;
984
+
985
+            case self::WD_ERR_FEATURES:
986
+                $msg = _('We could not retrieve list of server features.') . ' ' . $contactAdmin;
987
+                break;
988
+
989
+            case self::WD_ERR_NO_CURL:
990
+                $msg = _('PHP-Curl is not available.') . ' ' . $contactAdmin;
991
+                break;
992
+        }
993
+
994
+        return $msg;
995
+    }
996
+
997
+    public function getFormConfig() {
998
+        $json = json_encode($this->metaConfig);
999
+
1000
+        if ($json === false) {
1001
+            error_log(json_last_error());
1002
+        }
1003
+
1004
+        return $json;
1005
+    }
1006
+
1007
+    public function getFormConfigWithData() {
1008
+        return json_encode($this->metaConfig);
1009
+    }
1010
+
1011
+    /**
1012
+     * a simple php error_log wrapper.
1013
+     *
1014
+     * @param string $err_string error message
1015
+     */
1016
+    private function log($err_string) {
1017
+        if ($this->debug) {
1018
+            error_log("[BACKEND_WEBDAV]: " . $err_string);
1019
+        }
1020
+    }
1021
+
1022
+    /**
1023
+     * ============================ FEATURE FUNCTIONS ========================.
1024
+     *
1025
+     * @param mixed $dir
1026
+     */
1027
+
1028
+    /**
1029
+     * Returns the bytes that are currently used.
1030
+     *
1031
+     * @param string $dir directory to check
1032
+     *
1033
+     * @return int bytes that are used or -1 on error
1034
+     */
1035
+    public function getQuotaBytesUsed($dir) {
1036
+        $lsdata = $this->ls($dir, false);
1037
+
1038
+        if (isset($lsdata) && is_array($lsdata)) {
1039
+            return $lsdata[$dir]["quota-used-bytes"];
1040
+        }
1041
+
1042
+        return -1;
1043
+    }
1044
+
1045
+    /**
1046
+     * Returns the bytes that are currently available.
1047
+     *
1048
+     * @param string $dir directory to check
1049
+     *
1050
+     * @return int bytes that are available or -1 on error
1051
+     */
1052
+    public function getQuotaBytesAvailable($dir) {
1053
+        $lsdata = $this->ls($dir, false);
1054
+
1055
+        if (isset($lsdata) && is_array($lsdata)) {
1056
+            return $lsdata[$dir]["quota-available-bytes"];
1057
+        }
1058
+
1059
+        return -1;
1060
+    }
1061
+
1062
+    /**
1063
+     * Return the version string of the server backend.
1064
+     *
1065
+     * @throws BackendException
1066
+     *
1067
+     * @return string
1068
+     */
1069
+    public function getServerVersion() {
1070
+        // check if curl is available
1071
+        $serverHasCurl = function_exists('curl_version');
1072
+        if (!$serverHasCurl) {
1073
+            $e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_NO_CURL), 500);
1074
+            $e->setTitle($this->backendTransName . _('PHP-CURL not installed'));
1075
+
1076
+            throw $e;
1077
+        }
1078
+
1079
+        $webdavurl = $this->webdavUrl();
1080
+
1081
+        $url = substr($webdavurl, 0, strlen($webdavurl) - strlen("remote.php/webdav/")) . "status.php";
1082
+
1083
+        // try to get the contents of the owncloud status page
1084
+        $ch = curl_init();
1085
+        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
1086
+        curl_setopt($ch, CURLOPT_TIMEOUT, 3); // timeout of 3 seconds
1087
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1088
+        curl_setopt($ch, CURLOPT_URL, $url);
1089
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
1090
+        if ($this->allowselfsigned) {
1091
+            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
1092
+            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
1093
+        }
1094
+        $versiondata = curl_exec($ch);
1095
+        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1096
+        curl_close($ch);
1097
+
1098
+        if ($httpcode && $httpcode == "200" && $versiondata) {
1099
+            $versions = json_decode($versiondata);
1100
+            $version = $versions->versionstring;
1101
+        }
1102
+        else {
1103
+            $version = "Undetected (no Owncloud?)";
1104
+        }
1105
+
1106
+        return $version;
1107
+    }
1108 1108
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -191,7 +191,7 @@
 block discarded – undo
191 191
 				"fields" => $this->formFields,
192 192
 				"formConfig" => $this->formConfig,
193 193
 			],
194
-			"data" => [ // here we can specify the default values.
194
+			"data" => [// here we can specify the default values.
195 195
 				"server_address" => "files.demo.com",
196 196
 				"server_port" => "80",
197 197
 				"server_path" => "/remote.php/webdav",
Please login to merge, or discard this patch.
Braces   +22 added lines, -44 removed lines patch added patch discarded remove patch
@@ -214,8 +214,7 @@  discard block
 block discarded – undo
214 214
 		if ($backend_config["use_grommunio_credentials"] === false) {
215 215
 			$this->set_user($backend_config["user"]);
216 216
 			$this->set_pass($backend_config["password"]);
217
-		}
218
-		else {
217
+		} else {
219 218
 			// For backward compatibility we will check if the Encryption store exists. If not,
220 219
 			// we will fall back to the old way of retrieving the password from the session.
221 220
 			if (class_exists('EncryptionStore')) {
@@ -223,8 +222,7 @@  discard block
 block discarded – undo
223 222
 				$encryptionStore = \EncryptionStore::getInstance();
224 223
 				$this->set_user($encryptionStore->get('username'));
225 224
 				$this->set_pass($encryptionStore->get('password'));
226
-			}
227
-			else {
225
+			} else {
228 226
 				$this->set_user($GLOBALS['mapisession']->getUserName());
229 227
 				$password = $_SESSION['password'];
230 228
 				if (function_exists('openssl_decrypt')) {
@@ -338,8 +336,7 @@  discard block
 block discarded – undo
338 336
 			$this->sabre_client->addCurlSetting(CURLOPT_SSL_VERIFYPEER, !$this->allowselfsigned);
339 337
 
340 338
 			return true;
341
-		}
342
-		catch (Exception $e) {
339
+		} catch (Exception $e) {
343 340
 			$this->log('Failed to open: ' . $e->getMessage());
344 341
 			if (intval($e->getHTTPCode()) == 401) {
345 342
 				$e = new BackendException($this->parseErrorCodeToMessage(self::WD_ERR_UNAUTHORIZED), $e->getHTTPCode());
@@ -417,15 +414,13 @@  discard block
 block discarded – undo
417 414
 			$this->log("[LS] done in {$time} seconds");
418 415
 
419 416
 			return $lsdata;
420
-		}
421
-		catch (ClientException $e) {
417
+		} catch (ClientException $e) {
422 418
 			$this->log('ls sabre ClientException: ' . $e->getMessage());
423 419
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
424 420
 			$e->setTitle($this->backendTransName . _('Sabre error'));
425 421
 
426 422
 			throw $e;
427
-		}
428
-		catch (Exception $e) {
423
+		} catch (Exception $e) {
429 424
 			$this->log('ls general exception: ' . $e->getMessage() . " [" . $e->getHTTPCode() . "]");
430 425
 			// THIS IS A FIX FOR OWNCLOUD - It does return 500 instead of 401...
431 426
 			$err_code = $e->getHTTPCode();
@@ -465,14 +460,12 @@  discard block
 block discarded – undo
465 460
 			$this->log("[MKCOL] done in {$time} seconds: " . $response['statusCode']);
466 461
 
467 462
 			return true;
468
-		}
469
-		catch (ClientException $e) {
463
+		} catch (ClientException $e) {
470 464
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
471 465
 			$e->setTitle($this->backendTransName . _('Sabre error'));
472 466
 
473 467
 			throw $e;
474
-		}
475
-		catch (Exception $e) {
468
+		} catch (Exception $e) {
476 469
 			$this->log('[MKCOL] fatal: ' . $e->getMessage());
477 470
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
478 471
 			$e->setTitle($this->backendTransName . _('Directory creation failed'));
@@ -502,14 +495,12 @@  discard block
 block discarded – undo
502 495
 			$this->log("[DELETE] done in {$time} seconds: " . $response['statusCode']);
503 496
 
504 497
 			return true;
505
-		}
506
-		catch (ClientException $e) {
498
+		} catch (ClientException $e) {
507 499
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
508 500
 			$e->setTitle($this->backendTransName . _('Sabre error'));
509 501
 
510 502
 			throw $e;
511
-		}
512
-		catch (Exception $e) {
503
+		} catch (Exception $e) {
513 504
 			$this->log('[DELETE] fatal: ' . $e->getMessage());
514 505
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
515 506
 			$e->setTitle($this->backendTransName . _('Deletion failed'));
@@ -538,8 +529,7 @@  discard block
 block discarded – undo
538 529
 		$this->log("[MOVE] start for dir: {$src_path} -> {$dst_path}");
539 530
 		if ($overwrite) {
540 531
 			$overwrite = 'T';
541
-		}
542
-		else {
532
+		} else {
543 533
 			$overwrite = 'F';
544 534
 		}
545 535
 
@@ -550,14 +540,12 @@  discard block
 block discarded – undo
550 540
 			$this->log("[MOVE] done in {$time} seconds: " . $response['statusCode']);
551 541
 
552 542
 			return true;
553
-		}
554
-		catch (ClientException $e) {
543
+		} catch (ClientException $e) {
555 544
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
556 545
 			$e->setTitle($this->backendTransName . _('Sabre error'));
557 546
 
558 547
 			throw $e;
559
-		}
560
-		catch (Exception $e) {
548
+		} catch (Exception $e) {
561 549
 			$this->log('[MOVE] fatal: ' . $e->getMessage());
562 550
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
563 551
 			$e->setTitle($this->backendTransName . _('Moving failed'));
@@ -590,14 +578,12 @@  discard block
 block discarded – undo
590 578
 			$this->log("[PUT] done in {$time} seconds: " . $response['statusCode']);
591 579
 
592 580
 			return true;
593
-		}
594
-		catch (ClientException $e) {
581
+		} catch (ClientException $e) {
595 582
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
596 583
 			$e->setTitle($this->backendTransName . _('Sabre error'));
597 584
 
598 585
 			throw $e;
599
-		}
600
-		catch (Exception $e) {
586
+		} catch (Exception $e) {
601 587
 			$this->log('[PUT] fatal: ' . $e->getMessage());
602 588
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
603 589
 			$e->setTitle($this->backendTransName . _('Connection failed'));
@@ -669,14 +655,12 @@  discard block
 block discarded – undo
669 655
 			$time_end = microtime(true);
670 656
 			$time = $time_end - $time_start;
671 657
 			$this->log("[GET_FILE] done in {$time} seconds: " . $response['statusCode']);
672
-		}
673
-		catch (ClientException $e) {
658
+		} catch (ClientException $e) {
674 659
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
675 660
 			$e->setTitle($this->backendTransName . _('Sabre error'));
676 661
 
677 662
 			throw $e;
678
-		}
679
-		catch (Exception $e) {
663
+		} catch (Exception $e) {
680 664
 			$this->log('[GET_FILE] - FATAL -' . $e->getMessage());
681 665
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
682 666
 			$e->setTitle($this->backendTransName . _('File or folder not found'));
@@ -751,8 +735,7 @@  discard block
 block discarded – undo
751 735
 		$type = $response["{DAV:}resourcetype"]->resourceType;
752 736
 		if (is_array($type) && !empty($type)) {
753 737
 			$type = $type[0] == "{DAV:}collection" ? "collection" : "file";
754
-		}
755
-		else {
738
+		} else {
756 739
 			$type = "file"; // fall back to file if detection fails... less harmful
757 740
 		}
758 741
 
@@ -849,8 +832,7 @@  discard block
 block discarded – undo
849 832
 		$this->log("[COPY] start for dir: {$src_path} -> {$dst_path}");
850 833
 		if ($overwrite) {
851 834
 			$overwrite = 'T';
852
-		}
853
-		else {
835
+		} else {
854 836
 			$overwrite = 'F';
855 837
 		}
856 838
 
@@ -866,14 +848,12 @@  discard block
 block discarded – undo
866 848
 			$this->log("[COPY] done in {$time} seconds: " . $response['statusCode']);
867 849
 
868 850
 			return true;
869
-		}
870
-		catch (ClientException $e) {
851
+		} catch (ClientException $e) {
871 852
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getCode()), $e->getCode());
872 853
 			$e->setTitle($this->backendTransName . _('Sabre error'));
873 854
 
874 855
 			throw $e;
875
-		}
876
-		catch (Exception $e) {
856
+		} catch (Exception $e) {
877 857
 			$this->log('[COPY] - FATAL - ' . $e->getMessage());
878 858
 			$e = new BackendException($this->parseErrorCodeToMessage($e->getHTTPCode()), $e->getHTTPCode());
879 859
 			$e->setTitle($this->backendTransName . _('Copying failed'));
@@ -890,8 +870,7 @@  discard block
 block discarded – undo
890 870
 	protected function webdavUrl() {
891 871
 		if ($this->ssl) {
892 872
 			$url = "https://";
893
-		}
894
-		else {
873
+		} else {
895 874
 			$url = "http://";
896 875
 		}
897 876
 
@@ -1098,8 +1077,7 @@  discard block
 block discarded – undo
1098 1077
 		if ($httpcode && $httpcode == "200" && $versiondata) {
1099 1078
 			$versions = json_decode($versiondata);
1100 1079
 			$version = $versions->versionstring;
1101
-		}
1102
-		else {
1080
+		} else {
1103 1081
 			$version = "Undetected (no Owncloud?)";
1104 1082
 		}
1105 1083
 
Please login to merge, or discard this patch.
plugins/files/php/Files/Backend/Webdav/sabredav/FilesWebDavClient.php 1 patch
Indentation   +111 added lines, -111 removed lines patch added patch discarded remove patch
@@ -9,115 +9,115 @@
 block discarded – undo
9 9
 include __DIR__ . "/vendor/autoload.php";
10 10
 
11 11
 class FilesWebDavClient extends \Sabre\DAV\Client {
12
-	public function __construct(array $settings) {
13
-		if (isset($settings['userName'])) {
14
-			$this->userName = $settings['userName'];
15
-		}
16
-		if (isset($settings['password'])) {
17
-			$this->password = $settings['password'];
18
-		}
19
-		parent::__construct($settings);
20
-	}
21
-
22
-	/**
23
-	 * Performs an actual HTTP request, and returns the result.
24
-	 *
25
-	 * If the specified url is relative, it will be expanded based on the base
26
-	 * url.
27
-	 *
28
-	 * The returned array contains 3 keys:
29
-	 *   * body - the response body
30
-	 *   * httpCode - a HTTP code (200, 404, etc)
31
-	 *   * headers - a list of response http headers. The header names have
32
-	 *     been lowercased.
33
-	 *
34
-	 * @param string $url
35
-	 * @param string $dstpath
36
-	 * @param array  $headers
37
-	 *
38
-	 * @return array
39
-	 */
40
-	public function getFile($url = '', $dstpath, $headers = []) {
41
-		$url = $this->getAbsoluteUrl($url);
42
-		$file_handle = fopen($dstpath, "w");
43
-
44
-		if (!$file_handle) {
45
-			throw new \Sabre\DAV\Exception('[CURL] Error writing to temporary file! (' . $dstpath . ')');
46
-		}
47
-
48
-		// straight up curl instead of sabredav here, sabredav put's the entire get result in memory
49
-		$curl = curl_init($url);
50
-
51
-		if ($this->verifyPeer !== null) {
52
-			curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verifyPeer);
53
-		}
54
-		if ($this->trustedCertificates) {
55
-			curl_setopt($curl, CURLOPT_CAINFO, $this->trustedCertificates);
56
-		}
57
-
58
-		curl_setopt($curl, CURLOPT_USERPWD, $this->userName . ":" . $this->password);
59
-		curl_setopt($curl, CURLOPT_FILE, $file_handle);
60
-		curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
61
-		curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
62
-		curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
63
-
64
-		curl_exec($curl);
65
-
66
-		$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
67
-
68
-		curl_close($curl);
69
-
70
-		$response = [
71
-			'statusCode' => $statusCode,
72
-		];
73
-
74
-		if ($response['statusCode'] >= 400) {
75
-			switch ($response['statusCode']) {
76
-				case 400 :
77
-					throw new \Sabre\DAV\Exception\BadRequest('Bad request');
78
-
79
-				case 401 :
80
-					throw new \Sabre\DAV\Exception\NotAuthenticated('Not authenticated');
81
-
82
-				case 402 :
83
-					throw new \Sabre\DAV\Exception\PaymentRequired('Payment required');
84
-
85
-				case 403 :
86
-					throw new \Sabre\DAV\Exception\Forbidden('Forbidden');
87
-
88
-				case 404:
89
-					throw new \Sabre\DAV\Exception\NotFound('Resource not found.');
90
-
91
-				case 405 :
92
-					throw new \Sabre\DAV\Exception\MethodNotAllowed('Method not allowed');
93
-
94
-				case 409 :
95
-					throw new \Sabre\DAV\Exception\Conflict('Conflict');
96
-
97
-				case 412 :
98
-					throw new \Sabre\DAV\Exception\PreconditionFailed('Precondition failed');
99
-
100
-				case 416 :
101
-					throw new \Sabre\DAV\Exception\RequestedRangeNotSatisfiable('Requested Range Not Satisfiable');
102
-
103
-				case 500 :
104
-					throw new \Sabre\DAV\Exception('Internal server error');
105
-
106
-				case 501 :
107
-					throw new \Sabre\DAV\Exception\NotImplemented('Not Implemented');
108
-
109
-				case 507 :
110
-					throw new \Sabre\DAV\Exception\InsufficientStorage('Insufficient storage');
111
-
112
-				default:
113
-					throw new \Sabre\DAV\Exception('HTTP error response. (errorcode ' . $response['statusCode'] . ')');
114
-			}
115
-		}
116
-
117
-		return $response;
118
-	}
119
-
120
-	public function uploadChunkedFile($destination, $resource) {
121
-		return $this->request("PUT", $destination, $resource);
122
-	}
12
+    public function __construct(array $settings) {
13
+        if (isset($settings['userName'])) {
14
+            $this->userName = $settings['userName'];
15
+        }
16
+        if (isset($settings['password'])) {
17
+            $this->password = $settings['password'];
18
+        }
19
+        parent::__construct($settings);
20
+    }
21
+
22
+    /**
23
+     * Performs an actual HTTP request, and returns the result.
24
+     *
25
+     * If the specified url is relative, it will be expanded based on the base
26
+     * url.
27
+     *
28
+     * The returned array contains 3 keys:
29
+     *   * body - the response body
30
+     *   * httpCode - a HTTP code (200, 404, etc)
31
+     *   * headers - a list of response http headers. The header names have
32
+     *     been lowercased.
33
+     *
34
+     * @param string $url
35
+     * @param string $dstpath
36
+     * @param array  $headers
37
+     *
38
+     * @return array
39
+     */
40
+    public function getFile($url = '', $dstpath, $headers = []) {
41
+        $url = $this->getAbsoluteUrl($url);
42
+        $file_handle = fopen($dstpath, "w");
43
+
44
+        if (!$file_handle) {
45
+            throw new \Sabre\DAV\Exception('[CURL] Error writing to temporary file! (' . $dstpath . ')');
46
+        }
47
+
48
+        // straight up curl instead of sabredav here, sabredav put's the entire get result in memory
49
+        $curl = curl_init($url);
50
+
51
+        if ($this->verifyPeer !== null) {
52
+            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verifyPeer);
53
+        }
54
+        if ($this->trustedCertificates) {
55
+            curl_setopt($curl, CURLOPT_CAINFO, $this->trustedCertificates);
56
+        }
57
+
58
+        curl_setopt($curl, CURLOPT_USERPWD, $this->userName . ":" . $this->password);
59
+        curl_setopt($curl, CURLOPT_FILE, $file_handle);
60
+        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
61
+        curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
62
+        curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
63
+
64
+        curl_exec($curl);
65
+
66
+        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
67
+
68
+        curl_close($curl);
69
+
70
+        $response = [
71
+            'statusCode' => $statusCode,
72
+        ];
73
+
74
+        if ($response['statusCode'] >= 400) {
75
+            switch ($response['statusCode']) {
76
+                case 400 :
77
+                    throw new \Sabre\DAV\Exception\BadRequest('Bad request');
78
+
79
+                case 401 :
80
+                    throw new \Sabre\DAV\Exception\NotAuthenticated('Not authenticated');
81
+
82
+                case 402 :
83
+                    throw new \Sabre\DAV\Exception\PaymentRequired('Payment required');
84
+
85
+                case 403 :
86
+                    throw new \Sabre\DAV\Exception\Forbidden('Forbidden');
87
+
88
+                case 404:
89
+                    throw new \Sabre\DAV\Exception\NotFound('Resource not found.');
90
+
91
+                case 405 :
92
+                    throw new \Sabre\DAV\Exception\MethodNotAllowed('Method not allowed');
93
+
94
+                case 409 :
95
+                    throw new \Sabre\DAV\Exception\Conflict('Conflict');
96
+
97
+                case 412 :
98
+                    throw new \Sabre\DAV\Exception\PreconditionFailed('Precondition failed');
99
+
100
+                case 416 :
101
+                    throw new \Sabre\DAV\Exception\RequestedRangeNotSatisfiable('Requested Range Not Satisfiable');
102
+
103
+                case 500 :
104
+                    throw new \Sabre\DAV\Exception('Internal server error');
105
+
106
+                case 501 :
107
+                    throw new \Sabre\DAV\Exception\NotImplemented('Not Implemented');
108
+
109
+                case 507 :
110
+                    throw new \Sabre\DAV\Exception\InsufficientStorage('Insufficient storage');
111
+
112
+                default:
113
+                    throw new \Sabre\DAV\Exception('HTTP error response. (errorcode ' . $response['statusCode'] . ')');
114
+            }
115
+        }
116
+
117
+        return $response;
118
+    }
119
+
120
+    public function uploadChunkedFile($destination, $resource) {
121
+        return $this->request("PUT", $destination, $resource);
122
+    }
123 123
 }
Please login to merge, or discard this patch.
plugins/files/php/Files/Backend/Webdav/cssloader.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -7,31 +7,31 @@
 block discarded – undo
7 7
 use Files\Backend\AbstractCSSLoader;
8 8
 
9 9
 class BackendCSSLoader extends AbstractCSSLoader {
10
-	public function __construct() {
11
-		$this->CSS_PATH = __DIR__ . "/css/";
12
-	}
10
+    public function __construct() {
11
+        $this->CSS_PATH = __DIR__ . "/css/";
12
+    }
13 13
 
14
-	/**
15
-	 * Returns a combined CSS String.
16
-	 *
17
-	 * @param bool $debug
18
-	 *
19
-	 * @return string
20
-	 */
21
-	public function get_combined_css($debug = false) {
22
-		// Populate the list of directories to check against
23
-		if (($directoryHandle = opendir($this->CSS_PATH)) !== false) {
24
-			while (($file = readdir($directoryHandle)) !== false) {
25
-				// Make sure we're not dealing with a folder or a link to the parent directory
26
-				if (is_dir($this->CSS_PATH . $file) || ($file == '.' || $file == '..') === true) {
27
-					continue;
28
-				}
14
+    /**
15
+     * Returns a combined CSS String.
16
+     *
17
+     * @param bool $debug
18
+     *
19
+     * @return string
20
+     */
21
+    public function get_combined_css($debug = false) {
22
+        // Populate the list of directories to check against
23
+        if (($directoryHandle = opendir($this->CSS_PATH)) !== false) {
24
+            while (($file = readdir($directoryHandle)) !== false) {
25
+                // Make sure we're not dealing with a folder or a link to the parent directory
26
+                if (is_dir($this->CSS_PATH . $file) || ($file == '.' || $file == '..') === true) {
27
+                    continue;
28
+                }
29 29
 
30
-				// Add file content to our buffer
31
-				$this->cssBuffer .= file_get_contents($this->CSS_PATH . $file);
32
-			}
33
-		}
30
+                // Add file content to our buffer
31
+                $this->cssBuffer .= file_get_contents($this->CSS_PATH . $file);
32
+            }
33
+        }
34 34
 
35
-		return $this->cssBuffer;
36
-	}
35
+        return $this->cssBuffer;
36
+    }
37 37
 }
Please login to merge, or discard this patch.
plugins/files/php/Files/Backend/interface.version.php 1 patch
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -3,5 +3,5 @@
 block discarded – undo
3 3
 namespace Files\Backend;
4 4
 
5 5
 interface iFeatureVersionInfo {
6
-	public function getServerVersion();
6
+    public function getServerVersion();
7 7
 }
Please login to merge, or discard this patch.
plugins/files/php/Files/Backend/class.abstract_css_loader.php 1 patch
Indentation   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -3,11 +3,11 @@
 block discarded – undo
3 3
 namespace Files\Backend;
4 4
 
5 5
 abstract class AbstractCSSLoader {
6
-	protected $cssBuffer = "";
6
+    protected $cssBuffer = "";
7 7
 
8
-	// path to css folder
9
-	protected $CSS_PATH;
8
+    // path to css folder
9
+    protected $CSS_PATH;
10 10
 
11
-	// get combined css string
12
-	abstract public function get_combined_css($debug = false);
11
+    // get combined css string
12
+    abstract public function get_combined_css($debug = false);
13 13
 }
Please login to merge, or discard this patch.
plugins/files/php/Files/Core/class.exception.php 1 patch
Indentation   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -3,36 +3,36 @@
 block discarded – undo
3 3
 namespace Files\Core;
4 4
 
5 5
 class Exception extends \Exception {
6
-	/**
7
-	 * The exception title to show as a message box title at client side.
8
-	 */
9
-	public $title;
6
+    /**
7
+     * The exception title to show as a message box title at client side.
8
+     */
9
+    public $title;
10 10
 
11
-	/**
12
-	 * @constructor
13
-	 *
14
-	 * @param string $message The error message
15
-	 * @param int    $code    The error code
16
-	 */
17
-	public function __construct($message, $code = 0) {
18
-		parent::__construct($message, $code);
19
-	}
11
+    /**
12
+     * @constructor
13
+     *
14
+     * @param string $message The error message
15
+     * @param int    $code    The error code
16
+     */
17
+    public function __construct($message, $code = 0) {
18
+        parent::__construct($message, $code);
19
+    }
20 20
 
21
-	/**
22
-	 * Function sets title of an exception that will be sent to the client side
23
-	 * to show it to user.
24
-	 *
25
-	 * @param string $title title of an exception
26
-	 */
27
-	public function setTitle($title) {
28
-		$this->title = $title;
29
-	}
21
+    /**
22
+     * Function sets title of an exception that will be sent to the client side
23
+     * to show it to user.
24
+     *
25
+     * @param string $title title of an exception
26
+     */
27
+    public function setTitle($title) {
28
+        $this->title = $title;
29
+    }
30 30
 
31
-	/**
32
-	 * @return string returns title that should be sent to client to display as a message box
33
-	 *                title
34
-	 */
35
-	public function getTitle() {
36
-		return $this->title;
37
-	}
31
+    /**
32
+     * @return string returns title that should be sent to client to display as a message box
33
+     *                title
34
+     */
35
+    public function getTitle() {
36
+        return $this->title;
37
+    }
38 38
 }
Please login to merge, or discard this patch.
plugins/files/php/Files/Core/Util/class.arrayutil.php 2 patches
Indentation   +161 added lines, -161 removed lines patch added patch discarded remove patch
@@ -3,165 +3,165 @@
 block discarded – undo
3 3
 namespace Files\Core\Util;
4 4
 
5 5
 class ArrayUtil {
6
-	/**
7
-	 * Sort multidimensional array by any key.
8
-	 *
9
-	 * @static
10
-	 *
11
-	 * @param array  $arr the array to sort
12
-	 * @param string $key the key to sort
13
-	 * @param string $dir ASC or DESC sort direction
14
-	 *
15
-	 * @return array the sorted array
16
-	 */
17
-	public static function sort_by_key($arr, $key, $dir) {
18
-		global $key2sort;
19
-		$key2sort = $key;
20
-
21
-		if ($dir == "DESC") {
22
-			usort($arr, ['self', 'invsort']);
23
-		}
24
-		else {
25
-			usort($arr, ['self', 'sort']);
26
-		}
27
-
28
-		return $arr;
29
-	}
30
-
31
-	/**
32
-	 * Sort multidimensional properties array by any key.
33
-	 *
34
-	 * @static
35
-	 *
36
-	 * @param array  $arr the array to sort
37
-	 * @param string $key the key to sort
38
-	 * @param string $dir ASC or DESC sort direction
39
-	 *
40
-	 * @return array the sorted array
41
-	 */
42
-	public static function sort_props_by_key($arr, $key, $dir) {
43
-		global $key2sort;
44
-		$key2sort = $key;
45
-
46
-		if ($dir == "DESC") {
47
-			usort($arr, ['self', 'invpropsort']);
48
-		}
49
-		else {
50
-			usort($arr, ['self', 'propsort']);
51
-		}
52
-
53
-		return $arr;
54
-	}
55
-
56
-	/**
57
-	 * compare function for multidimensional array sorting.
58
-	 *
59
-	 * @static
60
-	 *
61
-	 * @param array $a this argument will be compared with argument $b
62
-	 * @param array $b this argument will be compared with argument $a
63
-	 *
64
-	 * @return int compare value. If $a < $b the return value will be -1.
65
-	 */
66
-	public static function sort($a, $b) {
67
-		global $key2sort;
68
-
69
-		if ($a['isFolder'] == $b['isFolder']) {
70
-			if (is_numeric($a[$key2sort]) && is_numeric($b[$key2sort])) {
71
-				if ($a[$key2sort] == $b[$key2sort]) {
72
-					return 0;
73
-				}
74
-
75
-				return ($a[$key2sort] < $b[$key2sort]) ? -1 : 1;
76
-			}
77
-
78
-			return strcasecmp($a[$key2sort], $b[$key2sort]);
79
-		}
80
-
81
-		return (int) $a['isFolder'] - (int) $b['isFolder'];
82
-	}
83
-
84
-	/**
85
-	 * inverse compare function for multidimensional array sorting.
86
-	 *
87
-	 * @static
88
-	 *
89
-	 * @param array $a this argument will be compared with argument $b
90
-	 * @param array $b this argument will be compared with argument $a
91
-	 *
92
-	 * @return int compare value. If $a < $b the return value will be 1.
93
-	 */
94
-	public static function invsort($a, $b) {
95
-		global $key2sort;
96
-
97
-		if ($a['isFolder'] == $b['isFolder']) {
98
-			if (is_numeric($a[$key2sort]) && is_numeric($b[$key2sort])) {
99
-				if ($a[$key2sort] == $b[$key2sort]) {
100
-					return 0;
101
-				}
102
-
103
-				return ($a[$key2sort] < $b[$key2sort]) ? 1 : -1;
104
-			}
105
-
106
-			return -1 * strcasecmp($a[$key2sort], $b[$key2sort]);
107
-		}
108
-
109
-		return (int) $b['isFolder'] - (int) $a['isFolder'];
110
-	}
111
-
112
-	/**
113
-	 * compare function for multidimensional array sorting.
114
-	 *
115
-	 * @static
116
-	 *
117
-	 * @param array $a this argument will be compared with argument $b
118
-	 * @param array $b this argument will be compared with argument $a
119
-	 *
120
-	 * @return int compare value. If $a < $b the return value will be -1.
121
-	 */
122
-	public static function propsort($a, $b) {
123
-		global $key2sort;
124
-
125
-		if ($a['props']['type'] == $b['props']['type']) {
126
-			if (is_numeric($a['props'][$key2sort]) && is_numeric($b['props'][$key2sort])) {
127
-				if ($a['props'][$key2sort] == $b['props'][$key2sort]) {
128
-					return 0;
129
-				}
130
-
131
-				return ($a['props'][$key2sort] < $b['props'][$key2sort]) ? -1 : 1;
132
-			}
133
-
134
-			return strcasecmp($a['props'][$key2sort], $b['props'][$key2sort]);
135
-		}
136
-
137
-		return $a['props']['type'] - $b['props']['type'];
138
-	}
139
-
140
-	/**
141
-	 * inverse compare function for multidimensional array sorting.
142
-	 *
143
-	 * @static
144
-	 *
145
-	 * @param array $a this argument will be compared with argument $b
146
-	 * @param array $b this argument will be compared with argument $a
147
-	 *
148
-	 * @return int compare value. If $a < $b the return value will be 1.
149
-	 */
150
-	public static function invpropsort($a, $b) {
151
-		global $key2sort;
152
-
153
-		if ($a['props']['type'] == $b['props']['type']) {
154
-			if (is_numeric($a['props'][$key2sort]) && is_numeric($b['props'][$key2sort])) {
155
-				if ($a['props'][$key2sort] == $b['props'][$key2sort]) {
156
-					return 0;
157
-				}
158
-
159
-				return ($a['props'][$key2sort] < $b['props'][$key2sort]) ? 1 : -1;
160
-			}
161
-
162
-			return -1 * strcasecmp($a['props'][$key2sort], $b['props'][$key2sort]);
163
-		}
164
-
165
-		return $b['props']['type'] - $a['props']['type'];
166
-	}
6
+    /**
7
+     * Sort multidimensional array by any key.
8
+     *
9
+     * @static
10
+     *
11
+     * @param array  $arr the array to sort
12
+     * @param string $key the key to sort
13
+     * @param string $dir ASC or DESC sort direction
14
+     *
15
+     * @return array the sorted array
16
+     */
17
+    public static function sort_by_key($arr, $key, $dir) {
18
+        global $key2sort;
19
+        $key2sort = $key;
20
+
21
+        if ($dir == "DESC") {
22
+            usort($arr, ['self', 'invsort']);
23
+        }
24
+        else {
25
+            usort($arr, ['self', 'sort']);
26
+        }
27
+
28
+        return $arr;
29
+    }
30
+
31
+    /**
32
+     * Sort multidimensional properties array by any key.
33
+     *
34
+     * @static
35
+     *
36
+     * @param array  $arr the array to sort
37
+     * @param string $key the key to sort
38
+     * @param string $dir ASC or DESC sort direction
39
+     *
40
+     * @return array the sorted array
41
+     */
42
+    public static function sort_props_by_key($arr, $key, $dir) {
43
+        global $key2sort;
44
+        $key2sort = $key;
45
+
46
+        if ($dir == "DESC") {
47
+            usort($arr, ['self', 'invpropsort']);
48
+        }
49
+        else {
50
+            usort($arr, ['self', 'propsort']);
51
+        }
52
+
53
+        return $arr;
54
+    }
55
+
56
+    /**
57
+     * compare function for multidimensional array sorting.
58
+     *
59
+     * @static
60
+     *
61
+     * @param array $a this argument will be compared with argument $b
62
+     * @param array $b this argument will be compared with argument $a
63
+     *
64
+     * @return int compare value. If $a < $b the return value will be -1.
65
+     */
66
+    public static function sort($a, $b) {
67
+        global $key2sort;
68
+
69
+        if ($a['isFolder'] == $b['isFolder']) {
70
+            if (is_numeric($a[$key2sort]) && is_numeric($b[$key2sort])) {
71
+                if ($a[$key2sort] == $b[$key2sort]) {
72
+                    return 0;
73
+                }
74
+
75
+                return ($a[$key2sort] < $b[$key2sort]) ? -1 : 1;
76
+            }
77
+
78
+            return strcasecmp($a[$key2sort], $b[$key2sort]);
79
+        }
80
+
81
+        return (int) $a['isFolder'] - (int) $b['isFolder'];
82
+    }
83
+
84
+    /**
85
+     * inverse compare function for multidimensional array sorting.
86
+     *
87
+     * @static
88
+     *
89
+     * @param array $a this argument will be compared with argument $b
90
+     * @param array $b this argument will be compared with argument $a
91
+     *
92
+     * @return int compare value. If $a < $b the return value will be 1.
93
+     */
94
+    public static function invsort($a, $b) {
95
+        global $key2sort;
96
+
97
+        if ($a['isFolder'] == $b['isFolder']) {
98
+            if (is_numeric($a[$key2sort]) && is_numeric($b[$key2sort])) {
99
+                if ($a[$key2sort] == $b[$key2sort]) {
100
+                    return 0;
101
+                }
102
+
103
+                return ($a[$key2sort] < $b[$key2sort]) ? 1 : -1;
104
+            }
105
+
106
+            return -1 * strcasecmp($a[$key2sort], $b[$key2sort]);
107
+        }
108
+
109
+        return (int) $b['isFolder'] - (int) $a['isFolder'];
110
+    }
111
+
112
+    /**
113
+     * compare function for multidimensional array sorting.
114
+     *
115
+     * @static
116
+     *
117
+     * @param array $a this argument will be compared with argument $b
118
+     * @param array $b this argument will be compared with argument $a
119
+     *
120
+     * @return int compare value. If $a < $b the return value will be -1.
121
+     */
122
+    public static function propsort($a, $b) {
123
+        global $key2sort;
124
+
125
+        if ($a['props']['type'] == $b['props']['type']) {
126
+            if (is_numeric($a['props'][$key2sort]) && is_numeric($b['props'][$key2sort])) {
127
+                if ($a['props'][$key2sort] == $b['props'][$key2sort]) {
128
+                    return 0;
129
+                }
130
+
131
+                return ($a['props'][$key2sort] < $b['props'][$key2sort]) ? -1 : 1;
132
+            }
133
+
134
+            return strcasecmp($a['props'][$key2sort], $b['props'][$key2sort]);
135
+        }
136
+
137
+        return $a['props']['type'] - $b['props']['type'];
138
+    }
139
+
140
+    /**
141
+     * inverse compare function for multidimensional array sorting.
142
+     *
143
+     * @static
144
+     *
145
+     * @param array $a this argument will be compared with argument $b
146
+     * @param array $b this argument will be compared with argument $a
147
+     *
148
+     * @return int compare value. If $a < $b the return value will be 1.
149
+     */
150
+    public static function invpropsort($a, $b) {
151
+        global $key2sort;
152
+
153
+        if ($a['props']['type'] == $b['props']['type']) {
154
+            if (is_numeric($a['props'][$key2sort]) && is_numeric($b['props'][$key2sort])) {
155
+                if ($a['props'][$key2sort] == $b['props'][$key2sort]) {
156
+                    return 0;
157
+                }
158
+
159
+                return ($a['props'][$key2sort] < $b['props'][$key2sort]) ? 1 : -1;
160
+            }
161
+
162
+            return -1 * strcasecmp($a['props'][$key2sort], $b['props'][$key2sort]);
163
+        }
164
+
165
+        return $b['props']['type'] - $a['props']['type'];
166
+    }
167 167
 }
Please login to merge, or discard this patch.
Braces   +2 added lines, -4 removed lines patch added patch discarded remove patch
@@ -20,8 +20,7 @@  discard block
 block discarded – undo
20 20
 
21 21
 		if ($dir == "DESC") {
22 22
 			usort($arr, ['self', 'invsort']);
23
-		}
24
-		else {
23
+		} else {
25 24
 			usort($arr, ['self', 'sort']);
26 25
 		}
27 26
 
@@ -45,8 +44,7 @@  discard block
 block discarded – undo
45 44
 
46 45
 		if ($dir == "DESC") {
47 46
 			usort($arr, ['self', 'invpropsort']);
48
-		}
49
-		else {
47
+		} else {
50 48
 			usort($arr, ['self', 'propsort']);
51 49
 		}
52 50
 
Please login to merge, or discard this patch.