Handling validation errors in different controllers - php

I'm fairly new to cakephp, so I may just be setting things up wrong here.
I have created a simple blog with comments and posts (among other things).
I can add Comments while viewing a Post which submits back to the Comments controller (/controllers/comments/add).
The problem that I am running into is that when there are validation errors, it displays them in the /views/comments/add view, rather than the view where I was adding the comment /views/posts/view.
This has to be a pretty common thing to do I'd think, where am I going wrong?

You can ask the add method of the comments controller to render a different view:
$this->render('/Posts/view');
But then of course you'll need to make sure all the data that the 'Posts/view/' file needs is collected and set by the add method of the Comments controller.
Instead, what I would do is just make the comment form submit via AJAX (you know about AJAX?). That way, you can render the Comments/add view (or the appropriate part of it) without refreshing the rest of the page.
Of course, users with Javascript disabled will still have to go to a different page to correct their errors. But that shouldn't happen often, and you can always just redirect them back to the Posts page once they successfully submit their comment.
If you're new to CakePHP, and you're going to use AJAX, you'll probably want to use something like this somewhere:
if ($this->request->is('ajax')) {
$this->render('/Elements/ajax_comment_form');
}
// If it's not AJAX it'll fall through and show the regular comment add.ctp view

Related

PHP MVC Form Submission

I have a question related to form submission done in PHP application that's built in MVC architecture (self-written framework).
All examples that I've seen so far (including existing back-end frameworks) work this way that once form for adding record to database is submitted then certain method of controller is executed [say i.e. addRecord()], which triggers method of appropriate model. If everything goes OK then record is added and controller's method [addRecord() in this example] renders view of "index" page that displays table with records from database.
What I would like to achieve is to render view with form used to add records (the same that I used to add first record) instead of "index". Obviously I can do it easily by just rendering appropriate view from addRecord() (view with the form).
But the tricky point is when you check url you'll see the following:
The first time you enter it will be i.e.
http://project_name/my_controller/create
Once first form was submietted and you return to the view from addRecord() method then url will be:
http://project_name/my_controller/addRecord
What I would like to see is return to the original url, that is http://project_name/my_controller/create
Not sure if this is clear?
PS. Of course I could use AJAX call for form submission (that way I will stay at the same page) but perhaps it's possible to achieve the same without AJAX.
Thanks in advance,
On the controller you will want to submit to the addRecord route and do the processing. Have a check to make sure it was successful and on successful submission you can redirect back to the create route.
It is hard to give an example since you are using a custom made framework. I use slim which has a redirect method for a route. If what you have made does not have something like that then using should do the trick.
header('Location: '.$createUrl);
die(); //or exit

WordPress $_POST variables disappear completely on form submission

I have created a page template in WordPress to display a form with action="". Very simply, it will not post any of the form data upon submission. I have tried var_dump($_POST) but it just gives me array(0) {} every single time. I've tried examples provided by some websites for creating a form, but I can't reproduce the same results.
I have thoroughly search for answers to this problem but nothing seems to work. It must be something internal or very advanced. I just want to know why my form data won't post and where it might be going.
Check your data using a non-WP page, meaning put a php file in web-root, and have the form action point to it, such as ...action="/formtest.php", and on that page:
<?php
var_dump($_POST);
?>
This will test if you really aren't getting the POST vars. Then, since you'll 99% likely find they ARE being posted, the likely trouble is that your page IS being redirected somewhere by the theme as mentioned elsewhere (e.g. my theme includes a hook on 'template_redirect'...).
If you are theme savvy and just looking for a quick fix- at the expense of losing it on theme upgrade- you can create an exception just for your temp.php page, but the way that many developers handle it is via Plugins, or handle your form via Ajax. Many others have encountered this same issue, and so, either tacking on code to a Plugin, or performing in-page Ajax (since you are submitting to SELF anyway...).
This page will give you a leg-up on WP Ajax, it's a reputable and well written doc.

CodeIgniter - Login form on each page

Ive run into a little problem with an application im trying to write with CodeIgniter, basically i want to have a login form on each page up the very top of the site, but im finding it difficult to figure out the logic with the validation function.
From my understanding, the validation rules ( set_rules ) have to be set from the controller, now if i want a login form on each page, does this mean i have to set the rules on each and every controller i write? this seems a little odd. can i set the validation rules from inside the view?
What i have at the moment is one view for the login box, which i call from my view with the
<?php $this->load->view('includes/members_login'); ?>
command.
Any help or guidance on this would be great .... im quite stuck.
Cheers,
No, you only have to set the rules in the controller function that recieves/processes the login form. I generally keep a dedicated "Auth" controller to execute related operations like login/logout/reset password/etc...
for layout, you can just include it in the consistant header, but just point the form at your controller/function that processes the login.
For login forms though, I'm not sure why you'd want to "validate" them. Either the user/pass matches up or it doesn't.
One idea that comes on my mind is to create basic layout for all of your pages which will load lets say 5,6 other files and build view for each page.
Some of these parts will be called on every page, like header, navigation... so you can use your login form in these parts and it will be loaded on every request.
I think you should try something like AJAX via javascript to authenticate any user login. Basically the login button would be handled by an onclick event which would get the details of the button and pass it to your "Auth" (or Login or maybe UserAuth - up to you to decide) controller which would do the validation..
If you really want the login form on every page, you could create your own My_Controller and do the form validation in the constructor. Alternatively, as you said, you can do it in the view also. CI doesn't force adherence to MVC. If putting the code into your view would make for quicker development and easier maintenance, there is no reason not to do so.

Action called from many other places, how to handle a "Back" button?

I have an action (view for example) in a controller that is called from multiple other actions in other controllers. How is the best way to create a "Back" button that will take me back to the page that got me here?
I've used named parameters like "back_controller" and "back_action" and that works fairly well but they get awkward when the page has a form that gets submitted. I have to be sure to pass those parameters as hidden fields or in the form url and then look for them after the form has been processed.
Is there some kind of stack or other solution that anyone else has come up with that handles this situation better? I see this problem in a lot of my projects and I've yet to come up with a good solution.
I don't completely understand your question, but this may be helpful:
If you need to redirect to the referer page you can use:
$this->redirect($this->referer());
http://book.cakephp.org/view/425/redirect
I don't believe in back buttons. That is a feature that the browser does quite well and you would be better off having buttons always taking you to specific destinations rather than back.
If you must have a back button, you could create a history stack in the session. When a page loads you just push that page on the history (you will want to make sure you don't push the same page on the stack multiple times). You could create URL like /back who's sole job is to redirect the user to the last page they were on.
$_SERVER['HTTP_REFERER']

Action View Helper in Zend - Work around?

I'm working on building up an interface that I want to function as a "tabbed browsing" sort of function. Each of these tabs has already been written as an action and the tabbed interface works fine as links to the individual tabs. I decided to try writing the "index" page for this controller - putting the content of all the tabs into hidden divs and swapping between them with jQuery, but once I started to use the action view helper - I ran into a lot of people saying that its bad practice. (see this article)
Some of these actions build up forms - grab some data from the model, etc to display. I want each of the actions to continue to function on their own (some parse forms as well).
Browsing to /item should give you the tabbed menu, plus all of the div's contents in a hidden tag - where /item/tab2 is a specific action (form submit for instance).
Another complication/caveat - Some of the actions will throw Access Exceptions if the user doesn't have access to that "tab". I'd prefer not to build access checking into the system twice (thus showing a tab with empty content).
I'm just trying to figure out what the best practice is to handle this sort of thing, and I thought that the action helper might be it. If I try to use View Helpers - I start wondering if that is the right place to assemble a Zend_Form.
Does anyone have any suggestions on the "proper" way to work around not using the Zend_View_Helper_Action ?
The Correct way to work around the action view helper, as I stated in the article you cited, is to create partials which access the model directly to fetch the data they need. This can be through a view helper (you make this yourself ;)) if this would involve a lot of logic in your view.
The action view helper is plagued with more than just performance issues, but also creates horrendous debugging nightmares, and if you need it, then your application is probably not following MVC, and therefore, you are using the controller for reuse, instead of the model, which is the patterns intention.
You can render partials from within your layout or current actions view with the render or partial methods of the view object.
If you have multiple actions to deal with multiple possible posts from your tabs, then you should set all of these actions to render the same view script, which will then render all of the tabs with data direct from the model.
If you're not generating the tab/tab panes from existing markup, and you're loading the content on demand, then you simply must check whether the user has permission to access the tab before displaying the tab itself, and again when attempting to load the tab's content.
Checking whether the user has these access permissions should be an acceptable mode of operation and should not be expensive to perform.
If these actions produce content that works in some standalone page, in addition to the tabs, then the Action view helper is the corrent way to proceed. Simply perform the same ACL (or other) check performed in the action when generating the tab.
I'm not entirely sure what your exact problem is, however you can disable the layout:
$this->_helper->layout->disableLayout();
Then the requested Action will just display it's view script, which you can load into the tab.
Any authorisation code you have will function as normal and you can display the requested view script for the Action, or not depending on if they have access.
You can catch any access exceptions by using a try/catch block:
try { // action throwing exceptions } catch (Exception $e) { // catch silently }

Categories