このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
|
apricot:ext:interceptor [2020/05/25 17:37] y2sunlight |
apricot:ext:interceptor [2020/06/08 16:25] (現在) tanaka [Apricot インターセプター] |
||
|---|---|---|---|
| 行 1: | 行 1: | ||
| - | > 編集中 | ||
| - | |||
| - | ----- | ||
| - | |||
| ====== Apricot インターセプター ====== | ====== Apricot インターセプター ====== | ||
| --- // | --- // | ||
| 行 26: | 行 22: | ||
| インターセプター とはアクションの前処理の事です。ミドルウェアと同じでリクエストを中断してレスポンスオブジェクトを生成することもできますが、アクションの後処理はできません。これを図示すると以下のようになります。 | インターセプター とはアクションの前処理の事です。ミドルウェアと同じでリクエストを中断してレスポンスオブジェクトを生成することもできますが、アクションの後処理はできません。これを図示すると以下のようになります。 | ||
| - | Middleware | + | === インターセプター構造 === |
| - | ┌──────────┐ | + | |
| - | | | | + | {{: |
| - | | + | |
| - | [Request ] --> | -------> | --> |--|--------> | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | [Response] <-- | < | + | |
| - | | + | |
| - | | + | |
| 上図から分かるようにミドルウェアパイプラインから見ると、インターセプターはアクションに含まれます。ミドルウェアとの一番の違いは、ミドルウェアは基本的に全てのコントローラを対象としているのに対し、インターセプターは、各コントローラで独自に設定ができるという点です。 | 上図から分かるようにミドルウェアパイプラインから見ると、インターセプターはアクションに含まれます。ミドルウェアとの一番の違いは、ミドルウェアは基本的に全てのコントローラを対象としているのに対し、インターセプターは、各コントローラで独自に設定ができるという点です。 | ||
| 行 73: | 行 61: | ||
| protected function intercept($actionName, | protected function intercept($actionName, | ||
| { | { | ||
| - | $interceptor_arr | + | |
| - | if (!array_key_exists($actionName, | + | |
| { | { | ||
| - | $this-> | + | |
| + | | ||
| } | } | ||
| - | $this-> | ||
| } | } | ||
| 行 104: | 行 91: | ||
| // Invoke Interceptor | // Invoke Interceptor | ||
| - | | + | |
| + | foreach($this-> | ||
| { | { | ||
| - | | + | |
| - | foreach($this-> | + | |
| { | { | ||
| - | | + | |
| + | $response = call_user_func_array($interceptor, | ||
| + | } | ||
| + | elseif(strpos($interceptor,' | ||
| + | { | ||
| + | // Case of Controller/ | ||
| + | list($class, | ||
| + | if (empty($class)) | ||
| { | { | ||
| - | | + | $instance |
| - | | + | |
| } | } | ||
| - | | + | |
| { | { | ||
| - | | + | $class = " |
| - | list($class, | + | $instance = new $class; |
| - | if (empty($class)) | + | |
| - | { | + | |
| - | $instance = $this; | + | |
| - | } | + | |
| - | else | + | |
| - | { | + | |
| - | | + | |
| - | $instance = new $class; | + | |
| - | } | + | |
| - | + | ||
| - | // Call interceptor | + | |
| - | $response = call_user_func_array(array($instance, | + | |
| } | } | ||
| - | if ($response instanceof \Core\Foundation\Response) | + | |
| - | { | + | $response = call_user_func_array(array($instance, |
| - | return $response; | + | } |
| - | } | + | |
| + | | ||
| + | { | ||
| + | return $response; | ||
| } | } | ||
| } | } | ||
| 行 148: | 行 132: | ||
| * '' | * '' | ||
| + | * リクエストされているアクション(Application:: | ||
| * アクションにインターセプターを追加します。 | * アクションにインターセプターを追加します。 | ||
| - | * BaseControllerは、インターセプターを配列( < | + | * BaseControllerは、インターセプターを配列( < |
| * '' | * '' | ||
| 行 162: | 行 147: | ||
| ===== インターセプターの使用 ===== | ===== インターセプターの使用 ===== | ||
| - | インターセプターの登録は、コントローラーのコンストラクタで '' | + | インターセプターの登録は、コントローラーのコンストラクタで '' |
| <code php> | <code php> | ||
| 行 180: | 行 165: | ||
| </ | </ | ||
| - | インターセプターに渡される引数は、第1引数に、コントローラのインスタンスが、その後にアクションと同じの引数が続きます。 | + | インターセプターに渡される引数は、第1引数に、コントローラのインスタンスが、その後にアクションと同じの引数が続きます。また、インターセプターはレスポンスオブジェクトを返して以降のアクションを中止することができます。 |
| - | '' | + | インターセプターにメソッド型を使用する場合は、以下のように < |
| <code php> | <code php> | ||
| 行 211: | 行 196: | ||
| ==== 認証コントローラ ==== | ==== 認証コントローラ ==== | ||
| - | >TODO: | + | 認証コントローラのバリデーションをクロージャ型のインタセプターとして再実装します。[[apricot: |
| + | |||
| + | - コンストラクタ( <nowiki>__construct()</ | ||
| + | - コンストラクタ内で、login()アクションのインタセプターを登録します。< | ||
| + | $this-> | ||
| + | { | ||
| + | // バリデーションのロジック | ||
| + | }); | ||
| + | </ | ||
| + | - login() メソッド内からバリデーション( validate() ) の呼び出し部分を削除します。 | ||
| + | - validate() を削除します。 | ||
| + | |||
| + | 以下に修正後の最終的な AuthController.php を示します。 | ||
| + | |||
| + | {{fa> | ||
| + | <code php AuthController.php> | ||
| + | <?php | ||
| + | namespace App\Controllers; | ||
| + | |||
| + | use Core\Input; | ||
| + | use Core\Foundation\ErrorBag; | ||
| + | use App\Foundation\Security\AuthUser; | ||
| + | use App\Foundation\Controller; | ||
| + | use App\Foundation\ValidatorErrorBag; | ||
| + | |||
| + | /** | ||
| + | * Authコントローラ | ||
| + | */ | ||
| + | class AuthController extends Controller | ||
| + | { | ||
| + | public function __construct() | ||
| + | { | ||
| + | // インターセプターの登録 | ||
| + | $this-> | ||
| + | { | ||
| + | $inputs = Input::all(); | ||
| + | |||
| + | // Validation | ||
| + | $v =(new \Valitron\Validator($inputs)) | ||
| + | -> | ||
| + | -> | ||
| + | -> | ||
| + | -> | ||
| + | |||
| + | if(!$v-> | ||
| + | { | ||
| + | $errorBag = new ValidatorErrorBag($v-> | ||
| + | return redirect(back())-> | ||
| + | } | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ログインフォーム表示 | ||
| + | * @return \Core\Foundation\Response | ||
| + | */ | ||
| + | public function showForm() | ||
| + | { | ||
| + | if (AuthUser:: | ||
| + | { | ||
| + | // 認証済ならトップ画面表示 | ||
| + | return redirect(route('' | ||
| + | } | ||
| + | |||
| + | if (AuthUser:: | ||
| + | { | ||
| + | // 自動認証できたらトップ画面表示 | ||
| + | return redirect(route('' | ||
| + | } | ||
| + | |||
| + | return render(' | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ログイン(ユーザ認証) | ||
| + | * @return \Core\Foundation\Response | ||
| + | */ | ||
| + | public function login() | ||
| + | { | ||
| + | $inputs = Input:: | ||
| + | |||
| + | if (!AuthUser:: | ||
| + | { | ||
| + | // ユーザが見つからない | ||
| + | $errorBag = new ErrorBag([__(' | ||
| + | return redirect(back())-> | ||
| + | } | ||
| + | |||
| + | // ログイン成功 | ||
| + | return redirect(AuthUser:: | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ログアウト | ||
| + | * @return \Core\Foundation\Response | ||
| + | */ | ||
| + | public function logout() | ||
| + | { | ||
| + | // セッションの破棄 | ||
| + | AuthUser:: | ||
| + | |||
| + | // ログイン画面表示 | ||
| + | return redirect(route(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| \\ | \\ | ||
| 行 218: | 行 308: | ||
| ==== ユーザコントローラ ==== | ==== ユーザコントローラ ==== | ||
| - | >TODO: | + | ユーザコントローラのバリデーションをメソッド型のインタセプターとして再実装します。[[apricot: |
| + | |||
| + | >ユーザコントローラには、[[apricot:app: | ||
| + | |||
| + | - コンストラクタ内で、insert()アクションのインタセプターを登録します。< | ||
| + | $this-> | ||
| + | </ | ||
| + | - 同様に、update()アクションのインタセプターを登録します。< | ||
| + | $this-> | ||
| + | </ | ||
| + | - insert() と update()メソッド内からバリデーションの呼び出し部分を削除します。 | ||
| + | |||
| + | 以下に修正後の最終的な UserController.php を示します。 | ||
| + | |||
| + | {{fa> | ||
| + | <code php UserController.php> | ||
| + | <?php | ||
| + | namespace App\Controllers; | ||
| + | |||
| + | use App\Exceptions\ApplicationException; | ||
| + | use App\Foundation\Controller; | ||
| + | use App\Models\User; | ||
| + | use Core\Input; | ||
| + | |||
| + | /** | ||
| + | * ユーザコントローラ | ||
| + | */ | ||
| + | class UserController extends Controller | ||
| + | { | ||
| + | /** | ||
| + | * User | ||
| + | * @var \App\Models\User | ||
| + | */ | ||
| + | private $user; | ||
| + | |||
| + | /** | ||
| + | * ユーザコントローラの生成 | ||
| + | */ | ||
| + | public function __construct() | ||
| + | { | ||
| + | // モデル | ||
| + | $this-> | ||
| + | |||
| + | // インターセプター登録 | ||
| + | $this-> | ||
| + | $this-> | ||
| + | |||
| + | // トランザクションアクション登録 | ||
| + | $this-> | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ユーザ一覧 | ||
| + | * @return \Core\Foundation\Response | ||
| + | */ | ||
| + | public function index() | ||
| + | { | ||
| + | // 全件検索 | ||
| + | $users = $this-> | ||
| + | return render(" | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ユーザ新規登録 | ||
| + | * @return \Core\Foundation\Response | ||
| + | */ | ||
| + | public function create() | ||
| + | { | ||
| + | // 新規作成 | ||
| + | $user = $this-> | ||
| + | return render(" | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ユーザレコード挿入 | ||
| + | * @return \Core\Foundation\Response | ||
| + | */ | ||
| + | public function insert() | ||
| + | { | ||
| + | $inputs = Input:: | ||
| + | |||
| + | try | ||
| + | { | ||
| + | // ユーザレコード挿入 | ||
| + | $user = $this-> | ||
| + | } | ||
| + | catch(\Exception $e) | ||
| + | { | ||
| + | throw new ApplicationException(__(' | ||
| + | } | ||
| + | |||
| + | // ユーザ一編集画面にリダイレクト | ||
| + | return redirect(route(" | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ユーザ編集 | ||
| + | * @return \Core\Foundation\Response | ||
| + | */ | ||
| + | public function edit(int $id) | ||
| + | { | ||
| + | // 主キー検索 | ||
| + | $user = $this-> | ||
| + | if ($user!==false) | ||
| + | { | ||
| + | return render(" | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | return redirect(route(" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ユーザレコード更新 | ||
| + | * @param int $id | ||
| + | * @return \Core\Foundation\Response | ||
| + | */ | ||
| + | public function update(int $id) | ||
| + | { | ||
| + | $inputs = Input:: | ||
| + | |||
| + | try | ||
| + | { | ||
| + | // レコード更新 | ||
| + | $this-> | ||
| + | } | ||
| + | catch(ApplicationException $e) | ||
| + | { | ||
| + | throw $e; | ||
| + | } | ||
| + | catch(\Exception $e) | ||
| + | { | ||
| + | throw new ApplicationException(__(' | ||
| + | } | ||
| + | |||
| + | // ユーザ一編集画面にリダイレクト | ||
| + | return redirect(route(" | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ユーザレコード削除 | ||
| + | * @param int $id | ||
| + | * @return \Core\Foundation\Response | ||
| + | */ | ||
| + | public function delete(int $id) | ||
| + | { | ||
| + | try | ||
| + | { | ||
| + | // レコード削除 | ||
| + | $this-> | ||
| + | } | ||
| + | catch(ApplicationException $e) | ||
| + | { | ||
| + | throw $e; | ||
| + | } | ||
| + | catch(\Exception $e) | ||
| + | { | ||
| + | throw new ApplicationException(__(' | ||
| + | } | ||
| + | |||
| + | // ユーザ一覧画面にリダイレクト | ||
| + | return redirect(route(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| \\ | \\ | ||