Skip to content

Move File Only Shows 1 Level of Sub-Directories #1179

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

Open
shockdot opened this issue Dec 21, 2022 · 2 comments
Open

Move File Only Shows 1 Level of Sub-Directories #1179

shockdot opened this issue Dec 21, 2022 · 2 comments

Comments

@shockdot
Copy link

Operating system
Windows 10

Laravel version
7:30.6

Package version
2.5.1

Steps to reproduce your issue

  1. Add an image to the root directory.
  2. Create a directory in the root directory, call it "Layer1".
  3. Create a sub-directory in the Layer1 directory, call it "Layer2".
  4. Use the "Move" feature to move the image in the root directory, you will only be able to view the first layer of subdirectories, not Layer2.
@jleroy-gm
Copy link

Has anyone found a workaround to get these subdirectories displayed on the side menu ?

@patacra
Copy link

patacra commented May 6, 2025

Topic 1 : missing destination sub-folders

I confirm that I have the same problem on Windows 11. I see that this is due to the way it has been implemented in ItemsController->move():

https://github.com/UniSharp/laravel-filemanager/blob/e82f8f65e1df7b55075a791c5bc97cf35724449d/src/Controllers/ItemsController.php#L39C1-L59C6

As one can see, it only looks for the children of one level and doesn't do it recursively.
The view template move.blade.php will only loop on this single-level list of children.

By the way, this view has quite a lot of problems:

  • The <div id="items"> and all the child items are not unique (which is not allowed in HTML, as the id
    should be unique in the DOM). This <div id="items"> should be moved out of the @foreach loop of folders.

  • The id attribute of the <input type="hidden" id="my folder to move" name="items[]" value="my folder to move">
    is also invalid, because a folder name can contain invalid characters for an id attribute. The JavaScript code at the
    bottom should read the value attribute, instead of this id attribute, which should be something more like item-to-move-0,
    item-to-move-1, etc.

A first improvement, to have valid HTML, but not yet with recursion for the sub-folders:

<ul class="nav nav-pills flex-column">
  @foreach($root_folders as $root_folder)
    <li class="nav-item">
      <a class="nav-link" href="#" data-type="0" onclick="moveToNewFolder(`{{ $root_folder->url }}`)">
        <i class="fa fa-folder fa-fw"></i> {{ $root_folder->name }}
        <input type="hidden" name="goToFolder" value="{{ $root_folder->url }}">
      </a>
    </li>
    @foreach($root_folder->children as $directory)
    <li class="nav-item sub-item">
      <a class="nav-link" href="#" data-type="0" onclick="moveToNewFolder(`{{ $directory->url }}`)">
        <i class="fa fa-folder fa-fw"></i> {{ $directory->name }}
        <input type="hidden" name="goToFolder" value="{{ $directory->url }}">
      </a>
    </li>
    @endforeach
  @endforeach
</ul>

<div id="items-to-move">
  @foreach($items as $i => $item)
    <input type="hidden" id="item-to-move-{{ $i }}" name="items[]" value="{{ $item }}">
  @endforeach
</div>

<script>
  function moveToNewFolder(folder) {
    $("#notify").modal('hide');
    let items = [];
    $("#items-to-move").find("input").each(function() {items.push(this.value)});
    performLfmRequest('domove', {
      items: items,
      goToFolder: folder
    }).done(refreshFoldersAndItems);
  }
</script>

It should be possible to create a sub-template inside the move.blade.php template, to do recursion with the
use of Blade recursive partials.

I'll try to make one and refactor the ItemsController->move() method to drill down recursively into the sub-folders
and use the improved views.

Topic 2 : error 500 when doing the move operation, on Windows

When selecting a folder, the browser will initiate the move operation, which will trigger the doMove() method of
the ItemController, leading to a crash of the server (error 500).

Debugging the PHP code, I found out that it is crashing here:

$input = iconv('UTF-8', mb_detect_encoding($input), $input);

This is because the doMove() method of the ItemController is reading the items to move,
which is an array, and not a string. This is because one can move one or several items, with the multi-select function.

$items = $this->helper->input('items');

The crash only happens on Windows because the conversion from UTF-8 is only done on this system.

I'm not really sure how to refactor this code properly, but it would perhaps be possible to rewrite the
Lfm::translateFromUtf8() method to handle arrays, simply by looping or doing it recursively:

    /**
     * Translate file or directory name(s) to be compatible on Windows.
     *
     * @param  string|array  $input  Any string or array of strings.
     * @return string|array
     */
    public function translateFromUtf8($input)
    {
        if ($this->isRunningOnWindows()) {
            if (is_array($input)) {
                foreach ($input as &$item) {
                    $item = iconv('UTF-8', mb_detect_encoding($item), $item);
                }
            } else {
                $input = iconv('UTF-8', mb_detect_encoding($input), $input);
            }
        }

        return $input;
    }

I made pull request #1260 to fix it with the code above.
I just see that some validation steps don't pass, but it seems to have nothing to do with my changes
as it is looking for a missing test class. It would really be great if someone from the LFM team could look at it 🙏

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

No branches or pull requests

3 participants