I want to download a excel file through Checkbox Unique ID in laravel, I am using Maatwebsite\Excel Here - laravel

My Controller File
public function enquiryExport($id, Request $request)
{
$id[] = $request->explode(",",$id);
return Excel::download(new EnquiryExport($id), 'enquiry.xlsx');
}
and My Export File
protected $id;
function __construct($id) {
$this->id = $id;
}
public function collection()
{
return Enquiry::whereIn('id',explode(",",$this->id))->get();
/* return Enquiry::all(); */
}
Route is like
Route::get('enquiryExport', 'enquiryController#enquiryExport');
Still I am getting this error
"message": "Too few arguments to function App\\Http\\Controllers\\enquiryController::enquiryExport(), 1 passed and exactly 2 expected",
I am checkbox id through AJAX here.

The problems is your Route method.
Get method: the query string (name/value pairs) is sent in the URL of a GET request
Post method: the data sent to the server with POST is stored in the request body of the HTTP request
If you use Get method: try this (I have just read it, not tried)
Route::get('enquiryExport/{id}', 'enquiryController#enquiryExport')->name('enquiryExport');
Submit
If you use Post method: try this (I am used to use this)
Route::post('enquiryExport', 'enquiryController#enquiryExport');
public function enquiryExport(Request $request)
{
return Excel::download(new EnquiryExport($request->input('id')), 'enquiry.xlsx');
}
You can read more here: https://www.w3schools.com/tags/ref_httpmethods.asp

Try this
In controller:
public function enquiryExport(Request $request, $id)
{
return Excel::download(new EnquiryExport($request->id), ''.date('Y-m-d'). '.xlsx', \Maatwebsite\Excel\Excel::XLSX);
}
In Export File:
protected $id;
function __construct($id) {
$this->id = $id;
}
public function collection()
{
return Enquiry::where('id', $this->id)->get();
}
public function map($enquiry): array
{
return [
// $enquiry->WRITE YOUR RECORDS,
// ...
];
}
public function headings(): array
{
return [
//NAME HEADINGS(TITLE) OF YOUR RECORDS IN SIDE SINGLE QUOTATION,
// ...
];
}
In Route:
Route::get('enquiryExport/{id}', 'enquiryController#enquiryExport');

Related

Model binding for JSON api using Laravel

We are moving an older PHP project over to laravel. We are trying to post JSON to our api we created, but are not aware how to have the JSON be bound to a model. We added the model as a parameter to the function, it is created but none of the properties are set on it from the JSON. Does this type of model binding exist in laravel?
class CalculatorModel
{
/**
* Value A.
*
* #var integer
*/
public $A;
/**
* Value B.
*
* #var integer
*/
public $B;
}
class CalculatorController
{
// What is trying to be achieved.
public function add(CalculatorModel $model)
{
return Calculator::Add($model);
}
// What we are trying to avoid
// as there is a lot of properties/objects in our real world JSON
public function add(Request $request)
{
$a = $request->json()->all();
$m = new CalculatorModel();
$m->A = $a['A'];
$m->B = $a['B'];
....
return Calculator::Add($m);
}
}
// in reoutes/api.php
Route::post('add', 'API\CalculatorController#add');
// External library's class
class Calculator
{
public static function Add(CalculatorModel $m)
{
return $m->A + $m->B;
}
}
Simple JSON post
{
"A": 2,
"B": 2
}
In ASP.Net, we are able to add a [FromBody] attribute to the parameter so that ASP.Net would bind the content body as the model instead of form content. We are looking for similar functionality in laravel.
There is no such binding in Laravel. Laravel binding is about Models/DB access as #PKeidel said. All you need is controller method without any models.
public function add(Request $request)
{
return $request->A + $request->B;
}
UPD: What about new constructor for CalculatorModel class?
public function __construct(array $properties = [])
{
foreach ($properties as $key => $value) {
$this->{$key} = $value;
}
}
public function add(Request $request)
{
$m = new CalculatorModel($request->all());
return Calculator::Add($m);
}
In any case Laravel does not offer out of the box solution for this.
Try this to wrap your API, which can then be used by Eloquent as if it were a database model:
https://github.com/CristalTeam/php-api-wrapper
All what models are about is saving/reading something from the database. So if this is not what you want, forget about it. Because in Laravel models are bound to database tables ;-)
If you just want so receive some values as json, do a calculation and return a value you are thinking to complicated.
Create a route:
Route::post('add', function() {
$data = request()->json();
return $data->get('A') + $data->get('B');
});
Or:
Route::post('add', function(\Illuminate\Http\Request $r) {
return $r->A + $r->B;
});
This is all it takes.
After that just make sure to send your data with json header. Like so:
fetch('/add', {
method:"post",
headers: {'Content-Type': 'application/json'},
body: '{"A": 2,"B": 2}'
})
.then((d) => d.text())
.then((html) => {
output.innerHTML = html;
})
See it in action here: https://laravelplayground.com/#/snippets/006b4871-5d92-4a2d-b8af-8a21423024e6

show error while fetch username

show error : Missing argument 1 for App\Http\Controllers\AdminLoginController::name()
public function name($username) {
$user = AdminLogin::find($username);
return response()->json($user);
}
AdminLoginController: Its a adminlogin controller code
class AdminLoginController extends Controller{
public function show(){
$res ="Hello world!";
return response()->json($res);
}
public function log() {
$users = AdminLogin::all();
return response()->json($users);
}
public function name($username) {
$user = AdminLogin::where('username',$username)->first();
return response()->json($user);
}
RouteLoginController: Its a adminlogin controller code :
<?php
$app->get('/', function () use ($app) {
return $app->version();
});
$app->group(['prefix' => 'api/v1'], function ($app)
{
$app->get('adminlogin', 'AdminLoginController#show'); //get single route
$app->get('user', 'AdminLoginController#log'); //get single route
$app->get('username', 'AdminLoginController#name'); //get single route
$app->post('adminlogin', 'AdminLoginController#login'); //get single route
});
Error :
(1/1) ErrorException
Missing argument 1 for App\Http\Controllers\AdminLoginController::name()
Your controller method is taking the username param but the route binding is not passing one. Change your route
$app->get('username', 'AdminLoginController#name');
to
$app->get('user/{username}', 'AdminLoginController#name');
If you don't want to change your route, change your controller function signature to the below (as shown in the other answers), and make sure you are passing the 'username' as request param while invoking the url.
public function name(\Illuminate\Http\Request $request) {
$user = AdminLogin::where('username',$request->username)->first();
return response()->json(['user' => $user]);
}
You are probably calling this function using an ajax request and putting the name in the query string. In this case, the name parameter will not be sent as an attribute of the function but will be part of the request object.
You can solve this like so:
public function name(\Illuminate\Http\Request $request) {
$user = AdminLogin::find($request->username);
return response()->json($user);
}
You should try this :
public function name($username) {
$user = AdminLogin::where('username',$username)->first();
return response()->json(['user' => $user]);
}
OR
public function name(\Illuminate\Http\Request $request) {
$user = AdminLogin::where('username',$request->username)->first();
return response()->json(['user' => $user]);
}

Laravel 5 Sanitizing Required Field Behavior

I am trying to sanitize the user input in my application following this article
Below is my request
class TestRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
$this->sanitize();
return [
'title'=>'required|max:100'
];
}
public function sanitize()
{
$input = $this->all();
if(!empty($input))
{
$input['title'] = trim(strip_tags($input['title']));
$this->replace($input);
}
}
}
Tough the title is required field, if I try to put <h1></h1> as input in the title field, as per the logic in sanitize() function the tags are stripped away, but an empty string is saved in the database. The required field validation in the rules in not taking any effect.
How to handle this?
Update:
Below is the controller method for saving the request.
public function save(TestRequest $request)
{
$input = $request->all();
...
}
First option is to use merge() instead of replace() in your code, i.e.:
$this->merge( ['title' => trim(strip_tags($input['title']))] );
Second option is to override the all() function, i.e.:
public function all()
{
$input = parent::all();
if( !empty($input) )
{
$input['title'] = trim(strip_tags($input['title']));
}
return $input;
}
In the last code example you dont have to use the sanitize() function.

Laravel validation request class return model with errors

When validating a form with a request class you can manually validate the data using the validate() method but what do you return back I've tried return $this and return $this->errors but it just shows SQL integrity constraint duplicate entry which is correct but it doesn't show my form with the errors. When doing validation inside the controller you return the model and the errors but what do I return and set errors on validate method in the request class.
Request Class:
namespace App\Http\Requests;
use App\Http\Requests\Request;
use Auth;
class ProductRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
protected $action;
public function authorize()
{
if(Auth::check()) {
return true;
}
}
public function validate() {
$v = \Validator::make(parent::all(), $this->rules());
if ($v->passes()) return true;
$this->errors = $v->messages();
// tried returning $this; and $this->errors
return false;
}
public function all()
{
$data = parent::all();
if( $data['slug'] === '') {
// if the slug is blank, create one from title data
$data['slug'] = str_slug( $data['title'], '-' );
}
return $data;
}
public function messages()
{
}
public function rules() {
}
}
your rule method is empty your not validating any thing the error you got is an SQL exception not a validation error.

How to redirect store to update method?

How to redirect store to update method? I tryed the following code:
public function store(ProductRequest $request)
{
return $this->update(new Product, $request);
}
public function update(Product $product, ProductRequest $request)
{
// code
}
However, the first parameter of update need an already in database user and the above code does not work as expected. (it update the entire users in db!)
What is the correct way to achieve that?
public function store(UserRequest $request)
{
return $this->maintain(new User, $request);
}
public function update(User $user, UserRequest $request)
{
return $this->maintain($user, $request);
}
private function maintain($user, $request)
{
//code;
}
The model for the update method could be the problem, your code is okay for this part:
public function store(Request $request)
{
return $this->update(new Product, $request);
}
public function update(Product $product, Request $request)
{
$product->fill($request->all())->save();
// code
}
For example, with route model binding:
Route::resource('products', 'ProductController');
Route::model('products', App\Product::class);
Or with a custom binding:
Route::resource('products', 'ProductController');
Route::bind('products', function($param) {
return Product::where('slug', $param)->first();
});
Make sure you are not using get() in custom binding, it will pass back a collection.

Resources