Laravel version update
Laravel version update
This commit is contained in:
31
vendor/flowjs/flow-php-server/src/Flow/Mongo/MongoConfig.php
vendored
Normal file
31
vendor/flowjs/flow-php-server/src/Flow/Mongo/MongoConfig.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Flow\Mongo;
|
||||
|
||||
use Flow\Config;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class MongoConfig extends Config implements MongoConfigInterface
|
||||
{
|
||||
private $gridFs;
|
||||
|
||||
/**
|
||||
* @param \MongoGridFS $gridFS storage of the upload (and chunks)
|
||||
*/
|
||||
function __construct(\MongoGridFS $gridFS)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->gridFs = $gridFS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return \MongoGridFS
|
||||
*/
|
||||
public function getGridFs()
|
||||
{
|
||||
return $this->gridFs;
|
||||
}
|
||||
}
|
18
vendor/flowjs/flow-php-server/src/Flow/Mongo/MongoConfigInterface.php
vendored
Normal file
18
vendor/flowjs/flow-php-server/src/Flow/Mongo/MongoConfigInterface.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Flow\Mongo;
|
||||
|
||||
use Flow\ConfigInterface;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface MongoConfigInterface extends ConfigInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \MongoGridFS
|
||||
*/
|
||||
public function getGridFs();
|
||||
|
||||
}
|
181
vendor/flowjs/flow-php-server/src/Flow/Mongo/MongoFile.php
vendored
Normal file
181
vendor/flowjs/flow-php-server/src/Flow/Mongo/MongoFile.php
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
namespace Flow\Mongo;
|
||||
|
||||
use Flow\File;
|
||||
use Flow\Request;
|
||||
use Flow\RequestInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Notes:
|
||||
*
|
||||
* - One should ensure indices on the gridfs collection on the property 'flowIdentifier'.
|
||||
* - Chunk preprocessor not supported (must not modify chunks size)!
|
||||
* - Must use 'forceChunkSize=true' on client side.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class MongoFile extends File
|
||||
{
|
||||
private $uploadGridFsFile;
|
||||
|
||||
/**
|
||||
* @var MongoConfigInterface
|
||||
*/
|
||||
private $config;
|
||||
|
||||
function __construct(MongoConfigInterface $config, RequestInterface $request = null)
|
||||
{
|
||||
if ($request === null) {
|
||||
$request = new Request();
|
||||
}
|
||||
parent::__construct($config, $request);
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* return array
|
||||
*/
|
||||
protected function getGridFsFile()
|
||||
{
|
||||
if (!$this->uploadGridFsFile) {
|
||||
$gridFsFileQuery = $this->getGridFsFileQuery();
|
||||
$changed = $gridFsFileQuery;
|
||||
$changed['flowUpdated'] = new \MongoDate();
|
||||
$this->uploadGridFsFile = $this->config->getGridFs()->findAndModify($gridFsFileQuery, $changed, null,
|
||||
['upsert' => true, 'new' => true]);
|
||||
}
|
||||
|
||||
return $this->uploadGridFsFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $index int|string 1-based
|
||||
* @return bool
|
||||
*/
|
||||
public function chunkExists($index)
|
||||
{
|
||||
return $this->config->getGridFs()->chunks->find([
|
||||
'files_id' => $this->getGridFsFile()['_id'],
|
||||
'n' => (intval($index) - 1)
|
||||
])->limit(1)->hasNext();
|
||||
}
|
||||
|
||||
public function checkChunk()
|
||||
{
|
||||
return $this->chunkExists($this->request->getCurrentChunkNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* Save chunk
|
||||
* @return bool
|
||||
* @throws \Exception if upload size is invalid or some other unexpected error occurred.
|
||||
*/
|
||||
public function saveChunk()
|
||||
{
|
||||
try {
|
||||
$file = $this->request->getFile();
|
||||
|
||||
$chunkQuery = [
|
||||
'files_id' => $this->getGridFsFile()['_id'],
|
||||
'n' => intval($this->request->getCurrentChunkNumber()) - 1,
|
||||
];
|
||||
$chunk = $chunkQuery;
|
||||
$data = file_get_contents($file['tmp_name']);
|
||||
$actualChunkSize = strlen($data);
|
||||
if ($actualChunkSize > $this->request->getDefaultChunkSize() ||
|
||||
($actualChunkSize < $this->request->getDefaultChunkSize() &&
|
||||
$this->request->getCurrentChunkNumber() != $this->request->getTotalChunks())
|
||||
) {
|
||||
throw new \Exception("Invalid upload! (size: {$actualChunkSize})");
|
||||
}
|
||||
$chunk['data'] = new \MongoBinData($data, 0); // \MongoBinData::GENERIC is not defined for older mongo drivers
|
||||
$this->config->getGridFs()->chunks->findAndModify($chunkQuery, $chunk, [], ['upsert' => true]);
|
||||
unlink($file['tmp_name']);
|
||||
|
||||
$this->ensureIndices();
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
// try to remove a possibly (partly) stored chunk:
|
||||
if (isset($chunkQuery)) {
|
||||
$this->config->getGridFs()->chunks->remove($chunkQuery);
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function validateFile()
|
||||
{
|
||||
$totalChunks = $this->request->getTotalChunks();
|
||||
|
||||
for ($i = 1; $i <= $totalChunks; $i++) {
|
||||
if (!$this->chunkExists($i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Merge all chunks to single file
|
||||
* @param $metadata array additional metadata for final file
|
||||
* @return \MongoId|bool of saved file or false if file was already saved
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function saveToGridFs($metadata = null)
|
||||
{
|
||||
$file = $this->getGridFsFile();
|
||||
$file['flowStatus'] = 'finished';
|
||||
$file['metadata'] = $metadata;
|
||||
$result = $this->config->getGridFs()->findAndModify($this->getGridFsFileQuery(), $file);
|
||||
// on second invocation no more file can be found, as the flowStatus changed:
|
||||
if (is_null($result)) {
|
||||
return false;
|
||||
} else {
|
||||
return $file['_id'];
|
||||
}
|
||||
}
|
||||
|
||||
public function save($destination)
|
||||
{
|
||||
throw new \Exception("Must not use 'save' on MongoFile - use 'saveToGridFs'!");
|
||||
}
|
||||
|
||||
public function deleteChunks()
|
||||
{
|
||||
// nothing to do, as chunks are directly part of the final file
|
||||
}
|
||||
|
||||
public function ensureIndices()
|
||||
{
|
||||
$chunksCollection = $this->config->getGridFs()->chunks;
|
||||
$indexKeys = ['files_id' => 1, 'n' => 1];
|
||||
$indexOptions = ['unique' => true, 'background' => true];
|
||||
if(method_exists($chunksCollection, 'createIndex')) { // only available for PECL mongo >= 1.5.0
|
||||
$chunksCollection->createIndex($indexKeys, $indexOptions);
|
||||
} else {
|
||||
$chunksCollection->ensureIndex($indexKeys, $indexOptions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getGridFsFileQuery()
|
||||
{
|
||||
return [
|
||||
'flowIdentifier' => $this->request->getIdentifier(),
|
||||
'flowStatus' => 'uploading',
|
||||
'filename' => $this->request->getFileName(),
|
||||
'chunkSize' => intval($this->request->getDefaultChunkSize()),
|
||||
'length' => intval($this->request->getTotalSize())
|
||||
];
|
||||
}
|
||||
}
|
31
vendor/flowjs/flow-php-server/src/Flow/Mongo/MongoUploader.php
vendored
Normal file
31
vendor/flowjs/flow-php-server/src/Flow/Mongo/MongoUploader.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Flow\Mongo;
|
||||
|
||||
use Flow\FileOpenException;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class MongoUploader
|
||||
{
|
||||
/**
|
||||
* Delete chunks older than expiration time.
|
||||
*
|
||||
* @param \MongoGridFS $gridFs
|
||||
* @param int $expirationTime seconds
|
||||
*
|
||||
* @throws FileOpenException
|
||||
*/
|
||||
public static function pruneChunks($gridFs, $expirationTime = 172800)
|
||||
{
|
||||
$result = $gridFs->remove([
|
||||
'flowUpdated' => ['$lt' => new \MongoDate(time() - $expirationTime)],
|
||||
'flowStatus' => 'uploading'
|
||||
]);
|
||||
|
||||
if (!$result) {
|
||||
throw new FileOpenException("Could not remove chunks!");
|
||||
}
|
||||
}
|
||||
}
|
50
vendor/flowjs/flow-php-server/src/Flow/Mongo/README.md
vendored
Normal file
50
vendor/flowjs/flow-php-server/src/Flow/Mongo/README.md
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
Usage
|
||||
--------------
|
||||
|
||||
* Must use 'forceChunkSize=true' on client side.
|
||||
* Chunk preprocessor not supported.
|
||||
* One should ensure indices on the gridfs collection on the property 'flowIdentifier'.
|
||||
|
||||
Besides the points above, the usage is analogous to the 'normal' flow-php:
|
||||
|
||||
```php
|
||||
$config = new \Flow\Mongo\MongoConfig($yourGridFs);
|
||||
$file = new \Flow\Mongo\MongoFile($config);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
if ($file->checkChunk()) {
|
||||
header("HTTP/1.1 200 Ok");
|
||||
} else {
|
||||
header("HTTP/1.1 204 No Content");
|
||||
return ;
|
||||
}
|
||||
} else {
|
||||
if ($file->validateChunk()) {
|
||||
$file->saveChunk();
|
||||
} else {
|
||||
// error, invalid chunk upload request, retry
|
||||
header("HTTP/1.1 400 Bad Request");
|
||||
return ;
|
||||
}
|
||||
}
|
||||
if ($file->validateFile()) {
|
||||
// File upload was completed
|
||||
$id = $file->saveToGridFs(['your metadata'=>'value']);
|
||||
if($id) {
|
||||
//do custom post processing here, $id is the MongoId of the gridfs file
|
||||
}
|
||||
} else {
|
||||
// This is not a final chunk, continue to upload
|
||||
}
|
||||
```
|
||||
|
||||
Delete unfinished files
|
||||
-----------------------
|
||||
|
||||
For this you should setup cron, which would check each chunk upload time.
|
||||
If chunk is uploaded long time ago, then chunk should be deleted.
|
||||
|
||||
Helper method for checking this:
|
||||
```php
|
||||
\Flow\Mongo\MongoUploader::pruneChunks($yourGridFs);
|
||||
```
|
Reference in New Issue
Block a user