Completed
Pull Request — master (#7361)
by Blizzz
15:08
created
apps/files_trashbin/lib/Storage.php 1 patch
Indentation   +277 added lines, -277 removed lines patch added patch discarded remove patch
@@ -40,282 +40,282 @@
 block discarded – undo
40 40
 
41 41
 class Storage extends Wrapper {
42 42
 
43
-	private $mountPoint;
44
-	// remember already deleted files to avoid infinite loops if the trash bin
45
-	// move files across storages
46
-	private $deletedFiles = array();
47
-
48
-	/**
49
-	 * Disable trash logic
50
-	 *
51
-	 * @var bool
52
-	 */
53
-	private static $disableTrash = false;
54
-
55
-	/**
56
-	 * remember which file/folder was moved out of s shared folder
57
-	 * in this case we want to add a copy to the owners trash bin
58
-	 *
59
-	 * @var array
60
-	 */
61
-	private static $moveOutOfSharedFolder = [];
62
-
63
-	/** @var  IUserManager */
64
-	private $userManager;
65
-
66
-	/** @var ILogger */
67
-	private $logger;
68
-
69
-	/** @var EventDispatcher */
70
-	private $eventDispatcher;
71
-
72
-	/** @var IRootFolder */
73
-	private $rootFolder;
74
-
75
-	/**
76
-	 * Storage constructor.
77
-	 *
78
-	 * @param array $parameters
79
-	 * @param IUserManager|null $userManager
80
-	 * @param ILogger|null $logger
81
-	 * @param EventDispatcher|null $eventDispatcher
82
-	 * @param IRootFolder|null $rootFolder
83
-	 */
84
-	public function __construct($parameters,
85
-								IUserManager $userManager = null,
86
-								ILogger $logger = null,
87
-								EventDispatcher $eventDispatcher = null,
88
-								IRootFolder $rootFolder = null) {
89
-		$this->mountPoint = $parameters['mountPoint'];
90
-		$this->userManager = $userManager;
91
-		$this->logger = $logger;
92
-		$this->eventDispatcher = $eventDispatcher;
93
-		$this->rootFolder = $rootFolder;
94
-		parent::__construct($parameters);
95
-	}
96
-
97
-	/**
98
-	 * @internal
99
-	 */
100
-	public static function preRenameHook($params) {
101
-		// in cross-storage cases, a rename is a copy + unlink,
102
-		// that last unlink must not go to trash, only exception:
103
-		// if the file was moved from a shared storage to a local folder,
104
-		// in this case the owner should get a copy in his trash bin so that
105
-		// they can restore the files again
106
-
107
-		$oldPath = $params['oldpath'];
108
-		$newPath = dirname($params['newpath']);
109
-		$currentUser = \OC::$server->getUserSession()->getUser();
110
-
111
-		$fileMovedOutOfSharedFolder = false;
112
-
113
-		try {
114
-			if ($currentUser) {
115
-				$currentUserId = $currentUser->getUID();
116
-
117
-				$view = new View($currentUserId . '/files');
118
-				$fileInfo = $view->getFileInfo($oldPath);
119
-				if ($fileInfo) {
120
-					$sourceStorage = $fileInfo->getStorage();
121
-					$sourceOwner = $view->getOwner($oldPath);
122
-					$targetOwner = $view->getOwner($newPath);
123
-
124
-					if ($sourceOwner !== $targetOwner
125
-						&& $sourceStorage->instanceOfStorage('OCA\Files_Sharing\SharedStorage')
126
-					) {
127
-						$fileMovedOutOfSharedFolder = true;
128
-					}
129
-				}
130
-			}
131
-		} catch (\Exception $e) {
132
-			// do nothing, in this case we just disable the trashbin and continue
133
-			$logger = \OC::$server->getLogger();
134
-			$logger->debug('Trashbin storage could not check if a file was moved out of a shared folder: ' . $e->getMessage());
135
-		}
136
-
137
-		if($fileMovedOutOfSharedFolder) {
138
-			self::$moveOutOfSharedFolder['/' . $currentUserId . '/files' . $oldPath] = true;
139
-		} else {
140
-			self::$disableTrash = true;
141
-		}
142
-
143
-	}
144
-
145
-	/**
146
-	 * @internal
147
-	 */
148
-	public static function postRenameHook($params) {
149
-		self::$disableTrash = false;
150
-	}
151
-
152
-	/**
153
-	 * Rename path1 to path2 by calling the wrapped storage.
154
-	 *
155
-	 * @param string $path1 first path
156
-	 * @param string $path2 second path
157
-	 * @return bool
158
-	 */
159
-	public function rename($path1, $path2) {
160
-		$result = $this->storage->rename($path1, $path2);
161
-		if ($result === false) {
162
-			// when rename failed, the post_rename hook isn't triggered,
163
-			// but we still want to reenable the trash logic
164
-			self::$disableTrash = false;
165
-		}
166
-		return $result;
167
-	}
168
-
169
-	/**
170
-	 * Deletes the given file by moving it into the trashbin.
171
-	 *
172
-	 * @param string $path path of file or folder to delete
173
-	 *
174
-	 * @return bool true if the operation succeeded, false otherwise
175
-	 */
176
-	public function unlink($path) {
177
-		try {
178
-			if (isset(self::$moveOutOfSharedFolder[$this->mountPoint . $path])) {
179
-				$result = $this->doDelete($path, 'unlink', true);
180
-				unset(self::$moveOutOfSharedFolder[$this->mountPoint . $path]);
181
-			} else {
182
-				$result = $this->doDelete($path, 'unlink');
183
-			}
184
-		} catch (GenericEncryptionException $e) {
185
-			// in case of a encryption exception we delete the file right away
186
-			$this->logger->info(
187
-				"Can't move file" .  $path .
188
-				"to the trash bin, therefore it was deleted right away");
189
-
190
-			$result = $this->storage->unlink($path);
191
-		}
192
-
193
-		return $result;
194
-	}
195
-
196
-	/**
197
-	 * Deletes the given folder by moving it into the trashbin.
198
-	 *
199
-	 * @param string $path path of folder to delete
200
-	 *
201
-	 * @return bool true if the operation succeeded, false otherwise
202
-	 */
203
-	public function rmdir($path) {
204
-		if (isset(self::$moveOutOfSharedFolder[$this->mountPoint . $path])) {
205
-			$result = $this->doDelete($path, 'rmdir', true);
206
-			unset(self::$moveOutOfSharedFolder[$this->mountPoint . $path]);
207
-		} else {
208
-			$result = $this->doDelete($path, 'rmdir');
209
-		}
210
-
211
-		return $result;
212
-	}
213
-
214
-	/**
215
-	 * check if it is a file located in data/user/files only files in the
216
-	 * 'files' directory should be moved to the trash
217
-	 *
218
-	 * @param $path
219
-	 * @return bool
220
-	 */
221
-	protected function shouldMoveToTrash($path){
222
-
223
-		// check if there is a app which want to disable the trash bin for this file
224
-		$fileId = $this->storage->getCache()->getId($path);
225
-		$nodes = $this->rootFolder->getById($fileId);
226
-		foreach ($nodes as $node) {
227
-			$event = $this->createMoveToTrashEvent($node);
228
-			$this->eventDispatcher->dispatch('OCA\Files_Trashbin::moveToTrash', $event);
229
-			if ($event->shouldMoveToTrashBin() === false) {
230
-				return false;
231
-			}
232
-		}
233
-
234
-		$normalized = Filesystem::normalizePath($this->mountPoint . '/' . $path);
235
-		$parts = explode('/', $normalized);
236
-		if (count($parts) < 4) {
237
-			return false;
238
-		}
239
-
240
-		if ($parts[2] === 'files' && $this->userManager->userExists($parts[1])) {
241
-			return true;
242
-		}
243
-
244
-		return false;
245
-	}
246
-
247
-	/**
248
-	 * get move to trash event
249
-	 *
250
-	 * @param Node $node
251
-	 * @return MoveToTrashEvent
252
-	 */
253
-	protected function createMoveToTrashEvent(Node $node) {
254
-		$event = new MoveToTrashEvent($node);
255
-		return $event;
256
-	}
257
-
258
-	/**
259
-	 * Run the delete operation with the given method
260
-	 *
261
-	 * @param string $path path of file or folder to delete
262
-	 * @param string $method either "unlink" or "rmdir"
263
-	 * @param bool $ownerOnly delete for owner only (if file gets moved out of a shared folder)
264
-	 *
265
-	 * @return bool true if the operation succeeded, false otherwise
266
-	 */
267
-	private function doDelete($path, $method, $ownerOnly = false) {
268
-		if (self::$disableTrash
269
-			|| !\OC_App::isEnabled('files_trashbin')
270
-			|| (pathinfo($path, PATHINFO_EXTENSION) === 'part')
271
-			|| $this->shouldMoveToTrash($path) === false
272
-		) {
273
-			return call_user_func_array([$this->storage, $method], [$path]);
274
-		}
275
-
276
-		// check permissions before we continue, this is especially important for
277
-		// shared files
278
-		if (!$this->isDeletable($path)) {
279
-			return false;
280
-		}
281
-
282
-		$normalized = Filesystem::normalizePath($this->mountPoint . '/' . $path, true, false, true);
283
-		$result = true;
284
-		$view = Filesystem::getView();
285
-		if (!isset($this->deletedFiles[$normalized]) && $view instanceof View) {
286
-			$this->deletedFiles[$normalized] = $normalized;
287
-			if ($filesPath = $view->getRelativePath($normalized)) {
288
-				$filesPath = trim($filesPath, '/');
289
-				$result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath, $ownerOnly);
290
-				// in cross-storage cases the file will be copied
291
-				// but not deleted, so we delete it here
292
-				if ($result) {
293
-					call_user_func_array([$this->storage, $method], [$path]);
294
-				}
295
-			} else {
296
-				$result = call_user_func_array([$this->storage, $method], [$path]);
297
-			}
298
-			unset($this->deletedFiles[$normalized]);
299
-		} else if ($this->storage->file_exists($path)) {
300
-			$result = call_user_func_array([$this->storage, $method], [$path]);
301
-		}
302
-
303
-		return $result;
304
-	}
305
-
306
-	/**
307
-	 * Setup the storate wrapper callback
308
-	 */
309
-	public static function setupStorage() {
310
-		\OC\Files\Filesystem::addStorageWrapper('oc_trashbin', function ($mountPoint, $storage) {
311
-			return new \OCA\Files_Trashbin\Storage(
312
-				array('storage' => $storage, 'mountPoint' => $mountPoint),
313
-				\OC::$server->getUserManager(),
314
-				\OC::$server->getLogger(),
315
-				\OC::$server->getEventDispatcher(),
316
-				\OC::$server->getLazyRootFolder()
317
-			);
318
-		}, 1);
319
-	}
43
+    private $mountPoint;
44
+    // remember already deleted files to avoid infinite loops if the trash bin
45
+    // move files across storages
46
+    private $deletedFiles = array();
47
+
48
+    /**
49
+     * Disable trash logic
50
+     *
51
+     * @var bool
52
+     */
53
+    private static $disableTrash = false;
54
+
55
+    /**
56
+     * remember which file/folder was moved out of s shared folder
57
+     * in this case we want to add a copy to the owners trash bin
58
+     *
59
+     * @var array
60
+     */
61
+    private static $moveOutOfSharedFolder = [];
62
+
63
+    /** @var  IUserManager */
64
+    private $userManager;
65
+
66
+    /** @var ILogger */
67
+    private $logger;
68
+
69
+    /** @var EventDispatcher */
70
+    private $eventDispatcher;
71
+
72
+    /** @var IRootFolder */
73
+    private $rootFolder;
74
+
75
+    /**
76
+     * Storage constructor.
77
+     *
78
+     * @param array $parameters
79
+     * @param IUserManager|null $userManager
80
+     * @param ILogger|null $logger
81
+     * @param EventDispatcher|null $eventDispatcher
82
+     * @param IRootFolder|null $rootFolder
83
+     */
84
+    public function __construct($parameters,
85
+                                IUserManager $userManager = null,
86
+                                ILogger $logger = null,
87
+                                EventDispatcher $eventDispatcher = null,
88
+                                IRootFolder $rootFolder = null) {
89
+        $this->mountPoint = $parameters['mountPoint'];
90
+        $this->userManager = $userManager;
91
+        $this->logger = $logger;
92
+        $this->eventDispatcher = $eventDispatcher;
93
+        $this->rootFolder = $rootFolder;
94
+        parent::__construct($parameters);
95
+    }
96
+
97
+    /**
98
+     * @internal
99
+     */
100
+    public static function preRenameHook($params) {
101
+        // in cross-storage cases, a rename is a copy + unlink,
102
+        // that last unlink must not go to trash, only exception:
103
+        // if the file was moved from a shared storage to a local folder,
104
+        // in this case the owner should get a copy in his trash bin so that
105
+        // they can restore the files again
106
+
107
+        $oldPath = $params['oldpath'];
108
+        $newPath = dirname($params['newpath']);
109
+        $currentUser = \OC::$server->getUserSession()->getUser();
110
+
111
+        $fileMovedOutOfSharedFolder = false;
112
+
113
+        try {
114
+            if ($currentUser) {
115
+                $currentUserId = $currentUser->getUID();
116
+
117
+                $view = new View($currentUserId . '/files');
118
+                $fileInfo = $view->getFileInfo($oldPath);
119
+                if ($fileInfo) {
120
+                    $sourceStorage = $fileInfo->getStorage();
121
+                    $sourceOwner = $view->getOwner($oldPath);
122
+                    $targetOwner = $view->getOwner($newPath);
123
+
124
+                    if ($sourceOwner !== $targetOwner
125
+                        && $sourceStorage->instanceOfStorage('OCA\Files_Sharing\SharedStorage')
126
+                    ) {
127
+                        $fileMovedOutOfSharedFolder = true;
128
+                    }
129
+                }
130
+            }
131
+        } catch (\Exception $e) {
132
+            // do nothing, in this case we just disable the trashbin and continue
133
+            $logger = \OC::$server->getLogger();
134
+            $logger->debug('Trashbin storage could not check if a file was moved out of a shared folder: ' . $e->getMessage());
135
+        }
136
+
137
+        if($fileMovedOutOfSharedFolder) {
138
+            self::$moveOutOfSharedFolder['/' . $currentUserId . '/files' . $oldPath] = true;
139
+        } else {
140
+            self::$disableTrash = true;
141
+        }
142
+
143
+    }
144
+
145
+    /**
146
+     * @internal
147
+     */
148
+    public static function postRenameHook($params) {
149
+        self::$disableTrash = false;
150
+    }
151
+
152
+    /**
153
+     * Rename path1 to path2 by calling the wrapped storage.
154
+     *
155
+     * @param string $path1 first path
156
+     * @param string $path2 second path
157
+     * @return bool
158
+     */
159
+    public function rename($path1, $path2) {
160
+        $result = $this->storage->rename($path1, $path2);
161
+        if ($result === false) {
162
+            // when rename failed, the post_rename hook isn't triggered,
163
+            // but we still want to reenable the trash logic
164
+            self::$disableTrash = false;
165
+        }
166
+        return $result;
167
+    }
168
+
169
+    /**
170
+     * Deletes the given file by moving it into the trashbin.
171
+     *
172
+     * @param string $path path of file or folder to delete
173
+     *
174
+     * @return bool true if the operation succeeded, false otherwise
175
+     */
176
+    public function unlink($path) {
177
+        try {
178
+            if (isset(self::$moveOutOfSharedFolder[$this->mountPoint . $path])) {
179
+                $result = $this->doDelete($path, 'unlink', true);
180
+                unset(self::$moveOutOfSharedFolder[$this->mountPoint . $path]);
181
+            } else {
182
+                $result = $this->doDelete($path, 'unlink');
183
+            }
184
+        } catch (GenericEncryptionException $e) {
185
+            // in case of a encryption exception we delete the file right away
186
+            $this->logger->info(
187
+                "Can't move file" .  $path .
188
+                "to the trash bin, therefore it was deleted right away");
189
+
190
+            $result = $this->storage->unlink($path);
191
+        }
192
+
193
+        return $result;
194
+    }
195
+
196
+    /**
197
+     * Deletes the given folder by moving it into the trashbin.
198
+     *
199
+     * @param string $path path of folder to delete
200
+     *
201
+     * @return bool true if the operation succeeded, false otherwise
202
+     */
203
+    public function rmdir($path) {
204
+        if (isset(self::$moveOutOfSharedFolder[$this->mountPoint . $path])) {
205
+            $result = $this->doDelete($path, 'rmdir', true);
206
+            unset(self::$moveOutOfSharedFolder[$this->mountPoint . $path]);
207
+        } else {
208
+            $result = $this->doDelete($path, 'rmdir');
209
+        }
210
+
211
+        return $result;
212
+    }
213
+
214
+    /**
215
+     * check if it is a file located in data/user/files only files in the
216
+     * 'files' directory should be moved to the trash
217
+     *
218
+     * @param $path
219
+     * @return bool
220
+     */
221
+    protected function shouldMoveToTrash($path){
222
+
223
+        // check if there is a app which want to disable the trash bin for this file
224
+        $fileId = $this->storage->getCache()->getId($path);
225
+        $nodes = $this->rootFolder->getById($fileId);
226
+        foreach ($nodes as $node) {
227
+            $event = $this->createMoveToTrashEvent($node);
228
+            $this->eventDispatcher->dispatch('OCA\Files_Trashbin::moveToTrash', $event);
229
+            if ($event->shouldMoveToTrashBin() === false) {
230
+                return false;
231
+            }
232
+        }
233
+
234
+        $normalized = Filesystem::normalizePath($this->mountPoint . '/' . $path);
235
+        $parts = explode('/', $normalized);
236
+        if (count($parts) < 4) {
237
+            return false;
238
+        }
239
+
240
+        if ($parts[2] === 'files' && $this->userManager->userExists($parts[1])) {
241
+            return true;
242
+        }
243
+
244
+        return false;
245
+    }
246
+
247
+    /**
248
+     * get move to trash event
249
+     *
250
+     * @param Node $node
251
+     * @return MoveToTrashEvent
252
+     */
253
+    protected function createMoveToTrashEvent(Node $node) {
254
+        $event = new MoveToTrashEvent($node);
255
+        return $event;
256
+    }
257
+
258
+    /**
259
+     * Run the delete operation with the given method
260
+     *
261
+     * @param string $path path of file or folder to delete
262
+     * @param string $method either "unlink" or "rmdir"
263
+     * @param bool $ownerOnly delete for owner only (if file gets moved out of a shared folder)
264
+     *
265
+     * @return bool true if the operation succeeded, false otherwise
266
+     */
267
+    private function doDelete($path, $method, $ownerOnly = false) {
268
+        if (self::$disableTrash
269
+            || !\OC_App::isEnabled('files_trashbin')
270
+            || (pathinfo($path, PATHINFO_EXTENSION) === 'part')
271
+            || $this->shouldMoveToTrash($path) === false
272
+        ) {
273
+            return call_user_func_array([$this->storage, $method], [$path]);
274
+        }
275
+
276
+        // check permissions before we continue, this is especially important for
277
+        // shared files
278
+        if (!$this->isDeletable($path)) {
279
+            return false;
280
+        }
281
+
282
+        $normalized = Filesystem::normalizePath($this->mountPoint . '/' . $path, true, false, true);
283
+        $result = true;
284
+        $view = Filesystem::getView();
285
+        if (!isset($this->deletedFiles[$normalized]) && $view instanceof View) {
286
+            $this->deletedFiles[$normalized] = $normalized;
287
+            if ($filesPath = $view->getRelativePath($normalized)) {
288
+                $filesPath = trim($filesPath, '/');
289
+                $result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath, $ownerOnly);
290
+                // in cross-storage cases the file will be copied
291
+                // but not deleted, so we delete it here
292
+                if ($result) {
293
+                    call_user_func_array([$this->storage, $method], [$path]);
294
+                }
295
+            } else {
296
+                $result = call_user_func_array([$this->storage, $method], [$path]);
297
+            }
298
+            unset($this->deletedFiles[$normalized]);
299
+        } else if ($this->storage->file_exists($path)) {
300
+            $result = call_user_func_array([$this->storage, $method], [$path]);
301
+        }
302
+
303
+        return $result;
304
+    }
305
+
306
+    /**
307
+     * Setup the storate wrapper callback
308
+     */
309
+    public static function setupStorage() {
310
+        \OC\Files\Filesystem::addStorageWrapper('oc_trashbin', function ($mountPoint, $storage) {
311
+            return new \OCA\Files_Trashbin\Storage(
312
+                array('storage' => $storage, 'mountPoint' => $mountPoint),
313
+                \OC::$server->getUserManager(),
314
+                \OC::$server->getLogger(),
315
+                \OC::$server->getEventDispatcher(),
316
+                \OC::$server->getLazyRootFolder()
317
+            );
318
+        }, 1);
319
+    }
320 320
 
321 321
 }
Please login to merge, or discard this patch.