Completed
Pull Request — stable10 (#4802)
by Morris
22:59 queued 10:49
created
lib/private/Group/Manager.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -154,7 +154,7 @@
 block discarded – undo
154 154
 
155 155
 	/**
156 156
 	 * @param string $gid
157
-	 * @return \OCP\IGroup
157
+	 * @return null|Group
158 158
 	 */
159 159
 	protected function getGroupObject($gid) {
160 160
 		$backends = array();
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -85,20 +85,20 @@  discard block
 block discarded – undo
85 85
 		$this->userManager = $userManager;
86 86
 		$cachedGroups = & $this->cachedGroups;
87 87
 		$cachedUserGroups = & $this->cachedUserGroups;
88
-		$this->listen('\OC\Group', 'postDelete', function ($group) use (&$cachedGroups, &$cachedUserGroups) {
88
+		$this->listen('\OC\Group', 'postDelete', function($group) use (&$cachedGroups, &$cachedUserGroups) {
89 89
 			/**
90 90
 			 * @var \OC\Group\Group $group
91 91
 			 */
92 92
 			unset($cachedGroups[$group->getGID()]);
93 93
 			$cachedUserGroups = array();
94 94
 		});
95
-		$this->listen('\OC\Group', 'postAddUser', function ($group) use (&$cachedUserGroups) {
95
+		$this->listen('\OC\Group', 'postAddUser', function($group) use (&$cachedUserGroups) {
96 96
 			/**
97 97
 			 * @var \OC\Group\Group $group
98 98
 			 */
99 99
 			$cachedUserGroups = array();
100 100
 		});
101
-		$this->listen('\OC\Group', 'postRemoveUser', function ($group) use (&$cachedUserGroups) {
101
+		$this->listen('\OC\Group', 'postRemoveUser', function($group) use (&$cachedUserGroups) {
102 102
 			/**
103 103
 			 * @var \OC\Group\Group $group
104 104
 			 */
@@ -304,32 +304,32 @@  discard block
 block discarded – undo
304 304
 	 */
305 305
 	public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) {
306 306
 		$group = $this->get($gid);
307
-		if(is_null($group)) {
307
+		if (is_null($group)) {
308 308
 			return array();
309 309
 		}
310 310
 
311 311
 		$search = trim($search);
312 312
 		$groupUsers = array();
313 313
 
314
-		if(!empty($search)) {
314
+		if (!empty($search)) {
315 315
 			// only user backends have the capability to do a complex search for users
316 316
 			$searchOffset = 0;
317 317
 			$searchLimit = $limit * 100;
318
-			if($limit === -1) {
318
+			if ($limit === -1) {
319 319
 				$searchLimit = 500;
320 320
 			}
321 321
 
322 322
 			do {
323 323
 				$filteredUsers = $this->userManager->searchDisplayName($search, $searchLimit, $searchOffset);
324
-				foreach($filteredUsers as $filteredUser) {
325
-					if($group->inGroup($filteredUser)) {
326
-						$groupUsers[]= $filteredUser;
324
+				foreach ($filteredUsers as $filteredUser) {
325
+					if ($group->inGroup($filteredUser)) {
326
+						$groupUsers[] = $filteredUser;
327 327
 					}
328 328
 				}
329 329
 				$searchOffset += $searchLimit;
330
-			} while(count($groupUsers) < $searchLimit+$offset && count($filteredUsers) >= $searchLimit);
330
+			} while (count($groupUsers) < $searchLimit + $offset && count($filteredUsers) >= $searchLimit);
331 331
 
332
-			if($limit === -1) {
332
+			if ($limit === -1) {
333 333
 				$groupUsers = array_slice($groupUsers, $offset);
334 334
 			} else {
335 335
 				$groupUsers = array_slice($groupUsers, $offset, $limit);
@@ -339,7 +339,7 @@  discard block
 block discarded – undo
339 339
 		}
340 340
 
341 341
 		$matchingUsers = array();
342
-		foreach($groupUsers as $groupUser) {
342
+		foreach ($groupUsers as $groupUser) {
343 343
 			$matchingUsers[$groupUser->getUID()] = $groupUser->getDisplayName();
344 344
 		}
345 345
 		return $matchingUsers;
Please login to merge, or discard this patch.
Indentation   +265 added lines, -265 removed lines patch added patch discarded remove patch
@@ -55,298 +55,298 @@
 block discarded – undo
55 55
  * @package OC\Group
56 56
  */
57 57
 class Manager extends PublicEmitter implements IGroupManager {
58
-	/**
59
-	 * @var GroupInterface[] $backends
60
-	 */
61
-	private $backends = array();
58
+    /**
59
+     * @var GroupInterface[] $backends
60
+     */
61
+    private $backends = array();
62 62
 
63
-	/**
64
-	 * @var \OC\User\Manager $userManager
65
-	 */
66
-	private $userManager;
63
+    /**
64
+     * @var \OC\User\Manager $userManager
65
+     */
66
+    private $userManager;
67 67
 
68
-	/**
69
-	 * @var \OC\Group\Group[]
70
-	 */
71
-	private $cachedGroups = array();
68
+    /**
69
+     * @var \OC\Group\Group[]
70
+     */
71
+    private $cachedGroups = array();
72 72
 
73
-	/**
74
-	 * @var \OC\Group\Group[]
75
-	 */
76
-	private $cachedUserGroups = array();
73
+    /**
74
+     * @var \OC\Group\Group[]
75
+     */
76
+    private $cachedUserGroups = array();
77 77
 
78
-	/** @var \OC\SubAdmin */
79
-	private $subAdmin = null;
78
+    /** @var \OC\SubAdmin */
79
+    private $subAdmin = null;
80 80
 
81
-	/**
82
-	 * @param \OC\User\Manager $userManager
83
-	 */
84
-	public function __construct(\OC\User\Manager $userManager) {
85
-		$this->userManager = $userManager;
86
-		$cachedGroups = & $this->cachedGroups;
87
-		$cachedUserGroups = & $this->cachedUserGroups;
88
-		$this->listen('\OC\Group', 'postDelete', function ($group) use (&$cachedGroups, &$cachedUserGroups) {
89
-			/**
90
-			 * @var \OC\Group\Group $group
91
-			 */
92
-			unset($cachedGroups[$group->getGID()]);
93
-			$cachedUserGroups = array();
94
-		});
95
-		$this->listen('\OC\Group', 'postAddUser', function ($group) use (&$cachedUserGroups) {
96
-			/**
97
-			 * @var \OC\Group\Group $group
98
-			 */
99
-			$cachedUserGroups = array();
100
-		});
101
-		$this->listen('\OC\Group', 'postRemoveUser', function ($group) use (&$cachedUserGroups) {
102
-			/**
103
-			 * @var \OC\Group\Group $group
104
-			 */
105
-			$cachedUserGroups = array();
106
-		});
107
-	}
81
+    /**
82
+     * @param \OC\User\Manager $userManager
83
+     */
84
+    public function __construct(\OC\User\Manager $userManager) {
85
+        $this->userManager = $userManager;
86
+        $cachedGroups = & $this->cachedGroups;
87
+        $cachedUserGroups = & $this->cachedUserGroups;
88
+        $this->listen('\OC\Group', 'postDelete', function ($group) use (&$cachedGroups, &$cachedUserGroups) {
89
+            /**
90
+             * @var \OC\Group\Group $group
91
+             */
92
+            unset($cachedGroups[$group->getGID()]);
93
+            $cachedUserGroups = array();
94
+        });
95
+        $this->listen('\OC\Group', 'postAddUser', function ($group) use (&$cachedUserGroups) {
96
+            /**
97
+             * @var \OC\Group\Group $group
98
+             */
99
+            $cachedUserGroups = array();
100
+        });
101
+        $this->listen('\OC\Group', 'postRemoveUser', function ($group) use (&$cachedUserGroups) {
102
+            /**
103
+             * @var \OC\Group\Group $group
104
+             */
105
+            $cachedUserGroups = array();
106
+        });
107
+    }
108 108
 
109
-	/**
110
-	 * Checks whether a given backend is used
111
-	 *
112
-	 * @param string $backendClass Full classname including complete namespace
113
-	 * @return bool
114
-	 */
115
-	public function isBackendUsed($backendClass) {
116
-		$backendClass = strtolower(ltrim($backendClass, '\\'));
109
+    /**
110
+     * Checks whether a given backend is used
111
+     *
112
+     * @param string $backendClass Full classname including complete namespace
113
+     * @return bool
114
+     */
115
+    public function isBackendUsed($backendClass) {
116
+        $backendClass = strtolower(ltrim($backendClass, '\\'));
117 117
 
118
-		foreach ($this->backends as $backend) {
119
-			if (strtolower(get_class($backend)) === $backendClass) {
120
-				return true;
121
-			}
122
-		}
118
+        foreach ($this->backends as $backend) {
119
+            if (strtolower(get_class($backend)) === $backendClass) {
120
+                return true;
121
+            }
122
+        }
123 123
 
124
-		return false;
125
-	}
124
+        return false;
125
+    }
126 126
 
127
-	/**
128
-	 * @param \OCP\GroupInterface $backend
129
-	 */
130
-	public function addBackend($backend) {
131
-		$this->backends[] = $backend;
132
-		$this->clearCaches();
133
-	}
127
+    /**
128
+     * @param \OCP\GroupInterface $backend
129
+     */
130
+    public function addBackend($backend) {
131
+        $this->backends[] = $backend;
132
+        $this->clearCaches();
133
+    }
134 134
 
135
-	public function clearBackends() {
136
-		$this->backends = array();
137
-		$this->clearCaches();
138
-	}
135
+    public function clearBackends() {
136
+        $this->backends = array();
137
+        $this->clearCaches();
138
+    }
139 139
 	
140
-	protected function clearCaches() {
141
-		$this->cachedGroups = array();
142
-		$this->cachedUserGroups = array();
143
-	}
140
+    protected function clearCaches() {
141
+        $this->cachedGroups = array();
142
+        $this->cachedUserGroups = array();
143
+    }
144 144
 
145
-	/**
146
-	 * @param string $gid
147
-	 * @return \OC\Group\Group
148
-	 */
149
-	public function get($gid) {
150
-		if (isset($this->cachedGroups[$gid])) {
151
-			return $this->cachedGroups[$gid];
152
-		}
153
-		return $this->getGroupObject($gid);
154
-	}
145
+    /**
146
+     * @param string $gid
147
+     * @return \OC\Group\Group
148
+     */
149
+    public function get($gid) {
150
+        if (isset($this->cachedGroups[$gid])) {
151
+            return $this->cachedGroups[$gid];
152
+        }
153
+        return $this->getGroupObject($gid);
154
+    }
155 155
 
156
-	/**
157
-	 * @param string $gid
158
-	 * @return \OCP\IGroup
159
-	 */
160
-	protected function getGroupObject($gid) {
161
-		$backends = array();
162
-		foreach ($this->backends as $backend) {
163
-			if ($backend->groupExists($gid)) {
164
-				$backends[] = $backend;
165
-			}
166
-		}
167
-		if (count($backends) === 0) {
168
-			return null;
169
-		}
170
-		$this->cachedGroups[$gid] = new Group($gid, $backends, $this->userManager, $this);
171
-		return $this->cachedGroups[$gid];
172
-	}
156
+    /**
157
+     * @param string $gid
158
+     * @return \OCP\IGroup
159
+     */
160
+    protected function getGroupObject($gid) {
161
+        $backends = array();
162
+        foreach ($this->backends as $backend) {
163
+            if ($backend->groupExists($gid)) {
164
+                $backends[] = $backend;
165
+            }
166
+        }
167
+        if (count($backends) === 0) {
168
+            return null;
169
+        }
170
+        $this->cachedGroups[$gid] = new Group($gid, $backends, $this->userManager, $this);
171
+        return $this->cachedGroups[$gid];
172
+    }
173 173
 
174
-	/**
175
-	 * @param string $gid
176
-	 * @return bool
177
-	 */
178
-	public function groupExists($gid) {
179
-		return !is_null($this->get($gid));
180
-	}
174
+    /**
175
+     * @param string $gid
176
+     * @return bool
177
+     */
178
+    public function groupExists($gid) {
179
+        return !is_null($this->get($gid));
180
+    }
181 181
 
182
-	/**
183
-	 * @param string $gid
184
-	 * @return \OC\Group\Group
185
-	 */
186
-	public function createGroup($gid) {
187
-		if ($gid === '' || is_null($gid)) {
188
-			return false;
189
-		} else if ($group = $this->get($gid)) {
190
-			return $group;
191
-		} else {
192
-			$this->emit('\OC\Group', 'preCreate', array($gid));
193
-			foreach ($this->backends as $backend) {
194
-				if ($backend->implementsActions(\OC\Group\Backend::CREATE_GROUP)) {
195
-					$backend->createGroup($gid);
196
-					$group = $this->getGroupObject($gid);
197
-					$this->emit('\OC\Group', 'postCreate', array($group));
198
-					return $group;
199
-				}
200
-			}
201
-			return null;
202
-		}
203
-	}
182
+    /**
183
+     * @param string $gid
184
+     * @return \OC\Group\Group
185
+     */
186
+    public function createGroup($gid) {
187
+        if ($gid === '' || is_null($gid)) {
188
+            return false;
189
+        } else if ($group = $this->get($gid)) {
190
+            return $group;
191
+        } else {
192
+            $this->emit('\OC\Group', 'preCreate', array($gid));
193
+            foreach ($this->backends as $backend) {
194
+                if ($backend->implementsActions(\OC\Group\Backend::CREATE_GROUP)) {
195
+                    $backend->createGroup($gid);
196
+                    $group = $this->getGroupObject($gid);
197
+                    $this->emit('\OC\Group', 'postCreate', array($group));
198
+                    return $group;
199
+                }
200
+            }
201
+            return null;
202
+        }
203
+    }
204 204
 
205
-	/**
206
-	 * @param string $search
207
-	 * @param int $limit
208
-	 * @param int $offset
209
-	 * @return \OC\Group\Group[]
210
-	 */
211
-	public function search($search, $limit = null, $offset = null) {
212
-		$groups = array();
213
-		foreach ($this->backends as $backend) {
214
-			$groupIds = $backend->getGroups($search, $limit, $offset);
215
-			foreach ($groupIds as $groupId) {
216
-				$groups[$groupId] = $this->get($groupId);
217
-			}
218
-			if (!is_null($limit) and $limit <= 0) {
219
-				return array_values($groups);
220
-			}
221
-		}
222
-		return array_values($groups);
223
-	}
205
+    /**
206
+     * @param string $search
207
+     * @param int $limit
208
+     * @param int $offset
209
+     * @return \OC\Group\Group[]
210
+     */
211
+    public function search($search, $limit = null, $offset = null) {
212
+        $groups = array();
213
+        foreach ($this->backends as $backend) {
214
+            $groupIds = $backend->getGroups($search, $limit, $offset);
215
+            foreach ($groupIds as $groupId) {
216
+                $groups[$groupId] = $this->get($groupId);
217
+            }
218
+            if (!is_null($limit) and $limit <= 0) {
219
+                return array_values($groups);
220
+            }
221
+        }
222
+        return array_values($groups);
223
+    }
224 224
 
225
-	/**
226
-	 * @param \OC\User\User|null $user
227
-	 * @return \OC\Group\Group[]
228
-	 */
229
-	public function getUserGroups($user) {
230
-		if (is_null($user)) {
231
-			return [];
232
-		}
233
-		return $this->getUserIdGroups($user->getUID());
234
-	}
225
+    /**
226
+     * @param \OC\User\User|null $user
227
+     * @return \OC\Group\Group[]
228
+     */
229
+    public function getUserGroups($user) {
230
+        if (is_null($user)) {
231
+            return [];
232
+        }
233
+        return $this->getUserIdGroups($user->getUID());
234
+    }
235 235
 
236
-	/**
237
-	 * @param string $uid the user id
238
-	 * @return \OC\Group\Group[]
239
-	 */
240
-	public function getUserIdGroups($uid) {
241
-		if (isset($this->cachedUserGroups[$uid])) {
242
-			return $this->cachedUserGroups[$uid];
243
-		}
244
-		$groups = array();
245
-		foreach ($this->backends as $backend) {
246
-			$groupIds = $backend->getUserGroups($uid);
247
-			if (is_array($groupIds)) {
248
-				foreach ($groupIds as $groupId) {
249
-					$groups[$groupId] = $this->get($groupId);
250
-				}
251
-			}
252
-		}
253
-		$this->cachedUserGroups[$uid] = $groups;
254
-		return $this->cachedUserGroups[$uid];
255
-	}
236
+    /**
237
+     * @param string $uid the user id
238
+     * @return \OC\Group\Group[]
239
+     */
240
+    public function getUserIdGroups($uid) {
241
+        if (isset($this->cachedUserGroups[$uid])) {
242
+            return $this->cachedUserGroups[$uid];
243
+        }
244
+        $groups = array();
245
+        foreach ($this->backends as $backend) {
246
+            $groupIds = $backend->getUserGroups($uid);
247
+            if (is_array($groupIds)) {
248
+                foreach ($groupIds as $groupId) {
249
+                    $groups[$groupId] = $this->get($groupId);
250
+                }
251
+            }
252
+        }
253
+        $this->cachedUserGroups[$uid] = $groups;
254
+        return $this->cachedUserGroups[$uid];
255
+    }
256 256
 
257
-	/**
258
-	 * Checks if a userId is in the admin group
259
-	 * @param string $userId
260
-	 * @return bool if admin
261
-	 */
262
-	public function isAdmin($userId) {
263
-		return $this->isInGroup($userId, 'admin');
264
-	}
257
+    /**
258
+     * Checks if a userId is in the admin group
259
+     * @param string $userId
260
+     * @return bool if admin
261
+     */
262
+    public function isAdmin($userId) {
263
+        return $this->isInGroup($userId, 'admin');
264
+    }
265 265
 
266
-	/**
267
-	 * Checks if a userId is in a group
268
-	 * @param string $userId
269
-	 * @param string $group
270
-	 * @return bool if in group
271
-	 */
272
-	public function isInGroup($userId, $group) {
273
-		return array_key_exists($group, $this->getUserIdGroups($userId));
274
-	}
266
+    /**
267
+     * Checks if a userId is in a group
268
+     * @param string $userId
269
+     * @param string $group
270
+     * @return bool if in group
271
+     */
272
+    public function isInGroup($userId, $group) {
273
+        return array_key_exists($group, $this->getUserIdGroups($userId));
274
+    }
275 275
 
276
-	/**
277
-	 * get a list of group ids for a user
278
-	 * @param \OC\User\User $user
279
-	 * @return array with group ids
280
-	 */
281
-	public function getUserGroupIds($user) {
282
-		return array_map(function($value) {
283
-			return (string) $value;
284
-		}, array_keys($this->getUserGroups($user)));
285
-	}
276
+    /**
277
+     * get a list of group ids for a user
278
+     * @param \OC\User\User $user
279
+     * @return array with group ids
280
+     */
281
+    public function getUserGroupIds($user) {
282
+        return array_map(function($value) {
283
+            return (string) $value;
284
+        }, array_keys($this->getUserGroups($user)));
285
+    }
286 286
 
287
-	/**
288
-	 * get a list of all display names in a group
289
-	 * @param string $gid
290
-	 * @param string $search
291
-	 * @param int $limit
292
-	 * @param int $offset
293
-	 * @return array an array of display names (value) and user ids (key)
294
-	 */
295
-	public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) {
296
-		$group = $this->get($gid);
297
-		if(is_null($group)) {
298
-			return array();
299
-		}
287
+    /**
288
+     * get a list of all display names in a group
289
+     * @param string $gid
290
+     * @param string $search
291
+     * @param int $limit
292
+     * @param int $offset
293
+     * @return array an array of display names (value) and user ids (key)
294
+     */
295
+    public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) {
296
+        $group = $this->get($gid);
297
+        if(is_null($group)) {
298
+            return array();
299
+        }
300 300
 
301
-		$search = trim($search);
302
-		$groupUsers = array();
301
+        $search = trim($search);
302
+        $groupUsers = array();
303 303
 
304
-		if(!empty($search)) {
305
-			// only user backends have the capability to do a complex search for users
306
-			$searchOffset = 0;
307
-			$searchLimit = $limit * 100;
308
-			if($limit === -1) {
309
-				$searchLimit = 500;
310
-			}
304
+        if(!empty($search)) {
305
+            // only user backends have the capability to do a complex search for users
306
+            $searchOffset = 0;
307
+            $searchLimit = $limit * 100;
308
+            if($limit === -1) {
309
+                $searchLimit = 500;
310
+            }
311 311
 
312
-			do {
313
-				$filteredUsers = $this->userManager->searchDisplayName($search, $searchLimit, $searchOffset);
314
-				foreach($filteredUsers as $filteredUser) {
315
-					if($group->inGroup($filteredUser)) {
316
-						$groupUsers[]= $filteredUser;
317
-					}
318
-				}
319
-				$searchOffset += $searchLimit;
320
-			} while(count($groupUsers) < $searchLimit+$offset && count($filteredUsers) >= $searchLimit);
312
+            do {
313
+                $filteredUsers = $this->userManager->searchDisplayName($search, $searchLimit, $searchOffset);
314
+                foreach($filteredUsers as $filteredUser) {
315
+                    if($group->inGroup($filteredUser)) {
316
+                        $groupUsers[]= $filteredUser;
317
+                    }
318
+                }
319
+                $searchOffset += $searchLimit;
320
+            } while(count($groupUsers) < $searchLimit+$offset && count($filteredUsers) >= $searchLimit);
321 321
 
322
-			if($limit === -1) {
323
-				$groupUsers = array_slice($groupUsers, $offset);
324
-			} else {
325
-				$groupUsers = array_slice($groupUsers, $offset, $limit);
326
-			}
327
-		} else {
328
-			$groupUsers = $group->searchUsers('', $limit, $offset);
329
-		}
322
+            if($limit === -1) {
323
+                $groupUsers = array_slice($groupUsers, $offset);
324
+            } else {
325
+                $groupUsers = array_slice($groupUsers, $offset, $limit);
326
+            }
327
+        } else {
328
+            $groupUsers = $group->searchUsers('', $limit, $offset);
329
+        }
330 330
 
331
-		$matchingUsers = array();
332
-		foreach($groupUsers as $groupUser) {
333
-			$matchingUsers[$groupUser->getUID()] = $groupUser->getDisplayName();
334
-		}
335
-		return $matchingUsers;
336
-	}
331
+        $matchingUsers = array();
332
+        foreach($groupUsers as $groupUser) {
333
+            $matchingUsers[$groupUser->getUID()] = $groupUser->getDisplayName();
334
+        }
335
+        return $matchingUsers;
336
+    }
337 337
 
338
-	/**
339
-	 * @return \OC\SubAdmin
340
-	 */
341
-	public function getSubAdmin() {
342
-		if (!$this->subAdmin) {
343
-			$this->subAdmin = new \OC\SubAdmin(
344
-				$this->userManager,
345
-				$this,
346
-				\OC::$server->getDatabaseConnection()
347
-			);
348
-		}
338
+    /**
339
+     * @return \OC\SubAdmin
340
+     */
341
+    public function getSubAdmin() {
342
+        if (!$this->subAdmin) {
343
+            $this->subAdmin = new \OC\SubAdmin(
344
+                $this->userManager,
345
+                $this,
346
+                \OC::$server->getDatabaseConnection()
347
+            );
348
+        }
349 349
 
350
-		return $this->subAdmin;
351
-	}
350
+        return $this->subAdmin;
351
+    }
352 352
 }
Please login to merge, or discard this patch.
lib/private/Installer.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -482,7 +482,7 @@
 block discarded – undo
482 482
 
483 483
 	/**
484 484
 	 * Removes an app
485
-	 * @param string $name name of the application to remove
485
+	 * @param string $appId
486 486
 	 * @return boolean
487 487
 	 *
488 488
 	 *
Please login to merge, or discard this patch.
Indentation   +586 added lines, -586 removed lines patch added patch discarded remove patch
@@ -53,590 +53,590 @@
 block discarded – undo
53 53
  */
54 54
 class Installer {
55 55
 
56
-	/**
57
-	 *
58
-	 * This function installs an app. All information needed are passed in the
59
-	 * associative array $data.
60
-	 * The following keys are required:
61
-	 *   - source: string, can be "path" or "http"
62
-	 *
63
-	 * One of the following keys is required:
64
-	 *   - path: path to the file containing the app
65
-	 *   - href: link to the downloadable file containing the app
66
-	 *
67
-	 * The following keys are optional:
68
-	 *   - pretend: boolean, if set true the system won't do anything
69
-	 *   - noinstall: boolean, if true appinfo/install.php won't be loaded
70
-	 *   - inactive: boolean, if set true the appconfig/app.sample.php won't be
71
-	 *     renamed
72
-	 *
73
-	 * This function works as follows
74
-	 *   -# fetching the file
75
-	 *   -# unzipping it
76
-	 *   -# check the code
77
-	 *   -# installing the database at appinfo/database.xml
78
-	 *   -# including appinfo/install.php
79
-	 *   -# setting the installed version
80
-	 *
81
-	 * It is the task of oc_app_install to create the tables and do whatever is
82
-	 * needed to get the app working.
83
-	 *
84
-	 * Installs an app
85
-	 * @param array $data with all information
86
-	 * @throws \Exception
87
-	 * @return integer
88
-	 */
89
-	public static function installApp( $data = array()) {
90
-		$l = \OC::$server->getL10N('lib');
91
-
92
-		list($extractDir, $path) = self::downloadApp($data);
93
-
94
-		$info = self::checkAppsIntegrity($data, $extractDir, $path);
95
-		$appId = OC_App::cleanAppId($info['id']);
96
-		$basedir = OC_App::getInstallPath().'/'.$appId;
97
-		//check if the destination directory already exists
98
-		if(is_dir($basedir)) {
99
-			OC_Helper::rmdirr($extractDir);
100
-			if($data['source']=='http') {
101
-				unlink($path);
102
-			}
103
-			throw new \Exception($l->t("App directory already exists"));
104
-		}
105
-
106
-		if(!empty($data['pretent'])) {
107
-			return false;
108
-		}
109
-
110
-		//copy the app to the correct place
111
-		if(@!mkdir($basedir)) {
112
-			OC_Helper::rmdirr($extractDir);
113
-			if($data['source']=='http') {
114
-				unlink($path);
115
-			}
116
-			throw new \Exception($l->t("Can't create app folder. Please fix permissions. %s", array($basedir)));
117
-		}
118
-
119
-		$extractDir .= '/' . $info['id'];
120
-		if(!file_exists($extractDir)) {
121
-			OC_Helper::rmdirr($basedir);
122
-			throw new \Exception($l->t("Archive does not contain a directory named %s", $info['id']));
123
-		}
124
-		OC_Helper::copyr($extractDir, $basedir);
125
-
126
-		//remove temporary files
127
-		OC_Helper::rmdirr($extractDir);
128
-
129
-		//install the database
130
-		if(is_file($basedir.'/appinfo/database.xml')) {
131
-			if (\OC::$server->getAppConfig()->getValue($info['id'], 'installed_version') === null) {
132
-				OC_DB::createDbFromStructure($basedir.'/appinfo/database.xml');
133
-			} else {
134
-				OC_DB::updateDbFromStructure($basedir.'/appinfo/database.xml');
135
-			}
136
-		}
137
-
138
-		\OC_App::setupBackgroundJobs($info['background-jobs']);
139
-
140
-		//run appinfo/install.php
141
-		if((!isset($data['noinstall']) or $data['noinstall']==false)) {
142
-			self::includeAppScript($basedir . '/appinfo/install.php');
143
-		}
144
-
145
-		$appData = OC_App::getAppInfo($appId);
146
-		OC_App::executeRepairSteps($appId, $appData['repair-steps']['install']);
147
-
148
-		//set the installed version
149
-		\OC::$server->getConfig()->setAppValue($info['id'], 'installed_version', OC_App::getAppVersion($info['id']));
150
-		\OC::$server->getConfig()->setAppValue($info['id'], 'enabled', 'no');
151
-
152
-		//set remote/public handlers
153
-		foreach($info['remote'] as $name=>$path) {
154
-			\OC::$server->getConfig()->setAppValue('core', 'remote_'.$name, $info['id'].'/'.$path);
155
-		}
156
-		foreach($info['public'] as $name=>$path) {
157
-			\OC::$server->getConfig()->setAppValue('core', 'public_'.$name, $info['id'].'/'.$path);
158
-		}
159
-
160
-		OC_App::setAppTypes($info['id']);
161
-
162
-		return $info['id'];
163
-	}
164
-
165
-	/**
166
-	 * @brief checks whether or not an app is installed
167
-	 * @param string $app app
168
-	 * @returns bool
169
-	 *
170
-	 * Checks whether or not an app is installed, i.e. registered in apps table.
171
-	 */
172
-	public static function 	isInstalled( $app ) {
173
-		return (\OC::$server->getConfig()->getAppValue($app, "installed_version", null) !== null);
174
-	}
175
-
176
-	/**
177
-	 * @brief Update an application
178
-	 * @param array $info
179
-	 * @param bool $isShipped
180
-	 * @throws \Exception
181
-	 * @return bool
182
-	 *
183
-	 * This function could work like described below, but currently it disables and then
184
-	 * enables the app again. This does result in an updated app.
185
-	 *
186
-	 *
187
-	 * This function installs an app. All information needed are passed in the
188
-	 * associative array $info.
189
-	 * The following keys are required:
190
-	 *   - source: string, can be "path" or "http"
191
-	 *
192
-	 * One of the following keys is required:
193
-	 *   - path: path to the file containing the app
194
-	 *   - href: link to the downloadable file containing the app
195
-	 *
196
-	 * The following keys are optional:
197
-	 *   - pretend: boolean, if set true the system won't do anything
198
-	 *   - noupgrade: boolean, if true appinfo/upgrade.php won't be loaded
199
-	 *
200
-	 * This function works as follows
201
-	 *   -# fetching the file
202
-	 *   -# removing the old files
203
-	 *   -# unzipping new file
204
-	 *   -# including appinfo/upgrade.php
205
-	 *   -# setting the installed version
206
-	 *
207
-	 * upgrade.php can determine the current installed version of the app using
208
-	 * "\OC::$server->getAppConfig()->getValue($appid, 'installed_version')"
209
-	 */
210
-	public static function updateApp($info=array(), $isShipped=false) {
211
-		list($extractDir, $path) = self::downloadApp($info);
212
-		$info = self::checkAppsIntegrity($info, $extractDir, $path, $isShipped);
213
-
214
-		$currentDir = OC_App::getAppPath($info['id']);
215
-		$basedir  = OC_App::getInstallPath();
216
-		$basedir .= '/';
217
-		$basedir .= $info['id'];
218
-
219
-		if($currentDir !== false && is_writable($currentDir)) {
220
-			$basedir = $currentDir;
221
-		}
222
-		if(is_dir($basedir)) {
223
-			OC_Helper::rmdirr($basedir);
224
-		}
225
-
226
-		$appInExtractDir = $extractDir;
227
-		if (substr($extractDir, -1) !== '/') {
228
-			$appInExtractDir .= '/';
229
-		}
230
-
231
-		$appInExtractDir .= $info['id'];
232
-		OC_Helper::copyr($appInExtractDir, $basedir);
233
-		OC_Helper::rmdirr($extractDir);
234
-
235
-		return OC_App::updateApp($info['id']);
236
-	}
237
-
238
-	/**
239
-	 * update an app by it's id
240
-	 *
241
-	 * @param integer $ocsId
242
-	 * @return bool
243
-	 * @throws \Exception
244
-	 */
245
-	public static function updateAppByOCSId($ocsId) {
246
-		$ocsClient = new OCSClient(
247
-			\OC::$server->getHTTPClientService(),
248
-			\OC::$server->getConfig(),
249
-			\OC::$server->getLogger()
250
-		);
251
-		$appData = $ocsClient->getApplication($ocsId, \OCP\Util::getVersion());
252
-		$download = $ocsClient->getApplicationDownload($ocsId, \OCP\Util::getVersion());
253
-
254
-		if (isset($download['downloadlink']) && trim($download['downloadlink']) !== '') {
255
-			$download['downloadlink'] = str_replace(' ', '%20', $download['downloadlink']);
256
-			$info = array(
257
-				'source' => 'http',
258
-				'href' => $download['downloadlink'],
259
-				'appdata' => $appData
260
-			);
261
-		} else {
262
-			throw new \Exception('Could not fetch app info!');
263
-		}
264
-
265
-		return self::updateApp($info);
266
-	}
267
-
268
-	/**
269
-	 * @param array $data
270
-	 * @return array
271
-	 * @throws \Exception
272
-	 */
273
-	public static function downloadApp($data = array()) {
274
-		$l = \OC::$server->getL10N('lib');
275
-
276
-		if(!isset($data['source'])) {
277
-			throw new \Exception($l->t("No source specified when installing app"));
278
-		}
279
-
280
-		//download the file if necessary
281
-		if($data['source']=='http') {
282
-			$pathInfo = pathinfo($data['href']);
283
-			$extension = isset($pathInfo['extension']) ? '.' . $pathInfo['extension'] : '';
284
-			$path = \OC::$server->getTempManager()->getTemporaryFile($extension);
285
-			if(!isset($data['href'])) {
286
-				throw new \Exception($l->t("No href specified when installing app from http"));
287
-			}
288
-			$client = \OC::$server->getHTTPClientService()->newClient();
289
-			$client->get($data['href'], ['save_to' => $path]);
290
-		} else {
291
-			if(!isset($data['path'])) {
292
-				throw new \Exception($l->t("No path specified when installing app from local file"));
293
-			}
294
-			$path=$data['path'];
295
-		}
296
-
297
-		//detect the archive type
298
-		$mime = \OC::$server->getMimeTypeDetector()->detect($path);
299
-		if ($mime !=='application/zip' && $mime !== 'application/x-gzip' && $mime !== 'application/x-bzip2') {
300
-			throw new \Exception($l->t("Archives of type %s are not supported", array($mime)));
301
-		}
302
-
303
-		//extract the archive in a temporary folder
304
-		$extractDir = \OC::$server->getTempManager()->getTemporaryFolder();
305
-		OC_Helper::rmdirr($extractDir);
306
-		mkdir($extractDir);
307
-		if($archive=\OC\Archive\Archive::open($path)) {
308
-			$archive->extract($extractDir);
309
-		} else {
310
-			OC_Helper::rmdirr($extractDir);
311
-			if($data['source']=='http') {
312
-				unlink($path);
313
-			}
314
-			throw new \Exception($l->t("Failed to open archive when installing app"));
315
-		}
316
-
317
-		return array(
318
-			$extractDir,
319
-			$path
320
-		);
321
-	}
322
-
323
-	/**
324
-	 * check an app's integrity
325
-	 * @param array $data
326
-	 * @param string $extractDir
327
-	 * @param string $path
328
-	 * @param bool $isShipped
329
-	 * @return array
330
-	 * @throws \Exception
331
-	 */
332
-	public static function checkAppsIntegrity($data, $extractDir, $path, $isShipped = false) {
333
-		$l = \OC::$server->getL10N('lib');
334
-		//load the info.xml file of the app
335
-		if(!is_file($extractDir.'/appinfo/info.xml')) {
336
-			//try to find it in a subdir
337
-			$dh=opendir($extractDir);
338
-			if(is_resource($dh)) {
339
-				while (($folder = readdir($dh)) !== false) {
340
-					if($folder[0]!='.' and is_dir($extractDir.'/'.$folder)) {
341
-						if(is_file($extractDir.'/'.$folder.'/appinfo/info.xml')) {
342
-							$extractDir.='/'.$folder;
343
-						}
344
-					}
345
-				}
346
-			}
347
-		}
348
-		if(!is_file($extractDir.'/appinfo/info.xml')) {
349
-			OC_Helper::rmdirr($extractDir);
350
-			if($data['source'] === 'http') {
351
-				unlink($path);
352
-			}
353
-			throw new \Exception($l->t("App does not provide an info.xml file"));
354
-		}
355
-
356
-		$info = OC_App::getAppInfo($extractDir.'/appinfo/info.xml', true);
357
-		if(!is_array($info)) {
358
-			throw new \Exception($l->t('App cannot be installed because appinfo file cannot be read.'));
359
-		}
360
-
361
-		// We can't trust the parsed info.xml file as it may have been tampered
362
-		// with by an attacker and thus we need to use the local data to check
363
-		// whether the application needs to be signed.
364
-		$appId = OC_App::cleanAppId($data['appdata']['id']);
365
-		$appBelongingToId = OC_App::getInternalAppIdByOcs($appId);
366
-		if(is_string($appBelongingToId)) {
367
-			$previouslySigned = \OC::$server->getConfig()->getAppValue($appBelongingToId, 'signed', 'false');
368
-		} else {
369
-			$appBelongingToId = $info['id'];
370
-			$previouslySigned = 'false';
371
-		}
372
-		if($data['appdata']['level'] === OC_App::officialApp || $previouslySigned === 'true') {
373
-			\OC::$server->getConfig()->setAppValue($appBelongingToId, 'signed', 'true');
374
-			$integrityResult = \OC::$server->getIntegrityCodeChecker()->verifyAppSignature(
375
-					$appBelongingToId,
376
-					$extractDir
377
-			);
378
-			if($integrityResult !== []) {
379
-				$e = new \Exception(
380
-						$l->t(
381
-								'Signature could not get checked. Please contact the app developer and check your admin screen.'
382
-						)
383
-				);
384
-				throw $e;
385
-			}
386
-		}
387
-
388
-		// check the code for not allowed calls
389
-		if(!$isShipped && !Installer::checkCode($extractDir)) {
390
-			OC_Helper::rmdirr($extractDir);
391
-			throw new \Exception($l->t("App can't be installed because of not allowed code in the App"));
392
-		}
393
-
394
-		// check if the app is compatible with this version of ownCloud
395
-		if(!OC_App::isAppCompatible(\OCP\Util::getVersion(), $info)) {
396
-			OC_Helper::rmdirr($extractDir);
397
-			throw new \Exception($l->t("App can't be installed because it is not compatible with this version of the server"));
398
-		}
399
-
400
-		// check if shipped tag is set which is only allowed for apps that are shipped with ownCloud
401
-		if(!$isShipped && isset($info['shipped']) && ($info['shipped']=='true')) {
402
-			OC_Helper::rmdirr($extractDir);
403
-			throw new \Exception($l->t("App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps"));
404
-		}
405
-
406
-		// check if the ocs version is the same as the version in info.xml/version
407
-		$version = trim($info['version']);
408
-
409
-		if(isset($data['appdata']['version']) && $version<>trim($data['appdata']['version'])) {
410
-			OC_Helper::rmdirr($extractDir);
411
-			throw new \Exception($l->t("App can't be installed because the version in info.xml is not the same as the version reported from the app store"));
412
-		}
413
-
414
-		return $info;
415
-	}
416
-
417
-	/**
418
-	 * Check if an update for the app is available
419
-	 * @param string $app
420
-	 * @return string|false false or the version number of the update
421
-	 *
422
-	 * The function will check if an update for a version is available
423
-	 */
424
-	public static function isUpdateAvailable( $app ) {
425
-		static $isInstanceReadyForUpdates = null;
426
-
427
-		if ($isInstanceReadyForUpdates === null) {
428
-			$installPath = OC_App::getInstallPath();
429
-			if ($installPath === false || $installPath === null) {
430
-				$isInstanceReadyForUpdates = false;
431
-			} else {
432
-				$isInstanceReadyForUpdates = true;
433
-			}
434
-		}
435
-
436
-		if ($isInstanceReadyForUpdates === false) {
437
-			return false;
438
-		}
439
-
440
-		$ocsid=\OC::$server->getAppConfig()->getValue( $app, 'ocsid', '');
441
-
442
-		if($ocsid<>'') {
443
-			$ocsClient = new OCSClient(
444
-				\OC::$server->getHTTPClientService(),
445
-				\OC::$server->getConfig(),
446
-				\OC::$server->getLogger()
447
-			);
448
-			$ocsdata = $ocsClient->getApplication($ocsid, \OCP\Util::getVersion());
449
-			$ocsversion= (string) $ocsdata['version'];
450
-			$currentversion=OC_App::getAppVersion($app);
451
-			if (version_compare($ocsversion, $currentversion, '>')) {
452
-				return($ocsversion);
453
-			}else{
454
-				return false;
455
-			}
456
-
457
-		}else{
458
-			return false;
459
-		}
460
-
461
-	}
462
-
463
-	/**
464
-	 * Check if app is already downloaded
465
-	 * @param string $name name of the application to remove
466
-	 * @return boolean
467
-	 *
468
-	 * The function will check if the app is already downloaded in the apps repository
469
-	 */
470
-	public static function isDownloaded( $name ) {
471
-		foreach(\OC::$APPSROOTS as $dir) {
472
-			$dirToTest  = $dir['path'];
473
-			$dirToTest .= '/';
474
-			$dirToTest .= $name;
475
-			$dirToTest .= '/';
476
-
477
-			if (is_dir($dirToTest)) {
478
-				return true;
479
-			}
480
-		}
481
-
482
-		return false;
483
-	}
484
-
485
-	/**
486
-	 * Removes an app
487
-	 * @param string $name name of the application to remove
488
-	 * @return boolean
489
-	 *
490
-	 *
491
-	 * This function works as follows
492
-	 *   -# call uninstall repair steps
493
-	 *   -# removing the files
494
-	 *
495
-	 * The function will not delete preferences, tables and the configuration,
496
-	 * this has to be done by the function oc_app_uninstall().
497
-	 */
498
-	public static function removeApp($appId) {
499
-
500
-		if(Installer::isDownloaded( $appId )) {
501
-			$appDir=OC_App::getInstallPath() . '/' . $appId;
502
-			OC_Helper::rmdirr($appDir);
503
-
504
-			return true;
505
-		}else{
506
-			\OCP\Util::writeLog('core', 'can\'t remove app '.$appId.'. It is not installed.', \OCP\Util::ERROR);
507
-
508
-			return false;
509
-		}
510
-
511
-	}
512
-
513
-	/**
514
-	 * Installs shipped apps
515
-	 *
516
-	 * This function installs all apps found in the 'apps' directory that should be enabled by default;
517
-	 * @param bool $softErrors When updating we ignore errors and simply log them, better to have a
518
-	 *                         working ownCloud at the end instead of an aborted update.
519
-	 * @return array Array of error messages (appid => Exception)
520
-	 */
521
-	public static function installShippedApps($softErrors = false) {
522
-		$errors = [];
523
-		foreach(\OC::$APPSROOTS as $app_dir) {
524
-			if($dir = opendir( $app_dir['path'] )) {
525
-				while( false !== ( $filename = readdir( $dir ))) {
526
-					if( substr( $filename, 0, 1 ) != '.' and is_dir($app_dir['path']."/$filename") ) {
527
-						if( file_exists( $app_dir['path']."/$filename/appinfo/info.xml" )) {
528
-							if(!Installer::isInstalled($filename)) {
529
-								$info=OC_App::getAppInfo($filename);
530
-								$enabled = isset($info['default_enable']);
531
-								if (($enabled || in_array($filename, \OC::$server->getAppManager()->getAlwaysEnabledApps()))
532
-									  && \OC::$server->getConfig()->getAppValue($filename, 'enabled') !== 'no') {
533
-									if ($softErrors) {
534
-										try {
535
-											Installer::installShippedApp($filename);
536
-										} catch (HintException $e) {
537
-											if ($e->getPrevious() instanceof TableExistsException) {
538
-												$errors[$filename] = $e;
539
-												continue;
540
-											}
541
-											throw $e;
542
-										}
543
-									} else {
544
-										Installer::installShippedApp($filename);
545
-									}
546
-									\OC::$server->getConfig()->setAppValue($filename, 'enabled', 'yes');
547
-								}
548
-							}
549
-						}
550
-					}
551
-				}
552
-				closedir( $dir );
553
-			}
554
-		}
555
-
556
-		return $errors;
557
-	}
558
-
559
-	/**
560
-	 * install an app already placed in the app folder
561
-	 * @param string $app id of the app to install
562
-	 * @return integer
563
-	 */
564
-	public static function installShippedApp($app) {
565
-		//install the database
566
-		$appPath = OC_App::getAppPath($app);
567
-		if(is_file("$appPath/appinfo/database.xml")) {
568
-			try {
569
-				OC_DB::createDbFromStructure("$appPath/appinfo/database.xml");
570
-			} catch (TableExistsException $e) {
571
-				throw new HintException(
572
-					'Failed to enable app ' . $app,
573
-					'Please ask for help via one of our <a href="https://nextcloud.com/support/" target="_blank" rel="noreferrer">support channels</a>.',
574
-					0, $e
575
-				);
576
-			}
577
-		}
578
-
579
-		//run appinfo/install.php
580
-		\OC_App::registerAutoloading($app, $appPath);
581
-		self::includeAppScript("$appPath/appinfo/install.php");
582
-
583
-		$info = OC_App::getAppInfo($app);
584
-		if (is_null($info)) {
585
-			return false;
586
-		}
587
-		\OC_App::setupBackgroundJobs($info['background-jobs']);
588
-
589
-		OC_App::executeRepairSteps($app, $info['repair-steps']['install']);
590
-
591
-		$config = \OC::$server->getConfig();
592
-
593
-		$config->setAppValue($app, 'installed_version', OC_App::getAppVersion($app));
594
-		if (array_key_exists('ocsid', $info)) {
595
-			$config->setAppValue($app, 'ocsid', $info['ocsid']);
596
-		}
597
-
598
-		//set remote/public handlers
599
-		foreach($info['remote'] as $name=>$path) {
600
-			$config->setAppValue('core', 'remote_'.$name, $app.'/'.$path);
601
-		}
602
-		foreach($info['public'] as $name=>$path) {
603
-			$config->setAppValue('core', 'public_'.$name, $app.'/'.$path);
604
-		}
605
-
606
-		OC_App::setAppTypes($info['id']);
607
-
608
-		if(isset($info['settings']) && is_array($info['settings'])) {
609
-			// requires that autoloading was registered for the app,
610
-			// as happens before running the install.php some lines above
611
-			\OC::$server->getSettingsManager()->setupSettings($info['settings']);
612
-		}
613
-
614
-		return $info['id'];
615
-	}
616
-
617
-	/**
618
-	 * check the code of an app with some static code checks
619
-	 * @param string $folder the folder of the app to check
620
-	 * @return boolean true for app is o.k. and false for app is not o.k.
621
-	 */
622
-	public static function checkCode($folder) {
623
-		// is the code checker enabled?
624
-		if(!\OC::$server->getConfig()->getSystemValue('appcodechecker', false)) {
625
-			return true;
626
-		}
627
-
628
-		$codeChecker = new CodeChecker(new PrivateCheck(new EmptyCheck()));
629
-		$errors = $codeChecker->analyseFolder(basename($folder), $folder);
630
-
631
-		return empty($errors);
632
-	}
633
-
634
-	/**
635
-	 * @param $basedir
636
-	 */
637
-	private static function includeAppScript($script) {
638
-		if ( file_exists($script) ){
639
-			include $script;
640
-		}
641
-	}
56
+    /**
57
+     *
58
+     * This function installs an app. All information needed are passed in the
59
+     * associative array $data.
60
+     * The following keys are required:
61
+     *   - source: string, can be "path" or "http"
62
+     *
63
+     * One of the following keys is required:
64
+     *   - path: path to the file containing the app
65
+     *   - href: link to the downloadable file containing the app
66
+     *
67
+     * The following keys are optional:
68
+     *   - pretend: boolean, if set true the system won't do anything
69
+     *   - noinstall: boolean, if true appinfo/install.php won't be loaded
70
+     *   - inactive: boolean, if set true the appconfig/app.sample.php won't be
71
+     *     renamed
72
+     *
73
+     * This function works as follows
74
+     *   -# fetching the file
75
+     *   -# unzipping it
76
+     *   -# check the code
77
+     *   -# installing the database at appinfo/database.xml
78
+     *   -# including appinfo/install.php
79
+     *   -# setting the installed version
80
+     *
81
+     * It is the task of oc_app_install to create the tables and do whatever is
82
+     * needed to get the app working.
83
+     *
84
+     * Installs an app
85
+     * @param array $data with all information
86
+     * @throws \Exception
87
+     * @return integer
88
+     */
89
+    public static function installApp( $data = array()) {
90
+        $l = \OC::$server->getL10N('lib');
91
+
92
+        list($extractDir, $path) = self::downloadApp($data);
93
+
94
+        $info = self::checkAppsIntegrity($data, $extractDir, $path);
95
+        $appId = OC_App::cleanAppId($info['id']);
96
+        $basedir = OC_App::getInstallPath().'/'.$appId;
97
+        //check if the destination directory already exists
98
+        if(is_dir($basedir)) {
99
+            OC_Helper::rmdirr($extractDir);
100
+            if($data['source']=='http') {
101
+                unlink($path);
102
+            }
103
+            throw new \Exception($l->t("App directory already exists"));
104
+        }
105
+
106
+        if(!empty($data['pretent'])) {
107
+            return false;
108
+        }
109
+
110
+        //copy the app to the correct place
111
+        if(@!mkdir($basedir)) {
112
+            OC_Helper::rmdirr($extractDir);
113
+            if($data['source']=='http') {
114
+                unlink($path);
115
+            }
116
+            throw new \Exception($l->t("Can't create app folder. Please fix permissions. %s", array($basedir)));
117
+        }
118
+
119
+        $extractDir .= '/' . $info['id'];
120
+        if(!file_exists($extractDir)) {
121
+            OC_Helper::rmdirr($basedir);
122
+            throw new \Exception($l->t("Archive does not contain a directory named %s", $info['id']));
123
+        }
124
+        OC_Helper::copyr($extractDir, $basedir);
125
+
126
+        //remove temporary files
127
+        OC_Helper::rmdirr($extractDir);
128
+
129
+        //install the database
130
+        if(is_file($basedir.'/appinfo/database.xml')) {
131
+            if (\OC::$server->getAppConfig()->getValue($info['id'], 'installed_version') === null) {
132
+                OC_DB::createDbFromStructure($basedir.'/appinfo/database.xml');
133
+            } else {
134
+                OC_DB::updateDbFromStructure($basedir.'/appinfo/database.xml');
135
+            }
136
+        }
137
+
138
+        \OC_App::setupBackgroundJobs($info['background-jobs']);
139
+
140
+        //run appinfo/install.php
141
+        if((!isset($data['noinstall']) or $data['noinstall']==false)) {
142
+            self::includeAppScript($basedir . '/appinfo/install.php');
143
+        }
144
+
145
+        $appData = OC_App::getAppInfo($appId);
146
+        OC_App::executeRepairSteps($appId, $appData['repair-steps']['install']);
147
+
148
+        //set the installed version
149
+        \OC::$server->getConfig()->setAppValue($info['id'], 'installed_version', OC_App::getAppVersion($info['id']));
150
+        \OC::$server->getConfig()->setAppValue($info['id'], 'enabled', 'no');
151
+
152
+        //set remote/public handlers
153
+        foreach($info['remote'] as $name=>$path) {
154
+            \OC::$server->getConfig()->setAppValue('core', 'remote_'.$name, $info['id'].'/'.$path);
155
+        }
156
+        foreach($info['public'] as $name=>$path) {
157
+            \OC::$server->getConfig()->setAppValue('core', 'public_'.$name, $info['id'].'/'.$path);
158
+        }
159
+
160
+        OC_App::setAppTypes($info['id']);
161
+
162
+        return $info['id'];
163
+    }
164
+
165
+    /**
166
+     * @brief checks whether or not an app is installed
167
+     * @param string $app app
168
+     * @returns bool
169
+     *
170
+     * Checks whether or not an app is installed, i.e. registered in apps table.
171
+     */
172
+    public static function 	isInstalled( $app ) {
173
+        return (\OC::$server->getConfig()->getAppValue($app, "installed_version", null) !== null);
174
+    }
175
+
176
+    /**
177
+     * @brief Update an application
178
+     * @param array $info
179
+     * @param bool $isShipped
180
+     * @throws \Exception
181
+     * @return bool
182
+     *
183
+     * This function could work like described below, but currently it disables and then
184
+     * enables the app again. This does result in an updated app.
185
+     *
186
+     *
187
+     * This function installs an app. All information needed are passed in the
188
+     * associative array $info.
189
+     * The following keys are required:
190
+     *   - source: string, can be "path" or "http"
191
+     *
192
+     * One of the following keys is required:
193
+     *   - path: path to the file containing the app
194
+     *   - href: link to the downloadable file containing the app
195
+     *
196
+     * The following keys are optional:
197
+     *   - pretend: boolean, if set true the system won't do anything
198
+     *   - noupgrade: boolean, if true appinfo/upgrade.php won't be loaded
199
+     *
200
+     * This function works as follows
201
+     *   -# fetching the file
202
+     *   -# removing the old files
203
+     *   -# unzipping new file
204
+     *   -# including appinfo/upgrade.php
205
+     *   -# setting the installed version
206
+     *
207
+     * upgrade.php can determine the current installed version of the app using
208
+     * "\OC::$server->getAppConfig()->getValue($appid, 'installed_version')"
209
+     */
210
+    public static function updateApp($info=array(), $isShipped=false) {
211
+        list($extractDir, $path) = self::downloadApp($info);
212
+        $info = self::checkAppsIntegrity($info, $extractDir, $path, $isShipped);
213
+
214
+        $currentDir = OC_App::getAppPath($info['id']);
215
+        $basedir  = OC_App::getInstallPath();
216
+        $basedir .= '/';
217
+        $basedir .= $info['id'];
218
+
219
+        if($currentDir !== false && is_writable($currentDir)) {
220
+            $basedir = $currentDir;
221
+        }
222
+        if(is_dir($basedir)) {
223
+            OC_Helper::rmdirr($basedir);
224
+        }
225
+
226
+        $appInExtractDir = $extractDir;
227
+        if (substr($extractDir, -1) !== '/') {
228
+            $appInExtractDir .= '/';
229
+        }
230
+
231
+        $appInExtractDir .= $info['id'];
232
+        OC_Helper::copyr($appInExtractDir, $basedir);
233
+        OC_Helper::rmdirr($extractDir);
234
+
235
+        return OC_App::updateApp($info['id']);
236
+    }
237
+
238
+    /**
239
+     * update an app by it's id
240
+     *
241
+     * @param integer $ocsId
242
+     * @return bool
243
+     * @throws \Exception
244
+     */
245
+    public static function updateAppByOCSId($ocsId) {
246
+        $ocsClient = new OCSClient(
247
+            \OC::$server->getHTTPClientService(),
248
+            \OC::$server->getConfig(),
249
+            \OC::$server->getLogger()
250
+        );
251
+        $appData = $ocsClient->getApplication($ocsId, \OCP\Util::getVersion());
252
+        $download = $ocsClient->getApplicationDownload($ocsId, \OCP\Util::getVersion());
253
+
254
+        if (isset($download['downloadlink']) && trim($download['downloadlink']) !== '') {
255
+            $download['downloadlink'] = str_replace(' ', '%20', $download['downloadlink']);
256
+            $info = array(
257
+                'source' => 'http',
258
+                'href' => $download['downloadlink'],
259
+                'appdata' => $appData
260
+            );
261
+        } else {
262
+            throw new \Exception('Could not fetch app info!');
263
+        }
264
+
265
+        return self::updateApp($info);
266
+    }
267
+
268
+    /**
269
+     * @param array $data
270
+     * @return array
271
+     * @throws \Exception
272
+     */
273
+    public static function downloadApp($data = array()) {
274
+        $l = \OC::$server->getL10N('lib');
275
+
276
+        if(!isset($data['source'])) {
277
+            throw new \Exception($l->t("No source specified when installing app"));
278
+        }
279
+
280
+        //download the file if necessary
281
+        if($data['source']=='http') {
282
+            $pathInfo = pathinfo($data['href']);
283
+            $extension = isset($pathInfo['extension']) ? '.' . $pathInfo['extension'] : '';
284
+            $path = \OC::$server->getTempManager()->getTemporaryFile($extension);
285
+            if(!isset($data['href'])) {
286
+                throw new \Exception($l->t("No href specified when installing app from http"));
287
+            }
288
+            $client = \OC::$server->getHTTPClientService()->newClient();
289
+            $client->get($data['href'], ['save_to' => $path]);
290
+        } else {
291
+            if(!isset($data['path'])) {
292
+                throw new \Exception($l->t("No path specified when installing app from local file"));
293
+            }
294
+            $path=$data['path'];
295
+        }
296
+
297
+        //detect the archive type
298
+        $mime = \OC::$server->getMimeTypeDetector()->detect($path);
299
+        if ($mime !=='application/zip' && $mime !== 'application/x-gzip' && $mime !== 'application/x-bzip2') {
300
+            throw new \Exception($l->t("Archives of type %s are not supported", array($mime)));
301
+        }
302
+
303
+        //extract the archive in a temporary folder
304
+        $extractDir = \OC::$server->getTempManager()->getTemporaryFolder();
305
+        OC_Helper::rmdirr($extractDir);
306
+        mkdir($extractDir);
307
+        if($archive=\OC\Archive\Archive::open($path)) {
308
+            $archive->extract($extractDir);
309
+        } else {
310
+            OC_Helper::rmdirr($extractDir);
311
+            if($data['source']=='http') {
312
+                unlink($path);
313
+            }
314
+            throw new \Exception($l->t("Failed to open archive when installing app"));
315
+        }
316
+
317
+        return array(
318
+            $extractDir,
319
+            $path
320
+        );
321
+    }
322
+
323
+    /**
324
+     * check an app's integrity
325
+     * @param array $data
326
+     * @param string $extractDir
327
+     * @param string $path
328
+     * @param bool $isShipped
329
+     * @return array
330
+     * @throws \Exception
331
+     */
332
+    public static function checkAppsIntegrity($data, $extractDir, $path, $isShipped = false) {
333
+        $l = \OC::$server->getL10N('lib');
334
+        //load the info.xml file of the app
335
+        if(!is_file($extractDir.'/appinfo/info.xml')) {
336
+            //try to find it in a subdir
337
+            $dh=opendir($extractDir);
338
+            if(is_resource($dh)) {
339
+                while (($folder = readdir($dh)) !== false) {
340
+                    if($folder[0]!='.' and is_dir($extractDir.'/'.$folder)) {
341
+                        if(is_file($extractDir.'/'.$folder.'/appinfo/info.xml')) {
342
+                            $extractDir.='/'.$folder;
343
+                        }
344
+                    }
345
+                }
346
+            }
347
+        }
348
+        if(!is_file($extractDir.'/appinfo/info.xml')) {
349
+            OC_Helper::rmdirr($extractDir);
350
+            if($data['source'] === 'http') {
351
+                unlink($path);
352
+            }
353
+            throw new \Exception($l->t("App does not provide an info.xml file"));
354
+        }
355
+
356
+        $info = OC_App::getAppInfo($extractDir.'/appinfo/info.xml', true);
357
+        if(!is_array($info)) {
358
+            throw new \Exception($l->t('App cannot be installed because appinfo file cannot be read.'));
359
+        }
360
+
361
+        // We can't trust the parsed info.xml file as it may have been tampered
362
+        // with by an attacker and thus we need to use the local data to check
363
+        // whether the application needs to be signed.
364
+        $appId = OC_App::cleanAppId($data['appdata']['id']);
365
+        $appBelongingToId = OC_App::getInternalAppIdByOcs($appId);
366
+        if(is_string($appBelongingToId)) {
367
+            $previouslySigned = \OC::$server->getConfig()->getAppValue($appBelongingToId, 'signed', 'false');
368
+        } else {
369
+            $appBelongingToId = $info['id'];
370
+            $previouslySigned = 'false';
371
+        }
372
+        if($data['appdata']['level'] === OC_App::officialApp || $previouslySigned === 'true') {
373
+            \OC::$server->getConfig()->setAppValue($appBelongingToId, 'signed', 'true');
374
+            $integrityResult = \OC::$server->getIntegrityCodeChecker()->verifyAppSignature(
375
+                    $appBelongingToId,
376
+                    $extractDir
377
+            );
378
+            if($integrityResult !== []) {
379
+                $e = new \Exception(
380
+                        $l->t(
381
+                                'Signature could not get checked. Please contact the app developer and check your admin screen.'
382
+                        )
383
+                );
384
+                throw $e;
385
+            }
386
+        }
387
+
388
+        // check the code for not allowed calls
389
+        if(!$isShipped && !Installer::checkCode($extractDir)) {
390
+            OC_Helper::rmdirr($extractDir);
391
+            throw new \Exception($l->t("App can't be installed because of not allowed code in the App"));
392
+        }
393
+
394
+        // check if the app is compatible with this version of ownCloud
395
+        if(!OC_App::isAppCompatible(\OCP\Util::getVersion(), $info)) {
396
+            OC_Helper::rmdirr($extractDir);
397
+            throw new \Exception($l->t("App can't be installed because it is not compatible with this version of the server"));
398
+        }
399
+
400
+        // check if shipped tag is set which is only allowed for apps that are shipped with ownCloud
401
+        if(!$isShipped && isset($info['shipped']) && ($info['shipped']=='true')) {
402
+            OC_Helper::rmdirr($extractDir);
403
+            throw new \Exception($l->t("App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps"));
404
+        }
405
+
406
+        // check if the ocs version is the same as the version in info.xml/version
407
+        $version = trim($info['version']);
408
+
409
+        if(isset($data['appdata']['version']) && $version<>trim($data['appdata']['version'])) {
410
+            OC_Helper::rmdirr($extractDir);
411
+            throw new \Exception($l->t("App can't be installed because the version in info.xml is not the same as the version reported from the app store"));
412
+        }
413
+
414
+        return $info;
415
+    }
416
+
417
+    /**
418
+     * Check if an update for the app is available
419
+     * @param string $app
420
+     * @return string|false false or the version number of the update
421
+     *
422
+     * The function will check if an update for a version is available
423
+     */
424
+    public static function isUpdateAvailable( $app ) {
425
+        static $isInstanceReadyForUpdates = null;
426
+
427
+        if ($isInstanceReadyForUpdates === null) {
428
+            $installPath = OC_App::getInstallPath();
429
+            if ($installPath === false || $installPath === null) {
430
+                $isInstanceReadyForUpdates = false;
431
+            } else {
432
+                $isInstanceReadyForUpdates = true;
433
+            }
434
+        }
435
+
436
+        if ($isInstanceReadyForUpdates === false) {
437
+            return false;
438
+        }
439
+
440
+        $ocsid=\OC::$server->getAppConfig()->getValue( $app, 'ocsid', '');
441
+
442
+        if($ocsid<>'') {
443
+            $ocsClient = new OCSClient(
444
+                \OC::$server->getHTTPClientService(),
445
+                \OC::$server->getConfig(),
446
+                \OC::$server->getLogger()
447
+            );
448
+            $ocsdata = $ocsClient->getApplication($ocsid, \OCP\Util::getVersion());
449
+            $ocsversion= (string) $ocsdata['version'];
450
+            $currentversion=OC_App::getAppVersion($app);
451
+            if (version_compare($ocsversion, $currentversion, '>')) {
452
+                return($ocsversion);
453
+            }else{
454
+                return false;
455
+            }
456
+
457
+        }else{
458
+            return false;
459
+        }
460
+
461
+    }
462
+
463
+    /**
464
+     * Check if app is already downloaded
465
+     * @param string $name name of the application to remove
466
+     * @return boolean
467
+     *
468
+     * The function will check if the app is already downloaded in the apps repository
469
+     */
470
+    public static function isDownloaded( $name ) {
471
+        foreach(\OC::$APPSROOTS as $dir) {
472
+            $dirToTest  = $dir['path'];
473
+            $dirToTest .= '/';
474
+            $dirToTest .= $name;
475
+            $dirToTest .= '/';
476
+
477
+            if (is_dir($dirToTest)) {
478
+                return true;
479
+            }
480
+        }
481
+
482
+        return false;
483
+    }
484
+
485
+    /**
486
+     * Removes an app
487
+     * @param string $name name of the application to remove
488
+     * @return boolean
489
+     *
490
+     *
491
+     * This function works as follows
492
+     *   -# call uninstall repair steps
493
+     *   -# removing the files
494
+     *
495
+     * The function will not delete preferences, tables and the configuration,
496
+     * this has to be done by the function oc_app_uninstall().
497
+     */
498
+    public static function removeApp($appId) {
499
+
500
+        if(Installer::isDownloaded( $appId )) {
501
+            $appDir=OC_App::getInstallPath() . '/' . $appId;
502
+            OC_Helper::rmdirr($appDir);
503
+
504
+            return true;
505
+        }else{
506
+            \OCP\Util::writeLog('core', 'can\'t remove app '.$appId.'. It is not installed.', \OCP\Util::ERROR);
507
+
508
+            return false;
509
+        }
510
+
511
+    }
512
+
513
+    /**
514
+     * Installs shipped apps
515
+     *
516
+     * This function installs all apps found in the 'apps' directory that should be enabled by default;
517
+     * @param bool $softErrors When updating we ignore errors and simply log them, better to have a
518
+     *                         working ownCloud at the end instead of an aborted update.
519
+     * @return array Array of error messages (appid => Exception)
520
+     */
521
+    public static function installShippedApps($softErrors = false) {
522
+        $errors = [];
523
+        foreach(\OC::$APPSROOTS as $app_dir) {
524
+            if($dir = opendir( $app_dir['path'] )) {
525
+                while( false !== ( $filename = readdir( $dir ))) {
526
+                    if( substr( $filename, 0, 1 ) != '.' and is_dir($app_dir['path']."/$filename") ) {
527
+                        if( file_exists( $app_dir['path']."/$filename/appinfo/info.xml" )) {
528
+                            if(!Installer::isInstalled($filename)) {
529
+                                $info=OC_App::getAppInfo($filename);
530
+                                $enabled = isset($info['default_enable']);
531
+                                if (($enabled || in_array($filename, \OC::$server->getAppManager()->getAlwaysEnabledApps()))
532
+                                      && \OC::$server->getConfig()->getAppValue($filename, 'enabled') !== 'no') {
533
+                                    if ($softErrors) {
534
+                                        try {
535
+                                            Installer::installShippedApp($filename);
536
+                                        } catch (HintException $e) {
537
+                                            if ($e->getPrevious() instanceof TableExistsException) {
538
+                                                $errors[$filename] = $e;
539
+                                                continue;
540
+                                            }
541
+                                            throw $e;
542
+                                        }
543
+                                    } else {
544
+                                        Installer::installShippedApp($filename);
545
+                                    }
546
+                                    \OC::$server->getConfig()->setAppValue($filename, 'enabled', 'yes');
547
+                                }
548
+                            }
549
+                        }
550
+                    }
551
+                }
552
+                closedir( $dir );
553
+            }
554
+        }
555
+
556
+        return $errors;
557
+    }
558
+
559
+    /**
560
+     * install an app already placed in the app folder
561
+     * @param string $app id of the app to install
562
+     * @return integer
563
+     */
564
+    public static function installShippedApp($app) {
565
+        //install the database
566
+        $appPath = OC_App::getAppPath($app);
567
+        if(is_file("$appPath/appinfo/database.xml")) {
568
+            try {
569
+                OC_DB::createDbFromStructure("$appPath/appinfo/database.xml");
570
+            } catch (TableExistsException $e) {
571
+                throw new HintException(
572
+                    'Failed to enable app ' . $app,
573
+                    'Please ask for help via one of our <a href="https://nextcloud.com/support/" target="_blank" rel="noreferrer">support channels</a>.',
574
+                    0, $e
575
+                );
576
+            }
577
+        }
578
+
579
+        //run appinfo/install.php
580
+        \OC_App::registerAutoloading($app, $appPath);
581
+        self::includeAppScript("$appPath/appinfo/install.php");
582
+
583
+        $info = OC_App::getAppInfo($app);
584
+        if (is_null($info)) {
585
+            return false;
586
+        }
587
+        \OC_App::setupBackgroundJobs($info['background-jobs']);
588
+
589
+        OC_App::executeRepairSteps($app, $info['repair-steps']['install']);
590
+
591
+        $config = \OC::$server->getConfig();
592
+
593
+        $config->setAppValue($app, 'installed_version', OC_App::getAppVersion($app));
594
+        if (array_key_exists('ocsid', $info)) {
595
+            $config->setAppValue($app, 'ocsid', $info['ocsid']);
596
+        }
597
+
598
+        //set remote/public handlers
599
+        foreach($info['remote'] as $name=>$path) {
600
+            $config->setAppValue('core', 'remote_'.$name, $app.'/'.$path);
601
+        }
602
+        foreach($info['public'] as $name=>$path) {
603
+            $config->setAppValue('core', 'public_'.$name, $app.'/'.$path);
604
+        }
605
+
606
+        OC_App::setAppTypes($info['id']);
607
+
608
+        if(isset($info['settings']) && is_array($info['settings'])) {
609
+            // requires that autoloading was registered for the app,
610
+            // as happens before running the install.php some lines above
611
+            \OC::$server->getSettingsManager()->setupSettings($info['settings']);
612
+        }
613
+
614
+        return $info['id'];
615
+    }
616
+
617
+    /**
618
+     * check the code of an app with some static code checks
619
+     * @param string $folder the folder of the app to check
620
+     * @return boolean true for app is o.k. and false for app is not o.k.
621
+     */
622
+    public static function checkCode($folder) {
623
+        // is the code checker enabled?
624
+        if(!\OC::$server->getConfig()->getSystemValue('appcodechecker', false)) {
625
+            return true;
626
+        }
627
+
628
+        $codeChecker = new CodeChecker(new PrivateCheck(new EmptyCheck()));
629
+        $errors = $codeChecker->analyseFolder(basename($folder), $folder);
630
+
631
+        return empty($errors);
632
+    }
633
+
634
+    /**
635
+     * @param $basedir
636
+     */
637
+    private static function includeAppScript($script) {
638
+        if ( file_exists($script) ){
639
+            include $script;
640
+        }
641
+    }
642 642
 }
Please login to merge, or discard this patch.
Spacing   +69 added lines, -69 removed lines patch added patch discarded remove patch
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
 	 * @throws \Exception
87 87
 	 * @return integer
88 88
 	 */
89
-	public static function installApp( $data = array()) {
89
+	public static function installApp($data = array()) {
90 90
 		$l = \OC::$server->getL10N('lib');
91 91
 
92 92
 		list($extractDir, $path) = self::downloadApp($data);
@@ -95,29 +95,29 @@  discard block
 block discarded – undo
95 95
 		$appId = OC_App::cleanAppId($info['id']);
96 96
 		$basedir = OC_App::getInstallPath().'/'.$appId;
97 97
 		//check if the destination directory already exists
98
-		if(is_dir($basedir)) {
98
+		if (is_dir($basedir)) {
99 99
 			OC_Helper::rmdirr($extractDir);
100
-			if($data['source']=='http') {
100
+			if ($data['source'] == 'http') {
101 101
 				unlink($path);
102 102
 			}
103 103
 			throw new \Exception($l->t("App directory already exists"));
104 104
 		}
105 105
 
106
-		if(!empty($data['pretent'])) {
106
+		if (!empty($data['pretent'])) {
107 107
 			return false;
108 108
 		}
109 109
 
110 110
 		//copy the app to the correct place
111
-		if(@!mkdir($basedir)) {
111
+		if (@!mkdir($basedir)) {
112 112
 			OC_Helper::rmdirr($extractDir);
113
-			if($data['source']=='http') {
113
+			if ($data['source'] == 'http') {
114 114
 				unlink($path);
115 115
 			}
116 116
 			throw new \Exception($l->t("Can't create app folder. Please fix permissions. %s", array($basedir)));
117 117
 		}
118 118
 
119
-		$extractDir .= '/' . $info['id'];
120
-		if(!file_exists($extractDir)) {
119
+		$extractDir .= '/'.$info['id'];
120
+		if (!file_exists($extractDir)) {
121 121
 			OC_Helper::rmdirr($basedir);
122 122
 			throw new \Exception($l->t("Archive does not contain a directory named %s", $info['id']));
123 123
 		}
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
 		OC_Helper::rmdirr($extractDir);
128 128
 
129 129
 		//install the database
130
-		if(is_file($basedir.'/appinfo/database.xml')) {
130
+		if (is_file($basedir.'/appinfo/database.xml')) {
131 131
 			if (\OC::$server->getAppConfig()->getValue($info['id'], 'installed_version') === null) {
132 132
 				OC_DB::createDbFromStructure($basedir.'/appinfo/database.xml');
133 133
 			} else {
@@ -138,8 +138,8 @@  discard block
 block discarded – undo
138 138
 		\OC_App::setupBackgroundJobs($info['background-jobs']);
139 139
 
140 140
 		//run appinfo/install.php
141
-		if((!isset($data['noinstall']) or $data['noinstall']==false)) {
142
-			self::includeAppScript($basedir . '/appinfo/install.php');
141
+		if ((!isset($data['noinstall']) or $data['noinstall'] == false)) {
142
+			self::includeAppScript($basedir.'/appinfo/install.php');
143 143
 		}
144 144
 
145 145
 		$appData = OC_App::getAppInfo($appId);
@@ -150,10 +150,10 @@  discard block
 block discarded – undo
150 150
 		\OC::$server->getConfig()->setAppValue($info['id'], 'enabled', 'no');
151 151
 
152 152
 		//set remote/public handlers
153
-		foreach($info['remote'] as $name=>$path) {
153
+		foreach ($info['remote'] as $name=>$path) {
154 154
 			\OC::$server->getConfig()->setAppValue('core', 'remote_'.$name, $info['id'].'/'.$path);
155 155
 		}
156
-		foreach($info['public'] as $name=>$path) {
156
+		foreach ($info['public'] as $name=>$path) {
157 157
 			\OC::$server->getConfig()->setAppValue('core', 'public_'.$name, $info['id'].'/'.$path);
158 158
 		}
159 159
 
@@ -169,7 +169,7 @@  discard block
 block discarded – undo
169 169
 	 *
170 170
 	 * Checks whether or not an app is installed, i.e. registered in apps table.
171 171
 	 */
172
-	public static function 	isInstalled( $app ) {
172
+	public static function 	isInstalled($app) {
173 173
 		return (\OC::$server->getConfig()->getAppValue($app, "installed_version", null) !== null);
174 174
 	}
175 175
 
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
 	 * upgrade.php can determine the current installed version of the app using
208 208
 	 * "\OC::$server->getAppConfig()->getValue($appid, 'installed_version')"
209 209
 	 */
210
-	public static function updateApp($info=array(), $isShipped=false) {
210
+	public static function updateApp($info = array(), $isShipped = false) {
211 211
 		list($extractDir, $path) = self::downloadApp($info);
212 212
 		$info = self::checkAppsIntegrity($info, $extractDir, $path, $isShipped);
213 213
 
@@ -216,10 +216,10 @@  discard block
 block discarded – undo
216 216
 		$basedir .= '/';
217 217
 		$basedir .= $info['id'];
218 218
 
219
-		if($currentDir !== false && is_writable($currentDir)) {
219
+		if ($currentDir !== false && is_writable($currentDir)) {
220 220
 			$basedir = $currentDir;
221 221
 		}
222
-		if(is_dir($basedir)) {
222
+		if (is_dir($basedir)) {
223 223
 			OC_Helper::rmdirr($basedir);
224 224
 		}
225 225
 
@@ -273,30 +273,30 @@  discard block
 block discarded – undo
273 273
 	public static function downloadApp($data = array()) {
274 274
 		$l = \OC::$server->getL10N('lib');
275 275
 
276
-		if(!isset($data['source'])) {
276
+		if (!isset($data['source'])) {
277 277
 			throw new \Exception($l->t("No source specified when installing app"));
278 278
 		}
279 279
 
280 280
 		//download the file if necessary
281
-		if($data['source']=='http') {
281
+		if ($data['source'] == 'http') {
282 282
 			$pathInfo = pathinfo($data['href']);
283
-			$extension = isset($pathInfo['extension']) ? '.' . $pathInfo['extension'] : '';
283
+			$extension = isset($pathInfo['extension']) ? '.'.$pathInfo['extension'] : '';
284 284
 			$path = \OC::$server->getTempManager()->getTemporaryFile($extension);
285
-			if(!isset($data['href'])) {
285
+			if (!isset($data['href'])) {
286 286
 				throw new \Exception($l->t("No href specified when installing app from http"));
287 287
 			}
288 288
 			$client = \OC::$server->getHTTPClientService()->newClient();
289 289
 			$client->get($data['href'], ['save_to' => $path]);
290 290
 		} else {
291
-			if(!isset($data['path'])) {
291
+			if (!isset($data['path'])) {
292 292
 				throw new \Exception($l->t("No path specified when installing app from local file"));
293 293
 			}
294
-			$path=$data['path'];
294
+			$path = $data['path'];
295 295
 		}
296 296
 
297 297
 		//detect the archive type
298 298
 		$mime = \OC::$server->getMimeTypeDetector()->detect($path);
299
-		if ($mime !=='application/zip' && $mime !== 'application/x-gzip' && $mime !== 'application/x-bzip2') {
299
+		if ($mime !== 'application/zip' && $mime !== 'application/x-gzip' && $mime !== 'application/x-bzip2') {
300 300
 			throw new \Exception($l->t("Archives of type %s are not supported", array($mime)));
301 301
 		}
302 302
 
@@ -304,11 +304,11 @@  discard block
 block discarded – undo
304 304
 		$extractDir = \OC::$server->getTempManager()->getTemporaryFolder();
305 305
 		OC_Helper::rmdirr($extractDir);
306 306
 		mkdir($extractDir);
307
-		if($archive=\OC\Archive\Archive::open($path)) {
307
+		if ($archive = \OC\Archive\Archive::open($path)) {
308 308
 			$archive->extract($extractDir);
309 309
 		} else {
310 310
 			OC_Helper::rmdirr($extractDir);
311
-			if($data['source']=='http') {
311
+			if ($data['source'] == 'http') {
312 312
 				unlink($path);
313 313
 			}
314 314
 			throw new \Exception($l->t("Failed to open archive when installing app"));
@@ -332,29 +332,29 @@  discard block
 block discarded – undo
332 332
 	public static function checkAppsIntegrity($data, $extractDir, $path, $isShipped = false) {
333 333
 		$l = \OC::$server->getL10N('lib');
334 334
 		//load the info.xml file of the app
335
-		if(!is_file($extractDir.'/appinfo/info.xml')) {
335
+		if (!is_file($extractDir.'/appinfo/info.xml')) {
336 336
 			//try to find it in a subdir
337
-			$dh=opendir($extractDir);
338
-			if(is_resource($dh)) {
337
+			$dh = opendir($extractDir);
338
+			if (is_resource($dh)) {
339 339
 				while (($folder = readdir($dh)) !== false) {
340
-					if($folder[0]!='.' and is_dir($extractDir.'/'.$folder)) {
341
-						if(is_file($extractDir.'/'.$folder.'/appinfo/info.xml')) {
342
-							$extractDir.='/'.$folder;
340
+					if ($folder[0] != '.' and is_dir($extractDir.'/'.$folder)) {
341
+						if (is_file($extractDir.'/'.$folder.'/appinfo/info.xml')) {
342
+							$extractDir .= '/'.$folder;
343 343
 						}
344 344
 					}
345 345
 				}
346 346
 			}
347 347
 		}
348
-		if(!is_file($extractDir.'/appinfo/info.xml')) {
348
+		if (!is_file($extractDir.'/appinfo/info.xml')) {
349 349
 			OC_Helper::rmdirr($extractDir);
350
-			if($data['source'] === 'http') {
350
+			if ($data['source'] === 'http') {
351 351
 				unlink($path);
352 352
 			}
353 353
 			throw new \Exception($l->t("App does not provide an info.xml file"));
354 354
 		}
355 355
 
356 356
 		$info = OC_App::getAppInfo($extractDir.'/appinfo/info.xml', true);
357
-		if(!is_array($info)) {
357
+		if (!is_array($info)) {
358 358
 			throw new \Exception($l->t('App cannot be installed because appinfo file cannot be read.'));
359 359
 		}
360 360
 
@@ -363,19 +363,19 @@  discard block
 block discarded – undo
363 363
 		// whether the application needs to be signed.
364 364
 		$appId = OC_App::cleanAppId($data['appdata']['id']);
365 365
 		$appBelongingToId = OC_App::getInternalAppIdByOcs($appId);
366
-		if(is_string($appBelongingToId)) {
366
+		if (is_string($appBelongingToId)) {
367 367
 			$previouslySigned = \OC::$server->getConfig()->getAppValue($appBelongingToId, 'signed', 'false');
368 368
 		} else {
369 369
 			$appBelongingToId = $info['id'];
370 370
 			$previouslySigned = 'false';
371 371
 		}
372
-		if($data['appdata']['level'] === OC_App::officialApp || $previouslySigned === 'true') {
372
+		if ($data['appdata']['level'] === OC_App::officialApp || $previouslySigned === 'true') {
373 373
 			\OC::$server->getConfig()->setAppValue($appBelongingToId, 'signed', 'true');
374 374
 			$integrityResult = \OC::$server->getIntegrityCodeChecker()->verifyAppSignature(
375 375
 					$appBelongingToId,
376 376
 					$extractDir
377 377
 			);
378
-			if($integrityResult !== []) {
378
+			if ($integrityResult !== []) {
379 379
 				$e = new \Exception(
380 380
 						$l->t(
381 381
 								'Signature could not get checked. Please contact the app developer and check your admin screen.'
@@ -386,19 +386,19 @@  discard block
 block discarded – undo
386 386
 		}
387 387
 
388 388
 		// check the code for not allowed calls
389
-		if(!$isShipped && !Installer::checkCode($extractDir)) {
389
+		if (!$isShipped && !Installer::checkCode($extractDir)) {
390 390
 			OC_Helper::rmdirr($extractDir);
391 391
 			throw new \Exception($l->t("App can't be installed because of not allowed code in the App"));
392 392
 		}
393 393
 
394 394
 		// check if the app is compatible with this version of ownCloud
395
-		if(!OC_App::isAppCompatible(\OCP\Util::getVersion(), $info)) {
395
+		if (!OC_App::isAppCompatible(\OCP\Util::getVersion(), $info)) {
396 396
 			OC_Helper::rmdirr($extractDir);
397 397
 			throw new \Exception($l->t("App can't be installed because it is not compatible with this version of the server"));
398 398
 		}
399 399
 
400 400
 		// check if shipped tag is set which is only allowed for apps that are shipped with ownCloud
401
-		if(!$isShipped && isset($info['shipped']) && ($info['shipped']=='true')) {
401
+		if (!$isShipped && isset($info['shipped']) && ($info['shipped'] == 'true')) {
402 402
 			OC_Helper::rmdirr($extractDir);
403 403
 			throw new \Exception($l->t("App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps"));
404 404
 		}
@@ -406,7 +406,7 @@  discard block
 block discarded – undo
406 406
 		// check if the ocs version is the same as the version in info.xml/version
407 407
 		$version = trim($info['version']);
408 408
 
409
-		if(isset($data['appdata']['version']) && $version<>trim($data['appdata']['version'])) {
409
+		if (isset($data['appdata']['version']) && $version <> trim($data['appdata']['version'])) {
410 410
 			OC_Helper::rmdirr($extractDir);
411 411
 			throw new \Exception($l->t("App can't be installed because the version in info.xml is not the same as the version reported from the app store"));
412 412
 		}
@@ -421,7 +421,7 @@  discard block
 block discarded – undo
421 421
 	 *
422 422
 	 * The function will check if an update for a version is available
423 423
 	 */
424
-	public static function isUpdateAvailable( $app ) {
424
+	public static function isUpdateAvailable($app) {
425 425
 		static $isInstanceReadyForUpdates = null;
426 426
 
427 427
 		if ($isInstanceReadyForUpdates === null) {
@@ -437,24 +437,24 @@  discard block
 block discarded – undo
437 437
 			return false;
438 438
 		}
439 439
 
440
-		$ocsid=\OC::$server->getAppConfig()->getValue( $app, 'ocsid', '');
440
+		$ocsid = \OC::$server->getAppConfig()->getValue($app, 'ocsid', '');
441 441
 
442
-		if($ocsid<>'') {
442
+		if ($ocsid <> '') {
443 443
 			$ocsClient = new OCSClient(
444 444
 				\OC::$server->getHTTPClientService(),
445 445
 				\OC::$server->getConfig(),
446 446
 				\OC::$server->getLogger()
447 447
 			);
448 448
 			$ocsdata = $ocsClient->getApplication($ocsid, \OCP\Util::getVersion());
449
-			$ocsversion= (string) $ocsdata['version'];
450
-			$currentversion=OC_App::getAppVersion($app);
449
+			$ocsversion = (string) $ocsdata['version'];
450
+			$currentversion = OC_App::getAppVersion($app);
451 451
 			if (version_compare($ocsversion, $currentversion, '>')) {
452 452
 				return($ocsversion);
453
-			}else{
453
+			} else {
454 454
 				return false;
455 455
 			}
456 456
 
457
-		}else{
457
+		} else {
458 458
 			return false;
459 459
 		}
460 460
 
@@ -467,8 +467,8 @@  discard block
 block discarded – undo
467 467
 	 *
468 468
 	 * The function will check if the app is already downloaded in the apps repository
469 469
 	 */
470
-	public static function isDownloaded( $name ) {
471
-		foreach(\OC::$APPSROOTS as $dir) {
470
+	public static function isDownloaded($name) {
471
+		foreach (\OC::$APPSROOTS as $dir) {
472 472
 			$dirToTest  = $dir['path'];
473 473
 			$dirToTest .= '/';
474 474
 			$dirToTest .= $name;
@@ -497,12 +497,12 @@  discard block
 block discarded – undo
497 497
 	 */
498 498
 	public static function removeApp($appId) {
499 499
 
500
-		if(Installer::isDownloaded( $appId )) {
501
-			$appDir=OC_App::getInstallPath() . '/' . $appId;
500
+		if (Installer::isDownloaded($appId)) {
501
+			$appDir = OC_App::getInstallPath().'/'.$appId;
502 502
 			OC_Helper::rmdirr($appDir);
503 503
 
504 504
 			return true;
505
-		}else{
505
+		} else {
506 506
 			\OCP\Util::writeLog('core', 'can\'t remove app '.$appId.'. It is not installed.', \OCP\Util::ERROR);
507 507
 
508 508
 			return false;
@@ -520,13 +520,13 @@  discard block
 block discarded – undo
520 520
 	 */
521 521
 	public static function installShippedApps($softErrors = false) {
522 522
 		$errors = [];
523
-		foreach(\OC::$APPSROOTS as $app_dir) {
524
-			if($dir = opendir( $app_dir['path'] )) {
525
-				while( false !== ( $filename = readdir( $dir ))) {
526
-					if( substr( $filename, 0, 1 ) != '.' and is_dir($app_dir['path']."/$filename") ) {
527
-						if( file_exists( $app_dir['path']."/$filename/appinfo/info.xml" )) {
528
-							if(!Installer::isInstalled($filename)) {
529
-								$info=OC_App::getAppInfo($filename);
523
+		foreach (\OC::$APPSROOTS as $app_dir) {
524
+			if ($dir = opendir($app_dir['path'])) {
525
+				while (false !== ($filename = readdir($dir))) {
526
+					if (substr($filename, 0, 1) != '.' and is_dir($app_dir['path']."/$filename")) {
527
+						if (file_exists($app_dir['path']."/$filename/appinfo/info.xml")) {
528
+							if (!Installer::isInstalled($filename)) {
529
+								$info = OC_App::getAppInfo($filename);
530 530
 								$enabled = isset($info['default_enable']);
531 531
 								if (($enabled || in_array($filename, \OC::$server->getAppManager()->getAlwaysEnabledApps()))
532 532
 									  && \OC::$server->getConfig()->getAppValue($filename, 'enabled') !== 'no') {
@@ -549,7 +549,7 @@  discard block
 block discarded – undo
549 549
 						}
550 550
 					}
551 551
 				}
552
-				closedir( $dir );
552
+				closedir($dir);
553 553
 			}
554 554
 		}
555 555
 
@@ -564,12 +564,12 @@  discard block
 block discarded – undo
564 564
 	public static function installShippedApp($app) {
565 565
 		//install the database
566 566
 		$appPath = OC_App::getAppPath($app);
567
-		if(is_file("$appPath/appinfo/database.xml")) {
567
+		if (is_file("$appPath/appinfo/database.xml")) {
568 568
 			try {
569 569
 				OC_DB::createDbFromStructure("$appPath/appinfo/database.xml");
570 570
 			} catch (TableExistsException $e) {
571 571
 				throw new HintException(
572
-					'Failed to enable app ' . $app,
572
+					'Failed to enable app '.$app,
573 573
 					'Please ask for help via one of our <a href="https://nextcloud.com/support/" target="_blank" rel="noreferrer">support channels</a>.',
574 574
 					0, $e
575 575
 				);
@@ -596,16 +596,16 @@  discard block
 block discarded – undo
596 596
 		}
597 597
 
598 598
 		//set remote/public handlers
599
-		foreach($info['remote'] as $name=>$path) {
599
+		foreach ($info['remote'] as $name=>$path) {
600 600
 			$config->setAppValue('core', 'remote_'.$name, $app.'/'.$path);
601 601
 		}
602
-		foreach($info['public'] as $name=>$path) {
602
+		foreach ($info['public'] as $name=>$path) {
603 603
 			$config->setAppValue('core', 'public_'.$name, $app.'/'.$path);
604 604
 		}
605 605
 
606 606
 		OC_App::setAppTypes($info['id']);
607 607
 
608
-		if(isset($info['settings']) && is_array($info['settings'])) {
608
+		if (isset($info['settings']) && is_array($info['settings'])) {
609 609
 			// requires that autoloading was registered for the app,
610 610
 			// as happens before running the install.php some lines above
611 611
 			\OC::$server->getSettingsManager()->setupSettings($info['settings']);
@@ -621,7 +621,7 @@  discard block
 block discarded – undo
621 621
 	 */
622 622
 	public static function checkCode($folder) {
623 623
 		// is the code checker enabled?
624
-		if(!\OC::$server->getConfig()->getSystemValue('appcodechecker', false)) {
624
+		if (!\OC::$server->getConfig()->getSystemValue('appcodechecker', false)) {
625 625
 			return true;
626 626
 		}
627 627
 
@@ -635,7 +635,7 @@  discard block
 block discarded – undo
635 635
 	 * @param $basedir
636 636
 	 */
637 637
 	private static function includeAppScript($script) {
638
-		if ( file_exists($script) ){
638
+		if (file_exists($script)) {
639 639
 			include $script;
640 640
 		}
641 641
 	}
Please login to merge, or discard this patch.
Braces   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -450,11 +450,11 @@  discard block
 block discarded – undo
450 450
 			$currentversion=OC_App::getAppVersion($app);
451 451
 			if (version_compare($ocsversion, $currentversion, '>')) {
452 452
 				return($ocsversion);
453
-			}else{
453
+			} else{
454 454
 				return false;
455 455
 			}
456 456
 
457
-		}else{
457
+		} else{
458 458
 			return false;
459 459
 		}
460 460
 
@@ -502,7 +502,7 @@  discard block
 block discarded – undo
502 502
 			OC_Helper::rmdirr($appDir);
503 503
 
504 504
 			return true;
505
-		}else{
505
+		} else{
506 506
 			\OCP\Util::writeLog('core', 'can\'t remove app '.$appId.'. It is not installed.', \OCP\Util::ERROR);
507 507
 
508 508
 			return false;
Please login to merge, or discard this patch.
lib/private/L10N/Factory.php 3 patches
Doc Comments   +5 added lines patch added patch discarded remove patch
@@ -278,6 +278,11 @@
 block discarded – undo
278 278
 	 */
279 279
 	// FIXME This method is only public, until OC_L10N does not need it anymore,
280 280
 	// FIXME This is also the reason, why it is not in the public interface
281
+
282
+	/**
283
+	 * @param string|boolean $app
284
+	 * @param string|null $lang
285
+	 */
281 286
 	public function getL10nFilesForApp($app, $lang) {
282 287
 		$languageFiles = [];
283 288
 
Please login to merge, or discard this patch.
Indentation   +351 added lines, -351 removed lines patch added patch discarded remove patch
@@ -37,355 +37,355 @@
 block discarded – undo
37 37
  */
38 38
 class Factory implements IFactory {
39 39
 
40
-	/** @var string */
41
-	protected $requestLanguage = '';
42
-
43
-	/**
44
-	 * cached instances
45
-	 * @var array Structure: Lang => App => \OCP\IL10N
46
-	 */
47
-	protected $instances = [];
48
-
49
-	/**
50
-	 * @var array Structure: App => string[]
51
-	 */
52
-	protected $availableLanguages = [];
53
-
54
-	/**
55
-	 * @var array Structure: string => callable
56
-	 */
57
-	protected $pluralFunctions = [];
58
-
59
-	/** @var IConfig */
60
-	protected $config;
61
-
62
-	/** @var IRequest */
63
-	protected $request;
64
-
65
-	/** @var IUserSession */
66
-	protected $userSession;
67
-
68
-	/** @var string */
69
-	protected $serverRoot;
70
-
71
-	/**
72
-	 * @param IConfig $config
73
-	 * @param IRequest $request
74
-	 * @param IUserSession $userSession
75
-	 * @param string $serverRoot
76
-	 */
77
-	public function __construct(IConfig $config,
78
-								IRequest $request,
79
-								IUserSession $userSession,
80
-								$serverRoot) {
81
-		$this->config = $config;
82
-		$this->request = $request;
83
-		$this->userSession = $userSession;
84
-		$this->serverRoot = $serverRoot;
85
-	}
86
-
87
-	/**
88
-	 * Get a language instance
89
-	 *
90
-	 * @param string $app
91
-	 * @param string|null $lang
92
-	 * @return \OCP\IL10N
93
-	 */
94
-	public function get($app, $lang = null) {
95
-		$app = \OC_App::cleanAppId($app);
96
-		if ($lang !== null) {
97
-			$lang = str_replace(array('\0', '/', '\\', '..'), '', (string) $lang);
98
-		}
99
-		if ($lang === null || !$this->languageExists($app, $lang)) {
100
-			$lang = $this->findLanguage($app);
101
-		}
102
-
103
-		if (!isset($this->instances[$lang][$app])) {
104
-			$this->instances[$lang][$app] = new L10N(
105
-				$this, $app, $lang,
106
-				$this->getL10nFilesForApp($app, $lang)
107
-			);
108
-		}
109
-
110
-		return $this->instances[$lang][$app];
111
-	}
112
-
113
-	/**
114
-	 * Find the best language
115
-	 *
116
-	 * @param string|null $app App id or null for core
117
-	 * @return string language If nothing works it returns 'en'
118
-	 */
119
-	public function findLanguage($app = null) {
120
-		if ($this->requestLanguage !== '' && $this->languageExists($app, $this->requestLanguage)) {
121
-			return $this->requestLanguage;
122
-		}
123
-
124
-		/**
125
-		 * At this point ownCloud might not yet be installed and thus the lookup
126
-		 * in the preferences table might fail. For this reason we need to check
127
-		 * whether the instance has already been installed
128
-		 *
129
-		 * @link https://github.com/owncloud/core/issues/21955
130
-		 */
131
-		if($this->config->getSystemValue('installed', false)) {
132
-			$userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() :  null;
133
-			if(!is_null($userId)) {
134
-				$userLang = $this->config->getUserValue($userId, 'core', 'lang', null);
135
-			} else {
136
-				$userLang = null;
137
-			}
138
-		} else {
139
-			$userId = null;
140
-			$userLang = null;
141
-		}
142
-
143
-		if ($userLang) {
144
-			$this->requestLanguage = $userLang;
145
-			if ($this->languageExists($app, $userLang)) {
146
-				return $userLang;
147
-			}
148
-		}
149
-
150
-		$defaultLanguage = $this->config->getSystemValue('default_language', false);
151
-
152
-		if ($defaultLanguage !== false && $this->languageExists($app, $defaultLanguage)) {
153
-			return $defaultLanguage;
154
-		}
155
-
156
-		$lang = $this->setLanguageFromRequest($app);
157
-		if ($userId !== null && $app === null && !$userLang) {
158
-			$this->config->setUserValue($userId, 'core', 'lang', $lang);
159
-		}
160
-
161
-		return $lang;
162
-	}
163
-
164
-	/**
165
-	 * Find all available languages for an app
166
-	 *
167
-	 * @param string|null $app App id or null for core
168
-	 * @return array an array of available languages
169
-	 */
170
-	public function findAvailableLanguages($app = null) {
171
-		$key = $app;
172
-		if ($key === null) {
173
-			$key = 'null';
174
-		}
175
-
176
-		// also works with null as key
177
-		if (!empty($this->availableLanguages[$key])) {
178
-			return $this->availableLanguages[$key];
179
-		}
180
-
181
-		$available = ['en']; //english is always available
182
-		$dir = $this->findL10nDir($app);
183
-		if (is_dir($dir)) {
184
-			$files = scandir($dir);
185
-			if ($files !== false) {
186
-				foreach ($files as $file) {
187
-					if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
188
-						$available[] = substr($file, 0, -5);
189
-					}
190
-				}
191
-			}
192
-		}
193
-
194
-		// merge with translations from theme
195
-		$theme = $this->config->getSystemValue('theme');
196
-		if (!empty($theme)) {
197
-			$themeDir = $this->serverRoot . '/themes/' . $theme . substr($dir, strlen($this->serverRoot));
198
-
199
-			if (is_dir($themeDir)) {
200
-				$files = scandir($themeDir);
201
-				if ($files !== false) {
202
-					foreach ($files as $file) {
203
-						if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
204
-							$available[] = substr($file, 0, -5);
205
-						}
206
-					}
207
-				}
208
-			}
209
-		}
210
-
211
-		$this->availableLanguages[$key] = $available;
212
-		return $available;
213
-	}
214
-
215
-	/**
216
-	 * @param string|null $app App id or null for core
217
-	 * @param string $lang
218
-	 * @return bool
219
-	 */
220
-	public function languageExists($app, $lang) {
221
-		if ($lang === 'en') {//english is always available
222
-			return true;
223
-		}
224
-
225
-		$languages = $this->findAvailableLanguages($app);
226
-		return array_search($lang, $languages) !== false;
227
-	}
228
-
229
-	/**
230
-	 * @param string|null $app App id or null for core
231
-	 * @return string
232
-	 */
233
-	public function setLanguageFromRequest($app = null) {
234
-		$header = $this->request->getHeader('ACCEPT_LANGUAGE');
235
-		if ($header) {
236
-			$available = $this->findAvailableLanguages($app);
237
-
238
-			// E.g. make sure that 'de' is before 'de_DE'.
239
-			sort($available);
240
-
241
-			$preferences = preg_split('/,\s*/', strtolower($header));
242
-			foreach ($preferences as $preference) {
243
-				list($preferred_language) = explode(';', $preference);
244
-				$preferred_language = str_replace('-', '_', $preferred_language);
245
-
246
-				foreach ($available as $available_language) {
247
-					if ($preferred_language === strtolower($available_language)) {
248
-						if ($app === null && !$this->requestLanguage) {
249
-							$this->requestLanguage = $available_language;
250
-						}
251
-						return $available_language;
252
-					}
253
-				}
254
-
255
-				// Fallback from de_De to de
256
-				foreach ($available as $available_language) {
257
-					if (substr($preferred_language, 0, 2) === $available_language) {
258
-						if ($app === null && !$this->requestLanguage) {
259
-							$this->requestLanguage = $available_language;
260
-						}
261
-						return $available_language;
262
-					}
263
-				}
264
-			}
265
-		}
266
-
267
-		if ($app === null && !$this->requestLanguage) {
268
-			$this->requestLanguage = 'en';
269
-		}
270
-		return 'en'; // Last try: English
271
-	}
272
-
273
-	/**
274
-	 * Get a list of language files that should be loaded
275
-	 *
276
-	 * @param string $app
277
-	 * @param string $lang
278
-	 * @return string[]
279
-	 */
280
-	// FIXME This method is only public, until OC_L10N does not need it anymore,
281
-	// FIXME This is also the reason, why it is not in the public interface
282
-	public function getL10nFilesForApp($app, $lang) {
283
-		$languageFiles = [];
284
-
285
-		$i18nDir = $this->findL10nDir($app);
286
-		$transFile = strip_tags($i18nDir) . strip_tags($lang) . '.json';
287
-
288
-		if ((\OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
289
-				|| \OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
290
-				|| \OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
291
-				|| \OC_Helper::isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
292
-			)
293
-			&& file_exists($transFile)) {
294
-			// load the translations file
295
-			$languageFiles[] = $transFile;
296
-		}
297
-
298
-		// merge with translations from theme
299
-		$theme = $this->config->getSystemValue('theme');
300
-		if (!empty($theme)) {
301
-			$transFile = $this->serverRoot . '/themes/' . $theme . substr($transFile, strlen($this->serverRoot));
302
-			if (file_exists($transFile)) {
303
-				$languageFiles[] = $transFile;
304
-			}
305
-		}
306
-
307
-		return $languageFiles;
308
-	}
309
-
310
-	/**
311
-	 * find the l10n directory
312
-	 *
313
-	 * @param string $app App id or empty string for core
314
-	 * @return string directory
315
-	 */
316
-	protected function findL10nDir($app = null) {
317
-		if (in_array($app, ['core', 'lib', 'settings'])) {
318
-			if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
319
-				return $this->serverRoot . '/' . $app . '/l10n/';
320
-			}
321
-		} else if ($app && \OC_App::getAppPath($app) !== false) {
322
-			// Check if the app is in the app folder
323
-			return \OC_App::getAppPath($app) . '/l10n/';
324
-		}
325
-		return $this->serverRoot . '/core/l10n/';
326
-	}
327
-
328
-
329
-	/**
330
-	 * Creates a function from the plural string
331
-	 *
332
-	 * Parts of the code is copied from Habari:
333
-	 * https://github.com/habari/system/blob/master/classes/locale.php
334
-	 * @param string $string
335
-	 * @return string
336
-	 */
337
-	public function createPluralFunction($string) {
338
-		if (isset($this->pluralFunctions[$string])) {
339
-			return $this->pluralFunctions[$string];
340
-		}
341
-
342
-		if (preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
343
-			// sanitize
344
-			$nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
345
-			$plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
346
-
347
-			$body = str_replace(
348
-				array( 'plural', 'n', '$n$plurals', ),
349
-				array( '$plural', '$n', '$nplurals', ),
350
-				'nplurals='. $nplurals . '; plural=' . $plural
351
-			);
352
-
353
-			// add parents
354
-			// important since PHP's ternary evaluates from left to right
355
-			$body .= ';';
356
-			$res = '';
357
-			$p = 0;
358
-			for($i = 0; $i < strlen($body); $i++) {
359
-				$ch = $body[$i];
360
-				switch ( $ch ) {
361
-					case '?':
362
-						$res .= ' ? (';
363
-						$p++;
364
-						break;
365
-					case ':':
366
-						$res .= ') : (';
367
-						break;
368
-					case ';':
369
-						$res .= str_repeat( ')', $p ) . ';';
370
-						$p = 0;
371
-						break;
372
-					default:
373
-						$res .= $ch;
374
-				}
375
-			}
376
-
377
-			$body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
378
-			$function = create_function('$n', $body);
379
-			$this->pluralFunctions[$string] = $function;
380
-			return $function;
381
-		} else {
382
-			// default: one plural form for all cases but n==1 (english)
383
-			$function = create_function(
384
-				'$n',
385
-				'$nplurals=2;$plural=($n==1?0:1);return ($plural>=$nplurals?$nplurals-1:$plural);'
386
-			);
387
-			$this->pluralFunctions[$string] = $function;
388
-			return $function;
389
-		}
390
-	}
40
+    /** @var string */
41
+    protected $requestLanguage = '';
42
+
43
+    /**
44
+     * cached instances
45
+     * @var array Structure: Lang => App => \OCP\IL10N
46
+     */
47
+    protected $instances = [];
48
+
49
+    /**
50
+     * @var array Structure: App => string[]
51
+     */
52
+    protected $availableLanguages = [];
53
+
54
+    /**
55
+     * @var array Structure: string => callable
56
+     */
57
+    protected $pluralFunctions = [];
58
+
59
+    /** @var IConfig */
60
+    protected $config;
61
+
62
+    /** @var IRequest */
63
+    protected $request;
64
+
65
+    /** @var IUserSession */
66
+    protected $userSession;
67
+
68
+    /** @var string */
69
+    protected $serverRoot;
70
+
71
+    /**
72
+     * @param IConfig $config
73
+     * @param IRequest $request
74
+     * @param IUserSession $userSession
75
+     * @param string $serverRoot
76
+     */
77
+    public function __construct(IConfig $config,
78
+                                IRequest $request,
79
+                                IUserSession $userSession,
80
+                                $serverRoot) {
81
+        $this->config = $config;
82
+        $this->request = $request;
83
+        $this->userSession = $userSession;
84
+        $this->serverRoot = $serverRoot;
85
+    }
86
+
87
+    /**
88
+     * Get a language instance
89
+     *
90
+     * @param string $app
91
+     * @param string|null $lang
92
+     * @return \OCP\IL10N
93
+     */
94
+    public function get($app, $lang = null) {
95
+        $app = \OC_App::cleanAppId($app);
96
+        if ($lang !== null) {
97
+            $lang = str_replace(array('\0', '/', '\\', '..'), '', (string) $lang);
98
+        }
99
+        if ($lang === null || !$this->languageExists($app, $lang)) {
100
+            $lang = $this->findLanguage($app);
101
+        }
102
+
103
+        if (!isset($this->instances[$lang][$app])) {
104
+            $this->instances[$lang][$app] = new L10N(
105
+                $this, $app, $lang,
106
+                $this->getL10nFilesForApp($app, $lang)
107
+            );
108
+        }
109
+
110
+        return $this->instances[$lang][$app];
111
+    }
112
+
113
+    /**
114
+     * Find the best language
115
+     *
116
+     * @param string|null $app App id or null for core
117
+     * @return string language If nothing works it returns 'en'
118
+     */
119
+    public function findLanguage($app = null) {
120
+        if ($this->requestLanguage !== '' && $this->languageExists($app, $this->requestLanguage)) {
121
+            return $this->requestLanguage;
122
+        }
123
+
124
+        /**
125
+         * At this point ownCloud might not yet be installed and thus the lookup
126
+         * in the preferences table might fail. For this reason we need to check
127
+         * whether the instance has already been installed
128
+         *
129
+         * @link https://github.com/owncloud/core/issues/21955
130
+         */
131
+        if($this->config->getSystemValue('installed', false)) {
132
+            $userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() :  null;
133
+            if(!is_null($userId)) {
134
+                $userLang = $this->config->getUserValue($userId, 'core', 'lang', null);
135
+            } else {
136
+                $userLang = null;
137
+            }
138
+        } else {
139
+            $userId = null;
140
+            $userLang = null;
141
+        }
142
+
143
+        if ($userLang) {
144
+            $this->requestLanguage = $userLang;
145
+            if ($this->languageExists($app, $userLang)) {
146
+                return $userLang;
147
+            }
148
+        }
149
+
150
+        $defaultLanguage = $this->config->getSystemValue('default_language', false);
151
+
152
+        if ($defaultLanguage !== false && $this->languageExists($app, $defaultLanguage)) {
153
+            return $defaultLanguage;
154
+        }
155
+
156
+        $lang = $this->setLanguageFromRequest($app);
157
+        if ($userId !== null && $app === null && !$userLang) {
158
+            $this->config->setUserValue($userId, 'core', 'lang', $lang);
159
+        }
160
+
161
+        return $lang;
162
+    }
163
+
164
+    /**
165
+     * Find all available languages for an app
166
+     *
167
+     * @param string|null $app App id or null for core
168
+     * @return array an array of available languages
169
+     */
170
+    public function findAvailableLanguages($app = null) {
171
+        $key = $app;
172
+        if ($key === null) {
173
+            $key = 'null';
174
+        }
175
+
176
+        // also works with null as key
177
+        if (!empty($this->availableLanguages[$key])) {
178
+            return $this->availableLanguages[$key];
179
+        }
180
+
181
+        $available = ['en']; //english is always available
182
+        $dir = $this->findL10nDir($app);
183
+        if (is_dir($dir)) {
184
+            $files = scandir($dir);
185
+            if ($files !== false) {
186
+                foreach ($files as $file) {
187
+                    if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
188
+                        $available[] = substr($file, 0, -5);
189
+                    }
190
+                }
191
+            }
192
+        }
193
+
194
+        // merge with translations from theme
195
+        $theme = $this->config->getSystemValue('theme');
196
+        if (!empty($theme)) {
197
+            $themeDir = $this->serverRoot . '/themes/' . $theme . substr($dir, strlen($this->serverRoot));
198
+
199
+            if (is_dir($themeDir)) {
200
+                $files = scandir($themeDir);
201
+                if ($files !== false) {
202
+                    foreach ($files as $file) {
203
+                        if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
204
+                            $available[] = substr($file, 0, -5);
205
+                        }
206
+                    }
207
+                }
208
+            }
209
+        }
210
+
211
+        $this->availableLanguages[$key] = $available;
212
+        return $available;
213
+    }
214
+
215
+    /**
216
+     * @param string|null $app App id or null for core
217
+     * @param string $lang
218
+     * @return bool
219
+     */
220
+    public function languageExists($app, $lang) {
221
+        if ($lang === 'en') {//english is always available
222
+            return true;
223
+        }
224
+
225
+        $languages = $this->findAvailableLanguages($app);
226
+        return array_search($lang, $languages) !== false;
227
+    }
228
+
229
+    /**
230
+     * @param string|null $app App id or null for core
231
+     * @return string
232
+     */
233
+    public function setLanguageFromRequest($app = null) {
234
+        $header = $this->request->getHeader('ACCEPT_LANGUAGE');
235
+        if ($header) {
236
+            $available = $this->findAvailableLanguages($app);
237
+
238
+            // E.g. make sure that 'de' is before 'de_DE'.
239
+            sort($available);
240
+
241
+            $preferences = preg_split('/,\s*/', strtolower($header));
242
+            foreach ($preferences as $preference) {
243
+                list($preferred_language) = explode(';', $preference);
244
+                $preferred_language = str_replace('-', '_', $preferred_language);
245
+
246
+                foreach ($available as $available_language) {
247
+                    if ($preferred_language === strtolower($available_language)) {
248
+                        if ($app === null && !$this->requestLanguage) {
249
+                            $this->requestLanguage = $available_language;
250
+                        }
251
+                        return $available_language;
252
+                    }
253
+                }
254
+
255
+                // Fallback from de_De to de
256
+                foreach ($available as $available_language) {
257
+                    if (substr($preferred_language, 0, 2) === $available_language) {
258
+                        if ($app === null && !$this->requestLanguage) {
259
+                            $this->requestLanguage = $available_language;
260
+                        }
261
+                        return $available_language;
262
+                    }
263
+                }
264
+            }
265
+        }
266
+
267
+        if ($app === null && !$this->requestLanguage) {
268
+            $this->requestLanguage = 'en';
269
+        }
270
+        return 'en'; // Last try: English
271
+    }
272
+
273
+    /**
274
+     * Get a list of language files that should be loaded
275
+     *
276
+     * @param string $app
277
+     * @param string $lang
278
+     * @return string[]
279
+     */
280
+    // FIXME This method is only public, until OC_L10N does not need it anymore,
281
+    // FIXME This is also the reason, why it is not in the public interface
282
+    public function getL10nFilesForApp($app, $lang) {
283
+        $languageFiles = [];
284
+
285
+        $i18nDir = $this->findL10nDir($app);
286
+        $transFile = strip_tags($i18nDir) . strip_tags($lang) . '.json';
287
+
288
+        if ((\OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
289
+                || \OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
290
+                || \OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
291
+                || \OC_Helper::isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
292
+            )
293
+            && file_exists($transFile)) {
294
+            // load the translations file
295
+            $languageFiles[] = $transFile;
296
+        }
297
+
298
+        // merge with translations from theme
299
+        $theme = $this->config->getSystemValue('theme');
300
+        if (!empty($theme)) {
301
+            $transFile = $this->serverRoot . '/themes/' . $theme . substr($transFile, strlen($this->serverRoot));
302
+            if (file_exists($transFile)) {
303
+                $languageFiles[] = $transFile;
304
+            }
305
+        }
306
+
307
+        return $languageFiles;
308
+    }
309
+
310
+    /**
311
+     * find the l10n directory
312
+     *
313
+     * @param string $app App id or empty string for core
314
+     * @return string directory
315
+     */
316
+    protected function findL10nDir($app = null) {
317
+        if (in_array($app, ['core', 'lib', 'settings'])) {
318
+            if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
319
+                return $this->serverRoot . '/' . $app . '/l10n/';
320
+            }
321
+        } else if ($app && \OC_App::getAppPath($app) !== false) {
322
+            // Check if the app is in the app folder
323
+            return \OC_App::getAppPath($app) . '/l10n/';
324
+        }
325
+        return $this->serverRoot . '/core/l10n/';
326
+    }
327
+
328
+
329
+    /**
330
+     * Creates a function from the plural string
331
+     *
332
+     * Parts of the code is copied from Habari:
333
+     * https://github.com/habari/system/blob/master/classes/locale.php
334
+     * @param string $string
335
+     * @return string
336
+     */
337
+    public function createPluralFunction($string) {
338
+        if (isset($this->pluralFunctions[$string])) {
339
+            return $this->pluralFunctions[$string];
340
+        }
341
+
342
+        if (preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
343
+            // sanitize
344
+            $nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
345
+            $plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
346
+
347
+            $body = str_replace(
348
+                array( 'plural', 'n', '$n$plurals', ),
349
+                array( '$plural', '$n', '$nplurals', ),
350
+                'nplurals='. $nplurals . '; plural=' . $plural
351
+            );
352
+
353
+            // add parents
354
+            // important since PHP's ternary evaluates from left to right
355
+            $body .= ';';
356
+            $res = '';
357
+            $p = 0;
358
+            for($i = 0; $i < strlen($body); $i++) {
359
+                $ch = $body[$i];
360
+                switch ( $ch ) {
361
+                    case '?':
362
+                        $res .= ' ? (';
363
+                        $p++;
364
+                        break;
365
+                    case ':':
366
+                        $res .= ') : (';
367
+                        break;
368
+                    case ';':
369
+                        $res .= str_repeat( ')', $p ) . ';';
370
+                        $p = 0;
371
+                        break;
372
+                    default:
373
+                        $res .= $ch;
374
+                }
375
+            }
376
+
377
+            $body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
378
+            $function = create_function('$n', $body);
379
+            $this->pluralFunctions[$string] = $function;
380
+            return $function;
381
+        } else {
382
+            // default: one plural form for all cases but n==1 (english)
383
+            $function = create_function(
384
+                '$n',
385
+                '$nplurals=2;$plural=($n==1?0:1);return ($plural>=$nplurals?$nplurals-1:$plural);'
386
+            );
387
+            $this->pluralFunctions[$string] = $function;
388
+            return $function;
389
+        }
390
+    }
391 391
 }
Please login to merge, or discard this patch.
Spacing   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -128,9 +128,9 @@  discard block
 block discarded – undo
128 128
 		 *
129 129
 		 * @link https://github.com/owncloud/core/issues/21955
130 130
 		 */
131
-		if($this->config->getSystemValue('installed', false)) {
132
-			$userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() :  null;
133
-			if(!is_null($userId)) {
131
+		if ($this->config->getSystemValue('installed', false)) {
132
+			$userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() : null;
133
+			if (!is_null($userId)) {
134 134
 				$userLang = $this->config->getUserValue($userId, 'core', 'lang', null);
135 135
 			} else {
136 136
 				$userLang = null;
@@ -194,7 +194,7 @@  discard block
 block discarded – undo
194 194
 		// merge with translations from theme
195 195
 		$theme = $this->config->getSystemValue('theme');
196 196
 		if (!empty($theme)) {
197
-			$themeDir = $this->serverRoot . '/themes/' . $theme . substr($dir, strlen($this->serverRoot));
197
+			$themeDir = $this->serverRoot.'/themes/'.$theme.substr($dir, strlen($this->serverRoot));
198 198
 
199 199
 			if (is_dir($themeDir)) {
200 200
 				$files = scandir($themeDir);
@@ -283,12 +283,12 @@  discard block
 block discarded – undo
283 283
 		$languageFiles = [];
284 284
 
285 285
 		$i18nDir = $this->findL10nDir($app);
286
-		$transFile = strip_tags($i18nDir) . strip_tags($lang) . '.json';
286
+		$transFile = strip_tags($i18nDir).strip_tags($lang).'.json';
287 287
 
288
-		if ((\OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
289
-				|| \OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
290
-				|| \OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
291
-				|| \OC_Helper::isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
288
+		if ((\OC_Helper::isSubDirectory($transFile, $this->serverRoot.'/core/l10n/')
289
+				|| \OC_Helper::isSubDirectory($transFile, $this->serverRoot.'/lib/l10n/')
290
+				|| \OC_Helper::isSubDirectory($transFile, $this->serverRoot.'/settings/l10n/')
291
+				|| \OC_Helper::isSubDirectory($transFile, \OC_App::getAppPath($app).'/l10n/')
292 292
 			)
293 293
 			&& file_exists($transFile)) {
294 294
 			// load the translations file
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
 		// merge with translations from theme
299 299
 		$theme = $this->config->getSystemValue('theme');
300 300
 		if (!empty($theme)) {
301
-			$transFile = $this->serverRoot . '/themes/' . $theme . substr($transFile, strlen($this->serverRoot));
301
+			$transFile = $this->serverRoot.'/themes/'.$theme.substr($transFile, strlen($this->serverRoot));
302 302
 			if (file_exists($transFile)) {
303 303
 				$languageFiles[] = $transFile;
304 304
 			}
@@ -315,14 +315,14 @@  discard block
 block discarded – undo
315 315
 	 */
316 316
 	protected function findL10nDir($app = null) {
317 317
 		if (in_array($app, ['core', 'lib', 'settings'])) {
318
-			if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
319
-				return $this->serverRoot . '/' . $app . '/l10n/';
318
+			if (file_exists($this->serverRoot.'/'.$app.'/l10n/')) {
319
+				return $this->serverRoot.'/'.$app.'/l10n/';
320 320
 			}
321 321
 		} else if ($app && \OC_App::getAppPath($app) !== false) {
322 322
 			// Check if the app is in the app folder
323
-			return \OC_App::getAppPath($app) . '/l10n/';
323
+			return \OC_App::getAppPath($app).'/l10n/';
324 324
 		}
325
-		return $this->serverRoot . '/core/l10n/';
325
+		return $this->serverRoot.'/core/l10n/';
326 326
 	}
327 327
 
328 328
 
@@ -339,15 +339,15 @@  discard block
 block discarded – undo
339 339
 			return $this->pluralFunctions[$string];
340 340
 		}
341 341
 
342
-		if (preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
342
+		if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
343 343
 			// sanitize
344
-			$nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
345
-			$plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
344
+			$nplurals = preg_replace('/[^0-9]/', '', $matches[1]);
345
+			$plural = preg_replace('#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2]);
346 346
 
347 347
 			$body = str_replace(
348
-				array( 'plural', 'n', '$n$plurals', ),
349
-				array( '$plural', '$n', '$nplurals', ),
350
-				'nplurals='. $nplurals . '; plural=' . $plural
348
+				array('plural', 'n', '$n$plurals',),
349
+				array('$plural', '$n', '$nplurals',),
350
+				'nplurals='.$nplurals.'; plural='.$plural
351 351
 			);
352 352
 
353 353
 			// add parents
@@ -355,9 +355,9 @@  discard block
 block discarded – undo
355 355
 			$body .= ';';
356 356
 			$res = '';
357 357
 			$p = 0;
358
-			for($i = 0; $i < strlen($body); $i++) {
358
+			for ($i = 0; $i < strlen($body); $i++) {
359 359
 				$ch = $body[$i];
360
-				switch ( $ch ) {
360
+				switch ($ch) {
361 361
 					case '?':
362 362
 						$res .= ' ? (';
363 363
 						$p++;
@@ -366,7 +366,7 @@  discard block
 block discarded – undo
366 366
 						$res .= ') : (';
367 367
 						break;
368 368
 					case ';':
369
-						$res .= str_repeat( ')', $p ) . ';';
369
+						$res .= str_repeat(')', $p).';';
370 370
 						$p = 0;
371 371
 						break;
372 372
 					default:
@@ -374,7 +374,7 @@  discard block
 block discarded – undo
374 374
 				}
375 375
 			}
376 376
 
377
-			$body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
377
+			$body = $res.'return ($plural>=$nplurals?$nplurals-1:$plural);';
378 378
 			$function = create_function('$n', $body);
379 379
 			$this->pluralFunctions[$string] = $function;
380 380
 			return $function;
Please login to merge, or discard this patch.
lib/private/L10N/L10N.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -176,7 +176,7 @@
 block discarded – undo
176 176
 	 * Returns an associative array with all translations
177 177
 	 *
178 178
 	 * Called by \OC_L10N_String
179
-	 * @return array
179
+	 * @return string[]
180 180
 	 */
181 181
 	public function getTranslations() {
182 182
 		return $this->translations;
Please login to merge, or discard this patch.
Indentation   +186 added lines, -186 removed lines patch added patch discarded remove patch
@@ -28,190 +28,190 @@
 block discarded – undo
28 28
 
29 29
 class L10N implements IL10N {
30 30
 
31
-	/** @var IFactory */
32
-	protected $factory;
33
-
34
-	/** @var string App of this object */
35
-	protected $app;
36
-
37
-	/** @var string Language of this object */
38
-	protected $lang;
39
-
40
-	/** @var string Plural forms (string) */
41
-	private $pluralFormString = 'nplurals=2; plural=(n != 1);';
42
-
43
-	/** @var string Plural forms (function) */
44
-	private $pluralFormFunction = null;
45
-
46
-	/** @var string[] */
47
-	private $translations = [];
48
-
49
-	/**
50
-	 * @param IFactory $factory
51
-	 * @param string $app
52
-	 * @param string $lang
53
-	 * @param array $files
54
-	 */
55
-	public function __construct(IFactory $factory, $app, $lang, array $files) {
56
-		$this->factory = $factory;
57
-		$this->app = $app;
58
-		$this->lang = $lang;
59
-
60
-		$this->translations = [];
61
-		foreach ($files as $languageFile) {
62
-			$this->load($languageFile);
63
-		}
64
-	}
65
-
66
-	/**
67
-	 * The code (en, de, ...) of the language that is used for this instance
68
-	 *
69
-	 * @return string language
70
-	 */
71
-	public function getLanguageCode() {
72
-		return $this->lang;
73
-	}
74
-
75
-	/**
76
-	 * Translating
77
-	 * @param string $text The text we need a translation for
78
-	 * @param array $parameters default:array() Parameters for sprintf
79
-	 * @return string Translation or the same text
80
-	 *
81
-	 * Returns the translation. If no translation is found, $text will be
82
-	 * returned.
83
-	 */
84
-	public function t($text, $parameters = array()) {
85
-		return (string) new \OC_L10N_String($this, $text, $parameters);
86
-	}
87
-
88
-	/**
89
-	 * Translating
90
-	 * @param string $text_singular the string to translate for exactly one object
91
-	 * @param string $text_plural the string to translate for n objects
92
-	 * @param integer $count Number of objects
93
-	 * @param array $parameters default:array() Parameters for sprintf
94
-	 * @return string Translation or the same text
95
-	 *
96
-	 * Returns the translation. If no translation is found, $text will be
97
-	 * returned. %n will be replaced with the number of objects.
98
-	 *
99
-	 * The correct plural is determined by the plural_forms-function
100
-	 * provided by the po file.
101
-	 *
102
-	 */
103
-	public function n($text_singular, $text_plural, $count, $parameters = array()) {
104
-		$identifier = "_${text_singular}_::_${text_plural}_";
105
-		if (isset($this->translations[$identifier])) {
106
-			return (string) new \OC_L10N_String($this, $identifier, $parameters, $count);
107
-		} else {
108
-			if ($count === 1) {
109
-				return (string) new \OC_L10N_String($this, $text_singular, $parameters, $count);
110
-			} else {
111
-				return (string) new \OC_L10N_String($this, $text_plural, $parameters, $count);
112
-			}
113
-		}
114
-	}
115
-
116
-	/**
117
-	 * Localization
118
-	 * @param string $type Type of localization
119
-	 * @param \DateTime|int|string $data parameters for this localization
120
-	 * @param array $options
121
-	 * @return string|int|false
122
-	 *
123
-	 * Returns the localized data.
124
-	 *
125
-	 * Implemented types:
126
-	 *  - date
127
-	 *    - Creates a date
128
-	 *    - params: timestamp (int/string)
129
-	 *  - datetime
130
-	 *    - Creates date and time
131
-	 *    - params: timestamp (int/string)
132
-	 *  - time
133
-	 *    - Creates a time
134
-	 *    - params: timestamp (int/string)
135
-	 *  - firstday: Returns the first day of the week (0 sunday - 6 saturday)
136
-	 *  - jsdate: Returns the short JS date format
137
-	 */
138
-	public function l($type, $data = null, $options = array()) {
139
-		// Use the language of the instance
140
-		$locale = $this->getLanguageCode();
141
-		if ($locale === 'sr@latin') {
142
-			$locale = 'sr_latn';
143
-		}
144
-
145
-		if ($type === 'firstday') {
146
-			return (int) Calendar::getFirstWeekday($locale);
147
-		}
148
-		if ($type === 'jsdate') {
149
-			return (string) Calendar::getDateFormat('short', $locale);
150
-		}
151
-
152
-		$value = new \DateTime();
153
-		if ($data instanceof \DateTime) {
154
-			$value = $data;
155
-		} else if (is_string($data) && !is_numeric($data)) {
156
-			$data = strtotime($data);
157
-			$value->setTimestamp($data);
158
-		} else if ($data !== null) {
159
-			$value->setTimestamp($data);
160
-		}
161
-
162
-		$options = array_merge(array('width' => 'long'), $options);
163
-		$width = $options['width'];
164
-		switch ($type) {
165
-			case 'date':
166
-				return (string) Calendar::formatDate($value, $width, $locale);
167
-			case 'datetime':
168
-				return (string) Calendar::formatDatetime($value, $width, $locale);
169
-			case 'time':
170
-				return (string) Calendar::formatTime($value, $width, $locale);
171
-			default:
172
-				return false;
173
-		}
174
-	}
175
-
176
-	/**
177
-	 * Returns an associative array with all translations
178
-	 *
179
-	 * Called by \OC_L10N_String
180
-	 * @return array
181
-	 */
182
-	public function getTranslations() {
183
-		return $this->translations;
184
-	}
185
-
186
-	/**
187
-	 * Returnsed function accepts the argument $n
188
-	 *
189
-	 * Called by \OC_L10N_String
190
-	 * @return string the plural form function
191
-	 */
192
-	public function getPluralFormFunction() {
193
-		if (is_null($this->pluralFormFunction)) {
194
-			$this->pluralFormFunction = $this->factory->createPluralFunction($this->pluralFormString);
195
-		}
196
-		return $this->pluralFormFunction;
197
-	}
198
-
199
-	/**
200
-	 * @param $translationFile
201
-	 * @return bool
202
-	 */
203
-	protected function load($translationFile) {
204
-		$json = json_decode(file_get_contents($translationFile), true);
205
-		if (!is_array($json)) {
206
-			$jsonError = json_last_error();
207
-			\OC::$server->getLogger()->warning("Failed to load $translationFile - json error code: $jsonError", ['app' => 'l10n']);
208
-			return false;
209
-		}
210
-
211
-		if (!empty($json['pluralForm'])) {
212
-			$this->pluralFormString = $json['pluralForm'];
213
-		}
214
-		$this->translations = array_merge($this->translations, $json['translations']);
215
-		return true;
216
-	}
31
+    /** @var IFactory */
32
+    protected $factory;
33
+
34
+    /** @var string App of this object */
35
+    protected $app;
36
+
37
+    /** @var string Language of this object */
38
+    protected $lang;
39
+
40
+    /** @var string Plural forms (string) */
41
+    private $pluralFormString = 'nplurals=2; plural=(n != 1);';
42
+
43
+    /** @var string Plural forms (function) */
44
+    private $pluralFormFunction = null;
45
+
46
+    /** @var string[] */
47
+    private $translations = [];
48
+
49
+    /**
50
+     * @param IFactory $factory
51
+     * @param string $app
52
+     * @param string $lang
53
+     * @param array $files
54
+     */
55
+    public function __construct(IFactory $factory, $app, $lang, array $files) {
56
+        $this->factory = $factory;
57
+        $this->app = $app;
58
+        $this->lang = $lang;
59
+
60
+        $this->translations = [];
61
+        foreach ($files as $languageFile) {
62
+            $this->load($languageFile);
63
+        }
64
+    }
65
+
66
+    /**
67
+     * The code (en, de, ...) of the language that is used for this instance
68
+     *
69
+     * @return string language
70
+     */
71
+    public function getLanguageCode() {
72
+        return $this->lang;
73
+    }
74
+
75
+    /**
76
+     * Translating
77
+     * @param string $text The text we need a translation for
78
+     * @param array $parameters default:array() Parameters for sprintf
79
+     * @return string Translation or the same text
80
+     *
81
+     * Returns the translation. If no translation is found, $text will be
82
+     * returned.
83
+     */
84
+    public function t($text, $parameters = array()) {
85
+        return (string) new \OC_L10N_String($this, $text, $parameters);
86
+    }
87
+
88
+    /**
89
+     * Translating
90
+     * @param string $text_singular the string to translate for exactly one object
91
+     * @param string $text_plural the string to translate for n objects
92
+     * @param integer $count Number of objects
93
+     * @param array $parameters default:array() Parameters for sprintf
94
+     * @return string Translation or the same text
95
+     *
96
+     * Returns the translation. If no translation is found, $text will be
97
+     * returned. %n will be replaced with the number of objects.
98
+     *
99
+     * The correct plural is determined by the plural_forms-function
100
+     * provided by the po file.
101
+     *
102
+     */
103
+    public function n($text_singular, $text_plural, $count, $parameters = array()) {
104
+        $identifier = "_${text_singular}_::_${text_plural}_";
105
+        if (isset($this->translations[$identifier])) {
106
+            return (string) new \OC_L10N_String($this, $identifier, $parameters, $count);
107
+        } else {
108
+            if ($count === 1) {
109
+                return (string) new \OC_L10N_String($this, $text_singular, $parameters, $count);
110
+            } else {
111
+                return (string) new \OC_L10N_String($this, $text_plural, $parameters, $count);
112
+            }
113
+        }
114
+    }
115
+
116
+    /**
117
+     * Localization
118
+     * @param string $type Type of localization
119
+     * @param \DateTime|int|string $data parameters for this localization
120
+     * @param array $options
121
+     * @return string|int|false
122
+     *
123
+     * Returns the localized data.
124
+     *
125
+     * Implemented types:
126
+     *  - date
127
+     *    - Creates a date
128
+     *    - params: timestamp (int/string)
129
+     *  - datetime
130
+     *    - Creates date and time
131
+     *    - params: timestamp (int/string)
132
+     *  - time
133
+     *    - Creates a time
134
+     *    - params: timestamp (int/string)
135
+     *  - firstday: Returns the first day of the week (0 sunday - 6 saturday)
136
+     *  - jsdate: Returns the short JS date format
137
+     */
138
+    public function l($type, $data = null, $options = array()) {
139
+        // Use the language of the instance
140
+        $locale = $this->getLanguageCode();
141
+        if ($locale === 'sr@latin') {
142
+            $locale = 'sr_latn';
143
+        }
144
+
145
+        if ($type === 'firstday') {
146
+            return (int) Calendar::getFirstWeekday($locale);
147
+        }
148
+        if ($type === 'jsdate') {
149
+            return (string) Calendar::getDateFormat('short', $locale);
150
+        }
151
+
152
+        $value = new \DateTime();
153
+        if ($data instanceof \DateTime) {
154
+            $value = $data;
155
+        } else if (is_string($data) && !is_numeric($data)) {
156
+            $data = strtotime($data);
157
+            $value->setTimestamp($data);
158
+        } else if ($data !== null) {
159
+            $value->setTimestamp($data);
160
+        }
161
+
162
+        $options = array_merge(array('width' => 'long'), $options);
163
+        $width = $options['width'];
164
+        switch ($type) {
165
+            case 'date':
166
+                return (string) Calendar::formatDate($value, $width, $locale);
167
+            case 'datetime':
168
+                return (string) Calendar::formatDatetime($value, $width, $locale);
169
+            case 'time':
170
+                return (string) Calendar::formatTime($value, $width, $locale);
171
+            default:
172
+                return false;
173
+        }
174
+    }
175
+
176
+    /**
177
+     * Returns an associative array with all translations
178
+     *
179
+     * Called by \OC_L10N_String
180
+     * @return array
181
+     */
182
+    public function getTranslations() {
183
+        return $this->translations;
184
+    }
185
+
186
+    /**
187
+     * Returnsed function accepts the argument $n
188
+     *
189
+     * Called by \OC_L10N_String
190
+     * @return string the plural form function
191
+     */
192
+    public function getPluralFormFunction() {
193
+        if (is_null($this->pluralFormFunction)) {
194
+            $this->pluralFormFunction = $this->factory->createPluralFunction($this->pluralFormString);
195
+        }
196
+        return $this->pluralFormFunction;
197
+    }
198
+
199
+    /**
200
+     * @param $translationFile
201
+     * @return bool
202
+     */
203
+    protected function load($translationFile) {
204
+        $json = json_decode(file_get_contents($translationFile), true);
205
+        if (!is_array($json)) {
206
+            $jsonError = json_last_error();
207
+            \OC::$server->getLogger()->warning("Failed to load $translationFile - json error code: $jsonError", ['app' => 'l10n']);
208
+            return false;
209
+        }
210
+
211
+        if (!empty($json['pluralForm'])) {
212
+            $this->pluralFormString = $json['pluralForm'];
213
+        }
214
+        $this->translations = array_merge($this->translations, $json['translations']);
215
+        return true;
216
+    }
217 217
 }
Please login to merge, or discard this patch.
lib/private/legacy/api.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -331,7 +331,7 @@
 block discarded – undo
331 331
 
332 332
 	/**
333 333
 	 * http basic auth
334
-	 * @return string|false (username, or false on failure)
334
+	 * @return string (username, or false on failure)
335 335
 	 */
336 336
 	private static function loginUser() {
337 337
 		if(self::$isLoggedIn === true) {
Please login to merge, or discard this patch.
Spacing   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
 				$requirements = array()) {
93 93
 		$name = strtolower($method).$url;
94 94
 		$name = str_replace(array('/', '{', '}'), '_', $name);
95
-		if(!isset(self::$actions[$name])) {
95
+		if (!isset(self::$actions[$name])) {
96 96
 			$oldCollection = OC::$server->getRouter()->getCurrentCollection();
97 97
 			OC::$server->getRouter()->useCollection('ocs');
98 98
 			OC::$server->getRouter()->create($name, $url)
@@ -115,17 +115,17 @@  discard block
 block discarded – undo
115 115
 		$method = $request->getMethod();
116 116
 
117 117
 		// Prepare the request variables
118
-		if($method === 'PUT') {
118
+		if ($method === 'PUT') {
119 119
 			$parameters['_put'] = $request->getParams();
120
-		} else if($method === 'DELETE') {
120
+		} else if ($method === 'DELETE') {
121 121
 			$parameters['_delete'] = $request->getParams();
122 122
 		}
123 123
 		$name = $parameters['_route'];
124 124
 		// Foreach registered action
125 125
 		$responses = array();
126
-		foreach(self::$actions[$name] as $action) {
126
+		foreach (self::$actions[$name] as $action) {
127 127
 			// Check authentication and availability
128
-			if(!self::isAuthorised($action)) {
128
+			if (!self::isAuthorised($action)) {
129 129
 				$responses[] = array(
130 130
 					'app' => $action['app'],
131 131
 					'response' => new OC_OCS_Result(null, API::RESPOND_UNAUTHORISED, 'Unauthorised'),
@@ -133,7 +133,7 @@  discard block
 block discarded – undo
133 133
 					);
134 134
 				continue;
135 135
 			}
136
-			if(!is_callable($action['action'])) {
136
+			if (!is_callable($action['action'])) {
137 137
 				$responses[] = array(
138 138
 					'app' => $action['app'],
139 139
 					'response' => new OC_OCS_Result(null, API::RESPOND_NOT_FOUND, 'Api method not found'),
@@ -173,15 +173,15 @@  discard block
 block discarded – undo
173 173
 			'failed' => array(),
174 174
 			);
175 175
 
176
-		foreach($responses as $response) {
177
-			if($response['shipped'] || ($response['app'] === 'core')) {
178
-				if($response['response']->succeeded()) {
176
+		foreach ($responses as $response) {
177
+			if ($response['shipped'] || ($response['app'] === 'core')) {
178
+				if ($response['response']->succeeded()) {
179 179
 					$shipped['succeeded'][$response['app']] = $response;
180 180
 				} else {
181 181
 					$shipped['failed'][$response['app']] = $response;
182 182
 				}
183 183
 			} else {
184
-				if($response['response']->succeeded()) {
184
+				if ($response['response']->succeeded()) {
185 185
 					$thirdparty['succeeded'][$response['app']] = $response;
186 186
 				} else {
187 187
 					$thirdparty['failed'][$response['app']] = $response;
@@ -190,14 +190,14 @@  discard block
 block discarded – undo
190 190
 		}
191 191
 
192 192
 		// Remove any error responses if there is one shipped response that succeeded
193
-		if(!empty($shipped['failed'])) {
193
+		if (!empty($shipped['failed'])) {
194 194
 			// Which shipped response do we use if they all failed?
195 195
 			// They may have failed for different reasons (different status codes)
196 196
 			// Which response code should we return?
197 197
 			// Maybe any that are not \OCP\API::RESPOND_SERVER_ERROR
198 198
 			// Merge failed responses if more than one
199 199
 			$data = array();
200
-			foreach($shipped['failed'] as $failure) {
200
+			foreach ($shipped['failed'] as $failure) {
201 201
 				$data = array_merge_recursive($data, $failure['response']->getData());
202 202
 			}
203 203
 			$picked = reset($shipped['failed']);
@@ -206,12 +206,12 @@  discard block
 block discarded – undo
206 206
 			$headers = $picked['response']->getHeaders();
207 207
 			$response = new OC_OCS_Result($data, $code, $meta['message'], $headers);
208 208
 			return $response;
209
-		} elseif(!empty($shipped['succeeded'])) {
209
+		} elseif (!empty($shipped['succeeded'])) {
210 210
 			$responses = array_merge($shipped['succeeded'], $thirdparty['succeeded']);
211
-		} elseif(!empty($thirdparty['failed'])) {
211
+		} elseif (!empty($thirdparty['failed'])) {
212 212
 			// Merge failed responses if more than one
213 213
 			$data = array();
214
-			foreach($thirdparty['failed'] as $failure) {
214
+			foreach ($thirdparty['failed'] as $failure) {
215 215
 				$data = array_merge_recursive($data, $failure['response']->getData());
216 216
 			}
217 217
 			$picked = reset($thirdparty['failed']);
@@ -228,8 +228,8 @@  discard block
 block discarded – undo
228 228
 		$codes = [];
229 229
 		$header = [];
230 230
 
231
-		foreach($responses as $response) {
232
-			if($response['shipped']) {
231
+		foreach ($responses as $response) {
232
+			if ($response['shipped']) {
233 233
 				$data = array_merge_recursive($response['response']->getData(), $data);
234 234
 			} else {
235 235
 				$data = array_merge_recursive($data, $response['response']->getData());
@@ -242,8 +242,8 @@  discard block
 block discarded – undo
242 242
 		// Use any non 100 status codes
243 243
 		$statusCode = 100;
244 244
 		$statusMessage = null;
245
-		foreach($codes as $code) {
246
-			if($code['code'] != 100) {
245
+		foreach ($codes as $code) {
246
+			if ($code['code'] != 100) {
247 247
 				$statusCode = $code['code'];
248 248
 				$statusMessage = $code['meta']['message'];
249 249
 				break;
@@ -260,7 +260,7 @@  discard block
 block discarded – undo
260 260
 	 */
261 261
 	private static function isAuthorised($action) {
262 262
 		$level = $action['authlevel'];
263
-		switch($level) {
263
+		switch ($level) {
264 264
 			case API::GUEST_AUTH:
265 265
 				// Anyone can access
266 266
 				return true;
@@ -270,16 +270,16 @@  discard block
 block discarded – undo
270 270
 			case API::SUBADMIN_AUTH:
271 271
 				// Check for subadmin
272 272
 				$user = self::loginUser();
273
-				if(!$user) {
273
+				if (!$user) {
274 274
 					return false;
275 275
 				} else {
276 276
 					$userObject = \OC::$server->getUserSession()->getUser();
277
-					if($userObject === null) {
277
+					if ($userObject === null) {
278 278
 						return false;
279 279
 					}
280 280
 					$isSubAdmin = \OC::$server->getGroupManager()->getSubAdmin()->isSubAdmin($userObject);
281 281
 					$admin = OC_User::isAdminUser($user);
282
-					if($isSubAdmin || $admin) {
282
+					if ($isSubAdmin || $admin) {
283 283
 						return true;
284 284
 					} else {
285 285
 						return false;
@@ -288,7 +288,7 @@  discard block
 block discarded – undo
288 288
 			case API::ADMIN_AUTH:
289 289
 				// Check for admin
290 290
 				$user = self::loginUser();
291
-				if(!$user) {
291
+				if (!$user) {
292 292
 					return false;
293 293
 				} else {
294 294
 					return OC_User::isAdminUser($user);
@@ -304,7 +304,7 @@  discard block
 block discarded – undo
304 304
 	 * @return string|false (username, or false on failure)
305 305
 	 */
306 306
 	private static function loginUser() {
307
-		if(self::$isLoggedIn === true) {
307
+		if (self::$isLoggedIn === true) {
308 308
 			return \OC_User::getUser();
309 309
 		}
310 310
 
@@ -358,13 +358,13 @@  discard block
 block discarded – undo
358 358
 	 * @param OC_OCS_Result $result
359 359
 	 * @param string $format the format xml|json
360 360
 	 */
361
-	public static function respond($result, $format='xml') {
361
+	public static function respond($result, $format = 'xml') {
362 362
 		$request = \OC::$server->getRequest();
363 363
 
364 364
 		// Send 401 headers if unauthorised
365
-		if($result->getStatusCode() === API::RESPOND_UNAUTHORISED) {
365
+		if ($result->getStatusCode() === API::RESPOND_UNAUTHORISED) {
366 366
 			// If request comes from JS return dummy auth request
367
-			if($request->getHeader('X-Requested-With') === 'XMLHttpRequest') {
367
+			if ($request->getHeader('X-Requested-With') === 'XMLHttpRequest') {
368 368
 				header('WWW-Authenticate: DummyBasic realm="Authorisation Required"');
369 369
 			} else {
370 370
 				header('WWW-Authenticate: Basic realm="Authorisation Required"');
@@ -372,8 +372,8 @@  discard block
 block discarded – undo
372 372
 			header('HTTP/1.0 401 Unauthorized');
373 373
 		}
374 374
 
375
-		foreach($result->getHeaders() as $name => $value) {
376
-			header($name . ': ' . $value);
375
+		foreach ($result->getHeaders() as $name => $value) {
376
+			header($name.': '.$value);
377 377
 		}
378 378
 
379 379
 		$meta = $result->getMeta();
@@ -395,14 +395,14 @@  discard block
 block discarded – undo
395 395
 	 * @param XMLWriter $writer
396 396
 	 */
397 397
 	private static function toXML($array, $writer) {
398
-		foreach($array as $k => $v) {
398
+		foreach ($array as $k => $v) {
399 399
 			if ($k[0] === '@') {
400 400
 				$writer->writeAttribute(substr($k, 1), $v);
401 401
 				continue;
402 402
 			} else if (is_numeric($k)) {
403 403
 				$k = 'element';
404 404
 			}
405
-			if(is_array($v)) {
405
+			if (is_array($v)) {
406 406
 				$writer->startElement($k);
407 407
 				self::toXML($v, $writer);
408 408
 				$writer->endElement();
Please login to merge, or discard this patch.
Indentation   +462 added lines, -462 removed lines patch added patch discarded remove patch
@@ -68,467 +68,467 @@
 block discarded – undo
68 68
 
69 69
 class OC_API {
70 70
 
71
-	/**
72
-	 * API authentication levels
73
-	 */
74
-
75
-	/** @deprecated Use \OCP\API::GUEST_AUTH instead */
76
-	const GUEST_AUTH = 0;
77
-
78
-	/** @deprecated Use \OCP\API::USER_AUTH instead */
79
-	const USER_AUTH = 1;
80
-
81
-	/** @deprecated Use \OCP\API::SUBADMIN_AUTH instead */
82
-	const SUBADMIN_AUTH = 2;
83
-
84
-	/** @deprecated Use \OCP\API::ADMIN_AUTH instead */
85
-	const ADMIN_AUTH = 3;
86
-
87
-	/**
88
-	 * API Response Codes
89
-	 */
90
-
91
-	/** @deprecated Use \OCP\API::RESPOND_UNAUTHORISED instead */
92
-	const RESPOND_UNAUTHORISED = 997;
93
-
94
-	/** @deprecated Use \OCP\API::RESPOND_SERVER_ERROR instead */
95
-	const RESPOND_SERVER_ERROR = 996;
96
-
97
-	/** @deprecated Use \OCP\API::RESPOND_NOT_FOUND instead */
98
-	const RESPOND_NOT_FOUND = 998;
99
-
100
-	/** @deprecated Use \OCP\API::RESPOND_UNKNOWN_ERROR instead */
101
-	const RESPOND_UNKNOWN_ERROR = 999;
102
-
103
-	/**
104
-	 * api actions
105
-	 */
106
-	protected static $actions = array();
107
-	private static $logoutRequired = false;
108
-	private static $isLoggedIn = false;
109
-
110
-	/**
111
-	 * registers an api call
112
-	 * @param string $method the http method
113
-	 * @param string $url the url to match
114
-	 * @param callable $action the function to run
115
-	 * @param string $app the id of the app registering the call
116
-	 * @param int $authLevel the level of authentication required for the call
117
-	 * @param array $defaults
118
-	 * @param array $requirements
119
-	 */
120
-	public static function register($method, $url, $action, $app,
121
-				$authLevel = API::USER_AUTH,
122
-				$defaults = array(),
123
-				$requirements = array()) {
124
-		$name = strtolower($method).$url;
125
-		$name = str_replace(array('/', '{', '}'), '_', $name);
126
-		if(!isset(self::$actions[$name])) {
127
-			$oldCollection = OC::$server->getRouter()->getCurrentCollection();
128
-			OC::$server->getRouter()->useCollection('ocs');
129
-			OC::$server->getRouter()->create($name, $url)
130
-				->method($method)
131
-				->defaults($defaults)
132
-				->requirements($requirements)
133
-				->action('OC_API', 'call');
134
-			self::$actions[$name] = array();
135
-			OC::$server->getRouter()->useCollection($oldCollection);
136
-		}
137
-		self::$actions[$name][] = array('app' => $app, 'action' => $action, 'authlevel' => $authLevel);
138
-	}
139
-
140
-	/**
141
-	 * handles an api call
142
-	 * @param array $parameters
143
-	 */
144
-	public static function call($parameters) {
145
-		$request = \OC::$server->getRequest();
146
-		$method = $request->getMethod();
147
-
148
-		// Prepare the request variables
149
-		if($method === 'PUT') {
150
-			$parameters['_put'] = $request->getParams();
151
-		} else if($method === 'DELETE') {
152
-			$parameters['_delete'] = $request->getParams();
153
-		}
154
-		$name = $parameters['_route'];
155
-		// Foreach registered action
156
-		$responses = array();
157
-		foreach(self::$actions[$name] as $action) {
158
-			// Check authentication and availability
159
-			if(!self::isAuthorised($action)) {
160
-				$responses[] = array(
161
-					'app' => $action['app'],
162
-					'response' => new OC_OCS_Result(null, API::RESPOND_UNAUTHORISED, 'Unauthorised'),
163
-					'shipped' => OC_App::isShipped($action['app']),
164
-					);
165
-				continue;
166
-			}
167
-			if(!is_callable($action['action'])) {
168
-				$responses[] = array(
169
-					'app' => $action['app'],
170
-					'response' => new OC_OCS_Result(null, API::RESPOND_NOT_FOUND, 'Api method not found'),
171
-					'shipped' => OC_App::isShipped($action['app']),
172
-					);
173
-				continue;
174
-			}
175
-			// Run the action
176
-			$responses[] = array(
177
-				'app' => $action['app'],
178
-				'response' => call_user_func($action['action'], $parameters),
179
-				'shipped' => OC_App::isShipped($action['app']),
180
-				);
181
-		}
182
-		$response = self::mergeResponses($responses);
183
-		$format = self::requestedFormat();
184
-		if (self::$logoutRequired) {
185
-			\OC::$server->getUserSession()->logout();
186
-		}
187
-
188
-		self::respond($response, $format);
189
-	}
190
-
191
-	/**
192
-	 * merge the returned result objects into one response
193
-	 * @param array $responses
194
-	 * @return OC_OCS_Result
195
-	 */
196
-	public static function mergeResponses($responses) {
197
-		// Sort into shipped and third-party
198
-		$shipped = array(
199
-			'succeeded' => array(),
200
-			'failed' => array(),
201
-			);
202
-		$thirdparty = array(
203
-			'succeeded' => array(),
204
-			'failed' => array(),
205
-			);
206
-
207
-		foreach($responses as $response) {
208
-			if($response['shipped'] || ($response['app'] === 'core')) {
209
-				if($response['response']->succeeded()) {
210
-					$shipped['succeeded'][$response['app']] = $response;
211
-				} else {
212
-					$shipped['failed'][$response['app']] = $response;
213
-				}
214
-			} else {
215
-				if($response['response']->succeeded()) {
216
-					$thirdparty['succeeded'][$response['app']] = $response;
217
-				} else {
218
-					$thirdparty['failed'][$response['app']] = $response;
219
-				}
220
-			}
221
-		}
222
-
223
-		// Remove any error responses if there is one shipped response that succeeded
224
-		if(!empty($shipped['failed'])) {
225
-			// Which shipped response do we use if they all failed?
226
-			// They may have failed for different reasons (different status codes)
227
-			// Which response code should we return?
228
-			// Maybe any that are not \OCP\API::RESPOND_SERVER_ERROR
229
-			// Merge failed responses if more than one
230
-			$data = array();
231
-			foreach($shipped['failed'] as $failure) {
232
-				$data = array_merge_recursive($data, $failure['response']->getData());
233
-			}
234
-			$picked = reset($shipped['failed']);
235
-			$code = $picked['response']->getStatusCode();
236
-			$meta = $picked['response']->getMeta();
237
-			$headers = $picked['response']->getHeaders();
238
-			$response = new OC_OCS_Result($data, $code, $meta['message'], $headers);
239
-			return $response;
240
-		} elseif(!empty($shipped['succeeded'])) {
241
-			$responses = array_merge($shipped['succeeded'], $thirdparty['succeeded']);
242
-		} elseif(!empty($thirdparty['failed'])) {
243
-			// Merge failed responses if more than one
244
-			$data = array();
245
-			foreach($thirdparty['failed'] as $failure) {
246
-				$data = array_merge_recursive($data, $failure['response']->getData());
247
-			}
248
-			$picked = reset($thirdparty['failed']);
249
-			$code = $picked['response']->getStatusCode();
250
-			$meta = $picked['response']->getMeta();
251
-			$headers = $picked['response']->getHeaders();
252
-			$response = new OC_OCS_Result($data, $code, $meta['message'], $headers);
253
-			return $response;
254
-		} else {
255
-			$responses = $thirdparty['succeeded'];
256
-		}
257
-		// Merge the successful responses
258
-		$data = [];
259
-		$codes = [];
260
-		$header = [];
261
-
262
-		foreach($responses as $response) {
263
-			if($response['shipped']) {
264
-				$data = array_merge_recursive($response['response']->getData(), $data);
265
-			} else {
266
-				$data = array_merge_recursive($data, $response['response']->getData());
267
-			}
268
-			$header = array_merge_recursive($header, $response['response']->getHeaders());
269
-			$codes[] = ['code' => $response['response']->getStatusCode(),
270
-				'meta' => $response['response']->getMeta()];
271
-		}
272
-
273
-		// Use any non 100 status codes
274
-		$statusCode = 100;
275
-		$statusMessage = null;
276
-		foreach($codes as $code) {
277
-			if($code['code'] != 100) {
278
-				$statusCode = $code['code'];
279
-				$statusMessage = $code['meta']['message'];
280
-				break;
281
-			}
282
-		}
283
-
284
-		return new OC_OCS_Result($data, $statusCode, $statusMessage, $header);
285
-	}
286
-
287
-	/**
288
-	 * authenticate the api call
289
-	 * @param array $action the action details as supplied to OC_API::register()
290
-	 * @return bool
291
-	 */
292
-	private static function isAuthorised($action) {
293
-		$level = $action['authlevel'];
294
-		switch($level) {
295
-			case API::GUEST_AUTH:
296
-				// Anyone can access
297
-				return true;
298
-			case API::USER_AUTH:
299
-				// User required
300
-				return self::loginUser();
301
-			case API::SUBADMIN_AUTH:
302
-				// Check for subadmin
303
-				$user = self::loginUser();
304
-				if(!$user) {
305
-					return false;
306
-				} else {
307
-					$userObject = \OC::$server->getUserSession()->getUser();
308
-					if($userObject === null) {
309
-						return false;
310
-					}
311
-					$isSubAdmin = \OC::$server->getGroupManager()->getSubAdmin()->isSubAdmin($userObject);
312
-					$admin = OC_User::isAdminUser($user);
313
-					if($isSubAdmin || $admin) {
314
-						return true;
315
-					} else {
316
-						return false;
317
-					}
318
-				}
319
-			case API::ADMIN_AUTH:
320
-				// Check for admin
321
-				$user = self::loginUser();
322
-				if(!$user) {
323
-					return false;
324
-				} else {
325
-					return OC_User::isAdminUser($user);
326
-				}
327
-			default:
328
-				// oops looks like invalid level supplied
329
-				return false;
330
-		}
331
-	}
332
-
333
-	/**
334
-	 * http basic auth
335
-	 * @return string|false (username, or false on failure)
336
-	 */
337
-	private static function loginUser() {
338
-		if(self::$isLoggedIn === true) {
339
-			return \OC_User::getUser();
340
-		}
341
-
342
-		// reuse existing login
343
-		$loggedIn = \OC::$server->getUserSession()->isLoggedIn();
344
-		if ($loggedIn === true) {
345
-			if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor()) {
346
-				// Do not allow access to OCS until the 2FA challenge was solved successfully
347
-				return false;
348
-			}
349
-			$ocsApiRequest = isset($_SERVER['HTTP_OCS_APIREQUEST']) ? $_SERVER['HTTP_OCS_APIREQUEST'] === 'true' : false;
350
-			if ($ocsApiRequest) {
351
-
352
-				// initialize the user's filesystem
353
-				\OC_Util::setupFS(\OC_User::getUser());
354
-				self::$isLoggedIn = true;
355
-
356
-				return OC_User::getUser();
357
-			}
358
-			return false;
359
-		}
360
-
361
-		// basic auth - because OC_User::login will create a new session we shall only try to login
362
-		// if user and pass are set
363
-		$userSession = \OC::$server->getUserSession();
364
-		$request = \OC::$server->getRequest();
365
-		try {
366
-			$loginSuccess = $userSession->tryTokenLogin($request);
367
-			if (!$loginSuccess) {
368
-				$loginSuccess = $userSession->tryBasicAuthLogin($request, \OC::$server->getBruteForceThrottler());
369
-			}
370
-		} catch (\OC\User\LoginException $e) {
371
-			return false;
372
-		}
71
+    /**
72
+     * API authentication levels
73
+     */
74
+
75
+    /** @deprecated Use \OCP\API::GUEST_AUTH instead */
76
+    const GUEST_AUTH = 0;
77
+
78
+    /** @deprecated Use \OCP\API::USER_AUTH instead */
79
+    const USER_AUTH = 1;
80
+
81
+    /** @deprecated Use \OCP\API::SUBADMIN_AUTH instead */
82
+    const SUBADMIN_AUTH = 2;
83
+
84
+    /** @deprecated Use \OCP\API::ADMIN_AUTH instead */
85
+    const ADMIN_AUTH = 3;
86
+
87
+    /**
88
+     * API Response Codes
89
+     */
90
+
91
+    /** @deprecated Use \OCP\API::RESPOND_UNAUTHORISED instead */
92
+    const RESPOND_UNAUTHORISED = 997;
93
+
94
+    /** @deprecated Use \OCP\API::RESPOND_SERVER_ERROR instead */
95
+    const RESPOND_SERVER_ERROR = 996;
96
+
97
+    /** @deprecated Use \OCP\API::RESPOND_NOT_FOUND instead */
98
+    const RESPOND_NOT_FOUND = 998;
99
+
100
+    /** @deprecated Use \OCP\API::RESPOND_UNKNOWN_ERROR instead */
101
+    const RESPOND_UNKNOWN_ERROR = 999;
102
+
103
+    /**
104
+     * api actions
105
+     */
106
+    protected static $actions = array();
107
+    private static $logoutRequired = false;
108
+    private static $isLoggedIn = false;
109
+
110
+    /**
111
+     * registers an api call
112
+     * @param string $method the http method
113
+     * @param string $url the url to match
114
+     * @param callable $action the function to run
115
+     * @param string $app the id of the app registering the call
116
+     * @param int $authLevel the level of authentication required for the call
117
+     * @param array $defaults
118
+     * @param array $requirements
119
+     */
120
+    public static function register($method, $url, $action, $app,
121
+                $authLevel = API::USER_AUTH,
122
+                $defaults = array(),
123
+                $requirements = array()) {
124
+        $name = strtolower($method).$url;
125
+        $name = str_replace(array('/', '{', '}'), '_', $name);
126
+        if(!isset(self::$actions[$name])) {
127
+            $oldCollection = OC::$server->getRouter()->getCurrentCollection();
128
+            OC::$server->getRouter()->useCollection('ocs');
129
+            OC::$server->getRouter()->create($name, $url)
130
+                ->method($method)
131
+                ->defaults($defaults)
132
+                ->requirements($requirements)
133
+                ->action('OC_API', 'call');
134
+            self::$actions[$name] = array();
135
+            OC::$server->getRouter()->useCollection($oldCollection);
136
+        }
137
+        self::$actions[$name][] = array('app' => $app, 'action' => $action, 'authlevel' => $authLevel);
138
+    }
139
+
140
+    /**
141
+     * handles an api call
142
+     * @param array $parameters
143
+     */
144
+    public static function call($parameters) {
145
+        $request = \OC::$server->getRequest();
146
+        $method = $request->getMethod();
147
+
148
+        // Prepare the request variables
149
+        if($method === 'PUT') {
150
+            $parameters['_put'] = $request->getParams();
151
+        } else if($method === 'DELETE') {
152
+            $parameters['_delete'] = $request->getParams();
153
+        }
154
+        $name = $parameters['_route'];
155
+        // Foreach registered action
156
+        $responses = array();
157
+        foreach(self::$actions[$name] as $action) {
158
+            // Check authentication and availability
159
+            if(!self::isAuthorised($action)) {
160
+                $responses[] = array(
161
+                    'app' => $action['app'],
162
+                    'response' => new OC_OCS_Result(null, API::RESPOND_UNAUTHORISED, 'Unauthorised'),
163
+                    'shipped' => OC_App::isShipped($action['app']),
164
+                    );
165
+                continue;
166
+            }
167
+            if(!is_callable($action['action'])) {
168
+                $responses[] = array(
169
+                    'app' => $action['app'],
170
+                    'response' => new OC_OCS_Result(null, API::RESPOND_NOT_FOUND, 'Api method not found'),
171
+                    'shipped' => OC_App::isShipped($action['app']),
172
+                    );
173
+                continue;
174
+            }
175
+            // Run the action
176
+            $responses[] = array(
177
+                'app' => $action['app'],
178
+                'response' => call_user_func($action['action'], $parameters),
179
+                'shipped' => OC_App::isShipped($action['app']),
180
+                );
181
+        }
182
+        $response = self::mergeResponses($responses);
183
+        $format = self::requestedFormat();
184
+        if (self::$logoutRequired) {
185
+            \OC::$server->getUserSession()->logout();
186
+        }
187
+
188
+        self::respond($response, $format);
189
+    }
190
+
191
+    /**
192
+     * merge the returned result objects into one response
193
+     * @param array $responses
194
+     * @return OC_OCS_Result
195
+     */
196
+    public static function mergeResponses($responses) {
197
+        // Sort into shipped and third-party
198
+        $shipped = array(
199
+            'succeeded' => array(),
200
+            'failed' => array(),
201
+            );
202
+        $thirdparty = array(
203
+            'succeeded' => array(),
204
+            'failed' => array(),
205
+            );
206
+
207
+        foreach($responses as $response) {
208
+            if($response['shipped'] || ($response['app'] === 'core')) {
209
+                if($response['response']->succeeded()) {
210
+                    $shipped['succeeded'][$response['app']] = $response;
211
+                } else {
212
+                    $shipped['failed'][$response['app']] = $response;
213
+                }
214
+            } else {
215
+                if($response['response']->succeeded()) {
216
+                    $thirdparty['succeeded'][$response['app']] = $response;
217
+                } else {
218
+                    $thirdparty['failed'][$response['app']] = $response;
219
+                }
220
+            }
221
+        }
222
+
223
+        // Remove any error responses if there is one shipped response that succeeded
224
+        if(!empty($shipped['failed'])) {
225
+            // Which shipped response do we use if they all failed?
226
+            // They may have failed for different reasons (different status codes)
227
+            // Which response code should we return?
228
+            // Maybe any that are not \OCP\API::RESPOND_SERVER_ERROR
229
+            // Merge failed responses if more than one
230
+            $data = array();
231
+            foreach($shipped['failed'] as $failure) {
232
+                $data = array_merge_recursive($data, $failure['response']->getData());
233
+            }
234
+            $picked = reset($shipped['failed']);
235
+            $code = $picked['response']->getStatusCode();
236
+            $meta = $picked['response']->getMeta();
237
+            $headers = $picked['response']->getHeaders();
238
+            $response = new OC_OCS_Result($data, $code, $meta['message'], $headers);
239
+            return $response;
240
+        } elseif(!empty($shipped['succeeded'])) {
241
+            $responses = array_merge($shipped['succeeded'], $thirdparty['succeeded']);
242
+        } elseif(!empty($thirdparty['failed'])) {
243
+            // Merge failed responses if more than one
244
+            $data = array();
245
+            foreach($thirdparty['failed'] as $failure) {
246
+                $data = array_merge_recursive($data, $failure['response']->getData());
247
+            }
248
+            $picked = reset($thirdparty['failed']);
249
+            $code = $picked['response']->getStatusCode();
250
+            $meta = $picked['response']->getMeta();
251
+            $headers = $picked['response']->getHeaders();
252
+            $response = new OC_OCS_Result($data, $code, $meta['message'], $headers);
253
+            return $response;
254
+        } else {
255
+            $responses = $thirdparty['succeeded'];
256
+        }
257
+        // Merge the successful responses
258
+        $data = [];
259
+        $codes = [];
260
+        $header = [];
261
+
262
+        foreach($responses as $response) {
263
+            if($response['shipped']) {
264
+                $data = array_merge_recursive($response['response']->getData(), $data);
265
+            } else {
266
+                $data = array_merge_recursive($data, $response['response']->getData());
267
+            }
268
+            $header = array_merge_recursive($header, $response['response']->getHeaders());
269
+            $codes[] = ['code' => $response['response']->getStatusCode(),
270
+                'meta' => $response['response']->getMeta()];
271
+        }
272
+
273
+        // Use any non 100 status codes
274
+        $statusCode = 100;
275
+        $statusMessage = null;
276
+        foreach($codes as $code) {
277
+            if($code['code'] != 100) {
278
+                $statusCode = $code['code'];
279
+                $statusMessage = $code['meta']['message'];
280
+                break;
281
+            }
282
+        }
283
+
284
+        return new OC_OCS_Result($data, $statusCode, $statusMessage, $header);
285
+    }
286
+
287
+    /**
288
+     * authenticate the api call
289
+     * @param array $action the action details as supplied to OC_API::register()
290
+     * @return bool
291
+     */
292
+    private static function isAuthorised($action) {
293
+        $level = $action['authlevel'];
294
+        switch($level) {
295
+            case API::GUEST_AUTH:
296
+                // Anyone can access
297
+                return true;
298
+            case API::USER_AUTH:
299
+                // User required
300
+                return self::loginUser();
301
+            case API::SUBADMIN_AUTH:
302
+                // Check for subadmin
303
+                $user = self::loginUser();
304
+                if(!$user) {
305
+                    return false;
306
+                } else {
307
+                    $userObject = \OC::$server->getUserSession()->getUser();
308
+                    if($userObject === null) {
309
+                        return false;
310
+                    }
311
+                    $isSubAdmin = \OC::$server->getGroupManager()->getSubAdmin()->isSubAdmin($userObject);
312
+                    $admin = OC_User::isAdminUser($user);
313
+                    if($isSubAdmin || $admin) {
314
+                        return true;
315
+                    } else {
316
+                        return false;
317
+                    }
318
+                }
319
+            case API::ADMIN_AUTH:
320
+                // Check for admin
321
+                $user = self::loginUser();
322
+                if(!$user) {
323
+                    return false;
324
+                } else {
325
+                    return OC_User::isAdminUser($user);
326
+                }
327
+            default:
328
+                // oops looks like invalid level supplied
329
+                return false;
330
+        }
331
+    }
332
+
333
+    /**
334
+     * http basic auth
335
+     * @return string|false (username, or false on failure)
336
+     */
337
+    private static function loginUser() {
338
+        if(self::$isLoggedIn === true) {
339
+            return \OC_User::getUser();
340
+        }
341
+
342
+        // reuse existing login
343
+        $loggedIn = \OC::$server->getUserSession()->isLoggedIn();
344
+        if ($loggedIn === true) {
345
+            if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor()) {
346
+                // Do not allow access to OCS until the 2FA challenge was solved successfully
347
+                return false;
348
+            }
349
+            $ocsApiRequest = isset($_SERVER['HTTP_OCS_APIREQUEST']) ? $_SERVER['HTTP_OCS_APIREQUEST'] === 'true' : false;
350
+            if ($ocsApiRequest) {
351
+
352
+                // initialize the user's filesystem
353
+                \OC_Util::setupFS(\OC_User::getUser());
354
+                self::$isLoggedIn = true;
355
+
356
+                return OC_User::getUser();
357
+            }
358
+            return false;
359
+        }
360
+
361
+        // basic auth - because OC_User::login will create a new session we shall only try to login
362
+        // if user and pass are set
363
+        $userSession = \OC::$server->getUserSession();
364
+        $request = \OC::$server->getRequest();
365
+        try {
366
+            $loginSuccess = $userSession->tryTokenLogin($request);
367
+            if (!$loginSuccess) {
368
+                $loginSuccess = $userSession->tryBasicAuthLogin($request, \OC::$server->getBruteForceThrottler());
369
+            }
370
+        } catch (\OC\User\LoginException $e) {
371
+            return false;
372
+        }
373 373
 	
374
-		if ($loginSuccess === true) {
375
-			self::$logoutRequired = true;
376
-
377
-			// initialize the user's filesystem
378
-			\OC_Util::setupFS(\OC_User::getUser());
379
-			self::$isLoggedIn = true;
380
-
381
-			return \OC_User::getUser();
382
-		}
383
-
384
-		return false;
385
-	}
386
-
387
-	/**
388
-	 * respond to a call
389
-	 * @param OC_OCS_Result $result
390
-	 * @param string $format the format xml|json
391
-	 */
392
-	public static function respond($result, $format='xml') {
393
-		$request = \OC::$server->getRequest();
394
-
395
-		// Send 401 headers if unauthorised
396
-		if($result->getStatusCode() === API::RESPOND_UNAUTHORISED) {
397
-			// If request comes from JS return dummy auth request
398
-			if($request->getHeader('X-Requested-With') === 'XMLHttpRequest') {
399
-				header('WWW-Authenticate: DummyBasic realm="Authorisation Required"');
400
-			} else {
401
-				header('WWW-Authenticate: Basic realm="Authorisation Required"');
402
-			}
403
-			header('HTTP/1.0 401 Unauthorized');
404
-		}
405
-
406
-		foreach($result->getHeaders() as $name => $value) {
407
-			header($name . ': ' . $value);
408
-		}
409
-
410
-		$meta = $result->getMeta();
411
-		$data = $result->getData();
412
-		if (self::isV2($request)) {
413
-			$statusCode = self::mapStatusCodes($result->getStatusCode());
414
-			if (!is_null($statusCode)) {
415
-				$meta['statuscode'] = $statusCode;
416
-				OC_Response::setStatus($statusCode);
417
-			}
418
-		}
419
-
420
-		self::setContentType($format);
421
-		$body = self::renderResult($format, $meta, $data);
422
-		echo $body;
423
-	}
424
-
425
-	/**
426
-	 * @param XMLWriter $writer
427
-	 */
428
-	private static function toXML($array, $writer) {
429
-		foreach($array as $k => $v) {
430
-			if ($k[0] === '@') {
431
-				$writer->writeAttribute(substr($k, 1), $v);
432
-				continue;
433
-			} else if (is_numeric($k)) {
434
-				$k = 'element';
435
-			}
436
-			if(is_array($v)) {
437
-				$writer->startElement($k);
438
-				self::toXML($v, $writer);
439
-				$writer->endElement();
440
-			} else {
441
-				$writer->writeElement($k, $v);
442
-			}
443
-		}
444
-	}
445
-
446
-	/**
447
-	 * @return string
448
-	 */
449
-	public static function requestedFormat() {
450
-		$formats = array('json', 'xml');
451
-
452
-		$format = !empty($_GET['format']) && in_array($_GET['format'], $formats) ? $_GET['format'] : 'xml';
453
-		return $format;
454
-	}
455
-
456
-	/**
457
-	 * Based on the requested format the response content type is set
458
-	 * @param string $format
459
-	 */
460
-	public static function setContentType($format = null) {
461
-		$format = is_null($format) ? self::requestedFormat() : $format;
462
-		if ($format === 'xml') {
463
-			header('Content-type: text/xml; charset=UTF-8');
464
-			return;
465
-		}
466
-
467
-		if ($format === 'json') {
468
-			header('Content-Type: application/json; charset=utf-8');
469
-			return;
470
-		}
471
-
472
-		header('Content-Type: application/octet-stream; charset=utf-8');
473
-	}
474
-
475
-	/**
476
-	 * @param \OCP\IRequest $request
477
-	 * @return bool
478
-	 */
479
-	protected static function isV2(\OCP\IRequest $request) {
480
-		$script = $request->getScriptName();
481
-
482
-		return substr($script, -11) === '/ocs/v2.php';
483
-	}
484
-
485
-	/**
486
-	 * @param integer $sc
487
-	 * @return int
488
-	 */
489
-	public static function mapStatusCodes($sc) {
490
-		switch ($sc) {
491
-			case API::RESPOND_NOT_FOUND:
492
-				return Http::STATUS_NOT_FOUND;
493
-			case API::RESPOND_SERVER_ERROR:
494
-				return Http::STATUS_INTERNAL_SERVER_ERROR;
495
-			case API::RESPOND_UNKNOWN_ERROR:
496
-				return Http::STATUS_INTERNAL_SERVER_ERROR;
497
-			case API::RESPOND_UNAUTHORISED:
498
-				// already handled for v1
499
-				return null;
500
-			case 100:
501
-				return Http::STATUS_OK;
502
-		}
503
-		// any 2xx, 4xx and 5xx will be used as is
504
-		if ($sc >= 200 && $sc < 600) {
505
-			return $sc;
506
-		}
507
-
508
-		return Http::STATUS_BAD_REQUEST;
509
-	}
510
-
511
-	/**
512
-	 * @param string $format
513
-	 * @return string
514
-	 */
515
-	public static function renderResult($format, $meta, $data) {
516
-		$response = array(
517
-			'ocs' => array(
518
-				'meta' => $meta,
519
-				'data' => $data,
520
-			),
521
-		);
522
-		if ($format == 'json') {
523
-			return OC_JSON::encode($response);
524
-		}
525
-
526
-		$writer = new XMLWriter();
527
-		$writer->openMemory();
528
-		$writer->setIndent(true);
529
-		$writer->startDocument();
530
-		self::toXML($response, $writer);
531
-		$writer->endDocument();
532
-		return $writer->outputMemory(true);
533
-	}
374
+        if ($loginSuccess === true) {
375
+            self::$logoutRequired = true;
376
+
377
+            // initialize the user's filesystem
378
+            \OC_Util::setupFS(\OC_User::getUser());
379
+            self::$isLoggedIn = true;
380
+
381
+            return \OC_User::getUser();
382
+        }
383
+
384
+        return false;
385
+    }
386
+
387
+    /**
388
+     * respond to a call
389
+     * @param OC_OCS_Result $result
390
+     * @param string $format the format xml|json
391
+     */
392
+    public static function respond($result, $format='xml') {
393
+        $request = \OC::$server->getRequest();
394
+
395
+        // Send 401 headers if unauthorised
396
+        if($result->getStatusCode() === API::RESPOND_UNAUTHORISED) {
397
+            // If request comes from JS return dummy auth request
398
+            if($request->getHeader('X-Requested-With') === 'XMLHttpRequest') {
399
+                header('WWW-Authenticate: DummyBasic realm="Authorisation Required"');
400
+            } else {
401
+                header('WWW-Authenticate: Basic realm="Authorisation Required"');
402
+            }
403
+            header('HTTP/1.0 401 Unauthorized');
404
+        }
405
+
406
+        foreach($result->getHeaders() as $name => $value) {
407
+            header($name . ': ' . $value);
408
+        }
409
+
410
+        $meta = $result->getMeta();
411
+        $data = $result->getData();
412
+        if (self::isV2($request)) {
413
+            $statusCode = self::mapStatusCodes($result->getStatusCode());
414
+            if (!is_null($statusCode)) {
415
+                $meta['statuscode'] = $statusCode;
416
+                OC_Response::setStatus($statusCode);
417
+            }
418
+        }
419
+
420
+        self::setContentType($format);
421
+        $body = self::renderResult($format, $meta, $data);
422
+        echo $body;
423
+    }
424
+
425
+    /**
426
+     * @param XMLWriter $writer
427
+     */
428
+    private static function toXML($array, $writer) {
429
+        foreach($array as $k => $v) {
430
+            if ($k[0] === '@') {
431
+                $writer->writeAttribute(substr($k, 1), $v);
432
+                continue;
433
+            } else if (is_numeric($k)) {
434
+                $k = 'element';
435
+            }
436
+            if(is_array($v)) {
437
+                $writer->startElement($k);
438
+                self::toXML($v, $writer);
439
+                $writer->endElement();
440
+            } else {
441
+                $writer->writeElement($k, $v);
442
+            }
443
+        }
444
+    }
445
+
446
+    /**
447
+     * @return string
448
+     */
449
+    public static function requestedFormat() {
450
+        $formats = array('json', 'xml');
451
+
452
+        $format = !empty($_GET['format']) && in_array($_GET['format'], $formats) ? $_GET['format'] : 'xml';
453
+        return $format;
454
+    }
455
+
456
+    /**
457
+     * Based on the requested format the response content type is set
458
+     * @param string $format
459
+     */
460
+    public static function setContentType($format = null) {
461
+        $format = is_null($format) ? self::requestedFormat() : $format;
462
+        if ($format === 'xml') {
463
+            header('Content-type: text/xml; charset=UTF-8');
464
+            return;
465
+        }
466
+
467
+        if ($format === 'json') {
468
+            header('Content-Type: application/json; charset=utf-8');
469
+            return;
470
+        }
471
+
472
+        header('Content-Type: application/octet-stream; charset=utf-8');
473
+    }
474
+
475
+    /**
476
+     * @param \OCP\IRequest $request
477
+     * @return bool
478
+     */
479
+    protected static function isV2(\OCP\IRequest $request) {
480
+        $script = $request->getScriptName();
481
+
482
+        return substr($script, -11) === '/ocs/v2.php';
483
+    }
484
+
485
+    /**
486
+     * @param integer $sc
487
+     * @return int
488
+     */
489
+    public static function mapStatusCodes($sc) {
490
+        switch ($sc) {
491
+            case API::RESPOND_NOT_FOUND:
492
+                return Http::STATUS_NOT_FOUND;
493
+            case API::RESPOND_SERVER_ERROR:
494
+                return Http::STATUS_INTERNAL_SERVER_ERROR;
495
+            case API::RESPOND_UNKNOWN_ERROR:
496
+                return Http::STATUS_INTERNAL_SERVER_ERROR;
497
+            case API::RESPOND_UNAUTHORISED:
498
+                // already handled for v1
499
+                return null;
500
+            case 100:
501
+                return Http::STATUS_OK;
502
+        }
503
+        // any 2xx, 4xx and 5xx will be used as is
504
+        if ($sc >= 200 && $sc < 600) {
505
+            return $sc;
506
+        }
507
+
508
+        return Http::STATUS_BAD_REQUEST;
509
+    }
510
+
511
+    /**
512
+     * @param string $format
513
+     * @return string
514
+     */
515
+    public static function renderResult($format, $meta, $data) {
516
+        $response = array(
517
+            'ocs' => array(
518
+                'meta' => $meta,
519
+                'data' => $data,
520
+            ),
521
+        );
522
+        if ($format == 'json') {
523
+            return OC_JSON::encode($response);
524
+        }
525
+
526
+        $writer = new XMLWriter();
527
+        $writer->openMemory();
528
+        $writer->setIndent(true);
529
+        $writer->startDocument();
530
+        self::toXML($response, $writer);
531
+        $writer->endDocument();
532
+        return $writer->outputMemory(true);
533
+    }
534 534
 }
Please login to merge, or discard this patch.
lib/private/legacy/eventsource.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -88,7 +88,7 @@
 block discarded – undo
88 88
 	 * send a message to the client
89 89
 	 *
90 90
 	 * @param string $type
91
-	 * @param mixed $data
91
+	 * @param string $data
92 92
 	 *
93 93
 	 * @throws \BadMethodCallException
94 94
 	 * if only one parameter is given, a typeless message will be send with that parameter as data
Please login to merge, or discard this patch.
Indentation   +88 added lines, -88 removed lines patch added patch discarded remove patch
@@ -33,98 +33,98 @@
 block discarded – undo
33 33
  * use server side events with caution, to many open requests can hang the server
34 34
  */
35 35
 class OC_EventSource implements \OCP\IEventSource {
36
-	/**
37
-	 * @var bool
38
-	 */
39
-	private $fallback;
36
+    /**
37
+     * @var bool
38
+     */
39
+    private $fallback;
40 40
 
41
-	/**
42
-	 * @var int
43
-	 */
44
-	private $fallBackId = 0;
41
+    /**
42
+     * @var int
43
+     */
44
+    private $fallBackId = 0;
45 45
 
46
-	/**
47
-	 * @var bool
48
-	 */
49
-	private $started = false;
46
+    /**
47
+     * @var bool
48
+     */
49
+    private $started = false;
50 50
 
51
-	protected function init() {
52
-		if ($this->started) {
53
-			return;
54
-		}
55
-		$this->started = true;
51
+    protected function init() {
52
+        if ($this->started) {
53
+            return;
54
+        }
55
+        $this->started = true;
56 56
 
57
-		// prevent php output buffering, caching and nginx buffering
58
-		OC_Util::obEnd();
59
-		header('Cache-Control: no-cache');
60
-		header('X-Accel-Buffering: no');
61
-		$this->fallback = isset($_GET['fallback']) and $_GET['fallback'] == 'true';
62
-		if ($this->fallback) {
63
-			$this->fallBackId = (int)$_GET['fallback_id'];
64
-			/**
65
-			 * FIXME: The default content-security-policy of ownCloud forbids inline
66
-			 * JavaScript for security reasons. IE starting on Windows 10 will
67
-			 * however also obey the CSP which will break the event source fallback.
68
-			 *
69
-			 * As a workaround thus we set a custom policy which allows the execution
70
-			 * of inline JavaScript.
71
-			 *
72
-			 * @link https://github.com/owncloud/core/issues/14286
73
-			 */
74
-			header("Content-Security-Policy: default-src 'none'; script-src 'unsafe-inline'");
75
-			header("Content-Type: text/html");
76
-			echo str_repeat('<span></span>' . PHP_EOL, 10); //dummy data to keep IE happy
77
-		} else {
78
-			header("Content-Type: text/event-stream");
79
-		}
80
-		if(!\OC::$server->getRequest()->passesStrictCookieCheck()) {
81
-			header('Location: '.\OC::$WEBROOT);
82
-			exit();
83
-		}
84
-		if (!(\OC::$server->getRequest()->passesCSRFCheck())) {
85
-			$this->send('error', 'Possible CSRF attack. Connection will be closed.');
86
-			$this->close();
87
-			exit();
88
-		}
89
-		flush();
90
-	}
57
+        // prevent php output buffering, caching and nginx buffering
58
+        OC_Util::obEnd();
59
+        header('Cache-Control: no-cache');
60
+        header('X-Accel-Buffering: no');
61
+        $this->fallback = isset($_GET['fallback']) and $_GET['fallback'] == 'true';
62
+        if ($this->fallback) {
63
+            $this->fallBackId = (int)$_GET['fallback_id'];
64
+            /**
65
+             * FIXME: The default content-security-policy of ownCloud forbids inline
66
+             * JavaScript for security reasons. IE starting on Windows 10 will
67
+             * however also obey the CSP which will break the event source fallback.
68
+             *
69
+             * As a workaround thus we set a custom policy which allows the execution
70
+             * of inline JavaScript.
71
+             *
72
+             * @link https://github.com/owncloud/core/issues/14286
73
+             */
74
+            header("Content-Security-Policy: default-src 'none'; script-src 'unsafe-inline'");
75
+            header("Content-Type: text/html");
76
+            echo str_repeat('<span></span>' . PHP_EOL, 10); //dummy data to keep IE happy
77
+        } else {
78
+            header("Content-Type: text/event-stream");
79
+        }
80
+        if(!\OC::$server->getRequest()->passesStrictCookieCheck()) {
81
+            header('Location: '.\OC::$WEBROOT);
82
+            exit();
83
+        }
84
+        if (!(\OC::$server->getRequest()->passesCSRFCheck())) {
85
+            $this->send('error', 'Possible CSRF attack. Connection will be closed.');
86
+            $this->close();
87
+            exit();
88
+        }
89
+        flush();
90
+    }
91 91
 
92
-	/**
93
-	 * send a message to the client
94
-	 *
95
-	 * @param string $type
96
-	 * @param mixed $data
97
-	 *
98
-	 * @throws \BadMethodCallException
99
-	 * if only one parameter is given, a typeless message will be send with that parameter as data
100
-	 */
101
-	public function send($type, $data = null) {
102
-		if ($data and !preg_match('/^[A-Za-z0-9_]+$/', $type)) {
103
-			throw new BadMethodCallException('Type needs to be alphanumeric ('. $type .')');
104
-		}
105
-		$this->init();
106
-		if (is_null($data)) {
107
-			$data = $type;
108
-			$type = null;
109
-		}
110
-		if ($this->fallback) {
111
-			$response = '<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack('
112
-				. $this->fallBackId . ',"' . $type . '",' . OCP\JSON::encode($data) . ')</script>' . PHP_EOL;
113
-			echo $response;
114
-		} else {
115
-			if ($type) {
116
-				echo 'event: ' . $type . PHP_EOL;
117
-			}
118
-			echo 'data: ' . OCP\JSON::encode($data) . PHP_EOL;
119
-		}
120
-		echo PHP_EOL;
121
-		flush();
122
-	}
92
+    /**
93
+     * send a message to the client
94
+     *
95
+     * @param string $type
96
+     * @param mixed $data
97
+     *
98
+     * @throws \BadMethodCallException
99
+     * if only one parameter is given, a typeless message will be send with that parameter as data
100
+     */
101
+    public function send($type, $data = null) {
102
+        if ($data and !preg_match('/^[A-Za-z0-9_]+$/', $type)) {
103
+            throw new BadMethodCallException('Type needs to be alphanumeric ('. $type .')');
104
+        }
105
+        $this->init();
106
+        if (is_null($data)) {
107
+            $data = $type;
108
+            $type = null;
109
+        }
110
+        if ($this->fallback) {
111
+            $response = '<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack('
112
+                . $this->fallBackId . ',"' . $type . '",' . OCP\JSON::encode($data) . ')</script>' . PHP_EOL;
113
+            echo $response;
114
+        } else {
115
+            if ($type) {
116
+                echo 'event: ' . $type . PHP_EOL;
117
+            }
118
+            echo 'data: ' . OCP\JSON::encode($data) . PHP_EOL;
119
+        }
120
+        echo PHP_EOL;
121
+        flush();
122
+    }
123 123
 
124
-	/**
125
-	 * close the connection of the event source
126
-	 */
127
-	public function close() {
128
-		$this->send('__internal__', 'close'); //server side closing can be an issue, let the client do it
129
-	}
124
+    /**
125
+     * close the connection of the event source
126
+     */
127
+    public function close() {
128
+        $this->send('__internal__', 'close'); //server side closing can be an issue, let the client do it
129
+    }
130 130
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -60,7 +60,7 @@  discard block
 block discarded – undo
60 60
 		header('X-Accel-Buffering: no');
61 61
 		$this->fallback = isset($_GET['fallback']) and $_GET['fallback'] == 'true';
62 62
 		if ($this->fallback) {
63
-			$this->fallBackId = (int)$_GET['fallback_id'];
63
+			$this->fallBackId = (int) $_GET['fallback_id'];
64 64
 			/**
65 65
 			 * FIXME: The default content-security-policy of ownCloud forbids inline
66 66
 			 * JavaScript for security reasons. IE starting on Windows 10 will
@@ -73,11 +73,11 @@  discard block
 block discarded – undo
73 73
 			 */
74 74
 			header("Content-Security-Policy: default-src 'none'; script-src 'unsafe-inline'");
75 75
 			header("Content-Type: text/html");
76
-			echo str_repeat('<span></span>' . PHP_EOL, 10); //dummy data to keep IE happy
76
+			echo str_repeat('<span></span>'.PHP_EOL, 10); //dummy data to keep IE happy
77 77
 		} else {
78 78
 			header("Content-Type: text/event-stream");
79 79
 		}
80
-		if(!\OC::$server->getRequest()->passesStrictCookieCheck()) {
80
+		if (!\OC::$server->getRequest()->passesStrictCookieCheck()) {
81 81
 			header('Location: '.\OC::$WEBROOT);
82 82
 			exit();
83 83
 		}
@@ -100,7 +100,7 @@  discard block
 block discarded – undo
100 100
 	 */
101 101
 	public function send($type, $data = null) {
102 102
 		if ($data and !preg_match('/^[A-Za-z0-9_]+$/', $type)) {
103
-			throw new BadMethodCallException('Type needs to be alphanumeric ('. $type .')');
103
+			throw new BadMethodCallException('Type needs to be alphanumeric ('.$type.')');
104 104
 		}
105 105
 		$this->init();
106 106
 		if (is_null($data)) {
@@ -109,13 +109,13 @@  discard block
 block discarded – undo
109 109
 		}
110 110
 		if ($this->fallback) {
111 111
 			$response = '<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack('
112
-				. $this->fallBackId . ',"' . $type . '",' . OCP\JSON::encode($data) . ')</script>' . PHP_EOL;
112
+				. $this->fallBackId.',"'.$type.'",'.OCP\JSON::encode($data).')</script>'.PHP_EOL;
113 113
 			echo $response;
114 114
 		} else {
115 115
 			if ($type) {
116
-				echo 'event: ' . $type . PHP_EOL;
116
+				echo 'event: '.$type.PHP_EOL;
117 117
 			}
118
-			echo 'data: ' . OCP\JSON::encode($data) . PHP_EOL;
118
+			echo 'data: '.OCP\JSON::encode($data).PHP_EOL;
119 119
 		}
120 120
 		echo PHP_EOL;
121 121
 		flush();
Please login to merge, or discard this patch.
lib/private/legacy/helper.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -560,7 +560,7 @@
 block discarded – undo
560 560
 	 *
561 561
 	 * @param string $path
562 562
 	 * @param \OCP\Files\FileInfo $rootInfo (optional)
563
-	 * @return array
563
+	 * @return string
564 564
 	 * @throws \OCP\Files\NotFoundException
565 565
 	 */
566 566
 	public static function getStorageInfo($path, $rootInfo = null) {
Please login to merge, or discard this patch.
Braces   +3 added lines, -2 removed lines patch added patch discarded remove patch
@@ -271,8 +271,9 @@
 block discarded – undo
271 271
 		}
272 272
 		foreach ($dirs as $dir) {
273 273
 			foreach ($exts as $ext) {
274
-				if ($check_fn("$dir/$name" . $ext))
275
-					return true;
274
+				if ($check_fn("$dir/$name" . $ext)) {
275
+									return true;
276
+				}
276 277
 			}
277 278
 		}
278 279
 		return false;
Please login to merge, or discard this patch.
Indentation   +624 added lines, -624 removed lines patch added patch discarded remove patch
@@ -48,628 +48,628 @@
 block discarded – undo
48 48
  * Collection of useful functions
49 49
  */
50 50
 class OC_Helper {
51
-	private static $templateManager;
52
-
53
-	/**
54
-	 * Creates an absolute url for public use
55
-	 * @param string $service id
56
-	 * @param bool $add_slash
57
-	 * @return string the url
58
-	 *
59
-	 * Returns a absolute url to the given service.
60
-	 */
61
-	public static function linkToPublic($service, $add_slash = false) {
62
-		if ($service === 'files') {
63
-			$url = OC::$server->getURLGenerator()->getAbsoluteURL('/s');
64
-		} else {
65
-			$url = OC::$server->getURLGenerator()->getAbsoluteURL(OC::$server->getURLGenerator()->linkTo('', 'public.php').'?service='.$service);
66
-		}
67
-		return $url . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : '');
68
-	}
69
-
70
-	/**
71
-	 * Make a human file size
72
-	 * @param int $bytes file size in bytes
73
-	 * @return string a human readable file size
74
-	 *
75
-	 * Makes 2048 to 2 kB.
76
-	 */
77
-	public static function humanFileSize($bytes) {
78
-		if ($bytes < 0) {
79
-			return "?";
80
-		}
81
-		if ($bytes < 1024) {
82
-			return "$bytes B";
83
-		}
84
-		$bytes = round($bytes / 1024, 0);
85
-		if ($bytes < 1024) {
86
-			return "$bytes KB";
87
-		}
88
-		$bytes = round($bytes / 1024, 1);
89
-		if ($bytes < 1024) {
90
-			return "$bytes MB";
91
-		}
92
-		$bytes = round($bytes / 1024, 1);
93
-		if ($bytes < 1024) {
94
-			return "$bytes GB";
95
-		}
96
-		$bytes = round($bytes / 1024, 1);
97
-		if ($bytes < 1024) {
98
-			return "$bytes TB";
99
-		}
100
-
101
-		$bytes = round($bytes / 1024, 1);
102
-		return "$bytes PB";
103
-	}
104
-
105
-	/**
106
-	 * Make a php file size
107
-	 * @param int $bytes file size in bytes
108
-	 * @return string a php parseable file size
109
-	 *
110
-	 * Makes 2048 to 2k and 2^41 to 2048G
111
-	 */
112
-	public static function phpFileSize($bytes) {
113
-		if ($bytes < 0) {
114
-			return "?";
115
-		}
116
-		if ($bytes < 1024) {
117
-			return $bytes . "B";
118
-		}
119
-		$bytes = round($bytes / 1024, 1);
120
-		if ($bytes < 1024) {
121
-			return $bytes . "K";
122
-		}
123
-		$bytes = round($bytes / 1024, 1);
124
-		if ($bytes < 1024) {
125
-			return $bytes . "M";
126
-		}
127
-		$bytes = round($bytes / 1024, 1);
128
-		return $bytes . "G";
129
-	}
130
-
131
-	/**
132
-	 * Make a computer file size
133
-	 * @param string $str file size in human readable format
134
-	 * @return float a file size in bytes
135
-	 *
136
-	 * Makes 2kB to 2048.
137
-	 *
138
-	 * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418
139
-	 */
140
-	public static function computerFileSize($str) {
141
-		$str = strtolower($str);
142
-		if (is_numeric($str)) {
143
-			return floatval($str);
144
-		}
145
-
146
-		$bytes_array = array(
147
-			'b' => 1,
148
-			'k' => 1024,
149
-			'kb' => 1024,
150
-			'mb' => 1024 * 1024,
151
-			'm' => 1024 * 1024,
152
-			'gb' => 1024 * 1024 * 1024,
153
-			'g' => 1024 * 1024 * 1024,
154
-			'tb' => 1024 * 1024 * 1024 * 1024,
155
-			't' => 1024 * 1024 * 1024 * 1024,
156
-			'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
157
-			'p' => 1024 * 1024 * 1024 * 1024 * 1024,
158
-		);
159
-
160
-		$bytes = floatval($str);
161
-
162
-		if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
163
-			$bytes *= $bytes_array[$matches[1]];
164
-		} else {
165
-			return false;
166
-		}
167
-
168
-		$bytes = round($bytes);
169
-
170
-		return $bytes;
171
-	}
172
-
173
-	/**
174
-	 * Recursive copying of folders
175
-	 * @param string $src source folder
176
-	 * @param string $dest target folder
177
-	 *
178
-	 */
179
-	static function copyr($src, $dest) {
180
-		if (is_dir($src)) {
181
-			if (!is_dir($dest)) {
182
-				mkdir($dest);
183
-			}
184
-			$files = scandir($src);
185
-			foreach ($files as $file) {
186
-				if ($file != "." && $file != "..") {
187
-					self::copyr("$src/$file", "$dest/$file");
188
-				}
189
-			}
190
-		} elseif (file_exists($src) && !\OC\Files\Filesystem::isFileBlacklisted($src)) {
191
-			copy($src, $dest);
192
-		}
193
-	}
194
-
195
-	/**
196
-	 * Recursive deletion of folders
197
-	 * @param string $dir path to the folder
198
-	 * @param bool $deleteSelf if set to false only the content of the folder will be deleted
199
-	 * @return bool
200
-	 */
201
-	static function rmdirr($dir, $deleteSelf = true) {
202
-		if (is_dir($dir)) {
203
-			$files = new RecursiveIteratorIterator(
204
-				new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
205
-				RecursiveIteratorIterator::CHILD_FIRST
206
-			);
207
-
208
-			foreach ($files as $fileInfo) {
209
-				/** @var SplFileInfo $fileInfo */
210
-				if ($fileInfo->isLink()) {
211
-					unlink($fileInfo->getPathname());
212
-				} else if ($fileInfo->isDir()) {
213
-					rmdir($fileInfo->getRealPath());
214
-				} else {
215
-					unlink($fileInfo->getRealPath());
216
-				}
217
-			}
218
-			if ($deleteSelf) {
219
-				rmdir($dir);
220
-			}
221
-		} elseif (file_exists($dir)) {
222
-			if ($deleteSelf) {
223
-				unlink($dir);
224
-			}
225
-		}
226
-		if (!$deleteSelf) {
227
-			return true;
228
-		}
229
-
230
-		return !file_exists($dir);
231
-	}
232
-
233
-	/**
234
-	 * @return \OC\Files\Type\TemplateManager
235
-	 */
236
-	static public function getFileTemplateManager() {
237
-		if (!self::$templateManager) {
238
-			self::$templateManager = new \OC\Files\Type\TemplateManager();
239
-		}
240
-		return self::$templateManager;
241
-	}
242
-
243
-	/**
244
-	 * detect if a given program is found in the search PATH
245
-	 *
246
-	 * @param string $name
247
-	 * @param bool $path
248
-	 * @internal param string $program name
249
-	 * @internal param string $optional search path, defaults to $PATH
250
-	 * @return bool    true if executable program found in path
251
-	 */
252
-	public static function canExecute($name, $path = false) {
253
-		// path defaults to PATH from environment if not set
254
-		if ($path === false) {
255
-			$path = getenv("PATH");
256
-		}
257
-		// check method depends on operating system
258
-		if (!strncmp(PHP_OS, "WIN", 3)) {
259
-			// on Windows an appropriate COM or EXE file needs to exist
260
-			$exts = array(".exe", ".com");
261
-			$check_fn = "file_exists";
262
-		} else {
263
-			// anywhere else we look for an executable file of that name
264
-			$exts = array("");
265
-			$check_fn = "is_executable";
266
-		}
267
-		// Default check will be done with $path directories :
268
-		$dirs = explode(PATH_SEPARATOR, $path);
269
-		// WARNING : We have to check if open_basedir is enabled :
270
-		$obd = OC::$server->getIniWrapper()->getString('open_basedir');
271
-		if ($obd != "none") {
272
-			$obd_values = explode(PATH_SEPARATOR, $obd);
273
-			if (count($obd_values) > 0 and $obd_values[0]) {
274
-				// open_basedir is in effect !
275
-				// We need to check if the program is in one of these dirs :
276
-				$dirs = $obd_values;
277
-			}
278
-		}
279
-		foreach ($dirs as $dir) {
280
-			foreach ($exts as $ext) {
281
-				if ($check_fn("$dir/$name" . $ext))
282
-					return true;
283
-			}
284
-		}
285
-		return false;
286
-	}
287
-
288
-	/**
289
-	 * copy the contents of one stream to another
290
-	 *
291
-	 * @param resource $source
292
-	 * @param resource $target
293
-	 * @return array the number of bytes copied and result
294
-	 */
295
-	public static function streamCopy($source, $target) {
296
-		if (!$source or !$target) {
297
-			return array(0, false);
298
-		}
299
-		$bufSize = 8192;
300
-		$result = true;
301
-		$count = 0;
302
-		while (!feof($source)) {
303
-			$buf = fread($source, $bufSize);
304
-			$bytesWritten = fwrite($target, $buf);
305
-			if ($bytesWritten !== false) {
306
-				$count += $bytesWritten;
307
-			}
308
-			// note: strlen is expensive so only use it when necessary,
309
-			// on the last block
310
-			if ($bytesWritten === false
311
-				|| ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
312
-			) {
313
-				// write error, could be disk full ?
314
-				$result = false;
315
-				break;
316
-			}
317
-		}
318
-		return array($count, $result);
319
-	}
320
-
321
-	/**
322
-	 * Adds a suffix to the name in case the file exists
323
-	 *
324
-	 * @param string $path
325
-	 * @param string $filename
326
-	 * @return string
327
-	 */
328
-	public static function buildNotExistingFileName($path, $filename) {
329
-		$view = \OC\Files\Filesystem::getView();
330
-		return self::buildNotExistingFileNameForView($path, $filename, $view);
331
-	}
332
-
333
-	/**
334
-	 * Adds a suffix to the name in case the file exists
335
-	 *
336
-	 * @param string $path
337
-	 * @param string $filename
338
-	 * @return string
339
-	 */
340
-	public static function buildNotExistingFileNameForView($path, $filename, \OC\Files\View $view) {
341
-		if ($path === '/') {
342
-			$path = '';
343
-		}
344
-		if ($pos = strrpos($filename, '.')) {
345
-			$name = substr($filename, 0, $pos);
346
-			$ext = substr($filename, $pos);
347
-		} else {
348
-			$name = $filename;
349
-			$ext = '';
350
-		}
351
-
352
-		$newpath = $path . '/' . $filename;
353
-		if ($view->file_exists($newpath)) {
354
-			if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
355
-				//Replace the last "(number)" with "(number+1)"
356
-				$last_match = count($matches[0]) - 1;
357
-				$counter = $matches[1][$last_match][0] + 1;
358
-				$offset = $matches[0][$last_match][1];
359
-				$match_length = strlen($matches[0][$last_match][0]);
360
-			} else {
361
-				$counter = 2;
362
-				$match_length = 0;
363
-				$offset = false;
364
-			}
365
-			do {
366
-				if ($offset) {
367
-					//Replace the last "(number)" with "(number+1)"
368
-					$newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length);
369
-				} else {
370
-					$newname = $name . ' (' . $counter . ')';
371
-				}
372
-				$newpath = $path . '/' . $newname . $ext;
373
-				$counter++;
374
-			} while ($view->file_exists($newpath));
375
-		}
376
-
377
-		return $newpath;
378
-	}
379
-
380
-	/**
381
-	 * Checks if $sub is a subdirectory of $parent
382
-	 *
383
-	 * @param string $sub
384
-	 * @param string $parent
385
-	 * @return bool
386
-	 */
387
-	public static function isSubDirectory($sub, $parent) {
388
-		$realpathSub = realpath($sub);
389
-		$realpathParent = realpath($parent);
390
-
391
-		// realpath() may return false in case the directory does not exist
392
-		// since we can not be sure how different PHP versions may behave here
393
-		// we do an additional check whether realpath returned false
394
-		if($realpathSub === false ||  $realpathParent === false) {
395
-			return false;
396
-		}
397
-
398
-		// Check whether $sub is a subdirectory of $parent
399
-		if (strpos($realpathSub, $realpathParent) === 0) {
400
-			return true;
401
-		}
402
-
403
-		return false;
404
-	}
405
-
406
-	/**
407
-	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
408
-	 *
409
-	 * @param array $input The array to work on
410
-	 * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
411
-	 * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
412
-	 * @return array
413
-	 *
414
-	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
415
-	 * based on http://www.php.net/manual/en/function.array-change-key-case.php#107715
416
-	 *
417
-	 */
418
-	public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
419
-		$case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER;
420
-		$ret = array();
421
-		foreach ($input as $k => $v) {
422
-			$ret[mb_convert_case($k, $case, $encoding)] = $v;
423
-		}
424
-		return $ret;
425
-	}
426
-
427
-	/**
428
-	 * performs a search in a nested array
429
-	 * @param array $haystack the array to be searched
430
-	 * @param string $needle the search string
431
-	 * @param string $index optional, only search this key name
432
-	 * @return mixed the key of the matching field, otherwise false
433
-	 *
434
-	 * performs a search in a nested array
435
-	 *
436
-	 * taken from http://www.php.net/manual/en/function.array-search.php#97645
437
-	 */
438
-	public static function recursiveArraySearch($haystack, $needle, $index = null) {
439
-		$aIt = new RecursiveArrayIterator($haystack);
440
-		$it = new RecursiveIteratorIterator($aIt);
441
-
442
-		while ($it->valid()) {
443
-			if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
444
-				return $aIt->key();
445
-			}
446
-
447
-			$it->next();
448
-		}
449
-
450
-		return false;
451
-	}
452
-
453
-	/**
454
-	 * calculates the maximum upload size respecting system settings, free space and user quota
455
-	 *
456
-	 * @param string $dir the current folder where the user currently operates
457
-	 * @param int $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
458
-	 * @return int number of bytes representing
459
-	 */
460
-	public static function maxUploadFilesize($dir, $freeSpace = null) {
461
-		if (is_null($freeSpace) || $freeSpace < 0){
462
-			$freeSpace = self::freeSpace($dir);
463
-		}
464
-		return min($freeSpace, self::uploadLimit());
465
-	}
466
-
467
-	/**
468
-	 * Calculate free space left within user quota
469
-	 *
470
-	 * @param string $dir the current folder where the user currently operates
471
-	 * @return int number of bytes representing
472
-	 */
473
-	public static function freeSpace($dir) {
474
-		$freeSpace = \OC\Files\Filesystem::free_space($dir);
475
-		if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
476
-			$freeSpace = max($freeSpace, 0);
477
-			return $freeSpace;
478
-		} else {
479
-			return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
480
-		}
481
-	}
482
-
483
-	/**
484
-	 * Calculate PHP upload limit
485
-	 *
486
-	 * @return int PHP upload file size limit
487
-	 */
488
-	public static function uploadLimit() {
489
-		$ini = \OC::$server->getIniWrapper();
490
-		$upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
491
-		$post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size'));
492
-		if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
493
-			return INF;
494
-		} elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
495
-			return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
496
-		} else {
497
-			return min($upload_max_filesize, $post_max_size);
498
-		}
499
-	}
500
-
501
-	/**
502
-	 * Checks if a function is available
503
-	 *
504
-	 * @param string $function_name
505
-	 * @return bool
506
-	 */
507
-	public static function is_function_enabled($function_name) {
508
-		if (!function_exists($function_name)) {
509
-			return false;
510
-		}
511
-		$ini = \OC::$server->getIniWrapper();
512
-		$disabled = explode(',', $ini->get('disable_functions'));
513
-		$disabled = array_map('trim', $disabled);
514
-		if (in_array($function_name, $disabled)) {
515
-			return false;
516
-		}
517
-		$disabled = explode(',', $ini->get('suhosin.executor.func.blacklist'));
518
-		$disabled = array_map('trim', $disabled);
519
-		if (in_array($function_name, $disabled)) {
520
-			return false;
521
-		}
522
-		return true;
523
-	}
524
-
525
-	/**
526
-	 * Try to find a program
527
-	 * Note: currently windows is not supported
528
-	 *
529
-	 * @param string $program
530
-	 * @return null|string
531
-	 */
532
-	public static function findBinaryPath($program) {
533
-		$memcache = \OC::$server->getMemCacheFactory()->create('findBinaryPath');
534
-		if ($memcache->hasKey($program)) {
535
-			return $memcache->get($program);
536
-		}
537
-		$result = null;
538
-		if (self::is_function_enabled('exec')) {
539
-			$exeSniffer = new ExecutableFinder();
540
-			// Returns null if nothing is found
541
-			$result = $exeSniffer->find($program);
542
-			if (empty($result)) {
543
-				$paths = getenv('PATH');
544
-				if (empty($paths)) {
545
-					$paths = '/usr/local/bin /usr/bin /opt/bin /bin';
546
-				} else {
547
-					$paths = str_replace(':',' ',getenv('PATH'));
548
-				}
549
-				$command = 'find ' . $paths . ' -name ' . escapeshellarg($program) . ' 2> /dev/null';
550
-				exec($command, $output, $returnCode);
551
-				if (count($output) > 0) {
552
-					$result = escapeshellcmd($output[0]);
553
-				}
554
-			}
555
-		}
556
-		// store the value for 5 minutes
557
-		$memcache->set($program, $result, 300);
558
-		return $result;
559
-	}
560
-
561
-	/**
562
-	 * Calculate the disc space for the given path
563
-	 *
564
-	 * @param string $path
565
-	 * @param \OCP\Files\FileInfo $rootInfo (optional)
566
-	 * @return array
567
-	 * @throws \OCP\Files\NotFoundException
568
-	 */
569
-	public static function getStorageInfo($path, $rootInfo = null) {
570
-		// return storage info without adding mount points
571
-		$includeExtStorage = \OC::$server->getSystemConfig()->getValue('quota_include_external_storage', false);
572
-
573
-		if (!$rootInfo) {
574
-			$rootInfo = \OC\Files\Filesystem::getFileInfo($path, false);
575
-		}
576
-		if (!$rootInfo instanceof \OCP\Files\FileInfo) {
577
-			throw new \OCP\Files\NotFoundException();
578
-		}
579
-		$used = $rootInfo->getSize();
580
-		if ($used < 0) {
581
-			$used = 0;
582
-		}
583
-		$quota = \OCP\Files\FileInfo::SPACE_UNLIMITED;
584
-		$storage = $rootInfo->getStorage();
585
-		$sourceStorage = $storage;
586
-		if ($storage->instanceOfStorage('\OC\Files\Storage\Shared')) {
587
-			$includeExtStorage = false;
588
-			$sourceStorage = $storage->getSourceStorage();
589
-		}
590
-		if ($includeExtStorage) {
591
-			$quota = OC_Util::getUserQuota(\OCP\User::getUser());
592
-			if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
593
-				// always get free space / total space from root + mount points
594
-				return self::getGlobalStorageInfo();
595
-			}
596
-		}
597
-
598
-		// TODO: need a better way to get total space from storage
599
-		if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota')) {
600
-			/** @var \OC\Files\Storage\Wrapper\Quota $storage */
601
-			$quota = $sourceStorage->getQuota();
602
-		}
603
-		$free = $sourceStorage->free_space('');
604
-		if ($free >= 0) {
605
-			$total = $free + $used;
606
-		} else {
607
-			$total = $free; //either unknown or unlimited
608
-		}
609
-		if ($total > 0) {
610
-			if ($quota > 0 && $total > $quota) {
611
-				$total = $quota;
612
-			}
613
-			// prevent division by zero or error codes (negative values)
614
-			$relative = round(($used / $total) * 10000) / 100;
615
-		} else {
616
-			$relative = 0;
617
-		}
618
-
619
-		$ownerId = $storage->getOwner($path);
620
-		$ownerDisplayName = '';
621
-		$owner = \OC::$server->getUserManager()->get($ownerId);
622
-		if($owner) {
623
-			$ownerDisplayName = $owner->getDisplayName();
624
-		}
625
-
626
-		return [
627
-			'free' => $free,
628
-			'used' => $used,
629
-			'quota' => $quota,
630
-			'total' => $total,
631
-			'relative' => $relative,
632
-			'owner' => $ownerId,
633
-			'ownerDisplayName' => $ownerDisplayName,
634
-		];
635
-	}
636
-
637
-	/**
638
-	 * Get storage info including all mount points and quota
639
-	 *
640
-	 * @return array
641
-	 */
642
-	private static function getGlobalStorageInfo() {
643
-		$quota = OC_Util::getUserQuota(\OCP\User::getUser());
644
-
645
-		$rootInfo = \OC\Files\Filesystem::getFileInfo('', 'ext');
646
-		$used = $rootInfo['size'];
647
-		if ($used < 0) {
648
-			$used = 0;
649
-		}
650
-
651
-		$total = $quota;
652
-		$free = $quota - $used;
653
-
654
-		if ($total > 0) {
655
-			if ($quota > 0 && $total > $quota) {
656
-				$total = $quota;
657
-			}
658
-			// prevent division by zero or error codes (negative values)
659
-			$relative = round(($used / $total) * 10000) / 100;
660
-		} else {
661
-			$relative = 0;
662
-		}
663
-
664
-		return array('free' => $free, 'used' => $used, 'total' => $total, 'relative' => $relative);
665
-
666
-	}
667
-
668
-	/**
669
-	 * Returns whether the config file is set manually to read-only
670
-	 * @return bool
671
-	 */
672
-	public static function isReadOnlyConfigEnabled() {
673
-		return \OC::$server->getConfig()->getSystemValue('config_is_read_only', false);
674
-	}
51
+    private static $templateManager;
52
+
53
+    /**
54
+     * Creates an absolute url for public use
55
+     * @param string $service id
56
+     * @param bool $add_slash
57
+     * @return string the url
58
+     *
59
+     * Returns a absolute url to the given service.
60
+     */
61
+    public static function linkToPublic($service, $add_slash = false) {
62
+        if ($service === 'files') {
63
+            $url = OC::$server->getURLGenerator()->getAbsoluteURL('/s');
64
+        } else {
65
+            $url = OC::$server->getURLGenerator()->getAbsoluteURL(OC::$server->getURLGenerator()->linkTo('', 'public.php').'?service='.$service);
66
+        }
67
+        return $url . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : '');
68
+    }
69
+
70
+    /**
71
+     * Make a human file size
72
+     * @param int $bytes file size in bytes
73
+     * @return string a human readable file size
74
+     *
75
+     * Makes 2048 to 2 kB.
76
+     */
77
+    public static function humanFileSize($bytes) {
78
+        if ($bytes < 0) {
79
+            return "?";
80
+        }
81
+        if ($bytes < 1024) {
82
+            return "$bytes B";
83
+        }
84
+        $bytes = round($bytes / 1024, 0);
85
+        if ($bytes < 1024) {
86
+            return "$bytes KB";
87
+        }
88
+        $bytes = round($bytes / 1024, 1);
89
+        if ($bytes < 1024) {
90
+            return "$bytes MB";
91
+        }
92
+        $bytes = round($bytes / 1024, 1);
93
+        if ($bytes < 1024) {
94
+            return "$bytes GB";
95
+        }
96
+        $bytes = round($bytes / 1024, 1);
97
+        if ($bytes < 1024) {
98
+            return "$bytes TB";
99
+        }
100
+
101
+        $bytes = round($bytes / 1024, 1);
102
+        return "$bytes PB";
103
+    }
104
+
105
+    /**
106
+     * Make a php file size
107
+     * @param int $bytes file size in bytes
108
+     * @return string a php parseable file size
109
+     *
110
+     * Makes 2048 to 2k and 2^41 to 2048G
111
+     */
112
+    public static function phpFileSize($bytes) {
113
+        if ($bytes < 0) {
114
+            return "?";
115
+        }
116
+        if ($bytes < 1024) {
117
+            return $bytes . "B";
118
+        }
119
+        $bytes = round($bytes / 1024, 1);
120
+        if ($bytes < 1024) {
121
+            return $bytes . "K";
122
+        }
123
+        $bytes = round($bytes / 1024, 1);
124
+        if ($bytes < 1024) {
125
+            return $bytes . "M";
126
+        }
127
+        $bytes = round($bytes / 1024, 1);
128
+        return $bytes . "G";
129
+    }
130
+
131
+    /**
132
+     * Make a computer file size
133
+     * @param string $str file size in human readable format
134
+     * @return float a file size in bytes
135
+     *
136
+     * Makes 2kB to 2048.
137
+     *
138
+     * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418
139
+     */
140
+    public static function computerFileSize($str) {
141
+        $str = strtolower($str);
142
+        if (is_numeric($str)) {
143
+            return floatval($str);
144
+        }
145
+
146
+        $bytes_array = array(
147
+            'b' => 1,
148
+            'k' => 1024,
149
+            'kb' => 1024,
150
+            'mb' => 1024 * 1024,
151
+            'm' => 1024 * 1024,
152
+            'gb' => 1024 * 1024 * 1024,
153
+            'g' => 1024 * 1024 * 1024,
154
+            'tb' => 1024 * 1024 * 1024 * 1024,
155
+            't' => 1024 * 1024 * 1024 * 1024,
156
+            'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
157
+            'p' => 1024 * 1024 * 1024 * 1024 * 1024,
158
+        );
159
+
160
+        $bytes = floatval($str);
161
+
162
+        if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
163
+            $bytes *= $bytes_array[$matches[1]];
164
+        } else {
165
+            return false;
166
+        }
167
+
168
+        $bytes = round($bytes);
169
+
170
+        return $bytes;
171
+    }
172
+
173
+    /**
174
+     * Recursive copying of folders
175
+     * @param string $src source folder
176
+     * @param string $dest target folder
177
+     *
178
+     */
179
+    static function copyr($src, $dest) {
180
+        if (is_dir($src)) {
181
+            if (!is_dir($dest)) {
182
+                mkdir($dest);
183
+            }
184
+            $files = scandir($src);
185
+            foreach ($files as $file) {
186
+                if ($file != "." && $file != "..") {
187
+                    self::copyr("$src/$file", "$dest/$file");
188
+                }
189
+            }
190
+        } elseif (file_exists($src) && !\OC\Files\Filesystem::isFileBlacklisted($src)) {
191
+            copy($src, $dest);
192
+        }
193
+    }
194
+
195
+    /**
196
+     * Recursive deletion of folders
197
+     * @param string $dir path to the folder
198
+     * @param bool $deleteSelf if set to false only the content of the folder will be deleted
199
+     * @return bool
200
+     */
201
+    static function rmdirr($dir, $deleteSelf = true) {
202
+        if (is_dir($dir)) {
203
+            $files = new RecursiveIteratorIterator(
204
+                new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
205
+                RecursiveIteratorIterator::CHILD_FIRST
206
+            );
207
+
208
+            foreach ($files as $fileInfo) {
209
+                /** @var SplFileInfo $fileInfo */
210
+                if ($fileInfo->isLink()) {
211
+                    unlink($fileInfo->getPathname());
212
+                } else if ($fileInfo->isDir()) {
213
+                    rmdir($fileInfo->getRealPath());
214
+                } else {
215
+                    unlink($fileInfo->getRealPath());
216
+                }
217
+            }
218
+            if ($deleteSelf) {
219
+                rmdir($dir);
220
+            }
221
+        } elseif (file_exists($dir)) {
222
+            if ($deleteSelf) {
223
+                unlink($dir);
224
+            }
225
+        }
226
+        if (!$deleteSelf) {
227
+            return true;
228
+        }
229
+
230
+        return !file_exists($dir);
231
+    }
232
+
233
+    /**
234
+     * @return \OC\Files\Type\TemplateManager
235
+     */
236
+    static public function getFileTemplateManager() {
237
+        if (!self::$templateManager) {
238
+            self::$templateManager = new \OC\Files\Type\TemplateManager();
239
+        }
240
+        return self::$templateManager;
241
+    }
242
+
243
+    /**
244
+     * detect if a given program is found in the search PATH
245
+     *
246
+     * @param string $name
247
+     * @param bool $path
248
+     * @internal param string $program name
249
+     * @internal param string $optional search path, defaults to $PATH
250
+     * @return bool    true if executable program found in path
251
+     */
252
+    public static function canExecute($name, $path = false) {
253
+        // path defaults to PATH from environment if not set
254
+        if ($path === false) {
255
+            $path = getenv("PATH");
256
+        }
257
+        // check method depends on operating system
258
+        if (!strncmp(PHP_OS, "WIN", 3)) {
259
+            // on Windows an appropriate COM or EXE file needs to exist
260
+            $exts = array(".exe", ".com");
261
+            $check_fn = "file_exists";
262
+        } else {
263
+            // anywhere else we look for an executable file of that name
264
+            $exts = array("");
265
+            $check_fn = "is_executable";
266
+        }
267
+        // Default check will be done with $path directories :
268
+        $dirs = explode(PATH_SEPARATOR, $path);
269
+        // WARNING : We have to check if open_basedir is enabled :
270
+        $obd = OC::$server->getIniWrapper()->getString('open_basedir');
271
+        if ($obd != "none") {
272
+            $obd_values = explode(PATH_SEPARATOR, $obd);
273
+            if (count($obd_values) > 0 and $obd_values[0]) {
274
+                // open_basedir is in effect !
275
+                // We need to check if the program is in one of these dirs :
276
+                $dirs = $obd_values;
277
+            }
278
+        }
279
+        foreach ($dirs as $dir) {
280
+            foreach ($exts as $ext) {
281
+                if ($check_fn("$dir/$name" . $ext))
282
+                    return true;
283
+            }
284
+        }
285
+        return false;
286
+    }
287
+
288
+    /**
289
+     * copy the contents of one stream to another
290
+     *
291
+     * @param resource $source
292
+     * @param resource $target
293
+     * @return array the number of bytes copied and result
294
+     */
295
+    public static function streamCopy($source, $target) {
296
+        if (!$source or !$target) {
297
+            return array(0, false);
298
+        }
299
+        $bufSize = 8192;
300
+        $result = true;
301
+        $count = 0;
302
+        while (!feof($source)) {
303
+            $buf = fread($source, $bufSize);
304
+            $bytesWritten = fwrite($target, $buf);
305
+            if ($bytesWritten !== false) {
306
+                $count += $bytesWritten;
307
+            }
308
+            // note: strlen is expensive so only use it when necessary,
309
+            // on the last block
310
+            if ($bytesWritten === false
311
+                || ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
312
+            ) {
313
+                // write error, could be disk full ?
314
+                $result = false;
315
+                break;
316
+            }
317
+        }
318
+        return array($count, $result);
319
+    }
320
+
321
+    /**
322
+     * Adds a suffix to the name in case the file exists
323
+     *
324
+     * @param string $path
325
+     * @param string $filename
326
+     * @return string
327
+     */
328
+    public static function buildNotExistingFileName($path, $filename) {
329
+        $view = \OC\Files\Filesystem::getView();
330
+        return self::buildNotExistingFileNameForView($path, $filename, $view);
331
+    }
332
+
333
+    /**
334
+     * Adds a suffix to the name in case the file exists
335
+     *
336
+     * @param string $path
337
+     * @param string $filename
338
+     * @return string
339
+     */
340
+    public static function buildNotExistingFileNameForView($path, $filename, \OC\Files\View $view) {
341
+        if ($path === '/') {
342
+            $path = '';
343
+        }
344
+        if ($pos = strrpos($filename, '.')) {
345
+            $name = substr($filename, 0, $pos);
346
+            $ext = substr($filename, $pos);
347
+        } else {
348
+            $name = $filename;
349
+            $ext = '';
350
+        }
351
+
352
+        $newpath = $path . '/' . $filename;
353
+        if ($view->file_exists($newpath)) {
354
+            if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
355
+                //Replace the last "(number)" with "(number+1)"
356
+                $last_match = count($matches[0]) - 1;
357
+                $counter = $matches[1][$last_match][0] + 1;
358
+                $offset = $matches[0][$last_match][1];
359
+                $match_length = strlen($matches[0][$last_match][0]);
360
+            } else {
361
+                $counter = 2;
362
+                $match_length = 0;
363
+                $offset = false;
364
+            }
365
+            do {
366
+                if ($offset) {
367
+                    //Replace the last "(number)" with "(number+1)"
368
+                    $newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length);
369
+                } else {
370
+                    $newname = $name . ' (' . $counter . ')';
371
+                }
372
+                $newpath = $path . '/' . $newname . $ext;
373
+                $counter++;
374
+            } while ($view->file_exists($newpath));
375
+        }
376
+
377
+        return $newpath;
378
+    }
379
+
380
+    /**
381
+     * Checks if $sub is a subdirectory of $parent
382
+     *
383
+     * @param string $sub
384
+     * @param string $parent
385
+     * @return bool
386
+     */
387
+    public static function isSubDirectory($sub, $parent) {
388
+        $realpathSub = realpath($sub);
389
+        $realpathParent = realpath($parent);
390
+
391
+        // realpath() may return false in case the directory does not exist
392
+        // since we can not be sure how different PHP versions may behave here
393
+        // we do an additional check whether realpath returned false
394
+        if($realpathSub === false ||  $realpathParent === false) {
395
+            return false;
396
+        }
397
+
398
+        // Check whether $sub is a subdirectory of $parent
399
+        if (strpos($realpathSub, $realpathParent) === 0) {
400
+            return true;
401
+        }
402
+
403
+        return false;
404
+    }
405
+
406
+    /**
407
+     * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
408
+     *
409
+     * @param array $input The array to work on
410
+     * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
411
+     * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
412
+     * @return array
413
+     *
414
+     * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
415
+     * based on http://www.php.net/manual/en/function.array-change-key-case.php#107715
416
+     *
417
+     */
418
+    public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
419
+        $case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER;
420
+        $ret = array();
421
+        foreach ($input as $k => $v) {
422
+            $ret[mb_convert_case($k, $case, $encoding)] = $v;
423
+        }
424
+        return $ret;
425
+    }
426
+
427
+    /**
428
+     * performs a search in a nested array
429
+     * @param array $haystack the array to be searched
430
+     * @param string $needle the search string
431
+     * @param string $index optional, only search this key name
432
+     * @return mixed the key of the matching field, otherwise false
433
+     *
434
+     * performs a search in a nested array
435
+     *
436
+     * taken from http://www.php.net/manual/en/function.array-search.php#97645
437
+     */
438
+    public static function recursiveArraySearch($haystack, $needle, $index = null) {
439
+        $aIt = new RecursiveArrayIterator($haystack);
440
+        $it = new RecursiveIteratorIterator($aIt);
441
+
442
+        while ($it->valid()) {
443
+            if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
444
+                return $aIt->key();
445
+            }
446
+
447
+            $it->next();
448
+        }
449
+
450
+        return false;
451
+    }
452
+
453
+    /**
454
+     * calculates the maximum upload size respecting system settings, free space and user quota
455
+     *
456
+     * @param string $dir the current folder where the user currently operates
457
+     * @param int $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
458
+     * @return int number of bytes representing
459
+     */
460
+    public static function maxUploadFilesize($dir, $freeSpace = null) {
461
+        if (is_null($freeSpace) || $freeSpace < 0){
462
+            $freeSpace = self::freeSpace($dir);
463
+        }
464
+        return min($freeSpace, self::uploadLimit());
465
+    }
466
+
467
+    /**
468
+     * Calculate free space left within user quota
469
+     *
470
+     * @param string $dir the current folder where the user currently operates
471
+     * @return int number of bytes representing
472
+     */
473
+    public static function freeSpace($dir) {
474
+        $freeSpace = \OC\Files\Filesystem::free_space($dir);
475
+        if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
476
+            $freeSpace = max($freeSpace, 0);
477
+            return $freeSpace;
478
+        } else {
479
+            return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
480
+        }
481
+    }
482
+
483
+    /**
484
+     * Calculate PHP upload limit
485
+     *
486
+     * @return int PHP upload file size limit
487
+     */
488
+    public static function uploadLimit() {
489
+        $ini = \OC::$server->getIniWrapper();
490
+        $upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
491
+        $post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size'));
492
+        if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
493
+            return INF;
494
+        } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
495
+            return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
496
+        } else {
497
+            return min($upload_max_filesize, $post_max_size);
498
+        }
499
+    }
500
+
501
+    /**
502
+     * Checks if a function is available
503
+     *
504
+     * @param string $function_name
505
+     * @return bool
506
+     */
507
+    public static function is_function_enabled($function_name) {
508
+        if (!function_exists($function_name)) {
509
+            return false;
510
+        }
511
+        $ini = \OC::$server->getIniWrapper();
512
+        $disabled = explode(',', $ini->get('disable_functions'));
513
+        $disabled = array_map('trim', $disabled);
514
+        if (in_array($function_name, $disabled)) {
515
+            return false;
516
+        }
517
+        $disabled = explode(',', $ini->get('suhosin.executor.func.blacklist'));
518
+        $disabled = array_map('trim', $disabled);
519
+        if (in_array($function_name, $disabled)) {
520
+            return false;
521
+        }
522
+        return true;
523
+    }
524
+
525
+    /**
526
+     * Try to find a program
527
+     * Note: currently windows is not supported
528
+     *
529
+     * @param string $program
530
+     * @return null|string
531
+     */
532
+    public static function findBinaryPath($program) {
533
+        $memcache = \OC::$server->getMemCacheFactory()->create('findBinaryPath');
534
+        if ($memcache->hasKey($program)) {
535
+            return $memcache->get($program);
536
+        }
537
+        $result = null;
538
+        if (self::is_function_enabled('exec')) {
539
+            $exeSniffer = new ExecutableFinder();
540
+            // Returns null if nothing is found
541
+            $result = $exeSniffer->find($program);
542
+            if (empty($result)) {
543
+                $paths = getenv('PATH');
544
+                if (empty($paths)) {
545
+                    $paths = '/usr/local/bin /usr/bin /opt/bin /bin';
546
+                } else {
547
+                    $paths = str_replace(':',' ',getenv('PATH'));
548
+                }
549
+                $command = 'find ' . $paths . ' -name ' . escapeshellarg($program) . ' 2> /dev/null';
550
+                exec($command, $output, $returnCode);
551
+                if (count($output) > 0) {
552
+                    $result = escapeshellcmd($output[0]);
553
+                }
554
+            }
555
+        }
556
+        // store the value for 5 minutes
557
+        $memcache->set($program, $result, 300);
558
+        return $result;
559
+    }
560
+
561
+    /**
562
+     * Calculate the disc space for the given path
563
+     *
564
+     * @param string $path
565
+     * @param \OCP\Files\FileInfo $rootInfo (optional)
566
+     * @return array
567
+     * @throws \OCP\Files\NotFoundException
568
+     */
569
+    public static function getStorageInfo($path, $rootInfo = null) {
570
+        // return storage info without adding mount points
571
+        $includeExtStorage = \OC::$server->getSystemConfig()->getValue('quota_include_external_storage', false);
572
+
573
+        if (!$rootInfo) {
574
+            $rootInfo = \OC\Files\Filesystem::getFileInfo($path, false);
575
+        }
576
+        if (!$rootInfo instanceof \OCP\Files\FileInfo) {
577
+            throw new \OCP\Files\NotFoundException();
578
+        }
579
+        $used = $rootInfo->getSize();
580
+        if ($used < 0) {
581
+            $used = 0;
582
+        }
583
+        $quota = \OCP\Files\FileInfo::SPACE_UNLIMITED;
584
+        $storage = $rootInfo->getStorage();
585
+        $sourceStorage = $storage;
586
+        if ($storage->instanceOfStorage('\OC\Files\Storage\Shared')) {
587
+            $includeExtStorage = false;
588
+            $sourceStorage = $storage->getSourceStorage();
589
+        }
590
+        if ($includeExtStorage) {
591
+            $quota = OC_Util::getUserQuota(\OCP\User::getUser());
592
+            if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
593
+                // always get free space / total space from root + mount points
594
+                return self::getGlobalStorageInfo();
595
+            }
596
+        }
597
+
598
+        // TODO: need a better way to get total space from storage
599
+        if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota')) {
600
+            /** @var \OC\Files\Storage\Wrapper\Quota $storage */
601
+            $quota = $sourceStorage->getQuota();
602
+        }
603
+        $free = $sourceStorage->free_space('');
604
+        if ($free >= 0) {
605
+            $total = $free + $used;
606
+        } else {
607
+            $total = $free; //either unknown or unlimited
608
+        }
609
+        if ($total > 0) {
610
+            if ($quota > 0 && $total > $quota) {
611
+                $total = $quota;
612
+            }
613
+            // prevent division by zero or error codes (negative values)
614
+            $relative = round(($used / $total) * 10000) / 100;
615
+        } else {
616
+            $relative = 0;
617
+        }
618
+
619
+        $ownerId = $storage->getOwner($path);
620
+        $ownerDisplayName = '';
621
+        $owner = \OC::$server->getUserManager()->get($ownerId);
622
+        if($owner) {
623
+            $ownerDisplayName = $owner->getDisplayName();
624
+        }
625
+
626
+        return [
627
+            'free' => $free,
628
+            'used' => $used,
629
+            'quota' => $quota,
630
+            'total' => $total,
631
+            'relative' => $relative,
632
+            'owner' => $ownerId,
633
+            'ownerDisplayName' => $ownerDisplayName,
634
+        ];
635
+    }
636
+
637
+    /**
638
+     * Get storage info including all mount points and quota
639
+     *
640
+     * @return array
641
+     */
642
+    private static function getGlobalStorageInfo() {
643
+        $quota = OC_Util::getUserQuota(\OCP\User::getUser());
644
+
645
+        $rootInfo = \OC\Files\Filesystem::getFileInfo('', 'ext');
646
+        $used = $rootInfo['size'];
647
+        if ($used < 0) {
648
+            $used = 0;
649
+        }
650
+
651
+        $total = $quota;
652
+        $free = $quota - $used;
653
+
654
+        if ($total > 0) {
655
+            if ($quota > 0 && $total > $quota) {
656
+                $total = $quota;
657
+            }
658
+            // prevent division by zero or error codes (negative values)
659
+            $relative = round(($used / $total) * 10000) / 100;
660
+        } else {
661
+            $relative = 0;
662
+        }
663
+
664
+        return array('free' => $free, 'used' => $used, 'total' => $total, 'relative' => $relative);
665
+
666
+    }
667
+
668
+    /**
669
+     * Returns whether the config file is set manually to read-only
670
+     * @return bool
671
+     */
672
+    public static function isReadOnlyConfigEnabled() {
673
+        return \OC::$server->getConfig()->getSystemValue('config_is_read_only', false);
674
+    }
675 675
 }
Please login to merge, or discard this patch.
Spacing   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -64,7 +64,7 @@  discard block
 block discarded – undo
64 64
 		} else {
65 65
 			$url = OC::$server->getURLGenerator()->getAbsoluteURL(OC::$server->getURLGenerator()->linkTo('', 'public.php').'?service='.$service);
66 66
 		}
67
-		return $url . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : '');
67
+		return $url.(($add_slash && $service[strlen($service) - 1] != '/') ? '/' : '');
68 68
 	}
69 69
 
70 70
 	/**
@@ -114,18 +114,18 @@  discard block
 block discarded – undo
114 114
 			return "?";
115 115
 		}
116 116
 		if ($bytes < 1024) {
117
-			return $bytes . "B";
117
+			return $bytes."B";
118 118
 		}
119 119
 		$bytes = round($bytes / 1024, 1);
120 120
 		if ($bytes < 1024) {
121
-			return $bytes . "K";
121
+			return $bytes."K";
122 122
 		}
123 123
 		$bytes = round($bytes / 1024, 1);
124 124
 		if ($bytes < 1024) {
125
-			return $bytes . "M";
125
+			return $bytes."M";
126 126
 		}
127 127
 		$bytes = round($bytes / 1024, 1);
128
-		return $bytes . "G";
128
+		return $bytes."G";
129 129
 	}
130 130
 
131 131
 	/**
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
 		}
279 279
 		foreach ($dirs as $dir) {
280 280
 			foreach ($exts as $ext) {
281
-				if ($check_fn("$dir/$name" . $ext))
281
+				if ($check_fn("$dir/$name".$ext))
282 282
 					return true;
283 283
 			}
284 284
 		}
@@ -349,7 +349,7 @@  discard block
 block discarded – undo
349 349
 			$ext = '';
350 350
 		}
351 351
 
352
-		$newpath = $path . '/' . $filename;
352
+		$newpath = $path.'/'.$filename;
353 353
 		if ($view->file_exists($newpath)) {
354 354
 			if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
355 355
 				//Replace the last "(number)" with "(number+1)"
@@ -365,11 +365,11 @@  discard block
 block discarded – undo
365 365
 			do {
366 366
 				if ($offset) {
367 367
 					//Replace the last "(number)" with "(number+1)"
368
-					$newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length);
368
+					$newname = substr_replace($name, '('.$counter.')', $offset, $match_length);
369 369
 				} else {
370
-					$newname = $name . ' (' . $counter . ')';
370
+					$newname = $name.' ('.$counter.')';
371 371
 				}
372
-				$newpath = $path . '/' . $newname . $ext;
372
+				$newpath = $path.'/'.$newname.$ext;
373 373
 				$counter++;
374 374
 			} while ($view->file_exists($newpath));
375 375
 		}
@@ -391,7 +391,7 @@  discard block
 block discarded – undo
391 391
 		// realpath() may return false in case the directory does not exist
392 392
 		// since we can not be sure how different PHP versions may behave here
393 393
 		// we do an additional check whether realpath returned false
394
-		if($realpathSub === false ||  $realpathParent === false) {
394
+		if ($realpathSub === false || $realpathParent === false) {
395 395
 			return false;
396 396
 		}
397 397
 
@@ -458,7 +458,7 @@  discard block
 block discarded – undo
458 458
 	 * @return int number of bytes representing
459 459
 	 */
460 460
 	public static function maxUploadFilesize($dir, $freeSpace = null) {
461
-		if (is_null($freeSpace) || $freeSpace < 0){
461
+		if (is_null($freeSpace) || $freeSpace < 0) {
462 462
 			$freeSpace = self::freeSpace($dir);
463 463
 		}
464 464
 		return min($freeSpace, self::uploadLimit());
@@ -476,7 +476,7 @@  discard block
 block discarded – undo
476 476
 			$freeSpace = max($freeSpace, 0);
477 477
 			return $freeSpace;
478 478
 		} else {
479
-			return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
479
+			return (INF > 0) ? INF : PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
480 480
 		}
481 481
 	}
482 482
 
@@ -489,9 +489,9 @@  discard block
 block discarded – undo
489 489
 		$ini = \OC::$server->getIniWrapper();
490 490
 		$upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
491 491
 		$post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size'));
492
-		if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
492
+		if ((int) $upload_max_filesize === 0 and (int) $post_max_size === 0) {
493 493
 			return INF;
494
-		} elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
494
+		} elseif ((int) $upload_max_filesize === 0 or (int) $post_max_size === 0) {
495 495
 			return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
496 496
 		} else {
497 497
 			return min($upload_max_filesize, $post_max_size);
@@ -544,9 +544,9 @@  discard block
 block discarded – undo
544 544
 				if (empty($paths)) {
545 545
 					$paths = '/usr/local/bin /usr/bin /opt/bin /bin';
546 546
 				} else {
547
-					$paths = str_replace(':',' ',getenv('PATH'));
547
+					$paths = str_replace(':', ' ', getenv('PATH'));
548 548
 				}
549
-				$command = 'find ' . $paths . ' -name ' . escapeshellarg($program) . ' 2> /dev/null';
549
+				$command = 'find '.$paths.' -name '.escapeshellarg($program).' 2> /dev/null';
550 550
 				exec($command, $output, $returnCode);
551 551
 				if (count($output) > 0) {
552 552
 					$result = escapeshellcmd($output[0]);
@@ -619,7 +619,7 @@  discard block
 block discarded – undo
619 619
 		$ownerId = $storage->getOwner($path);
620 620
 		$ownerDisplayName = '';
621 621
 		$owner = \OC::$server->getUserManager()->get($ownerId);
622
-		if($owner) {
622
+		if ($owner) {
623 623
 			$ownerDisplayName = $owner->getDisplayName();
624 624
 		}
625 625
 
Please login to merge, or discard this patch.
lib/private/legacy/l10n.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -323,7 +323,7 @@
 block discarded – undo
323 323
 	/**
324 324
 	 * find all available languages for an app
325 325
 	 * @param string $app App that needs to be translated
326
-	 * @return array an array of available languages
326
+	 * @return string[] an array of available languages
327 327
 	 * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->findAvailableLanguages() instead
328 328
 	 */
329 329
 	public static function findAvailableLanguages($app=null) {
Please login to merge, or discard this patch.
Indentation   +305 added lines, -305 removed lines patch added patch discarded remove patch
@@ -35,309 +35,309 @@
 block discarded – undo
35 35
  * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->get() instead
36 36
  */
37 37
 class OC_L10N implements \OCP\IL10N {
38
-	/**
39
-	 * cache
40
-	 */
41
-	protected static $cache = array();
42
-	protected static $availableLanguages = array();
43
-
44
-	/**
45
-	 * The best language
46
-	 */
47
-	protected static $language = '';
48
-
49
-	/**
50
-	 * App of this object
51
-	 */
52
-	protected $app;
53
-
54
-	/**
55
-	 * Language of this object
56
-	 */
57
-	protected $lang;
58
-
59
-	/**
60
-	 * Translations
61
-	 */
62
-	private $translations = array();
63
-
64
-	/**
65
-	 * Plural forms (string)
66
-	 */
67
-	private $pluralFormString = 'nplurals=2; plural=(n != 1);';
68
-
69
-	/**
70
-	 * Plural forms (function)
71
-	 */
72
-	private $pluralFormFunction = null;
73
-
74
-	/**
75
-	 * The constructor
76
-	 * @param string $app app requesting l10n
77
-	 * @param string $lang default: null Language
78
-	 *
79
-	 * If language is not set, the constructor tries to find the right
80
-	 * language.
81
-	 * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->get() instead
82
-	 */
83
-	public function __construct($app, $lang = null) {
84
-		$app = \OC_App::cleanAppId($app);
85
-		$this->app = $app;
86
-
87
-		if ($lang !== null) {
88
-			$lang = str_replace(array('\0', '/', '\\', '..'), '', $lang);
89
-		}
90
-
91
-		// Find the right language
92
-		if ($app !== 'test' && !\OC::$server->getL10NFactory()->languageExists($app, $lang)) {
93
-			$lang = \OC::$server->getL10NFactory()->findLanguage($app);
94
-		}
95
-
96
-		$this->lang = $lang;
97
-	}
98
-
99
-	/**
100
-	 * @param $transFile
101
-	 * @return bool
102
-	 */
103
-	public function load($transFile) {
104
-		$this->app = true;
105
-
106
-		$json = json_decode(file_get_contents($transFile), true);
107
-		if (!is_array($json)) {
108
-			$jsonError = json_last_error();
109
-			\OC::$server->getLogger()->warning("Failed to load $transFile - json error code: $jsonError", ['app' => 'l10n']);
110
-			return false;
111
-		}
112
-
113
-		$this->pluralFormString = $json['pluralForm'];
114
-		$translations = $json['translations'];
115
-
116
-		$this->translations = array_merge($this->translations, $translations);
117
-
118
-		return true;
119
-	}
120
-
121
-	protected function init() {
122
-		if ($this->app === true) {
123
-			return;
124
-		}
125
-		$app = $this->app;
126
-		$lang = $this->lang;
127
-		$this->app = true;
128
-
129
-		/** @var \OC\L10N\Factory $factory */
130
-		$factory = \OC::$server->getL10NFactory();
131
-		$languageFiles = $factory->getL10nFilesForApp($app, $lang);
132
-
133
-		$this->translations = [];
134
-		foreach ($languageFiles as $languageFile) {
135
-			$this->load($languageFile);
136
-		}
137
-	}
138
-
139
-	/**
140
-	 * Translating
141
-	 * @param string $text The text we need a translation for
142
-	 * @param array $parameters default:array() Parameters for sprintf
143
-	 * @return \OC_L10N_String Translation or the same text
144
-	 *
145
-	 * Returns the translation. If no translation is found, $text will be
146
-	 * returned.
147
-	 */
148
-	public function t($text, $parameters = array()) {
149
-		return new OC_L10N_String($this, $text, $parameters);
150
-	}
151
-
152
-	/**
153
-	 * Translating
154
-	 * @param string $text_singular the string to translate for exactly one object
155
-	 * @param string $text_plural the string to translate for n objects
156
-	 * @param integer $count Number of objects
157
-	 * @param array $parameters default:array() Parameters for sprintf
158
-	 * @return \OC_L10N_String Translation or the same text
159
-	 *
160
-	 * Returns the translation. If no translation is found, $text will be
161
-	 * returned. %n will be replaced with the number of objects.
162
-	 *
163
-	 * The correct plural is determined by the plural_forms-function
164
-	 * provided by the po file.
165
-	 *
166
-	 */
167
-	public function n($text_singular, $text_plural, $count, $parameters = array()) {
168
-		$this->init();
169
-		$identifier = "_${text_singular}_::_${text_plural}_";
170
-		if( array_key_exists($identifier, $this->translations)) {
171
-			return new OC_L10N_String( $this, $identifier, $parameters, $count );
172
-		}else{
173
-			if($count === 1) {
174
-				return new OC_L10N_String($this, $text_singular, $parameters, $count);
175
-			}else{
176
-				return new OC_L10N_String($this, $text_plural, $parameters, $count);
177
-			}
178
-		}
179
-	}
180
-
181
-	/**
182
-	 * getTranslations
183
-	 * @return array Fetch all translations
184
-	 *
185
-	 * Returns an associative array with all translations
186
-	 */
187
-	public function getTranslations() {
188
-		$this->init();
189
-		return $this->translations;
190
-	}
191
-
192
-	/**
193
-	 * getPluralFormFunction
194
-	 * @return string the plural form function
195
-	 *
196
-	 * returned function accepts the argument $n
197
-	 */
198
-	public function getPluralFormFunction() {
199
-		$this->init();
200
-		if (is_null($this->pluralFormFunction)) {
201
-			$this->pluralFormFunction = \OC::$server->getL10NFactory()->createPluralFunction($this->pluralFormString);
202
-		}
203
-		return $this->pluralFormFunction;
204
-	}
205
-
206
-	/**
207
-	 * Localization
208
-	 * @param string $type Type of localization
209
-	 * @param array|int|string $data parameters for this localization
210
-	 * @param array $options
211
-	 * @return string|false
212
-	 *
213
-	 * Returns the localized data.
214
-	 *
215
-	 * Implemented types:
216
-	 *  - date
217
-	 *    - Creates a date
218
-	 *    - params: timestamp (int/string)
219
-	 *  - datetime
220
-	 *    - Creates date and time
221
-	 *    - params: timestamp (int/string)
222
-	 *  - time
223
-	 *    - Creates a time
224
-	 *    - params: timestamp (int/string)
225
-	 *  - firstday: Returns the first day of the week (0 sunday - 6 saturday)
226
-	 *  - jsdate: Returns the short JS date format
227
-	 */
228
-	public function l($type, $data, $options = array()) {
229
-		if ($type === 'firstday') {
230
-			return $this->getFirstWeekDay();
231
-		}
232
-		if ($type === 'jsdate') {
233
-			return $this->getDateFormat();
234
-		}
235
-
236
-		$this->init();
237
-		$value = new DateTime();
238
-		if($data instanceof DateTime) {
239
-			$value = $data;
240
-		} elseif(is_string($data) && !is_numeric($data)) {
241
-			$data = strtotime($data);
242
-			$value->setTimestamp($data);
243
-		} else {
244
-			$value->setTimestamp($data);
245
-		}
246
-
247
-		// Use the language of the instance
248
-		$locale = $this->transformToCLDRLocale($this->getLanguageCode());
249
-
250
-		$options = array_merge(array('width' => 'long'), $options);
251
-		$width = $options['width'];
252
-		switch($type) {
253
-			case 'date':
254
-				return Punic\Calendar::formatDate($value, $width, $locale);
255
-			case 'datetime':
256
-				return Punic\Calendar::formatDatetime($value, $width, $locale);
257
-			case 'time':
258
-				return Punic\Calendar::formatTime($value, $width, $locale);
259
-			default:
260
-				return false;
261
-		}
262
-	}
263
-
264
-	/**
265
-	 * The code (en, de, ...) of the language that is used for this OC_L10N object
266
-	 *
267
-	 * @return string language
268
-	 */
269
-	public function getLanguageCode() {
270
-		return $this->lang;
271
-	}
272
-
273
-	/**
274
-	 * @return string
275
-	 * @throws \Punic\Exception\ValueNotInList
276
-	 * @deprecated 9.0.0 Use $this->l('jsdate', null) instead
277
-	 */
278
-	public function getDateFormat() {
279
-		$locale = $this->transformToCLDRLocale($this->getLanguageCode());
280
-		return Punic\Calendar::getDateFormat('short', $locale);
281
-	}
282
-
283
-	/**
284
-	 * @return int
285
-	 * @deprecated 9.0.0 Use $this->l('firstday', null) instead
286
-	 */
287
-	public function getFirstWeekDay() {
288
-		$locale = $this->transformToCLDRLocale($this->getLanguageCode());
289
-		return Punic\Calendar::getFirstWeekday($locale);
290
-	}
291
-
292
-	/**
293
-	 * @param string $locale
294
-	 * @return string
295
-	 */
296
-	private function transformToCLDRLocale($locale) {
297
-		if ($locale === 'sr@latin') {
298
-			return 'sr_latn';
299
-		}
300
-
301
-		return $locale;
302
-	}
303
-
304
-	/**
305
-	 * find the best language
306
-	 * @param string $app
307
-	 * @return string language
308
-	 *
309
-	 * If nothing works it returns 'en'
310
-	 * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->findLanguage() instead
311
-	 */
312
-	public static function findLanguage($app = null) {
313
-		return \OC::$server->getL10NFactory()->findLanguage($app);
314
-	}
315
-
316
-	/**
317
-	 * @return string
318
-	 * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->setLanguageFromRequest() instead
319
-	 */
320
-	public static function setLanguageFromRequest() {
321
-		return \OC::$server->getL10NFactory()->setLanguageFromRequest();
322
-	}
323
-
324
-	/**
325
-	 * find all available languages for an app
326
-	 * @param string $app App that needs to be translated
327
-	 * @return array an array of available languages
328
-	 * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->findAvailableLanguages() instead
329
-	 */
330
-	public static function findAvailableLanguages($app=null) {
331
-		return \OC::$server->getL10NFactory()->findAvailableLanguages($app);
332
-	}
333
-
334
-	/**
335
-	 * @param string $app
336
-	 * @param string $lang
337
-	 * @return bool
338
-	 * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->languageExists() instead
339
-	 */
340
-	public static function languageExists($app, $lang) {
341
-		return \OC::$server->getL10NFactory()->languageExists($app, $lang);
342
-	}
38
+    /**
39
+     * cache
40
+     */
41
+    protected static $cache = array();
42
+    protected static $availableLanguages = array();
43
+
44
+    /**
45
+     * The best language
46
+     */
47
+    protected static $language = '';
48
+
49
+    /**
50
+     * App of this object
51
+     */
52
+    protected $app;
53
+
54
+    /**
55
+     * Language of this object
56
+     */
57
+    protected $lang;
58
+
59
+    /**
60
+     * Translations
61
+     */
62
+    private $translations = array();
63
+
64
+    /**
65
+     * Plural forms (string)
66
+     */
67
+    private $pluralFormString = 'nplurals=2; plural=(n != 1);';
68
+
69
+    /**
70
+     * Plural forms (function)
71
+     */
72
+    private $pluralFormFunction = null;
73
+
74
+    /**
75
+     * The constructor
76
+     * @param string $app app requesting l10n
77
+     * @param string $lang default: null Language
78
+     *
79
+     * If language is not set, the constructor tries to find the right
80
+     * language.
81
+     * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->get() instead
82
+     */
83
+    public function __construct($app, $lang = null) {
84
+        $app = \OC_App::cleanAppId($app);
85
+        $this->app = $app;
86
+
87
+        if ($lang !== null) {
88
+            $lang = str_replace(array('\0', '/', '\\', '..'), '', $lang);
89
+        }
90
+
91
+        // Find the right language
92
+        if ($app !== 'test' && !\OC::$server->getL10NFactory()->languageExists($app, $lang)) {
93
+            $lang = \OC::$server->getL10NFactory()->findLanguage($app);
94
+        }
95
+
96
+        $this->lang = $lang;
97
+    }
98
+
99
+    /**
100
+     * @param $transFile
101
+     * @return bool
102
+     */
103
+    public function load($transFile) {
104
+        $this->app = true;
105
+
106
+        $json = json_decode(file_get_contents($transFile), true);
107
+        if (!is_array($json)) {
108
+            $jsonError = json_last_error();
109
+            \OC::$server->getLogger()->warning("Failed to load $transFile - json error code: $jsonError", ['app' => 'l10n']);
110
+            return false;
111
+        }
112
+
113
+        $this->pluralFormString = $json['pluralForm'];
114
+        $translations = $json['translations'];
115
+
116
+        $this->translations = array_merge($this->translations, $translations);
117
+
118
+        return true;
119
+    }
120
+
121
+    protected function init() {
122
+        if ($this->app === true) {
123
+            return;
124
+        }
125
+        $app = $this->app;
126
+        $lang = $this->lang;
127
+        $this->app = true;
128
+
129
+        /** @var \OC\L10N\Factory $factory */
130
+        $factory = \OC::$server->getL10NFactory();
131
+        $languageFiles = $factory->getL10nFilesForApp($app, $lang);
132
+
133
+        $this->translations = [];
134
+        foreach ($languageFiles as $languageFile) {
135
+            $this->load($languageFile);
136
+        }
137
+    }
138
+
139
+    /**
140
+     * Translating
141
+     * @param string $text The text we need a translation for
142
+     * @param array $parameters default:array() Parameters for sprintf
143
+     * @return \OC_L10N_String Translation or the same text
144
+     *
145
+     * Returns the translation. If no translation is found, $text will be
146
+     * returned.
147
+     */
148
+    public function t($text, $parameters = array()) {
149
+        return new OC_L10N_String($this, $text, $parameters);
150
+    }
151
+
152
+    /**
153
+     * Translating
154
+     * @param string $text_singular the string to translate for exactly one object
155
+     * @param string $text_plural the string to translate for n objects
156
+     * @param integer $count Number of objects
157
+     * @param array $parameters default:array() Parameters for sprintf
158
+     * @return \OC_L10N_String Translation or the same text
159
+     *
160
+     * Returns the translation. If no translation is found, $text will be
161
+     * returned. %n will be replaced with the number of objects.
162
+     *
163
+     * The correct plural is determined by the plural_forms-function
164
+     * provided by the po file.
165
+     *
166
+     */
167
+    public function n($text_singular, $text_plural, $count, $parameters = array()) {
168
+        $this->init();
169
+        $identifier = "_${text_singular}_::_${text_plural}_";
170
+        if( array_key_exists($identifier, $this->translations)) {
171
+            return new OC_L10N_String( $this, $identifier, $parameters, $count );
172
+        }else{
173
+            if($count === 1) {
174
+                return new OC_L10N_String($this, $text_singular, $parameters, $count);
175
+            }else{
176
+                return new OC_L10N_String($this, $text_plural, $parameters, $count);
177
+            }
178
+        }
179
+    }
180
+
181
+    /**
182
+     * getTranslations
183
+     * @return array Fetch all translations
184
+     *
185
+     * Returns an associative array with all translations
186
+     */
187
+    public function getTranslations() {
188
+        $this->init();
189
+        return $this->translations;
190
+    }
191
+
192
+    /**
193
+     * getPluralFormFunction
194
+     * @return string the plural form function
195
+     *
196
+     * returned function accepts the argument $n
197
+     */
198
+    public function getPluralFormFunction() {
199
+        $this->init();
200
+        if (is_null($this->pluralFormFunction)) {
201
+            $this->pluralFormFunction = \OC::$server->getL10NFactory()->createPluralFunction($this->pluralFormString);
202
+        }
203
+        return $this->pluralFormFunction;
204
+    }
205
+
206
+    /**
207
+     * Localization
208
+     * @param string $type Type of localization
209
+     * @param array|int|string $data parameters for this localization
210
+     * @param array $options
211
+     * @return string|false
212
+     *
213
+     * Returns the localized data.
214
+     *
215
+     * Implemented types:
216
+     *  - date
217
+     *    - Creates a date
218
+     *    - params: timestamp (int/string)
219
+     *  - datetime
220
+     *    - Creates date and time
221
+     *    - params: timestamp (int/string)
222
+     *  - time
223
+     *    - Creates a time
224
+     *    - params: timestamp (int/string)
225
+     *  - firstday: Returns the first day of the week (0 sunday - 6 saturday)
226
+     *  - jsdate: Returns the short JS date format
227
+     */
228
+    public function l($type, $data, $options = array()) {
229
+        if ($type === 'firstday') {
230
+            return $this->getFirstWeekDay();
231
+        }
232
+        if ($type === 'jsdate') {
233
+            return $this->getDateFormat();
234
+        }
235
+
236
+        $this->init();
237
+        $value = new DateTime();
238
+        if($data instanceof DateTime) {
239
+            $value = $data;
240
+        } elseif(is_string($data) && !is_numeric($data)) {
241
+            $data = strtotime($data);
242
+            $value->setTimestamp($data);
243
+        } else {
244
+            $value->setTimestamp($data);
245
+        }
246
+
247
+        // Use the language of the instance
248
+        $locale = $this->transformToCLDRLocale($this->getLanguageCode());
249
+
250
+        $options = array_merge(array('width' => 'long'), $options);
251
+        $width = $options['width'];
252
+        switch($type) {
253
+            case 'date':
254
+                return Punic\Calendar::formatDate($value, $width, $locale);
255
+            case 'datetime':
256
+                return Punic\Calendar::formatDatetime($value, $width, $locale);
257
+            case 'time':
258
+                return Punic\Calendar::formatTime($value, $width, $locale);
259
+            default:
260
+                return false;
261
+        }
262
+    }
263
+
264
+    /**
265
+     * The code (en, de, ...) of the language that is used for this OC_L10N object
266
+     *
267
+     * @return string language
268
+     */
269
+    public function getLanguageCode() {
270
+        return $this->lang;
271
+    }
272
+
273
+    /**
274
+     * @return string
275
+     * @throws \Punic\Exception\ValueNotInList
276
+     * @deprecated 9.0.0 Use $this->l('jsdate', null) instead
277
+     */
278
+    public function getDateFormat() {
279
+        $locale = $this->transformToCLDRLocale($this->getLanguageCode());
280
+        return Punic\Calendar::getDateFormat('short', $locale);
281
+    }
282
+
283
+    /**
284
+     * @return int
285
+     * @deprecated 9.0.0 Use $this->l('firstday', null) instead
286
+     */
287
+    public function getFirstWeekDay() {
288
+        $locale = $this->transformToCLDRLocale($this->getLanguageCode());
289
+        return Punic\Calendar::getFirstWeekday($locale);
290
+    }
291
+
292
+    /**
293
+     * @param string $locale
294
+     * @return string
295
+     */
296
+    private function transformToCLDRLocale($locale) {
297
+        if ($locale === 'sr@latin') {
298
+            return 'sr_latn';
299
+        }
300
+
301
+        return $locale;
302
+    }
303
+
304
+    /**
305
+     * find the best language
306
+     * @param string $app
307
+     * @return string language
308
+     *
309
+     * If nothing works it returns 'en'
310
+     * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->findLanguage() instead
311
+     */
312
+    public static function findLanguage($app = null) {
313
+        return \OC::$server->getL10NFactory()->findLanguage($app);
314
+    }
315
+
316
+    /**
317
+     * @return string
318
+     * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->setLanguageFromRequest() instead
319
+     */
320
+    public static function setLanguageFromRequest() {
321
+        return \OC::$server->getL10NFactory()->setLanguageFromRequest();
322
+    }
323
+
324
+    /**
325
+     * find all available languages for an app
326
+     * @param string $app App that needs to be translated
327
+     * @return array an array of available languages
328
+     * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->findAvailableLanguages() instead
329
+     */
330
+    public static function findAvailableLanguages($app=null) {
331
+        return \OC::$server->getL10NFactory()->findAvailableLanguages($app);
332
+    }
333
+
334
+    /**
335
+     * @param string $app
336
+     * @param string $lang
337
+     * @return bool
338
+     * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->languageExists() instead
339
+     */
340
+    public static function languageExists($app, $lang) {
341
+        return \OC::$server->getL10NFactory()->languageExists($app, $lang);
342
+    }
343 343
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -167,12 +167,12 @@  discard block
 block discarded – undo
167 167
 	public function n($text_singular, $text_plural, $count, $parameters = array()) {
168 168
 		$this->init();
169 169
 		$identifier = "_${text_singular}_::_${text_plural}_";
170
-		if( array_key_exists($identifier, $this->translations)) {
171
-			return new OC_L10N_String( $this, $identifier, $parameters, $count );
172
-		}else{
173
-			if($count === 1) {
170
+		if (array_key_exists($identifier, $this->translations)) {
171
+			return new OC_L10N_String($this, $identifier, $parameters, $count);
172
+		} else {
173
+			if ($count === 1) {
174 174
 				return new OC_L10N_String($this, $text_singular, $parameters, $count);
175
-			}else{
175
+			} else {
176 176
 				return new OC_L10N_String($this, $text_plural, $parameters, $count);
177 177
 			}
178 178
 		}
@@ -235,9 +235,9 @@  discard block
 block discarded – undo
235 235
 
236 236
 		$this->init();
237 237
 		$value = new DateTime();
238
-		if($data instanceof DateTime) {
238
+		if ($data instanceof DateTime) {
239 239
 			$value = $data;
240
-		} elseif(is_string($data) && !is_numeric($data)) {
240
+		} elseif (is_string($data) && !is_numeric($data)) {
241 241
 			$data = strtotime($data);
242 242
 			$value->setTimestamp($data);
243 243
 		} else {
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
 
250 250
 		$options = array_merge(array('width' => 'long'), $options);
251 251
 		$width = $options['width'];
252
-		switch($type) {
252
+		switch ($type) {
253 253
 			case 'date':
254 254
 				return Punic\Calendar::formatDate($value, $width, $locale);
255 255
 			case 'datetime':
@@ -327,7 +327,7 @@  discard block
 block discarded – undo
327 327
 	 * @return array an array of available languages
328 328
 	 * @deprecated 9.0.0 Use \OC::$server->getL10NFactory()->findAvailableLanguages() instead
329 329
 	 */
330
-	public static function findAvailableLanguages($app=null) {
330
+	public static function findAvailableLanguages($app = null) {
331 331
 		return \OC::$server->getL10NFactory()->findAvailableLanguages($app);
332 332
 	}
333 333
 
Please login to merge, or discard this patch.
Braces   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -169,10 +169,10 @@
 block discarded – undo
169 169
 		$identifier = "_${text_singular}_::_${text_plural}_";
170 170
 		if( array_key_exists($identifier, $this->translations)) {
171 171
 			return new OC_L10N_String( $this, $identifier, $parameters, $count );
172
-		}else{
172
+		} else{
173 173
 			if($count === 1) {
174 174
 				return new OC_L10N_String($this, $text_singular, $parameters, $count);
175
-			}else{
175
+			} else{
176 176
 				return new OC_L10N_String($this, $text_plural, $parameters, $count);
177 177
 			}
178 178
 		}
Please login to merge, or discard this patch.
lib/private/legacy/template/functions.php 3 patches
Doc Comments   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -182,7 +182,7 @@  discard block
 block discarded – undo
182 182
  * make preview_icon available as a simple function
183 183
  * Returns the path to the preview of the image.
184 184
  * @param string $path path of file
185
- * @return link to the preview
185
+ * @return string to the preview
186 186
  */
187 187
 function preview_icon( $path ) {
188 188
 	return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_preview', ['x' => 32, 'y' => 32, 'file' => $path]);
@@ -190,6 +190,7 @@  discard block
 block discarded – undo
190 190
 
191 191
 /**
192 192
  * @param string $path
193
+ * @param string $token
193 194
  */
194 195
 function publicPreview_icon ( $path, $token ) {
195 196
 	return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_public_preview', ['x' => 32, 'y' => 32, 'file' => $path, 't' => $token]);
Please login to merge, or discard this patch.
Indentation   +81 added lines, -81 removed lines patch added patch discarded remove patch
@@ -34,7 +34,7 @@  discard block
 block discarded – undo
34 34
  * @param string $string the string which will be escaped and printed
35 35
  */
36 36
 function p($string) {
37
-	print(\OCP\Util::sanitizeHTML($string));
37
+    print(\OCP\Util::sanitizeHTML($string));
38 38
 }
39 39
 
40 40
 /**
@@ -43,7 +43,7 @@  discard block
 block discarded – undo
43 43
  * @param string|array $string the string which will be printed as it is
44 44
  */
45 45
 function print_unescaped($string) {
46
-	print($string);
46
+    print($string);
47 47
 }
48 48
 
49 49
 /**
@@ -53,13 +53,13 @@  discard block
 block discarded – undo
53 53
  * if an array is given it will add all scripts
54 54
  */
55 55
 function script($app, $file = null) {
56
-	if(is_array($file)) {
57
-		foreach($file as $f) {
58
-			OC_Util::addScript($app, $f);
59
-		}
60
-	} else {
61
-		OC_Util::addScript($app, $file);
62
-	}
56
+    if(is_array($file)) {
57
+        foreach($file as $f) {
58
+            OC_Util::addScript($app, $f);
59
+        }
60
+    } else {
61
+        OC_Util::addScript($app, $file);
62
+    }
63 63
 }
64 64
 
65 65
 /**
@@ -69,13 +69,13 @@  discard block
 block discarded – undo
69 69
  * if an array is given it will add all scripts
70 70
  */
71 71
 function vendor_script($app, $file = null) {
72
-	if(is_array($file)) {
73
-		foreach($file as $f) {
74
-			OC_Util::addVendorScript($app, $f);
75
-		}
76
-	} else {
77
-		OC_Util::addVendorScript($app, $file);
78
-	}
72
+    if(is_array($file)) {
73
+        foreach($file as $f) {
74
+            OC_Util::addVendorScript($app, $f);
75
+        }
76
+    } else {
77
+        OC_Util::addVendorScript($app, $file);
78
+    }
79 79
 }
80 80
 
81 81
 /**
@@ -85,13 +85,13 @@  discard block
 block discarded – undo
85 85
  * if an array is given it will add all styles
86 86
  */
87 87
 function style($app, $file = null) {
88
-	if(is_array($file)) {
89
-		foreach($file as $f) {
90
-			OC_Util::addStyle($app, $f);
91
-		}
92
-	} else {
93
-		OC_Util::addStyle($app, $file);
94
-	}
88
+    if(is_array($file)) {
89
+        foreach($file as $f) {
90
+            OC_Util::addStyle($app, $f);
91
+        }
92
+    } else {
93
+        OC_Util::addStyle($app, $file);
94
+    }
95 95
 }
96 96
 
97 97
 /**
@@ -101,13 +101,13 @@  discard block
 block discarded – undo
101 101
  * if an array is given it will add all styles
102 102
  */
103 103
 function vendor_style($app, $file = null) {
104
-	if(is_array($file)) {
105
-		foreach($file as $f) {
106
-			OC_Util::addVendorStyle($app, $f);
107
-		}
108
-	} else {
109
-		OC_Util::addVendorStyle($app, $file);
110
-	}
104
+    if(is_array($file)) {
105
+        foreach($file as $f) {
106
+            OC_Util::addVendorStyle($app, $f);
107
+        }
108
+    } else {
109
+        OC_Util::addVendorStyle($app, $file);
110
+    }
111 111
 }
112 112
 
113 113
 /**
@@ -116,7 +116,7 @@  discard block
 block discarded – undo
116 116
  * if an array is given it will add all styles
117 117
  */
118 118
 function translation($app) {
119
-	OC_Util::addTranslations($app);
119
+    OC_Util::addTranslations($app);
120 120
 }
121 121
 
122 122
 /**
@@ -126,15 +126,15 @@  discard block
 block discarded – undo
126 126
  * if an array is given it will add all components
127 127
  */
128 128
 function component($app, $file) {
129
-	if(is_array($file)) {
130
-		foreach($file as $f) {
131
-			$url = link_to($app, 'component/' . $f . '.html');
132
-			OC_Util::addHeader('link', array('rel' => 'import', 'href' => $url));
133
-		}
134
-	} else {
135
-		$url = link_to($app, 'component/' . $file . '.html');
136
-		OC_Util::addHeader('link', array('rel' => 'import', 'href' => $url));
137
-	}
129
+    if(is_array($file)) {
130
+        foreach($file as $f) {
131
+            $url = link_to($app, 'component/' . $f . '.html');
132
+            OC_Util::addHeader('link', array('rel' => 'import', 'href' => $url));
133
+        }
134
+    } else {
135
+        $url = link_to($app, 'component/' . $file . '.html');
136
+        OC_Util::addHeader('link', array('rel' => 'import', 'href' => $url));
137
+    }
138 138
 }
139 139
 
140 140
 /**
@@ -147,7 +147,7 @@  discard block
 block discarded – undo
147 147
  * For further information have a look at \OCP\IURLGenerator::linkTo
148 148
  */
149 149
 function link_to( $app, $file, $args = array() ) {
150
-	return \OC::$server->getURLGenerator()->linkTo($app, $file, $args);
150
+    return \OC::$server->getURLGenerator()->linkTo($app, $file, $args);
151 151
 }
152 152
 
153 153
 /**
@@ -155,7 +155,7 @@  discard block
 block discarded – undo
155 155
  * @return string url to the online documentation
156 156
  */
157 157
 function link_to_docs($key) {
158
-	return \OC::$server->getURLGenerator()->linkToDocs($key);
158
+    return \OC::$server->getURLGenerator()->linkToDocs($key);
159 159
 }
160 160
 
161 161
 /**
@@ -167,7 +167,7 @@  discard block
 block discarded – undo
167 167
  * For further information have a look at \OCP\IURLGenerator::imagePath
168 168
  */
169 169
 function image_path( $app, $image ) {
170
-	return \OC::$server->getURLGenerator()->imagePath( $app, $image );
170
+    return \OC::$server->getURLGenerator()->imagePath( $app, $image );
171 171
 }
172 172
 
173 173
 /**
@@ -176,7 +176,7 @@  discard block
 block discarded – undo
176 176
  * @return string link to the image
177 177
  */
178 178
 function mimetype_icon( $mimetype ) {
179
-	return \OC::$server->getMimeTypeDetector()->mimeTypeIcon( $mimetype );
179
+    return \OC::$server->getMimeTypeDetector()->mimeTypeIcon( $mimetype );
180 180
 }
181 181
 
182 182
 /**
@@ -186,14 +186,14 @@  discard block
 block discarded – undo
186 186
  * @return link to the preview
187 187
  */
188 188
 function preview_icon( $path ) {
189
-	return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_preview', ['x' => 32, 'y' => 32, 'file' => $path]);
189
+    return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_preview', ['x' => 32, 'y' => 32, 'file' => $path]);
190 190
 }
191 191
 
192 192
 /**
193 193
  * @param string $path
194 194
  */
195 195
 function publicPreview_icon ( $path, $token ) {
196
-	return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_public_preview', ['x' => 32, 'y' => 32, 'file' => $path, 't' => $token]);
196
+    return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_public_preview', ['x' => 32, 'y' => 32, 'file' => $path, 't' => $token]);
197 197
 }
198 198
 
199 199
 /**
@@ -204,7 +204,7 @@  discard block
 block discarded – undo
204 204
  * For further information have a look at OC_Helper::humanFileSize
205 205
  */
206 206
 function human_file_size( $bytes ) {
207
-	return OC_Helper::humanFileSize( $bytes );
207
+    return OC_Helper::humanFileSize( $bytes );
208 208
 }
209 209
 
210 210
 /**
@@ -213,9 +213,9 @@  discard block
 block discarded – undo
213 213
  * @return $timestamp without time value
214 214
  */
215 215
 function strip_time($timestamp){
216
-	$date = new \DateTime("@{$timestamp}");
217
-	$date->setTime(0, 0, 0);
218
-	return intval($date->format('U'));
216
+    $date = new \DateTime("@{$timestamp}");
217
+    $date->setTime(0, 0, 0);
218
+    return intval($date->format('U'));
219 219
 }
220 220
 
221 221
 /**
@@ -227,39 +227,39 @@  discard block
 block discarded – undo
227 227
  * @return string timestamp
228 228
  */
229 229
 function relative_modified_date($timestamp, $fromTime = null, $dateOnly = false) {
230
-	/** @var \OC\DateTimeFormatter $formatter */
231
-	$formatter = \OC::$server->query('DateTimeFormatter');
230
+    /** @var \OC\DateTimeFormatter $formatter */
231
+    $formatter = \OC::$server->query('DateTimeFormatter');
232 232
 
233
-	if ($dateOnly){
234
-		return $formatter->formatDateSpan($timestamp, $fromTime);
235
-	}
236
-	return $formatter->formatTimeSpan($timestamp, $fromTime);
233
+    if ($dateOnly){
234
+        return $formatter->formatDateSpan($timestamp, $fromTime);
235
+    }
236
+    return $formatter->formatTimeSpan($timestamp, $fromTime);
237 237
 }
238 238
 
239 239
 function html_select_options($options, $selected, $params=array()) {
240
-	if (!is_array($selected)) {
241
-		$selected=array($selected);
242
-	}
243
-	if (isset($params['combine']) && $params['combine']) {
244
-		$options = array_combine($options, $options);
245
-	}
246
-	$value_name = $label_name = false;
247
-	if (isset($params['value'])) {
248
-		$value_name = $params['value'];
249
-	}
250
-	if (isset($params['label'])) {
251
-		$label_name = $params['label'];
252
-	}
253
-	$html = '';
254
-	foreach($options as $value => $label) {
255
-		if ($value_name && is_array($label)) {
256
-			$value = $label[$value_name];
257
-		}
258
-		if ($label_name && is_array($label)) {
259
-			$label = $label[$label_name];
260
-		}
261
-		$select = in_array($value, $selected) ? ' selected="selected"' : '';
262
-		$html .= '<option value="' . \OCP\Util::sanitizeHTML($value) . '"' . $select . '>' . \OCP\Util::sanitizeHTML($label) . '</option>'."\n";
263
-	}
264
-	return $html;
240
+    if (!is_array($selected)) {
241
+        $selected=array($selected);
242
+    }
243
+    if (isset($params['combine']) && $params['combine']) {
244
+        $options = array_combine($options, $options);
245
+    }
246
+    $value_name = $label_name = false;
247
+    if (isset($params['value'])) {
248
+        $value_name = $params['value'];
249
+    }
250
+    if (isset($params['label'])) {
251
+        $label_name = $params['label'];
252
+    }
253
+    $html = '';
254
+    foreach($options as $value => $label) {
255
+        if ($value_name && is_array($label)) {
256
+            $value = $label[$value_name];
257
+        }
258
+        if ($label_name && is_array($label)) {
259
+            $label = $label[$label_name];
260
+        }
261
+        $select = in_array($value, $selected) ? ' selected="selected"' : '';
262
+        $html .= '<option value="' . \OCP\Util::sanitizeHTML($value) . '"' . $select . '>' . \OCP\Util::sanitizeHTML($label) . '</option>'."\n";
263
+    }
264
+    return $html;
265 265
 }
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -53,8 +53,8 @@  discard block
 block discarded – undo
53 53
  * if an array is given it will add all scripts
54 54
  */
55 55
 function script($app, $file = null) {
56
-	if(is_array($file)) {
57
-		foreach($file as $f) {
56
+	if (is_array($file)) {
57
+		foreach ($file as $f) {
58 58
 			OC_Util::addScript($app, $f);
59 59
 		}
60 60
 	} else {
@@ -69,8 +69,8 @@  discard block
 block discarded – undo
69 69
  * if an array is given it will add all scripts
70 70
  */
71 71
 function vendor_script($app, $file = null) {
72
-	if(is_array($file)) {
73
-		foreach($file as $f) {
72
+	if (is_array($file)) {
73
+		foreach ($file as $f) {
74 74
 			OC_Util::addVendorScript($app, $f);
75 75
 		}
76 76
 	} else {
@@ -85,8 +85,8 @@  discard block
 block discarded – undo
85 85
  * if an array is given it will add all styles
86 86
  */
87 87
 function style($app, $file = null) {
88
-	if(is_array($file)) {
89
-		foreach($file as $f) {
88
+	if (is_array($file)) {
89
+		foreach ($file as $f) {
90 90
 			OC_Util::addStyle($app, $f);
91 91
 		}
92 92
 	} else {
@@ -101,8 +101,8 @@  discard block
 block discarded – undo
101 101
  * if an array is given it will add all styles
102 102
  */
103 103
 function vendor_style($app, $file = null) {
104
-	if(is_array($file)) {
105
-		foreach($file as $f) {
104
+	if (is_array($file)) {
105
+		foreach ($file as $f) {
106 106
 			OC_Util::addVendorStyle($app, $f);
107 107
 		}
108 108
 	} else {
@@ -126,13 +126,13 @@  discard block
 block discarded – undo
126 126
  * if an array is given it will add all components
127 127
  */
128 128
 function component($app, $file) {
129
-	if(is_array($file)) {
130
-		foreach($file as $f) {
131
-			$url = link_to($app, 'component/' . $f . '.html');
129
+	if (is_array($file)) {
130
+		foreach ($file as $f) {
131
+			$url = link_to($app, 'component/'.$f.'.html');
132 132
 			OC_Util::addHeader('link', array('rel' => 'import', 'href' => $url));
133 133
 		}
134 134
 	} else {
135
-		$url = link_to($app, 'component/' . $file . '.html');
135
+		$url = link_to($app, 'component/'.$file.'.html');
136 136
 		OC_Util::addHeader('link', array('rel' => 'import', 'href' => $url));
137 137
 	}
138 138
 }
@@ -146,7 +146,7 @@  discard block
 block discarded – undo
146 146
  *
147 147
  * For further information have a look at \OCP\IURLGenerator::linkTo
148 148
  */
149
-function link_to( $app, $file, $args = array() ) {
149
+function link_to($app, $file, $args = array()) {
150 150
 	return \OC::$server->getURLGenerator()->linkTo($app, $file, $args);
151 151
 }
152 152
 
@@ -166,8 +166,8 @@  discard block
 block discarded – undo
166 166
  *
167 167
  * For further information have a look at \OCP\IURLGenerator::imagePath
168 168
  */
169
-function image_path( $app, $image ) {
170
-	return \OC::$server->getURLGenerator()->imagePath( $app, $image );
169
+function image_path($app, $image) {
170
+	return \OC::$server->getURLGenerator()->imagePath($app, $image);
171 171
 }
172 172
 
173 173
 /**
@@ -175,8 +175,8 @@  discard block
 block discarded – undo
175 175
  * @param string $mimetype mimetype
176 176
  * @return string link to the image
177 177
  */
178
-function mimetype_icon( $mimetype ) {
179
-	return \OC::$server->getMimeTypeDetector()->mimeTypeIcon( $mimetype );
178
+function mimetype_icon($mimetype) {
179
+	return \OC::$server->getMimeTypeDetector()->mimeTypeIcon($mimetype);
180 180
 }
181 181
 
182 182
 /**
@@ -185,14 +185,14 @@  discard block
 block discarded – undo
185 185
  * @param string $path path of file
186 186
  * @return link to the preview
187 187
  */
188
-function preview_icon( $path ) {
188
+function preview_icon($path) {
189 189
 	return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_preview', ['x' => 32, 'y' => 32, 'file' => $path]);
190 190
 }
191 191
 
192 192
 /**
193 193
  * @param string $path
194 194
  */
195
-function publicPreview_icon ( $path, $token ) {
195
+function publicPreview_icon($path, $token) {
196 196
 	return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_public_preview', ['x' => 32, 'y' => 32, 'file' => $path, 't' => $token]);
197 197
 }
198 198
 
@@ -203,8 +203,8 @@  discard block
 block discarded – undo
203 203
  *
204 204
  * For further information have a look at OC_Helper::humanFileSize
205 205
  */
206
-function human_file_size( $bytes ) {
207
-	return OC_Helper::humanFileSize( $bytes );
206
+function human_file_size($bytes) {
207
+	return OC_Helper::humanFileSize($bytes);
208 208
 }
209 209
 
210 210
 /**
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
  * @param int $timestamp UNIX timestamp to strip
213 213
  * @return $timestamp without time value
214 214
  */
215
-function strip_time($timestamp){
215
+function strip_time($timestamp) {
216 216
 	$date = new \DateTime("@{$timestamp}");
217 217
 	$date->setTime(0, 0, 0);
218 218
 	return intval($date->format('U'));
@@ -230,15 +230,15 @@  discard block
 block discarded – undo
230 230
 	/** @var \OC\DateTimeFormatter $formatter */
231 231
 	$formatter = \OC::$server->query('DateTimeFormatter');
232 232
 
233
-	if ($dateOnly){
233
+	if ($dateOnly) {
234 234
 		return $formatter->formatDateSpan($timestamp, $fromTime);
235 235
 	}
236 236
 	return $formatter->formatTimeSpan($timestamp, $fromTime);
237 237
 }
238 238
 
239
-function html_select_options($options, $selected, $params=array()) {
239
+function html_select_options($options, $selected, $params = array()) {
240 240
 	if (!is_array($selected)) {
241
-		$selected=array($selected);
241
+		$selected = array($selected);
242 242
 	}
243 243
 	if (isset($params['combine']) && $params['combine']) {
244 244
 		$options = array_combine($options, $options);
@@ -251,7 +251,7 @@  discard block
 block discarded – undo
251 251
 		$label_name = $params['label'];
252 252
 	}
253 253
 	$html = '';
254
-	foreach($options as $value => $label) {
254
+	foreach ($options as $value => $label) {
255 255
 		if ($value_name && is_array($label)) {
256 256
 			$value = $label[$value_name];
257 257
 		}
@@ -259,7 +259,7 @@  discard block
 block discarded – undo
259 259
 			$label = $label[$label_name];
260 260
 		}
261 261
 		$select = in_array($value, $selected) ? ' selected="selected"' : '';
262
-		$html .= '<option value="' . \OCP\Util::sanitizeHTML($value) . '"' . $select . '>' . \OCP\Util::sanitizeHTML($label) . '</option>'."\n";
262
+		$html .= '<option value="'.\OCP\Util::sanitizeHTML($value).'"'.$select.'>'.\OCP\Util::sanitizeHTML($label).'</option>'."\n";
263 263
 	}
264 264
 	return $html;
265 265
 }
Please login to merge, or discard this patch.