Listen to Event : User::creating - laravel

I'm doing a new plugin for OctoberCms. I would like to limit the front end registration for some specific domains.
I tried to this :
class Plugin extends PluginBase
{
[......]
public function boot()
{
// Listen for user creation
Event::listen('eloquent.creating: October\Rain\Auth\Models\User', function($model) {
{
$this->checkDomains($user);
[.....]
}
}
}
But my listener is not working. Do you know what is the Event, I should listen to catch before a new account is created ?
Thanks

You can bind to all of the model internal events like this:
User::extend(function($model) {
$model->bindEvent('model.beforeSave', function() use ($model) {
// do something
});
});
You can use before and after for create, update, save, fetch and delete

Alternatively, you can use,
public function boot()
{
User::creating(function($model) {
var_dump($model->name);
});
}
available events to listen:
creating, created, updating, updated, deleting, deleted, saving, saved, restoring, restored

You can also use the following:
\Event::listen('eloquent.creating: RainLab\User\Models\User', function($user){
$this->checkDomains($user);
});

Are you referring to a Front-End User's registration ? - I assumed you're using the RainLab User Plugin which has an event rainlab.user.beforeRegister fired in the Account component or you can add a custom one in the model's beforeCreate() event
then simply create a init.php file in the root directory of your plugin and list your listeners there :
Event::listen('rainlab.user.beforeRegister', 'Path\To\ListenersClass');

Related

Updating a model property by POST API, can run an event?

The clear description is, an API with the post method updates a value of a model property. how I can set up a listener in Laravel that after every change by API, run an event for example send email or sms?
If you were wanting to create an event when any update happened you could easily just do this via the boot.
class SomeModel extends Model
{
public static function boot()
{
static::updated(function ($model) {
// send your email/sms
});
parent::boot();
}
}
However this would trigger when ever the model is updated, Since you only want this when you are updating via the API you would want to create a custom event and trigger it via dispatch in your api route/controller.
https://laravel.com/docs/8.x/events#dispatching-events

October CMS - Extending the function of a plugin?

I've created a plugin to extend the User plugin and I now want to extend the update function of its controller.
Actually what I'd like to do is to check some data when an admin
clicks on the Update button then, according to the data, let the admin edit the user form as usual or redirect him to the user list.
I'm trying to do this through a route in my plugin:
Route::get('backend/rainlab/user/users/update/{id}', '\RainLab\User\Controllers\Users#check_update');
in my Plugin.php file
public function boot()
{
\RainLab\User\Controllers\Users::extend( function($controller) {
$controller->addDynamicMethod('check_update', function($recordId = null, $context = null) use ($controller) {
return $controller->asExtension('FormController')->update($recordId, $context);
});
});
}
But I get a blank page. The user form is not displayed.
Can someone helps me ?
This wont work as it will break life-cycle of back-end and direct call method of controller.
As other solution, we can use events :) - backend.page.beforeDisplay
In your plugin's plugin.php file's boot method
public function boot() {
\Event::listen('backend.page.beforeDisplay', function($controller, $action, $params) {
if($controller instanceof \RainLab\User\Controllers\Users) {
// for update action
if($action === 'update') {
// check data ($params) and make decision based on that
// allow user to edit or NOT
if(true) {
// just redirect him to somewhere else
\Flash::error('Please No.');
return \Redirect::to('/backend/rainlab/user/users');
}
// if all good don't return anything and it will work as normal
}
}
});
}
it will do the job based on condition you can allow user to edit OR not (redirect him with message to other action).
if any doubts please comment.

How to hook into the delete event for a resource in laravel nova?

I have one query, I want to delete the image from the server when particular resource get deleted from Nova.
can anyone suggest me is there any way to override delete method for the resource.
EDIT: How to hook into the delete event for a resource in laravel nova?
Note: I know we can do using observer. but I am looking for another
way.
In order to hook into laravel nova's delete resource event, you don't have a builtin way. But the parent model's have a delete method, you can override it and do extra work there
//app/ParentModel.php
public function delete() {
/* add your extra logic for deleted model */
parent::delete();
}
you can use boot in your model like this:
public static function boot()
{
parent::boot();
self::deleted(function ($model) {
parent::remove($model, self::$index);
});
}
I used Observers and deleted function Nova Resource Events and works fine

Prevent Certain CRUD Operations on Laravel Eloquent Models

Is there an easy way to prevent certain CRUD operations from being performed on an Eloquent model?
How I'm doing it now (from memory, I think I'm missing an argument to be compatible with Eloquent's save(), but that's not important):
<?php
class Foo extends Eloquent {
public function save()
{
// Prevent Foo from being updated.
if (!empty($this->id)) {
throw new \Exception('Update functionality is not allowed.');
}
parent::save();
}
}
In this case, these models should not be allowed to be updated under any circumstance, and I want my app to explode should something try to update them. Is there a cleaner way to do this without overriding Eloquent's save() method?
In addition to #AlanStorm's answer, here's a comprehensive info:
You can setup global listener for all the models:
Event::listen('eloquent.saving: *', function ($model) {
return false;
});
Or for given model:
Event::listen('eloquent.saving: User', function ($user) {
return false;
});
// or
User::saving(function ($user) {
return false;
});
// If it's not global, but for single model, then I would place it in boot():
// SomeModel
public static function boot()
{
parent::boot();
static::saving(function ($someModel) {
return false;
});
}
For read-only model you need just one saving event listener returning false, then all: Model::create, $model->save(), $model->update() will be rejected.
Here's the list of all Eloquent events: booting, booted, creating, created, saving, saved, updating, updated, deleting, deleted and also restoring and restored provided by SoftDeletingTrait.
Eloquent's event system allows you to cancel a write operation by
Listening for the creating, updating, saving, or deleting events
Returning false from your event callback.
For example, to prevent people from creating new model objects, something like this
Foo::creating(function($foo)
{
return false; //no one gets to create something
});
in your app/start/global.php file would do the job.

Laravel 4 how to listen to a model event?

I want to have an event listener binding with a model event updating.
For instance, after a post is updated, there's an alert notifying the updated post title, how to write an event listener to have the notifying (with the post title value passing to the listener?
This post:
http://driesvints.com/blog/using-laravel-4-model-events/
Shows you how to set up event listeners using the "boot()" static function inside the model:
class Post extends eloquent {
public static function boot()
{
parent::boot();
static::creating(function($post)
{
$post->created_by = Auth::user()->id;
$post->updated_by = Auth::user()->id;
});
static::updating(function($post)
{
$post->updated_by = Auth::user()->id;
});
}
}
The list of events that #phill-sparks shared in his answer can be applied to individual modules.
The documentation briefly mentions Model Events. They've all got a helper function on the model so you don't need to know how they're constructed.
Eloquent models fire several events, allowing you to hook into various points in the model's lifecycle using the following methods: creating, created, updating, updated, saving, saved, deleting, deleted. If false is returned from the creating, updating, saving or deleting events, the action will be cancelled.
Project::creating(function($project) { }); // *
Project::created(function($project) { });
Project::updating(function($project) { }); // *
Project::updated(function($project) { });
Project::saving(function($project) { }); // *
Project::saved(function($project) { });
Project::deleting(function($project) { }); // *
Project::deleted(function($project) { });
If you return false from the functions marked * then they will cancel the operation.
For more detail, you can look through Illuminate/Database/Eloquent/Model and you will find all the events in there, look for uses of static::registerModelEvent and $this->fireModelEvent.
Events on Eloquent models are structured as eloquent.{$event}: {$class} and pass the model instance as a parameter.
I got stuck on this because I assumed subscribing to default model events like Event:listen('user.created',function($user) would have worked (as I said in a comment). So far I've seen these options work in the example of the default model user created event:
//This will work in general, but not in the start.php file
User::created(function($user)....
//this will work in the start.php file
Event::listen('eloquent.created: User', function($user)....
Event::listen('eloquent.created: ModelName', function(ModelName $model) {
//...
})

Resources