문제

To use the private:// scheme of Drupal 8 I had to :

  • Create a folder outside the docroot folder
  • Implement a $settings['file_private_path'] = '../private-files'; to designate this folder
  • Make sure authorization matches the website user to write into it

Then I load the filesystem helper (I could use injection dependency but that is not the point here) :

$this->filesystem = \Drupal::service('file_system');

Prepare the directory in case it does not exists :

$this->filesystem->prepareDirectory('private://any_folder', FileSystemInterface::CREATE_DIRECTORY);

And then I could save a (unmanaged) file:

$this->filesystem->saveData(json_encode(['My Beautiful File Body']), 'private://any_folder/any_file.json', FileSystemInterface::EXISTS_REPLACE);

And this works fine.

But to load the file, I would have expected to have an "opposite" (say, loadData() ) method in $this->filesystem.

And as the file is unmanaged (which is fine) I cannout use File Entity::load() to load it.

So I end up with :

$loadedFile = json_decode(file_get_contents('private://any_folder/any_file.json'), JSON_OBJECT_AS_ARRAY);

Which works fine, but raises questions :

  • Is this a legitimate way to do it (meaning, using a Drupal helper to save a file, then loading it from a straight PHP function) ?

  • Why there is no loadData() method in the FileSystem service as I would have expected ?

  • How does the Drupal scheme 'public:// or private://) is resolved from this PHP function ?

도움이 되었습니까?

해결책

To answer your questions in respective order:

  • Sure. If there's no built-in API function to make it easier, there's nothing wrong with using file_get_contents since the function can use Drupal's file stream protocols. The core test, FileSaveDataTest::testFileSaveData(), is doing this to confirm that saveData() works.
  • One can only guess about the requirements as the class was composed. saveData() is a wrapper around a file_put_contents() op so that logging can take place when Drupal writes to a temp file. Perhaps there was no need to wrap file_get_contents in the same way?
  • Drupal has a StreamWrapperManager service class that registered different custom myscheme:// streams with PHP. This manager makes use of core PHP function stream_wrapper_register() to register any injected class that has the tags: { name: stream_wrapper, scheme: myscheme }. For example, look at CoreServiceProvider::register() which registers the private:// scheme when it detects file_private_path settings has been set.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 drupal.stackexchange
scroll top