2

I need to upload a file to my server via a custom field type and I'm trying it like this:

    public function prepValueFromPost($value)
{
    // Get file
    $file = \CUploadedFile::getInstanceByName('fields[handle]');

    // Determine folder
    $folder = 'folder/to/upload';

    // Ensure folder exists
    IOHelper::ensureFolderExists($folder);

    // Get filepath - save in storage folder
    $path = $folder . $file->getName();

    // Save file to Craft's temp folder for later use
    $file->saveAs($path);
}

public function getInputHtml($name, $value)
{   
    return craft()->templates->render('_includes/forms/file', array(
        'name'  => $name,
        'value' => $value,
    ));
}

This sadly ends up in the following error:

Fatal error: Call to a member function getName() on a non-object in...

Does anyone have an idea how to solve this? My file input has the name "fields[handle]" but i also tried "handle" but nothing changes...

1 Answer 1

4

Yii’s CUploadedFile class actually doesn’t support retrieving uploaded files that came from a file input whose name was “namespaced” (e.g. name="fields[handle]" rather than just name="handle").

However, Craft has its own UploadedFile class which extends CUploadedFile, and the whole point of it is to add that namespaced input name support. It uses a dot syntax rather than square brackets, so if a file input had the name fields[handle], you would fetch that file like this:

$file = UploadedFile::getInstanceByName('fields.handle');

Problem is, you can’t actually rely on the file input name having a fields namespace – it will vary depending on the form. In fact many element forms within Craft have randomized namespaces (e.g. the Quick Post dashboard widget, or the modal windows that come up when you double-click on an element within a relational field).

That’s why field types have a getContentPostLocation() method, which returns the input name that would have been used for the current field, namespace and all, converted into dot syntax. So you can plug that value directly into getInstanceByName() and get your uploaded file.

$contentPostLocation = $this->getContentPostLocation();

if ($contentPostLocation)
{
    $file = UploadedFile::getInstanceByName($contentPostLocation);

    // ...
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.