Saving bulk data in a query - laravel - php

I have a input field for entering numbers into a database. Now, a unique token is created for each number that is entered.
Now currently with my code below, when i enter +144223202320,+4403224202340, it is saved into the database but both numbers are saved in the same column like
phone token
+144223202320,+4403224202340 dfsfsfsdfsdfdsfs
But this is what i want
phone token
+144223202320 1111112323242343
+4403224202340 dfsfsfsdfsdfdsfs
Controller
public function send( Request $request)
{
do {
//generate a random string using Laravel's str_random helper
$token = str_random();
}
while (Invite::where('token', $token)->first());
$invite = Invite::create([
'phone' => $request->get('phone'),
'token' => $token
]);
return redirect()->back()->with('status','Message successfully sent');
}
How can i get this done please?

Explode the phone number and write a record in the database for each phone you get
public function send( Request $request)
{
foreach(explode(",", $request->get('phone')) as $phone){
do {
//generate a random string using Laravel's str_random helper
$token = str_random();
}while (Invite::where('token', $token)->first());
$invite = Invite::create([
'phone' => $phone,
'token' => $token
]);
}
return redirect()->back()->with('status','Message successfully sent');
}
Update
Seems like in a for loop the object is not being recreated. Use this approach instead
public function send( Request $request)
{
foreach(explode(",", $request->get('phone')) as $phone){
do {
//generate a random string using Laravel's str_random helper
$token = str_random();
}while (Invite::where('token', $token)->first());
$invite = new Invite;
$invite->phone = $phone;
$invite->token = $token;
$invite->save();
}
return redirect()->back()->with('status','Message successfully sent');
}

You can try this approach with recursive check of tokens.
P.S. You might need to make few adjustments to work 100% on your code.
public function send(Request $request){
$phones = explode("," $request->phone);
foreach($phones as $phone){
$token = $this->generateUniqueInviteToken();
if($token){
$invite = new Invite();
$invite->phone = $phone;
$invite->token = $token;
if($invite->save()){
return redirect()->back()->with('status', 'Message successfully sent');
}
return redirect()->back()->with('status', 'FAILED');
}
}
}
public function generateUniqueInviteToken(){
$token = str_random();
$checkedInvite = Invite::where("token", $token)->first();
if(!$checkedInvite){
return $token;
}else{
$this->generateUniqueInviteToken();
}
}

Related

How to Generate unique usernames using Laravel

I am trying to generate unique usernames for users upon registration using laravel. I want to include both the first name and the last name. If I use only the first or last name it works, but if I try both, it enters a blank value to the database. Please Help.
Here is my code:
Auth Controller
`
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'firstname'=>'required|max:191',
'lastname'=>'required|max:191',
'phone'=>'required',
'email'=>'required|email|max:191|unique:users,email',
'password'=>'required|min:6',
]);
if($validator->fails())
{
return response()->json([
'validation_errors'=>$validator->messages(),
]);
}
else
{
$userObject = New User;
$userName = $userObject->generateUserName($request['firstname'.'lastname']);
$user = User::create([
'firstname'=>$request->firstname,
'lastname'=>$request->lastname,
'phone'=>$request->phone,
'email'=>$request->email,
'password'=>Hash::make($request->password),
'username'=>$userName,
]);
$token = $user->createToken($user->phone.'_Token')->plainTextToken;
return response()->json([
'status'=>200,
'username'=>$user->firstname,
'token'=>$token,
'message'=>'Registered Successfully',
]);
}
}
`
The User Model
`
public function generateUserName($firstname){
$username = Str::lower(Str::slug($firstname));
if(User::where('username', '=', $username)->exists()){
$uniqueUserName = $username.'-'.Str::lower(Str::random(5));
$username = $this->generateUserName($uniqueUserName);
}
return $username;
}
`
your issue generate from $request['firstname'.'lastname'], you are actually Concating keys of a request array though you want to Concat the value of 2 separate keys which means to use it like this $request['firstname'] and $request['lastname']. please change the below line
$userName = $userObject->generateUserName($request['firstname'.'lastname']);
with this
$userName = $userObject->generateUserName($request['firstname'].$request['lastname']);

i wanna check if client name doesn't repeat but doesn't work

public function insertclients(Request $request)
{
$client = new Clients();
$client->client_name = $request->input('client_name');
$client->client_society = $request->input('client_society');
$client->client_email = $request->input('client_email');
$client->client_address = $request->input('client_address');
$client->client_phone = $request->input('client_phone');
$client->client_fix = $request->input('client_fix');
if ($this->nameclient($request->input('client_name')) < 1) {
$client->save();
return response()->json($client);
} else {
return response()->json('error', 'Client name already exists'); }
// return redirect('clients')->with('flash_message', 'Client Addedd!');
}
public function nameclient(Request $request)
{
//check count of client name
$count = Clients::where('client_name', $request->input('client_name'))->get();
$clicount = $count->count();
return $clicount;
}
I have this method for add new client but i wanna check if the name don't repeat so i create other function who check the name of client and i call it in the ferst but doesn't work.
You are already sending the input with $this->nameclient($request->input('client_name')
so change your method to accept a string variable
public function nameclient($clientName)
{
return Clients::where('client_name', $clientName)->count();
}
Bonus:
Maybe this way it would be more readable
public function insertclients(Request $request)
{
if ($this->nameclient($request->input('client_name')) {
return response()->json('error', 'Client name already exists');
}
$client = new Clients();
$client->client_name = $request->input('client_name');
$client->client_society = $request->input('client_society');
$client->client_email = $request->input('client_email');
$client->client_address = $request->input('client_address');
$client->client_phone = $request->input('client_phone');
$client->client_fix = $request->input('client_fix');
$client->save();
return response()->json($client);
// return redirect('clients')->with('flash_message', 'Client Addedd!');
}
You can also use laravel Validation instead of using the method nameclient and add the other validation rules in it like required fields and such.
public function insertclients(Request $request)
{
$request->validate([
'client_name' => 'required|unique:clients|max:255',
]);
$client = new Clients();
$client->client_name = $request->input('client_name');
$client->client_society = $request->input('client_society');
$client->client_email = $request->input('client_email');
$client->client_address = $request->input('client_address');
$client->client_phone = $request->input('client_phone');
$client->client_fix = $request->input('client_fix');
$client->save();
return response()->json($client);
// return redirect('clients')->with('flash_message', 'Client Addedd!');
}

How to pass calculated/final value of one function to other functions in a controller of Codeigniter application

Using sessions we can achieve this, but need this without sessions or cookies.
<?php
class Employees extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
public function auth() {
$adminEmail = $this->input->post('adminEmail');
$adminPassword = $this->input->post('adminPassword');
if ($adminEmail != "" && $adminPassword != "") {
$query = $this->db->query("select * from admin_tbl where email= '$adminEmail' and password = '$adminPassword'");
//if user exist
if ($query->num_rows() <= 0) {
$response = array();
$jwtoken = "";
$this->session->set_flashdata("invalid", "Wrong email or password");
$response = array(
'status' => 'invalid',
'message' => $_SESSION['invalid'],
'token' => $jwtoken,
);
//used to send finalized values
$this->output
->set_content_type('application/json')
->set_output(json_encode($response));
return $jwtoken; //return value
} else {
// $this->session->set_userdata('adminEmail', $adminEmail);
$response = array();
$jwt = new JWT();
$data = array(
'adminEmail' => $adminEmail,
'iat' => time()
);
$jwtoken = $jwt->encode($data, jwtSecretKey, 'HS256');
// I want to pass $jwtoken's variable to all the functions in a controller
$this->session->set_flashdata("login", "Scucessfully login!");
// if (isset($_SESSION['adminEmail'])) {
if ($jwtoken != "") {
$response = array(
'status' => 'valid',
'message' => $_SESSION['login'],
'token' => $jwtoken
);
}
$abc = $jwtoken;
//used to send finalized values
$this->output
->set_content_type('application/json')
->set_output(json_encode($response));
return $jwtoken; //return value
}
}
}
public function addNew()
{
$response = array();
$this->auth(); // this value is always null returned by auth() method
}
}
?>
This is more of a OOP programming basics question. If you want to re-use a variable in another function of the same controller object, you have to set the variable globally for the Employees class and then set/get its value in your functions by using $this->yourVariableName. But the set value of the object instance can only be reused in that instance only. Which means that after the auth() function, another function should be called subsequently to "access" the $this->yourVariableName.
Another way is to pass the $jwtoken as a parameter to a function.
But the following code answers your question "How to pass calculated/final value of one function to other functions in a controller of Codeigniter application", if it doesn't, then your question should be corrected I guess.
Edit:
Ow ok, first the auth() function is being called, then you would like to pass the $jwtoken value to another function, am I right? Well once a function is finished executing, the variable "disappears" if not passed to another function. If you would like to process the $jwtoken value immediately within the auth() function, then the answer is to pass the $jwtoken value to another function from within the auth() function:
<?php
class Employees extends CI_Controller
{
public function __construct() {
parent::__construct();
}
public function auth() {
$adminEmail = $this->input->post('adminEmail');
$adminPassword = $this->input->post('adminPassword');
if ($adminEmail != "" && $adminPassword != "") {
$query = $this->db->query("select * from admin_tbl where email= '$adminEmail' and password = '$adminPassword'");
//if user exist
if ($query->num_rows() <= 0) {
$response = array();
$jwtoken = "";
$this->session->set_flashdata("invalid", "Wrong email or password");
$response = array(
'status' => 'invalid',
'message' => $_SESSION['invalid'],
'token' => $jwtoken,
);
//used to send finalized values
$this->output
->set_content_type('application/json')
->set_output(json_encode($response));
return $jwtoken; //return value
} else {
// $this->session->set_userdata('adminEmail', $adminEmail);
$response = array();
$jwt = new JWT();
$data = array(
'adminEmail' => $adminEmail,
'iat' => time()
);
$jwtoken = $jwt->encode($data, jwtSecretKey, 'HS256');
// I want to pass $jwtoken's variable to all the functions in a controller
// this is one way you can pass the value to another function, depending on what you want to do, you can also place a condition and continue only if the return value of the following function is respected:
$this->addNew($jwtoken);
// What is the addNew() supposed to do?
$this->session->set_flashdata("login", "Scucessfully login!");
// if (isset($_SESSION['adminEmail'])) {
if ($jwtoken != "") {
$response = array(
'status' => 'valid',
'message' => $_SESSION['login'],
'token' => $jwtoken
);
}
$abc = $jwtoken;
//used to send finalized values
$this->output
->set_content_type('application/json')
->set_output(json_encode($response));
return $jwtoken; //return value
}
}
}
public function addNew($jwtoken = "default_value_if_not_set") {
echo $jwtoken;
}
}
Since you are creating an API, I assume the API is a REST api and stateless, so there is no interference of sessions and cookies.
I assume your process works like this:
User does a login request from the app to the api and the api returns a token when the credentials check is valid
The token is stored in the app (in a local database for example) and used for other requests
So the only thing you need to do is (I assume you have a route to addNew):
public function addNew() {
$token = $this->input->get('token');
$loginData = $this->validateToken($token);
//... add new process
}
And from your app you need to pass the token with the request to the api.
How do you validate the token?
To obtain the data you have set in the token, you have to decode the token:
/**
* throws SignatureInvalidException
*/
function validateToken($token)
{
$jwt = new JWT();
return $jwt->decode($token, jwtSecretKey, 'HS256');
}
Code improvement
Avoid using sessions and cookies
Since your api is stateless, you have to avoid settings cookies or sessions. So in your controller you can remove the flash data helper:
public function auth() {
$adminEmail = $this->input->post('adminEmail');
$adminPassword = $this->input->post('adminPassword');
if ($adminEmail != "" && $adminPassword != "") {
$query = $this->db->query("select * from admin_tbl where email= '$adminEmail' and password = '$adminPassword'");
//if user exist
if ($query->num_rows() <= 0) {
$response = array();
$jwtoken = "";
# REMOVE THIS LINE
# $this->session->set_flashdata("invalid", "Wrong email or password");
$response = array(
'status' => 'invalid',
'message' => "Wrong email or password", //CHANGE THIS LINE
'token' => $jwtoken,
);
//used to send finalized values
$this->output
->set_content_type('application/json')
->set_output(json_encode($response));
return $jwtoken; //return value
} else {
// $this->session->set_userdata('adminEmail', $adminEmail);
$response = array();
$jwt = new JWT();
$data = array(
'adminEmail' => $adminEmail,
'iat' => time()
);
$jwtoken = $jwt->encode($data, jwtSecretKey, 'HS256');
// I want to pass $jwtoken's variable to all the functions in a controller
# REMOVE THIS LINE
# $this->session->set_flashdata("login", "Scucessfully login!");
// if (isset($_SESSION['adminEmail'])) {
if ($jwtoken != "") {
$response = array(
'status' => 'valid',
'message' => "Scucessfully login!", //CHANGE THIS LINE
'token' => $jwtoken
);
}
$abc = $jwtoken;
//used to send finalized values
$this->output
->set_content_type('application/json')
->set_output(json_encode($response));
return $jwtoken; //return value
}
}
}
Return the output response instead of $jwtoken
In your response you have already set the the token, so you can simply return the response:
return $this->output
->set_content_type('application/json')
->set_output(json_encode($response));
Your query is vulnerable to sql injections
Use escape method around you variables or bind the params:
$sql = "select * from admin_tbl where email=? and password = ?";
$query = $this->db->query($sql, array($adminEmail, $adminPassword));

Laravel save multi part form

I have a 3 part form that I want to be able to update the database after each submit. There is one table that holds all the fields below.
form1 asks for first and last name
form2 asks for email and phone
form3 asks for city and state
In my controller I have 3 separate functions to save each step of the form:
public function name(Request $request){
$lead = Lead::firstOrNew(123);
$lead->firstName = $request->get('firstName ');
$lead->lastName = $request->get('lastName');
$lead->save();
return redirect('/form2');
}
public function info(Request $request){
$lead = Lead::find(123);
$lead->email = $request->get('email');
$lead->phone = $request->get('phone');
$lead->save();
return redirect('/form3');
}
public function address(Request $request){
$lead = Lead::find(123);
$lead->city = $request->get('city');
$lead->state = $request->get('state');
$lead->save();
return redirect('/done');
}
Is there any way to combine that to one update function?
Just do conditional check, update the model and define redirect url:
public function info(Request $request) {
$lead = Lead::firstOrNew(123);
if ($request->has('firstName') && $request->has('lastName')) {
$lead->firstName = $request->get('firstName ');
$lead->lastName = $request->get('lastName');
$redirect = '/form2';
} else if ($request->has('email') && $request->has('phone')) {
$lead->email = $request->get('email');
$lead->phone = $request->get('lastName');
$redirect = '/form3';
} else if ($request->has('city') && $request->has('state')) {
$lead->city = $request->get('city');
$lead->state = $request->get('state');
$redirect = '/done';
}
$lead->save();
return redirect($redirect);
}
Also, you can probably do group update via update just make sure you whitelist the attributes in your model
public function info(Request $request) {
$lead = Lead::firstOrNew(123);
$lead->update($request->all());
if ($request->has('firstName') && $request->has('lastName')) {
$redirect = '/form2';
} else if ($request->has('email') && $request->has('phone')) {
$redirect = '/form3';
} else if ($request->has('city') && $request->has('state')) {
$redirect = '/done';
}
return redirect($redirect);
}
Or I'd better just add a redirect variable to your form like:
<input type="hidden" name="redirect" value="form1">
and simplify your controller method like:
public function info(Request $request) {
$lead = Lead::firstOrNew(123);
$lead->update($request->all());
return redirect($request->input('redirect'));
}
You could refactor the methods to call a common "update" function. See example code below.
public function name(Request $request){
$this->update(123, $request);
return redirect('/form2');
}
public function info(Request $request){
$this->update(123, $request);
return redirect('/form3');
}
public function address(Request $request){
$this->update(123, $request);
return redirect('/done');
}
private function update($id, $request) {
$lead = Lead::find($id);
foreach ($field as ['firstName', 'lastName', ...]) {
if ($request->has($field)) {
$lead->{$field} = $request->get($field);
}
}
$lead->save();
}
You can add a hidden field to all three forms (but with the name name, e.g form_name), and set their values to identify the form (form1, form2, form3) when it is submitted. Then in your controller, you check the value of the form_name field on the request to determine where you want to redirect to, like this:
public function info(Request $request) {
$lead = Lead::firstOrNew(123);
$lead->update($request->all());
//this will be from the hidden field (form_name)
$form_type = $request->get('form_name');
if ($form_type == 'form1') {
$redirect = '/form2';
} else if ($form_type == 'form2') {
$redirect = '/form3';
} else if ($form_type == 'form3') {
$redirect = '/done';
}
return redirect($redirect);
}
If you have the option for using javaScript then save the first and second form data on cookies or local storage and when the user reaches last part of the form then take data out of cookies or local storage then added with the last form, but keep these in the hidden input.
Given that HTTP requests are stateless (which means each request know nothing about the one before and after it), I would rather prefer you use sessions, so that you can be able to store information as you redirect from one form to the other. In that case, your code should look like so:
<?php
public function name(Request $request){
Session::put('nameData', $request->all()); //Store the info from form1 in session and redirect to form2
return redirect('/form2');
}
public function info(Request $request){
$validSessionData = Session::has('nameData');
if (!$validSessionData) { //Check if the user filled form1, if not, go back to form1
return redirect('/form1');
}
$nameAndInfo = Session::pull('nameData', []) + $request->all(); //Merge the info from form1 with info from form2. You could decide to keep them separate and merge later.
Session::put('nameAndInfo', $nameAndInfo);
return redirect('/form3');
}
public function address(Request $request){
$validSessionData = Session::has('nameAndInfo');
if (!$validSessionData) { Another check. You could also extend this by checking for form2 session data
return redirect('/form1');
}
$allData = Session::pull('nameAndInfo', []) + $request->all(); //Merge all session data
$lead = Lead::firstOrNew(123);
$lead->firstName = $allData['firstName'];
$lead->lastName = $allData['lastName'];
$lead->email = $allData['email'];
$lead->phone = $allData['phone'];
$lead->city = $allData['city'];
$lead->state = $allData['state'];
$lead->save();
return redirect('/done');
}

php global variable is null

I have a protected $headers variable in my class assigning a value using the function
public function actionLogIn()
{
$userCode = Input::get('username');
$password = Input::get('password');
$loginData = array(
'code' => $userCode,
'passkey' => $password
);
$loginData = json_encode($loginData);
$this->headers = Auth::login($loginData);//Modified login method
if(! is_null($this->headers))
{
return View::make('forms.welcome')->with('title', 'Welcome');
}else{
echo "Invalid access!";
}
}
and when I use print_r($this->headers); it successfully prints out the value I need,
but when I tried to access $this->headers using the function:
public function actionLogOut()
{
if(is_null($this->headers)){
echo "is null", "\n";
}//for checking only
Auth::logout($this->headers);
}
$this->headers is null. What could be the problem ? also $headers is actually an array. Thanks!
A new controller instance is created for every request. That means that even though you store information in $this, it's not there when the user requests a new page.
What you want to do is store data in something that doesn't change between requests - either in the session or in cookies.
In the session, it would look like this: (warning - untested code)
public function actionLogIn() {
...
$loginData = json_encode($loginData);
$user = Auth::login($loginData);
if ($user) {
Session::put('logged_in_user',$user);
return View::make('forms.welcome')->with('title', 'Welcome');
}else{
echo "Invalid access!";
}
}
public function actionLogOut() {
if(Session::has('logged_in_user'){
$user = Session::get('logged_in_user');
Auth::logout($user);
Session::forget('logged_in_user');
} else {
echo "is null\n";
}
}
Take a look at http://four.laravel.com/docs/session for more information on Sessions in Laravel.

Categories