jhofm/flysystem-iterator

usage question

ctf0 opened this issue · 12 comments

ctf0 commented

first, thanx for your hard work.
second, i wanted to ask how would u use it with something like listWith ex. here is what i currently use

$storageDisk = app('filesystem')->disk('public');
$storageDisk->addPlugin(new ListWith()); // https://flysystem.thephpleague.com/docs/advanced/provided-plugins/

return $storageDisk->listWith(
    ['mimetype', 'visibility', 'timestamp', 'size'],
    $folder, // directory path
    $rec // true or false
);

any help is appreciated.

jhofm commented

hi there!
unfortunately plugins cannot change how the listContents() function works, which is used by the ListWith plugin to iterate over the folder.
so currently the only way would be to basically copy the foreach() in ListWith's handle() function and use that with a flysystem-iterator.
but what i could do is add a listWith mode to the plugin, something like this:

$fs->createIterator(
['value' => 'list', 'list' => ['mimetype', 'visibility', 'timestamp', 'size']]
);

but i'd need to implement that first. i'll look into it

ctf0 commented

awesome, many thanx

jhofm commented

i created a PR here that might work for you: #7

using it looks a bit different from what i initially wrote; you just need to pass the list of additional metadata to include:

$it = $fs->createIterator(['list-with' => ['mimetype']]);

one thing to keep in mind: like with the ListWith plugin, metadata can only be obtained for files, not directories or links. everything that is not a file will not contain the metadata, just basic data returned from listContents().
so it's probably a good idea to use a file filter as well:

$it = $fs->createIterator(
  [
    'filter' => FilterFactory::isFile(),
    'list-with' => ['mimetype']
  ]
);

if this works for you I'll update the readme and release the update, let me know otherwise.

cheers

ctf0 commented

i've installed the branch copy and here is what i have so far

$this->storageDisk->addPlugin(new IteratorPlugin());
return $this->storageDisk->createIterator(
    [
        'list-with' => ['mimetype', 'visibility', 'timestamp', 'size'],
    ],
    [
        'value'     => $folder,
        'recursive' => $rec,
    ]
);

but am getting incorrect listing ex.

// using listWith "correct"
/ 
    -> abc 
        -> test
        -> other files...

// using iterator "incorrect"
/ 
    -> abc 
    -> test
    -> other files...

i presume the issue is related the recursive option.

jhofm commented

the second array you pass to the createIterator() method doesn't do anything. if you want to disable recursion you'd need to do it as part of the first array

$fs->createIterator(['recursive' => false, 'list-with' => [...]])

the value parameter specifies what type of values the iterator should return, list item arrays being the default. passing a folder will not work, the first item will always be the directory the filesystem adapter was created with.
but that's just a sidenote, as that second array is simply ignored.

can you clarify what the difference between correct and incorrect is, i'm not sure I understand.
i suppose your adapter starts off at a directory '/abc' and there's a file '/abc/test' and other files in there. you mean you don't expect the root directory to be the first item returned but the test file instead?

jhofm commented

i pushed a commit that automatically forwards the iterator by one if recursion is enabled. assuming i understood your problem correctly that should fix it.

ctf0 commented

here is the usage now

return $this->storageDisk->createIterator(
            [
                'list-with'   => ['mimetype', 'visibility', 'timestamp', 'size'],
                'recursive'   => $rec,
                'path'        => $folder,
            ],
        );

passing a folder will not work, the first item will always be the directory the filesystem adapter was created with.

i think this is the issue, because the usage should follow

as creating a constructor for the disk every time you want to use the plugin is not ideal.

jhofm commented

i didn't really bother with subdirectories since the instantiation cost of the filesystem is negligable and subdirectory support is handled inconsistently between plugins. but it's an easy addition, i made it an optional second parameter like the ListWith plugin does.

return $this->storageDisk->createIterator(
            [
                'list-with'   => ['mimetype', 'visibility', 'timestamp', 'size'],
                'recursive'   => $rec
            ],
            $folder
        );

should work now

ctf0 commented

focken awesome, now it works as expected, many many thanx

ctf0 commented

plz ping me when u release the new changes.

jhofm commented

cool, i'll do some cleanup tomorrow and release the changes as v3.0. thanks for your input!

jhofm commented

the 2.2.0 release is out. not 3.0.0 because i kept it backward-compatible.
a small change compared to yesterday is that the directory in which the iteration starts will be included again, unless the parameter 'skip-root' => true is passed to the config array. otherwise everything should behave the same