updating 2 table column at the same time, laravel - laravel-5.4

I've been working on this for quite a while now, this problem is composed on eloquent relationships on Laravel 5.4, in this case, what I want to do is that, to accept verification of the user, and update its verif_level(column name from users) to level '2', now, the structure of the verification_accounts table consists of its id, and user_id, which is a foreign key from the users table. Now, everything works fine, but the id of the verif_level being updated on the users table is the same as the id of the verification_accounts table is 9 and its user_id is 9459, the data updated on the users table is also 9 which has the same value on the verification_accounts table. which supposed to be 9459's verif_level to be updated to level 2, here is the code for the controller:
public function updateVerification(Request $request)
{
$validator = \Validator::make($request->all(), [
'admin_feedback' => 'required',
]);
$verification = VerificationAccount::find($request->id)->load('user');
$user = User::find($request->id);
if ($validator->passes())
if($verification->verification_level == '1'){
$verification->status = 1;
$verification->proccessed_by = \Auth::user()->id;
$verification->admin_feedback = $request->admin_feedback;
$verification->save();
$user->verif_level = '2';
$user->save();
return response()->json(['success' => true,'message' => 'Verification successfully updated']);
}
else{
return response()->json(['success' => false,'message' => 'Verification already accepted']);
}
else{
return ['error' => $validator->errors()];
}
}
but when I do "$request->user_id", it returns an error of creating an array of empty object. and idea how to deal with this?

Related

Last inserted id Inside transaction with Lumen/Laravel

How can I get the last inserted id
I use the following code which works:
DB::insert("INSERT INTO members (name,email)values($name,$email)");
$lastID = DB::getPdo() -> lastInsertId();
But the following code doesn't give me the last inserted id.
DB::transaction(function () {
$result = DB::insert("INSERT INTO members (name,email)values($name,$email)");
$lastID = DB::getPdo() -> lastInsertId();
}, 5);
return $lastID;
Even when I use the variable($lastID) outside the transaction it still doesn't work.
What am I doing wrong here?
When using the query builder, Laravel has the function insertGetId which inserts the row and returns the newly created id.
$lastid = DB::table('members')->insertGetId(['name' => $name, 'email' => $email]);
Please see sample code below. Hope it helps.
public function testModel($data) {
$id = DB::transaction(function() use ($data) {
$record_id = DB::table('users')->insertGetId($data);
DB::update('update users set votes = 100 where name = ?', ['John']);
return $record_id;
});
return $id; // this will return the last inserted id which is the $record_id inside the DB::transaction
}
You can get it easily:
$last_id = DB::table('members')->insertGetId(['name => $name, 'email => $email]);
this worked for me
public function testModel($data) {
$last_id = DB::transaction(function() use ($data) {
Table::create($data);
return DB::getPdo()->lastInsertId();
});
return $last_id; // this will return the last inserted id
}
The trick should be quite simple if you use Model. Let's assume you've Member model. So when you try to insert record it returns the inserted record in response.
/** Insert record **/
$member = Member::create(['name' => $name, 'email' => $email])
/** your last inserted id will be in $member **/
$lastInsertedId = $member->id
Hope this works for you.

How to force data update on laravel validation custom unique

I'm new in laravel. I have a table with menu_id and title I tried to make this title field unique when have the same menu_id. I found the solution here
But I got problem when update it. Can anyone help please?
My code
Validator::extend('unique_custom', function ($attribute, $value, $parameters)
{
// Get the parameters passed to the rule
list($table, $field, $field2, $field2Value) = $parameters;
// Check the table and return true only if there are no entries matching
// both the first field name and the user input value as well as
// the second field name and the second field value
return \DB::table($table)->where($field, $value)->where($field2, $field2Value)->count() == 0;
});
public function updateSubmenu( Request $request) {
$this->validate( $request, [
'menu_id' => 'required',
'title' => 'required|unique_custom:posts,title,menu_id,'.$request->menu_id,
'order_by' => 'required|integer',
'description' => 'required'
],
[
'title.unique_custom' => 'This title already token'
]
);
}
Can you explain what problem have you got on update? Some exception?
Edit:
If you couldn't update record if title not changes, you need to add one condition to Validator:
Validator::extend('unique_custom', function ($attribute, $value, $parameters)
{
// Get the parameters passed to the rule
list($table, $field, $field2, $field2Value) = $parameters;
// If old value not changed, don't check its unique.
$current = \DB::table($table)->where('title')->first();
if( $current->{$field} == $value) {
return true;
}
return \DB::table($table)->where($field, $value)->where($field2, $field2Value)->count() == 0;
});

OctoberCMS: How to maintain a two-way friendship relation?

I'm extending the rainlab.user plugin to allow each user to have friends via a simple intermediate table with the following fields:
user_id
friend_id
status
I've extended the User model:
use RainLab\User\Models\User as FrontUser;
FrontUser::extend(function($model) {
$model->belongsToMany['friends']=[
'RainLab\User\Models\User',
'table' => 'meysam_social_friends',
'pivot' => ['status'],
'pivotModel' => 'Meysam\Social\Models\FriendsPivot',
'timestamps' => true,
'key' => 'user_id',
'otherKey' => 'friend_id'
];
$model->addDynamicMethod('isFriendWith', function (FrontUser $user) use ($model) {
$model->friends->contains($user->id);
});
$model->addDynamicMethod('addFriend', function (FrontUser $user) use ($model) {
$model->friends()->attach($user->id);
});
$model->addDynamicMethod('removeFriend', function (FrontUser $user) use ($model) {
$model->friends()->detach($user->id);
});
});
And also extended the Rainlab.User Controller to have Friends tab where all friends of a user are listed and can be added and removed:
use RainLab\User\Controllers\Users as UsersController;
UsersController::extend(function($controller) {
if(!isset($controller->implement['Backend.Behaviors.RelationController'])) {
$controller->implement[] = 'Backend.Behaviors.RelationController';
}
$controller->relationConfig = '$/meysam/social/controllers/user/config_relations.yaml';
});
UsersController::extendFormFields(function($form, $model, $context) {
if(!$model instanceof FrontUser or $context != 'preview'){
// friends tab should not be displayed in update and create contexts
return;
}
$form->addTabFields([
'friends' => [
'label' => '',
'tab' => 'Friends',
'type' => 'partial',
'path' => '$/meysam/social/controllers/user/_friends.htm',
]
]);
});
Now I need to maintain a two-way friendship relationship. i.e. whenever user_id and friend_id is added to the friends table, I want to automatically add friend_id and user_id to the table as well. To achieve this, I implemented afterSave and beforeSave in the FriendsPivot model:
class FriendsPivot extends Pivot
{
/*
* Validation
*/
public $rules = [
'status' => 'required'
];
public $belongsTo = [
'user' => ['RainLab\User\Models\User', 'key' => 'user_id'],
'friend' => ['RainLab\User\Models\User', 'key' => 'friend_id']
];
public function getStatusOptions()
{
return [
1 => 'Pending',
2 => 'Approved',
3 => 'Blocked',
];
}
public function afterSave()
{
Log::info('Saving pivot...');
if(!$this->friend->isFriendWith($this->user)) {
$this->friend->addFriend($this->user);
}
}
public function beforeDelete()
{
Log::info('Deleting pivot...');
if($this->friend->isFriendWith($this->user)) {
$this->friend->removeFriend($this->user);
}
}
}
The problem is that beforeDelete is never called. afterSave gets called but beforeDelete never gets called and therefor the inverse of the relationship is not deleted (user_id-friend_id gets removed from database but friend_id-user_id does not get deleted). Why is beforeDelete not called? Is there anything I'm doing wrong? Is there any better way to maintain a two-way friendship relation?
I found this post because I'm trying to do exactly the same thing as you. If you have solved this then I wonder if you would be willing to share your solution?
This sounds very odd at first, but maybe this is because of the special delete behavior of the Pivot model. It appears that it builds a raw query using the QueryBuilder and thus bypasses any regular Eloquent (October) events.
In my eyes, the best solution would be to trigger the delete event manually in the delete method, but I'm unsure if this has any side effects.
Maybe you could test that and prepare a PR on Github if it works.

NULL value is saving in database instead of user submitted info

I am new to laravel and I am facing following problem
My problem
Problem i m facing is that whenever I submit the form after filling firstname lastname and phone, then everything going well except one thing that in my MYSQL database data is save as firstname: NULL lastname:NULL And phone:NULL instead of saving the data which i had enter.
I have a angularjs form in which is there fields like firstname lastname and phone.on submit it goes to submitContact() in controller:
submit.js:
var addnew = angular.module('addnew',[]);
// create angular controller
addnew.controller('addContactController',
function($scope,$location,$window,$http) {
// function to submit the form after all validation has occurred
$scope.submitContact = function() {
$scope.addnew = {firstname:'', lastname:'',phone:''};
$scope.addnew.firstname=$scope.firstname;
$scope.addnew.lastname=$scope.lastname;
$scope.addnew.phone=$scope.phone;
$http.get("http://localhost:8000/index.php/user/addnew",{"firstname": $scope.firstname, "phone": $scope.phone, "lastname": $scope.lastname})
.then(function mysuccess(response) {
$scope.mycard = response.data;
$scope.statuscode = response.status;
$scope.statustext = response.statustext;
$window.alert(JSON.stringify(response));
console.log(response.data);
});
};
});
http://localhost:8000/index.php/user/addnew this links to my laravel through routes.
my route.php:
Route::get('/user/addnew', 'usercontroller#store');
my usercontroller.php
public function store(Request $request)
{
//contacts::create(Request::all());
$user = new contacts;// contacts is my table name and my database is defined in .env file
$user->firstname = Input::get('firstname');
$user->lastname = Input::get('lastname');
$user->phone = Input::get('phone');
$user->save();
//I Used print_r to see that weather my submitted data is coming in $user or not:
print_r($user);
echo "saved";
}
my contact.php:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class contacts extends Model
{
protected $fillable =['firstname','lastname','phone'];
}
?>
Now, My problem
when i print_r $user then i got the error as my array is NOT catching my submitted data
print_r ($user) output in console window:
[fillable:protected] => Array
(
[0] => firstname
[1] => lastname
[2] => phone
)
[connection:protected] =>
[table:protected] =>
[primaryKey:protected] => id
[keyType:protected] => int
[perPage:protected] => 15
[incrementing] => 1
[timestamps] => 1
[attributes:protected] => Array
(
[firstname] =>
[lastname] =>
[phone] =>
[updated_at] => 2016-10-07 03:46:34
[created_at] => 2016-10-07 03:46:34
[id] => 38
)
[original:protected] => Array
(
[firstname] =>
[lastname] =>
[phone] =>
[updated_at] => 2016-10-07 03:46:34
[created_at] => 2016-10-07 03:46:34
[id] => 38
)
I want to know where I m making mistake and how can I correct that mistake.
Thanking you in anticipation.
Try this:
$user = new Contact();
Instead of this:
$user = new contacts;
Also, change class name to class Contact extends Model and a filename to a Contact.php.
Alternatively, since you're using $fillable you can create new row:
Contact::create($request->all());
https://laravel.com/docs/5.3/eloquent#mass-assignment
I think you should use POST instead of GET.
$http.post("http://localhost:8000/index.php/user/addnew",{"firstname": $scope.firstname, "phone": $scope.phone, "lastname": $scope.lastname})
.then(function mysuccess(response) {
$scope.mycard = response.data;
$scope.statuscode = response.status;
$scope.statustext = response.statustext;
$window.alert(JSON.stringify(response));
console.log(response.data);
});
And
Route::post('/user/addnew', 'usercontroller#store');
And I noticed that you are posting to /index.php/user/addnew
And your route is '/user/addnew'
'/index.php/user/addnew' and '/user/addnew' are different.
try posting to localhost:8000/user/addnew instead
To explain:
/user/addnew always refer to host:port/user/addnew
While user/addnew will just concatenate it to your current url
for example if you're currently at: localhost:8000/users/1
Clicking a link to user/addnew will bring you to localhost:8000/users/1/user/addnew while a link to /user/addnew will bring you to localhost:8000/user/addnew
EDIT:
Is this redundant?
$scope.addnew.firstname=$scope.firstname;
$scope.addnew.lastname=$scope.lastname;
$scope.addnew.phone=$scope.phone;
What you were sending is this:
{"firstname": $scope.firstname, "phone": $scope.phone, "lastname": $scope.lastname}
I think you can send this instead:
$scope.addnew
and again, you should use POST, not GET.
did you already update your http request to post? did you update the url?
Actually, I achived this by using $request->input('firstname'); $request->input('firstname'); $request->input('firstname');, since, it was JSON thats why. Else, If I had been using Laravel blade file then I could have done it by above solutions.

QueryException - Integrity constraint violation: 1062 Duplicate entry when I hit the route 'logout'

I get the above error when I try and logout by hitting the route /logout. The table that is referenced in the screenshot is mdbids. It stores all of my IDs (strings, 16 characters in length).
When a user is created their MDBID (id) is stored in the mdbids table.
routes.php
<?php
Route::get('login', ['as' => 'login', 'uses' => 'SessionsController#create']);
Route::get('logout', ['as' => 'logout', 'uses' => 'SessionsController#destroy']);
SessionsController.php
<?php
use MDB\Forms\LoginForm;
class SessionsController extends \BaseController {
protected $loginForm;
function __construct(LoginForm $loginForm)
{
$this->loginForm = $loginForm;
}
public function create()
{
if(Auth::check()) return Redirect::to("/users");
return View::make('sessions.create');
}
public function store()
{
$this->loginForm->validate($input = Input::only('email','password'));
if (Auth::attempt($input)) {
Notification::success('You signed in successfully!');
return Redirect::intended('/');
}
Notification::error('The form contains some errors');
return Redirect::to('login')->withInput()->withFlashMessage("The form contains some errors");
}
public function destroy()
{
Auth::logout();
return Redirect::home();
}
}
The following is taken from my User.php (model) file. It isn't the whole file as it is fairly big, but this is the only part where IDs are mentioned.
User.php (model)
<?php
public function save(array $options = array())
{
$this->mdbid = $this->mdbid ?: str_random(16);
$this->key = $this->key ?: str_random(11);
Mdbid::create([
'mdbid' => $this->mdbid,
'table_number' => 7,
'table_name' => 'users',
'created_at' => Carbon::now(),
'updated_at' => Carbon::now()
]);
parent::save($options);
}
I don't know where to start to look. Any help is greatly appreciated.
Your issue is that the logout is actually causing save() to run, and therefor you are causing Mdbid::create to run with an already added key (presumably when you logged in, or somewhere else in your User model?).
Solution #1:
You could add a logout() function to the User model that you have. Something similar to
function logout()
{
$this->mdbid = null;
return Auth::logout()
}
This will stop two of the same keys being added to the logout function.
Solution #2
If what you are trying to accomplish is adding a row upon a successful login, then you should not be using the User::save() function, rather, you should be listening for the auth.login event.
Inside app/start/global.php, add the following code:
Event::listen('auth.login', function($user)
{
$user->mdbid = $user->mdbid ?: str_random(16);
$user->key = $user->key ?: str_random(11);
Mdbid::create([
'mdbid' => $user->mdbid,
'table_number' => 7,
'table_name' => 'users',
'created_at' => Carbon::now(),
'updated_at' => Carbon::now()
]);
});
This will ensure only one row gets added to Mdbid per successful login, instead of adding a new row (with the same id) each time the User model is updated.
Solution #3 (a.k.a. what was really wanted)
Each table has mdbid as a primary key. Each primary key needs to be added to the Mdbid table each time a new row is inserted.
The way that this should be done is with an Observer. The first part is adding a new Observer class that will be used for all of the models we want to add the mdbid into:
class MdbidObserver
{
/**
* Observe new rows being added into the database
*/
public function creating($model)
{
// note that $model could be any model
$model->mdbid = $model->mdbid ?: str_random(16);
$model->key = $model->key ?: str_random(11);
Mdbid::create([
'mdbid' => $model->mdbid,
'table_number' => 7,
'table_name' => 'users',
'created_at' => Carbon::now(),
'updated_at' => Carbon::now()
]);
}
}
The second part is adding the Observer to all the models that we want the mdbid added to (inside app/start/global.php):
User::observe(new MdbidObserver);
Artist::observe(new MdbidObserver);
Album::observe(new MdbidObserver);
To stop any issues with mdbid not actually being random already being used, you might want to add a loop just before $model->mdbid. Something similar to:
$isUnique = false;
while (!$isUnique)
{
$unqiueId = str_random(16);
$row = Mdbid::where('mdbid', $uniqueId);
if (is_object($row))
$isUnique = true;
}
$model->mdbid = $uniqueId;