Skip to content

Commit

Permalink
DP-460 Upgrade to PHP 8.1 / Laravel 9
Browse files Browse the repository at this point in the history
- Update requires and replace array_get method
- Refactor blob streaming in order to support file caching added in
df-file v0.8 (see RemoteFileSystem::streamBlobIfModified). Vendor
details implemented in GridFsSystem::getBlobInChunks
  • Loading branch information
daniilly committed Feb 28, 2023
1 parent c054463 commit 79abdb5
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 122 deletions.
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
"dreamfactory/df-database": "~0.11",
"jenssegers/mongodb": "~3.3.0|~3.4.0|~3.5.0|~3.6.0"
"dreamfactory/df-database": "~1.0",
"dreamfactory/df-file": "~0.8",
"jenssegers/mongodb": "~3.9.2"
},
"autoload": {
"psr-4": {
Expand Down
93 changes: 17 additions & 76 deletions src/Components/GridFsSystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use MongoDB\Client as MongoDBClient;
use Illuminate\Http\Request;
use MongoDB\Driver\Exception\ConnectionTimeoutException;
use \Illuminate\Support\Arr;

class GridFsSystem extends RemoteFileSystem
{
Expand Down Expand Up @@ -45,7 +46,7 @@ public function __construct($config, $name)
$this->request = Request::capture();
$config['driver'] = 'mongodb';

if (!empty($dsn = strval(array_get($config, 'dsn')))) {
if (!empty($dsn = strval(Arr::get($config, 'dsn')))) {
// add prefix if not there
// NOTE: We may want to change this to match the code in MondoDB.php as a regex check
// if this breaks for calling Atlas / replica sets with the +srv option
Expand All @@ -56,13 +57,13 @@ public function __construct($config, $name)
}

// laravel database config requires options to be [], not null
if (empty($options = array_get($config, 'options', []))) {
if (empty($options = Arr::get($config, 'options', []))) {
$config['options'] = [];
}
if (empty($db = array_get($config, 'database'))) {
if (!empty($db = array_get($config, 'options.db'))) {
if (empty($db = Arr::get($config, 'database'))) {
if (!empty($db = Arr::get($config, 'options.db'))) {
$config['database'] = $db;
} elseif (!empty($db = array_get($config, 'options.database'))) {
} elseif (!empty($db = Arr::get($config, 'options.database'))) {
$config['database'] = $db;
} else {
// Attempt to find db in connection string
Expand All @@ -81,18 +82,18 @@ public function __construct($config, $name)
throw new InternalServerErrorException("No MongoDb database selected in configuration.");
}

$driverOptions = (array)array_get($config, 'driver_options');
if (null !== $context = array_get($driverOptions, 'context')) {
$driverOptions = (array)Arr::get($config, 'driver_options');
if (null !== $context = Arr::get($driverOptions, 'context')) {
// Automatically creates a stream from context
$config['driver_options']['context'] = stream_context_create($context);
}

if (empty($prefix = array_get($config, 'dsn'))) {
if (empty($prefix = Arr::get($config, 'dsn'))) {
$connectionOptions = [];
$host = array_get($config, 'host');
$port = array_get($config, 'port');
$username = array_get($config, 'username');
$password = array_get($config, 'password');
$host = Arr::get($config, 'host');
$port = Arr::get($config, 'port');
$username = Arr::get($config, 'username');
$password = Arr::get($config, 'password');
$connectionStr = sprintf("mongodb://%s:%s", $host,
$port, $db);

Expand All @@ -111,7 +112,7 @@ public function __construct($config, $name)
$this->blobConn = $this->createConnection($dsn);
}

$bucketName = array_get($config, 'bucket_name');
$bucketName = Arr::get($config, 'bucket_name');

if (!empty($bucketName)) {
$this->gridFS = $this->blobConn->$db->selectGridFSBucket(['bucketName' => $bucketName]);
Expand Down Expand Up @@ -222,7 +223,7 @@ protected function getBlobMeta($obj)
$return = [
'oid' => (string)$obj->_id,
'name' => $obj->filename,
'content_type' => (isset($obj->contentType)) ? $obj->contentType : '',
'content_type' => $obj->contentType ?? '',
'content_length' => $obj->length,
'last_modified' => $date->format(\DateTime::ATOM),
'path' => $obj->filename,
Expand Down Expand Up @@ -360,75 +361,15 @@ public function getBlobProperties($container, $name)
return $this->getBlobMeta($obj);
}

/**
*
* @param string $container
* @param string $name
* @param array $params
*
* @throws \DreamFactory\Core\Exceptions\DfException
*/
public function streamBlob($container, $name, $params = [])
protected function getBlobInChunks($container, $name, $chunkSize): \Generator
{
try {
$fileObj = $this->gridFindOne($name);
$range = (isset($params['range'])) ? $params['range'] : null;
$start = $end = -1;
$stream = $this->gridFS->openDownloadStream($fileObj->_id);
$date = $fileObj->uploadDate->toDateTime();
$size = $fullsize = intval($fileObj->length);

header('Last-Modified: ' . $date->format(\DateTime::ATOM));

/** If content type is not set, try to determine it. */
if (!isset($fileObj->contentType)) {
$ext = FileUtilities::getFileExtension($name);
$contentType = FileUtilities::determineContentType($ext);
header('Content-Type: ' . $contentType);
} else {
header('Content-Type: ' . $fileObj->contentType);
}

$disposition =
(isset($params['disposition']) && !empty($params['disposition'])) ? $params['disposition']
: 'inline';

header('Content-Disposition: ' . $disposition . '; filename="' . $name . '";');

// All this for range header being passed.
if ($range != null) {
$eqPos = strpos($range, "=");
$toPos = strpos($range, "-");
$unit = substr($range, 0, $eqPos);
$start = intval(substr($range, $eqPos + 1, $toPos));
$end = intval(substr($range, $toPos + 1));
$success = fseek($stream, $start);
if ($success == 0) {
$size = $end - $start;
// Don't let the passed size exceed the actual.
if ($fullsize <= $size) {
$size = $fullsize;
}
$response_code = 206;
header('Accept-Ranges: ' . $unit);
header('Content-Range: ' . $unit . " " . $start . "-" . ($fullsize - 1) . "/" . $fullsize, true,
$response_code);
}
}

header('Content-Length:' . $size);

while (!feof($stream)) {
if ($start = -1 && $end = -1) {
/** if entire file is requested... */
echo stream_get_contents($stream, \Config::get('df.file_chunk_size'));
} else {
/** if Bit of file, in chunks */
echo stream_get_contents($stream, $end, $start);
}
yield stream_get_contents($stream, $chunkSize);
}
} catch (ConnectionTimeoutException $ex) {
throw new ConnectionTimeoutException($ex->getMessage());
} catch (\Exception $ex) {
throw new DfException('Failed to retrieve GridFS file "' . $name . '": ' . $ex->getMessage());
}
Expand Down
5 changes: 3 additions & 2 deletions src/Database/Schema/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use DreamFactory\Core\Database\Schema\TableSchema;
use Jenssegers\Mongodb\Connection;
use MongoDB\Model\CollectionInfo;
use \Illuminate\Support\Arr;

/**
* Schema is the class for retrieving metadata information from a MongoDB database (version 4.1.x and 5.x).
Expand Down Expand Up @@ -58,12 +59,12 @@ protected function getTableNames($schema = '')
*/
public function createTable($table, $options)
{
if (empty($tableName = array_get($table, 'name'))) {
if (empty($tableName = Arr::get($table, 'name'))) {
throw new \Exception("No valid name exist in the received table schema.");
}

$options = [];
if (!empty($native = array_get($table, 'native'))) {
if (!empty($native = Arr::get($table, 'native'))) {
}

return $this->connection->getMongoDB()->createCollection($tableName, $options);
Expand Down
7 changes: 4 additions & 3 deletions src/Models/MongoDbConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use DreamFactory\Core\Exceptions\BadRequestException;
use DreamFactory\Core\Models\BaseServiceConfigModel;
use DreamFactory\Core\MongoDb\Services\MongoDb;
use \Illuminate\Support\Arr;

/**
* MongoDbConfig
Expand Down Expand Up @@ -57,11 +58,11 @@ public function validate($data, $throwException = true)
{
static::checkExtensions(['mongodb']);

if (empty(array_get($data, 'database')) && empty(array_get($data, 'options.db')) &&
empty(array_get($data, 'options.database'))
if (empty(Arr::get($data, 'database')) && empty(Arr::get($data, 'options.db')) &&
empty(Arr::get($data, 'options.database'))
) {
// Attempt to find db in connection string
$dsn = strval(array_get($data, 'dsn'));
$dsn = strval(Arr::get($data, 'dsn'));
$db = strstr(preg_replace('/mongodb(\+srv)?\:\/\//', '', $dsn), '/');
if (false !== $pos = strpos($db, '?')) {
$db = substr($db, 0, $pos);
Expand Down
Loading

0 comments on commit 79abdb5

Please sign in to comment.