I have done my coding but the laravel audit seems not catch the data for update.
The data i try to update is on the column of value, but on the database the value are not be catch on audit table for auditing the update changes .
below is the coding for update the data.
academicsetting.php:
class AcademicSetting extends Model implements Auditable
{
use SoftDeletes, ActiveScope;
use \OwenIt\Auditing\Auditable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $dates = ['deleted_at'];
protected $fillable = [
'id',
'type',
'field',
'name',
'value',
'description',
'is_active',
'created_by',
'created_at',
'updated_by',
'updated_at',
'deleted_by',
'deleted_at',
];
protected $casts = [
'value' => 'json',
];
public function transformAudit(array $data): array
{
dump($data);exit();
if ($data['event'] == 'created') {
$data['new_values']['created_by'] = Staff::where('id', $this->getAttribute('created_by'))->value('name');
$data['new_values']['updated_by'] = Staff::where('id', $this->getAttribute('updated_by'))->value('name');
}
if ($data['event'] == 'deleted') {
$data['old_values']['deleted_by'] = Staff::where('id', $this->getOriginal('deleted_by'))->value('name');
$data['new_values']['deleted_by'] = Staff::where('id', $this->getAttribute('deleted_by'))->value('name');
}
if ($data['event'] == 'updated') {
$data['old_values']['updated_by'] = Staff::where('id', $this->getOriginal('updated_by'))->value('name');
$data['new_values']['updated_by'] = Staff::where('id', $this->getAttribute('updated_by'))->value('name');
}
return $data;
}
}
academicgeneralcontroller.php:
public function update(Request $request, $id)
{
/** implode multi dropdown value */
$request['final_attendance_reset_mark'] = $request->input('final_attendance_reset_mark');
/** end */
$this->general->update($request->except('_token', 'academicsetting-table_length', '_method'), $id);
Session::flash('alert-success', msg('msg_success_update'));
return redirect()->route('academic_general.index');
}
generalrepository.php:
class GeneralRepository extends Repository
{
/**
* Specify Model class name
*
* #return mixed
*/
public function model()
{
return AcademicSetting::class;
}
public function update(array $data, $id, $attribute = 'id')
{
// dump($data);exit();
foreach ($data as $key => $value) {
if ($key == 'final_attendance_reset_mark') {
$array = [];
if (!empty($value)) {
foreach ($value as $key_value => $value) {
$array[(int) $key_value] = (int) $value;
}
}
$json = json_encode($array, JSON_FORCE_OBJECT);
// dump($json);
$update_value = [
'value' => $json,
];
} else {
$update_value = ['value' => $value];
}
dump($update_value);exit();
$general = AcademicSetting::where('field', $key)->update($update_value);
}
}
}
Not sure if this will help but,
i see you have the following in the transform method:
$data['new_values']['created_by'] = Staff::where('id', $this->getAttribute('created_by'))->value('name');
in the documentation i see the following:
$data['old_values']['role_name'] = Role::find($this->getOriginal('role_id'))->name;
the above is to record the audit by transforming the role_id to the role_name, enabling you to capture the role_name as well.
https://laravel-auditing.herokuapp.com/docs/4.1/audit-transformation
Related
I'm trying to save new user with Ajax request in Laravel and i'm getting the following error,
Object of class App\User could not be converted to int
I must add the the user is saved, so i'm not sure from where this error comes.
Here is the UserController:
public function save_user(Request $request)
{
try {
if (request()->ajax()) {
$lastUserId = User::where('user_id', '>', 0)->orderBy('user_id', 'desc')->get('user_id')->first()->toArray();
$user = new User;
$data = Input::all();
$user->user_id = intval($lastUserId['user_id'] + 1);
$user->user_type = $data['user_type'];
$user->email = $data['email'];
$user->password = 'e10adc3949ba59abbe56e057f20f883e';
$user->first_name = $data['first_name'];
$user->last_name = $data['last_name'];
$user->save();
if ($user > 0) {
return response()->json('Success');
}
return response()->json(['status' => 200, 'message' => 'save success']);
}
} catch (\Exception $e) {
echo $e->getMessage();
}
Here is the Ajax request:
$('#saveUser').on('click', function (e) {
e.preventDefault();
var $inputs = $('#new-user-form :input');
var values = {};
$inputs.each(function () {
if (this.name != '_token' && this.name.length > 0) {
values[this.name] = $(this).val();
}
});
$.ajax({
url: '/api/save_user',
type: "post",
data: values,
dataType: 'JSON',
success: function (data) {
/// location.reload();
}
});
})
Here is the User Model
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Detail;
class User extends Authenticatable
{
public function users(){
return $this->hasMany('\App\User'); //Product Model Name
}
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
I've tried to convert all the input values to their type - like in the DB but it didn't worked
In your condition, you are trying to see if a collection of user is > 0, and because of that, you're getting the error above, since Laravel is trying to parse the collection of user to int datatype, to make it countable. Refactor your condition to this:
if (count($user) > 0) {
return response()->json('Success');
}
or another way:
if ($user) {
return response()->json('Success');
}
Try to change this in your controller
if ($user > 0) {
return response()->json('Success');
}
To this
if ($user) {
return response()->json('Success');
}
I have this issue from several days in Scrutinizer CI.
I would get ride of it, but don't know how to do. This is the migration script:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('username')->unique();
$table->string('password');
$table->rememberToken();
$table->datetime('last_change_password')->nullable();
$table->timestamps();
});
}
And this is my App\User
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Validator;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'username', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* #param int $id the id of the user
* #param array $data
*
* #return mixed
*/
public function changePassword(int $id, array $data)
{
$rules = [
'username' => 'sometimes|required|string|min:8|unique:users,username,'.$id,
'new_password' => 'required|string|confirmed|min:8'
];
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
return $validator->errors()->all();
} else {
$object = $this->find($id);
if (is_object($object)) {
if (isset($data[ 'username' ])) {
$object->username = $data[ 'username' ];
}
$object->password = bcrypt($data[ 'new_password' ]);
$object->last_change_password = \Carbon\Carbon::now();
$status = $object->save();
} else {
$status = false;
}
return $status;
}
}
/**
*
* #param array $data the data to update
* #return bool
*/
public function updateRecord(array $data)
{
$rules = [
'username' => 'sometimes|required|string|min:8|unique:users,username,'.$data[ 'id' ],
'password' => 'required|string|min:8'
];
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
return $validator->errors()->all();
} else {
$id = $data[ 'id' ];
$object = $this->find($id);
if (is_object($object)) {
foreach ($data as $key => $value) {
if (in_array($key, $this->fillable)) {
$object->$key = $value;
}
}
$status = $object->save();
} else {
$status = false;
}
return $status;
}
}
}
This is the error I am getting the at moment:
Type error: Argument 1 passed to Illuminate\Database\Eloquent\Relations\BelongsToMany::save()
must be an instance of Illuminate\Database\Eloquent\Model,
integer given,
called in /home/sasha/Documents/OffProjects/vetnearme/vetnearme/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php on line 814
The create user method, where I call the giveRole() method:
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
// On registration user will be given the default role of user
$user->giveRole();
$verifyUser = VerifyUser::create([
'user_id' => $user->id,
'token' => str_random(40)
]);
Mail::to($user->email)->send(new VerifyMail($user));
return $user;
}
HasPermissionsTrait:
<?php
namespace App\App\Permissions;
use App\{Role, Permission};
/**
*
*/
trait HasPermissionsTrait
{
public function giveRole($role = 'user')
{
$role = \DB::table('roles')->where('name', '=', $role)->first();
$this->roles()->saveMany([$role->id]);
return $this;
}
public function givePermission(...$permissions)
{
$permissions = $this->getPermissions(\array_flatten($permissions));
if($permissions === null)
return $this;
$this->permissions()->saveMany($permissions);
return $this;
}
public function widrawPermission(...$permissions)
{
$permissions = $this->getPermissions(\array_flatten($permissions));
$this->permissions()->detach($permissions);
return $this;
}
public function updatePermissions(...$permissions)
{
$this->permissions()->detach();
return $this->givePermission($permissions);
}
public function hasRole(...$roles)
{
foreach ($roles as $role) {
if($this->roles->contains('name', $role))
return true;
}
return false;
}
public function hasPermissionTo($permission)
{
return $this->hasPermissionThroughRole($permission) || $this->hasPermission($permission);
}
protected function hasPermission($permission)
{
return (bool) $this->permissions->where('name', $permission->name)->count();
}
protected function hasPermissionThroughRole($permission)
{
foreach ($permission->roles as $role) {
if($this->role->contains($role))
return true;
}
return false;
}
protected function getPermissions(array $permissions)
{
return Permissions::whereIn('name', $permissions)->get();
}
public function roles()
{
return $this->belongsToMany(Role::class, 'users_roles', 'user_id', 'role_id');
}
public function permissions()
{
return $this->belongsToMany(Permissions::class, 'users_permissions');
}
}
Role model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function permissions()
{
return $this->belongsToMany(Permissions::class, 'roles_permissions');
}
}
User model:
namespace App;
use App\App\Permissions\HasPermissionsTrait;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable, HasPermissionsTrait;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function clinic()
{
return $this->hasOne(Clinic::class, 'owner_id');
}
public function files()
{
return $this->hasMany('App/Media');
}
public function verifyUser()
{
return $this->hasOne('App\VerifyUser');
}
}
What am I doing wrong here?
Have you tried passing in the role model instead of the id? Also, on a separate note, it looks as if you might as well just call save as you are not actually ever utilizing an array in this instance.
trait HasPermissionsTrait
{
public function giveRole($role = 'user')
{
$role = \DB::table('roles')->where('name', '=', $role)->first();
$this->roles()->saveMany([$role]);
return $this;
}
}
saveMany calls save:
public function saveMany($models, array $joinings = [])
{
foreach ($models as $key => $model) {
$this->save($model, (array) Arr::get($joinings, $key), false);
}
$this->touchIfTouching();
return $models;
}
and save has typecasted Model, not int:
/**
* Save a new model and attach it to the parent model.
*
* #param \Illuminate\Database\Eloquent\Model $model
* #param array $joining
* #param bool $touch
* #return \Illuminate\Database\Eloquent\Model
*/
public function save(Model $model, array $joining = [], $touch = true)
{
$model->save(['touch' => false]);
$this->attach($model->getKey(), $joining, $touch);
return $model;
}
I'm creating role method in laravel, but when I start the page I have this error. If anyone has any idea you can share it. Thank you.
This is my User model
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function roles(){
return $this->belongsTo(App\Role);
}
public function isEmployee(){
return ($this->roles()->count()) ? true : false;
}
public function hasRole($role){
return (in_array($this->roles->pluck("names"), $role));
}
private function getIdInArray($array, $term){
foreach ($array as $key => $value){
if($value == $term){
return $key;
}
}
throw new UnexpectedValueException;
}
public function makeEmployee($title){
$assigned_roles = array();
$roles = Role::all()->pluck("name", "id");
switch($title){
case 'super_admin':
$assigned_roles[] = $this->getIdArray($roles, 'create');
$assigned_roles[] = $this->getIdArray($roles, 'update');
case 'admin':
$assigned_roles[] = $this->getIdArray($roles, 'delete');
$assigned_roles[] = $this->getIdArray($roles, 'ban');
case 'moderator':
$assigned_roles[] = $this->getIdArray($roles, 'kickass');
$assigned_roles[] = $this->getIdArray($roles, 'lemons');
break;
default:
throw new \Exception("The employee status entered does not exist");
}
$this->roles()->sync($assigned_roles);
}
}
We are working on two laravel projects one for front end laravel and for backend api. I followed tutorials on connecting this two projects but make use of guzzlehttp. However I am getting undefined index password. I already dd the user['data'] in getUsers method and gettign the correct password. Can any one help me on this.
ApiUserProvider
<?php
namespace App\Auth;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Illuminate\Http\Request;
use GuzzleHttp\Client;
class ApiUserProvider implements UserProvider
{
public function retrieveByCredentials(array $credentials)
{
$user = $this->getUserByUsername($credentials['username']);
return $this->getApiUser($user);
}
public function retrieveById($identifier)
{
$user = $this->getUserById($identifier);
return $this->getApiUser($user);
}
public function validateCredentials(UserContract $user, array $credentials)
{
return $user->getAuthPassword() == bcrypt($credentials['password']);
}
protected function getApiUser($user)
{
if ($user !== null) {
return new ApiUser($user);
}
}
protected function getUsers()
{
$client = new Client(['base_uri' => 'http://127.0.0.1:80/api.kourse/public/api/v1/']);
$response1 = $client->request('POST', 'oauth/access_token', [
'form_params' => [
'client_id' => 'id1',
'client_secret' => 'secret1',
'grant_type' => 'password',
'username' => 'email#yahoo',
'password' => 'password'
]
]);
$location = json_decode($response1->getBody(), true);
$token = $location['access_token'];
// Send a request to https://foo.com/api/test
$response2 = $client->request('GET', 'users/self', [
'headers' => [
'Authorization' => 'Bearer '. $token
]
]);
$user = json_decode($response2->getBody(), true);
return $user['data'];
}
protected function getUserById($id)
{
$user = [];
if($this->getUsers()['email'] == $id){
$user['id'] = $id;
}
dd($user);
return $user ?: null;
}
protected function getUserByUsername($username)
{
$user = [];
if($this->getUsers()['email'] == $username){
$user['email'] = $username;
}
return $user ?: null;
}
// The methods below need to be defined because of the Authenticatable contract
// but need no implementation for 'Auth::attempt' to work and can be implemented
// if you need their functionality
public function retrieveByToken($identifier, $token) { }
public function updateRememberToken(UserContract $user, $token) { }
}
ApiUser
namespace App\Auth;
use Illuminate\Auth\GenericUser;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
class ApiUser extends GenericUser implements UserContract
{
public function getAuthIdentifier()
{
return $this->attributes['id'];
}
}
UserController
public function login(Request $request)
{
$email = $request->email;
$password = bcrypt($request->password);
if (Auth::attempt(['username' => $email, 'password' => $password])) {
return "hello";
}
}
error
AuthServiceProvider
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any application authentication / authorization services.
*
* #param \Illuminate\Contracts\Auth\Access\Gate $gate
* #return void
*/
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
Auth::provider('api', function($app, array $config) {
return new ApiUserProvider($config['model']);
});
}
}
My best guess would be to open then User model and if you have:
protected $hidden = [
'password',
'remember_token',
];
to make it an empty array, like this protected $hidden = [];. I guess this might work because when you make new ApiUser return new ApiUser($user); it's converting the User object to array and it removes the password attribute because of the $hidden property.