unique_field_ajax.module in Unique field ajax 8
Same filename and directory in other branches
Unique value for cck fields check module.
File
unique_field_ajax.moduleView source
<?php
/**
* @file
* Unique value for cck fields check module.
*/
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\field\Entity\FieldConfig;
/**
* Implements hook_help().
*/
function unique_field_ajax_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the unique_field_ajax module.
case 'help.page.unique_field_ajax':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Unique Field module allows administrators to require that content supplied for specified fields is unique.') . '</p>';
return $output;
default:
}
}
/**
* Implements hook_form_BASE_FORM_ID_alter().
*
* Removes the default values form from the field settings page.
* Users expect to use the default value form to predefine only certain values
* on the widget, but Drupal expects the default value to be complete, and used
* whenever an actual address isn't provided. Therefore it's preferable to
* hide this functionality and implement our own via custom widget settings.
*/
function unique_field_ajax_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$field = $form_state
->getFormObject()
->getEntity();
$unique_field_ajax_types = [
'string',
'list_string',
'text',
'email',
'entity_reference',
'path',
'uri',
];
if (!$field
->getFieldStorageDefinition()
->isMultiple()) {
if (in_array($field
->getType(), $unique_field_ajax_types)) {
$form['third_party_settings']['unique_field_ajax']['unique'] = array(
'#type' => 'checkbox',
'#title' => t("Unique"),
'#default_value' => $field
->getThirdPartySetting('unique_field_ajax', 'unique'),
'#weight' => -10,
);
$form['third_party_settings']['unique_field_ajax']['per_lang'] = array(
'#type' => 'checkbox',
'#title' => t("Per Language"),
'#description' => t("Do not allow duplicated content per language"),
'#default_value' => $field
->getThirdPartySetting('unique_field_ajax', 'per_lang'),
'#weight' => -9,
'#states' => array(
'visible' => array(
':input[name="third_party_settings[unique_field_ajax][unique]"]' => array(
'checked' => TRUE,
),
),
),
);
$form['third_party_settings']['unique_field_ajax']['use_ajax'] = array(
'#type' => 'checkbox',
'#title' => t("Use Ajax"),
'#description' => t("Use ajax for validation."),
'#default_value' => $field
->getThirdPartySetting('unique_field_ajax', 'use_ajax'),
'#weight' => -8,
'#states' => array(
'visible' => array(
':input[name="third_party_settings[unique_field_ajax][unique]"]' => array(
'checked' => TRUE,
),
),
),
);
$form['third_party_settings']['unique_field_ajax']['message'] = array(
'#type' => 'textarea',
'#title' => t("Error message"),
'#description' => t("The message to show under the field when the value is not unique"),
'#default_value' => $field
->getThirdPartySetting('unique_field_ajax', 'message'),
'#weight' => -7,
'#states' => array(
'visible' => array(
':input[name="third_party_settings[unique_field_ajax][unique]"]' => array(
'checked' => TRUE,
),
),
),
);
}
}
}
/**
* Attaching data to unique fields.
*
* @param $element
* @param \Drupal\Core\Form\FormStateInterface $form_state
* @param $context
*/
function unique_field_ajax_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {
$field_definition = $context['items']
->getFieldDefinition();
$name = $field_definition
->getFieldStorageDefinition()
->getName();
if ($field_definition instanceof FieldConfig) {
$is_unique_per_lang = NULL;
if (\Drupal::moduleHandler()
->moduleExists('language') && \Drupal::languageManager()
->getCurrentLanguage()
->getId()) {
$is_unique_per_lang = $field_definition
->getThirdPartySetting('unique_field_ajax', 'per_lang');
}
if ($field_definition
->getThirdPartySetting('unique_field_ajax', 'unique')) {
$element['value']['#unique_field_ajax_settings'] = [
'per_lang' => $is_unique_per_lang,
'field_definition' => $field_definition,
'field_name' => $name,
];
$element['value']['#element_validate'][] = 'unique_field_ajax_validate_unique';
if ($field_definition
->getThirdPartySetting('unique_field_ajax', 'use_ajax')) {
$element['#process'] = [
'_unique_field_ajax_process',
];
}
}
}
}
/**
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
* @return mixed
*/
function _unique_field_ajax(array &$form, FormStateInterface $form_state) {
$element = $form_state
->getTriggeringElement();
return NestedArray::getValue($form, $element['#array_parents']);
}
/**
* Attach ajax to unique field.
*
* @param $element
* @param \Drupal\Core\Form\FormStateInterface $form_state
* @param $form
*
* @return mixed
*/
function _unique_field_ajax_process($element, FormStateInterface &$form_state, &$form) {
$field_name = $element['value']['#unique_field_ajax_settings']['field_name'];
$field_definition = $element['value']['#unique_field_ajax_settings']['field_definition'];
$field_label = $field_definition
->label();
$wrapper = 'unique-' . $field_name;
if (!empty($form['#attached']['library']) && !in_array('unique_field_ajax/unique_event', $form['#attached']['library'])) {
$form['#attached']['library'][] = 'unique_field_ajax/unique_event';
}
$settings = array(
'id' => '#' . $wrapper . ' input',
);
$form['#attached']['drupalSettings']['unique_field_ajax'][] = $settings;
$element['value']['#ajax'] = [
'callback' => '_unique_field_ajax',
'event' => 'finishedinput',
'wrapper' => $wrapper,
'progress' => array(
'type' => 'throbber',
'message' => t('Verifying @field_label...', array(
'@field_label' => $field_label,
)),
),
];
$element['value']['#prefix'] = '<div id="' . $wrapper . '">';
$element['value']['#suffix'] = '</div>';
$value = $form_state
->getValue($field_name);
$value = !empty($value) ? $value[0]['value'] : NULL;
$entity = $form_state
->getFormObject()
->getEntity();
$entity_type = $entity
->getEntityTypeId();
$langcode = !empty($form_state
->getValues()['langcode'][0]['value']) ? $form_state
->getValues()['langcode'][0]['value'] : '0';
$valid = unique_field_ajax_is_unique($entity_type, $langcode, $field_name, $value, $entity
->bundle(), $element['value']['#unique_field_ajax_settings']['per_lang'], $entity);
$message = $field_definition
->getThirdPartySetting('unique_field_ajax', 'message');
if (empty($message)) {
$message = t('This field has to be unique.');
}
if (!$valid) {
$element['value']['#attributes']['class'][] = 'error';
$element['value']['#attributes']['aria-invalid'] = 'true';
$element['value']['#suffix'] = '<div class="error">' . $message . '</div>' . $element['value']['#suffix'];
}
return $element;
}
/**
* Ajax callback to validate the email field.
*/
function unique_field_ajax_validate_unique($element, FormStateInterface $form_state, array $form) {
$entity = $form_state
->getFormObject()
->getEntity();
// If !isset langcode set it to 0.
$langcode = !empty($form_state
->getValues()['langcode'][0]['value']) && $form_state
->getValues()['langcode'][0]['value'] ? $form_state
->getValues()['langcode'][0]['value'] : '0';
$field_name = $element['#unique_field_ajax_settings']['field_name'];
$field_definition = $element['#unique_field_ajax_settings']['field_definition'];
$field_label = $field_definition
->label();
$value = $form_state
->getValue($field_name);
$entity_type = $entity
->getEntityTypeId();
// If field is not unique set error.
$valid = unique_field_ajax_is_unique($entity_type, $langcode, $field_name, $value[0]['value'], $entity
->bundle(), $element['#unique_field_ajax_settings']['per_lang'], $entity);
if (!$valid) {
$form_state
->setErrorByName($field_name, t('The field @field_label has to be unique.', array(
'@field_label' => $field_label,
)));
$form_state
->setRebuild();
}
}
/**
* Test if the field value already exist in the database.
*
* @param $entity_type
* @param $langcode
* @param $field_name
* @param $field_value
* @param $bundle
* @param $is_unique_per_lang
*
* @return array|int
*/
function unique_field_ajax_is_unique($entity_type, $langcode, $field_name, $field_value, $bundle, $is_unique_per_lang, $entity) {
$entity_type_definition = Drupal::entityTypeManager()
->getDefinition($entity_type);
$query = Drupal::entityQuery($entity_type)
->condition($field_name, $field_value, '=');
// Test if the entity has a bundle.
if (!empty($entity_type_definition
->getKey('bundle'))) {
$query
->condition($entity_type_definition
->getKey('bundle'), $bundle, '=');
}
// Test unique per language.
if ($is_unique_per_lang) {
$query
->condition('langcode', $langcode);
}
$entities = $query
->execute();
if (!empty($entities)) {
if ($id = $entity
->id()) {
if (!in_array($id, $entities)) {
return FALSE;
}
}
else {
return FALSE;
}
}
return TRUE;
}
Functions
Name![]() |
Description |
---|---|
unique_field_ajax_field_widget_form_alter | Attaching data to unique fields. |
unique_field_ajax_form_field_config_edit_form_alter | Implements hook_form_BASE_FORM_ID_alter(). |
unique_field_ajax_help | Implements hook_help(). |
unique_field_ajax_is_unique | Test if the field value already exist in the database. |
unique_field_ajax_validate_unique | Ajax callback to validate the email field. |
_unique_field_ajax | |
_unique_field_ajax_process | Attach ajax to unique field. |