0

私のアプリケーションには、独自のウィジェットを備えた多くのモジュールと多くのフォームがあります。ウィジェット
をグローバルに「設定解除」、「非表示」、または「読み取り専用にする」ことを試みています。フォームのconfigure()
関数で 1つのウィジェットに対してそれを行うことが可能であることは知っていますが、可能であればグローバルな方法でより良い解決策を探しています。すべてのモジュール フォームを変更し、それらを追跡するのは面倒な場合があります。 スレッドは少し長くなる可能性がありますが、問題を理解しやすいと思います。読む時間があれば、どうもありがとうございます :) いくつかのオプションをテストするために 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 updated_at のテンプレート _form.php :
多くのオプションをテストし、updated_at を次のように手動でレンダリングしました: "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 のコアコードを変更する必要がありますか?

時間を割いて読んでいただければ、どうもありがとうございます。コメントや解決策は大歓迎です:)

4

2 に答える 2

0

私は機能する方法を見つけましたが、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());
        }
      }
    }
于 2013-02-18T13:29:58.947 に答える
0

クラス替えはBaseFormDoctrine役に立ちません。フォームのウィジェットは、指定されたフォームの基本クラス(BaseTbNewsFormあなたの場合)に設定されるため、BaseFormDoctrineクラスで行われた変更をオーバーライドします。

各フォームに対して同じ操作を行いたいが、各クラスのコードを書き直したくない場合は、ユーティリティ クラスを作成し、フォームのconfigure()関数でそのメソッドを呼び出すことができます。

Doctrine / Symfony の内部を変更せずにグローバルに実行するオプションはないと思います (フォームの基本クラスを生成する方法を変更する必要があります)。

于 2013-02-08T10:56:44.657 に答える