How to add an image upload field in a custom Field Type I'm defining a new custom Field Type in Drupal 8, let's say MyFieldType, with custom widget and formatter also.

Such Field Type should have these two fields:


text: a simple text value
image: a field where the user that use this Field Type can upload an image, as the built-in image field type.


I created the custom field type with the text field with no problems. Now I'm trying to add the image field also, but I'm stuck and I don't understand how to proceed.

What is the correct way to add an image upload field in a custom Field Type?



What I tried

Below there are the main parts from the custom Field Type. All files are from the folder modules\custom\my_field_type\src\Plugin\Field.

From the file FieldType\MyFieldType.php:

class MyFieldType extends FieldItemBase {

  //

  public static function propertyDefinitions(
    FieldStorageDefinitionInterface $field_definition
  ) {

    $properties['text'] = DataDefinition::create('string')
        -&gt;setLabel(t('Text Value'));

    // $properties['image'] ... go here?
    // ...

    return $properties;
  }

  //

  public static function schema(
    FieldStorageDefinitionInterface $field_definition
  ) {

    $columns = array(

      'text' =&gt; array(
        'type' =&gt; 'varchar',
        'length' =&gt; 255,
      ),

      // What column for the 'image' field?
      // ...

    );

    $schema = array(
      'columns' =&gt; $columns,
    );

    return $schema;
  }

}


From the file FieldWidget\MyFieldTypeWidget.php:

class MyFieldTypeWidget extends WidgetBase {

  public function formElement(
    FieldItemListInterface $items,
    $delta, 
    Array $element, 
    Array &amp;$form, 
    FormStateInterface $formState
  ) {

    $element['value'] = [
      '#type' =&gt; 'textfield',
      '#title' =&gt; t('Value'),
      '#default_value' =&gt; isset($items[$delta]-&gt;value) ? 
          $items[$delta]-&gt;value : null,
      '#empty_value' =&gt; '',
    ];

    $element['image'] = [
      '#type' =&gt; 'file',
      '#title' =&gt; t('Image'),

      '#default_value' =&gt; isset($items[$delta]-&gt;image) ? 
        $items[$delta]-&gt;image : null,

      '#empty_value' =&gt; '',
    ];

    return $element;
  }

}


I can see the file upload field in the edit form (adding a new field with this custom type), but I don't know how to go on and (eventually) how to handle the uploaded image inside the class MyFieldType.
What you want to do, is to save a reference to the file which is uploaded. 

Since what you are making is an image upload with extra text field, you should consider using either


\Drupal\image\Plugin\Field\FieldWidget\ImageWidget
\Drupal\image\Plugin\Field\FieldWidget\FileWidget


as foundation to your widget. That way you should be able to reuse much of the trick image/file handling and just add custom parts or overrides for your custom widget.

You should also consider using either


\Drupal\image\Plugin\Field\FieldType\ImageItem
Drupal\file\Plugin\Field\FieldType\FileItem


as foundation to your field type, since they also handle a lot of things for you. The image variant adds a lot of stuff, like alt, height, width, which is something you probably want/need at some point, so no reason making all of this yourself.