update.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <?php
  2. /**
  3. * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. /**
  9. * handles updating the filecache according to outside changes
  10. */
  11. class OC_FileCache_Update{
  12. /**
  13. * check if a file or folder is updated outside owncloud
  14. * @param string path
  15. * @param string root (optional)
  16. * @param boolean folder
  17. * @return bool
  18. */
  19. public static function hasUpdated($path,$root=false,$folder=false){
  20. if($root===false){
  21. $view=OC_Filesystem::getView();
  22. }else{
  23. $view=new OC_FilesystemView($root);
  24. }
  25. if(!$view->file_exists($path)){
  26. return false;
  27. }
  28. $cachedData=OC_FileCache_Cached::get($path,$root);
  29. if(isset($cachedData['mtime'])){
  30. $cachedMTime=$cachedData['mtime'];
  31. if($folder){
  32. return $view->hasUpdated($path.'/',$cachedMTime);
  33. }else{
  34. return $view->hasUpdated($path,$cachedMTime);
  35. }
  36. }else{//file not in cache, so it has to be updated
  37. if(($path=='/' or $path=='') and $root===false){//dont auto update the home folder, it will be scanned
  38. return false;
  39. }
  40. return true;
  41. }
  42. }
  43. /**
  44. * delete non existing files from the cache
  45. */
  46. public static function cleanFolder($path,$root=false){
  47. if($root===false){
  48. $view=OC_Filesystem::getView();
  49. }else{
  50. $view=new OC_FilesystemView($root);
  51. }
  52. $cachedContent=OC_FileCache_Cached::getFolderContent($path,$root);
  53. foreach($cachedContent as $fileData){
  54. $path=$fileData['path'];
  55. $file=$view->getRelativePath($path);
  56. if(!$view->file_exists($file)){
  57. if($root===false){//filesystem hooks are only valid for the default root
  58. OC_Hook::emit('OC_Filesystem','post_delete',array('path'=>$file));
  59. }else{
  60. self::delete($file,$root);
  61. }
  62. }
  63. }
  64. }
  65. /**
  66. * update the cache according to changes in the folder
  67. * @param string path
  68. * @param string root (optional)
  69. */
  70. public static function updateFolder($path,$root=false){
  71. if($root===false){
  72. $view=OC_Filesystem::getView();
  73. }else{
  74. $view=new OC_FilesystemView($root);
  75. }
  76. $dh=$view->opendir($path.'/');
  77. if($dh){//check for changed/new files
  78. while (($filename = readdir($dh)) !== false) {
  79. if($filename != '.' and $filename != '..'){
  80. $file=$path.'/'.$filename;
  81. if(self::hasUpdated($file,$root)){
  82. if($root===false){//filesystem hooks are only valid for the default root
  83. OC_Hook::emit('OC_Filesystem','post_write',array('path'=>$file));
  84. }else{
  85. self::update($file,$root);
  86. }
  87. }
  88. }
  89. }
  90. }
  91. self::cleanFolder($path,$root);
  92. //update the folder last, so we can calculate the size correctly
  93. if($root===false){//filesystem hooks are only valid for the default root
  94. OC_Hook::emit('OC_Filesystem','post_write',array('path'=>$path));
  95. }else{
  96. self::update($path,$root);
  97. }
  98. }
  99. /**
  100. * called when changes are made to files
  101. * @param array $params
  102. * @param string root (optional)
  103. */
  104. public static function fileSystemWatcherWrite($params){
  105. $path=$params['path'];
  106. self::update($path);
  107. }
  108. /**
  109. * called when files are deleted
  110. * @param array $params
  111. * @param string root (optional)
  112. */
  113. public static function fileSystemWatcherDelete($params){
  114. $path=$params['path'];
  115. self::delete($path);
  116. }
  117. /**
  118. * called when files are deleted
  119. * @param array $params
  120. * @param string root (optional)
  121. */
  122. public static function fileSystemWatcherRename($params){
  123. $oldPath=$params['oldpath'];
  124. $newPath=$params['newpath'];
  125. self::rename($oldPath,$newPath);
  126. }
  127. /**
  128. * update the filecache according to changes to the fileysystem
  129. * @param string path
  130. * @param string root (optional)
  131. */
  132. public static function update($path,$root=false){
  133. if($root===false){
  134. $view=OC_Filesystem::getView();
  135. }else{
  136. $view=new OC_FilesystemView($root);
  137. }
  138. $mimetype=$view->getMimeType($path);
  139. $size=0;
  140. $cached=OC_FileCache_Cached::get($path,$root);
  141. $cachedSize=isset($cached['size'])?$cached['size']:0;
  142. if($mimetype=='httpd/unix-directory'){
  143. if(OC_FileCache::inCache($path,$root)){
  144. $cachedContent=OC_FileCache_Cached::getFolderContent($path,$root);
  145. foreach($cachedContent as $file){
  146. $size+=$file['size'];
  147. }
  148. $mtime=$view->filemtime($path.'/');
  149. $ctime=$view->filectime($path.'/');
  150. $writable=$view->is_writable($path.'/');
  151. OC_FileCache::put($path,array('size'=>$size,'mtime'=>$mtime,'ctime'=>$ctime,'mimetype'=>$mimetype,'writable'=>$writable));
  152. }else{
  153. $count=0;
  154. OC_FileCache::scan($path,null,$count,$root);
  155. return; //increaseSize is already called inside scan
  156. }
  157. }else{
  158. $size=OC_FileCache::scanFile($path,$root);
  159. }
  160. OC_FileCache::increaseSize(dirname($path),$size-$cachedSize,$root);
  161. }
  162. /**
  163. * update the filesystem after a delete has been detected
  164. * @param string path
  165. * @param string root (optional)
  166. */
  167. public static function delete($path,$root=false){
  168. $cached=OC_FileCache_Cached::get($path,$root);
  169. if(!isset($cached['size'])){
  170. return;
  171. }
  172. $size=$cached['size'];
  173. OC_FileCache::increaseSize(dirname($path),-$size,$root);
  174. OC_FileCache::delete($path,$root);
  175. }
  176. /**
  177. * update the filesystem after a rename has been detected
  178. * @param string oldPath
  179. * @param string newPath
  180. * @param string root (optional)
  181. */
  182. public static function rename($oldPath,$newPath,$root=false){
  183. if(!OC_FileCache::inCache($oldPath,$root)){
  184. return;
  185. }
  186. if($root===false){
  187. $view=OC_Filesystem::getView();
  188. }else{
  189. $view=new OC_FilesystemView($root);
  190. }
  191. $cached=OC_FileCache_Cached::get($oldPath,$root);
  192. $oldSize=$cached['size'];
  193. $size=$view->filesize($newPath);
  194. OC_FileCache::increaseSize(dirname($oldPath),-$oldSize,$root);
  195. OC_FileCache::increaseSize(dirname($newPath),$oldSize,$root);
  196. OC_FileCache::move($oldPath,$newPath);
  197. }
  198. }