Blame view

sources/lib/private/files/cache/updater.php 5.98 KB
03e52840d   Kload   Init
1
2
3
4
5
6
7
8
9
  <?php
  /**
   * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
   * This file is licensed under the Affero General Public License version 3 or
   * later.
   * See the COPYING-README file.
   */
  
  namespace OC\Files\Cache;
31b7f2792   Kload   Upgrade to ownclo...
10
  use OCP\Util;
03e52840d   Kload   Init
11
12
13
14
15
16
17
18
  /**
   * listen to filesystem hooks and change the cache accordingly
   */
  class Updater {
  
  	/**
  	 * resolve a path to a storage and internal path
  	 *
31b7f2792   Kload   Upgrade to ownclo...
19
  	 * @param string $path the relative path
03e52840d   Kload   Init
20
21
22
23
24
25
  	 * @return array consisting of the storage and the internal path
  	 */
  	static public function resolvePath($path) {
  		$view = \OC\Files\Filesystem::getView();
  		return $view->resolvePath($path);
  	}
31b7f2792   Kload   Upgrade to ownclo...
26
27
28
29
30
  	/**
  	 * perform a write update
  	 *
  	 * @param string $path the relative path of the file
  	 */
03e52840d   Kload   Init
31
32
33
34
35
36
37
38
39
40
41
42
  	static public function writeUpdate($path) {
  		/**
  		 * @var \OC\Files\Storage\Storage $storage
  		 * @var string $internalPath
  		 */
  		list($storage, $internalPath) = self::resolvePath($path);
  		if ($storage) {
  			$cache = $storage->getCache($internalPath);
  			$scanner = $storage->getScanner($internalPath);
  			$scanner->scan($internalPath, Scanner::SCAN_SHALLOW);
  			$cache->correctFolderSize($internalPath);
  			self::correctFolder($path, $storage->filemtime($internalPath));
31b7f2792   Kload   Upgrade to ownclo...
43
  			self::correctParentStorageMtime($storage, $internalPath);
03e52840d   Kload   Init
44
45
  		}
  	}
31b7f2792   Kload   Upgrade to ownclo...
46
47
48
49
50
  	/**
  	 * perform a delete update
  	 *
  	 * @param string $path the relative path of the file
  	 */
03e52840d   Kload   Init
51
52
53
54
55
56
57
  	static public function deleteUpdate($path) {
  		/**
  		 * @var \OC\Files\Storage\Storage $storage
  		 * @var string $internalPath
  		 */
  		list($storage, $internalPath) = self::resolvePath($path);
  		if ($storage) {
31b7f2792   Kload   Upgrade to ownclo...
58
59
60
61
  			$parent = dirname($internalPath);
  			if ($parent === '.') {
  				$parent = '';
  			}
03e52840d   Kload   Init
62
63
  			$cache = $storage->getCache($internalPath);
  			$cache->remove($internalPath);
31b7f2792   Kload   Upgrade to ownclo...
64
  			$cache->correctFolderSize($parent);
03e52840d   Kload   Init
65
  			self::correctFolder($path, time());
31b7f2792   Kload   Upgrade to ownclo...
66
  			self::correctParentStorageMtime($storage, $internalPath);
03e52840d   Kload   Init
67
68
  		}
  	}
31b7f2792   Kload   Upgrade to ownclo...
69
70
71
72
73
74
  	/**
  	 * preform a rename update
  	 *
  	 * @param string $from the relative path of the source file
  	 * @param string $to the relative path of the target file
  	 */
03e52840d   Kload   Init
75
76
77
78
79
80
81
82
83
84
85
86
87
  	static public function renameUpdate($from, $to) {
  		/**
  		 * @var \OC\Files\Storage\Storage $storageFrom
  		 * @var \OC\Files\Storage\Storage $storageTo
  		 * @var string $internalFrom
  		 * @var string $internalTo
  		 */
  		list($storageFrom, $internalFrom) = self::resolvePath($from);
  		list($storageTo, $internalTo) = self::resolvePath($to);
  		if ($storageFrom && $storageTo) {
  			if ($storageFrom === $storageTo) {
  				$cache = $storageFrom->getCache($internalFrom);
  				$cache->move($internalFrom, $internalTo);
31b7f2792   Kload   Upgrade to ownclo...
88
89
90
91
92
93
  				if (pathinfo($internalFrom, PATHINFO_EXTENSION) !== pathinfo($internalTo, PATHINFO_EXTENSION)) {
  					// redetect mime type change
  					$mimeType = $storageTo->getMimeType($internalTo);
  					$fileId = $storageTo->getCache()->getId($internalTo);
  					$storageTo->getCache()->update($fileId, array('mimetype' => $mimeType));
  				}
03e52840d   Kload   Init
94
95
96
97
  				$cache->correctFolderSize($internalFrom);
  				$cache->correctFolderSize($internalTo);
  				self::correctFolder($from, time());
  				self::correctFolder($to, time());
31b7f2792   Kload   Upgrade to ownclo...
98
99
  				self::correctParentStorageMtime($storageFrom, $internalFrom);
  				self::correctParentStorageMtime($storageTo, $internalTo);
03e52840d   Kload   Init
100
101
102
103
104
105
106
107
108
109
110
111
112
  			} else {
  				self::deleteUpdate($from);
  				self::writeUpdate($to);
  			}
  		}
  	}
  
  	/**
  	 * @brief get file owner and path
  	 * @param string $filename
  	 * @return array with the oweners uid and the owners path
  	 */
  	private static function getUidAndFilename($filename) {
31b7f2792   Kload   Upgrade to ownclo...
113

03e52840d   Kload   Init
114
115
  		$uid = \OC\Files\Filesystem::getOwner($filename);
  		\OC\Files\Filesystem::initMountPoints($uid);
31b7f2792   Kload   Upgrade to ownclo...
116
117
  
  		if ($uid != \OCP\User::getUser()) {
03e52840d   Kload   Init
118
  			$info = \OC\Files\Filesystem::getFileInfo($filename);
31b7f2792   Kload   Upgrade to ownclo...
119
  			$ownerView = new \OC\Files\View('/' . $uid . '/files');
03e52840d   Kload   Init
120
121
  			$filename = $ownerView->getPath($info['fileid']);
  		}
31b7f2792   Kload   Upgrade to ownclo...
122
  		return array($uid, '/files/' . $filename);
03e52840d   Kload   Init
123
124
125
126
127
128
129
130
131
  	}
  
  	/**
  	 * Update the mtime and ETag of all parent folders
  	 *
  	 * @param string $path
  	 * @param string $time
  	 */
  	static public function correctFolder($path, $time) {
03e52840d   Kload   Init
132
133
134
135
136
137
138
139
  		if ($path !== '' && $path !== '/') {
  
  			list($owner, $realPath) = self::getUidAndFilename(dirname($path));
  
  			/**
  			 * @var \OC\Files\Storage\Storage $storage
  			 * @var string $internalPath
  			 */
03e52840d   Kload   Init
140
141
142
143
144
145
146
147
  			$view = new \OC\Files\View('/' . $owner);
  
  			list($storage, $internalPath) = $view->resolvePath($realPath);
  			$cache = $storage->getCache();
  			$id = $cache->getId($internalPath);
  
  			while ($id !== -1) {
  				$cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath)));
31b7f2792   Kload   Upgrade to ownclo...
148
149
150
151
152
153
154
  				if ($realPath !== '') {
  					$realPath = dirname($realPath);
  					if($realPath === DIRECTORY_SEPARATOR ) {
  						$realPath = "";
  					}
  					// check storage for parent in case we change the storage in this step
  					list($storage, $internalPath) = $view->resolvePath($realPath);
03e52840d   Kload   Init
155
156
157
158
159
  					$cache = $storage->getCache();
  					$id = $cache->getId($internalPath);
  				} else {
  					$id = -1;
  				}
03e52840d   Kload   Init
160
  			}
31b7f2792   Kload   Upgrade to ownclo...
161
162
  		}
  	}
03e52840d   Kload   Init
163

31b7f2792   Kload   Upgrade to ownclo...
164
165
166
167
168
169
170
171
172
173
174
175
  	/**
  	 * update the storage_mtime of the parent
  	 *
  	 * @param \OC\Files\Storage\Storage $storage
  	 * @param string $internalPath
  	 */
  	static private function correctParentStorageMtime($storage, $internalPath) {
  		$cache = $storage->getCache();
  		$parentId = $cache->getParentId($internalPath);
  		$parent = dirname($internalPath);
  		if ($parentId != -1) {
  			$cache->update($parentId, array('storage_mtime' => $storage->filemtime($parent)));
03e52840d   Kload   Init
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  		}
  	}
  
  	/**
  	 * @param array $params
  	 */
  	static public function writeHook($params) {
  		self::writeUpdate($params['path']);
  	}
  
  	/**
  	 * @param array $params
  	 */
  	static public function touchHook($params) {
  		$path = $params['path'];
  		list($storage, $internalPath) = self::resolvePath($path);
  		$cache = $storage->getCache();
  		$id = $cache->getId($internalPath);
  		if ($id !== -1) {
  			$cache->update($id, array('etag' => $storage->getETag($internalPath)));
  		}
  		self::writeUpdate($path);
  	}
  
  	/**
  	 * @param array $params
  	 */
  	static public function renameHook($params) {
  		self::renameUpdate($params['oldpath'], $params['newpath']);
  	}
  
  	/**
  	 * @param array $params
  	 */
  	static public function deleteHook($params) {
  		self::deleteUpdate($params['path']);
  	}
  }