Maugrim_The_Reaper wrote:Isn't that a case of a loose interface? You seem to have three broad types: Filter, Flag and Rule. I'm not entirely sure how much Reflection this would need assuming they share an interface common to all Validator classes, or the attach() method differentiates between the three types to utilise each type's shared interface. Presumably you need to split types to manage run order unless it's dictated by the order in which attached.
Hit the nail on the head. And yes I need to split types to manage run order.
Maugrim_The_Reaper wrote:Do you have a specific use case where Reflection becomes necessary? In general I find Reflection in PHP tends to be a sign of overcomplicating a solution in 90% of cases. It's also a common performance issue - though that's usually removed as a side effect of simplifying the design through refactoring, not as a premature optimisation.
I also consider reflection a failure on my part in most instances, which usually reflects poor design; I definantly would like to see this go, although I don't see how I can refactor it out as of yet.
This is where I need reflection (during the attachment process)
Code: Select all
class Northern_Validator
{
/**
* Todo
*/
public function attach($field, $attachment, $error = false)
{
if (!$this->_fieldExists($field)) {
throw new Northern_Validator_Exception('Cannot find field name "'. $field);
}
$type = $this->_getReflectionType($attachment);
$this->fields[$field][$type] = array();
array_push($this->fields[$field][$type], $attachment);
}
/**
* Todo
*/
protected function _getReflectionType($attachment)
{
$type = new ReflectionClass($attachment);
$parts = explode('_', ucfirst($type->getName()));
if (!in_array($parts[2], $this->types)) {
throw new Northern_Validator_Exception('Must pass valid attachment type');
}
return $parts[2];
}
Obviously this sucks because a) you have to follow the naming convention (Northern_Validator_
Rule_NotNull(), Northern_Validator_
Filter_Trim())),
b) reflection is used on such a trivial task.
Maugrim_The_Reaper wrote:You should check the Zend Framework mailing list and wiki for tips and ideas. Chains have been discussed in the past ever since they deprecated Zend_Filter_Input and made input filtering such a low level task.
I have looked at it awhile ago when the proposal was fresh.. I guess its been awhile. Thanks for the tip Maugrim.]]
arborint wrote:The major difference is that I don't mix filters and rules in the same chain. I am not sure what your flags do? I use separate chains for validation and filtering. I prefer separate chains for exactly the reasons you mention -- their needs are slightly different and I can make them ultra simple if they are separate. To me validation inspects values and builds up error messages. Filtration modifies values. Those are two very different things to me.
The Ninja Space Goat wrote:ever since they deprecated Zend_Filter_Input
When did this happen, and why?

Because it was a giant, steaming, monolithic, procedural piece of crap!

Indeed, your filter and validator classes initially got me started down this path many months ago. I see where your coming from but like they say, if your zebra don't try and change your stripes.. or something to that effect. Reguardless, your right this does complicate things.. and now I am suffering for it
Maugrim_The_Reaper wrote:I think Flags should be simple constants - does having them as classes pose any particular advantage? Filters should be attached and run as a priority since they adjust input to minimise user errors. I'd also check exactly how many filters are required. It's possible you could manage this internally by knowing what type of data is being received (i.e. trim as part of validation where a "clean" value is extracted but leaving the raw value untouched). Is there any other type of filtering you intend adding?
The only reason I made them a class was because of the unforseen circumstances. I know last chain validator I always ran into shortfalls of the design. Looking back on this now, I think that idea was silly.. I like the idea of a constant, but again I would like some input as to what you guys would like to see in the API (not that you will be using this code.. probably already have your own filtering megahogs already finished

)
Code: Select all
$validators[0]->attach('foo', new Northern_Validator_Rule_NotNull(), 'error message', OPTIONAL);
Or something to this effect? Seems like were starting to have a lot of paramaters being passed, cluttering the code. Hrm..
The idea of checking running the filters is actually the opposite I had in mine. Filters to me have a lot more responsibilities than one would imagine. For instance, lets say I'm doing a file uploading form.. I'd have something like
Code: Select all
$validators[0] = new Northern_Validator('fileupload', $this->getInvokeArg('files'));
$validators[0]->attach('foo', new Northern_Validator_Rule_Files_NotNull(), 'field cannot be empty');
$validators[0]->attach('foo', new Northern_Validator_Filter_Files_Trim());
$validators[0]->attach('foo', new Northern_Validator_Filter_Files_MoveFile($path1, $path2));
//etc etc ...
Notice the MoveFile. If this is run prior to the rules then the thing would explode if the rules failed. I think I remember the Zend_Proposal using constants to set the priority of the order of attachments.
Maugrim_The_Reaper wrote:Is there any other type of filtering you intend adding?
Yes, all kinds of sorts. There will be about a dozen or so "standard" filters, and of course others can be added on a per application basis. This also brings me back to the reflection part, which I'd like to avoid completely so I can include filter objects from anywhere in the filesystem, not the the just the default directory.
Maugrim_The_Reaper wrote:
After this you're into validation which is the backbone of the chain. At this stage the order of Validators is unimportant though obviously it's a good point to put NotNull/Optional at the start since presumably it's the fastest and simplest one. Once you have a interface for Validators (as opposed to filter/flags) you're at the point where a helper class should be capable of manufacturing a chain. This is usually my preference - I absolutely dislike defining chains inside the source code since its so repetitive, so a Factory and a set of config files is where I aim.
I think your going to have to explain this a bit more

Kind of wen't over my head. You mean have all your validations predefined through a configuration file, read that configuration file, and finally factory and manufactor the chain?
But thanks alot for the replys so far guys, much appreciated

Keep em coming.