【问题标题】:symfony 1.4 how to globally unset, hide or make read only a form widget?symfony 1.4 如何全局取消设置、隐藏或只读表单小部件?
【发布时间】:2013-02-08 09:38:33
【问题描述】:

在我的应用程序中,我有很多模块和很多带有自己小部件的表单。
我一直在尝试全局“取消设置”、“隐藏”或“只读”一个小部件。
我知道可以为表单的 configure() 函数中的一个小部件执行此操作,但我正在寻找一种更好的解决方案,如果可能的话以全局方式。更改所有模块形式并跟踪它们可能会很痛苦。
线程可能有点长,但我认为它很容易理解问题。非常感谢您有时间阅读它:)

我用 Timestampable 行为构建了一个简单的新闻模块来测试一些选项,但它们仍然没有工作。

  • 表:TbNews
  • 列:
    • id 作为主键
    • scontent 作为用于保存新闻内容的文本字段。
    • created_at 作为日期时间。 (时间戳行为)
    • updated_at 作为日期时间。 (时间戳行为)


TbNews schema.yml:

TbNews:
  connection: doctrine_master
  tableName: tb_news
  columns:
    id:
      type: integer(8)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    scontent:
      type: string(64000)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
  actAs:
    Timestampable:
      created:
        name: created_at
        type: timestamp
        format: Y-m-d H:i:s
        options:
          notnull: false
          required: false
      updated:
        name: updated_at
        type: timestamp
        format: Y-m-d H:i:s
        options:
          notnull: false
          required: false


TbNews updated_at 形式
(例如,这里只写了updated_at列):

class TbNewsForm extends PluginTbNewsForm
{
  public function configure()
  {
      $this->setWidgets(array(
          'updated_at'   => new sfWidgetFormDateTime(),
      ));
      $this->setValidators(array(
        'updated_at'   => new sfValidatorDateTime(array('required' => false)),
      ));
  }
}


TbNews 的模板 _form.php 已更新_at
测试了很多选项,手动渲染updated_at with: "echo $form['updated_at']" 不渲染。

<?php echo $form->renderHiddenFields(false) ?>


带有update_at 列的全局测试: lib/form/doctrine/BaseFormDoctrine.class.php

  • 使用sfWidgetFormInputHidden(),小部件不会在模板中呈现。
    测试取消设置它,没有取消它,使用 setWidget,没有它......所有可能的选项,但字段 updated_at 未在模板中呈现。 (使用了 renderHiddenFields())
abstract class BaseFormDoctrine extends sfFormDoctrine
{
  public function setup()
  {
      $value_updated_at = $this->getObject()->updated_at;
      unset($this->widgetSchema['updated_at']);
      unset($this->validatorSchema['updated_at']);
      $this->widgetSchema['updated_at'] = new sfWidgetFormInputHidden();
      $this->widgetSchema['updated_at']->setOption('is_hidden', 'true');
      $this->widgetSchema['updated_at']->setOption('type', 'hidden'); 
      $this->setDefault('updated_at', $value_updated_at);
      $this->setWidget('updated_at', new sfWidgetFormInputHidden(array('value'=>$value_updated_at)));
      //$this->setWidget('updated_at', $this->widgetSchema['updated_at']);
  }
}


  • 只读:
    在 _form.php 模板中添加了 updated_at 字段,但未显示为只读。似乎不适用于sfWidgetFormDateTime
      $this->widgetSchema['updated_at']->setAttribute('readonly', 'readonly');
    


问题和想法:
可能BaseFormDoctrine 不是在所有表单模块中全局更改小部件的正确方法,或者我的测试中可能有问题。

您可能知道,如果我们直接在 Form 小部件TbNewsForm configure() 中使用上述代码,我们可以轻松地将小部​​件从一种类型更改为另一种类型,并单独渲染或隐藏它,并且它可以工作。
  • 但我们如何才能以全局方式实施它呢?
  • symfony Doctrine核心代码是否需要修改?

非常感谢您能花时间阅读它,欢迎任何评论或解决方案:)

【问题讨论】:

  • 基本上,您希望 updated_atcreated_at 在您的所有表单中都被隐藏,对吧?
  • 是 j0k,但会影响所有具有 created_at 和 updated_at 字段的模块。
  • 仅在全局范围内测试过 在 BaseFormDoctrine 中取消设置这些字段,但在更新时为 created_at 保存 NULL 值:UPDATE tb_news SET scontent = 'content3', created_at='', updated_at='2013-02-07 11:59:29' 其中 id='3';检查 C:\php5\PEAR\symfony\plugins\sfDoctrinePlugin\lib\vendor\doctrine\Doctrine\Template\Listener\Timestampable.php 的监听器代码,但没有简单的解决方案。
  • 我的项目中也有很多表单类,我通常在配置中取消设置created_at & updated_at。我更喜欢在正确的表单类中查看发生了什么,而不是全局查看。如果您想在后端应用程序中查看这些字段怎么办?你会在表单类中重新添加它们吗?
  • 是的,正如您所说,这是最好的方法,如果没有其他选择,我将不得不为每个表单类手动完成。但是,如果我们找到了一种全局设置它的工作方法,可以很容易地在 BaseFormDoctrine 添加模块黑/白名单条件,以便我们知道正在过滤哪些模块表单小部件,仅过滤其中一些并且仅在我们没有过滤时在后端。

标签: php forms symfony-1.4 doctrine-1.2


【解决方案1】:

更改 BaseFormDoctrine 类对您没有帮助。表单的小部件在给定表单的基类中设置(在您的情况下为BaseTbNewsForm),因此它们将覆盖在BaseFormDoctrine 类中所做的任何更改。

如果您想对每个表单执行相同的操作但又不想重写每个类中的代码,您可以创建一个实用程序类并在表单的configure() 函数中调用它的方法。

我认为在不更改 Doctrine / Symfony 内部结构的情况下,没有办法在全局范围内执行此操作(您必须更改生成表单的基类的方式)。

【讨论】:

  • 谢谢你,Michal,你的评论真的很受欢迎,不知怎的,这正是我的想法。我会在核心上尝试一些小的改动,并尽快报告它们,ty :)
【解决方案2】:

我找到了一种可行的方法,但可能不是最好的解决方案,因为它涉及修改 symfony 的源代码。核心文件中的函数:setupInheritance()sfFormDoctrine.class.php被之后的所有表单调用设置小部件和验证器,如果我们在那里添加代码,我们的更改将对所有表单全局生效。
在下面的示例中,所有小部件“created_at”和“updated_at”都将被取消设置,然后设置为隐藏:

 /**
   * Used in generated forms when models use inheritance.
   */
  protected function setupInheritance()
  {
    if (isset($this))
    {
      $oWidgetSchema = $this->getWidgetSchema();
      if (isset($oWidgetSchema))
      {
        $screatedcolumn = "created_at";
        $supdatedcolumn = "updated_at";

        //if ($this->isNew()) //we can add a check for new records

        //we can also add checks for frontend or backend
        //$request = sfContext::getInstance()->getRequest();
        //$this->url = 'http'.($request->isSecure() ? 's' : '').'://'. $request->getHost();
        //$suri_params = $request->getParameterHolder()->getAll();

        //set [created_at] as hidden field widget, and set its default value to the Original one before sending it to Timestampable.php Listener.
        if ( $oWidgetSchema->offsetExists($screatedcolumn) )
        {
          $value_created_at = $this->getObject()->created_at;
          unset($this->widgetSchema[$screatedcolumn]);
          $this->widgetSchema[$screatedcolumn] = new sfWidgetFormInputHidden();
          $this->widgetSchema[$screatedcolumn]->setOption('is_hidden', 'true');
          $this->widgetSchema[$screatedcolumn]->setOption('type', 'hidden');
          //unset($this->validatorSchema[$screatedcolumn]); //unset its validator to make sure values are not checked by default, optional.
          $this->setDefault($screatedcolumn, $value_created_at);
        }
        //set [updated_at] as hidden field widget, and set its default value to time() before sending it to Timestampable.php Listener.
        if ( $oWidgetSchema->offsetExists($supdatedcolumn) )
        {
          //$value_updated_at = $this->getObject()->updated_at;
          unset($this->widgetSchema[$supdatedcolumn]);
          $this->widgetSchema[$supdatedcolumn] = new sfWidgetFormInputHidden();
          $this->widgetSchema[$supdatedcolumn]->setOption('is_hidden', 'true');
          $this->widgetSchema[$supdatedcolumn]->setOption('type', 'hidden');
          //unset($this->validatorSchema[$supdatedcolumn]); //unset its validator to make sure values are not checked by default, optional.
          $this->setDefault($supdatedcolumn, time());
        }
      }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 1970-01-01
    相关资源
    最近更新 更多