【问题标题】:OpenCart changes type attributes of inputfieldsOpenCart 更改输入字段的类型属性
【发布时间】:2013-12-21 23:51:00
【问题描述】:

我在这里遇到了一件奇怪的事情。我正在开发 OpenCart,注册表单 (index.php?route=checkout/register)。
我有这样的表单和 2 个字段:

<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" />

现在:浏览器将这两个字段解释为:

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

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

但是,如果我像这样更改电子邮件字段属性顺序:

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

那么这些字段是真正的文本类型,它们不会被转换。
注意:我只修改第一个(电子邮件),然后解析电子邮件和电话正确。

我在 Firefox、Chrome 和 Opera 上看到了这种意外行为,
但是,如果我将输入复制到纯 html 中并查看它,它们就可以了..

知道发生了什么,当然还有为什么?

编辑:
发送到浏览器的完整 HTML(使用 web-sniffer.net 检索)在此 pastebin 中:http://pastebin.com/bCXab6Kb

这意味着当 php 将 HTML 发送到浏览器时,&lt;input type="text" 字段已经更改。
那么,什么(为什么/如何)将&lt;input type="text"&gt; 转换为类型email/tel(似乎基于名称属性)以及为什么当输入字段的属性顺序更改时会失败?

【问题讨论】:

  • 认真使用一些\n ...我在这个混乱中什么也看不懂。谢谢
  • @dan:我对其进行了编辑以整理标记。现在就来看看吧。
  • 感谢编辑,抱歉我赶时间:P
  • 可能是两件事改变了它:JavaScript 或“智能”自动检测并相应转换它的浏览器,我相信您可能正在使用 Chrome?
  • 我也想过js,但不是。无论如何这都没有意义,因为 js 也会找到并更改该输入,它不关心属性的顺序。我也想到了浏览器。顺便说一句,是的,它是 Chrome。我不认为这可以,我的意思是浏览器绝对不应该改变我们的属性,它会导致严重的问题。也许这只是我的意见......

标签: php html opencart user-input input-field


【解决方案1】:

OpenCart 到当前稳定的 version 1.5.6(和当前的 version 1.5.6.1)默认(或在其默认主题中)不使用任何 HTML5(输入字段等)。
这符合:When will opencart start to use html5?(2012 年 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" />

但是,在当前的 master-branch(2013 年 12 月)中,我 am 看到了一些 inconsistentsome 中使用 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)以及不同的类名。


这将我们带到您问题中最有趣的部分:什么(为什么/如何)将&lt;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(以及一些相关文件和数据库表)可以搜索和根据 xml 文件 (system/modification.xml) 中指定的规则在 php/tpl 文件中添加/追加/替换代码行(硬编码限制)在解析目标 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>         
    

    其中$action-&gt;getFile() 替换为$this-&gt;registry-&gt;get('modification')-&gt;getFile($action-&gt;getFile()) 之前 文件system/engine/front.php 被解析!

  2. vQmod™”(又名 Virtual Quick Mod)
    vQmod 是一个单独开发的包,基本上是 OpenCart 修改系统(上图)的完善版本,它来自 originated。 “附加组件”通常使用它来修改文件夹 vqmod(位于 OpenCart 的根目录)中的 OpenCart 和 installed(因为它默认不包含在 OpenCart 中)的生产版本。在此文件夹中,您会找到一个文件夹 vqcache 保存缓存的修改文件和一个文件夹 xml 保存 xml search/replace files
    与 OpenCart 的修改系统(上图)相比,这些 xml 文件的 syntax(最明显的是 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 而不是 text 时无法验证的有效电子邮件地址 (letters@gmail.com)...
这是(损坏/过时/部分安装)“响应式”/“移动”主题等(通常也会影响电话字段)的一个相当常见的问题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',

因此,solution 显然是将这些输入类型添加到 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”的文件夹。如果找不到它,则对包含&lt;input type="email"(例如)的字符串进行文本搜索(从您的 OpenCart 目录开始并包括子目录),并首先使用文件类型 xml 调查结果。
  • 要在验证(电子邮件、电话、传真等)失败的情况下使用该模块,请修复 JSON 调用(如果它已安装,您可以使用 vQmod,并将其添加为受影响文件的操作)。
  • 或者(正如您已经注意到的),通过更改属性顺序使 mod 崩溃(代价是此页面的其他 mod 也失败了,正如您注意到的那样)。
  • 如果上述方法都不适用于您的情况,我强烈建议重新安装 OpenCart 的干净版本!

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

【讨论】:

  • 我实际上确实使用了 vqmod,但现在我什至不认为它可能是“有罪的人”。我认为你完全正确,我也使用 embermonkey vqmod xml 文件。感谢您的解释和挖掘,我非常感谢。
【解决方案2】:

实际上,您所描述的行为根本不是来自 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 的东西,那么不要害怕并享受这些功能。例如,在您的问题中的非常示例中,如果输入的类型为 emailtel,则用户无法提交表单,直到 email 字段包含语义正确的电子邮件地址,他甚至无法填写任何tel 字段中的文字(非数字)字符...(是的,直到用户通过开发人员工具修改 HTML...)

【讨论】:

  • 我知道这些功能(新输入类型)会进行一些验证,但在我的情况下,它们会破坏表单并抛出无效的电子邮件和电话号码,即使它们完全有效且正确。而且我不是在谈论那种可以的形式。我的问题出在结帐登记表上。要复制这个把东西放在你的篮子里然后去结帐然后选择注册。出现在那里的字段由 js 调用,因此您无法在禁用 js 的情况下访问该页面。谢谢你的挣扎,但我想你误会了我
  • GitaarLAB 我会尽快检查的,抱歉我离开了一整天。谢谢
  • @geryjuhasz 您仍然可以通过调用http://your.ocinstall.com/index.php?route=checkout/register 访问该表单(注意区别)。如果电子邮件有效,它不能标记无效电子邮件(即,如果它标记该电子邮件无效,它确实是无效的 - 在此处发布该电子邮件地址 - 只需更改单词/字母,但将所有不寻常的字符和点保留在它们所在的位置)。我无法弄清楚如何仅通过更改输入类型来破坏表单,但是好的,我接受我可能误解了你。圣诞快乐!
  • 这是我的电子邮件地址,gmail 的。是 letter@gmail.com,绝对有效
  • 圣诞快乐!! @geryjuhasz:但是.. 您使用的是非默认主题(如果是的话,是哪一个)? 您是否在浏览器/php 错误日志中发现错误?您是否向我们发布了由 php (index.php?route=checkout/register) 生成的完整 html? (我已经在 cmets 中问过所有这些问题......)不要让我们在黑暗中刺伤
猜你喜欢
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 2013-05-17
  • 1970-01-01
相关资源
最近更新 更多