Craft 3 Custom Field Type with a File Uploader I have a custom field type I am porting from Craft 2 to Craft 3.

This field type used prepValueFromPost to grab a reference to a just uploaded file and then saves said file to an appropriate place for temporary storage (the file is sent on to a ticketing system which keeps its own copy so really it's only needed here for a few seconds).  The actual field value is jsut set to the full file path/name as a record.

I'm really struggling to port this across to Craft 3 as this area has seemingly been re-factored a lot...

I think I need to use serializeValue in place of prepValueFromPost, but I can't grab the actual filename from input in there and the value received is null (I expected it to be the filename..but it's not).  I used to use getContentPostLocation(); for this.

My specific questions are - is serializeValue() the right place to do this?  I want it to occur, once (per field - this is in a matrix), when the element (a Commerce Order) is saved.

And - how do I get the name of the uploaded file (i.e. what has replaced getContentPostLocation).

Here is the code that worked in Craft 2.

    public function prepValueFromPost($value, $element)
{

    $finalFilePath = null;

    //Weird function that works out the dynamic name of this field
    $filename = $this-&gt;getContentPostLocation();
    $file = UploadedFile::getInstanceByName($filename);

    //Save the file where we want it, delete the temporary file
    $outputDir = craft()-&gt;path-&gt;getTempPath() . "BusinessLogicPlugin_upload_" . time();
    IOHelper::ensureFolderExists($outputDir);
    //Was needed on dev, can't really hurt...leave it here.
    chmod($outputDir, 0775);

    $finalFilePath = $outputDir ."/" . $file-&gt;name;

    if(!($file-&gt;saveAs($finalFilePath, false))){
        BusinessLogicPlugin::log("Unable to save actual file [$finalFilePath], file will not be attached");
        $finalFilePath = "";
    }

    //Save the pathname of the file, if we were able to save it, otherwise empty string.
    return $finalFilePath;
}
Just as a little example how to store files in a custom field

/**
 * @inheritdoc
 */
public function normalizeValue($value, ElementInterface $element = null)
{

    $namespace = $element? $element-&gt;getFieldParamNamespace() . '.' : '';
    $file = UploadedFile::getInstanceByName($namespace . $this-&gt;handle);
    if($file !== null){
        // replace this
        $somePath = __DIR__ . DIRECTORY_SEPARATOR . $file-&gt;name;
        $file-&gt;saveAs($somePath);
    }
    return $file;
}

/**
 * @inheritdoc
 */
public function getInputHtml($value, ElementInterface $element = null): string
{
    Craft::$app-&gt;getView()-&gt;registerJs('Craft.cp.$primaryForm.attr(\'enctype\', \'multipart/form-data\');');
    return '&lt;input type="file" name="' . $this-&gt;handle . '"&gt;';
}


Edit:

If you want to store the file path in your Database you would check if $value is an instance of File and if so return the path. Otherwise just declare your field has contentColumn = false