Drupal 8 Commerce 2 - Create a custom pane with an upload field.

July 11, 2020

This example assumes you only have one order type and one order item type, if you have more than one of these then you will need to check for the product you are dealing with to determine whether an upload field is required or not during the checkout.

Step 1. Create a file field on the order item type

Go to -> Commerce > Configuration > Orders > Order item types and then manage fields on your order item type and add a File field, this example I will call this field 'field_file_upload'.

 

add field

Step 2. Create a custom module

For this example the module name is "commerce_custom_pane". There are only 2 files in the module -

1. commerce_custom_pane/commerce_custom_pane.info.yml

2. commerce_custom_pane/src/Commerce/CheckoutPane/CustomPaneWithUploadField.php

commerce_custom_pane
 commerce_custom_pane.info.yml
 / src
   / Commerce
    / CheckoutPane
        CustomPaneWithUploadField.php

Step 2a. First we create the info.yml module file to tell Drupal about our module and its dependencies.

# commerce_custom_pane.info.yml 
name: Commerce custom pane 
description: A custom pane with an upload field 
package: Custom 
type: module 
core: '8.x' 
dependencies: - drupal:commerce

 

Step 2b. Now we create the CustomPaneWithUploadField.php file.

Commerce checkout panes are annotation-based plugins, so we start by placing a @CommerceCheckoutPane annotation right before our class definition. Also, the buildPaneForm() method is required, so we'll add that in as well. The submitPaneForm() is called when the user submits the pane.

You should include an id and a label also. It is usually best practice to prefix your id with the name of your module, in this instance I have used 'commerce_custom_pane_file_upload', as I may later add more custom panes which I would name something like 'commerce_custom_pane_custom_message'.


<?php

namespace Drupal\commerce_custom_pane\Plugin\Commerce\CheckoutPane;

use Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\CheckoutPaneBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Entity\File;

/**
 * Provides a pane to upload images for projects.
 *
 * @CommerceCheckoutPane(
 *   id = "commerce_custom_pane_file_upload",
 *   label = @Translation("File Upload Pane"),
 * )
 */
class CustomPaneWithUploadField extends CheckoutPaneBase {

  /**
   * {@inheritdoc}
   */
  public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {

    // Get all items in the order and loop through them adding an upload field for eacg item

    foreach ($this->order->getItems() as $item) {

      $form['file_upload_'. $item->id()] = [
        '#type' => 'managed_file',
        '#title' => $this->t('Upload file'),
        '#upload_location' => 'private://client_uploads', // Can also use 'public://'
        '#required' => TRUE,
        '#upload_validators' => [
          'file_validate_extensions' => ['zip'], // Limit to any file extension(s) here
        ],
      ];
    }
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitPaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) {
    // Get the pane values
    $pane = $form_state->getValue('commerce_custom_pane_file_upload'); // The id we annotated earlier

    // Loop through each item on the order
    foreach ($this->order->getItems() as $item) {

      // Get the uploaded file
      $fid = $pane['file_upload_'.$item->id()][0];
      // Make the file managed
      $file = File::load($fid);
      $file->setPermanent();
      $file->save();
   
      // Add the file id to the file reference field on the order item
      $item->set('field_file_upload', $file->id());
      $item->save();
    }
  }
}

 

Step 3. Install your module and enable your custom pane

Go to Extend in the menu and install your custom module.

Next go to Commerce > Configuration > Orders > Checkout flow and edit your checkout flow, your new pane should be in the disabled section, simply drag into the checkout stage which is appropriate and click save.

Great, your pane should now appear during checkout.

You can check that your file has been added to the order item after your have completed a order by going to your order Commerce > Order then clicking edit on your order item and then looking at the order items.

Now click edit on one of your order items and your file should be present in a reference field.