-1

ユーザー、メンバー プロファイル、およびメンバー組織という 3 つの異なるオブジェクトを含むユーザー登録フォームに取り組んでいます。これらすべてをユーザー>メンバー>学校のような単一の登録フォームに埋め込もうとしています。これの基本的な実装は、典型的なsfDoctrineForm::embedRealtion手順で問題なく機能します。

問題は、組織が に一意のインデックスを持っていることmember_numberです。これに指定された値がデータベースに存在しないのは、そのユーザーが組織から最初にサインアップしたときだけです。したがって、この場合、検証エラー (検証をオフにするとキー制約違反) が発生します。

私が代わりにやりたいことは、データベース内で同じMemberOrganizationの存在をチェックすることですmember_number(プリ/ポストバリデーターまたはupdateObjectまたは適切な場所のいずれかで)。メンバー番号が既に存在する場合は、新しい MemberProfile を、送信された新しい組織にリンクするのではなく、この既存の組織に関連付けて、その組織の新しい値をすべて破棄します。

検証によって組織フォームのオブジェクトを変更しようとしましたが、これは常にorganization_idプロファイルからの制約違反になります。

$object = $this->getObject();
$table = $object->getTable();
$existing = $table->findOneByMemberNumber($values['member_number']);
if($existing)
{
  $members = clone $object->Members;
  $object->assignIdentifier($existing->identifier());
  $object->fromArray($existing->toArray(false), false);

  foreach($members as $member)
  {
    $member->link($object);
  }

  $values = $object->toArray(false); // return only the direct values
}

return $values;

スキーマは次のようになります。

User:
  columns:
  username: {type: string(100)}
  email: {type: string(255), unique: true}

MemberProfile:
  columns:
    # some none authentication related user details
    organization_id: {type: integer, notull: true}
    user_id: {type: integer, notnull: true}
  relations:
    User:
      local: user_id
      type: one
      foreign: id
      foreignType: one
    MemberOrganization:
      local: orgainization_id
      type: one
      foreign: id
      foreignType: many
      foreignAlias: Members

MemberOrganization:
  columns:
    membership_number: {type: string(255), unique: true}
    # other organization data
4

1 に答える 1

0

だから私がやったのはbind、トップレベルのフォーム(ユーザー用のもの)をオーバーライドすることでした。このメソッドでは、Orgainization の存在を確認し、存在する場合はそれを Member Profile オブジェクトに添付してから、すべてのサブフォームを再埋め込みします。

理想的には、実際にはメンバーフォームでこれを行いますが、値は最上位フォームでのみバインドされ、検証のためにエラースキーマをカスケードするだけなので、これはうまくいかないようです。オブジェクトの関連付けを正しくするには、完全な再埋め込みが必要なようです。

いくつかのサンプル コード (クエリを発行する前に会員番号のサニタイズ コードを除く):

  public function linkOrganizationIfExists(array $orgValues)
  {
    $defaultOrg = $this->embeddedForms['member_profile']->embeddedForms['organization']->getObject();
    $table = $defaultOrg->getTable();

    if(isset($orgValues['member_number']) 
      && ($existingOrg = $table->findOneByMemberNumber($orgValues['member_number'])))
    {
      $user = $this->getObject();
      $profile = $user->getMemberProfile();
      $profile->Organization = $existingOrg;

      // prepare the current values from the db to return
      $orgValues = array_merge($orgValues, array_intersect_key($existingOrg->toArray(false), $orgValues));

      $this->embedRelation('MemberProfile as member_profile', 'MemberProfileRegisttrationForm');
    }

    return $orgValues;
  }

  public function bind(array $taintedValues = null, array $taintedFiles = null)
  {
    if(isset($taintedValues['member_profile']['organization']))
    {
      $taintedValues['member_profile']['organization'] = $this->linkOrganizationIfExists($taintedValues['member_profile']['organization']);
    }

    parent::bind($taintedValues, $taintedFiles);
  } 
于 2011-03-12T05:32:13.207 に答える