Entity Availablity in a Table

I have some validation that I need to perform where I need to make a call to the database. So I’ve created a customer validation method, but in order to make the call, I need some data from the request form that was submitted (or it could be the authenticated session), basically a users id.

In CakePHP2, I would could get that data through $this->data in the model, as it was set once the data was passed to the save() method. Is there something similar for CakePHP4? I know I could set the data manually from the controller, but since the data is already being sent to the save method, is it available some where?

Can you share some code?

1 Like

After doing more reading, it looks like there are two types of validation that can be done in CakePHP4. This is a new concept for me, so I’m just trying to figure it all out. Validation and application rules. So in this particular instance, since I’m need to do a check against a database, I think I need to implement an application rule instead of validation. Looking into this more.

Yes. The documentation pushes the idea that Validation is to insure the correct data type is passed to the column. These Validations run during the patchEntity process.

Your case does sound more like a Rule. Rules make sure the business logic you decide on for your system is followed. These Rules run during the ‘save’ process.

Both work great within there sphere of influence. It might be worth mentioning that Rules can only be run against one entity.

I have had situations where a business rule had to be decided on a set of entities. For example, a set of related addresses where one must be, but no more than one can be marked as ‘primary’. In cases like this, the Rules system can’t help.

Ok, so the rule I need to build is basically checking the history of passwords. I have a business rule that says a user can’t reuse a password for for up to six password changes. So we store the past six password hashes in a separate database table and everytime they change the password we have to check to see if they’ve already used that.

I’ll have the one user entity, but will checking that against a set of other table records (I guess those will be their own set of entities), be a problem? If that makes sense? If not, I’m going to be giving this a shot anyway I guess, so I’ll find out.

That sounds like a case where you can use a Rule and have it do the query and enforce the business rule.

My problem scenario related to situations where the set of entities all came in on the form and needed to be considered as a whole.

I was talking about your security with a friend and he told me about one of his staff members that defeats their similar security by entering a sequence of new passwords until they can reuse the old one again :upside_down_face:

I guess a business rule on the ‘save new password’ process that only pushed the oldest historical hash off the list if the newest was significantly newer than the previous new one…

Security sometimes feels like a sink-hole.

It’s been demonstrated that you get better security by enforcing longer passwords and encouraging people to use a sequence of words that are meaningful to them, than by forcing regular updates.

Yes, I’m aware and very familiar with the issues. Unfortunately these aren’t my rules and they’re passed down from our security department. There are several rules we have to follow and that’s just one of them. They also enforce the longer, random passwords or pass phrases, which is good and in my opinion the only thing that really matters.

Forcing people to constantly change their password does little good. In fact, I wouldn’t be surprised if it lessens security, because people are more likely to use something smaller and simpler so they can more easily remember it.

Trust me… I get it. I think it looks better on paper and therefore corporations buy into it better. A sad false truth.

Like the clip, by the way. Really hits the nail on the head.

No, that should work fine. If you set up associations correctly, you should have no problem at all getting those old password records to look at.

This is frustrating. From a usability perspective, this doesn’t work well. I only noticed this after running through my registration form. All of my validation runs first, without the rules. Once that’s fixed, I then get errors on rules, like a unique email address… separately from validation. My email address is fine the first time (even though it’s not)… I do nothing with it, fix the other issues, and then it throw an error at me the second time.

From the user perspective, I would expect everything that is wrong to be thrown at me the first time. Any recommendations on this?

It makes some sense the way it is because if the data is incorrect for the column (validation) then no rules could be applied to that field.

And since Rules run as part of the save they won’t be checked until patching (validation) passes…

The clumsiness comes when one field is invalid and another field is valid but violates a rule.

I don’t know the details, and don’t know if it’s advisable, but you could skip your validation and write rules that did everything, data-type confirmation and business rules if you really think this will be a widespread problem for users.

Mostly though, I think people are familiar with forms and will at least get the data good enough to make it past Validation and into the business rule checks.

It’s easy to get caught up in the minutia of what might happen, loosing sight of what is typically going to happen.

I get what you’re saying. I could do inline validation and that would fix the problem I guess. Didn’t really want to do that, but that’s the only way to completely avoid the problem. Without having do what you suggested I guess.

You can do this right after your patchEntity call to apply all the rules and update the list of errors as applicable:

$this->Users->checkRules($user);
2 Likes

This works for me! Thanks.