Laravel Валидация данных (POST) . В сессию не сохраняются данные формы и текст ошибок валидации.

littus

Новичок
Всем доброго дня!
Как я понимаю проблема в том, что в сессию не сохраняются данные формы и текст ошибок валидации. Если я все тоже самое делаю, но без валидации данных в Контроллере, то в сесиию все отлично сохраняется.

Есть простая вью с формой отправки данных (через шаблонизатор 'blade'):
HTML:
<!--Main content-->
@section('main_content')
<pre>  
    {{ var_dump( Session::all() ) }} <!-- Or - var_dump( Session::all() and  var_dump( Session::all()['_old_input']['name'] ); -->
</pre>
    <!---->
    <div class="row center-block">
        <div class="col-lg-offset-3 col-md-offset-3 col-sm-offset-3 col-lg-6 col-md-6 col-sm-6 col-xs-12">

        <form method="POST" action="<?='/contact';?>">  <!-- <?//=route('contact');?> Or в удвоенных фиг.скобках route('contact') -->
            <div class="form-group">
                <label for="name">Name:</label>
                <input type="text" class="form-control" id="name" name="name" value="{{ old('name') }}" placeholder="Enter Name">
            </div>
            <div class="form-group">
                <label for="email">Email address:</label>
                <input type="email" class="form-control" id="email" name="email" value="{{ old('email') }}" placeholder="Enter E-mail">
            </div>
            <div class="form-group">
                <label for="site">Site:</label>
                <input type="text" class="form-control" id="site" name="site" value="{{ old('site') }}" placeholder="Enter Site">
            </div>
            <div class="form-group">
                <label for="text_area">Text:</label>
                <textarea class="form-control" id="text_area" name="text_area" rows="3" placeholder="Some text....."> {{ old('text_area') }} </textarea>
            </div>

            <div class="checkbox">
                <label><input type="checkbox" name="checkbox"> Remember me</label>
            </div>
            <button type="submit" class="btn btn-default">Submit</button>
        </form>

        </div> <!--/class="col-"-->
    </div> <!--/class="row"-->
@endsection
<!--/Main content-->
Есть простой Контроллер `ContactController.php`
PHP:
<?php
namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;

class ContactController extends Controller {


    public function show( Request $request, $prm=false ){

        $my_array = ['title1'=>'This variable `$title1` content', 'title2'=>'This variable `$title2` content', 'title3'=>'This variable `$title3` content']; //массив
        $my_array2 = ['one'=>array('param1'=>'This variable `param1` content', 'param2'=>'This variable `param2` content', 'param3'=>'This variable `param3` content'),
            'two'=>array('param4'=>'This variabl e `param4` content', 'param5'=>'This variable `param5` content', 'param6'=>'This variable `param6` content')
        ];

        $my_array3 = array(
            'title'=>'Contact',
            'data'=>[ 'one'=>'list 1',
                'two'=>'list 2',
                'three'=>'list 3',
                'four'=>'list 4',
                'five'=>'list 5',
            ],
            'dataI'=>['list-1','list-2','list-3','list-4','list-6','list-6'],
            'bvar'=>true,
            'script'=>"<script>alert('Hello! ++')</script>"
        );

        /** VALIDATION on Request */
        if( $request->isMethod('post') ) {
            //$request->session()->reflash();
            //$request->session()->keep(['name', 'email', 'site', 'text_area']);
            //$request->session()->reflash();
            //dump( $request->session()->all() );


            $rules = [
                'name' => 'required|max:10',
                'email' => 'required|email',
                //'site'=>'required',
                //'text_area'=>'required',
            ];

            $messages = [
                'required' => 'The :attribute field is required.',
            ];

            $this->validate($request, $rules, $messages);
                dump( $request->all() );
                dump( $request->session()->all() );
        }


        if( view()->exists('default.contact') ){
            return view('default.contact')
                ->withMydata($my_array2)
                ->withMydata2($my_array)
                ->withMydata3($my_array3);
        }
        else { abort(404); }

    }

} //__/class ContactController
По идее,когда валидация данных по установленным правилам успешна для кадого из перечисленных полей Формы, то код после инициализации процесса валидации (строка $this->validate($request, $rules, $messages);) будет выполнен и я получаю dump того, что в POST и того, что будет записано в сессию. Когда валидация успешна, данные в Форме не должны оставаться, а вот когда валидация провалена, то должно генерироваться исключение и должен происходить редирект на предыдущую страницу, а данные, сохраняться в сессии и, благодаря указанной конструкции в вьюхе
value="{{ old('name') }}" отображаться в полях. Но у меня этого не происходит.
Если я верно ввожу данные в форму, чтобы валидация была успешна, - я вижу распечатку POST, что значит, валидация таки успешно прошла (и правила то действуют, указанные в Контролллере), но вот когда я ввожу не верные для валидирования данные, чтоб провалить ее, то и сохраненных данных в полях я не вижу, что как я понимаю, должно быть автоматически в этом механизме валидации заложено.

Скажу также, что разрешение на запись flash()-данных я тоже прописал в `/app/Http/Kernel.php`
PHP:
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    ];
При этом, как я говорил, если я не буду в контроллере проводить валидацию данных, и установлю $request->flash(); чтобы данные из POST записывались в сессию одноразово, то они записываются и в Форме остаются, т.е. тут все работает корректно.
Но используя валидацию, я эту строку $request->flash(); удаляю, т.к. судя по документации механизм валидации сам это делает и это писать не нужно.

Кто подскажет, что я забыл прописать или сделал не верно, что у меня не работает валидация совместно с записью в сессию и отображением после провала валидации и соответственно редиректа, Формы с данными заполненными при отправки поста?

Использую сейчас Laravel 5.2
 

littus

Новичок
Перечитайте документацию, сделайте валидаюцию через request https://laravel.com/docs/5.2/validation#form-request-validation
Да, я вижу, что можно для этого сделать отдельный Класс и в нем указать правила валидации для каждого поля и я попробую так сделать, но в простых случаях должна работать и данная конструкция, без отдельно созданного Класса с правилами валидации. Здесь простой сценарий валидации всего 3 поля. Можно ведь и не создавать Класс.
Почему может не работать в данном случае? Есть же причина.
 

Adelf

Administrator
Команда форума
не делай так чтобы у тебя один метод обрабатывал и пост и гет. делай разные методы. всегда.
 

littus

Новичок
не делай так чтобы у тебя один метод обрабатывал и пост и гет. делай разные методы. всегда.
Хорошо, спасибо, я учту.
_______________________________
Как я могу видеть то валидация отрабатывает и ее правила действуют, но я не вижу отображения ошибок валидации, когда она не пройдена и данных в полях input при заполнении Формы при редиректе обратно.

Есть у кого-то идеи почему так может быть?
 

littus

Новичок
нет, дело не в этом, - во вью у меня для отображения ошибок конечно же есть вывод
HTML:
        @if( count($errors) > 0 )
            <div class="alert alert-danger">
                <ul>
                    @foreach( $errors->all() as $error ) <li>{{ $error }}</li> @endforeach
                </ul>
            </div>
        @endif

        <form method="POST" action="{{  route('contact') }}">
            ..........
            ..........
Здесь что-то другое.
Кстати, если я в своем Контроллере вверху прописываю
PHP:
use Validator;
то редактор кода мне подсвечивает и выводит подсказку undefined class Validatior , а так ведь не должно быть?
Может кто-то проверить. Может у меня что-то недоставилось в проекте в процессе установки или было перемещено. Я уже не знаю....
 

Adelf

Administrator
Команда форума
@AmdY, да там просто ларковские фасады. надо laravel-ide-helper и сгенерить нужный код.
 

AmdY

Пью пиво
Команда форума
Нах фасады, да и сам трейт туда же. Слишком сложная магия в сравнении с нормальной валидацией.
 

littus

Новичок
Огромное спасибо всем отписавшимся за помощь, - разобрался, все работает как нужно теперь.
Не знаю, почему не отработала конструкция, хотя должна и так работать (напомню проект на laravel 5.2):
Код:
 $this->validate($request, $rules)
dump( $request->all() );
Но я у себя сделал так и все стало работать и корректно (возвращаться при провале валидации "старые" поля с заполненными данными при отправке Формы и выводится ошибки валидации):

Код:
/** VALIDATION on Request */
        if( $request->isMethod('post') ):

            $rules = [
                'name' => 'required|max:10',
                'email' => 'required|email',
                'site'=>'required',
            ];
            $messages = [
                'required' => 'The :attribute field is required.',
            ];

            $validator = \Validator::make($request->all(), $rules);
            if( $validator->fails() ) {
                $request->flash();
                return view('default.contact')
                    ->withMydata($my_array2)
                    ->withMydata2($my_array)
                    ->withMydata3($my_array3)
                    ->withTitlecontactpage($title_contact_page)
                    ->withInfoMethodController($this->show_controller_method)
                    ->withErrors($validator)
                    ->withInput( $request->all() );
            }
            dump( $request->all() );

        endif;
1. Конструкции с return back()->withInput($request->input())->withErrors($validator); а также return redirect()->back()->withErrors($validator)->withInput($request->input()); - у меня не отрабатывают. И единственная успешная комбинация, которая все корректно вывела и сделала как должно быть у меня - приведена выше.

2. Вместо ->withInput( $request->all() ); можно прописать и ->withInput( $request->input() ) - тоже работает.

3. Вместо $validator = \Validator::make($request->all(), $rules); можно прописать $validator = $this->getValidationFactory()->make($request->all(), $rules); обратившись непосредственно к методу getValidationFactory() - тоже ОК - работает.
 

littus

Новичок
Да, но тогда подскажите, что я не верно сделал с учетом передела валидации через собственный Класс `Request` и, + как Вы и советовали, я разделил роуты для GET и POST и определил для них отдельные методы в своем Контроллере.
1. app/Http/routes.php
PHP:
Route::get('/contact_form/{prm?}', ['uses'=>'Admin\ContactformController@show_form_get'])->name('contact_form');

Route::post('/contact_form', ['uses'=>'Admin\ContactformController@show_form_post']);
2. app/Http/Requests/ContactRequest.php - мой пользовательский Класс-Request с правилами валидации:
PHP:
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;

class ContactRequest extends Request
{

    public function authorize()
    {
        return true;  //false.
    }

 
    public function rules()
    {
        return [
            'name' => 'required|max:10',
            //'name' => 'exists:users,name',
            'email' => 'required|email',
            'site'=>'required',
        ];
    }

}  //__/class ContactRequest
2. app/Http/Requests/ContactRequest.php - мой Контроллер с обработкой POST и GET (теперь разделенных по отдельности):
PHP:
<?php
namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Requests\ContactRequest;   //свой Класс `ContactRequest` с правилами валидации
use App\Http\Controllers\Controller;
use \Illuminate\Support\Facades\Validator;

class ContactformController extends Controller {

    public $show_controller_method = array(__METHOD__);
    //__________________________________________________________________________________________________________________

    /** Method handler http-request with GET
    */
    public function show_form_get( ){

        $this->show_controller_method[] = 'showform()';
        if( view()->exists('default.contact_form') ){
            return view('default.contact_form')->withInfoMethodController($this->show_controller_method);
        }
        else { abort(404); }

    }  //__/public function show_form_get()


    /** Method handler http-request with POST
    */
    public function show_form_post( ContactRequest $request ){

        /** VALIDATION on Request */
        if( $request->isMethod('post') ):
            dump( $request->all() );
        endif; //__/if( $request->isMethod('post') )

        $this->show_controller_method[] = 'showform()';
        if( view()->exists('default.contact_form') ){
            return view('default.contact_form')->withInfoMethodController($this->show_controller_method);
        }
        else { abort(404); }

    }

} //__/class ContactformController

3. Вью осталась таже, - т.е. там прописаны возвращение данных
Код:
value="{{ old('name') }}"  value="{{ old('email') }}"  и т.д. ...
а также отображение ошибок валидации ежели оные имеются:
Код:
@if( count($errors) > 0 )
    <div class="alert alert-danger">
        <ul>
            @foreach( $errors->all() as $error ) <li>{{ $error }}</li> @endforeach
        </ul>
    </div>
@endif
Сейчас как и прежде сама валидация работает (если она проходит успешно, - я вижу dump() поста, который я прописал в методе public function show_form_post ) Контроллера. Если валидация валится, то как и прежде редирект, но не ошибок валидации ни данных предыдущих input`ов нет.

По идее, должно работать. Почему нет?
 
Последнее редактирование:

Adelf

Administrator
Команда форума
Не надо показывать форму на post.
PHP:
<?php
namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Requests\ContactRequest;   //свой Класс `ContactRequest` с правилами валидации
use App\Http\Controllers\Controller;
use \Illuminate\Support\Facades\Validator;

class ContactformController extends Controller {

    public $show_controller_method = array(__METHOD__);

    public function show_form_get( )
    {
            return view('default.contact_form', ['viewparam' => 'value']);
    }

    public function show_form_post( ContactRequest $request ){
    // здесь мы не должны показывать никаких форм. просто выполнить действие и сделать редирект.
    }

}
 

littus

Новичок
не, не работает. Я убрал все из public function show_form_post() оставил только редирект, хотя как я понял он и так должен происходить при провале валидации!!

PHP:
public function show_form_post( ContactRequest $request ){
    // здесь мы не должны показывать никаких форм. просто выполнить действие и сделать редирект.
      return redirect()->route('contact_form');
    }
 

Adelf

Administrator
Команда форума
да. но при провале валидации он должен идти назад. на форму. и там показаться ошибки должны.
 

littus

Новичок
да. но при провале валидации он должен идти назад. на форму. и там показаться ошибки должны.
Идет, назад на Форму, - редирект имеет место, но ошибки валидации и сохраненные данные предыдущего POST запроса, которые должны быть записаны как flash()-данные, не отображаются.
 

Pathfinder

Новичок
В Kernel.php убери из protected $middleware StartSession и ShareErrorsFromSession. Они уже в middlewareGroups прописаны, поэтому и глючит. Вот когда появится другая группа маршрутов, нужно будет заново вписать, эти middleware)
 
Сверху