SitePoint Sponsor

User Tag List

Page 14 of 16 FirstFirst ... 410111213141516 LastLast
Results 326 to 350 of 397
  1. #326
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    It would be used like this:
    PHP Code:
    $controller =& new InputController();

    $param1 =& $controller->getParameter('field1');
    $param1->addFilter(new MyFilter());
    $param1->addRule(new MyValidator('Error message for Field 1'));

    $controller->processRequest(new Request());
    if (
    $controller->isError()) {
        
    $error_msg_array $controller->getMessage();

    So, RequestMapper dispatches to Action that uses InputController to do these things? Meaning, InputController isn't an extra layer between RM and Action, but something that belongs in the latter?

    The code seems alright to me, but its integration with the rest of our system isn't quite obvious. How about a wider-scoped usage example?

  2. #327
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ezku
    So, RequestMapper dispatches to Action that uses InputController to do these things? Meaning, InputController isn't an extra layer between RM and Action, but something that belongs in the latter?
    I think it could be separate or the front-end to the "Action". The "Action" could be a Controller or something simpler. Either way it would be good to have a structured way to get filtered and validated values from the Request.
    Quote Originally Posted by Ezku
    The code seems alright to me, but its integration with the rest of our system isn't quite obvious. How about a wider-scoped usage example?
    Agreed. The code presented is very small. I posted the code more to show "a way" to do filtering and validation using fairly standard classes.

    The trick with the "wider-scoped usage example" is that this code needs to provide the more complex Application Controller with request information in a structured way. I proposed using an event based state machine as the core of the Application Controller. The reason for this was to hopefully simplify things by making external and internal actions/requests/triggers use the same mechanism. That would mean that the Input Controller's output (selected parameters and errors) should somehow be converted to events or event triggers.
    Christopher

  3. #328
    SitePoint Zealot Overunner's Avatar
    Join Date
    Mar 2004
    Location
    Sweden
    Posts
    180
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Looks very interesting, arborint. I've not studied your code thoroughly yet, but I have a question regarding your form example (example_inputcontroller.php). It seems kinda tedious to write
    PHP Code:
    $param1 =& $controller->getParameter('XYZ'); 
    for every post variable in the form and then apply the neccessary filters and rules. I think it would be much easier to just apply the filters/rules directly.

    Also, I took the liberty to write more extensive rules for your validation code. The rules come with unit tests.
    Attached Files Attached Files

  4. #329
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Overunner
    Looks very interesting, arborint. I've not studied your code thoroughly yet, but I have a question regarding your form example (example_inputcontroller.php). It seems kinda tedious to write
    PHP Code:
    $param1 =& $controller->getParameter('XYZ'); 
    for every post variable in the form and then apply the neccessary filters and rules. I think it would be much easier to just apply the filters/rules directly.
    I made it simple with a setter, but as I said there are many ways to do this. I would like to see other styles. Show and example of what you are thinking.
    Quote Originally Posted by Overunner
    Also, I took the liberty to write more extensive rules for your validation code. The rules come with unit tests.
    Excellent. I noticed that you used rules that take a Datasource and name while I originally did a more generic one that just takes a value. I prefer the simpler one. Do people prefer one over the other? Should we provide both because the Datasource style could simple extend the basic style.

    If people want to do the Datasource route then we should probably make the Request inherit it as well.
    Christopher

  5. #330
    SitePoint Zealot Overunner's Avatar
    Join Date
    Mar 2004
    Location
    Sweden
    Posts
    180
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I made it simple with a setter, but as I said there are many ways to do this. I would like to see other styles. Show and example of what you are thinking.
    How about something like this:
    PHP Code:
    $controller->addFilter(new FilterRegexp('field1''/[^0-9]/'''));
    $controller->addRule(new RuleNotNull('field1''Please enter Field 1'));
    //... 
    Instead of having the controller fetch a specific post variable and apply filters/rules, I apply those directly by specifying the postvariable when I create the filters/rules.
    Or perhaps:
    PHP Code:
    $controller->addFilter('field1', new FilterRegexp('/[^0-9]/'''));
    $controller->addRule('field1', new RuleNotNull('Please enter Field 1')); 
    Excellent. I noticed that you used rules that take a Datasource and name while I originally did a more generic one that just takes a value. I prefer the simpler one. Do people prefer one over the other? Should we provide both because the Datasource style could simple extend the basic style.
    Yes, we should probably get rid of the Datasource. I don't think we will need it. It is btw an (almost) exact copy of the datasource WACT uses

  6. #331
    SitePoint Guru
    Join Date
    Oct 2001
    Posts
    656
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Are we designing a front controller here or a form validator...

  7. #332
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Overunner
    How about something like this:
    PHP Code:
    $controller->addFilter(new FilterRegexp('field1''/[^0-9]/'''));
    $controller->addRule(new RuleNotNull('field1''Please enter Field 1'));
    //... 
    Instead of having the controller fetch a specific post variable and apply filters/rules, I apply those directly by specifying the postvariable when I create the filters/rules.
    Or perhaps:
    PHP Code:
    $controller->addFilter('field1', new FilterRegexp('/[^0-9]/'''));
    $controller->addRule('field1', new RuleNotNull('Please enter Field 1')); 
    I was going for the simplest version the InputController with the Add functionality moved out to the InputControllerParameter class which deals specifically with an individual parameter. But there is no reason why we could not add simplehelper methods to the InputController to do the add directly like:
    PHP Code:
    class InputController {

    // ...

    function addFilter($name$filter) {
        
    $param =& $this->getParameter($name);
        
    $param->addFilter($filter);
    }

    function 
    addRule($name$rule) {
    // or PHP5 style
        
    $this->getParameter($name)->addRule($rule);

    I think this is the kind of stuff we would add as the need arises. Other examples of these handy helper functions might be:
    PHP Code:
    class InputController {

    // ...

    function getParameterValue($name) {
        return 
    $this->chain[$name]->value;
    }

    function 
    getAllParameterValues() {
        
    $values = array();
        foreach (
    $this->chain as $name => $param) {
            
    $values[$name] = $this->chain[$name]->value;
        }
        return 
    $values;

    Quote Originally Posted by Overunner
    Yes, we should probably get rid of the Datasource. I don't think we will need it. It is btw an (almost) exact copy of the datasource WACT uses
    I think if we find it makes sense to use a Datasource class we can add it later and refactor.
    Christopher

  8. #333
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Captain Proton
    Are we designing a front controller here or a form validator...
    We already did a first cut at a Front Controller. It ended up a pretty flexible design based on kyberfabrikken's Dispatcher style Front Controller. I think it's pretty good. We sort of put it aside to have a go at an Application Controller mainly because the Front Controller does not really do very much and everyone kept wanting to add Application Controller and View stuff into it.

    The Input Controller code I posted above is a front-end to an Application Controller. A Form Controller mightr be considered a specific case of an Application Controller.
    Christopher

  9. #334
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Overunner
    PHP Code:
    $controller->addFilter('field1', new FilterRegexp('/[^0-9]/'''));
    $controller->addRule('field1', new RuleNotNull('Please enter Field 1')); 
    This is more like it! But as it occurred to me a while ago - what differentiates filters and rules? I find no apparent reason to separate those two, but you must've had an idea here.

  10. #335
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ezku
    This is more like it!
    Well that's two votes that "add" methods in the controller look better so I will add the code I posted above to the InputController. The thing we need to keep in mind is that we want the Input Controller to also look good to other Controllers (Application, Form, etc.), not necessarily just us. I added the new methods and changed the example. You can download the Input Controller code, examples and tests here .

    Code that does what this code does should be in every PHP application. Filtering and Validation are an essential best practice. A Front Controller is a design choice -- Filtering and Validation are really mandatory. So it would be good if we can come up with some code here that is very flexible and easy for people to use.
    Quote Originally Posted by Ezku
    But as it occurred to me a while ago - what differentiates filters and rules? I find no apparent reason to separate those two, but you must've had an idea here.
    As you noticed the code is almost identical, but they do completely different things. Besides their very different behavior, separating them allows us to write unit tests for each Filter and Rule becaue is critical for security that they work perfectly.

    Filters change the value based on some algorithm. As examples, filters would use preg_replace() to remove invalid characters (see FilterRegexp) or substr() to limit to a maxium length (see FilterLength).

    Rules check a value against some criteria. They return nothing if the check passes. The return an error string you provide if the check fails. As examples, filters would use preg_match() to check for invalid character patterns (see RuleRegexp) or strlen() to check if a value is longer than the maxium length (see RuleLength).
    Christopher

  11. #336
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Overunner
    I took the liberty to write more extensive rules for your validation code. The rules come with unit tests.
    Overunner, can you integrate the rules and tests you posted, but without the DataSource, into the current code (v0.2)? Just increment the version number on the file and post it.
    Christopher

  12. #337
    SitePoint Zealot Overunner's Avatar
    Join Date
    Mar 2004
    Location
    Sweden
    Posts
    180
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Overunner, can you integrate the rules and tests you posted, but without the DataSource, into the current code (v0.2)? Just increment the version number on the file and post it.
    While working on it, I noticed a small design problem. It is not true that every rule is applied to precisely 1 post variable (field). Take MatchRule for instance, which need 2 fields. Hence, this is not possible:
    PHP Code:
    $controller->addRule('field1', new MatchRule('What should I compare field1 against?'); 
    I suggest we should assign the fields to which a specific rule applies to when we create that rule.
    PHP Code:
    $controller->addRule(new MatchRule('field1', ,'field2''Does not match!')); 
    Before I begin to refactor, I want some feedback...

  13. #338
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Overunner
    While working on it, I noticed a small design problem. It is not true that every rule is applied to precisely 1 post variable (field). Take MatchRule for instance, which need 2 fields.
    A valid concern. The latter solution is all I can come up with, yet somehow it isn't quite as elegant...

    With a lot of objects with this kind of functionality, it seems like we'd need a generic data holder object ready to be extended. (What's the Datasource for anyway? I couldn't spot a single reference to it in arborint's latest, except for its existance in rules/datasource.php.)

    PHP Code:
    /**
     *    Name:        Datasource.php
     *    Purpose:    Generic data holder object
     */
    class Datasource
    {
        protected 
    $data = array();
        
        public function 
    set($name$value) { $this->data[$name] = $value; }
        public function 
    get($name$default=NULL) { return (isset($this->data[$name]) ? $this->data[$name] : $default); }
        public function 
    has($name) { return isset($this->data[$name]); }
        
        public function 
    __set($name$value) { $this->set($name$value); }
        public function 
    __get($name) { return $this->get($name); }
    }

    class 
    Request extends Datasource
    {
        (...)
    }

    class 
    InputController extends Datasource
    {
        (...)

    Last edited by Ezku; Jul 4, 2005 at 06:33.

  14. #339
    SitePoint Addict timvw's Avatar
    Join Date
    Jan 2005
    Location
    Belgium
    Posts
    354
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I once wrote such a class, but i called it DataTransferObject...
    http://timvw.madoka.be/programming/p...object.php.txt

    The difference is that the constructor accepts an array with allowed "keys"... This way you can have a factory that generates the dto's considering the user permissions (fe: regular users shouldn't have access to password values..)

  15. #340
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Overunner
    I noticed a small design problem. It is not true that every rule is applied to precisely 1 post variable (field).
    You'll also need to support multi-dimensional (checkboxes, menu lists). At the least 2D.

  16. #341
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff
    You'll also need to support multi-dimensional (checkboxes, menu lists). At the least 2D.
    Isn't this automagically taken care of if the filters and rules have full access to the parameters and it's only up to communicating the necessary instructions on construction?

  17. #342
    SitePoint Guru
    Join Date
    Oct 2001
    Posts
    656
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Can I suggest that you split 1) the logic of deciding if a request is valid - form validation - from 2) the logic that determines what to do - the application controller?

  18. #343
    SitePoint Guru
    Join Date
    Oct 2001
    Posts
    656
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Two other design issues I can think of (because I have encountered these myself):
    - rules may only need to be checked if some other field is validated. For example, one field may only be required when another field is filled in
    - what if you want to internationalize your application without changing the rules? You have hardcoded the error messages here

  19. #344
    SitePoint Zealot Overunner's Avatar
    Join Date
    Mar 2004
    Location
    Sweden
    Posts
    180
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Isn't this automagically taken care of if the filters and rules have full access to the parameters and it's only up to communicating the necessary instructions on construction?
    ...meaning that we should do like this?
    PHP Code:
    $controller->addFilter(new FilterRegexp('field1''/[^0-9]/'''));
    $controller->addRule(new RuleNotNull('field1''Please enter Field 1')); 
    I can rewerite my unit tests to fit this design. Just want to confirm with you guys if this the route we should take.
    Can I suggest that you split 1) the logic of deciding if a request is valid - form validation - from 2) the logic that determines what to do - the application controller?
    I must admit that I'm not sure why arborint put form validation code in the Input Controller. How about moving that code to a more concrete controller like FormController? Input Controller would then be entirely dedicated to determine what to do based on a request.
    - what if you want to internationalize your application without changing the rules? You have hardcoded the error messages here
    I guess this can be easily taken are of:
    PHP Code:
    $controller->addRule(new RuleNotNull('field1'$language[$_GET['lang']]['ruleNotNull'])); 
    ...or anything similar. Of course, you wouldn't access the $_GET variable directly. Anyhow, internationalization is something we can take of later. First we need an application controller

  20. #345
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Captain Proton
    Can I suggest that you split 1) the logic of deciding if a request is valid - form validation - from 2) the logic that determines what to do - the application controller?
    I think that is the plan. The Input Controller just filters and validates. It could be the front end for any controller. The Application Controller would take the results of the Input Controller as its initial triggers/events.
    Quote Originally Posted by Captain Proton
    Two other design issues I can think of (because I have encountered these myself):
    - rules may only need to be checked if some other field is validated. For example, one field may only be required when another field is filled in
    I think using Overrunner's Rules solves this problem.
    Quote Originally Posted by Captain Proton
    - what if you want to internationalize your application without changing the rules? You have hardcoded the error messages here
    You would probably handle that when you passed the message like:
    PHP Code:
    $controller->addRule(new RequiredRule('name'I18N_NAME_ERROR)); 
    Then when displaying the errors do the actual message lookup on errors that actually happened. The errmsg does not have to be a string, but could be an ID.
    Christopher

  21. #346
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Overunner
    I must admit that I'm not sure why arborint put form validation code in the Input Controller. How about moving that code to a more concrete controller like FormController? Input Controller would then be entirely dedicated to determine what to do based on a request.
    It isn't just form validation, it is request validation. This code would (and should) be used for GET parameters as well.

    I think of a Form Controller is a single case version of an Application Controller. A Form Controller is a common example of a controller that would use an Input Controller as a front-end to determine if there were errors. A Form Controller usually has three basic states: initialize (first time / not submitted), redisplay with error messages, and complete with no errors so forward to some other page. The Input Controller gives it the information it needs to make the state decision, but the Form Controller is mainly a form generator and should stay focused on that job.

    Perhaps we should do a Form Controller that uses this Input Controller to demonstrate an example of something that people are familiar with?
    Christopher

  22. #347
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff
    You'll also need to support multi-dimensional (checkboxes, menu lists). At the least 2D.
    The nice thing about this style of filtering and validation is that you can write your own filters and rules to deal with any type of data coming at you. And because the filters and rules are separate you can easily write tests specifically for them as distinct units.
    Christopher

  23. #348
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I changed the code to use Overrunner's Rules. And to think I had talked him out of them! The Datasource is back (for the Validator and Rules) and it allows for MatchRule('field1', 'field2', 'Error Message'). I probably need to revisit the Filter code to make it like the Overrunner's as well (at least renaming), though I don't think using a Datasource for Filters makes as much sense.

    You can download the Input Controller code, examples and tests here.
    Christopher

  24. #349
    SitePoint Zealot Overunner's Avatar
    Join Date
    Mar 2004
    Location
    Sweden
    Posts
    180
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    Perhaps we should do a Form Controller that uses this Input Controller to demonstrate an example of something that people are familiar with?
    Yes, although I think we should first finish the Input Controller. I imagine you'll let the Form Controller inherit from the Input Controller?

    I've changed some minor things in your Validator and Filter classes (btw, I think we should rename the Filter class to FilterChain since it is more descriptive)

    One more thing. I think we should create an abstract base Filter class (for PHP4 version of the framework. For the PHP5 version, I think we should have an interface instead) which all the concrete Filters would inherit from.

    Bedtime now...
    Attached Files Attached Files

  25. #350
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Overunner
    Yes, although I think we should first finish the Input Controller.
    Hopefully everyone interested will take a look at the latest code and find problems, post fixes, improvements, etc.
    Quote Originally Posted by Overunner
    I imagine you'll let the Form Controller inherit from the Input Controller?
    Yes. A Form Controller would inherit the Input Controller classes. It would add code to run "actions" for at least the the three basic states (init, errors and done). This would probably be by dispatching Handlers (as done in the Front Controller). It should control loading initial values from a Datasource/Model and Insert/Update values when done. I suppose it would act as a View Helper of sorts passing on field values and error messages to the View code.

    Quote Originally Posted by Overunner
    I've changed some minor things in your Validator and Filter classes (btw, I think we should rename the Filter class to FilterChain since it is more descriptive)

    One more thing. I think we should create an abstract base Filter class (for PHP4 version of the framework. For the PHP5 version, I think we should have an interface instead) which all the concrete Filters would inherit from.
    Thanks Overrunner, I made the changes you mentioned. I also split up the filtering and validation into their own functions in the Input Controller because processRequest() was getting a little long and someone might want to use them independently.

    Download the Input Controller code, examples and tests here.
    Christopher


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •