Php symfony 1.4如何全局取消设置、隐藏或使表单小部件为只读?

Php symfony 1.4如何全局取消设置、隐藏或使表单小部件为只读?,php,forms,symfony-1.4,doctrine-1.2,Php,Forms,Symfony 1.4,Doctrine 1.2,在我的应用程序中,我有很多模块和表单,它们都有自己的小部件。 我一直在尝试全局“取消设置”、“隐藏”或“使只读”小部件。 我知道可以在表单的configure()函数中为一个小部件执行此操作,但我正在寻找更好的解决方案,如果可能的话,可以采用全局方式。更改所有模块表单并跟踪它们可能是一件痛苦的事情。 线程可能有点长,但我认为它很容易理解问题。如果您有时间阅读,非常感谢:) 我已经构建了一个简单的带有时间标记行为的新闻模块来测试一些选项,但仍然没有一个有效 表:TbNews 栏目: id作为

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

我已经构建了一个简单的带有时间标记行为的新闻模块来测试一些选项,但仍然没有一个有效

  • 表:
    TbNews
  • 栏目:
    • id
      作为主键
    • scontent
      作为保存新闻内容的文本字段
    • 在日期时间创建。(可设置时间的行为)
    • 更新为日期时间。(可设置时间的行为)

TbNews schema.yml:


TbNews以格式更新\u (对于该示例,仅在此处写入更新的_at列):


TbNews的模板\u form.php更新地址:
测试了很多选项,手动呈现更新的_at,带有:“echo$form['updated_at']”而不呈现它


  • 只读:
    在_form.php模板中添加了
    updated_at字段,但该字段未显示为只读。似乎不适用于
    sfWidgetFormDateTime


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

您可能知道,如果我们直接在表单小部件
TbNewsForm configure()
中使用上述代码,我们可以轻松地将小部件从一种类型更改为另一种类型,并单独呈现或隐藏它,它就可以工作了

  • 但我们如何在全球范围内实施它
  • 是否有必要更改symfony原则的核心代码

非常感谢您,如果您能抽出时间阅读,欢迎提供任何意见或解决方案:)

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

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


我不认为在不改变Doctrine/Symfony内部结构的情况下,有一种方法可以在全球范围内完成这项工作(您必须改变表单基类的生成方式)。

我找到了一种可行的方法,hovewer可能不是最好的解决方案,因为它涉及修改Symfony的源代码。核心文件:sfformdoctor.class.php中的函数:setupheritation()在设置小部件和验证器后被所有表单调用,如果我们在其中添加代码,我们的更改将全局适用于所有表单。
在下面的示例中,所有窗口小部件“创建时间”和“更新时间”都将取消设置,然后设置为隐藏:

 /**
   * 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());
        }
      }
    }

基本上,您希望所有表单都隐藏
updated_at
created_at
,对吗?是的j0k,但会影响所有创建了_at和更新了_at字段的模块。在BaseFormDoctrine中也只对这些字段进行了全局取消设置测试,但在更新时为created_at保存空值:update tb_news SET scontent='content3',创建时间='',更新时间='2013-02-07 11:59:29'其中id='3';检查了C:\php5\PEAR\symfony\plugins\sfDoctrinePlugin\lib\vendor\doctrine\doctrine\Template\Listener\timestable.php上的侦听器代码,但没有简单的解决方案。我的项目中也有很多表单类,我通常在配置中取消设置
处创建的
处更新的
。我更喜欢在正确的窗体类中看到正在发生的事情,而不是全局性的。如果您想在后端应用程序中查看这些字段,该怎么办?你会在表单类中重新添加它们吗?是的,正如你所说,这是最好的方法,如果没有其他选项,我将不得不为每个表单类手动添加。无论我们如何找到一种全局设置的有效方法,在BaseFormDoctrine中添加一个模块黑/白名单条件都是很容易的,这样我们就可以知道哪些模块构成的小部件正在被过滤,只过滤其中的一部分,并且只在我们不在后端的情况下进行过滤。谢谢你,Michal,你的评论真的很受欢迎,不知怎的,我是这么想的。我将尝试一些核心的小改动,并很快向您报告,泰:)
class TbNewsForm extends PluginTbNewsForm
{
  public function configure()
  {
      $this->setWidgets(array(
          'updated_at'   => new sfWidgetFormDateTime(),
      ));
      $this->setValidators(array(
        'updated_at'   => new sfValidatorDateTime(array('required' => false)),
      ));
  }
}
<?php echo $form->renderHiddenFields(false) ?>
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']);
  }
}
  $this->widgetSchema['updated_at']->setAttribute('readonly', 'readonly');
 /**
   * 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());
        }
      }
    }