Search code examples
silverstripe-4

Create file dynamically as File object and then publish


It's evidently a little more complicated to create a file dynamically in SS4

$folder = Folder::find_or_make('Cards');
$filename = 'myimage.jpg';
$contents = file_get_contents('http://example.com/image.jpg');
$pathToFile = Controller::join_links(Director::baseFolder(), ASSETS_DIR, $folder->Title, $filename);
file_put_contents($pathToFile, $contents);

$image = Image::create();

$image->ParentID = $folder->ID;
$image->Title = "My title";
$image->Name = $filename;
$image->FileFilename = 'Cards/' . $filename;
$image->write();

Member::actAs(Member::get()->first(), function() use ($image, $folder) {
    if (!$image->isPublished()) {
        $image->publishFile();
        $image->publishSingle();
    }
    if (!$folder->isPublished()) {
        $folder->publishSingle();
    }
});

The above, creates the file as expected in /assets/Cards/myimage.jpg and publishes it fine

However all previews are blank, so it's obviously not finding the file:

All previews are blank

Any idea what I missed in creating the Image object?


Solution

  • This should work:

    $folder = Folder::find_or_make('Cards');
    $contents = file_get_contents('http://example.com/image.jpg');
    
    $img = Image::create();
    $img->setFromString($contents, 'image.jpg');
    $img->ParentID = $parent->ID;
    $img->write();
    
    // This is needed to build the thumbnails
    \SilverStripe\AssetAdmin\Controller\AssetAdmin::create()->generateThumbnails($img);
    $img->publishSingle();
    

    FYI: $img->Filename no longer exists. An Image or File object have a File property, which is a composite field of type DBFile. This composite fields contains the filename, hash and a variant… So you should use the composite field to address these fields.