sitilge
sitilge

Reputation: 3737

Insert a file into specific directory/node using vfsStream

The use case of vfsStream is as follows:

$directories = explode('/', 'path/to/some/dir');

$structure = [];
$reference =& $structure;

foreach ($directories as $directory) {
    $reference[$directory] = [];
    $reference =& $reference[$directory];
}

vfsStream::setup();
$root = vfsStream::create($structure);
$file = vfsStream::newFile('file')
    ->at($root) //should changes be introduced here?
    ->setContent($content = 'Some content here');

The output of vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure() is

Array
(
    [root] => Array
    (
        [path] => Array
        (
            [to] => Array
            (
                [some] => Array
                (
                    [dir] => Array
                    (
                    )
                )
            )
        )

        [file] => Some content here
    )
)

Is it possible to insert a file into specific directory, for example, under dir directory?

Upvotes: 3

Views: 1608

Answers (2)

sitilge
sitilge

Reputation: 3737

The answer was given on github; thus instead of

->at($root)

one should use

->at($root->getChild('path/to/some/dir')).

Upvotes: 0

Yes, apparently it is possible to add a child to a vfsStreamFirectory with the addChild() method:

However I've found no simple method in the API Docs that allow for easily traversing a structure to add content. Here is a horrible hacky of doing this for this particular case, it would fail if for instance there were more than one folder per path element.

Basically we have to recursively step through each level, verify if the name is the one to which we want to add the file, then add it when it's found.

use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
use org\bovigo\vfs\visitor\vfsStreamStructureVisitor;

$directories = explode('/', 'path/to/some/dir');

$structure = [];
$reference =& $structure;

foreach ($directories as $directory) {
    $reference[$directory] = [];
    $reference =& $reference[$directory];
}

vfsStream::setup();
$root = vfsStream::create($structure);
$file = vfsStream::newFile('file')
    ->setContent($content = 'Some content here');

$elem = $root;
while ($elem instanceof vfsStreamDirectory)
{
    if ($elem->getName() === 'dir')
    {
        $elem->addChild($file);
    }
    $children = $elem = $elem->getChildren();
    if (!isset($children[0]))
    {
        break;
    }
    $elem = $children[0];
}

print_r(vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure());

Upvotes: 1

Related Questions