In Laravel 5 how do you pass data into the FormRequest class?
I am attempting to validate a get variable that comes from a HTML select element.
I am doing this by subclassing FormRequest and adding to the rules array. I would like to build this validation rule dynamically from the list of files to stay DRY.
What is the best way to pass this list into FileFormRequest?
app/Http/Controllers/UploadController.php (please excuse the public property)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Requests\FileFormRequest;
use App\Http\Controllers\Controller;
use File;
class UploadController extends Controller
{
public $files = [];
public function get(FileFormRequest $request)
{
$files_dir = storage_path('app').'/spreadsheets';
foreach (File::allFiles($files_dir) as $file) {
$file = $file->getBasename();
$this->files[$file] = $file;
}
return view('main', array(
'title' => '',
'file_names' => $this->files,
'file_name' => '',
'sheet_name' => '',
'encoding' => 'UTF-8'
));
}
}
app/Http/Requests/FileFormRequest.php
<?php namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Response;
class FileFormRequest extends FormRequest
{
public function rules()
{
// What goes here in place of the empty array?
$files = implode(',', []);
return [
'file_name' => 'sometimes|required|in:'.$files,
];
}
public function authorize()
{
return true;
}
}
OK I solved this by
Code was:
app/Contracts/Utilities/UploadFilesContract.php - create the interface
<?php
namespace App\Contracts\Utilities;
interface UploadFilesContract {
public function __construct($dir);
public function getDir();
public function getFilesBasenames();
}
app/Utilities/UploadFiles.php - create the class with the listing functionality
<?php
namespace App\Utilities;
use Illuminate\Support\Facades\File;
use App\Contracts\Utilities\UploadFilesContract;
class UploadFiles implements UploadFilesContract {
private $dir;
private $files;
public function __construct($dir = '')
{
$this->dir = storage_path('app').(0 < strlen($dir) ? '/'.$dir : '');
$this->files = File::allFiles($this->dir);
}
public function getDir()
{
return $this->dir;
}
public function getFilesBasenames()
{
$files = [];
foreach ($this->files as $file) {
$file = $file->getBasename();
$files[$file] = $file;
}
return $files;
}
}
app/Providers/UploadFilesServiceProvider.php - bind the interface to an instance of the class
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Utilities\UploadFiles;
class UploadFilesServiceProvider extends ServiceProvider
{
protected $defer = true;
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->bindShared('App\Contracts\Utilities\UploadFilesContract', function($app) {
return new UploadFiles('spreadsheets');
});
}
public function provides()
{
return ['App\Utilities\UploadFiles'];
}
}
app/Http/Controllers/UploadController.php - inject the uploaded files interface in the constructor
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Requests\FileFormRequest;
use App\Contracts\Utilities\UploadFilesContract;
class UploadController extends Controller
{
private $upload_files;
public function __construct(UploadFilesContract $upload_files) {
$this->upload_files = $upload_files;
}
public function get(FileFormRequest $request)
{
return view('main', array(
'title' => '',
'file_names' => $this->upload_files->getFilesBasenames(),
'file_name' => '',
'sheet_name' => '',
'encoding' => 'UTF-8'
));
}
}
app/Http/Requests/FileFormRequest.php - inject the uploaded files interface in the constructor
<?php namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Contracts\Utilities\UploadFilesContract;
class FileFormRequest extends FormRequest
{
private $upload_files;
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, UploadFilesContract $upload_files)
{
parent::__construct($query, $request, $attributes, $cookies, $files, $server, $content);
$this->upload_files = $upload_files;
}
/**
* @return array
*/
public function rules()
{
$files = implode(',', $this->upload_files->getFilesBasenames());
$rules = [
'file_name' => 'sometimes|required|in:'.$files,
];
return $rules;
}
/**
* @return bool
*/
public function authorize()
{
return true;
}
}
config/app.php - register the provider
<?php
// ...
'providers' => [
// ...
App\Providers\UploadFilesServiceProvider::class,
],
// ...
You may try this:
public function rules()
{
// Get the REQUEST (GET/POST) variable
$files = app('request')->get('form_field_name');
return [
'file_name' => 'sometimes|required|in:'.$files,
];
}
If form_field_name
is not an array then make it an array depending on the value it contains. Also, you may create another protected
method to get input from request if that requires much code, for example:
protected function getRequestInput()
{
$files = app('request')->get('form_field_name');
// Process it here and finally return, i.e:
return $files; // array
}
So you are now able to call the method from within rules
method like this:
$files = $this->getRequestInput();