How to validate X-editable request in laravel (Server side) - javascript

I've managed to get x-editable (https://vitalets.github.io/x-editable/) to work with a page, in so far as when I click on a field, it displays inline and I can edit it, and I'm able to successfully submit to a POST URI.
The idea here is that I'm sending three key-value pairs:
array:3 [▼
"name" => "name"
"value" => "mathematics"
"pk" => "1"
]
and my update() method catches the array, and it successfully updates the record in the database. But I'm failing to validate the data.
This is how my controller looks:
public function update(Request $request)
{
//
$id = $request->pk;
$subject = Subject::findOrFail($id);
$rules = array (
'name' => 'bail|required|max:20|unique:subjects,name,'.$id
);
This validation pass easily even if I try to fail it
$validator = Validator::make ( $request->all(), $rules );
if ($validator->fails ()) {
return response()->json ( array (
'errors' => $validator->getMessageBag ()->toArray ()
) );
} else {
$subject->update([$request->name => $request->value]);
}
return response ()->json ( $subject );
}
So it's as if I'm somehow not passing the "correct" Request object to validate()? There is no form submission, but the documentation clearly states that:
Laravel generates a JSON response containing all of the validation errors. This JSON response will be sent with a 422 HTTP status code.1
Route:
Route::post('/subjects/update/', 'SubjectsController#update');
script:
$('#subjects').editable({
container:'body',
selector:'td.name',
type:'post',
dataType:'JSON',
validate:function(value){
if ($.trim(value) === '') {
return "Field is required";
}
}
});
1https://laravel.com/docs/5.4/validation#quick-ajax-requests-and-validation

If I'm not mistaken, name is the field to be edited (the DB column), and value is, well, the value. It looks like you are updating the name column, so you have to validate the uniqueness of the value in the request, not the "name".
Also, I'd suggest you use the validate method of your controller (provided by the ValidatesRequests trait):
public function update(Request $request)
{
$id = $request->pk;
$subject = Subject::findOrFail($id);
$this->validate($request, [
'name' => 'required', // this should be the column to update
'value' => 'bail|required|max:20|unique:subjects,name,'.$id
];
$subject->update([$request->name => $request->value]);
return $subject;
}
Here validate will automatically reject with a 422 code and the validation errors in the JSON response. If it passes, it will continue with the update. (return $subject also returns a JSON representation of the object in the response.)

Related

Stripe: payment_init.php returns 403 forbidden error code

I am trying to integrate a Stripe payment method in a web application. I am stuck: payment_init.php does not load, when I am redirected to the page. I get 403 Forbidden error code ("Forbidden. You don't have permission to access this resource.
Additionally, a 400 Bad Request error was encountered while trying to use an ErrorDocument to handle the request").
Here is my payment_init.php file's code:
<?php
// Include the Stripe PHP library
require_once 'stripe-php/init.php';
// Include the configuration file
require_once 'config.php';
$chosenService = $_POST['submitService'];
printf($chosenService);
// Product Details
if ($chosenService === "1") {
$productName = "Hajvágás (6900 HUF)";
$productID = "hc001";
$productPrice = 6900;
} elseif ($chosenService === "2") {
$productName = 'Hajvágás + Szakáll (9900 HUF)';
$productID = "hc002";
$productPrice = 9900;
};
$currency = "huf";
$description = "20% előleg Mobil Barber";
printf($productName);
// Set API key
\Stripe\Stripe::setApiKey(STRIPE_API_KEY);
$response = array(
'status' => 0,
'error' => array(
'message' => 'Invalid Request!'
)
);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$input = file_get_contents('php://input');
$request = json_decode($input);
}
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo json_encode($response);
exit;
}
if (!empty($request->createCheckoutSession)) {
printf($productName);
// Convert product price to cent
$stripeAmount = round($productPrice * 100, 2);
// Create new Checkout Session for the order
try {
printf($productName);
$checkout_session = \Stripe\Checkout\Session::create([
'line_items' => [[
'price_data' => [
'currency' => $currency,
'unit_amount' => $productPrice,
'product_data' => [
'name' => $productName,
'description' => $description,
],
],
'quantity' => 1,
]],
'mode' => 'payment',
'success_url' => STRIPE_SUCCESS_URL . '?session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => STRIPE_CANCEL_URL,
]);
} catch (Exception $e) {
$api_error = $e->getMessage();
}
if (empty($api_error) && $checkout_session) {
$response = array(
'status' => 1,
'message' => 'Checkout Session created successfully!',
'sessionId' => $checkout_session->id
);
} else {
$response = array(
'status' => 0,
'error' => array(
'message' => 'Checkout Session creation failed! ' . $api_error
)
);
}
}
// Return response
echo json_encode($response);
When I print $chosenService and $productName variables outside the "if (!empty($request->createCheckoutSession)) {...}" condition, I get the parameters, so they are not NULL. But inside the condition I do not get anything back, neither NULL (does this mean that the $request is empty?). I even checked the Logs in Stripe dashboard, this is the err message there:
"parameter_missing - line_items[0][price_data][product_data][name]
Looks like you are missing the name field tied to a given line item's product_data.
This field is required in that it contains the name that will show up on associated invoice line item descriptions."
I would be really grateful, if someone could help me with this. Thank you in advance.
I don't think your problem is the $productName. I tested out the code you provided and it looks like the issue has to do with the price value. You convert the $productPrice to $stripeAmount but then you don't use it. Without the conversion the amounts for either of the services are less than the $0.50 threshold (with the USD = HUF conversion).
As their docs point out, Stripe requires your charge amounts to be valued between $0.50 and $999,999.00
I don't think this impacted your attempt here but it might also be worth updating the way in which you are invoking/using the Stripe PHP library to conform to the current standard: https://github.com/stripe/stripe-php#getting-started
It will mean you can more easily use the code snippets displayed in the API docs

parsing data to javascript with laravel controller

I send data with this code to JS:
$user = User::where('id' , $this->selectedItem)->first();
$this->dispatchBrowserEvent('userModal', [
'name' => $user->name,
'signup' => jdate($user->created_at),
]);
‍‍jDate() Is a function to convert to Persian date
but in frontend for signup I will receive a empty value
and this is JS code to receive data :
window.addEventListener('userModal', event => {
console.log(event.detail);
});
I would suggest to simply use Carbon instead of jDate().
'signup' => \Carbon\Carbon::parse($user->created_at)->setTimezone('Asia/Tehran'),

Angular passing data to the back-end service using find method

I've tried checking the data and console logging it and the data exist , but when I check the request from the back-end it was not passed . Is this how we pass data to the back-end service in angular ? or I have issue with my code ? Thanks.
Code
checkExistingFeedbackRequest(formGroup: FormGroup, respondents: Identity[]): Observable<FeedbackRequest[]> {
let request = formGroup.value
const data = respondents
.map(respondent => cleanUpFeedbackRequestAssociations({
...request,
respondent,
respondentId: respondent.id
}) as FeedbackRequest);
console.log("data:" , data)
return from(this.service.find<FeedbackRequest>(data)
.pipe(
map((result) => result.data)
);
}

Ajax validation and SyntaxError: JSON Parse error: Unrecognized token '<' on Laravel

It's my first time with JQuery and Ajax validation in Laravel. I'm trying to validate a form using Laravel Request rules.
Seems the server validate the fields because it sends me back the errors when I don't fill up the requests ones but when I do it I get this error on the console SyntaxError: JSON Parse error: Unrecognized token '<'
That's the code I wrote:
TechnicianFormRequest
public function rules()
{
return [
'nome' => 'required',
'cognome' => 'required',
'ruolo_principale' => '',
'antincendio' => '',
'primosoccorso' => '',
'rischioelettrico' => '',
'lavoroinquota' => '',
//
];
TechnicianController (store method)
public function store(TechnicianFormRequest $request)
{
$validated = $request->validated();
$technician = Tecinfo::create($validated);
return redirect()->action('TechnicianController#index')->with('success', 'Tecnico aggiunto con successo!');
// return dd($request->all());
}
Ajax Code:
(can't paste js code, so I add a pic)
Ajax code image
Thank you to everyone who will help me
Valerio
You are parsing Json in your ajax but not returning json from your store method
As Per Laravel Documentation:
The json method will automatically set the Content-Type header to application/json, as well as convert the given array to JSON using the json_encode PHP function
Use below in your controller to return json
return response()->json([
'success' => 'Tecnico aggiunto con successo!',
]);

how to pass object from view to controller

I have an object $trial that fills up while in the view. I would like to pass it to route as POST to call a function using it's data. This is to create an event for fullcalendar. I'm pretty sure that I've been sitting on this so long, that I'm way overthinking it.
Wanted to do this with eventRender callback but couldn't figure out how to pass the data into it, tried simple $.post just to get method not allowed or unknown status in the console.
I have some dummy data at the moment.
The goal here is to create event through marked time range.
Controller function to add new record to database if I manage to pass data
public function addEvent(Request $request)
{
//dd($request);
$event = new Event;
$event->title = $request['title'];
$event->start_date = $request['start_date'];
$event->end_date = $request['end_date'];
$event->save();
\Session::flash('success','Event added successfully.');
return redirect('/events');
}
web.php (routing)
Route::get('/events', 'EventController#index');
Route::post('/events', 'EventController#addEvent');
and then there is the index function on which I work the most currently to modify the table (make it editable, etc).
public $trial = [];
//
public function index()
{
$events = [];
$data = Event::all();
if($data->count()) {
foreach ($data as $key => $value) {
$events[] = Calendar::event(
$value->title,
true,
new \DateTime($value->start_date),
new \DateTime($value->end_date.' +1 day'),
null,
// Add color and link on event
[
'color' => '#f05050',
'url' => '/events',
]
);
}
}
$calendar = Calendar::addEvents($events) //add an array with addEvents
//->addEvent($eloquentEvent, [ //set custom color fo this event
//'color' => '#800',
//])
->setOptions([ //set fullcalendar options
'firstDay' => 1,
'selectable' => true,
'unselectAuto' => false,
'selectOverlap' => false,
'editable' => true,
'businessHours' => [
'dow' => [ 1, 2, 3, 4, 5 ],
'start'=> '08:00',
'end' => '19:00',
]
])->setCallbacks([ //set fullcalendar callback options (will not be JSON encoded)
'eventClick' => 'function(event) {
console.log("You clicked on an event with a title of: " + event.title);
}',
'select' => 'function(start, end) {
console.log("Selection start: " + start.format() + " selection end: " + end.format());
$trial = {
title: "rent",
start_date: start.format(),
end_date: end.format()
};
console.log($trial);
}',
]);
any suggestions would be welcome.
EDIT: generally, pretty much the only way i know how to pass data to be used in functions in controller is submitting it through form
I don't use Angular specifically, but it's got many similarities with Vue. I use a platform-agnostic package called Axios which allows you to send requests to your server.
To backtrack a second, a form is basically a general way to send a post request. The url is specified in the form, and the values are the input fields.
With any package, you would do something similar:
specify the url
specify the request type (post, get, etc)
pass parameters (but not required)
With Axios, it would look something like:
axios.post('/mySite.com/something', { datum1: 'value', datum2: true })
.then(response => () {
this.someFunction(response.data);
});
This has some ES6 magic in it (arrow functions), but this is very similar to many requests. Like I said, the second parameter is optional, or you can even pass a data object.
Don't forget to also include the csrf token. This is easiest if you just add in as a meta tag in your page head (see the Laravel Docs), but you can also pass it in directly as a _csrf parameter.

Categories