Laravel 7.x Observer not saving, created_by updated_by user - laravel

I have a Model named "Resource".
by using this command
php artisan make:observer ResourceObserver --model=Resource
this command create a new file, i update created, updated functions and update constructor
<?php
namespace App\Observers;
use App\Resource;
class ResourceObserver
{
protected $userID;
public function __construct()
{
$this->userID = auth()->user()->id;
}
/**
* Handle the resource "created" event.
*
* #param \App\Resource $resource
* #return void
*/
public function created(Resource $resource)
{
$resource->created_by = $this->userID;
}
/**
* Handle the resource "updated" event.
*
* #param \App\Resource $resource
* #return void
*/
public function updated(Resource $resource)
{
$resource->updated_by = $this->userID;
}
/**
* Handle the resource "deleted" event.
*
* #param \App\Resource $resource
* #return void
*/
public function deleted(Resource $resource)
{
//
}
/**
* Handle the resource "restored" event.
*
* #param \App\Resource $resource
* #return void
*/
public function restored(Resource $resource)
{
//
}
/**
* Handle the resource "force deleted" event.
*
* #param \App\Resource $resource
* #return void
*/
public function forceDeleted(Resource $resource)
{
//
}
}
this is my migration:
public function up()
{
Schema::create('resources', function (Blueprint $table) {
$table->id();
// some fields here
$table->foreignId('created_by')->nullable()->default(null)->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->default(null)->constrained('users')->onDelete('set null');
$table->timestamps();
});
}
then you should register the observer in AppServiceProvider like this:
use App\Observers\ResourceObserver;
use App\Resource;
public function boot()
{
Schema::defaultStringLength(191);
Resource::observe(ResourceObserver::class);
}
Now the problem appears when update any record it is not save the user_id
to update i use update function in ResourceController
public function update(Request $request, Resource $resource)
{
$validations = [
// some validations
];
$request->validate($validations);
try {
if (!empty($resource)) {
$resource->field_a = $request->field_a;
$resource->field_b = $request->field_b;
$resource->field_c = $request->field_c;
$resource->save();
return 'done messge';
} else {
return 'error message';
}
} catch (\Exception $e) {
return 'bug message';
}
}
Any help please?!

When issuing a mass update or delete via Eloquent, the saved, updated, deleting, and deleted model events will not be fired for the affected models. This is because the models are never actually retrieved when issuing a mass update or delete.
So, In ResourceObserver i just changed from method from updated to updating,
and created to creating

Related

Date and Time localization not works in Laravel-mix

I have Laravel mix installed on my server. there is a chat part on website and I use some kind of class :
class ActivityCell extends Component {
getTimestamp() {
const {message} = this.props;
return (
<span className="font-weight-semi-bold">
{utcDateCalendarTime(message.created_at)}
</span>
);
}
And here is my AppServiceProvider.php file :
<?php
namespace App\Providers;
use Illuminate\Http\Resources\Json\Resource;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function boot()
{
setlocale(LC_ALL, Config::get('app.lc_all'));
Carbon::setLocale(Config::get('app.locale'));
}
public function register()
{
$this->registerPlugins();
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
$this->bootDatabase();
$this->bootResource();
}
/**
* Boot database schema
*
* #return void
*/
private function bootDatabase()
{
Schema::defaultStringLength(191);
}
/**
* Boot resource
*
* #return void
*/
private function bootResource()
{
Resource::withoutWrapping();
}
/**
* Register plugins
*
* #return void
*/
private function registerPlugins()
{
$pluginDirs = File::directories(base_path('app/Plugins'));
foreach ($pluginDirs as $pluginDir) {
$class = "App\\Plugins\\" . basename($pluginDir) . "\\PluginServiceProvider";
if (class_exists($class) && is_subclass_of($class, ServiceProvider::class)) {
$this->app->register($class);
}
}
}
}
I tried to put setlocale(LC_TIME, 'tr'); on top of the class file but there is no success. Then tried to use carbon in order to make the date is viewed in different languages when I change the website language.
I added the following codes in app/config.php :
'locale' => env('APP_LOCALE', 'az'),
'lc_all' => env('APP_LC_ALL', 'az_AZ.UTF-8'),
and added following to the env file :
APP_LOCALE = az
APP_LC_ALL = az_AZ.UTF-8
in both methods, I was not successful. I am pretty sure that I am doing a mistake somewhere but can not find where exactly. Maybe I am missing to add something else to add. Any help would be highly appreciated.
EDIT : Adding Chat.php :
<?php
namespace App\Models;
use App\Events\ChatParticipationChanged;
use App\Events\ChatUpdated;
use App\Http\Resources\ChatMessage as ChatMessageResource;
use App\Http\Resources\MarketplaceTrade as MarketplaceTradeResource;
use ArrayObject;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use JSsVPSDioNXpfRC;
use DateTimeInterface;
class Chat extends Model
{
protected $lastMessageAttribute;
protected $lastMarketplaceTradeAttribute;
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
protected $guarded = [];
/**
* The event map for the model.
*
* #var array
*/
protected $dispatchesEvents = [
'updated' => ChatUpdated::class
];
/**
* Indicates if the IDs are auto-incrementing.
*
* #var bool
*/
public $incrementing = false;
/**
* Get the route key for the model.
*
* #return string
*/
protected function serializeDate(DateTimeInterface $date)
{
return $date->translatedFormat('A B M');
}
public function getRouteKeyName()
{
return 'id';
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function creator()
{
return $this->belongsTo(User::class, 'creator_id', 'id');
}
/**
* Participants for this chat
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function participants()
{
return $this->hasMany(ChatParticipant::class, 'chat_id', 'id');
}
/**
* Messages for this chat
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function messages()
{
return $this->hasMany(ChatMessage::class, 'chat_id', 'id');
}
/**
* Update user's participation record
*
* #param User $user
*/
public function updateParticipation($user)
{
$this->participants()->where('user_id', $user->id)
->update(['last_read_at' => now()]);
broadcast(new ChatParticipationChanged($this, $user));
}
/**
* All marketplace trades hosted by this chat
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function marketplaceTrades()
{
return $this->hasMany(MarketplaceTrade::class, 'chat_id', 'id')
->has('buyer')->has('seller');
}
/**
* #return Model|\Illuminate\Database\Eloquent\Relations\HasMany|mixed|object|null
*/
public function getLatestMarketplaceTrade()
{
if (!isset($this->lastMarketplaceTradeAttribute)) {
$trade = $this->marketplaceTrades()->latest()->first();
$this->lastMarketplaceTradeAttribute = new MarketplaceTradeResource($trade);
}
return $this->lastMarketplaceTradeAttribute;
}
/**
* Last chat message
*
* #return ChatMessageResource|ArrayObject|mixed
*/
public function getLatestMessage()
{
if (!isset($this->lastMessageAttribute)) {
$message = $this->messages()->latest()->first();
if ($message) {
$this->lastMessageAttribute = new ChatMessageResource($message);
} else {
$this->lastMessageAttribute = new ArrayObject();
}
}
return $this->lastMessageAttribute;
}
/**
* #param User $user
* #return array
*/
public function getParticipation($user)
{
$participant = $this->participants()
->where('user_id', $user->id)->without('user')
->first();
$unreadMessagesCount = ($participant && $participant->last_read_at) ?
$this->messages()->where('user_id', '!=', $user->id)
->where('created_at', '>', $participant->last_read_at)
->count() :
$this->messages()->where('user_id', '!=', $user->id)
->count();
return [
'user_id' => $user->id,
'unread_messages_count' => $unreadMessagesCount
];
}
/**
* If user should be allowed in this chat
*
* #param User $user
* #return bool
*/
public function shouldAllowUser($user)
{
$isParticipant = $this->participants()
->where('user_id', $user->id)->exists();
return (
$isParticipant ||
$user->can('moderate_chats')
);
}
/**
* #return string
*/
public function attachmentsDir()
{
return "chats/{$this->id}/message-attachments";
}
}
The problem is on your namespace :
// Using PHP callable syntax
use Carbon\Carbon;
Or,
// Using string syntax
\Carbon\Carbon::setLocale('ru');
You also need to use translatedFormat() method on your blade for use the translate format, like :
{{ Carbon\Carbon::now()->translatedFormat('A B M') }} // утра 428 фев
You can use serializeDate() method on your model, to change timestamp column as a translated dataTime format :
use DateTimeInterface;
protected function serializeDate(DateTimeInterface $date)
{
return $date->translatedFormat('A B M');
}

ReflectionException Class app\Repositories\MailMessageRepository does not exist

i'm having trouble accessing a repository, I can't call functions. I'm trying to integrate a softdelete button on my MailMessages datatable but I can't use the repository, I recived the following message:
ReflectionException Class app\Repositories\MailMessageRepository does
not exist
My MailMessageController
<?php
namespace App\Http\Controllers;
use App\DataTables\MailMessageDataTable;
use App\Http\Requests\MailMessageRequest;
use app\Repositories\MailMessageRepository;
use App\MailMessage;
use Illuminate\Http\Request;
use DataTables;
use PulkitJalan\Google\Facades\Google;
class MailMessageController extends Controller
{
protected $mailMessageRepository;
/**
* UserController constructor.
* #param $mailmessageRepository
*/
public function __construct(mailmessageRepository $mailmessageRepository)
{
parent::__construct();
$this->MailMessageRepository = $mailmessageRepository;
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(MailMessageDataTable $MailMessageDataTable)
{
return $MailMessageDataTable->render('mailmessage.index');
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
// $MailMessage = $this->MailMessageRepository;
return view('mailmessage.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(MailMessageRequest $request)
{
$MailMessage = $this->MailMessageRepository->saveMailMessage($request);
return redirect()->route('MailMessage.show', ["id" => $MailMessage->id])
->with(["message" => __('messages.create.success')]);
}
/**
* Display the specified resource.
*
* #param \App\MailMessage $mailMessage
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$MailMessage = MailMessage::find($id);
return view('MailMessage.show', ['MailMessage' => $MailMessage]);
}
/**
* Show the form for editing the specified resource.
*
* #param \App\MailMessage $mailMessage
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
$MailMessage = MailMessage::find($id);
return view('MailMessage.edit', ['MailMessage' => $MailMessage]);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\MailMessage $mailMessage
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$MailMessage = MailMessage::find($id);
$MailMessage->type = $request->type;
$MailMessage->description = $request->description;
$MailMessage->from_value = $request->from_value;
$MailMessage->to_value = $request->to_value;
$MailMessage->update();
return redirect('MailMessage/' .$MailMessage->id)->with(["message" => __('messages.edit.success')]);
}
/**
* Remove the specified resource from storage.
*
* #param \App\MailMessage $mailMessage
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
$MailMessage = $this->MailMessageRepository->getMessagebyId($id, true);
if ($MailMessage->trashed()) {
$MailMessage->restore();
}else{
$MailMessage->delete();
}
return redirect()->route('MailMessage.index')
->with(["message" => __('messages.update.success')]);
}
public function digest_report(MailMessage $mailMessage)
{
}
}
my MailMessageRepository
<?php
namespace App\Repositories;
use App\User;
use App\MailMessage;
use App\Enums\MailMessageType;
use Illuminate\Support\Facades\Auth;
class MailMessageRepository
{
public function getMessage($id, $trashed = false)
{
if($trashed){
return MailMessage::withTrashed();
}
return MailMessage;
}
public function getMessageById($id, $trashed = false)
{
if ($trashed) {
return MailMessage::withTrashed()->with('roles')
->where('id', '=', $id)->first();
}
return MailMessage->where('id', '=', $id)->first();
}
public function deleteMailMessage($id)
{
$MailMessage = MailMessage::find($id);
$MailMessage->delete();
}
public function saveMailMessage($request)
{
$MailMessage = new Message($request->all());
$MailMessage->save();
return $MailMessage;
}
public function setOAuthAccessToken($accessToken)
{
}
public function updateMailMessage($request, $id) {
}
}
Maybe something wrong, you declare mailMessageRepository variable so you need to use $this->mailMessageRepository
public function __construct(mailmessageRepository $mailmessageRepository)
{
parent::__construct();
$this->MailMessageRepository = $mailmessageRepository;
}
try this
public function __construct(MailMessageRepository $mailmessageRepository)
{
parent::__construct();
$this->mailMessageRepository = $mailmessageRepository;
}
and try replace all $this->MailMessageRepository to $this->mailMessageRepository in your code

"SQLSTATE[HY000]: General error: 1366 Incorrect integer value:"

I am a beginner in Laravel, making reply functions.
I would appreciate it if you could fix this code.
I got this error:
"SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '<div>da</div>' for column 'content' at row 1 (SQL: insert into `replies` (`content`, `discussion_ ▶"
2019_07_26_035335_create_replies_table.php
This is how my table looks:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRepliesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('replies', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id');
$table->integer('discussion_id');
$table->integer('content');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('replies');
}
}
RepliesController.php
namespace LaravelForum\Http\Controllers;
use Illuminate\Http\Request;
// 2019/07/29
// C:\laravel-apps\bulletin-board\app\Http\Requests\CreateReplyRequest.php
use LaravelForum\Http\Requests\CreateReplyRequest;
// postscript
use LaravelForum\Discussion;
class RepliesController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(CreateReplyRequest $request, Discussion $discussion)
{
// C:\laravel-apps\bulletin-board\app\Http\Requests\CreateReplyRequest.php
auth()->user()->replies()->create([
'content' => $request->content ,
'discussion_id' => $discussion->id
]);
session()->flash('success', 'Reply added');
return redirect()->back();
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
C:\laravel-apps\bulletin-board\app\Reply.php
<?php
namespace LaravelForum;
class Reply extends Model
{
//
public function owner()
{
return $this->belongsTo(User::class, 'user_id');
}
public function discussion()
{
return $this->belongsTo(Discussion::class);
}
}
C:\laravel-apps\bulletin-board\app\Http\Requests\CreateReplyRequest.php
<?php
namespace LaravelForum\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateReplyRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
//
'content' => 'required'
];
}
}
you are using $table->integer('content'); interger value for content column. instead of using integer value use $table->text('content'); for the content. As i felt you are refering reply body as content.

Laravel mass update , still fire event

As stated in the doc, laravel will not fire an event on mass update/insert/delete.
https://laravel.com/docs/5.8/eloquent#events
It uses the Builder for this and will not fire an event.
Is there a way that I can still fire an event after a mass update for example? I would only need the query Builder to extract the needed info myself ( log purposes).
It is actually possible , but you have to extend the Eloquent builder ,overwrite the update/insert methods and send the event there.
Just been playing around with it... Needs work, but the basic idea is the following :
class Test extends Model
{
protected $guarded = [];
public $dispatchesEvents = [
'saved' => SavedTest::class
];
/**
* INCLUDE this as a trait in your model.
* Overwrite the eloquentBuilder.
*
* #param \Illuminate\Database\Query\Builder $query
* #return \Illuminate\Database\Eloquent\Builder|static
*/
public function newEloquentBuilder($query)
{
return new TestBuilder($query);
}
}
Extend the eloquent builder...
class TestBuilder extends Builder
{
/**
* Update a record in the database and fire event.
*
* #param array $values
* #return int
*/
public function update(array $values)
{
// normal eloquent behavior.
$result =$this->toBase()->update($this->addUpdatedAtColumn($values));
/*
* Fire event.
*/
if($result){
if( $event = Arr::get($this->model->dispatchesEvents,'saved')){
// at the attributes.
$this->model->fill($this->addUpdatedAtColumn($values));
$queryBuilder =$this->toBase();
event(new $event($this->model,$queryBuilder));
}
}
}
public function insert(array $values)
{
// same idea..
}
}
The event class :
class SavedTest
{
use SerializesModels;
public $model;
public $query;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($model,$query =null)
{
$this->model = $model;
$this->query = $query;
}
}
The listener.
class SavedTestEvent
{
/**
* Create the event listener.
*
*
*/
public function __construct()
{
}
/**
* Handle the event.
*
* #param object $event
* #return void
*/
public function handle($event)
{
// The model , with the attributes.
dump($event->model);
// the query builder , you could extract the wheres or whatever to build your own log for it.
dump($event->query);
}
}
#Paolo on batch request it would not be file the event you must have to perform operation on single record.. like
Analytic::where('id', '>', 100)->get()->each(function($analytic) {
$analytic->delete();
});

Foreign Key not working in Laravel

I am creating cms app.
There are two tables - users and posts. Users table have an id of each user. On the other hand, Posts Table has user id which references to the id of users table.
However, while saving the post, I get an error that Field 'user_id' doesn't have a default value. Why is this? Please help me.
Posts Table:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->string('title');
$table->longText('description');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
DashboardController
<?php
namespace App\Http\Controllers\Dashboard;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Post;
class DashboardController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return view('dashboard.index');
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('dashboard.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$post = new Post();
$post->title = $request->title;
$post->description = $request->description;
$post->save();
return redirect()->intended('dashboard');
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
Post model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
//
}
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 = [
'fname', 'lname', 'email', 'password'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
}
Although, I defined a foreign key 'user_id', it doesn't automatically fetch the id from user table. How can I fix this?
You are not saving user_id:
public function store(Request $request)
{
$post = new Post();
$post->title = $request->title;
$post->description = $request->description;
$post->user_id = Auth::id();
$post->save();
return redirect()->intended('dashboard');
}
Firstly you need to add relations to Post.php:
public function user(){
return $this->belongsTo(User::class);
}
And in User.php:
public function posts(){
return $this->hasMany(Post::class);
}
In DashboardController in action store:
public function store(Request $request)
{
$post = new Post();
$post->title = $request->title;
$post->description = $request->description;
$user = Auth::user()->id;
$user->post()->save($post);
return redirect()->intended('dashboard');
}

Resources