Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHPORM-186 GridFS adapter for Filesystem #2985

Merged
merged 8 commits into from
Jun 4, 2024
Merged

Conversation

GromNaN
Copy link
Member

@GromNaN GromNaN commented May 30, 2024

Fix PHPORM-186

Integration of Flysystem GridFS Adapter for Laravel File Storage.

The configuration is similar to the Symfony Flysystem Bundle as it provides various way to configure the bucket:

  • using the database connection (default connection by default)
  • setting a service name for the bucket instance
  • setting a factory function for the bucket instance

Unlike the Symfony Bundle, I do not provide instantiation of a new MongoDB\Client from the configuration as we always have a database connection with Eloquent.

Checklist

  • Add tests and ensure they pass
  • Add an entry to the CHANGELOG.md file
  • Update documentation for new features

@GromNaN GromNaN force-pushed the PHPORM-186 branch 2 times, most recently from aa72f30 to 9bb2081 Compare May 30, 2024 22:25
@github-actions github-actions bot added the docs label May 30, 2024
@GromNaN GromNaN added enhancement and removed docs labels May 30, 2024
@GromNaN GromNaN requested a review from jmikola May 30, 2024 22:30
@GromNaN GromNaN marked this pull request as ready for review May 30, 2024 22:30
@GromNaN GromNaN requested review from a team as code owners May 30, 2024 22:30
@GromNaN GromNaN added the docs label May 30, 2024
@GromNaN GromNaN added this to the 4.5 milestone May 31, 2024
@GromNaN GromNaN changed the base branch from 4.4 to 4.5 May 31, 2024 07:27
docs/filesystems.txt Outdated Show resolved Hide resolved
'bucket' => 'fs',
'prefix' => '',
'read-only' => false,
'throw' => false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the complete list of supported options, with default values repeated just so users know what they can set? Since you have a table below with all options, I'd consider reducing this code example to just the necessary options.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not, but personally I find the complete example more synthetic and quicker to read, or even copy and paste.
I understand that we want developers to use the default minimal config, so that's what I'm going to keep.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the complete example more synthetic and quicker to read

Same. If this example was annotated with comments to call out default values (and thus assist user's with reducing their own config) I think it'd stand well on its own and we wouldn't even need the table that follows.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added optional settings in comments. Keeping the table for details.

docs/filesystems.txt Outdated Show resolved Hide resolved
docs/filesystems.txt Outdated Show resolved Hide resolved
docs/filesystems.txt Outdated Show resolved Hide resolved
docs/filesystems.txt Outdated Show resolved Hide resolved
src/MongoDBServiceProvider.php Show resolved Hide resolved
tests/FilesystemsTest.php Outdated Show resolved Hide resolved
]);

$disk = Storage::disk('gridfs-prefix');
$disk->put('hello/world.txt', 'Hello World!');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be mistaken and/or misunderstanding something, but aren't all files supposed to be prefixed with a leading directory separator?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The directory separator is always added between the prefix and the file name by the PathPrefixer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recall that the PathPrefixer adds it, but I thought the docs might present the canonical form. I just noted the absence of a leading / is consistent with examples in the Laravel Filesystem docs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the prefix is empty, the file name in the fs.files collection does not have the leading /. The only situation you can get a leading / is by having it in the prefix.

composer.json Show resolved Hide resolved
Copy link
Contributor

@norareidy norareidy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some comments, mostly about wording and introducing the code examples in the text. Let me know if you have any questions!

docs/filesystems.txt Outdated Show resolved Hide resolved
Configuration
-------------

Before using the GridFS driver, you will need to install the Flysystem GridFS package via the Composer package manager:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: we try to avoid the future tense and "via" in the docs. Also, I'd edit this sentence slightly so it introduces the code example:

Suggested change
Before using the GridFS driver, you will need to install the Flysystem GridFS package via the Composer package manager:
Before using the GridFS driver, install the Flysystem GridFS package through the Composer package manager by running the following command:

docs/filesystems.txt Outdated Show resolved Hide resolved
docs/filesystems.txt Show resolved Hide resolved
docs/filesystems.txt Outdated Show resolved Hide resolved
docs/filesystems.txt Show resolved Hide resolved
docs/filesystems.txt Outdated Show resolved Hide resolved
docs/filesystems.txt Outdated Show resolved Hide resolved
docs/filesystems.txt Outdated Show resolved Hide resolved
docs/filesystems.txt Outdated Show resolved Hide resolved
@GromNaN GromNaN requested review from norareidy and jmikola June 3, 2024 10:09
docs/filesystems.txt Outdated Show resolved Hide resolved
docs/filesystems.txt Outdated Show resolved Hide resolved
$bucket = $app['db']->connection('mongodb')->getMongoDB()->selectGridFSBucket();

// Download the last but one version of a file
$bucket->openDownloadStreamByName('hello.txt', ['revision' => -2])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since PathPrefixer doesn't apply here, would users need to write /hello.txt, or do the prefixes only kick in when a path is used? I expect this could be a pain point for users, that may warrant a note.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use the leading / in the PHP GridFS documentation. I don't know what to write in a note.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no prefixing done in PHPLIB, so the filename is used exactly as provided.

My question here is: would hello.txt here refer to the same file written by Flysystem, or would you need to use /hello.txt? It's not clear to me if Flysystem adds a prefix to every file name or just those that appear to use paths (i.e. already contain a / somewhere in the middle of the string).

Copy link
Member

@jmikola jmikola Jun 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this is answered by #2985 (comment). In that case, I suppose the note would be to remind users that prefixing is entirely handled by Flysystem. So if they're using a non-empty prefix option they'll need to ensure that filenames are prefixed manually when using PHPLIB directly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flysystem always adds the prefix to the file name stored in MongoDB.

@GromNaN GromNaN requested a review from jmikola June 4, 2024 07:54
@GromNaN GromNaN enabled auto-merge (squash) June 4, 2024 13:32
Copy link
Contributor

@norareidy norareidy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with some comments!

],
],

You can configure the disk the following settings in ``config/filesystems.php``:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I: I think you can delete "the disk"

Suggested change
You can configure the disk the following settings in ``config/filesystems.php``:
You can configure the following settings in ``config/filesystems.php``:

- **Required**. Specifies the filesystem driver to use. Must be ``gridfs`` for MongoDB.

* - ``connection``
- The database connection used to store jobs. It must be a ``mongodb`` connection. The driver uses the default connection if a connection is not specified.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: remove the article to match the other descriptions

Suggested change
- The database connection used to store jobs. It must be a ``mongodb`` connection. The driver uses the default connection if a connection is not specified.
- Database connection used to store jobs. It must be a ``mongodb`` connection. The driver uses the default connection if a connection is not specified.

* - ``prefix``
- Specifies a prefix for the name of the files that are stored in the bucket. Using a distinct bucket is recommended
in order to store the files in a different collection, instead of using a prefix.
The prefix should not start with a leading slash ``/``.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: Add parentheses around the slash

Suggested change
The prefix should not start with a leading slash ``/``.
The prefix should not start with a leading slash (``/``).

Usage
-----

A benefit of using Laravel Filesystem is that it provides a common interface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: Reword so this sentence is a little less subjective

Suggested change
A benefit of using Laravel Filesystem is that it provides a common interface
Laravel Filesystem provides a common interface

A benefit of using Laravel Filesystem is that it provides a common interface
for all the supported file systems. You can use the ``gridfs`` disk in the same
way as the ``local`` disk.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: introduce the code

Suggested change
The following example writes a file to the ``gridfs`` disk, then reads the file:

Comment on lines +130 to +131
File names in GridFS are metadata in file documents, which are identified by
unique ObjectIDs. If multiple documents share the same file name, they are
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: since this is the first time that file metadata documents are mentioned, I think it would be helpful to describe them

Suggested change
File names in GridFS are metadata in file documents, which are identified by
unique ObjectIDs. If multiple documents share the same file name, they are
GridFS creates file documents for each uploaded file. These documents contain metadata, including the file name and a
unique ObjectId. If multiple documents share the same file name, they are

- Deleting a file deletes all the revisions of this file name

The GridFS Adapter for Flysystem does not provide access to a specific revision
of a filename. You must use the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: I'd stay consistent with using either "filename" or "file name"

Suggested change
of a filename. You must use the
of a file name. You must use the

Comment on lines +158 to +159
If you use a prefix the Filesystem component, you will have to handle it
by yourself when using the GridFS API directly.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: clarify the first part of this sentence ("If you use a prefix the Filesystem component" part)

Q: what do you mean by "handle it by yourself" - could you clarify that in the note?

Suggested change
If you use a prefix the Filesystem component, you will have to handle it
by yourself when using the GridFS API directly.
If you specify the ``prefix`` GridFS setting, you will have to handle it
by yourself when using the GridFS API directly.

@GromNaN GromNaN merged commit 847e3c7 into mongodb:4.5 Jun 4, 2024
26 checks passed
@GromNaN GromNaN deleted the PHPORM-186 branch June 4, 2024 14:59
@GromNaN
Copy link
Member Author

GromNaN commented Jun 4, 2024

LGTM with some comments!

I applied your suggested changes in a new PR: #2993

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants