0

I am trying to get the values from an uploaded image inside a media entity during form submit.

Where my approach doesn't work:

  1. When first uploading an image in the media_image_add_form form.
  2. When editing an existing media entity and removing, then uploading a new image and trying to save.

My validation only works when editing and submitting an existing media entity (without changing the uploaded image file).

Here is my entire code for brevity, though it may be long, MYMODULE.module:

/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  if ($form_id == 'media_image_add_form' || $form_id == 'media_image_edit_form') {

    if ($form_state->getFormObject()->getEntity()->get("field_media_image")->entity) {

      $form['#validate'][] = '_MYMODULE_validate';
    }
  }
}

/**
 * Validates submission values in the FORM_ID() form.
 */
function _MYMODULE_validate(array &$form, FormStateInterface $form_state) {

  // $imageEntity = File::load($form_state->getValues()['field_media_image'][0]['fids'][0]); // Tried File::load here as well.
  $imageField = $form_state->getFormObject()->getEntity()->get("field_media_image");
  $imageEntity = $imageField->entity;
  $imageFileSize = $imageEntity->getSize();
  $imageFileMime = $imageEntity->getMimeType();
  $imageFileName = $imageEntity->getFilename();
  $isIssue = FALSE;
  $showConditionalMessage = FALSE;
  $ciuMessage = "";
  $ignoreWarnings = $form_state->getValues()['field_ignore_warnings']['value']; // Field set on media image entity type.

  // Conditional issue.
  if ($ignoreWarnings === 0 && $imageFileMime === "image/jpeg" && $imageFileSize / 1000 > 150) {
    $isIssue = TRUE;
    $showConditionalMessage = TRUE;
    $ciuMessage .= "<p>Conditional: This JPG file size is larger than 150kb, have you optimized this JPG image?</p>";
  }

  // Conditional issue.
  if ($ignoreWarnings === 0 && $imageFileMime === "image/png" && $imageFileSize / 1000 > 200) {
    $isIssue = TRUE;
    $showConditionalMessage = TRUE;
    $ciuMessage .= "<p>Conditional: This PNG file size is larger than 200kb, have you optimized this PNG image?</p>";
  }

  // Non-conditional issue.
  if (strpos($imageFileName, ' ') !== false) {
    $isIssue = TRUE;
    $ciuMessage .= "<p>Filenames cannot contain spaces.</p>";
  }

  // Non-conditional issue.
  if (strtolower($imageFileName) !== $imageFileName) {
    $isIssue = TRUE;
    $ciuMessage .= "<p>Filenames need to be in all lowercase.</p>";
  }

  if ($isIssue) {
    if ($showConditionalMessage) {
      $ciuMessage .= '<small>To ignore conditional errors, check the "Ignore conditional errors" checkbox below.</small>';
    }
    $form_state->setErrorByName('title', new FormattableMarkup($ciuMessage, []));
  }
}

One caveat for using hook_form_alter() is that some of the errors are conditional, and I would like to provide a field on the media entity type to allow ignoring some of the errors.

How can I get the uploaded file/values in $form_state when adding an image to a new media entity, or adding a new image to an existing media entity?

1

Normally you use a ConstraintValidator for validating entities. In this case core invokes a hook so that you can add your own error messages to the existing file validation process:

function hook_file_validate(Drupal\file\FileInterface $file) {
  $errors = [];

  if (!$file->getFilename()) {
    $errors[] = t("The file's name is empty. Please give a name to the file.");
  }
  if (strlen($file->getFilename()) > 255) {
    $errors[] = t("The file's name exceeds the 255 characters limit. Please rename the file and try again.");
  }

  return $errors;
}

About the caveat for using form alter. You can add custom #upload_validatorsto the image widget. Add settings if necessary:

$element['#upload_validators']['my_custom_file_validator'] = [$my_setting];
2
  • It looks like custom validators are implemented just like hook_file_validate, does the $my_settings array allow more than just validation parameters against setting errors? Not sure how this might allow adding other form elements (or other interaction) a user could interact with to ignore certain errors? Feb 28 at 23:05
  • 1
    It might be possible that the interaction you plan are not possible in the existing file validation process. Then attach an entity validator to the parent field object or media/node entity. This doesn't integrate in the Ajax driven file validation, though, you get the error message in a separate step. See drupal.stackexchange.com/questions/286438/…
    – 4k4
    Mar 1 at 7:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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