Signed-off-by: Robin Appelman <robin@icewind.nl>tags/v12.0.0beta1
@@ -42,6 +42,7 @@ require_once 'aws-autoloader.php'; | |||
use Aws\S3\S3Client; | |||
use Aws\S3\Exception\S3Exception; | |||
use Icewind\Streams\CallbackWrapper; | |||
use Icewind\Streams\IteratorDirectory; | |||
use OC\Files\ObjectStore\S3ConnectionTrait; | |||
@@ -366,14 +367,15 @@ class AmazonS3 extends \OC\Files\Storage\Common { | |||
$ext = ''; | |||
} | |||
$tmpFile = \OCP\Files::tmpFile($ext); | |||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); | |||
if ($this->file_exists($path)) { | |||
$source = $this->fopen($path, 'r'); | |||
file_put_contents($tmpFile, $source); | |||
} | |||
self::$tmpFiles[$tmpFile] = $path; | |||
return fopen('close://' . $tmpFile, $mode); | |||
$handle = fopen($tmpFile, $mode); | |||
return CallbackWrapper::wrap($handle, null, null, function() use ($path, $tmpFile) { | |||
$this->writeBack($tmpFile, $path); | |||
}); | |||
} | |||
return false; | |||
} | |||
@@ -514,15 +516,11 @@ class AmazonS3 extends \OC\Files\Storage\Common { | |||
return $this->id; | |||
} | |||
public function writeBack($tmpFile) { | |||
if (!isset(self::$tmpFiles[$tmpFile])) { | |||
return false; | |||
} | |||
public function writeBack($tmpFile, $path) { | |||
try { | |||
$this->getConnection()->putObject(array( | |||
'Bucket' => $this->bucket, | |||
'Key' => $this->cleanKey(self::$tmpFiles[$tmpFile]), | |||
'Key' => $this->cleanKey($path), | |||
'SourceFile' => $tmpFile, | |||
'ContentType' => \OC::$server->getMimeTypeDetector()->detect($tmpFile), | |||
'ContentLength' => filesize($tmpFile) |
@@ -31,6 +31,7 @@ | |||
namespace OCA\Files_External\Lib\Storage; | |||
use GuzzleHttp\Exception\RequestException; | |||
use Icewind\Streams\CallbackWrapper; | |||
use Icewind\Streams\IteratorDirectory; | |||
use Icewind\Streams\RetryWrapper; | |||
use OCP\Files\StorageNotAvailableException; | |||
@@ -45,8 +46,6 @@ class Dropbox extends \OC\Files\Storage\Common { | |||
private $metaData = array(); | |||
private $oauth; | |||
private static $tempFiles = array(); | |||
public function __construct($params) { | |||
if (isset($params['configured']) && $params['configured'] == 'true' | |||
&& isset($params['app_key']) | |||
@@ -305,27 +304,26 @@ class Dropbox extends \OC\Files\Storage\Common { | |||
$ext = ''; | |||
} | |||
$tmpFile = \OCP\Files::tmpFile($ext); | |||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); | |||
if ($this->file_exists($path)) { | |||
$source = $this->fopen($path, 'r'); | |||
file_put_contents($tmpFile, $source); | |||
} | |||
self::$tempFiles[$tmpFile] = $path; | |||
return fopen('close://'.$tmpFile, $mode); | |||
$handle = fopen($tmpFile, $mode); | |||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { | |||
$this->writeBack($tmpFile, $path); | |||
}); | |||
} | |||
return false; | |||
} | |||
public function writeBack($tmpFile) { | |||
if (isset(self::$tempFiles[$tmpFile])) { | |||
$handle = fopen($tmpFile, 'r'); | |||
try { | |||
$this->dropbox->putFile(self::$tempFiles[$tmpFile], $handle); | |||
unlink($tmpFile); | |||
$this->deleteMetaData(self::$tempFiles[$tmpFile]); | |||
} catch (\Exception $exception) { | |||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR); | |||
} | |||
public function writeBack($tmpFile, $path) { | |||
$handle = fopen($tmpFile, 'r'); | |||
try { | |||
$this->dropbox->putFile($path, $handle); | |||
unlink($tmpFile); | |||
$this->deleteMetaData($path); | |||
} catch (\Exception $exception) { | |||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR); | |||
} | |||
} | |||
@@ -33,6 +33,7 @@ | |||
namespace OCA\Files_External\Lib\Storage; | |||
use Icewind\Streams\CallbackWrapper; | |||
use Icewind\Streams\RetryWrapper; | |||
class FTP extends StreamWrapper{ | |||
@@ -127,21 +128,20 @@ class FTP extends StreamWrapper{ | |||
$ext=''; | |||
} | |||
$tmpFile=\OCP\Files::tmpFile($ext); | |||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); | |||
if ($this->file_exists($path)) { | |||
$this->getFile($path, $tmpFile); | |||
} | |||
self::$tempFiles[$tmpFile]=$path; | |||
return fopen('close://'.$tmpFile, $mode); | |||
$handle = fopen($tmpFile, $mode); | |||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { | |||
$this->writeBack($tmpFile, $path); | |||
}); | |||
} | |||
return false; | |||
} | |||
public function writeBack($tmpFile) { | |||
if (isset(self::$tempFiles[$tmpFile])) { | |||
$this->uploadFile($tmpFile, self::$tempFiles[$tmpFile]); | |||
unlink($tmpFile); | |||
} | |||
public function writeBack($tmpFile, $path) { | |||
$this->uploadFile($tmpFile, $path); | |||
unlink($tmpFile); | |||
} | |||
/** |
@@ -36,6 +36,7 @@ | |||
namespace OCA\Files_External\Lib\Storage; | |||
use GuzzleHttp\Exception\RequestException; | |||
use Icewind\Streams\CallbackWrapper; | |||
use Icewind\Streams\IteratorDirectory; | |||
use Icewind\Streams\RetryWrapper; | |||
@@ -50,8 +51,6 @@ class Google extends \OC\Files\Storage\Common { | |||
private $service; | |||
private $driveFiles; | |||
private static $tempFiles = array(); | |||
// Google Doc mimetypes | |||
const FOLDER = 'application/vnd.google-apps.folder'; | |||
const DOCUMENT = 'application/vnd.google-apps.document'; | |||
@@ -495,94 +494,91 @@ class Google extends \OC\Files\Storage\Common { | |||
case 'c': | |||
case 'c+': | |||
$tmpFile = \OCP\Files::tmpFile($ext); | |||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); | |||
if ($this->file_exists($path)) { | |||
$source = $this->fopen($path, 'rb'); | |||
file_put_contents($tmpFile, $source); | |||
} | |||
self::$tempFiles[$tmpFile] = $path; | |||
return fopen('close://'.$tmpFile, $mode); | |||
$handle = fopen($tmpFile, $mode); | |||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { | |||
$this->writeBack($tmpFile, $path); | |||
}); | |||
} | |||
} | |||
public function writeBack($tmpFile) { | |||
if (isset(self::$tempFiles[$tmpFile])) { | |||
$path = self::$tempFiles[$tmpFile]; | |||
$parentFolder = $this->getDriveFile(dirname($path)); | |||
if ($parentFolder) { | |||
$mimetype = \OC::$server->getMimeTypeDetector()->detect($tmpFile); | |||
$params = array( | |||
'mimeType' => $mimetype, | |||
'uploadType' => 'media' | |||
); | |||
$result = false; | |||
public function writeBack($tmpFile, $path) { | |||
$parentFolder = $this->getDriveFile(dirname($path)); | |||
if ($parentFolder) { | |||
$mimetype = \OC::$server->getMimeTypeDetector()->detect($tmpFile); | |||
$params = array( | |||
'mimeType' => $mimetype, | |||
'uploadType' => 'media' | |||
); | |||
$result = false; | |||
$chunkSizeBytes = 10 * 1024 * 1024; | |||
$useChunking = false; | |||
$size = filesize($tmpFile); | |||
if ($size > $chunkSizeBytes) { | |||
$useChunking = true; | |||
} else { | |||
$params['data'] = file_get_contents($tmpFile); | |||
} | |||
$chunkSizeBytes = 10 * 1024 * 1024; | |||
if ($this->file_exists($path)) { | |||
$file = $this->getDriveFile($path); | |||
$this->client->setDefer($useChunking); | |||
$request = $this->service->files->update($file->getId(), $file, $params); | |||
} else { | |||
$file = new \Google_Service_Drive_DriveFile(); | |||
$file->setTitle(basename($path)); | |||
$file->setMimeType($mimetype); | |||
$parent = new \Google_Service_Drive_ParentReference(); | |||
$parent->setId($parentFolder->getId()); | |||
$file->setParents(array($parent)); | |||
$this->client->setDefer($useChunking); | |||
$request = $this->service->files->insert($file, $params); | |||
} | |||
$useChunking = false; | |||
$size = filesize($tmpFile); | |||
if ($size > $chunkSizeBytes) { | |||
$useChunking = true; | |||
} else { | |||
$params['data'] = file_get_contents($tmpFile); | |||
if ($useChunking) { | |||
// Create a media file upload to represent our upload process. | |||
$media = new \Google_Http_MediaFileUpload( | |||
$this->client, | |||
$request, | |||
'text/plain', | |||
null, | |||
true, | |||
$chunkSizeBytes | |||
); | |||
$media->setFileSize($size); | |||
// Upload the various chunks. $status will be false until the process is | |||
// complete. | |||
$status = false; | |||
$handle = fopen($tmpFile, 'rb'); | |||
while (!$status && !feof($handle)) { | |||
$chunk = fread($handle, $chunkSizeBytes); | |||
$status = $media->nextChunk($chunk); | |||
} | |||
if ($this->file_exists($path)) { | |||
$file = $this->getDriveFile($path); | |||
$this->client->setDefer($useChunking); | |||
$request = $this->service->files->update($file->getId(), $file, $params); | |||
} else { | |||
$file = new \Google_Service_Drive_DriveFile(); | |||
$file->setTitle(basename($path)); | |||
$file->setMimeType($mimetype); | |||
$parent = new \Google_Service_Drive_ParentReference(); | |||
$parent->setId($parentFolder->getId()); | |||
$file->setParents(array($parent)); | |||
$this->client->setDefer($useChunking); | |||
$request = $this->service->files->insert($file, $params); | |||
// The final value of $status will be the data from the API for the object | |||
// that has been uploaded. | |||
$result = false; | |||
if ($status !== false) { | |||
$result = $status; | |||
} | |||
if ($useChunking) { | |||
// Create a media file upload to represent our upload process. | |||
$media = new \Google_Http_MediaFileUpload( | |||
$this->client, | |||
$request, | |||
'text/plain', | |||
null, | |||
true, | |||
$chunkSizeBytes | |||
); | |||
$media->setFileSize($size); | |||
// Upload the various chunks. $status will be false until the process is | |||
// complete. | |||
$status = false; | |||
$handle = fopen($tmpFile, 'rb'); | |||
while (!$status && !feof($handle)) { | |||
$chunk = fread($handle, $chunkSizeBytes); | |||
$status = $media->nextChunk($chunk); | |||
} | |||
// The final value of $status will be the data from the API for the object | |||
// that has been uploaded. | |||
$result = false; | |||
if ($status !== false) { | |||
$result = $status; | |||
} | |||
fclose($handle); | |||
} else { | |||
$result = $request; | |||
} | |||
fclose($handle); | |||
} else { | |||
$result = $request; | |||
} | |||
// Reset to the client to execute requests immediately in the future. | |||
$this->client->setDefer(false); | |||
// Reset to the client to execute requests immediately in the future. | |||
$this->client->setDefer(false); | |||
if ($result) { | |||
$this->setDriveFile($path, $result); | |||
} | |||
if ($result) { | |||
$this->setDriveFile($path, $result); | |||
} | |||
unlink($tmpFile); | |||
} | |||
} | |||
@@ -37,6 +37,7 @@ namespace OCA\Files_External\Lib\Storage; | |||
use Guzzle\Http\Url; | |||
use Guzzle\Http\Exception\ClientErrorResponseException; | |||
use Icewind\Streams\CallbackWrapper; | |||
use Icewind\Streams\IteratorDirectory; | |||
use OpenCloud; | |||
use OpenCloud\Common\Exceptions; | |||
@@ -410,7 +411,6 @@ class Swift extends \OC\Files\Storage\Common { | |||
$ext = ''; | |||
} | |||
$tmpFile = \OCP\Files::tmpFile($ext); | |||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); | |||
// Fetch existing file if required | |||
if ($mode[0] !== 'w' && $this->file_exists($path)) { | |||
if ($mode[0] === 'x') { | |||
@@ -424,9 +424,10 @@ class Swift extends \OC\Files\Storage\Common { | |||
fseek($tmpFile, 0, SEEK_END); | |||
} | |||
} | |||
self::$tmpFiles[$tmpFile] = $path; | |||
return fopen('close://' . $tmpFile, $mode); | |||
$handle = fopen($tmpFile, $mode); | |||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { | |||
$this->writeBack($tmpFile, $path); | |||
}); | |||
} | |||
} | |||
@@ -615,12 +616,9 @@ class Swift extends \OC\Files\Storage\Common { | |||
return $this->container; | |||
} | |||
public function writeBack($tmpFile) { | |||
if (!isset(self::$tmpFiles[$tmpFile])) { | |||
return false; | |||
} | |||
public function writeBack($tmpFile, $path) { | |||
$fileData = fopen($tmpFile, 'r'); | |||
$this->getContainer()->uploadObject(self::$tmpFiles[$tmpFile], $fileData); | |||
$this->getContainer()->uploadObject($path, $fileData); | |||
// invalidate target object to force repopulation on fetch | |||
$this->objectCache->remove(self::$tmpFiles[$tmpFile]); | |||
unlink($tmpFile); |
@@ -669,9 +669,6 @@ class OC { | |||
OC\Log\ErrorHandler::register($debug); | |||
} | |||
// register the stream wrappers | |||
stream_wrapper_register('close', 'OC\Files\Stream\Close'); | |||
\OC::$server->getEventLogger()->start('init_session', 'Initialize session'); | |||
OC_App::loadApps(array('session')); | |||
if (!self::$CLI) { |
@@ -33,6 +33,8 @@ | |||
namespace OC\Archive; | |||
use Icewind\Streams\CallbackWrapper; | |||
class TAR extends Archive { | |||
const PLAIN = 0; | |||
const GZIP = 1; | |||
@@ -359,22 +361,19 @@ class TAR extends Archive { | |||
if ($mode == 'r' or $mode == 'rb') { | |||
return fopen($tmpFile, $mode); | |||
} else { | |||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); | |||
self::$tempFiles[$tmpFile] = $path; | |||
return fopen('close://' . $tmpFile, $mode); | |||
$handle = fopen($tmpFile, $mode); | |||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { | |||
$this->writeBack($tmpFile, $path); | |||
}); | |||
} | |||
} | |||
private static $tempFiles = array(); | |||
/** | |||
* write back temporary files | |||
*/ | |||
function writeBack($tmpFile) { | |||
if (isset(self::$tempFiles[$tmpFile])) { | |||
$this->addFile(self::$tempFiles[$tmpFile], $tmpFile); | |||
unlink($tmpFile); | |||
} | |||
function writeBack($tmpFile, $path) { | |||
$this->addFile($path, $tmpFile); | |||
unlink($tmpFile); | |||
} | |||
/** |
@@ -31,6 +31,8 @@ | |||
namespace OC\Archive; | |||
use Icewind\Streams\CallbackWrapper; | |||
class ZIP extends Archive{ | |||
/** | |||
* @var \ZipArchive zip | |||
@@ -198,24 +200,22 @@ class ZIP extends Archive{ | |||
$ext=''; | |||
} | |||
$tmpFile=\OCP\Files::tmpFile($ext); | |||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); | |||
if($this->fileExists($path)) { | |||
$this->extractFile($path, $tmpFile); | |||
} | |||
self::$tempFiles[$tmpFile]=$path; | |||
return fopen('close://'.$tmpFile, $mode); | |||
$handle = fopen($tmpFile, $mode); | |||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { | |||
$this->writeBack($tmpFile, $path); | |||
}); | |||
} | |||
} | |||
private static $tempFiles=array(); | |||
/** | |||
* write back temporary files | |||
*/ | |||
function writeBack($tmpFile) { | |||
if(isset(self::$tempFiles[$tmpFile])) { | |||
$this->addFile(self::$tempFiles[$tmpFile], $tmpFile); | |||
unlink($tmpFile); | |||
} | |||
function writeBack($tmpFile, $path) { | |||
$this->addFile($path, $tmpFile); | |||
unlink($tmpFile); | |||
} | |||
/** |
@@ -25,16 +25,12 @@ | |||
namespace OC\Files\ObjectStore; | |||
use Icewind\Streams\CallbackWrapper; | |||
use Icewind\Streams\IteratorDirectory; | |||
use OC\Files\Cache\CacheEntry; | |||
use OCP\Files\ObjectStore\IObjectStore; | |||
class ObjectStoreStorage extends \OC\Files\Storage\Common { | |||
/** | |||
* @var array | |||
*/ | |||
private static $tmpFiles = array(); | |||
/** | |||
* @var \OCP\Files\ObjectStore\IObjectStore $objectStore | |||
*/ | |||
@@ -291,14 +287,14 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { | |||
$ext = ''; | |||
} | |||
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext); | |||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); | |||
if ($this->file_exists($path)) { | |||
$source = $this->fopen($path, 'r'); | |||
file_put_contents($tmpFile, $source); | |||
} | |||
self::$tmpFiles[$tmpFile] = $path; | |||
return fopen('close://' . $tmpFile, $mode); | |||
$handle = fopen($tmpFile, $mode); | |||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { | |||
$this->writeBack($tmpFile, $path); | |||
}); | |||
} | |||
return false; | |||
} | |||
@@ -368,12 +364,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { | |||
return true; | |||
} | |||
public function writeBack($tmpFile) { | |||
if (!isset(self::$tmpFiles[$tmpFile])) { | |||
return; | |||
} | |||
$path = self::$tmpFiles[$tmpFile]; | |||
public function writeBack($tmpFile, $path) { | |||
$stat = $this->stat($path); | |||
if (empty($stat)) { | |||
// create new file |
@@ -36,6 +36,7 @@ namespace OC\Files\Storage; | |||
use Exception; | |||
use GuzzleHttp\Exception\RequestException; | |||
use GuzzleHttp\Message\ResponseInterface; | |||
use Icewind\Streams\CallbackWrapper; | |||
use OC\Files\Filesystem; | |||
use OC\Files\Stream\Close; | |||
use Icewind\Streams\IteratorDirectory; | |||
@@ -77,8 +78,6 @@ class DAV extends Common { | |||
private $client; | |||
/** @var ArrayCache */ | |||
private $statCache; | |||
/** @var array */ | |||
private static $tempFiles = []; | |||
/** @var \OCP\Http\Client\IClientService */ | |||
private $httpClientService; | |||
@@ -409,20 +408,19 @@ class DAV extends Common { | |||
} | |||
$tmpFile = $tempManager->getTemporaryFile($ext); | |||
} | |||
Close::registerCallback($tmpFile, array($this, 'writeBack')); | |||
self::$tempFiles[$tmpFile] = $path; | |||
return fopen('close://' . $tmpFile, $mode); | |||
$handle = fopen($tmpFile, $mode); | |||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { | |||
$this->writeBack($tmpFile, $path); | |||
}); | |||
} | |||
} | |||
/** | |||
* @param string $tmpFile | |||
*/ | |||
public function writeBack($tmpFile) { | |||
if (isset(self::$tempFiles[$tmpFile])) { | |||
$this->uploadFile($tmpFile, self::$tempFiles[$tmpFile]); | |||
unlink($tmpFile); | |||
} | |||
public function writeBack($tmpFile, $path) { | |||
$this->uploadFile($tmpFile, $path); | |||
unlink($tmpFile); | |||
} | |||
/** {@inheritdoc} */ |
@@ -1,119 +0,0 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* | |||
* @author Jörn Friedrich Dreyer <jfd@butonic.de> | |||
* @author Morris Jobke <hey@morrisjobke.de> | |||
* @author Robin Appelman <robin@icewind.nl> | |||
* | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OC\Files\Stream; | |||
/** | |||
* stream wrapper that provides a callback on stream close | |||
*/ | |||
class Close { | |||
private static $callBacks = array(); | |||
private $path = ''; | |||
private $source; | |||
private static $open = array(); | |||
public function stream_open($path, $mode, $options, &$opened_path) { | |||
$path = substr($path, strlen('close://')); | |||
$this->path = $path; | |||
$this->source = fopen($path, $mode); | |||
if (is_resource($this->source)) { | |||
$this->meta = stream_get_meta_data($this->source); | |||
} | |||
self::$open[] = $path; | |||
return is_resource($this->source); | |||
} | |||
public function stream_seek($offset, $whence = SEEK_SET) { | |||
return fseek($this->source, $offset, $whence) === 0; | |||
} | |||
public function stream_tell() { | |||
return ftell($this->source); | |||
} | |||
public function stream_read($count) { | |||
return fread($this->source, $count); | |||
} | |||
public function stream_write($data) { | |||
return fwrite($this->source, $data); | |||
} | |||
public function stream_set_option($option, $arg1, $arg2) { | |||
switch ($option) { | |||
case STREAM_OPTION_BLOCKING: | |||
stream_set_blocking($this->source, $arg1); | |||
break; | |||
case STREAM_OPTION_READ_TIMEOUT: | |||
stream_set_timeout($this->source, $arg1, $arg2); | |||
break; | |||
case STREAM_OPTION_WRITE_BUFFER: | |||
stream_set_write_buffer($this->source, $arg1, $arg2); | |||
} | |||
} | |||
public function stream_stat() { | |||
return fstat($this->source); | |||
} | |||
public function stream_lock($mode) { | |||
flock($this->source, $mode); | |||
} | |||
public function stream_flush() { | |||
return fflush($this->source); | |||
} | |||
public function stream_eof() { | |||
return feof($this->source); | |||
} | |||
public function url_stat($path) { | |||
$path = substr($path, strlen('close://')); | |||
if (file_exists($path)) { | |||
return stat($path); | |||
} else { | |||
return false; | |||
} | |||
} | |||
public function stream_close() { | |||
fclose($this->source); | |||
if (isset(self::$callBacks[$this->path])) { | |||
call_user_func(self::$callBacks[$this->path], $this->path); | |||
} | |||
} | |||
public function unlink($path) { | |||
$path = substr($path, strlen('close://')); | |||
return unlink($path); | |||
} | |||
/** | |||
* @param string $path | |||
*/ | |||
public static function registerCallback($path, $callback) { | |||
self::$callBacks[$path] = $callback; | |||
} | |||
} |
@@ -1,68 +0,0 @@ | |||
<?php | |||
/** | |||
* ownCloud | |||
* | |||
* @author Robin Appelman | |||
* @copyright 2012 Robin Appelman icewind@owncloud.com | |||
* | |||
* This library is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or any later version. | |||
* | |||
* This library is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public | |||
* License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
namespace Test; | |||
/** | |||
* Class StreamWrappersTest | |||
* | |||
* @group DB | |||
*/ | |||
class StreamWrappersTest extends \Test\TestCase { | |||
private static $trashBinStatus; | |||
public static function setUpBeforeClass() { | |||
self::$trashBinStatus = \OC_App::isEnabled('files_trashbin'); | |||
\OC_App::disable('files_trashbin'); | |||
} | |||
public static function tearDownAfterClass() { | |||
if (self::$trashBinStatus) { | |||
(new \OC_App())->enable('files_trashbin'); | |||
} | |||
} | |||
public function testCloseStream() { | |||
//ensure all basic stream stuff works | |||
$sourceFile = \OC::$SERVERROOT . '/tests/data/lorem.txt'; | |||
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile('.txt'); | |||
$file = 'close://' . $tmpFile; | |||
$this->assertTrue(file_exists($file)); | |||
file_put_contents($file, file_get_contents($sourceFile)); | |||
$this->assertEquals(file_get_contents($sourceFile), file_get_contents($file)); | |||
unlink($file); | |||
clearstatcache(); | |||
$this->assertFalse(file_exists($file)); | |||
//test callback | |||
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile('.txt'); | |||
$file = 'close://' . $tmpFile; | |||
$actual = false; | |||
$callback = function($path) use (&$actual) { $actual = $path; }; | |||
\OC\Files\Stream\Close::registerCallback($tmpFile, $callback); | |||
$fh = fopen($file, 'w'); | |||
fwrite($fh, 'asd'); | |||
fclose($fh); | |||
$this->assertSame($tmpFile, $actual); | |||
} | |||
} |