validate and saving an array of objects laravel 6, vue, axios - php

vue function:
sendData() {
this.isLoading = true;
const postData = {
data: this.items,
};
var self = this;
axios.post(this.postUrl, postData).then(function (response) {
console.log(response.data);
self.isLoading = false;
});
this.items = [];
},
Laravel controller:
public function store(request $request)
{
foreach ($request->data as $data) {
$serie = [];
$serie = ['imei' => $data['serie']];
$imei = new Imei([
'imei' => $data['serie'],
'status_id' => 1,
'sucursal_id' => $data['sucursal'],
'equipo_id' => $data['equipo']
]);
$validator = Validator::make($serie, [
'imei' => 'unique:imeis,imei|digits:15',
]);
if ($validator->fails()) {
// Here I need to build the response of every imei with its validation error
} else {
$imei->save();
}
}
return >Here I want to return the errors back to vue
}
my vue app sends to laravel trough axios an array of objects that looks like this [{imei:xxxx,sucursal_id...},{imei:xxxx,sucursal_id...}] I need to validate imei is unique and save it, and if error return errors in the same way [{imei:xxxx,errorMsg: 'already exist in DB'}]. but I can't find the proper way to do it.

Basically you want to customize your errorbag right ? try this one out. Add this inside your fail condition. Let me know if it works.
$err = [{imei:xxxx,errorMsg: 'already exist in DB'}];
foreach ($validator->errors()->toArray() as $error) {
foreach($error as $sub_error) {
array_push($err, $sub_error);
}
}
return ['errors'=>$err];

Related

Addition of a new value to API response

Currently learning Laravel and any help is much appreciated!
My API controller has the following index function
public function index()
{
abort_if(Gate::denies('course_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$response=Course::all()->toArray();
$allData = [];
foreach (Course::all() as $ids=>$CMF) {
UNSET($response[$ids]['media']);
$data_sequence = DB::table('media_sequence')->where('data_id', $CMF["id"])->where('type','CMF')->first();
$data_id=$data_sequence->id;
$data_sequence = json_decode($data_sequence->data_sequence);
$data = [];
$data["id"] = $CMF["id"];
$data["title"] = $CMF["title"];
foreach ($data_sequence as $id => $dataSeq) {
if ($dataSeq->type == "Text") {
$response[$ids]['media'][]=["id"=>$data_id,"text"=> $dataSeq->name,"mime_type"=>"text"];
} elseif ($dataSeq->type == "file") {
foreach ($CMF["media"] as $file) {
if (str::slug($dataSeq->name) == str::slug($file["file_name"])) {
$file["thumb"] = $file->getUrl('video_thumb');
$response[$ids]['media'][]=$file;
}
}
}
}
$allData[] = $data;
}
return new CourseResource($response);
//Commented: return new CourseResource(Course::with(['category', 'assigned_teams', 'team'])->get());
}
Getting no result when trying to return 'assigned_teams' with $response
The API response still doesn't include 'assigned_teams'
I tried: return new CourseResource($response, 'assigned_teams');
It is not returning the assigned_items since it is not included in the $response array.
Change
$response=Course::all()->toArray();
To
$response=Course::with(['category', 'assigned_teams', 'team'])->get();
Read more: eager-loading-multiple-relationships
Btw, as #apokryfos mentioned, you should refactor your code using Eloquent Relationships and Eager Loading.
I assume that the assigned_teams are not handled in your CourseResource.
You need to extend your resource to respect this additional relation.
class CourseResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
// return teams if they have been loaded
'teams' => TeamsResource::collection($this->whenLoaded('assigned_teams')),
];
}
}
This is just exemplary, since you did not provided your code for CourceResource yet, you need to update it according to your needs.
Here is the link to the appropriate laravel documentation: https://laravel.com/docs/8.x/eloquent-resources#conditional-relationships

How to authenticate user without a DB in Laravel?

I created a new project in Laravel that consumes all data from an API. For private data like a user profile, I need an access token to get the data.
Once I have an access token, how do I set the token as Auth::id() in Laravel? Or perhaps I can store the user profile as Auth::user() so that I can use #auth in a frontend blade file?
class CustomAuthController extends Controller
{
public function index()
{
return view('login');
}
public function store(Request $request)
{
$request->validate([
'phone' => 'required|numeric'
]);
$data = [
'phone' => $request->phone
];
$codeSent = GeneralFunction::WebRequestPublicApi('first-login', $data, null, null, null, true);
if($codeSent->status == "success")
{
return redirect('verify');
} else {
$errors = new MessageBag();
$errors->add("phone", "Invalid phone number");
return view('login')->withErrors($errors);
}
}
public function showVerify()
{
return view('verify');
}
public function verify(Request $request)
{
try {
$request->validate([
'verify' => 'required|size:6'
]);
$data = [
'token_code' => $request->verify,
'source' => 'web'
];
$token = GeneralFunction::WebRequestPublicApi('verify-login', $data, null, null, null, true);
if($token->status === "success")
{
$userData = GeneralFunction::WebRequestPublicApi('membership', null, 'GET', null, null, true, $token->results->access_token);
if($userData->status !== "error")
{
$user = (array) $userData->results[0];
$request->session()->put('token', $token->results->access_token);
Auth::attempt($user, false, false);
return redirect('/');
}
} else {
$errors = new MessageBag();
$errors->add("verify", "Invalid Token");
return view('verify')->withErrors($errors);
}
} catch (Exception $e) {
$errors = new MessageBag();
$errors->add("verify", $e->getMessage());
return view('verify')->withErrors($errors);
}
}
}
I tried using Auth::attempt, Auth::login(), and the other method, but all of these required a user table. My project does not have a database.
You can do something like following.
In the controller
if($auth_ok)
{
session(['user' => ['key' => 'value', 'key2' => 'value2'] ]); // set session data
return view('frontend');
}
In the view
$user = session('user', false);
#if(!$user) // if not logged in
do something
#else // logged in successfully
Welcome my user
#endif
Hope this helps.
i guess the best thing you need to do is to use sqlite and once you got login from your api create a new user from it or find if there is existing already and Auth::login($newUser);

Vuejs display Laravel errors in flash component

In controller I have a method, where I validate request. I have and custom error, see please code:
public function createComment(Request $request) {
$request->validate(['body' => 'string|min:10', 'type' => 'integer']);
if($this->lastComment(Auth::user()->id)) {
return response()->json(['errors' => 'Please try after 24 hours..'], 422);
} else {
$comment = Comment::create($request->all());
return $comment;
}
}
In vue I have axios:
axios.post('/createReview', {
body: this.body,
user_id: this.user_id,
type: this.type,
}).then(response => {
this.$emit('created', response.data);
}).catch(error => {
this.isLoading = false;
this.flash(error.response.data, 'error');
});
How I can correctly send these errors on component flash? When I get error on component I get [Object object]. I use this flash package: https://www.npmjs.com/package/vue-flash-message
That component will only render one message at a time and you are passing it an object.
this.flash(error.response.data.errors, 'error');

How tu use recaptcha google with phalcon framework

I'm still trying to add a recaptcha to my website, I want try the recaptcha from Google but I can't use it properly. Checked or not, my email is still sent.
I tried to understand the code of How to validate Google reCaptcha v2 using phalcon/volt forms?.
But i don't understand where are my problems and more over how can you create an element like
$recaptcha = new Check('recaptcha');
My controller implementation :
<?php
/**
* ContactController
*
* Allows to contact the staff using a contact form
*/
class ContactController extends ControllerBase
{
public function initialize()
{
$this->tag->setTitle('Contact');
parent::initialize();
}
public function indexAction()
{
$this->view->form = new ContactForm;
}
/**
* Saves the contact information in the database
*/
public function sendAction()
{
if ($this->request->isPost() != true) {
return $this->forward('contact/index');
}
$form = new ContactForm;
$contact = new Contact();
// Validate the form
$data = $this->request->getPost();
if (!$form->isValid($data, $contact)) {
foreach ($form->getMessages() as $message) {
$this->flash->error($message);
}
return $this->forward('contact/index');
}
if ($contact->save() == false) {
foreach ($contact->getMessages() as $message) {
$this->flash->error($message);
}
return $this->forward('contact/index');
}
$this->flash->success('Merci, nous vous contacterons très rapidement');
return $this->forward('index/index');
}
}
In my view i added :
<div class="g-recaptcha" data-sitekey="mypublickey0123456789"></div>
{{ form.messages('recaptcha') }}
But my problem is after : i create a new validator for the recaptcha like in How to validate Google reCaptcha v2 using phalcon/volt forms? :
use \Phalcon\Validation\Validator;
use \Phalcon\Validation\ValidatorInterface;
use \Phalcon\Validation\Message;
class RecaptchaValidator extends Validator implements ValidatorInterface
{
public function validate(\Phalcon\Validation $validation, $attribute)
{
if (!$this->isValid($validation)) {
$message = $this->getOption('message');
if ($message) {
$validation->appendMessage(new Message($message, $attribute, 'Recaptcha'));
}
return false;
}
return true;
}
public function isValid($validation)
{
try {
$value = $validation->getValue('g-recaptcha-response');
$ip = $validation->request->getClientAddress();
$url = $config->'https://www.google.com/recaptcha/api/siteverify'
$data = ['secret' => $config->mysecretkey123456789
'response' => $value,
'remoteip' => $ip,
];
// Prepare POST request
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
],
];
// Make POST request and evaluate the response
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
return json_decode($result)->success;
}
catch (Exception $e) {
return null;
}
}
}
So i don't know if tjis code is correct anyway, i have a problem too after that : how to create an object "recaptcha" in my form add
$recaptcha = new ?????('recaptcha');
$recaptcha->addValidator(new RecaptchaValidator([
'message' => 'Please confirm that you are human'
]));
$this->add($recaptcha);
PS: I apologize because i'm a noob here and my mother tongue is not english, so if you don't understand me or want give me some advices to create a proper question, don't hesitate ^^
I've made a custom form element for recaptcha. Used it for many projects so far.
The form element class:
class Recaptcha extends \Phalcon\Forms\Element
{
public function render($attributes = null)
{
$html = '<script src="https://www.google.com/recaptcha/api.js?hl=en"></script>';
$html.= '<div class="g-recaptcha" data-sitekey="YOUR_PUBLIC_KEY"></div>';
return $html;
}
}
The recaptcha validator class:
use Phalcon\Validation\Validator;
use Phalcon\Validation\ValidatorInterface;
use Phalcon\Validation\Message;
class RecaptchaValidator extends Validator implements ValidatorInterface
{
public function validate(\Phalcon\Validation $validation, $attribute)
{
$value = $validation->getValue('g-recaptcha-response');
$ip = $validation->request->getClientAddress();
if (!$this->verify($value, $ip)) {
$validation->appendMessage(new Message($this->getOption('message'), $attribute, 'Recaptcha'));
return false;
}
return true;
}
protected function verify($value, $ip)
{
$params = [
'secret' => 'YOUR_PRIVATE_KEY',
'response' => $value,
'remoteip' => $ip
];
$response = json_decode(file_get_contents('https://www.google.com/recaptcha/api/siteverify?' . http_build_query($params)));
return (bool)$response->success;
}
}
Using in your form class:
$recaptcha = new Recaptcha($name);
$recaptcha->addValidator(new RecaptchaValidator([
'message' => 'YOUR_RECAPTCHA_ERROR_MESSAGE'
]));
Note 1: You were almost there, you just missed to create custom form element (the first and last code piece from my example);
Note 2: Also there is a library in Github: https://github.com/fizzka/phalcon-recaptcha I have not used it, but few peeps at phalcon forum recommended it.

Inserting a JSON array from Laravel

I'm wondering how I can loop insert an array value to database through Laravel.
A sample of a Json is here:
[{"rid":"252","recipient_id":"1","email_type":"Body","to_cc_bcc":"to","start_dte":"2016-05-18","end_dte":""},{"rid":"252","recipient_id":"5","email_type":"Body","to_cc_bcc":"to","start_dte":"2016-05-18","end_dte":""}]
And my controller for storing such is this:
public function store()
{
// validate
// read more on validation at http://laravel.com/docs/validation
$rules = array(
'name' => 'required',
);
$validator = Validator::make(Input::all(), $rules);
// process the login
if ($validator->fails()) {
return Redirect::to('reports')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
//Dump Recipient array
$cleanRecipients = json_decode(Input::get('test'), true);
foreach($cleanRecipients AS $value)
{
$report_recipient = new ReportRecipients;
$report_recipient->recipient_id = $value['recipient_id'];
$report_recipient->rid = $value['rid'];
$report_recipient->email_type = $value['email_type'];
$report_recipient->to_cc_bcc = $value['to_cc_bcc'];
$report_recipient->start_dte = !empty($value['start_dte']) ? $value['start_dte'] : null;
$report_recipient->end_dte = !empty($value['end_dte']) ? $value['end_dte'] : null;
}
$report_recipient->save();
// redirect
Session::flash('message', 'Report was Successfully Saved!');
return Redirect::to('reports');
What happens is that, it only stores the last set of values into the table and not all of them. I appreciate any help and thanks in advance.
Put your save() inside your loop. Also, you should do it in one transaction, to be atomic.
\DB::transaction(function() use($cleanRecipients) {
foreach($cleanRecipients AS $value) {
$report_recipient = new ReportRecipients;
$report_recipient->recipient_id = $value['recipient_id'];
$report_recipient->rid = $value['rid'];
$report_recipient->email_type = $value['email_type'];
$report_recipient->to_cc_bcc = $value['to_cc_bcc'];
$report_recipient->start_dte = !empty($value['start_dte']) ? $value['start_dte'] : null;
$report_recipient->end_dte = !empty($value['end_dte']) ? $value['end_dte'] : null;
$report_recipient->save();
});
You need to put $report_recipient->save(); inside your foreach loop.

Categories