🚗

Laravel 自作のカスタムルールに機能追加しがてら、value ヘルパー関数を使ってみる

2022/03/03に公開

まえがき

今回は、前回作成したカスタムルールに1つ機能(メソッド)を追加したいと思います。機能は、「とある条件を満たした時は、ルールを適用させない」というもので、value ヘルパー関数を使ってみます。

value ヘルパー関数って、ドキュメント見ても、使い方は分かっても、使い所はさっぱり分からなかったりします。

ややマニアックなヘルパー関数なので、この記事を読む価値(value)があるかどうかは、正直分かりかねます。🙇‍♂️
(Laravel 本体のソース見たりすると、結構出くわしたりしますが)

本題

という事で、前回のカスタムルールに上記機能を追加したいのですが、逆のアプローチの
「とある条件を満たせば、ルールを適用させる」も考えられる訳ですが、今回はそちらは割愛したいと思います。

メソッド名は、skipIf() とします。

以下のようなイメージです。

// 太郎さんの場合は、このチェックはスキップする
(new AllRequired('foo2', 'foo3'))->skipIf($name === '太郎')

ただ、場合によっては処理が複雑になる事も考え、無名関数を渡してその結果が true の時も、チェックをスキップするようにしたいので、以下の形もサポートする事にします。

(new AllRequired('foo2', 'foo3'))->skipIf(function () {
    // 幾つかの処理して
    return $name === '太郎';
})

という事で、引数にコールバック関数を渡された時は、それを実行した結果から判断しないといけなくなりました。何か面倒になってきました。そこで登場するのが、話題の value() ヘルパー関数です。
結果として、以下のようなコードを追加してやります。

class AllRequired implements ImplicitRule, DataAwareRule
{
    public bool $skip = false;

    public function passes($attribute, $value)
    {
        if ($this->skip) {
            return true;
        }

        // 以下略
    }

    /**
     * $callback の値又は実行結果が true 相当の時は、validation をスキップとする
     *
     * @param mixed $callback
     * @return object $this
     */
    public function skipIf($callback)
    {
        $this->skip = !! value($callback);

        return $this;
    }

value() ヘルパー関数は、コールバック関数の時はその実行結果を、コールバック関数以外の時はその値を返してくれます。お陰で、何か楽できた気分です。

おわりに

さて、この value() ヘルパー関数、こんな感じになっています。(GitHub:ソース)

Illuminate\Collections\helpers.php
if (! function_exists('value')) {
    /**
     * Return the default value of the given value.
     *
     * @param  mixed  $value
     * @return mixed
     */
    function value($value, ...$args)
    {
        return $value instanceof Closure ? $value(...$args) : $value;
    }
}

なんだ、1行か。という印象もありますが、それ以上に何故「Collections」の中に?という印象が強い関数でした。

ミス等ありましたらコメント下さい。

Discussion