SitePoint Sponsor

User Tag List

Page 2 of 16 FirstFirst 12345612 ... LastLast
Results 26 to 50 of 384
  1. #26
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    How to we add the state logic and possibly dispatch to the Input Controller? I am beginning to think that plug-in state machines (similar in concept/goals the plug-in Mappers in the Front Controller) is the way to go. That decouples the logic of the page moving it out of the housekeeping and structure code. The goal is that you can write a Controller with any behavior by changing just the state machine with the goal of not having the maximum amount of code outside the state machine. We could supply standard single form and wizard (multi-form sequence) state machines (and the requsite RoR emulator ).
    That quote had me tinkering for a while, and here is what I came up with;

    Basically, filters are rather trivial so let's forget about them and focus on rules and state.
    I figured that the pivot of the ApplicationController is to maintain state. Different states would result in different Handlers. This is in contrast to the FrontController which doesn't rely on state to choose a handler, but rather on the Request. Besides this, the ApplicationController would also need to be able to change state. And the need for changing state could be described through rules.

    So, the ApplicationController would have an array of Validators. When the ApplicationController is executed, it would run through the array and execute the Validators one by one until a Validator fails, or the array is empty. Each time a validator succeeds, the state is updated to reflect the new level.
    This is quite flexible in that allows for any number of states (multiform wizards for example).

    Of course I couldn't resist the urge to actually implement it, so :
    PHP Code:
    /**
      * @implements IHandler
      */
    class ApplicationController
    {
        var 
    $state 'init';
        var 
    $params;
        var 
    $filter;
        var 
    $validators = Array();

        function 
    ApplicationController() {
            
    $this->params =& new DataSpace();
            
    $this->filter =& new FilterChain();
        }

        function 
    addState($name, &$validator) {
            
    $this->validators[$name] =& $validator;
        }

        
    /**
          * @returns   void
          */
        
    function execute(&$request, &$response) {
            if (
    $request->method == 'POST') {
                
    $this->params->import($this->filter->process($request));
                
    $this->state 'submit';
            }

            foreach (
    array_keys($this->validators) as $state) {
                if (
    $this->validators[$state]->validate($this->params)) {
                    
    $this->state $state;
                } else {
                    break;
                }
            }

            
    $handler =& $this->getHandler($this->state);
            
    $handler->execute($this->params$response);
        }

        function & 
    getHandler($state) {
            
    trigger_error("abstract method");
        }
    // end class ApplicationController 
    PHP Code:
    class MyFormController extends ApplicationController
    {
        function 
    MyFormController() {
            
    parent::ApplicationController();
            
    $validator =& new Validator();
            
    $validator->addRule(new RequiredFieldRule("foo"));
            
    $this->addState('valid'$validator);
        }

        function & 
    getHandler($state) {
            switch (
    $state) {
                case 
    'init' : return new ServerPage("forminit");
                case 
    'submit' : return new ServerPage("forminvalid");
                case 
    'valid' : return new ServerPage("formdone");
                default :
                    
    trigger_error("Unknown state '$state'");
            }
        }

    // end class MyFormController 

  2. #27
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    here is what I came up with
    Interesting. I had to think a while to understand how that relates to actual actions, but that could definitely work. So each page set (like 'news') has its own ApplicationController that's set up with the relevant states and the capability to dispatch to an action according to input parameters. That way no single action needs to look after validation, and by proper design new types of ACs (thinking RoR here) will be easy to derive.

    Your code needs to be refined but it's a good start. How do others like it?

    An important design matter: how would composite views be done with an AC like this?
    Last edited by Ezku; Jul 9, 2005 at 10:05.

  3. #28
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    That quote had me tinkering for a while, and here is what I came up with;
    It's good to see some code, but one thing isn't clear to me; what exactly are the ServerPages that are being called at the end? Has somebody implemented that already, or is it still hypothetical?

  4. #29
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    From what I've read of the skeleton thread, I think Kyber's ServerPages are your common garden Page Controllers, it's just the name that has changed, not the responsibility... Kyber?

  5. #30
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees
    It's good to see some code, but one thing isn't clear to me; what exactly are the ServerPages that are being called at the end? Has somebody implemented that already, or is it still hypothetical?
    The handler is created in a hook method in the extending class (MyFormController) so you could return anything which implements the IHandler interface. I just picked ServerPage in the example above.

    Quote Originally Posted by Dr Livingston
    I think Kyber's ServerPages are your common garden Page Controllers
    Yes, pretty much.
    The ServerPage is implemented in the FrontController code (here). It probably should be put in a file for itself, rather than be stuck in with ServerPageMapper.

  6. #31
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ezku
    An important design matter: how would composite views be done with an AC like this?
    I don't think that rendering of composite views has much to do with the ApplicationController - We better leave that for later.

  7. #32
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    From what I've read of the skeleton thread, I think Kyber's ServerPages are your common garden Page Controllers, it's just the name that has changed, not the responsibility... Kyber?
    Ah, I seem to have gotten it a bit wrong there. So ApplicationController is actually yet another layer between FrontController and PageController instead of being a PC in itself. Makes sense, but that means that for every set of pages you have to have an AC, a PC and then the actions themselves.

    We should design our skeleton so that completely skipping the AC part is easy if you don't need the functionality or want it elsewhere. Should be pretty doable since it's merely a chain of Handlers.

    I'm still worried about composite views...

  8. #33
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ezku
    Ah, I seem to have gotten it a bit wrong there. So ApplicationController is actually yet another layer between FrontController and PageController instead of being a PC in itself.
    That's how I understand the concept. But there seems to be a veil of mysticism sorrounding the ApplicationController.

    Quote Originally Posted by Ezku
    Makes sense, but that means that for every set of pages you have to have an AC, a PC and then the actions themselves.
    PageController equals Action in my terminology (Or rather - the Action is a certain type of PageController ... ServerPage is another type). So you would rather have FrontController->ApplicationController->PageController. I tend not to use the term PageController about the latter of the three, since it's actually a bit misleading, but I'm quite sure we mean the same thing by it.

    Quote Originally Posted by Ezku
    We should design our skeleton so that completely skipping the AC part is easy if you don't need the functionality or want it elsewhere. Should be pretty doable since it's merely a chain of Handlers.
    Actually you have that freedom already.
    The FrontController picks a Handler. This Handler could be the final PageController or it could be an ApplicationController.

    Should I post the example in combination with the skeleton code, to show how they work together ?

    Quote Originally Posted by Ezku
    I'm still worried about composite views...
    Sure - And it's an interesting topic. I just think we better deal with the controllers first.

  9. #34
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    PageController equals Action in my terminology.
    But didn't the ServerPage contain three distinct states in your example? Those pretty much translate to actions which makes the ServerPage a PageController in the way that it hosts actions. Making sense?
    Actually you have that freedom already.
    I misphrased my thoughts there; Pretty much, yes, but it's essential not to lose that freedom.
    I just think we better deal with the controllers first.
    It's just that I feel composite views require collaboration from the Controller side of things as well, not just the View. It's admittedly a hard aspect and requires forethought, so perhaps I'll let it pass and see what you can concoct later.

  10. #35
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ezku
    But didn't the ServerPage contain three distinct states in your example?
    Not really - The ApplicationController would instantiate different ServerPage's depending on it's state. The ServerPage is nothing more than a wrapper around an include-call, so it translates to that the ApplicationController would include different pages, depending on it's state.
    There is nothing to hinder the ApplicationController from returning an Action instead of a ServerPage - that's just my arbitrary choice in the specific example.

  11. #36
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm still worried about composite views...
    Don't be...

    The issue regardless of the implementation, is the recursion. Solve the recursion and you have everything stitched up, is the way I see it. Once you have control over the recursion, you can then do what ever you want with the Composites, either as a whole or in part

    It's just that I feel composite views require collaboration from the Controller side of things as well, not just the View.
    Yes, you are correct in that respect. It is difficult to separate the process of generating the Composite structure away from the Application Controller, and I too feel this (Composite View) should be taken into consideration at the moment, before involvement goes any deeper...

    For the most part in my scripts, the Interface for the Application Controllers (basically Observers I suppose) are very close to the renderers.

  12. #37
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    PageController equals Action in my terminology (Or rather - the Action is a certain type of PageController ... ServerPage is another type). So you would rather have FrontController->ApplicationController->PageController. I tend not to use the term PageController about the latter of the three, since it's actually a bit misleading, but I'm quite sure we mean the same thing by it.
    I find the term PageController to be confusing in this context, because it implies a Model 1 architecture. However, it is accurate in the sense that it's a controller that corresponds to a given page. What term would you use to describe a RoR type Controller? It could be considered an ApplicationController, but one that doesn't hand off to an additional action?

  13. #38
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees
    I find the term PageController to be confusing in this context, because it implies a Model 1 architecture. However, it is accurate in the sense that it's a controller that corresponds to a given page. What term would you use to describe a RoR type Controller? It could be considered an ApplicationController, but one that doesn't hand off to an additional action?
    I notice from the comments above that there is the usual confusion about the different Controllers. My general understanding is:

    Page Controller ~ (Front Controller + Application Controller)

    A Page Controller is an all-in-one controller. Most PHP pages are informal Page Controllers, though they don't follow the guidance of the pattern on how to implement it. Any page that has what we would consider a single "controller" is a Page Controller. Common PHP pages like a contactus.php that accepts values from a form and then emails the result is a Page Controller even if it combines the Model and VIew into one big Transaction Script.

    If you want centralize code that is being replicated in every Page Controller, such a Access Control, or if you want a single entry point for many "pages" then you can create a Front Controller that dispatches controllers based on a value in the Request. It seems like as soon as you implement a Front Controller you cannot call the controllers it dispatches Page Controllers even that is generally what they are. That's why Fowler uses the term Input Conroller for controllers that deal with non-"action" parameters. Unfortunately this is exactly what a Page Controller does but stand alone. Hence the confusion because it is somewhat how it is used rather than what it is that counts.

    An Application Controller in some ways acts like a Front Controller in that it can manage multiple "pages". I think the distinction is that the Front Controller makes it's decisions on mappings whereas the Application Controller makes it's decisions using state logic.
    Christopher

  14. #39
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees
    I find the term PageController to be confusing in this context, because it implies a Model 1 architecture.
    Quote Originally Posted by arborint
    I notice from the comments above that there is the usual confusion about the different Controllers. My general understanding is:

    Page Controller ~ (Front Controller + Application Controller)
    Affirmative, and that's what I meant by being misleading. But I couldn't find a better name for it either. What I really meant was the terminal Handler in the dispatch-process. Or as 33degrees put it :
    Quote Originally Posted by 33degrees
    However, it is accurate in the sense that it's a controller that corresponds to a given page.
    So ... we're short of terminology ... Would FinalHandler cover ?

    Quote Originally Posted by 33degrees
    What term would you use to describe a RoR type Controller? It could be considered an ApplicationController, but one that doesn't hand off to an additional action?
    I would claim that the RoR Controller isn't an ApplicationController. It's a collection of one or more logically related FinalHandlers. There might be some ApplicationController logic stuffed into it aswell, but that's just because the ApplicationController hasn't been isolated from the FinalHandler(s). It's probably a design-choice, but it leaves a less flexible structure.

    I should probably add that I only know RoR fairly sporadic by reading the documentation, so I may be wrong about this.

    Quote Originally Posted by arborint
    An Application Controller in some ways acts like a Front Controller in that it can manage multiple "pages". I think the distinction is that the Front Controller makes it's decisions on mappings whereas the Application Controller makes it's decisions using state logic.
    Spot on.

  15. #40
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    That quote had me tinkering for a while, and here is what I came up with;

    Basically, filters are rather trivial so let's forget about them and focus on rules and state.
    I figured that the pivot of the ApplicationController is to maintain state. Different states would result in different Handlers. This is in contrast to the FrontController which doesn't rely on state to choose a handler, but rather on the Request. Besides this, the ApplicationController would also need to be able to change state. And the need for changing state could be described through rules.

    So, the ApplicationController would have an array of Validators. When the ApplicationController is executed, it would run through the array and execute the Validators one by one until a Validator fails, or the array is empty. Each time a validator succeeds, the state is updated to reflect the new level.
    This is quite flexible in that allows for any number of states (multiform wizards for example).
    I think you are definitely heading in the right direction and your code is giving me more ideas about what this thing might be. I think it might be an inversion of the code you implemented though so I need to experiment. The thing I am groping toward is the ability to trigger an event on a pre-registered condition or trigger an event directly.

    Take the Form Controller example:

    'submit'?
    • | -> no -> load values and display
      |
      | -> yes -> are all form values valid?
      • | -> no -> display with error messages
        |
        | -> yes -> save values and forward

    There is a cascade here, but how do we register events to manage that? Are the submit yes/no events the ones triggered by conditions and then the "yes" handler then triggers redisplay or forward events based on the form->isValid() ?
    Christopher

  16. #41
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    The thing I am groping toward is the ability to trigger an event on a pre-registered condition or trigger an event directly.
    (...)
    There is a cascade here, but how do we register events to manage that? Are the submit yes/no events the ones triggered by conditions and then the "yes" handler then triggers redisplay or forward events based on the form->isValid() ?
    It seems that the route is determined by conditions. Each condition may lead to a new condition or to a final Handler. So how about this :
    PHP Code:
    /**
      * @implements IHandler
      */
    class ApplicationController
    {
        var 
    $valid;
        var 
    $fail;

        var 
    $rules = Array();
        var 
    $filter;
        var 
    $method;

        function 
    ApplicationController(&$valid, &$fail$method REQUEST_METHOD_GET) {
            
    $this->valid =& $valid;
            
    $this->fail =& $fail;
            
    $this->method $method;
            
    $this->filter =& new FilterChain();
        }

        
    /**
          * @returns   void
          */
        
    function execute(&$request, &$response) {
            
    $request =& $this->filter->process($request);
            
    $logger =& new Logger();
            if (
    $this->validate($request$logger)) {
                
    $this->valid->execute($request$response);
            } else {
                
    $request->set('errors'$logger->getMessages());
                
    $this->fail->execute($request$response);
            }
        }

        function 
    validate(&$request, &$errorLogger) {
            if (
    $this->method != $request->method) {
                return 
    FALSE;
            }
            
    $valid TRUE;
            for (
    $i=0$l=count($this->rules); $i $l; ++$i) {
                
    $valid $this->rules[$i]->validate($request$errorLogger) && $valid;
            }
            return 
    $valid;
        }

        function 
    addRule(&$rule) {
            
    $this->rules[] =& $rule;
        }
    // end class ApplicationController 
    PHP Code:
    class MyForm extends ApplicationController
    {
        function 
    MyForm() {
            
    $submitHandler =& new ApplicationController(new ServerPage("page/formdone.php"), new ServerPage("page/forminvalid.php"), REQUEST_METHOD_POST);
            
    $submitHandler->addRule(new Rule_Required("foo"));
            
    $submitHandler->addRule(new Rule_Email("foo"));
            
    parent::ApplicationController($submitHandler, new ServerPage("page/forminit.php"), REQUEST_METHOD_POST);
        }
    // end class MyForm 

  17. #42
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Umm...

    Each condition may lead to a new condition or to a final Handler.
    There seams to be a lot of IF/ELSE conditions in the various class methods which I find is a bad choice. My thinking is that each condition in it's self, ie The logic would actually be it's own controller instead?

    As stated earlier there is a cascade/hierarchy structure, so this is how I'd structure it, leaveing the selection process down to a CoR. This I think would be more benifitcial in the event that (via refactoring) at a later date, you could abstract a lot of responsibility to generic classes...

    You could then have the generic controllers high in the hierarchy, and swap in/out controllers that would be more specific to the request at hand, which would be lower down the hierarchy.

  18. #43
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    There seams to be a lot of IF/ELSE conditions in the various class methods which I find is a bad choice. My thinking is that each condition in it's self, ie The logic would actually be it's own controller instead?

    As stated earlier there is a cascade/hierarchy structure, so this is how I'd structure it, leaveing the selection process down to a CoR.
    Yes, CoR also came to my mind after reading arborints post. I would say that the latest post by me implements exactly what you described above.
    The MyForm is an ApplicationController. When executed it will dispatch to a new controller - either a ServerPage (forminit.php) or to another ApplicationController (submithandler). The second ApplicationController (submithandler) will then in turn dispatch to one of two serverpages (formdone.php) or (forminvalid.php). The hierarchy could be made a lot more complex if needed, by simply adding new ApplicationControllers in lieu of a ServerPage.

    The only real limitation of this design is that each ApplicationController could only make a boolean decision (true | false), but as far as I know formal logic any decision could be reduced to a tree of boolean assertions.

    My example probably is a bit messy, since one ApplicationController (MyForm) is created through inheritance, while the other (submithandler) is created through composition. The diagram below should illustrate what is going on.

    Edit:

    Here's the same example, but using composition for creating both ApplicationControllers

    PHP Code:
    class FormController
    {
        var 
    $_submitController;
        var 
    $_formController;

        function 
    FormController(&$initHandler, &$failHandler, &$okHandler) {
            
    $this->_submitController =& new ApplicationController($okHandler$failHandlerREQUEST_METHOD_POST);
            
    $this->_formController =& new ApplicationController($this->_submitController$initHandlerREQUEST_METHOD_POST);
        }

        function 
    addFilter(&$filter) {
            
    $this->_formController->addFilter($filter);
        }

        function 
    addRule(&$rule) {
            
    $this->_submitController->addRule($rule);
        }

        function 
    execute(&$request, &$response) {
            
    $this->_formController->execute($request$response);
        }
    // end class FormController 
    PHP Code:
    class MyForm extends FormController
    {
        function 
    MyForm() {
            
    parent::FormController(
                new 
    ServerPage("page/forminit.php"),
                new 
    ServerPage("page/forminvalid.php"),
                new 
    ServerPage("page/formdone.php")
            );
            
    $this->addRule(new Rule_Required("foo"));
            
    $this->addRule(new Rule_Email("foo"));
        }
    // end class MyForm 
    Edit:

    Reuse ApplicationController from post #41.
    Perhaps the class currently called ApplicationController should be renamed to something like FlowController ?
    Attached Images Attached Images
    Last edited by kyberfabrikken; Jul 10, 2005 at 04:21.

  19. #44
    SitePoint Zealot Overunner's Avatar
    Join Date
    Mar 2004
    Location
    Sweden
    Posts
    180
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just a quick summary to see if I've got the execution flow correct:
    Front Controller -> Application Controller -> Action
    But our framework also supports (or should support) this:
    Front Controller -> Action (for pages which do not have any 'states')
    Quote Originally Posted by kyberfabrikken
    It seems that the route is determined by conditions. Each condition may lead to a new condition or to a final Handler. So how about this :
    (...)
    I get the feeling that your Application Controller code-example there is a bit too specific/concrete (for a base class). My understanding of an AC is that it should act as a state-machine and execute the appropriate Action depending on the state. Therefore, I wouldn't introduce things like form validation in the AC-class; I would leave that to a more concrete AC, like FormController. Instead, I think the AC should concentrate on managing different states. One way to go is perhaps with CoR, as Livingston suggested. I think this is good idea, since it lets ju plug in as many states as you want. For a Form Controller, it is 3 (init, redisplay, complete); for a Multi Form Controller, it is probably more. Here is how I'd use a concrete Form Controller:
    PHP Code:
    class MyFormController extends FormController
    {
      function 
    MyFormController()
      {
        
    $this->addState('init', new InitStateHandler());
        
    $this->addState('redisplay', new RedisplayHandler());
        
    $this->addState('complete', new CompleteHandler());

        
    $this->addRules(new RequiredRule('foo''You must enter something in field foo'));
      }
    }
    // Or...
    class MyFormController extends FormController
    {
      function 
    MyFormController()
      {
        
    $this->addState('init', new ServerPage('initForm.php'));
        
    $this->addState('redisplay', new ServerPage('redisplayForm.php'));
        
    $this->addState('complete', new ServerPage('completeForm.php'));

        
    $this->addRules(new RequiredRule('foo''You must enter something in field foo'));
      }

    Anyhow, just my random thoughts/feelings...I've probably got most of it wrong.

  20. #45
    SitePoint Addict
    Join Date
    Jan 2005
    Location
    Ireland
    Posts
    349
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Overunner
    Just a quick summary to see if I've got the execution flow correct:
    Front Controller -> Application Controller -> Action
    But our framework also supports (or should support) this:
    Front Controller -> Action (for pages which do not have any 'states')
    That is correct (unless I have been following wrong too ).

    Quote Originally Posted by Overunner
    For a Form Controller, it is 3 (init, redisplay, complete); for a Multi Form Controller, it is probably more. Here is how I'd use a concrete Form Controller:
    Is there more possible states for an Application Controller?

    Even for a multi-form, each invidual form would still have only 3 states (init, re-display, complete), and each individual form would have it own ApplicationController. The only difference when it is multi-form, is that the complete state might have more than one state in itself (ie. previous, next), and hence you may have another small controller (a MultiForm controller or something) to decide what to do next.

    There are course important steps to consider when dealing with multi-forms: dependicies (e.g. If in Field 1, 'Yes' was selected over 'No', page x may be skipped, etc), insurance form is taken in sequential steps, etc. However, the current Application Controller shouldn't hinder this.

    What will be needed when working with multi-forms is a session object or similar concept, to keep track of each individual form - although it really depends on the complexity of the form in question.

    I hope I haven't confused matters more so (for myself or anyone else).

  21. #46
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think this is good idea, since it lets ju plug in as many states as you want. For a Form Controller, it is 3 (init, redisplay, complete); for a Multi Form Controller, it is probably more.
    Quickly, there is two ways to attack this. The first is to validate a form as you go from one page (section) to another, and the second method is to validate all the form inputs at the end.

    Doing so the second method is more simpler to implement but is a lot less flexible. Just thought I'd bring that up, as sometimes one method is a requirement and you don't have a choice in the matter

    My understanding of an AC is that it should act as a state-machine and execute the appropriate Action depending on the state. Therefore, I wouldn't introduce things like form validation in the AC-class;
    At the moment I have the choice of using Intercepting Filters for each Composite's Controller, but at the moment they don't do validation of the sort being discussed at the moment.

    What I'm now thinking is that I could in some manner, introduce a filter (IF) to do the validation. So, the pre processing would validate the users inputs, and the post processing would manage the results, by passing the results back to the client script.

    This I think would be more flexible, but I'm not sure about the layering, so I'm still pondering on it. Just another thought...

  22. #47
    SitePoint Addict
    Join Date
    Jan 2005
    Location
    Ireland
    Posts
    349
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here is how I see the current ApplicationController works in connection with the FrontController. Just want to make sure I am visualising the direction being taken correctly.

    This is the FrontController (index.php):
    PHP Code:
    <?php
    error_reporting
    (E_ALL);
    require_once(
    'skeleton.inc.php');

    // the basic ActionMapper simply maps the parameter to a file/class-name
    require_once('ActionMapper.php');
    $controller =& new FrontController(new ActionMapper('action/''home''action'));
    $controller->execute(new Request());
    ?>
    Now, assume the user requests this http://host.com/index.php?action=contact

    Then this is our contact class (action/contact.php):

    PHP Code:
    /* Assume that FormController (post 43), ApplicationController (post 41) and all neccessary rules have been included */
    class contact extends FormController
    {
        function 
    execute(&$request, &$response) {
            
    parent::FormController(
                new 
    ServerPage("page/forminit.php"),
                new 
    ServerPage("page/forminvalid.php"),
                new 
    ServerPage("page/formdone.php")
            );
            
    $this->addRule(new Rule_Email("email"));
            
    $this->addRule(new Rule_Required("subject"));
            
    $this->addRule(new Rule_Required("body"));
            
    parent::execute(&$request, &$response);
        }
    // end class contact 
    And assuming I have coded forminit, forminvalid and formdone, all should be alright.
    Last edited by Ryan Wray; Jul 10, 2005 at 10:52. Reason: Mistake in my thoughts

  23. #48
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You got the FrontController part right, but I don't know what you've done with the Contact class. The following would work :
    PHP Code:
    /* Assume that FormController (post 43), ApplicationController (post 41) and all neccessary rules have been included */
    class Contact extends FormController
    {
        function 
    Contact() {
            
    parent::FormController(
                new 
    ServerPage("page/forminit.php"),
                new 
    ServerPage("page/forminvalid.php"),
                new 
    ServerPage("page/formdone.php")
            );
            
    $this->addRule(new Rule_Email("email"));
            
    $this->addRule(new Rule_Required("subject"));
            
    $this->addRule(new Rule_Required("body"));
        }
    // end class Contact 
    Edit:

    Since I have a working example already, I might aswell post it here. The code is attatched.
    I changed Request and DataSpace a bit. I also added Logger and updated Rules to reflect that. Apart from that, it's genuine Skeleton/FrontController from the CVS@sourceforge.
    I renamed the class ApplicationController to FlowController. Read my comment in the next post for an explanation.
    Attached Files Attached Files
    Last edited by kyberfabrikken; Jul 10, 2005 at 14:24.

  24. #49
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ryan Wray
    What will be needed when working with multi-forms is a session object or similar concept, to keep track of each individual form - although it really depends on the complexity of the form in question.
    Yes, the current code doesn't keep state between requests. The ApplicationController would have to keep state in a session-backed DataSpace - Should be fairly trivial to implement.


    Quote Originally Posted by Overunner
    I get the feeling that your Application Controller code-example there is a bit too specific/concrete (for a base class). My understanding of an AC is that it should act as a state-machine and execute the appropriate Action depending on the state. Therefore, I wouldn't introduce things like form validation in the AC-class;
    Well, it's really request-validation, rather than form-validation. And there isn't far from request to state, qua my reply to Ryan above.

    If there is anything specific about this ApplicationController it's rather that it uses rules to assert the next step. But what would you do instead ?

    Quote Originally Posted by Dr Livingston
    What I'm now thinking is that I could in some manner, introduce a filter (IF) to do the validation. So, the pre processing would validate the users inputs, and the post processing would manage the results, by passing the results back to the client script.
    InterceptingFilter and CoR are more or less synonymes. The ApplicationController I posted in #41 follows this pattern. Each Controller can decide (based on a set of rules) to dispatch to different successors.

    The FormController (post #43) on the other hand, is quite specific to solve a standard form. But you could make all sorts of variations of this by combining multiple ApplicationControllers.

    Off Topic:


    Naming the class in post #41 ApplicationController was probably a mistake. It's really just a utility which the actual ApplicationController makes use of. The FormController is one specific form of an ApplicationController.
    It's too late to go back and edit my posts now, but I should probably have kept the name Validator, or perhaps FlowController as I suggested a few posts back.
    Sorry for the confusion this may cause.

  25. #50
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    My experience is mainly from CakePHP (a Rails-port) and the like, and this seems really odd to me. You all seem to be haphazardly mixing classes and responsibilities together - I have no idea what goes where, much less why or how. The classes would seem awkward and inflexible. Is it just me or is this a cue for taking a step back and rethinking?

    For one, the InputController and ActionController seem to have melted together. The state machine approach is something to think about, but if it means having to settle for something like this, I'll have to decline.

    Just my 0.02e :/


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
  •