From: Alexey Borzov on
Hi Christian,

On 04.05.2010 11:40, Christian Weiske wrote:
> I am in the need to verify the user name in a registration form. Part
> of that process is using the existing API to check various things,
> including
> - reserved user names
> - already existing user names
> - validity of a user name
>
> Methods are something like
> - $userservice->isUsernameReserved()
> - $userservice->existsUser()
> - $userservice->isUsernameValid()
>
> I cannot use them with the normal callback rule, since the API methods
> return true when something is wrong for the name the user put into the
> form. There are two options now:
> 0. Extend the API. This is not always feasible
> 1. Write custom methods that invert the results of the API
> 2. Get the callback rule to invert the results of the method call
>
> Of course I would prefer number 2, since adding a "'inverted' => true"
> option to the callback rule is much easier and faster than defining an
> own function/adapting the API.
>
> What do you think about that?

While it won't be difficult to add such a parameter, I don't see how

$user->addRule('callback', 'Username already taken',
array('callback' => array($userservice, 'existsUser'),
'inverted' => true));

is better than
$user->addRule('callback', 'Username already taken',
array('callback' => create_function(
'$v, $userservice', 'return !$userservice->existsUser($v);'),
'arguments' => array($userservice));

or even, in PHP 5.3
$user->addRule('callback', 'Username already taken',
function ($v) use ($userservice) {
return !$userservice->existsUser($v);
});

For me the last example looks A LOT easier to understand.
From: Christian Weiske on
Hello Alexey,


> > Of course I would prefer number 2, since adding a "'inverted' =>
> > true" option to the callback rule is much easier and faster than
> > defining an own function/adapting the API.
> >
> > What do you think about that?
>
> While it won't be difficult to add such a parameter, I don't see how
>
> $user->addRule('callback', 'Username already taken',
> array('callback' => array($userservice, 'existsUser'),
> 'inverted' => true));
>
> is better than
> $user->addRule('callback', 'Username already taken',
> array('callback' => create_function(
> '$v, $userservice',
> 'return !$userservice->existsUser($v);'), 'arguments' =>
> array($userservice));
>
> or even, in PHP 5.3
> $user->addRule('callback', 'Username already taken',
> function ($v) use ($userservice) {
> return !$userservice->existsUser($v);
> });
>
> For me the last example looks A LOT easier to understand.

You are correct. Anyhow any of those are not easy to grasp.
I solved the problem for me by registering an own "icallback" rule that
just inverts the result of the normal callback - resulting in the most
simple code possible.
> $user->addRule(
> 'icallback', 'Username already taken',
> array('callback' => array($userservice, 'existsUser'))
> );

Do you feel that the use case is too off-world, or are you accepting
patches for that?

--
Regards/Mit freundlichen Grüßen
Christian Weiske

-=≡ Geeking around in the name of science since 1982 ≡=-
From: Alexey Borzov on
Hi Christian,

On 04.05.2010 21:10, Christian Weiske wrote:
>>> Of course I would prefer number 2, since adding a "'inverted' =>
>>> true" option to the callback rule is much easier and faster than
>>> defining an own function/adapting the API.
>>>
>>> What do you think about that?
>>
>> While it won't be difficult to add such a parameter, I don't see how
>>
>> $user->addRule('callback', 'Username already taken',
>> array('callback' => array($userservice, 'existsUser'),
>> 'inverted' => true));
>>
>> is better than
>> $user->addRule('callback', 'Username already taken',
>> array('callback' => create_function(
>> '$v, $userservice',
>> 'return !$userservice->existsUser($v);'), 'arguments' =>
>> array($userservice));
>>
>> or even, in PHP 5.3
>> $user->addRule('callback', 'Username already taken',
>> function ($v) use ($userservice) {
>> return !$userservice->existsUser($v);
>> });
>>
>> For me the last example looks A LOT easier to understand.
>
> You are correct. Anyhow any of those are not easy to grasp.
> I solved the problem for me by registering an own "icallback" rule that
> just inverts the result of the normal callback - resulting in the most
> simple code possible.
>> $user->addRule(
>> 'icallback', 'Username already taken',
>> array('callback' => array($userservice, 'existsUser'))
>> );
>
> Do you feel that the use case is too off-world, or are you accepting
> patches for that?

I thought about this a bit and it seems to me that 'notcallback' and probably
'notregex' rules may indeed be useful.

Maybe it even makes sense to somehow add generic not_() alongside and_() and
or_()? Can't come up with a good API, though.

$user->addRule('callback', 'Username, etc.', array($userservice, 'existsUser'))
->not_();

?
From: Christian Weiske on
Hi Alexey,


> > You are correct. Anyhow any of those are not easy to grasp.
> > I solved the problem for me by registering an own "icallback" rule
> > [...]
> > Do you feel that the use case is too off-world, or are you accepting
> > patches for that?
>
> I thought about this a bit and it seems to me that 'notcallback' and
> probably 'notregex' rules may indeed be useful.
>
> Maybe it even makes sense to somehow add generic not_() alongside
> and_() and or_()? Can't come up with a good API, though.
>
> $user->addRule('callback', 'Username, etc.', array($userservice,
> 'existsUser')) ->not_();

not_() in this case would set some internal variable which causes the
rule to invert its value?

If one did
> $element->not_($element->addRule(..))
, not() would return an inversion-rule object that encapsulates the
given rule object - this is the second possibility, but it looks ugly
and is more chars to type.

Let's look at the rules:
+ Callback.php
- inversion makes sense
- Compare.php
- already has comparison operator, does not need inversion
- Each.php
- Is a semi-rule only that relies on other rules, no inversion needed
- Empty.php
- Already has Nonempty, no inversion needed
- Length.php
- has min and max settings, no inversion needed
+ MaxFileSize.php
- inversion makes only sense if one wants to have a minimum file size
- MimeType.php
- inversion makes no sense here, except when wanting to exclude an
array of mime types
- Nonempty.php
- Inversion to Empty.php
+ Regex.php
- Inversion makes sense
- Required.php
- Inversion is totally useless here.

So we have 3 rules here for which inversion makes sense, and only 2
often-needed ones. I think it's the easier/better way to add the
respective inverted rules instead of adding new methods to the API.

--
Regards/Mit freundlichen Grüßen
Christian Weiske

-=≡ Geeking around in the name of science since 1982 ≡=-
From: Alexey Borzov on
Hi Christian,

On 08.05.2010 11:53, Christian Weiske wrote:
>> I thought about this a bit and it seems to me that 'notcallback' and
>> probably 'notregex' rules may indeed be useful.
>>
>> Maybe it even makes sense to somehow add generic not_() alongside
>> and_() and or_()? Can't come up with a good API, though.
>>
>> $user->addRule('callback', 'Username, etc.', array($userservice,
>> 'existsUser')) ->not_();
>
> not_() in this case would set some internal variable which causes the
> rule to invert its value?
>
> If one did
>> $element->not_($element->addRule(..))
> , not() would return an inversion-rule object that encapsulates the
> given rule object - this is the second possibility, but it looks ugly
> and is more chars to type.
>
> Let's look at the rules:
> + Callback.php
> - inversion makes sense
> - Compare.php
> - already has comparison operator, does not need inversion
> - Each.php
> - Is a semi-rule only that relies on other rules, no inversion needed
> - Empty.php
> - Already has Nonempty, no inversion needed
> - Length.php
> - has min and max settings, no inversion needed
> + MaxFileSize.php
> - inversion makes only sense if one wants to have a minimum file size
> - MimeType.php
> - inversion makes no sense here, except when wanting to exclude an
> array of mime types
> - Nonempty.php
> - Inversion to Empty.php
> + Regex.php
> - Inversion makes sense
> - Required.php
> - Inversion is totally useless here.
>
> So we have 3 rules here for which inversion makes sense, and only 2
> often-needed ones. I think it's the easier/better way to add the
> respective inverted rules instead of adding new methods to the API.

OK, committed NotCallback and NotRegex rules, for some reason these commits
didn't show in pear-cvs.

I've never seen the need for MinFileSize rule, so didn't bother with this yet.
Anyway, a better approach here will be to create a generic FileSize rule based
on Length, rather than an inversion of MaxFileSize.