1

別のコントローラーのアレイから、たとえばループで複数の新しいユーザーを作成するにはどうすればよいでしょうか?

フォーム送信で複数のユーザーを作成しようとすると失敗するという問題がありますが、単一の新しいユーザーの作成は設計どおりに機能します。問題は、新しいユーザーを保存してから、新しい user_id を return ステートメントに戻すときに発生する可能性があるようです。新しい ID が返されますが、後続のユーザー (2 番目、3 番目など) はすべて同じ id 値を取得し、後続の $this->save 呼び出しは、追加のユーザーを作成するのではなく、最初に作成されたユーザーを変更するようです。新しいユーザーはデータベースに表示されません。(繰り返しますが、この問題は、複数の新しいユーザーが作成される場合にのみ発生します。)

$user = $this->save(array('User' => array(私の 1 つの小さな手がかりは、importPublicLDAPUser() 関数 (user.php) で var_dump($user) を...の直後に実行する)));と、最初の要素については「変更済み」と「作成済み」の両方が表示されますが、残りは「変更」。これにより、次のユーザーを作成する前に、ユーザーを保存またはコミット (??) する必要があるなど、ステップが欠落していると思われます。

これを変更して$user = $this->User->save(array('group_id' => 3, ...前に「作成」を追加しようとしまし$this->User->create();たが、これらは「非オブジェクトでのメンバー関数 save() の呼び出し」および「非オブジェクトでのメンバー関数 create() の呼び出し」というエラーを生成します。

私のアプリケーションはドキュメントを管理します。各ドキュメントには多くの作成者を含めることができるため、ドキュメント、ドキュメント タイプ、ユーザー、グループ、および作成者用のコントローラーがあります。

新しいドキュメントが入力されると、フォームで複数のユーザーを選択して「作成者」レコードを作成できます。ローカル ユーザー テーブルに加えて、LDAP サーバーも検索し (両方とも自動提案を介して)、テキスト フィールドへの入力も可能にします。だから、著者はから選択されます

  • ユーザーの既存のテーブル
  • LDAPヘルパー経由
  • フリーテキスト入力。

この結果は、$Authors (ローカル ユーザー テーブルから) と $badAuthors (LDAP およびテキスト入力) の 2 つの配列であり、フォームが送信されたときにアプリがローカル ユーザー テーブルに追加しようとします。

次の場合、フォームは正常に機能します。

  1. 1 人以上の作成者がローカル ユーザー テーブルから追加されます。
  2. 単一の作成者が LDAP から追加され (users テーブルに新しいエントリを作成することに成功)、ゼロ以上のローカル ユーザー
  3. 1 人の作成者がテキスト入力から追加され (これも成功)、0 人以上のローカル ユーザー

ただし、ローカル以外のユーザーが 2 人以上追加された場合 ($badAuthors に複数の要素がある場合)、フォームは失敗します。「失敗」は、作成者またはユーザーのいずれかの保存ルーチンが失敗したことを意味するため、ドキュメントのコミット$this->Docu->commit();をスキップし、ajaxResponse を介してエラーを吐き出します。このように、フォームは Authors/badAuthors を 1 より大きくできるように設計されていますが、アプリは設計どおりに動作しますが、一度に 1 つの新しいユーザー エントリしか使用できません。

私が理解していないのは、 $badAuthors に複数の要素がある場合に、悪い作成者をループすると、ユーザーが正しく追加されない理由です。

ユーザーが各名前を入力すると (ユーザー テーブルと ajax ヘルパーなどを介して LDAP に対してチェックされます)、選択されると、author_name_list 配列が作成されます。その後:

foreach($this->params['form']['author_name_list'] as $author_name){
    $user_id = $this->Docu->User->field('id',array('User.name' => $author_name));
    if($user_id){
        $Authors['Author'][]=array(
            'docu_id'=>$this->Docu->id
            ,'user_id'=>$user_id
            );
    }else{
        $badAuthors[] = array('name'=>$author_name);
    }
 }

そのため、$badAuthors は LDAP で見つかったもの、または手動で入力したものになりました。

だから今、私はすべてのbadAuthorsを作成/保存しようとしています...

docu コントローラー (docu_controller.php):

if(count($badAuthors)){
foreach($badAuthors as $key => $author){

    $this->Memo->User->create();  // ** <-- this was missing!! **

        if($ldap_author = $this->Docu->User->importPublicLDAPUser($author['name'])){
    unset($badAuthors[$key]);
    $Authors['Author'] []= array(
        'docu_id'=>$this->Docu->id
        ,'user_id'=>$ldap_author['User']['id']
        ,'precedence' => $author['precedence']
    );
    } elseif ($new_author = $this->Docu->User->newReadonlyUser($author['name'])) {
    unset($badAuthors[$key]);
    $Authors['Author'] []= array(
        'docu_id'=>$this->Docu->id
        ,'user_id'=>$new_author['User']['id']
        ,'precedence' => $author['precedence']
    );
    }
}
}

if(!count($badAuthors)){
    $authors_saved = true;
    foreach($Authors['Author'] as $author_arr){
       $this->Docu->Author->create();
       if(!$this->Docu->Author->save(array('Author' => $author_arr))){
            $authors_saved = false;
            break;
       }
    }
}

ユーザーモデル (user.php)

function afterSave($created) {
    if (!$created) {
        $parent = $this->parentNode();
        $parent = $this->node($parent);
        $node = $this->node();
        $aro = $node[0];
        $aro['Aro']['parent_id'] = $parent[0]['Aro']['id'];
        $this->Aro->save($aro);
    }
}

function importPublicLDAPUser($cn){
    App::import('Vendor','adLDAP',array('file'=>'adLDAP.php'));
    $oLDAP = new adLDAP(Configure::read('LDAP_options.email'));
    $oLDAP->authenticate(NULL, NULL);

    $filter = '(&(cn='.$oLDAP->ldap_escape($cn).'))';

    $ldap_res = @$oLDAP->search($filter, array('cn', 'uid','profitcenter'),1);

    if(isset($ldap_res['count']) && ($ldap_res['count'] > 0)){//found it
    $user = $this->save(array('User' => array(
        'group_id' => 3,
        'name' => $ldap_res[0]['cn'][0],
        'username' => $ldap_res[0]['uid'][0],
        'grpnum' => pc2grpnum($ldap_res[0]['profitcenter'][0])
        )));                               

    if($user){
        $user['User']['id'] = $this->id;
    }
        return ($user ? $user : false);
    }else{
        return false;
    }
}

助言がありますか?ありがとう!!

4

1 に答える 1

0

私のdocu_controller.phpで、create()呼び出しが欠落していたことがわかりました。createがなくても、他のコントローラーがcommit()を実行したときに、オブジェクトを保存/作成できるようです。したがって、create()を追加する前、コミットする前、後のループ反復では、新しいオブジェクトではなく、元のオブジェクトを変更していました。コントローラに作成を追加することにより、メソッドの保存関数は、ループの反復ごとに新しいユーザーに作用します。

コントローラー内:

if(count($badAuthors)){
    foreach($badAuthors as $key => $author){
        $this->Memo->User->create();
            if($ldap_author = $this->Memo->User->importPublicLDAPUser($author['name'])){

メソッドで:

function importPublicLDAPUser($cn){
    ....
    $user = $this->save(array('User' => array(...
于 2012-11-02T19:36:38.013 に答える