OpenCart更改输入字段的类型属性

时间:2013-12-21 23:51:00

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

我在这里面对一件奇怪的事情。我正在开发一个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发送到浏览器时,<input type="text"字段已经更改 那么,什么(为什么/如何)将<input type="text">转换为类型email / tel(看似基于name属性),为什么在输入字段的属性顺序发生变化时会失败?

2 个答案:

答案 0 :(得分:2)

OpenCart直到当前稳定的version 1.5.6(以及当前的version 1.5.6.1,)默认情况下不使用任何HTML5(输入字段等)(或在其默认主题中)。
这符合:When will opencart start to use html5?(apr。&#39; 12):&#34;人们仍在抱怨IE6支持。当人们不再抱怨时,我们就可以开始专注于HTML5过渡&#34;

例如,文件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(12月13日)中,不一致使用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之前,PHP必须运行一些内容来更改存储在硬盘上的文件中的代码,然后再将其发送到浏览器:OpenCart和/或(其中一个)主题&#39;,&#39; modules&#39;,&#39; extensions&#39;等
由于某种html-parser可能不会搞砸这么简单的任务,最有可能的候选者是某种基本搜索和替换的脚本。

恰好有两个(高度相关的)脚本,OpenCart常见的,完全符合这个法案。

  1. OpenCart&#39;修改系统&#39;
    如果您不小心下载/安装了最新的&#39; (开发)master-branch(或者是一个贡献者),然后你会找到一些文件,比如system/engine/modification.php(以及一些相关的文件和数据库表),它们可以搜索和添加/追加/替换php / tpl文件中的代码(硬编码限制),根据xml文件(system/modification.xml中指定的规则解析目标php / tpl文件而不修改原始文件
    这个相当不言自明的xml文件基本上包含&#39;操作&#39;每个要动态修改的文件,例如:

    <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->getFile()之前$this->registry->get('modification')->getFile($action->getFile())替换为system/engine/front.php

  2. &#34; vQmod™&#34; (又名Virtual Quick Mod)
    vQmod是一个单独开发的软件包,基本上是OpenCart修改系统(上图)的精美版本,从中originated。它常用于附加组件&#39;修改文件夹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>
    

    注意:以上示例来自&#39; embermonkey响应主题&#39;并且是您正在体验的行为的一个很好的例子:它取代了输入属性。

  3. 这些修改脚本的目的是:

      

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

    这使得可以实际改变OpenCart中的任何php或tpl文件(主要的index.php除外)&#34;这样,更新OpenCart的核心文件添加/删除模板等将变得更容易,更可靠。


    最后,有效的电子邮件地址(letters@gmail.com)在输入的类型设置为email而不是text时无法验证...
    这是一个相当普遍的问题(破碎/过时/部分安装)&#39;响应&#39; /&#39;移动&#39;主题等(通常也影响电话领域) 12
    问题不在于浏览器拒绝有效的电子邮件地址(当输入字段的类型设置为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',
    

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

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

    PS:现在你知道了vQmod,你最好使用它(而不是修改核心文件),因为&#34;性能令人惊讶地看起来根本不是一个因素&#34;,给你的将来可以获得更可靠的升级途径!

答案 1 :(得分: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文档类型被定义为为HTML5,但OpenCart实际上并不使用任何HTML5功能。

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