4

I'm to validate the creation of a new content node, of a custom content type. It seems I cannot find the right hook.

I tried using hook_node_presave, however, the only way to stop node from creating is to throw an exception. This is rather user unfriendly.

 function custom_module_node_presave($node) {

    if($node->getType()=='custom_content_type'){
            if(some_business_rules_apply()){
                    drupal_set_message('You cannot add a new node.','error');
                    # cancel saving 
                    throw new \Exception(t('You cannot add a new node.'));
            }else{
                    # do something more
            }
    }
}

I tried to use hook_node_validate but it seems like it is not called. Do I miss something? Maybe, I use the wrong name for the hook function? Is there some kind of example for hook_node_validate?

function custom_type_node_validate(\Drupal\Core\Entity\EntityInterface $node, $form, &$form_state){
    \Drupal::logger('My logger')->info('Node validate');
}

1 Answer 1

14

In Drupal 8 the hook hook_node_validate() has been removed. Here are some suggestions.

Reference: hook_node_validate() and hook_node_submit() have been removed.

Field constraints

If you're trying to validate an individual field, use a constraint.

/**
 * Implements hook_entity_bundle_field_info_alter().
 */
function custom_general_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
  // Alter node.page.field_service.
  if ($entity_type->id() === 'node' && $bundle === 'page') {
      $fields['field_service']->addConstraint('CustomAssignableService', []);
  }

Entity constraints

For general constraints on the entire entity or constraints which are not specific to a single field.

/**
 * Implements hook_entity_type_alter().
 */
function custom_general_entity_type_alter(array &$entity_types) {
  if (isset($entity_types['node'])) {
    $entity_types['node']->addConstraint('CustomAuthorizedTerritory');
  }
}

Form validation

The "constraints" will always validate the field / entity no matter the form / method with which you use save the entity.

Additionally, you can provide form validation using a hook_node_form_alter() to improve the UX with nice error messages.

Note: These are "form-level" validations and are only applied when the node is created / updated from a said form. Users might be able to bypass these restrictions while saving the node using web services or other forms (if any).

// In the mymodule.module file.

/**
 * Implements hook_form_FORM_ID_form_alter().
 */
function mymodule_form_node_form_alter(&$form, FormStateInterface $form_state) {
  $form['#validate'][] = 'mymodule_node_form_validate';
}

function mymodule_node_form_validate($form, FormStateInterface $form_state) {
  $node = $form_state->getFormObject()->getEntity();
  if ($node->getType() == 'custom_content_type') {
    if ($form_state->getValue('some_property') !== '123') {
      $form_state->setErrorByName('some_property', t('Property must be 123.'));
    }
  }
}
1
  • 4
    You can always add a constraint directly on the node with hook_entity_type_alter() as well if it's not a single/specific field that you want to validate. Something like $entity_types['node']->addConstraint('MyCustomConstraint'); Then in there check the type.
    – Berdir
    Commented Dec 30, 2016 at 22:20

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.