I haven't seen anyone doing this, so i'm bit confused if it can be good approach.
Some small system with login. And i have simple group management withing that system. I want to be able to easily set and execute some triggers depending of action and on group in which user belongs.
First idea that came to my mind is to have in groups table 4 fields for triggers, named like this:
add_triggers (when user is added to trigger this)
delete_triggers (when user is removed from a group)
login_triggers (when user logs in to be triggered)
logout_triggers (when user logout to be triggered)
Now i'm wondering how to relate that to an actual trigger code?
Should i have separated class triggers that should receive just "names" of triggers and in that class to hold all possible trigger's code? So that i'm able to execute that in some kind of a loop?
Does anyone have any other idea how to organize that?
p.s. those groups are quite an important part of a system. Most of the things should be based on them. They even has extending tables for complex type of groups.
thnx
What your looking for is Laravel Events.
I would definetly recommend making a class that the event calls rather than writing procedural style code.
Event::listen('auth.login', 'LoginHandler#onLogin');
Related
In my Laravel application, I have a Model called Project which has, among others, a property called approved_at. There is also a ProjectController, which contains the usual methods *(index, show, create, update, edit...)
Now, the user that created the Project can edit it (modifying its other attributes), but only some "staff" members have the right to approve one.
From what I understand, there can be two ways to handle the approval operation:
Both users, from their respective views (let's call them edit and approve) fire the ProjectController#update method, which will internally distinguish who-can-do-what by means of authorization or policies;
I create a new ProjectApprovalController, with its own update method, and check the authorization at the endpoint (eg, /projects/{id}/approve).
What is the best approach to tackle this behaviour?
It depends on what do you want to do with this in the future. If there would be some kind of extra steps to do behind the approve method for example: connection to external micro service to check if project exists in external database with subsidies then you should definitely split it.
If you don’t mind I would suggest you to not focus so much on the implementation. Your application should be removable as fast as you build it. There is a great presentation about this from Greg Young called ‘The Art of
Destroying Software’. Be more focus to build your solution with SOLID principles and test the behaviour of this method to make it easier to replace in the future.
to answer your question, second option is more restful approach, but I don’t know if that is not shooting to fly with a cannon
How do you handle situation with blameable in the DDD way?
Ofcourse we can ignore some things, but i think that when entity need some tracking (creator, updater, time updated / created) it should be in the class that actually performs some actions on entity.
For example we have post and user, what whould be the correct way?
$post = new Post();
$post->create(); // here we can set some created_id and
other attributes by using mixins or traits like some fw do
Or it is better like this:
$user->createPost($post);
$user->update($post);
As for me second is better, even when we need to track changes that does not apply to post directly, for example:
$post->doSomethingWithPost();
$user->updatePost($post);
Seems like blameable just throws out one important entity - user who manages some things on entities.
Ofcourse we should not overcomplicate things, but usually when blameable is implemented, entity from which you will get id is a logged in user, that is incorrect to the bounded context.
Here it is some Blogging Context, where user of this context updates post and not some authenticated user.
Whats your thoughts on this one? Is there some similar questions that i maybe missed?
All your examples seem like they are not designed with the DDD principles in mind. The first indicator to me is the usage of a $user variable. In 99% of the cases this is too generic to really capture the intent of a given Model. I think there are hidden concepts that would first have to be made explicit. I think along the lines of RegisteredAuthor and Administrator. At least that's what I understand from:
Here it is some Blogging Context, where user of this context updates post and not some authenticated user.
Another question is how can a "user of this context" not be authenticated? How do you know who he is?
In general in an application that explicitly requires User management we normally have something like an IdentityContext as a supporting Sub Domain. In the different contexts we then have other Models like Author or BlogAdministrator holding a reference to the User's identity (UserId) from the IdentityContext. The Red Book has some nice examples on how to implement this.
To answer the question on how to track who changed something and when:
This concept is also referred to as Auditability, which in most revenue relevant parts of system is actually a must once your organization is reaching a certain size. In this scenario I actually always recommend an Event Sourcing approach since it comes with auditability batteries included.
In your case it would actually be enough to either capture the executing UserId as Metadata to the commands like WritePostCommand or ChangePostContentsCommand or use the UserId in a RequestContext object that knows about the execution context (who was sending this command, when was it sent, is this user allowed to execute this use case).
You can then, as Alexander Langer pointed out in the comments, just use this metadata inside your Repositories or Handlers to pass the information to the Aggregates that need it, or could even just send them to an audit log to not pollute your Domain Model with this responsibilities.
NOTE: Generally I would not use the DoctrineExtensions like Blameable in your Domain Model. They depend heavily on Doctrine's Event system, and you do not want to tie your Model into an Infrastructure concern.
Kind regards
This is a long running question that gets me every time I am developing.
I suppose it is not specific to CodeIgniter, but as I am using it, I will consider it in my example.
Firstly, which is better:
function add_entry($data_array)
{
//code to add entry
}
function edit_entry($data_array)
{
//code to update entry
}
OR
function save_changes($what,$data_array)
{
//if what == update update
//otherwise insert
}
Both produce the same action, but does it really matter which one you use?
Getting onto more complicated things.
I have a page where I need to get ONE entry from the database.
I also have a page where I need to get all the entries from the same database ordered by a user specified column.
My resultant method is a function similar to
function($data_array,$order_by='',$limit='')
{
//get where $data_array
//if order_by!='' add order by
//if limit !='' add limit
}
As I develop my application and realise new places where I need 'similar' database functionality I am what feels like hacking previous methods so they work with all my case scenarios. The methods end up containing lots of conditional statements, and getting quite complex with in some cases 4 or 5 input parameters.
Have I missed the point? I don't want duplicate code, and when for the most part the functions are very similar I feel like this 'hacking' methodology works best.
Could someone advise?
Finally my admin functionality is part of the same application in an admin controller. I have an admin model which contains specific methods for admin db interaction. I however use some model functionality from 'user' models.
FOr example if on an admin page I need to get details of a db entry I may load the user model to access this function. There is nothing wrong/insecure about this..? right?
In addition to that within my admin model itself I need to get data about a user database entry so I call my user model directly from my admin model. This is strictly OK, but why? If i need data and there is already a method in my user model which gets it.. it seems a little pointless to rewrite the code in the admin model BUT each time that function is called does it load the whole user model again?
Thanks a lot all.
In order, add edit in the model vs save. Personally I have a save built in MY_Model that chooses whether it is a save or an edit depending on the existence of a primary key in the data being passed, so obviously I prefer that method it means a lot less duplication of code since I can use the save for any table without having functions in the model at all.
As to the second question I think it depends on situation. I also have a number of functions that have a ton of conditionals on them depending on where they're used and for what. In some cases I'm finding this makes the legibility of the code a little rough. If you're running them all through if statements it also could be impacting performance. DRY is a concept, not a rule and like other design concepts there are times when they just don't make sense, it's like database normalization, it's my personal opinion it's VERY easy to over normalize a database and destroy performance and usability.
Finally, using user functions in the admin code. I don't see an issue here at all, the reverse probably isn't true, but rewriting a function just because it's an "admin" function, when it's identical to a user function is utterly pointless. So you're correct there, it's a waste of time and space.
I've read some guides / tutorials about Symfonys event system. But I am still not sure about the naming best practice. Unfortunatelly most documentations use default scenarios like login, etc. So here is an example from a game:
A command evaluations some kind of match result. It fires an appropriate event like this:
$dispatcher->dispatch('game_bundle.match_won', new MatchWonEvent($match, $winner));
Now I want to register several listeners to handle this event, like for example one for posting this to the winner's Facebook page and another one to book an achievement for the winner. In the examples I found the listener handling the login event was mainly called something like LoginListener, but shouldn't this name relate to the actual use of it instead of the event it is related to? Because now in my example I would need a MatchWonListener, but should that contain both the Facebook and the achievement logic? That would make the event system useless then... Wouldn't it be better to have one FacebookListener with an onMatchWon($event) and one AchievementListener with it's own onMatchWon($event) method? This would also make it easy to add more Facebook-related events into the FacebookListener for example.
I am confused about the naming in the samples and not sure about now. Am I getting it totally wrong?
There's no "best practice" on how to name events. However, if you name the listener after the event, I think that defeats the purpose of events altogether. The goal is to be able to let different parts of your system interact between each other without coupling and mixing concerns.
So considering you went this far of creating events to separate concerns, why would you go and mix all the different logics into one listener? In that case you might as well just do a direct call instead of dispatching an event.
I'm personally against names like "onMatchWon" because that doesn't describe what the method does. Let's say you want to listen to a match won event and update the achievements of the user who won. I'd probably have some user manager service or the sort with a method updateAchievements(MatchWonEvent $event). But I think that's more of a matter of taste, or convention if you're willing to.
So I've been working on an PHP MVC for a client for about 3 weeks now, I've got pretty far.
I'll explain a small part of the system.
There are three types of users, Fitters, Agencys, and Admins.
these can all log in and have limited functionality, admin obviously has all functionality!
The admin can add, edit and delete users, jobs, stock blah blah the usual.
The way I've set it up so far is like so...
The query string is like: /admin/users/?method=agency&action=add
This will call the admin controller, and call the users function.
The users function will then call the users model.
The users model contains functionality to add, edit, delete, admins, fitter, and agencies.
action=add&method=admin will call add_admin() which will dynamically return a form for admins
action=edit&method=fitter will call edit_fitter() which will dynamically return a form for editting fitters
Now I was wondering...
Would it be better for me to have an ADD class. with ALL the add methods like, add_fitter, add_agency, add_admin, add_job, add_stock etc... and then have a class for EDIT, a class for DELETE, and a class for VIEW ???
Would this be a good way?
I thought that by doing this, I can limit the dependancy on classes like the USERs class.
Because the users class adds, edits, deletes, inserts, updates and views fitters, agencies, and admins. So the user class needs a Validator, a database, a Form class that returns html forms for adding and editting etc etc.
However if i had ONE class for ALL the adding, then it would eradicate the dependancy for a validator? because the add class would be responsible for returning the form. Nothing else
The reason I'm asking this question is because I'm new to MVC. and I dont want to spend the next couple of hours changing all my code, and then realising that theres a problems with my proposed pattern.
So i'm just asking you kind people, can you foresee a problem with this method?
is this how its usually done?
or is this method steered clear of for a reason?
ANY advice or tips will be GREATLY appreciated!
Just to be clear... I'm asking whether I should have separate classes for Add, Edit, Delete and view
Alex
I think the best way is store the access level of the user (session, etc), and render the page according to what was stored in the session. Urls need to be only /admin/users/?action=add
Or
admin/user/edit/?id=27
router/controller/action/?param1=value1
Just if anybody was curious, i did implement my mvc this way and it's much better!