You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drupal Commerce结账:绕过邮箱验证存储文本至数据库的方法

问题描述

匿名访客在Drupal Commerce结账流程的「订单信息」步骤中,需在指定邮箱输入框填写内容,该内容会存入数据库commerce_order表的mail字段。输入框代码如下:

<input data-drupal-selector="edit-contact-information-email" type="email" id="edit-contact-information-email" name="contact_information[email]" value="" size="60" maxlength="254" class="form-email required" required="required" aria-required="true">

尝试通过JS修改输入框文本并将type改为text后,数据仍无法存入数据库,推测存在邮箱验证逻辑。需明确:

  1. 该验证逻辑在JS或PHP中的位置?
  2. 如何解决此问题?
解决方案

一、验证逻辑的位置

1. PHP端(核心验证,决定数据是否入库)

Drupal Commerce的订单邮箱验证核心在PHP层,主要分布在这几个位置:

  • 结账表单验证:结账流程的表单类(通常是src/Form/CheckoutForm.php或对应结账流程的表单文件)的validateForm()方法中,会调用邮箱验证器检查格式。
  • 实体字段约束:commerce_order实体的mail字段在src/Entity/Order.php的baseFieldDefinitions()方法里,被定义为EmailItem类型,自带邮箱格式约束;也可能在模块的schema配置文件(config/schema/commerce_order.schema.yml)中定义了格式规则。
  • 自定义钩子验证:如果有自定义模块或主题,可能通过hook_form_alter()或hook_entity_bundle_field_info_alter()添加了额外的邮箱验证规则。

2. JS端(前端拦截,仅阻止表单提交)

前端验证是辅助性的,触发点包括:

  • Drupal核心的core/misc/form.js会识别form-email类,对输入框做前端邮箱格式校验,不符合规则时阻止表单提交。
  • Commerce结账流程的专属JS(如commerce_checkout模块下的js/checkout.js)可能也有额外的前端验证逻辑。

二、解决方法

方法一:修改实体字段约束(推荐,无侵入)

自定义一个模块,通过钩子修改mail字段的类型约束,移除邮箱格式要求:

/**
 * Implements hook_entity_bundle_field_info_alter().
 */
function my_custom_module_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
  if ($entity_type->id() === 'commerce_order' && $bundle === 'default' && isset($fields['mail'])) {
    // 将邮箱字段改为普通字符串类型,保留必填属性
    $fields['mail']->setItemDefinition(\Drupal\Core\Field\BaseFieldDefinition::create('string')
      ->setLabel(t('Contact email'))
      ->setDescription(t('The contact information.'))
      ->setRequired(TRUE)
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'weight' => 0,
      ])
      ->setDisplayConfigurable('form', TRUE));
  }
}

执行后清除Drupal缓存,mail字段即可存储任意文本字符串。

方法二:修改表单验证逻辑

如果只需要针对结账表单取消验证,可通过钩子修改表单的验证规则:

/**
 * Implements hook_form_FORM_ID_alter().
 */
function my_custom_module_form_commerce_checkout_flow_multistep_default_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  // 移除邮箱字段的验证回调
  if (isset($form['contact_information']['email']['#element_validate'])) {
    unset($form['contact_information']['email']['#element_validate']);
  }
  // 替换字段类型为普通文本输入
  $form['contact_information']['email']['#type'] = 'textfield';
}

注意:FORM_ID需要替换为你实际使用的结账表单ID,可通过浏览器开发者工具查看表单的id属性获取。

方法三:前后端配合处理

  1. 前端:用JS移除前端验证标记,取消前端拦截:
document.addEventListener('DOMContentLoaded', function() {
  const emailInput = document.getElementById('edit-contact-information-email');
  if (emailInput) {
    emailInput.type = 'text';
    emailInput.classList.remove('form-email');
    // 清除Drupal绑定的验证器
    delete emailInput.dataset.drupalValidator;
  }
});
  1. 后端:配合上述PHP端的修改(方法一或方法二),确保后端不再验证邮箱格式,才能让数据顺利入库。

内容的提问来源于stack exchange,提问作者stckvrw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:30:41