function FileExampleSubmitHandlerHelper::handleFileRead

Submit handler for reading a stream wrapper.

Drupal now has full support for PHP's stream wrappers, which means that instead of the traditional use of all the file functions ($fp = fopen("/tmp/some_file.txt");) far more sophisticated and generalized (and extensible) things can be opened as if they were files. Drupal itself provides the public:// and private:// schemes for handling public and private files. PHP provides file:// (the default) and http://, so that a URL can be read or written (as in a POST) as if it were a file. In addition, new schemes can be provided for custom applications. The Stream Wrapper Example, if installed, impleents a custom 'session' scheme that you can test with this example.

Here we take the stream wrapper provided in the form. We grab the contents with file_get_contents(). Notice that's it's as simple as that: file_get_contents("http://example.com") or file_get_contents("public://somefile.txt") just works. Although it's not necessary, we use FileSystemInterface::saveData() to save this file locally and then find a local URL for it by using file_create_url().

Parameters

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

File

modules/file_example/src/FileExampleSubmitHandlerHelper.php, line 261

Class

FileExampleSubmitHandlerHelper
A submit handler helper class for the file_example module.

Namespace

Drupal\file_example

Code

public function handleFileRead(array &$form, FormStateInterface $form_state) {
    $form_values = $form_state->getValues();
    $uri = $form_values['fileops_file'];
    if (empty($uri) or !is_file($uri)) {
        $this->messenger
            ->addMessage($this->t('The file "%uri" does not exist', [
            '%uri' => $uri,
        ]), 'error');
        return;
    }
    $filename = $this->fileSystem
        ->basename($uri);
    // To ensure that the filename is valid, strip off any potential file
    // portion from the stream wrapper. If the filename includes a malicious
    // file extension, it will be neutralized by the event subscriber of the
    // FileUploadSanitizeNameEvent. This process helps to maintain the security
    // of the system and prevent any potential harm from malicious files.
    $event = new FileUploadSanitizeNameEvent($filename, 'txt');
    $this->eventDispatcher
        ->dispatch($event);
    $dirname = $this->fileSystem
        ->dirname($uri);
    if (str_ends_with($dirname, '/')) {
        $filename = $dirname . $event->getFilename();
    }
    else {
        $filename = $dirname . '/' . $event->getFilename();
    }
    $buffer = file_get_contents($filename);
    if ($buffer) {
        $sourcename = $this->fileSystem
            ->saveData($buffer, 'public://' . $event->getFilename());
        if ($sourcename) {
            $url = $this->fileHelper
                ->getExternalUrl($sourcename);
            $this->stateHelper
                ->setDefaultFile($sourcename);
            if ($url) {
                $this->messenger
                    ->addMessage($this->t('The file was read and copied to %filename which is accessible at <a href=":url">this URL</a>', [
                    '%filename' => $sourcename,
                    ':url' => $url->toString(),
                ]));
            }
            else {
                $this->messenger
                    ->addMessage($this->t('The file was read and copied to %filename (not accessible externally)', [
                    '%filename' => $sourcename,
                ]));
            }
        }
        else {
            $this->messenger
                ->addMessage($this->t('Failed to save the file'));
        }
    }
    else {
        // We failed to get the contents of the requested file.
        $this->messenger
            ->addMessage($this->t('Failed to retrieve the file %file', [
            '%file' => $uri,
        ]));
    }
}