Problem/Motivation

It's a great contrib module. Thanks @clivesj

We have an external host (internet) and an admin host (intranet) linking to a single Drupal site.
The client requests a special role to upload the files into the particular public folder in the admin site through FileBrowser module.
After the files are uploaded into the Drupal site, the client requires to copy the file URL as an external host URL.

the current url ("/filebrowser/download/nodeid") is very difficult for the non-programmer user to construct the file's external url.

Please see the screenshots attached
requirement
requirement

Steps to reproduce

Proposed resolution

To meet this custom requirement, we can modify the logic of the makeLink function in the DisplayFileList.php

 if ($file->fileData->type != 'file') {
      return Link::createFromRoute($name, 'entity.node.canonical', ['node' => $this->node->id()], $options);
    }
     else {
-      return Link::createFromRoute($name, 'filebrowser.page_download',['fid' => $fid]);
+      $externalhost = Settings::get('external_host');
+      $directoryuri = $this->filebrowser->folderPath;
+      if (isset($externalhost) && (strpos ($directoryuri, 'public://') !== false)) {
+        //create an external link if a public file link exists in local setting
+        $publicfolderpath =  Settings::get('file_public_path');
+        if (!isset($publicfolderpath)) {
+          $publicfolderpath = PublicStream::basePath();
+        }
+        $publicfolderpath = '/' . $publicfolderpath. '/';
+        $publicfolderpath = str_replace('public://', $publicfolderpath, $directoryuri);
+        $fexternal_url = $externalhost . $publicfolderpath . $file->relativePath;
+        $fexternal_link = Link::fromTextAndUrl($name, Url::fromUri($fexternal_url));
+        if (isset($fexternal_link)) {
+          return $fexternal_link;
+        }
+        else {
+          return Link::createFromRoute($name, 'filebrowser.page_download',['fid' => $fid]);
+        }
+      }
+      else {
+        return Link::createFromRoute($name, 'filebrowser.page_download',['fid' => $fid]);
+      }
     }
   }

Remaining tasks

User interface changes

Added additional download manager and new configuration field `external_host`to main confiuration an to node's widget

API changes

Data model changes

Comments

jamesyao created an issue. See original summary.

jamesyao’s picture

StatusFileSize
new1.81 KB
jamesyao’s picture

Issue summary: View changes
jamesyao’s picture

StatusFileSize
new4.14 KB

I moved the externalhost from settings.php (settings.local.php) to the configuration UI of the FileBrowser, which allows admin to dynamically set the external host in Dev, QA, UAT, and PROD environments.

clivesj’s picture

Thanks.
This is a nice enhancement. Any chance you can provide a patch for the 3.x branch?
There not much diff with 8.x but 8.x is strictly for D8 and 3.x only for D9.

jamesyao’s picture

Thanks @clivesj.

The patch (Display-external-URLs-3254557-04.patch) was tested against Drupal Core D9.3.x in my project. It should work for both D8 and D9.

jamesyao’s picture

Version: 8.x-2.x-dev » 3.x-dev
jamesyao’s picture

jamesyao’s picture

StatusFileSize
new4.15 KB

I fixed the a bug in the previous patch to check if the external host is not empty.

clivesj’s picture

I am a bit busy and cannot produce a patch.
Can you please look at the following:
1. Filebrowser.settings.yml format for the new setting:
adhoc_settings:
external_host: ' '

2. We also need HOOK_N in the install file to update the module configuration for adhoc_settings.

3. Please correct typo exnternal.

4. On the config form we need a better description than “leave open, it is for a special feature”. It should be descriptive for other users.
5. We need description documenting what the new feature does to include in the readme.

Thanks for your time.

jamesyao’s picture

StatusFileSize
new4.72 KB

Thanks @clivesj for your time and feedback. Much appreciated!

I updated the patch and will attach the readme of the patch later.

jamesyao’s picture

StatusFileSize
new4.73 KB
joseph.olstad’s picture

@jamesyao,

please replace deprecated db_add_field as follows:
https://api.drupal.org/api/drupal/core%21includes%21database.inc/functio...

also, please replace filebrowser_update_7100 with filebrowser_update_9001 as 3.0.x is D9+

and then change

function filebrowser_schema() {
  $schema['filebrowser_nodes'] = [
    'description' => 'Stores filebrowser specific data for each node',
    'fields' => [
      'nid' => [
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'description' => 'nid of the node holding this filebrowser',
      ],
      'folder_path' => [
        'type' => 'varchar',
        'length' => '255',
        'not null' => TRUE,
        'description' => 'uri to the exposed directory',
      ],
      'properties' => [
        'type' => 'text',
        'not null' => TRUE,
        'size' => 'big',
        'description' => 'serialised data containing the filebrowser settings for this node',
      ]
    ],
    'primary key' => ['nid']
  ];

to

function filebrowser_schema() {
  $schema['filebrowser_nodes'] = [
    'description' => 'Stores filebrowser specific data for each node',
    'fields' => [
      'nid' => [
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'description' => 'nid of the node holding this filebrowser',
      ],
      'folder_path' => [
        'type' => 'varchar',
        'length' => '255',
        'not null' => TRUE,
        'description' => 'uri to the exposed directory',
      ],
      'properties' => [
        'type' => 'text',
        'not null' => TRUE,
        'size' => 'big',
        'description' => 'serialised data containing the filebrowser settings for this node',
      ],
      'externalhost' => [
        'type' => 'varchar',
        'description' => "External host",
        'length' => 256,
        'not null' => FALSE,
      ]
    ],
    'primary key' => ['nid']
  ];

also, please recall that the php >=5.4 array syntax must be used
so rather than

$example = array('example', 'example2');

please use the expected Drupal 9 standard array style introduced in php 5.4:

$example = ['example', 'example2'];
jamesyao’s picture

StatusFileSize
new5.33 KB

Thanks @joseph.olstad for your feedback.

jamesyao’s picture

StatusFileSize
new5.88 KB

Fixed a syntax error (Class 'Database' not found) in Display-external-URLs-3254557-14.patch.

mmbk’s picture

Status: Active » Needs work
StatusFileSize
new30.62 KB

The patch is working as described, and solves 200% of my customer's request.

I tend to split this patch into two task
1. display the file's urls as absolute Urls into the filessystem so that the webserver can deliver it directly (This is what my customer wants) This has the effect that the urls will remain persistent if a file is replaced, so the files can be referred externally. This could be archived by adding a new `Download manager`

2. Replace the host-part of the url with the configured `external_host`,

Some reviews on the patch:

+++ b/filebrowser.install
@@ -115,3 +123,22 @@ function filebrowser_schema() {
+  if ($some_error_condition_met) {
+    throw new UpdateException('Something went wrong; here is what you should do.');
+  }

Hmm, this is uneccessary code, the variable is not defined and the message is not helpful, I guess it's some generated code

+++ b/src/File/DisplayFileList.php
@@ -350,7 +353,29 @@ class DisplayFileList extends ControllerBase {
+      $externalhost = $config['adhocsetting']['externalhost'];
+      $directoryuri = $this->filebrowser->folderPath;
+      if (isset($externalhost) && (!empty($externalhost)) && (strpos($directoryuri, 'public://') !== false)) {
+        $publicfolderpath =  Settings::get('file_public_path');
+        if (!isset($publicfolderpath)) {
+          $publicfolderpath = PublicStream::basePath();
+        }
+        $publicfolderpath = '/' . $publicfolderpath. '/';
+        $publicfolderpath = str_replace('public://', $publicfolderpath, $directoryuri);
+        $fexternal_url = $externalhost . $publicfolderpath . $file->relativePath;
+        $fexternal_link = Link::fromTextAndUrl($name, Url::fromUri($fexternal_url));
+        if (isset($fexternal_link)) {
+          return $fexternal_link;

This part should use the Streamwrappers, so that the generation is not restricted to the public wrapper.

mmbk’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new19.39 KB

As outlined in #16 I expanded the download_manager (I'm not totally convinced, that the naming is still valid, but it's good enough) with a `server` manager. Whenever this is selected a the link points to a file not to the file-entity.

When an `external host` is configured the `scheme&host` part of the url is replaced with the configured value.

The url is generated with the help of the used streamwrapper, this allows to use custom `flysystems` wrappers.

The previous patch got the `external host`from filebrowser's configuration, not from the displayed node, I changed this, it seems to make more sense.

The file `DisplayFileList.php` is reformatted with `phpcbf`there are still code-style-issues that have to be fixed manually.

mmbk’s picture

StatusFileSize
new22.33 KB
new19.39 KB

Arghh path #17 is an interdiff, don't use it, correct path and the interdiff attached here.

onfire84’s picture

pacht #18 does not apply with latest dev Version

clivesj’s picture

Version: 3.x-dev » 3.1.x-dev

  • clivesj committed 82b3569 on 3.1.x
    Issue #3254557 by jamesyao, mmbk, clivesj: A custom feature needs to...
clivesj’s picture

Status: Needs review » Fixed
StatusFileSize
new21.56 KB

The patch is against latest 3.1.x-dev
I have included code to update current configuration for the new setting.
dev is updated and if commit holds, I can make a new release 3.1.0 which has this new feature and is also D10 compatible.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.