Ellrion
9/21/2017 - 10:36 AM

Trait for confirmation request (by analogy with https://github.com/laravel/framework/blob/5.5/src/Illuminate/Foundation/Auth/Access/Authoriz

<?php

namespace App\Support\Http;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

trait ConfirmsRequests
{
    /**
     * Confirm the given request using confirmation field.
     *
     * @param string $field
     * @param mixed|\Illuminate\Database\Eloquent\Model $resource
     * @param string|null $parameter
     * @param \Illuminate\Http\Request|null $request
     *
     * @throws \App\Support\Http\ConfirmationException
     */
    public function confirm($field, $resource, $parameter = null, $request = null)
    {
        $request = $request ?: app('request');
        $parameter = $parameter ?: 'confirm_' . strtolower(class_basename($resource)) . '_' . $field;

        $field_in_resource = data_get($resource, $field);
        $field_in_request = data_get($request, $parameter);

        if ($field_in_resource !== $field_in_request) {
            $this->throwConfirmationException($request);
        }
    }

    /**
     *  Confirm the given request using password of auth user.
     *
     * @param string $field
     * @param string|null $guard
     * @param \Illuminate\Http\Request|null $request
     *
     * @throws \App\Support\Http\ConfirmationException
     */
    public function confirmByPass($field = 'password', $guard = null, $request = null)
    {
        $request = $request ?: app('request');
        $auth = app('auth');

        $confirmation = $auth->guard($guard)->getProvider()->validateCredentials(
            $auth->user(),
            ['password' => $request->input($field)]
        );

        if (!$confirmation) {
            $this->throwConfirmationException($request);
        }
    }

    /**
     * Throw the failed confirmation exception.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     *
     * @throws \App\Support\Http\ConfirmationException
     */
    protected function throwConfirmationException(Request $request)
    {
        throw new ConfirmationException($this->buildFailedConfirmationResponse(
            $request,
            $this->makeConfirmationErrors()
        ));
    }

    /**
     * Create the response for when a request fails confirmation.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  array  $errors
     * @return \Symfony\Component\HttpFoundation\Response
     */
    protected function buildFailedConfirmationResponse(Request $request, array $errors)
    {
        if ($request->expectsJson()) {
            return new JsonResponse($errors, 422);
        }

        return redirect()->to($this->getRedirectUrl())
            ->withInput($request->input())
            ->withErrors($errors);
    }

    /**
     * Format the request confirm errors to be returned.
     *
     * @return array
     */
    protected function makeConfirmationErrors()
    {
        return ['confirmation' => 'Failed confirmation.'];
    }
}
<?php

namespace App\Support\Http;

use Exception;

class ConfirmationException extends Exception
{
    /**
     * The recommended response to send to the client.
     *
     * @var \Symfony\Component\HttpFoundation\Response|null
     */
    public $response;

    /**
     * Create a new exception instance.
     *
     * @param  \Symfony\Component\HttpFoundation\Response  $response
     * @return void
     */
    public function __construct($response = null)
    {
        parent::__construct('The request failed to pass confirmation.');

        $this->response = $response;
    }

    /**
     * Get the underlying response instance.
     *
     * @return \Symfony\Component\HttpFoundation\Response|null
     */
    public function getResponse()
    {
        return $this->response;
    }
}