Aura.Filter any way to do "if rule does NOT fail, stop processing"?

67 views
Skip to first unread message

JH

unread,
Feb 7, 2014, 4:11:23 PM2/7/14
to aur...@googlegroups.com
I have a case where if one field is filled in, then a bunch of required fields don't need to be required/filtered anymore and can be blank.

I can write a Rule class that checks for that field and returns a boolean, as the first rule, then use it's normal filter for validation if the other field value is not filled in.
Problem is there's no way I see to stop filtering if a filter is true. Is there a way to trigger stopping all filtering for a field from inside a rule?

I guess if it's not currently available, making a new rule type is the answer here? Thanks.

JH

unread,
Feb 7, 2014, 4:13:53 PM2/7/14
to aur...@googlegroups.com
hmmmm, if I use the "Any" rule and pass my custom rule as first - that could work right? 

JH

unread,
Feb 7, 2014, 5:01:19 PM2/7/14
to aur...@googlegroups.com
Okay, looks like it should work, but when line 83 of Any.php is called:

    // get the rule for that name and prep it
    $rule = $this->rule_locator->get($name);

I get an error saying:

Uncaught exception 'Aura\Filter\Exception\RuleNotMapped' with message 'fieldHasValue'

Which is strange when it 1) is found when I don't use the Any rule, and 2) I can return my filter manually using:

$filter->getRuleLocator()->get('fieldHasValue')

any ideas?

Hari K T

unread,
Feb 7, 2014, 8:40:54 PM2/7/14
to aur...@googlegroups.com
I am not sure why it is happening.

Question is : Have you added the Rule to the rule locator as a service

https://github.com/auraphp/Aura.Filter#set-the-class-as-a-service

2 ) How is the Aura.Filter used, is it combined with Aura.Di ? ( used inside a framework / standalone )

Thanks

Hari K T

You can ring me : +91 9388 75 8821

Skype  : kthari85
Twitter : harikt


--
You received this message because you are subscribed to the Google Groups "The Aura Project for PHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to auraphp+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

JH

unread,
Feb 10, 2014, 10:59:03 AM2/10/14
to aur...@googlegroups.com
It's being used standalone (Input/Filter/View), I'm setting it up it from within a new Form object that I have extended. I have a function that sets up my custom filters that runs:

// get new filter
$this->filter = require "vendor/aura/filter/scripts/instance.php";
// set new custom filter
$locator->set('fieldHasValue', function () {
   return new FieldHasValue;
});

when I create a regular form rule ($this->addSoftRule()) using it, it works fine, but when used in the "Any" filter, it can't be found.

Thanks for you help.
Message has been deleted

JH

unread,
Feb 10, 2014, 11:24:39 AM2/10/14
to aur...@googlegroups.com
Here's a basic test script to see how it's being set up and the error I'm getting:

<?php
// composer
require_once('vendor/autoload.php');

use Aura\Input\Builder;
use Aura\Input\Filter;
use Aura\Input\Form;
use Aura\Filter\AbstractRule;

// if another field has a value, this field is marked as valid
class FieldHasValue extends AbstractRule
{
    protected $message = 'FILTER_FIELD_HAS_VALUE';

    public function validate($other_field = null)
    {
        $this->setParams(get_defined_vars());

        // if the other field exists
        if (isset($this->data->$other_field)) {
         // and it has a value assigned
         if ($this->data->$other_field) {
             // mark as valid
            return true;
         }
        }

        return false;
    }

    public function sanitize($other_field = null)
    {
     // do nothing
        return true;
    }
}

class Dummy_Form extends Form {

// load our fields
function init() {
// load custom filters
$filter = $this->setupCustomFilters();
// create field
$field1 = $this->setField('field1','text');
$field2 = $this->setField('field2','radio');
// set options
$field2->setOptions(['1'=>'Yes','0'=>'No']);
// set field 2 to be valid if bool or field1 is filled in - ie field 2 is option if field 1 is filled in
// $filter->addSoftRule('field2',$filter::IS,"fieldHasValue",'field1'); // this works fine when uncommented!
$filter->addSoftRule('field2',$filter::IS,"any",[
["fieldHasValue","field1"],
["bool"]
]); // this fails when run
// set filter message
$filter->useFieldMessage('field2','Field 2 must be filled in or field 1 must be not blank');
}

// setup our custom filters
function setupCustomFilters() {
// get filter
$this->filter = require "vendor/aura/filter/scripts/instance.php";
// set our custom filters
$locator = $this->filter->getRuleLocator();
$locator->set('fieldHasValue', function () {
    return new FieldHasValue;
});
// return filter object
return $this->filter;
}
}

$form = new Dummy_Form(new Builder(),new Filter());
// make a new template object
$template = require 'vendor/aura/view/scripts/instance.php';
// pass form through
$template->form = $form;

if ($_POST) {
// fill form with data
$form->fill($_POST);
// filter the form and see if its' good or not
if ($form->filter()) {
echo 'Good Form';
} else {
echo 'Bad Form, errors are: ';
foreach ($form->getMessages() as $f=>$m) {
echo("Field '$f': $m");
}
}
}

echo '<form method="POST" role="form">';
echo $template->fetch('forms/Dummy_Form/view.php');
echo '<button>Submit</button></form>';

and here is the error:

Fatal error: Uncaught exception 'Aura\Filter\Exception\RuleNotMapped' with message 'fieldHasValue' in /aura-test/vendor/aura/filter/src/Aura/Filter/RuleLocator.php:101

Stack trace:
#0 /aura-test/vendor/aura/filter/src/Aura/Filter/Rule/Any.php(83): Aura\Filter\RuleLocator->get('fieldHasValue')
#1 [internal function]: Aura\Filter\Rule\Any->validate(Array)
#2 /aura-test/vendor/aura/filter/src/Aura/Filter/AbstractRule.php(187): call_user_func_array(Array, Array)
#3 [internal function]: Aura\Filter\AbstractRule->is(Array)
#4 /aura-test/vendor/aura/filter/src/Aura/Filter/RuleCollection.php(362): call_user_func_array(Array, Array)
#5 /aura-test/vendor/aura/input/src/Aura/Input/Fieldset.php(329): Aura\Filter\RuleCollection->values(Object(Dummy_Form))
#6 /aura-test/test.php(89): Aura\Input\Fieldset->filter()
#7 {main} thrown in /aura-test/vendor/aura/filter/src/Aura/Filter/RuleLocator.php on line 101

Hari K T

unread,
Feb 10, 2014, 8:09:16 PM2/10/14
to aur...@googlegroups.com
It seems to me you are doing something wrong.

When you want to create a Form object you want to pass the $filter object. Now in your form init you calls setupCustomFilters which creates another instance of Aura.Filter.

Basically you want to instantiate the Aura.Filter and get the locator and add the new rule.


Eg from my blog post : http://harikt.com/blog/2013/05/21/standalone-forms-and-validation/

use Aura\Filter\RuleCollection;
use Aura\Input\FilterInterface;

class Filter extends RuleCollection implements FilterInterface
{
}


// $filter = require "vendor/aura/filter/scripts/instance.php";
$filter = new Filter();
// You want to register other locators if not registered. Good to use Aura.Di here.

$locator = $filter->getRuleLocator();

$locator->set('fieldHasValue', function () {
    return new FieldHasValue;
});

And pass this to the Form.

Thanks

// get filter
$this->filter = require "vendor/aura/filter/scripts/instance.php";
// set our custom filters
$locator = $this->filter->getRuleLocator();
$locator->set('fieldHasValue', function () {
   return new FieldHasValue;
});
// return filter object
return $this->filter;
}

// retreive the field definition from json file
function loadFields() {
// load custom filters
$filter = $this->setupCustomFilters();
}
}

--

JH

unread,
Feb 11, 2014, 11:13:45 AM2/11/14
to aur...@googlegroups.com
Okay, so I create my filter, get the locator, add my custom filter, and create a new form using an instance of my filter... but I get the same results - I can't use my custom filter when using the 'any' filter:

class Dummy_Form extends Form {

// load our fields
function init() {
$filter = $this->filter;
// create field
$field1 = $this->setField('field1','text');
$field2 = $this->setField('field2','radio');
// set options
$field2->setOptions(['1'=>'Yes','0'=>'No']);
// set field 2 to be valid if bool or field1 is filled in - ie field 2 is optional if field 1 is filled in
// $filter->addSoftRule('field2',$filter::IS,"fieldHasValue",'field1'); // this works fine when uncommented
$filter->addSoftRule('field2',$filter::IS,"any",[
["fieldHasValue","field1"],
["bool"]
]); // this fails when used with any
// set filter message
$filter->useFieldMessage('field2','Field 2 must be filled in or field 1 must be not blank');
}

}

$filter = new Filter(
    new RuleLocator(array_merge(
        require 'vendor/aura/filter/scripts/registry.php',
        ['any' => function () {
            $rule = new \Aura\Filter\Rule\Any;
            $rule->setRuleLocator(new RuleLocator(
                require 'vendor/aura/filter/scripts/registry.php'
            ));
            return $rule;
        }]
    )),
    new Translator(require 'vendor/aura/filter/intl/en_US.php')
);

// set our custom filters
$locator = $filter->getRuleLocator();
$locator->set('fieldHasValue', function () {
    return new FieldHasValue;
});

// pass filter with fieldHasValue to form
$form = new Dummy_Form(new Builder(),$filter);

The errors:

Fatal error: Uncaught exception 'Aura\Filter\Exception\RuleNotMapped' with message 'fieldHasValue' in /aura-test/vendor/aura/filter/src/Aura/Filter/RuleLocator.php:101 Stack trace:
#0 /aura-test/vendor/aura/filter/src/Aura/Filter/Rule/Any.php(83): Aura\Filter\RuleLocator->get('fieldHasValue')
#1 [internal function]: Aura\Filter\Rule\Any->validate(Array)
#2 /aura-test/vendor/aura/filter/src/Aura/Filter/AbstractRule.php(187): call_user_func_array(Array, Array)
#3 [internal function]: Aura\Filter\AbstractRule->is(Array)
#4 /aura-test/vendor/aura/filter/src/Aura/Filter/RuleCollection.php(362): call_user_func_array(Array, Array)
#5 /aura-test/vendor/aura/input/src/Aura/Input/Fieldset.php(329): Aura\Filter\RuleCollection->values(Object(Dummy_Form))
#6 /aura-test/test.php(100): Aura\Input\Fieldset->filter()

Hari K T

unread,
Feb 13, 2014, 2:45:16 AM2/13/14
to aur...@googlegroups.com
Sorry for the delay. Busy with different things.

You are absolutely right here.

This is a bug when you are using any or probably the way it need to be addressed is adding the new rule in the any's RuleLocator.

I have opened a PR https://github.com/auraphp/Aura.Filter/pull/35

Feel free to copy the piece of code until it is merged.

// First rule locator
$locator = $filter->getRuleLocator();

$locator->set('hex', function () {
    return new Hex;
});

$any_rule_locator = $locator->get('any')->getRuleLocator();
$any_rule_locator->set('hex', function () {
    return new Hex;
});

Hope that helps you to fix it.


Hari K T

You can ring me : +91 9388 75 8821

Skype  : kthari85
Twitter : harikt


--

JH

unread,
Feb 18, 2014, 10:02:39 AM2/18/14
to aur...@googlegroups.com
Thanks, but now I get:

Call to undefined method Aura\Filter\Rule\Any::getRuleLocator()

$locator->get('any') does not have a getRuleLocator method, only set.

Hari K T

unread,
Feb 18, 2014, 11:34:02 AM2/18/14
to aur...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages