|
Administrator
|
Hey, all --
There have been several new sections posted to the 2.0 roadmap that I want to bring to your attention: * Plugins: http://framework.zend.com/wiki/display/ZFDEV2/Plugin+Architectures * Zend_Form: http://framework.zend.com/wiki/display/ZFDEV2/Zend_Form+2.0 * Router: http://framework.zend.com/wiki/display/ZFDEV2/Zend_Controller_router+2.0 Please review and comment when you have time. Thanks! -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ |
|
Ok, my $0.02 (roll your eyes here)
Plugin stuff -- all sounds good... Maybe the "Interface" part of ConfigurableInterface is somewhat redundant.... or might be better as IConfigurable... (I assume this is about being worried that the PHP guys will add a same named interface in the future (ala the Date fiasco)) -- Zend-Form 2.0... I'm not a huge fan of the current (or this proposed) architecture. I'd rather see a component that takes PRG (Post-Redirect-Get) as the default mechanism and extrapolates interfaces from there... There should be strong integration with Zend_Session 2.0, and I'd like to see the Decorators and Translators moved to the view layer -- as they have little to do with the program logic and are purely presentation. The Decorators could be integrated tightly while still being independent of the validation specification. Zend_Form doesn't really need to know if data is coming from an input type=text, a textarea, or a select list... its all strings at the end of the process. I'd also recommend some sort of 'partial' for reusable forms decorator specs. I'm thinking something like this (psuedo, hacked) View (Form Partial); <?php echo new Zend\Form\Field\Text('username') ?> (Or) <?php use \Zend\Form\Field; ?> <?php echo new \Text('username',['elementNameReference']) ?> View (Page) <?php echo \Form('partialName'); ?> Controller: (Action) protected function _getWhateverForm() { $this->form = new \Form($config); $this->form->setSuccessRoute('routename'); // or equivilent set URI, goto, etc $this->form->setValidationErrorRoute('routename'); // or a constant depicting to redirect to self. $this->form->addElement* //... as normal for validators $this->form->setView('partialName'); // <--- where the decoration goes. (Or optionally a hand-coded form) } public function formAction() { if ($this->...->request->isPost()) { $this->form->process(); } else { $this->form->display(); } } Potentially code from _getWhateverForm could find itself in a model for reuse. This is obviously a quick overview, but the idea is to more tightly tie Zend_Form in with the request cycle, assume PRG is the priority method for forms, and treat decoration in the view, not the model or controller. -- The router changes look good as described... Kevin Matthew Weier O'Phinney wrote: > Hey, all -- > > There have been several new sections posted to the 2.0 roadmap that I > want to bring to your attention: > > * Plugins: > http://framework.zend.com/wiki/display/ZFDEV2/Plugin+Architectures > > * Zend_Form: > http://framework.zend.com/wiki/display/ZFDEV2/Zend_Form+2.0 > > * Router: > http://framework.zend.com/wiki/display/ZFDEV2/Zend_Controller_router+2.0 > > Please review and comment when you have time. > > Thanks! > > |
|
Administrator
|
-- Kevin McArthur <[hidden email]> wrote
(on Tuesday, 17 November 2009, 10:34 AM -0800): > Ok, my $0.02 (roll your eyes here) > > Plugin stuff -- all sounds good... Maybe the "Interface" part of > ConfigurableInterface is somewhat redundant.... or might be better > as IConfigurable... (I assume this is about being worried that the > PHP guys will add a same named interface in the future (ala the Date > fiasco)) This is already in our coding standard, and was part of the original framework interop meeting. There are comments regarding this on the main roadmap page if you need the rationale. > -- > > Zend-Form 2.0... I'm not a huge fan of the current (or this > proposed) architecture. I'd rather see a component that takes PRG > (Post-Redirect-Get) as the default mechanism and extrapolates > interfaces from there... PRG is something that can be built around forms, but has nothing to do with the main purpose of the form component, which is to encapsulate form element metadata and validation, and to facilitate rendering. PRG is something you'd handle in your controller. We should not be tightly binding forms and controllers; they should remain loosely coupled (if at all coupled). > There should be strong integration with Zend_Session 2.0, and I'd like > to see the Decorators and Translators moved to the view layer -- as > they have little to do with the program logic and are purely > presentation. Which, as I note in the proposal, is the plan. :) > The Decorators could be integrated tightly while still being > independent of the validation specification. Zend_Form doesn't really > need to know if data is coming from an input type=text, a textarea, or > a select list... its all strings at the end of the process. Which is a driving part of the redesign; sounds like we're in agreement. :) There may still be discrete element types, as this makes some strategies for decoration easier, but the basics are that the form and form elements are simply metadata containers, and you then attach filter and validation chains, or pass them through decorator chains. > I'd also recommend some sort of 'partial' for reusable forms decorator > specs. This can be achieved already via the ViewScript decorator, which simply passes the "element" to a partial. This will be retained. <snip> > This is obviously a quick overview, but the idea is to more tightly > tie Zend_Form in with the request cycle, assume PRG is the priority > method for forms, and treat decoration in the view, not the model or > controller. As noted, I don't think PRG has anything to do with the forms, but everything to do with controllers, and should be treated there. It's already trivially easy to accomplish. > The router changes look good as described... > > > Kevin > > > > Matthew Weier O'Phinney wrote: > >Hey, all -- > > > >There have been several new sections posted to the 2.0 roadmap that I > >want to bring to your attention: > > > > * Plugins: > > http://framework.zend.com/wiki/display/ZFDEV2/Plugin+Architectures > > > > * Zend_Form: > > http://framework.zend.com/wiki/display/ZFDEV2/Zend_Form+2.0 > > > > * Router: > > http://framework.zend.com/wiki/display/ZFDEV2/Zend_Controller_router+2.0 > > > >Please review and comment when you have time. > > > >Thanks! > > > -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ |
|
Inline.
The issue is that Zend_Form and PRG being so loosely coupled makes it a real pain to do PRG, and sadly results in most people who use Zend_Form not doing PRG (not good for anyone). The biggest issue comes from when validators add error messages, and fields need to remember their values. Currently this has to be manually saved to each field, and the controllers quickly become unwieldy. There's a prop for prg (and multi-page forms)... but I'm not sure how that integrates into 2.0 here....PRG is something that can be built around forms, but has nothing to do with the main purpose of the form component, which is to encapsulate form element metadata and validation, and to facilitate rendering. PRG is something you'd handle in your controller. We should not be tightly binding forms and controllers; they should remain loosely coupled (if at all coupled). PRG can be handled in the controller, but when you start doing that you really lose any value that ZFORM adds -- I pretty much just use Zend_Validate/Zend_Filter_Input on its own these days because ZFORM adds so little value in the the PRG context. I really think that a PRG scenario, and a simplification on how this works currently should be added to the 2.0 map -- even if you wont accept PRG as a default scenario [which I think it should be as get forms are usually treated as parameters, and most forms are therefore posted statefully] Using PRG _should_ be as easy as not using it, and the Zend_Session/FlashMessenger/SaveState stuff should all be handled in the core classes as its really laborious to do it in the controllers, and for the most part, totally redundant and unnecessary. Trivial is relative I suppose. The tying in of Zend_Form with Zend_Session to remember state, validation errors and flash messenger with the controller layer to glue it together, its not trivial enough. Most of the forms examples don't do PRG, and last I checked its not even the quickstart recommended method. (http://framework.zend.com/docs/quickstart/create-a-form doesn't redirect on failure for example) ... the docs follow in the same vain. What I'm recommending is for 2.0 is that PRG become 'the' way to do post forms in ZFW 2.0. Or at least, a heck of a lot less terse in terms of the coding required. Lets integrate Session/FlashMessenger/Routing/Controllers into a comprehensive 'forms' solution -- it'll result in better outcomes for deployed applications. There's already some unimplemented support in the 1.0 model in terms of state saving... so its been on the radar... Kevin |
|
Administrator
|
-- Kevin McArthur <[hidden email]> wrote
(on Tuesday, 17 November 2009, 11:44 AM -0800): > Inline. > > PRG is something that can be built around forms, but has nothing to do > with the main purpose of the form component, which is to encapsulate > form element metadata and validation, and to facilitate rendering. PRG > is something you'd handle in your controller. We should not be tightly > binding forms and controllers; they should remain loosely coupled (if at > all coupled). > > > The issue is that Zend_Form and PRG being so loosely coupled makes it a real > pain to do PRG, and sadly results in most people who use Zend_Form not doing > PRG (not good for anyone). The biggest issue comes from when validators add > error messages, and fields need to remember their values. Currently this has to > be manually saved to each field, and the controllers quickly become unwieldy. > There's a prop for prg (and multi-page forms)... but I'm not sure how that > integrates into 2.0 here.... > > PRG can be handled in the controller, but when you start doing that you really > lose any value that ZFORM adds -- I pretty much just use Zend_Validate/ > Zend_Filter_Input on its own these days because ZFORM adds so little value in > the the PRG context. > > I really think that a PRG scenario, and a simplification on how this works > currently should be added to the 2.0 map -- even if you wont accept PRG as a > default scenario [which I think it should be as get forms are usually treated > as parameters, and most forms are therefore posted statefully] Are we talking about the same thing? We're either not, or you're using Zend_Form and Zend_Controller very differently from anyone I've ever talked to. As an example of what I'm talking about: class FooController extends Zend_Controller_Action { public function barAction() { $form = new SomeForm(); $request = $this->getRequest(); if ($request->isPost()) { // POST request; validate form if (!$form->isValid($request->getPost())) { // Invalid; redisplay with errors $this->view->form = $form; return; } // Valid; update model, and REDIRECT $model = new SomeModel(); $id = $model->create($form->getValues()); return $this->_helper->redirector('item', 'foo', 'default', array( 'id' => $id, )); } // Display form $this->view->form = $form; } } The above does most aspects of PRG, and all those steps would be necessary regardless of how Zend_Form works; you're marshalling input, and deciding how to respond. If you're wanting redirection on failure, I'm not entirely sure I see the point; you'd get the same exact result as before. Most literature on PRG actually indicates that the Redirect/Get are only really necessary for _successful_ actions, not those resulting in validation errors. The work done for multi-page form support would make PRG for error cases trivially possible, however, and maintains the loose coupling between Zend_Form and the other MVC components by pushing this interaction into an action helper. This is the preferred approach, as keeping the components isolated makes them easier to test and repurpose. (As for the multi-page form support, unfortunately, the contributor has had no time to complete that component. If somebody is willing to step up and work on it, I'm sure the help would be welcome.) Forms do have use-cases outside of HTTP -- I personally want to work up a version that utilizes ncurses and/or readline so as to create CLI-based forms -- where PRG would have absolutely no meaning whatsoever. > Using PRG _should_ be as easy as not using it, and the Zend_Session/ > FlashMessenger/SaveState stuff should all be handled in the core classes as its > really laborious to do it in the controllers, and for the most part, totally > redundant and unnecessary. Regarding your comments on sessions... those *are* core classes, can be used with or without the MVC, and are as simple as instantiating and using objects. I'm really needing some examples here if I'm going to understand what you're getting at. > This is obviously a quick overview, but the idea is to more tightly > tie Zend_Form in with the request cycle, assume PRG is the priority > method for forms, and treat decoration in the view, not the model or > controller. > > > As noted, I don't think PRG has anything to do with the forms, but > everything to do with controllers, and should be treated there. It's > already trivially easy to accomplish. > > > Trivial is relative I suppose. The tying in of Zend_Form with > Zend_Session to remember state, validation errors and flash messenger > with the controller layer to glue it together, its not trivial enough. > > Most of the forms examples don't do PRG, and last I checked its not > even the quickstart recommended method. ( > http://framework.zend.com/docs/quickstart/create-a-form doesn't > redirect on failure for example) ... the docs follow in the same vain. See my above notes. If you apply the RG portion of PRG to simply the success responses, then it's already easily and readily supported. If you want to apply it to *all* form responses, then we need some more infrastructure -- but that is not difficult to achieve. We simply need a proposal (BTW, there is no PRG proposal, just the multi-page form proposal). > What I'm recommending is for 2.0 is that PRG become 'the' way to do post forms > in ZFW 2.0. Or at least, a heck of a lot less terse in terms of the coding > required. Lets integrate Session/FlashMessenger/Routing/Controllers into a > comprehensive 'forms' solution -- it'll result in better outcomes for deployed > applications. There's already some unimplemented support in the 1.0 model in > terms of state saving... so its been on the radar... Let's discuss this from a use cases perspective -- if you can provide some examples of how you envision it working, we can start creating a proposal, or work from the existing multi-page form proposal. -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ |
|
<snip> > > Are we talking about the same thing? Maybe not... When I use PRG I mean it to be any page the user _sees_ is the result of a get action --- always --- Errors, Success, Username taken... etc. This is essential in avoiding the 'this page has expired', repost/cancel dialog. In a modern environment with sessions as accessible as they are now, there's really no reason not to do this. > We're either not, or you're using > Zend_Form and Zend_Controller very differently from anyone I've ever > talked to. There's lots of guys like me ;) [and a few more who read my book , and do it the way I describe in there, which is PRG but without the form data state save] [code for (listing 15-16)] public function addAction() { $request = $this->getRequest(); //Determine if processing a post request if($request->isPost()) { //Filter tags from the name field $filters = array( 'name' => 'StripTags' ); //Validate name is not less than 1 character and not more than 64 $validation = array( 'name' => array ( array('StringLength', 1, 64) ) ); //Initialize Zend_Filter_Input (ZFI) passing it the entire getPost() array $zfi = new Zend_Filter_Input($filters, $validation, $request->getPost()); //If the validators passed this will be true if ($zfi->isValid()) { //Fetch the data from zfi directly and create an array for Zend_Db $clean = array(); $clean['name'] = $zfi->name; //Create an instance of the customers table and insert the $clean row $customers = new Customers(); $customers->insert($clean); //Redirect to the display page after adding $this->getHelper('redirector')->goto('index'); } else { //The form didn't validate, get the messages from ZFI foreach($zfi->getMessages() as $field=>$messages) { //Put each ZFI message into the FlashMessenger so it shows on the form foreach($messages as $message) { $this->getHelper('FlashMessenger') ->addMessage($field . ' : '. $message); } } //Redirect back to the input form, but with messages $this->getHelper('redirector')->goto('add'); } } //Not a post request, check for flash messages and expose to the view if($this->getHelper('FlashMessenger')->hasMessages()) { $this->view->messages = $this->getHelper('FlashMessenger')->getMessages(); } //The view renderer will now automatically render the add.phtml template } [/code] So thats a basic error-state prg... but normally I also add in a Zend_Session object around where I enqueue the error messages into the flashmessenger. On the display side, I manually pull from the session and repopulate the form saved values. That looks like: [code, pseudo] public function addAction() { $request = $this->getRequest(); //Determine if processing a post request if($request->isPost()) { //Filter tags from the name field $filters = array( 'name' => 'StripTags' ); //Validate name is not less than 1 character and not more than 64 $validation = array( 'name' => array ( array('StringLength', 1, 64) ) ); //Initialize Zend_Filter_Input (ZFI) passing it the entire getPost() array $zfi = new Zend_Filter_Input($filters, $validation, $request->getPost()); //If the validators passed this will be true if ($zfi->isValid()) { //Fetch the data from zfi directly and create an array for Zend_Db $clean = array(); $clean['name'] = $zfi->name; //Create an instance of the customers table and insert the $clean row $customers = new Customers(); $customers->insert($clean); //Redirect to the display page after adding $this->getHelper('redirector')->goto('index'); } else { //The form didn't validate, get the messages from ZFI foreach($zfi->getMessages() as $field=>$messages) { //Put each ZFI message into the FlashMessenger so it shows on the form foreach($messages as $message) { $this->getHelper('FlashMessenger') ->addMessage($field . ' : '. $message); } } $session = new Zend_Session_Namespace('nameofform'); $session->nameField = $zfi->name; //Redirect back to the input form, but with messages $this->getHelper('redirector')->goto('add'); } } //Not a post request, check for flash messages and expose to the view if($this->getHelper('FlashMessenger')->hasMessages()) { $this->view->messages = $this->getHelper('FlashMessenger')->getMessages(); } $session = new Zend_Session_Namespace('nameofform'); $this->view->nameField = $session->nameField; //The view renderer will now automatically render the add.phtml template } [/code] ... add in a big form (this is for one field)... and this gets rather terse to do for each form... <snip> > > > The above does most aspects of PRG, and all those steps would be > necessary regardless of how Zend_Form works; you're marshalling input, > and deciding how to respond. I think the most important part of PRG is in-fact on failure. If you're just going forward, you're not going to get to that expired state anyway. With this approach I've been able to make multi-stage shopping cart checkouts that can gracefully handle the back/forward button being clicked, and portions of a multi-stage form resubmitted, without breaking everything or confusing the user with state expired pages. > > If you're wanting redirection on failure, I'm not entirely sure I see > the point; you'd get the same exact result as before. Most literature on > PRG actually indicates that the Redirect/Get are only really necessary > for _successful_ actions, not those resulting in validation errors. Its important for an error state as when confronted with an error, users often hit the back button, and then state gets really messed up if they do or dont repost... and such. The flow charts can get really nasty if you don't follow the 'display only as a result of get' rule. > > The work done for multi-page form support would make PRG for error cases > trivially possible, however, and maintains the loose coupling between > Zend_Form and the other MVC components by pushing this interaction into > an action helper. This is the preferred approach, as keeping the > components isolated makes them easier to test and repurpose. (As for > the multi-page form support, unfortunately, the contributor has had no > time to complete that component. If somebody is willing to step up and > work on it, I'm sure the help would be welcome.) I've been tracking this, hoping it would be the solution to PRG. I hadn't realized it had died on the vine. I'm happy to work on the architecture with you guys if there's interest. > > Forms do have use-cases outside of HTTP -- I personally want to work up > a version that utilizes ncurses and/or readline so as to create > CLI-based forms -- where PRG would have absolutely no meaning > whatsoever. That would be cool... not sure what the ecosystem looks like when we start talking about forms processing in abstract terms tho. I've wanted to get some forms stuff setup for put and delete requests too, but those have their own caveats too. > >> Using PRG _should_ be as easy as not using it, and the Zend_Session/ >> FlashMessenger/SaveState stuff should all be handled in the core classes as its >> really laborious to do it in the controllers, and for the most part, totally >> redundant and unnecessary. > > Regarding your comments on sessions... those *are* core classes, can be > used with or without the MVC, and are as simple as instantiating and > using objects. I'm really needing some examples here if I'm going to > understand what you're getting at. > It's not complicated at current, but its terse and undocumented. You can see the examples above, but it really comes down to the state-saving, and integration with all the objects that are in play. It would also solve your multi-page forms requirement as a by-product really. > > See my above notes. If you apply the RG portion of PRG to simply the > success responses, then it's already easily and readily supported. If > you want to apply it to *all* form responses, then we need some more > infrastructure -- but that is not difficult to achieve. We simply need a > proposal (BTW, there is no PRG proposal, just the multi-page form > proposal). Should be applied to all IMHO. Its a rule in my shop that all pages a user sees is a result of a get request -- never post. > >> What I'm recommending is for 2.0 is that PRG become 'the' way to do post forms >> in ZFW 2.0. Or at least, a heck of a lot less terse in terms of the coding >> required. Lets integrate Session/FlashMessenger/Routing/Controllers into a >> comprehensive 'forms' solution -- it'll result in better outcomes for deployed >> applications. There's already some unimplemented support in the 1.0 model in >> terms of state saving... so its been on the radar... > > Let's discuss this from a use cases perspective -- if you can provide > some examples of how you envision it working, we can start creating a > proposal, or work from the existing multi-page form proposal. > I hope this is a good first step -- if you want to take the discussion off-list and onto the tracker, just lemme know where. Kevin Matthew Weier O'Phinney wrote: -- Kevin McArthur [hidden email] wrote (on Tuesday, 17 November 2009, 11:44 AM -0800): |
|
In reply to this post by weierophinney
On Tue, Nov 17, 2009 at 6:37 PM, Matthew Weier O'Phinney <[hidden email]> wrote: I commented on this page about plugin creation. There are no guidelines for the construction process? I think automated Dependency Injection is the way to go.Hey, all -- -- Giorgio Sironi Piccolo Principe & Web Engineer http://giorgiosironi.blogspot.com http://twitter.com/giorgiosironi |
| Powered by Nabble | Edit this page |
