diff --git a/file_example/src/Form/FileExampleReadWriteForm.php b/file_example/src/Form/FileExampleReadWriteForm.php
index d839982..7626cd2 100644
--- a/file_example/src/Form/FileExampleReadWriteForm.php
+++ b/file_example/src/Form/FileExampleReadWriteForm.php
@@ -12,6 +12,7 @@ use Drupal\file\FileInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\File\FileSystemInterface;
+use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Url;
@@ -47,8 +48,14 @@ class FileExampleReadWriteForm extends FormBase {
protected $fileSystem;
/**
+ * @var StreamWrapperInterface
+ * Service for fetching a stream wrapper for a file or directory.
+ */
+ protected $streamWrapperManager;
+
+ /**
* @var ModuleHandlerInterface
- * Handler for invoking hooks and other module operations.
+ * Service for invoking hooks and other module operations.
*/
protected $moduleHandler;
@@ -57,12 +64,23 @@ class FileExampleReadWriteForm extends FormBase {
*
* @param StateInterface $state
* Storage interface for state data.
+ * @param FileSystemInterface $file_system
+ * Interface for common file system operations.
+ * @param StreamWrapperManagerInterface $stream_wrapper_manager
+ * Interface to obtain stream wrappers used to manipulate a given file scheme.
+ * @param ModuleHandlerInterface $module_handler
+ * Interface to get information about the status of modules and other extensions.
+ * @param RequestStack $request_stack
+ * Access to the current request, including to session objects.
*/
- public function __construct(StateInterface $state, FileSystemInterface $file_system, ModuleHandlerInterface $module_handler, RequestStack $request_stack) {
+ public function __construct(StateInterface $state, FileSystemInterface $file_system,
+ StreamWrapperManagerInterface $stream_wrapper_manager,
+ ModuleHandlerInterface $module_handler, RequestStack $request_stack) {
$this->state = $state;
$this->fileSystem = $file_system;
$this->moduleHandler = $module_handler;
$this->requestStack = $request_stack;
+ $this->streamWrapperManager = $stream_wrapper_manager;
}
/**
@@ -75,7 +93,8 @@ class FileExampleReadWriteForm extends FormBase {
$file_system = $container->get('file_system');
$module_handler = $container->get('module_handler');
$request_stack = $container->get('request_stack');
- return new static($state, $file_system, $module_handler, $request_stack);
+ $stream_wrapper_manager = $container->get('stream_wrapper_manager');
+ return new static($state, $file_system, $stream_wrapper_manager, $module_handler, $request_stack);
}
/**
@@ -84,7 +103,7 @@ class FileExampleReadWriteForm extends FormBase {
* @return string
* The unique string identifying the form.
*/
- public function getFormID() {
+ public function getFormId() {
return 'file_example_readwrite';
}
@@ -175,26 +194,6 @@ class FileExampleReadWriteForm extends FormBase {
}
/**
- * {@inheritdoc}
- *
- * This is an override of LinkGeneratorTrait::l to work around
- * some problems related to handling non-routing URLs.
- *
- * @see https://www.drupal.org/node/2539622
- */
- protected function l($text, Url $url) {
- try {
- $new_url = Url::fromUri(file_create_url($url->getUri()));
- $l = parent::l($text, $new_url);
- return $l;
- }
- catch (\Exception $e) {
- // We might want to log this.
- }
- return '';
- }
-
- /**
* Prepare Url objects to prevent exceptions by the URL generator.
*
* Helper function to get us an external URL if this is legal, and to catch
@@ -205,35 +204,39 @@ class FileExampleReadWriteForm extends FormBase {
* exceptions if you deviate from what's expected. This function will raise
* the chances your URL will be valid, and not do this.
*
- * @param \Drupal\file\Entity\File $file_object|string
+ * @param \Drupal\file\Entity\File|string $file_object
* A file entity object.
*
* @return \Drupal\Core\Url
* A Url object that can be displayed as an internal URL.
- *
- * @see http://drupal.stackexchange.com/questions/177869/how-to-create-a-url-to-an-unmanaged-public-file-in-drupal-8
*/
- private static function getExternalUrl($file_object) {
+ protected function getExternalUrl($file_object) {
if ($file_object instanceof FileInterface) {
$uri = $file_object->getFileUri();
- $url = Url::fromUri($uri);
}
else {
// A little tricky, since file.inc is a little inconsistent, but often this
// is a Uri.
- $url = file_create_url($file_object);
+ $uri = file_create_url($file_object);
}
try {
- // If the Uri is unroutable (such as for a temporary file), or if Drupal cannot create
- // a link, we will throw here:
- if (is_string($url)) {
- $url = Url::fromUri($url);
+ // If we have been given a PHP stream URI, ask the stream itself if it knows
+ // how to create an external URL.
+ $wrapper = $this->streamWrapperManager->getViaUri($uri);
+ if ($wrapper) {
+ $external_url = $wrapper->getExternalUrl();
+ // Some streams may not have the concept of an external URL, so we check here.
+ if ($external_url) {
+ $url = Url::fromUri($external_url);
+ return $url;
+ }
}
- if (!empty($url) and $url->isExternal()) {
+ else {
+ $url = Url::fromUri($uri);
+ // If we did not throw on ::fromUri (you can), we return the URL.
return $url;
}
- // $url->toString();
}
catch (\Exception $e) {
return FALSE;
@@ -386,17 +389,17 @@ class FileExampleReadWriteForm extends FormBase {
// Managed operations work with a file object.
$file_object = \file_save_data($data, $uri, FILE_EXISTS_RENAME);
if (!empty($file_object)) {
- $url = self::getExternalUrl($file_object);
+ $url = $this->getExternalUrl($file_object);
$this->setDefaultFile($file_object->getFileUri());
$file_data = $file_object->toArray();
if ($url) {
drupal_set_message(
- $this->t('Saved managed file: %file to destination %destination (accessible via !url, actual uri=@uri)',
+ $this->t('Saved managed file: %file to destination %destination (accessible via this URL, actual uri=@uri)',
array(
'%file' => print_r($file_data, TRUE),
'%destination' => $uri,
'@uri' => $file_object->getFileUri(),
- '!url' => $this->l(t('this URL'), $url),
+ ':url' => $url->toString(),
)
)
);
@@ -449,15 +452,15 @@ class FileExampleReadWriteForm extends FormBase {
// With the unmanaged file we just get a filename back.
$filename = file_unmanaged_save_data($data, $destination, FILE_EXISTS_REPLACE);
if ($filename) {
- $url = self::getExternalUrl($filename);
+ $url = $this->getExternalUrl($filename);
$this->setDefaultFile($filename);
if ($url) {
drupal_set_message(
- $this->t('Saved file as %filename (accessible via !url, uri=@uri)',
+ $this->t('Saved file as %filename (accessible via this URL, uri=@uri)',
array(
'%filename' => $filename,
'@uri' => $filename,
- '!url' => $this->l(t('this URL'), $url),
+ ':url' => $url->toString(),
)
)
);
@@ -523,15 +526,15 @@ class FileExampleReadWriteForm extends FormBase {
return;
}
}
- $url = self::getExternalUrl($destination);
+ $url = $this->getExternalUrl($destination);
$this->setDefaultFile($destination);
if ($url) {
drupal_set_message(
- $this->t('Saved file as %filename (accessible via !url, uri=@uri)',
+ $this->t('Saved file as %filename (accessible via this URL, uri=@uri)',
array(
'%filename' => $destination,
'@uri' => $destination,
- '!url' => $this->l(t('this URL'), $url),
+ ':url' => $url->toString(),
)
)
);
@@ -593,16 +596,14 @@ class FileExampleReadWriteForm extends FormBase {
if ($buffer) {
$sourcename = file_unmanaged_save_data($buffer, 'public://' . $filename);
if ($sourcename) {
- $url = self::getExternalUrl($sourcename);
+ $url = $this->getExternalUrl($sourcename);
$this->setDefaultFile($sourcename);
if ($url) {
- // We need to convert the URL to string. Since the URL class throws on non-routables.
- $url_string = file_create_url($url->getUri());
drupal_set_message(
- $this->t('The file was read and copied to %filename which is accessible at !url',
+ $this->t('The file was read and copied to %filename which is accessible at this URL',
array(
'%filename' => $sourcename,
- '!url' => $this->l($url_string, $url),
+ ':url' => $url->toString(),
)
)
);