1

I'm facing a strange thing here. I'm working on an OpenCart, register form (index.php?route=checkout/register).
I have the form and 2 fields like this:

<span class="required">*</span> <?php echo $entry_email; ?><br />
<input type="text" name="email" value="" class="large-field" /><br />
<br />
<span class="required">*</span> <?php echo $entry_telephone; ?><br />
<input type="text" name="telephone" value="" class="large-field" />

Now: The browser interprets these 2 fields as:

<input type="email" name="email" value="" class="large-field">

and

<input type="tel" name="telephone" value="" class="large-field">

BUT if I change the email field attribute-order like so:

<input type="text" value="" class="large-field" name="email" />

then the fields are truly text types, they don't get transformed.
Attention: I only modify for the first one (email) and after that the email and the telephone are parsed correctly.

I am seeing this unexpected behavior on Firefox, Chrome and Opera,
however, if I copy the inputs in a plain html and view it, they are ok..

Any idea on what is happening, and of course why?

EDIT:
The full HTML that is sent to the browser (retrieved with web-sniffer.net) is in this pastebin: http://pastebin.com/bCXab6Kb

That means that the <input type="text" fields are already changed when php sends the HTML to the browser.
So, what (why/how) converts the <input type="text"> to type email/tel (seemingly based on name attribute) and why does this fail when the input-field's attribute order is changed?

4

2 回答 2

2

OpenCart 到当前稳定版本 1.5.6(和当前版本 1.5.6.1)默认(或在其默认主题中)不使用任何 HTML5(输入字段等)。
这符合:opencart 什么时候开始使用 html5?(12 年 4 月):“人们仍在抱怨 IE6 支持。当人们停止抱怨时,我们就可以开始关注 HTML5 过渡了”

例如,文件checkout/register.tpl(来自 v 1.5.6)(您已修改)默认包含:

<span class="required">*</span> <?php echo $entry_email; ?><br />
<input type="text" name="email" value="" class="large-field" />
<br />
<br />
<span class="required">*</span> <?php echo $entry_telephone; ?><br />
<input type="text" name="telephone" value="" class="large-field" />

但是,在当前的主分支(13 年 12 月)中,我看到某些页面中 HTML5 输入字段的使用不一致(例如:和):account/register.tplaccount/edit.tpl

<div class="form-group required">
  <label class="col-sm-2 control-label" for="input-email"><?php echo $entry_email; ?></label>
  <div class="col-sm-10">
    <input type="email" name="email" value="<?php echo $email; ?>" placeholder="<?php echo $entry_email; ?>" id="input-email" class="form-control" />
    <?php if ($error_email) { ?>
    <div class="text-danger"><?php echo $error_email; ?></div>
    <?php } ?>
  </div>
</div>
<div class="form-group required">
  <label class="col-sm-2 control-label" for="input-telephone"><?php echo $entry_telephone; ?></label>
  <div class="col-sm-10">
    <input type="tel" name="telephone" value="<?php echo $telephone; ?>" placeholder="<?php echo $entry_telephone; ?>" id="input-telephone" class="form-control" />
    <?php if ($error_telephone) { ?>
    <div class="text-danger"><?php echo $error_telephone; ?></div>
    <?php } ?>
  </div>
</div>
<div class="form-group">
  <label class="col-sm-2 control-label" for="input-fax"><?php echo $entry_fax; ?></label>
  <div class="col-sm-10">
    <input type="text" name="fax" value="<?php echo $fax; ?>" placeholder="<?php echo $entry_fax; ?>" id="input-fax" class="form-control" />
  </div>
</div>

请注意传真字段如何具有type="text"和缺少表格(有利于 div),最后是不同的类名。


这给我们带来了您问题中最有趣的部分:什么(为什么/如何)将<input type="text"类型转换为email/ tel(似乎基于名称属性)以及为什么当输入字段的属性顺序更改时这会失败?

正如我们在 PHP 发送到浏览器 ( http://pastebin.com/bCXab6Kb ) 的 HTML 代码中看到的那样,输入字段的类型属性已经改变。因此,改变这一点的不是浏览器或一段 javascript。
因此,假设 PHP 不会自行更改代码,那么 PHP 运行的脚本中必须有一些内容来更改存储在硬盘上的文件中的代码,然后再将其发送到浏览器:OpenCart 和/或(一个of) 它是“主题”、“模块”、“扩展”等
。由于某种 html 解析器可能不会搞砸这么简单的任务,因此最有可能的候选者是某种执行基本搜索和代替。

恰好有 2 个(高度相关的)脚本,与 OpenCart 通用,完全符合这个要求。

  1. OpenCart 的“修改系统”
    如果您不小心下载/安装了“最新”(开发)主分支(或者是贡献者),那么您会发现一些文件,如system/engine/modification.php(以及一些相关文件和数据库表),可以根据目标 php/tpl 文件之前的xml 文件 ( system/modification.xml )中指定的规则搜索和添加/附加/替换 php/tpl 文件中的代码行(硬编码限制)被解析并且不修改原始文件
    这个相当不言自明的 xml 文件基本上包含每个文件的“操作”,以便即时修改,例如:

    <file name="system/engine/front.php">
      <operation>
        <search>
          <![CDATA[$action->getFile()]]>
        </search>
        <add position="replace">
          <![CDATA[$this->registry->get('modification')->getFile($action->getFile())]]>
        </add>
      </operation>
    </file>         
    

    where$action->getFile()被替换为文件解析$this->registry->get('modification')->getFile($action->getFile()) 前!system/engine/front.php

  2. vQmod™</a>”(又名 Virtual Quick Mod)
    vQmod 是一个单独开发的软件包,基本上是 OpenCart 修改系统(上图)的完善版本,它
    起源于. “附加组件”通常使用它来修改 OpenCart 的生产版本并安装(因为它默认不包含在 OpenCart 中)在文件夹中vqmod(位于 OpenCart 的根目录中)。在此文件夹vqcache中,您将找到一个包含缓存修改文件的文件夹和一个xml包含xml search/replace files. 与 OpenCart 的修改系统(上图)相比, 这些 xml 文件的语法(最明显的是属性)
    略有不同:position

    <file name="catalog/view/theme/default/template/checkout/register.tpl">
      <operation>
        <search position="replace">
          <![CDATA[<input type="text" name="email" value="" class="large-field" />]]>
        </search>
        <add>
          <![CDATA[<input type="email" name="email" value="" class="large-field" />]]>
        </add>
      </operation>
      <operation>
        <search position="replace">
          <![CDATA[<input type="text" name="telephone" value="" class="large-field" />]]>
        </search>
        <add>
          <![CDATA[<input type="tel" name="telephone" value="" class="large-field" />]]>
        </add>
      </operation>
      <operation>
        <search position="replace">
          <![CDATA[<input type="text" name="fax" value="" class="large-field" />]]>
        </search>
        <add>
          <![CDATA[<input type="tel" name="fax" value="" class="large-field" />]]>
        </add>
      </operation>
    </file>
    

    注意:上面的示例来自“embermonkey 响应式主题”,是您所体验行为的一个很好的示例:它替换了输入属性。

这些修改脚本的目的是:

避免更改核心文件。这个概念很简单......不是直接对核心文件进行更改,而是将更改创建为 xml 搜索/替换脚本文件。这些脚本文件在页面加载期间被解析,因为每个“源”核心文件都使用“include”或“require”php函数加载。然后使用脚本文件更改对源进行修补,并保存到临时文件中。然后在执行期间用该临时文件替换原始文件。原始源文件永远不会更改。这会导致在执行期间对核心进行“虚拟”更改,而无需对核心文件进行任何实际修改。

这使得“虚拟更改 OpenCart 中的任何 php 或 tpl 文件(主 index.php 除外)”成为可能,以便更新 OpenCart 的核心文件添加/删除模板等变得更容易和更可靠。


email最后,有效的电子邮件地址(letters@gmail.com)在输入类型设置为而不是text...时无法验证。
这是(损坏/过时/部分安装)“响应式”/“ mobile' 主题等(通常也会影响电话领域)1 , 2
问题不在于浏览器拒绝有效的电子邮件地址(当输入字段的类型设置为email而不是 时text);相反,它是 OpenCart 的 JSON 验证器,默认情况下不获取输入类型email(和tel等)(当您或主题未打补丁时):

$('#button-guest').live('click', function() {
   $.ajax({
      url: 'index.php?route=checkout/guest/validate',
      type: 'post',
      data: $('#payment-address input[type=\'text\'], #payment-address input[type=\'checkbox\']:checked, #payment-address input[type=\'radio\']:checked, #payment-address input[type=\'hidden\'], #payment-address select'),
      dataType: 'json',

因此,显然,解决方案是将这些输入类型添加到 AJAX 调用:

$('#button-guest').live('click', function() {
   $.ajax({
      url: 'index.php?route=checkout/guest/validate',
      type: 'post',
      data: $('#payment-address input[type=\'text\']
             , #payment-address input[type=\'email\']   // added
         //  , #payment-address input[type=\'tel\']     // added
             , #payment-address input[type=\'checkbox\']:checked
             , #payment-address input[type=\'radio\']:checked
             , #payment-address input[type=\'hidden\']
             , #payment-address select'
             ),
      dataType: 'json',

总之,使用上面解释的内容:

  • 很可能您要么安装了包含 vQmod 的 OpenCart 的某种“完整”/“流行”重新分发,要么升级了包含 vQmod现有 OpenCart 安装,或者您安装了某种依赖于 vQmod 的附加组件并通过本身。
  • 要查找并禁用此 mod,您首先要在 OpenCart 目录中搜索名为“vQmod”的文件夹。如果找不到它,则对包含<input type="email"(例如)的字符串进行文本搜索(从 OpenCart 目录开始并包括子目录),并首先使用文件类型 xml 调查结果。
  • 要在没有验证(电子邮件、电话、传真等)失败的情况下使用该模块,请修复 JSON 调用(如果它已经安装,您可以使用 vQmod 并将其添加为受影响文件的操作)。
  • 或者(正如您已经注意到的),通过更改属性顺序使 mod 崩溃(以该页面的其他 mod 的价格也像您注意到的那样失败)。
  • 如果上述方法都不适用于您的情况,我强烈建议您重新安装 OpenCart 的干净版本!

PS:现在您知道了 vQmod,您最好使用它(而不是修改核心文件),因为“性能出人意料地似乎根本不是一个因素”,让您受益于更可靠的升级路径未来!

于 2013-12-28T20:22:51.830 回答
0

实际上,您所描述的行为根本不是来自 OpenCart - 至少不是来自具有默认主题的默认安装。

您可以关闭 JS 并直接访问此页面:http://your.ocinstall.com/index.php?route=account/register- 它将打开注册页面。

无论如何,在默认安装(和默认主题)中有这个 HTML:

    <tr>
      <td><span class="required">*</span> <?php echo $entry_email; ?></td>
      <td><input type="text" name="email" value="<?php echo $email; ?>" />
        <?php if ($error_email) { ?>
        <span class="error"><?php echo $error_email; ?></span>
        <?php } ?></td>
    </tr>
    <tr>
      <td><span class="required">*</span> <?php echo $entry_telephone; ?></td>
      <td><input type="text" name="telephone" value="<?php echo $telephone; ?>" />
        <?php if ($error_telephone) { ?>
        <span class="error"><?php echo $error_telephone; ?></span>
        <?php } ?></td>
    </tr>

但在 Firefox 中,属性的顺序仍然发生了变化(但不是属性值!):

<input type="text" value="" name="email" />

在 Chrome 中也是如此 - 没有更改任何属性值。唯一的原因可能是 JavaScript 库和/或正在使用的其他主题。

虽然 OpenCart 的默认主题 HTML 的 doctype被定义为 HTML5,但实际上 OpenCart 并没有使用任何 HTML5 特性。

无论如何,如果您的模板中真正使用了 HTML5,那么请不要害怕并享受这些功能。例如,在您的问题的非常示例中,如果输入的类型为emailor tel,则用户无法提交表单,直到该email字段包含语义正确的电子邮件地址,并且他甚至无法将任何文字(非数字)字符填写到tel字段...(是的,直到用户通过开发人员工具修改 HTML...)

于 2013-12-23T14:29:38.237 回答