質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.63%

cake3 NGワード設定

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 982

sbc

score 19

前提・実現したいこと

・登録フォームを用意(対象のinputはnameとかで)
・ng_wordテーブルに設定した言葉をバリデーションしたい

1.テーブルに単語を登録
2.ControllerのinitializeでTableRegistryを使用してng_wordEntityを取得
3.Actionで $this->set('ngword', $this->ngwords->find())

Controller

public function register($lang = null)
    {
        $lang = ($lang === null) ? 'ja' : $lang;
        $dataMaster = new DataMaster();
        $this->set('Countries', $dataMaster->getAllCountries($lang));
        $this->set('Languages', $dataMaster->getAllLanguages($lang));
        $this->set('Genders', $dataMaster->getAllGenders($lang));
        if ($lang === 'ja') {
            $this->set('Prefectures', $dataMaster->getAllPrefectures($lang));
        }else{
            $this->set('Prefectures', false);
        }

        $member = $this->Member->newEntity();
        if ($this->request->is('post')) {
            $member = $this->Member->newEntity($this->request->data, [
                'associated' => ['MemberDetail']
                ]);
            if ($member->errors()){
                $this->Flash->error(__('The member could not be saved. Please, try again.'));
            }
            if ($this->Member->save($member)) {
                $this->Flash->success(__('The member has been saved.'));
                return $this->redirect(['action' => 'login']);
            }
        }
        $this->set(compact('member'));
        $this->set('_serialize', ['member']);
    }

 

$ngWords = $this->ngwords->find();
        foreach ($ngWords as $row){
            $word[] = $row->word;
        }
        $this->set('ngwords', $word);

Table

public function validationDefault(Validator $validator)
    {
        $validator
            ->allowEmpty('id', 'create');

        $validator
            ->allowEmpty('nickname')
            ->add('nickname', [
                'ngword' => [
                    'rule' => function($value, $context){
                        return !TableRegistry::get('ng_word')->exists(["'{$value}' LIKE concat('%', word, '%')"]);
                    },
                    'massage' => '「おなまえ」に不適切な語句が含まれています'
                ]
            ]);

        $validator
            ->integer('gender')
            ->notEmpty('gender');

        $validator
            ->date('birthday')
            ->allowEmpty('birthday');

        $validator
            ->integer('country')
            ->allowEmpty('country');

        $validator
            ->integer('prefecture')
            ->allowEmpty('prefecture');

        $validator
            ->integer('language')
            ->allowEmpty('language');

        $validator
            ->allowEmpty('created_by');

        $validator
            ->dateTime('created_at');

        $validator
            ->allowEmpty('updated_by');

        $validator
            ->dateTime('updated_at');

        return $validator;
    }

Template

<div class="member form large-9 medium-8 columns content">
    <?= $this->Form->create($member) ?>
    <fieldset>
        <legend><?= __('新規会員登録') ?></legend>
        <p>全項目入力して下さい</p>
        <?php
            echo $this->Form->input('member_detail.0.nickname', ['label' => __('なまえ')]);
            echo $this->Form->input('member_detail.0.gender', ['label' => __('性別'), 'type' => 'radio', 'options' => $Genders]);
            echo $this->Form->input('member_detail.0.birthday', ['label' => __('生年月日'), 'type' => 'date', 'dateFormat' => 'YMD', 'monthNames' => false, 'maxYear' => date('Y'), 'minYear' => 1850, 'empty' => '---']);
            echo $this->Form->input('member_detail.0.country', ['label' => __('国籍'), 'type' => 'select', 'options' => $Countries]);
            if ($Prefectures) {
                echo $this->Form->input('member_detail.0.prefecture',
                    ['label' => __('都道府県'), 'type' => 'select', 'options' => $Prefectures]);
            }
            echo $this->Form->input('member_detail.0.language', ['label' => __('言語'), 'type' => 'select', 'options' => $Languages]);
            echo $this->Form->input('mail_address', ['label' => __('メールアドレス'), 'type' => 'email']);
            echo $this->Form->input('login_id', ['label' => __('ログインID'), 'type' => 'text']);
            echo $this->Form->input('login_password', ['label' => __('パスワード'), 'type' => 'password']);
            echo $this->Form->hidden('is_active', ['default' => 1]);
            echo $this->Form->hidden('is_deleted', ['default' => 0]);
        ?>
    </fieldset>
    <?= $this->Form->button(__('確認')) ?>
    <?= $this->Form->end() ?>
</div>

ここからどうして良いか分かりません。

カスタムバリデーションの作成や取得したデータをそこに反映させる方法等・・

補足情報(言語/FW/ツール等のバージョンなど)

php7.1.1 / cake PHP3.3.12/

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

カスタムバリデートで、バリデート関数内でng_wordテーブルにアクセスすればいいと思います。
以下、サンプルです。

    public function validationDefault(Validator $validator) {
        $validator
            ->add('name', [
                'ngword' => [
                    'rule' => function($value, $context) {
                        return !TableRegistry::get('ng_word')->exists(["'{$value}' LIKE concat('%', word, '%')"]);
                    },
                    'message' => 'NGワードが含まれています'
                ],
            ]);
        return $validator;
    }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/09 17:23

    できました!
    原因はTemplateのcreate()第一引数の記述かと思われます。
    $this->Form->create('member')と書いていたのですが
    $this->Form->create($member)に修正することで動作しました。
    本文のコードを動作確認状態に修正してあります。

    errorがあった場合はsaveは失敗するのでリダイレクトもされませんが、この書き方は良くないでしょうか。

    修正前の時点ではアソシエーション以外のデータのエラーメッセージも出ませんでした。
    バリデート失敗時にはinputに値は入っていました。

    キャンセル

  • 2017/02/09 17:34

    なるほど... $memberが正しいですね。解決して良かったです!

    > errorがあった場合はsaveは失敗するのでリダイレクトもされませんが、この書き方は良くないでしょうか。
    別に大丈夫ですが、error()があったら$this->Flash->error()の後にreturnしちゃった方がわかりやすいかと

    キャンセル

  • 2017/02/09 18:53

    なるほどです。。
    errorのあとはreturn ;で終わらせることにします。

    長々とお付き合い頂きありがとございました!。。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる