nextcloud/lib/filecache/update.php

214 lines
5.7 KiB
PHP

<?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.
*/
/**
* handles updating the filecache according to outside changes
*/
class OC_FileCache_Update{
/**
* check if a file or folder is updated outside owncloud
* @param string path
* @param string root (optional)
* @param boolean folder
* @return bool
*/
public static function hasUpdated($path,$root=false,$folder=false) {
if($root===false) {
$view=OC_Filesystem::getView();
}else{
$view=new OC_FilesystemView($root);
}
if(!$view->file_exists($path)) {
return false;
}
$cachedData=OC_FileCache_Cached::get($path,$root);
if(isset($cachedData['mtime'])) {
$cachedMTime=$cachedData['mtime'];
if($folder) {
return $view->hasUpdated($path.'/',$cachedMTime);
}else{
return $view->hasUpdated($path,$cachedMTime);
}
}else{//file not in cache, so it has to be updated
if(($path=='/' or $path=='') and $root===false) {//dont auto update the home folder, it will be scanned
return false;
}
return true;
}
}
/**
* delete non existing files from the cache
*/
public static function cleanFolder($path,$root=false) {
if($root===false) {
$view=OC_Filesystem::getView();
}else{
$view=new OC_FilesystemView($root);
}
$cachedContent=OC_FileCache_Cached::getFolderContent($path,$root);
foreach($cachedContent as $fileData) {
$path=$fileData['path'];
$file=$view->getRelativePath($path);
if(!$view->file_exists($file)) {
if($root===false) {//filesystem hooks are only valid for the default root
OC_Hook::emit('OC_Filesystem','post_delete',array('path'=>$file));
}else{
self::delete($file,$root);
}
}
}
}
/**
* update the cache according to changes in the folder
* @param string path
* @param string root (optional)
*/
public static function updateFolder($path,$root=false) {
if($root===false) {
$view=OC_Filesystem::getView();
}else{
$view=new OC_FilesystemView($root);
}
$dh=$view->opendir($path.'/');
if($dh) {//check for changed/new files
while (($filename = readdir($dh)) !== false) {
if($filename != '.' and $filename != '..') {
$file=$path.'/'.$filename;
if(self::hasUpdated($file,$root)) {
if($root===false) {//filesystem hooks are only valid for the default root
OC_Hook::emit('OC_Filesystem','post_write',array('path'=>$file));
}else{
self::update($file,$root);
}
}
}
}
}
self::cleanFolder($path,$root);
//update the folder last, so we can calculate the size correctly
if($root===false) {//filesystem hooks are only valid for the default root
OC_Hook::emit('OC_Filesystem','post_write',array('path'=>$path));
}else{
self::update($path,$root);
}
}
/**
* called when changes are made to files
* @param array $params
* @param string root (optional)
*/
public static function fileSystemWatcherWrite($params) {
$path=$params['path'];
self::update($path);
}
/**
* called when files are deleted
* @param array $params
* @param string root (optional)
*/
public static function fileSystemWatcherDelete($params) {
$path=$params['path'];
self::delete($path);
}
/**
* called when files are deleted
* @param array $params
* @param string root (optional)
*/
public static function fileSystemWatcherRename($params) {
$oldPath=$params['oldpath'];
$newPath=$params['newpath'];
self::rename($oldPath,$newPath);
}
/**
* update the filecache according to changes to the fileysystem
* @param string path
* @param string root (optional)
*/
public static function update($path,$root=false) {
if($root===false) {
$view=OC_Filesystem::getView();
}else{
$view=new OC_FilesystemView($root);
}
$mimetype=$view->getMimeType($path);
$size=0;
$cached=OC_FileCache_Cached::get($path,$root);
$cachedSize=isset($cached['size'])?$cached['size']:0;
if($view->is_dir($path.'/')) {
if(OC_FileCache::inCache($path,$root)) {
$cachedContent=OC_FileCache_Cached::getFolderContent($path,$root);
foreach($cachedContent as $file) {
$size+=$file['size'];
}
$mtime=$view->filemtime($path.'/');
$ctime=$view->filectime($path.'/');
$writable=$view->is_writable($path.'/');
OC_FileCache::put($path,array('size'=>$size,'mtime'=>$mtime,'ctime'=>$ctime,'mimetype'=>$mimetype,'writable'=>$writable));
}else{
$count=0;
OC_FileCache::scan($path,null,$count,$root);
return; //increaseSize is already called inside scan
}
}else{
$size=OC_FileCache::scanFile($path,$root);
}
OC_FileCache::increaseSize(dirname($path),$size-$cachedSize,$root);
}
/**
* update the filesystem after a delete has been detected
* @param string path
* @param string root (optional)
*/
public static function delete($path,$root=false) {
$cached=OC_FileCache_Cached::get($path,$root);
if(!isset($cached['size'])) {
return;
}
$size=$cached['size'];
OC_FileCache::increaseSize(dirname($path),-$size,$root);
OC_FileCache::delete($path,$root);
}
/**
* update the filesystem after a rename has been detected
* @param string oldPath
* @param string newPath
* @param string root (optional)
*/
public static function rename($oldPath,$newPath,$root=false) {
if(!OC_FileCache::inCache($oldPath,$root)) {
return;
}
if($root===false) {
$view=OC_Filesystem::getView();
}else{
$view=new OC_FilesystemView($root);
}
$cached=OC_FileCache_Cached::get($oldPath,$root);
$oldSize=$cached['size'];
OC_FileCache::increaseSize(dirname($oldPath),-$oldSize,$root);
OC_FileCache::increaseSize(dirname($newPath),$oldSize,$root);
OC_FileCache::move($oldPath,$newPath);
}
}