Sending Errors Back to Form: Code Igniter - php

I'm having trouble getting the form validation library to send my form errors back to my form in this case.
I have a controller that handles uploading images called addImage.php. This controller only handles the do_upload processing. I have a view called uploadimage.php that contains the upload form and submits to /addImage/do_upload.
The upload form is loaded on the front page of my website using a template in code igniter using
<?php $this->load->view('uploadimage'); ?>
The front page controller is contained in home.php
Right now after validation fails, I'm just redirecting to the homepage which clearly doesn't load the errors back (in addImage.php)
if($this->_submit_validate() == FALSE)
{
redirect('/', 'location');
return;
}
How can I redirect to my template_front.php while keeping those errors. Can I somehow call my home.php controller from the uploadimage.php controller to do this? I've confused myself trying to explain it! If this is totally unclear, let me know and I'll try to clarify.

Per the Documentation, you are suppose to simply re-load the view file on failure.
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
else
{
$this->load->view('formsuccess');
}
a redirect generates a new server request which flushes the validation error information.

on validation failure you should reload the form. May be you want to add a button to concel uploading.
On the view, you should add some tag to show errors (there are lots of info about validation helpares) like in:
<?=form_open_multipart("/personas/savefoto", array('class' => "form3") )?>
<h3><?=$heading?></h3>
<div class="center">
<?php echo '<strong>'.mb_convert_case($record['nombre'].' '.$record['apellido1'].' '.$record['apellido2'], MB_CASE_TITLE).'</strong><br/>';
if( file_exists("fotos/e".MATRIZ."/b".$record['id'].".jpg")){
?>
<img class="foto" src="<?php echo base_url()."fotos/e".MATRIZ."/b".$record['id']?>.jpg"/>
<br/><br/>
<?php
} ?>
</div>
<div class="form-row">
<label for="imagen">Nueva imagen <br/>(jpg, gif o png)</label>
<input type="file" name="userfile" size="20" />
<br/>
<?php if(isset($error_image)) echo '<p class="error">'.$error_image.'</p>'; ?>
</div>
<div class="form-row center">
<input type="submit" value="Aceptar" />
<input type="button" value="Cancelar" onclick="location.href='/system.php/personas/admin';">
</div>
<?=form_close();?>
look for the if(isset($error_image))

You could utilize the validation_errors() function and set them to a session variable
$this->session->set_userdata(array('form_errors', validation_errors()));
then access them on your redirect page.
echo $this->session->userdata('form_errors');
$this->session->unset_userdata('form_errors'); // prevent them from being stored past use

Related

How to run a function through my plugin page and print the result on that same page

I'm currently trying to add a debug page to my website. This page is simply dedicated to running some of the tasks done by my plugin and outputting some results on the same page.
I currently have a separate page in my Wordpress admin, this page contains a form and button that should be linked to a function that will do various steps and then return a value that must be printed on that page.
Here's the current code for the page and button :
function actu_admin_menu_option()
{
add_menu_page('Scripts', 'Sahar actus plugin', 'manage_options', 'actu-admin-menu', 'actu_scripts_page', '', 200);
}
add_action('admin_menu', 'actu_admin_menu_option');
// HTML page of the plugin
function actu_scripts_page()
{
?>
<div class="wrap">
<h2>Sahar actus plugin</h2>
<form action="<?php echo admin_url('admin-post.php'); ?>" method="post">
<input type="hidden" name="action" value="start_test">
<input class="button button-primary" type="submit" value="Start test">
</form>
</div>
<?php
}
function start_test()
{
return ("test started!");
}
add_action( 'admin_post_start_test', 'start_test' );
What I would like is for example to run the following function when clicking on the button and then outputting the returned value on the page.
function start_test()
{
return("test started!");
}
So when I press the button I want "test started!" to be printed on the page, currently clicking on the button redirects me to /wp-admin/admin-post.php which is a blank page.
I have no idea what is the best course of action to do it, should I make an ajax request on my button to run the function and then get the return value from that ajax call ? Or is there a better way to go about this ?
Thanks for helping me, have a great day
EDIT : Updated code, no errors but output is still not printed to page or console.
function actu_scripts_page()
{
?>
<div class="wrap">
<h2>Sahar actu plugin</h2>
<form action="" method="post">
<?php wp_nonce_field('do_test', '_test_nonce') ?>
<input type="hidden" name="action" value="start_test">
<input class="button button-primary" type="submit" value="Start test">
</form>
</div>
<?php
if (isset($_POST['start_test'])) {
if (isset($_POST['start_test'])) {
if (!wp_verify_nonce($_POST['_test_nonce'], 'do_test')) {
// error in nonce
} else {
start_test();
}
}
}
?>
<?php
}
function start_test()
{
echo("hhhhh");
die(); // tried with and without, no difference
}
add_action('admin_post_start_test', 'start_test');
There are two ways to acheive this, both are fine, it just depends on the user experience you desire. Use the normal http form submission (what you have already), or use ajax. The normal form submission is the easiest method.
Submit the form using the standard method (what you have there), which will reload the page. Important Note it would be better to leave the action attribute blank like action="" if you are submitting the page to itself.
You will also want to add a nonce to the form using wp_nonce_field() and check its value in the submission block with wp_verify_nonce().
So your form would like something like this:
<form action="" method="post">
<?php wp_nonce_field('do_test', '_test_nonce') ?>
<input type="hidden" name="action" value="start_test">
<input class="button button-primary" type="submit" value="Start test">
</form>
Add a php block to check if the form has been submitted and do your script in there, printing any output with php.
function start_test() {
// do things. If successful, return true. Otherwise return false
return true;
}
if( isset($_POST['start_test']) ) {
if( ! wp_verify_nonce( $_POST['_test_nonce'], 'do_test' ) {
// error in nonce
} else {
if( start_test() )
echo '<p>Success!</p>';
else
echo '<p>Failure!</p>';
}
}
There is a redirection happening through /wp-admin/admin-post.php that will return you back to the previous screen.
Your results are being printed on this page, and since it's redirecting, you don't get to see anything.
All you need to do to solve this issue, is add this after your debugging code:
die();
Or
exit();
This will stop the PHP from executing anything after your code. Thus, stopping the page from redirecting. Also, any functions that will run after you function, will not run normally, so if you're expecting saving for example, it won't happen after this piece of code.

PHP form not submitted to its caller method

I have installed a complete PHP system that is based on CodeIgniter. Its first view is a form with action set to
"<?php echo current_url(); ?>"
and this view is shown from a file that defines a class with some methods, a method for each subsequent view. This setup method exists in the directory: setup/controllers/Setup.php, while the views shown are in the directory: setup/views.
The code that shows the first view is:
if ($this->input->post('licence_agreed')) {
$this->session->set_tempdata('setup_step', 'requirements', $this->setup_timeout);
redirect('requirements');
}
if ( ! file_exists(VIEWPATH .'/license.php')) {
show_404();
} else {
$this->load->view('header', $data);
$this->load->view('license', $data);
$this->load->view('footer', $data);
}
The license form is defined as:
<form accept-charset="utf-8" method="POST" action="<?php echo current_url(); ?>" />
<input type="hidden" name="licence_agreed" value="1" />
<div class="terms"><?php echo lang('text_license_terms'); ?></div>
<div class="buttons">
<p class="text-right"><?php echo lang('text_license_agreed'); ?></p>
<div class="pull-right">
<button type="submit" class="btn btn-success"><?php echo lang('button_continue'); ?></button>
</div>
</div>
When I load the first view and post the form, it reloads the same view again. I have tried to debug the method above and it seems that it only executes the same if condition each time with the same result, regardless of the value of licence_agreed parameter.
I can't figure out what is the problem. It works fine on the server. But locally it reloads the same very first view all the time with no action taken.

How to maintain current URL in CodeIgniter

once again I'm lost. I'm gonna start ahead with the issue, because I am not even sure what I really want.
Example:
I have an article view. The URL is: http://index.php/news/article/3
This actually runs the article($id) function in my news controller and gives it the 3 as an argument. The function then fetches the article information and displays it in the view.
On the article page, the user can also log in. Logging in is triggered on pressing
submit button inside my form form_open('core/login')...button...</form> In the function I log the user in and refresh the current view with some elements changed according to the user being logged. The problem is that the URL is now http://index.php/core/login. Obviously I would like it to be the original URL.
Is there any, possibly simple, solution to achieve this? Thank you all for reading and in advance for your replies.
Difficult without more code but let me give you my theory / take on this:
Default controller:
User is not logged in - show default header, content, footer
User presses login, form is shown
User is authenticated - yes (continue) no (go back to form)
User is redirect('home')'d
Your default controller/home controller checks if auth'd: if authorised then show logged in header, content and logged in footer
or simply pass 'loggedIN' as a $data['loggedIN'] variable to the view - but this breaks the ideology of MVC framework.
More info from you and I can be more specific, or we can talk on IRC.
Adding this code from a controller i'm working on right this minute - I use ion_auth library (you should look it up, it's excellent).
This is my default controller - and as you can see some simple logic loads the different views/states.
public function index(){
if ($this->data['auth_login'] ) {
/*is already signed in so just present the lobby?*/
$data['page_title'] = "HN Lobby";
$data['menuItems'] = nav_anchor_helper_authd();
$data['myUserID'] = $this->ion_auth->get_user_id();
$data['lobby_players'] = $this->lobby_model->get_players();
$this->load->view('template/public/header',$data);
$this->load->view('player_pages/nav_2',$data);
$this->load->view('player_pages/lobby',$data);
$this->load->view('template/scripts/main',$data);/*scraper and other scripts*/
$this->load->view('template/public/footer',$data);
} else {
/*request login*/
$data['page_title'] = "PLAY HN";
$data['menuItems'] = nav_anchor_helper();
$data['auth_rtnurl'] = current_url();
$data['auth_conturl'] = current_url(); /*for now just come back to same page where lobby should load - perhaps in future a semi gooey login? e.g where was user going - this could be the continue url in this var right here << */
$data['message_body'] = $this->session->flashdata('message');
$this->load->view('template/public/header',$data);
$this->load->view('template/public/nav_1',$data);
$this->load->view('public_pages/play',$data);
$this->load->view('template/public/footer',$data);
}
}
Here is how I handle the return URL in my login function:
Login/auth controller: (using ion_auth)
function login()
{
$this->data['title'] = "Login";
//validate form input
$this->form_validation->set_rules('identity', 'Identity', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
if ($this->form_validation->run() == true)
{
if ($this->ion_auth->login($this->input->post('identity'), $this->input->post('password'), $remember))
{
//if the login is successful
//redirect them back to the home page
$this->session->set_flashdata('message', $this->ion_auth->messages());
$rtnurl = $this->input->post('auth_conturl');
if(!$rtnurl || $rtnurl == ""){
$rtnurl = '/';
}
redirect($rtnurl, 'refresh');
}
This is only an extract/segment of the login function - but as you can see i utilise the function 'redirect' from code igniter to push the user back to the return URL posted with the login form (which was set in the view/previous controller using the current_url() function.
Finally my default view file with login form to show you how i am passing the return url:
<div>
<h4>Login</h4>
<div id="infoMessage" class="errortext"><?php echo $message_body;?></div>
<?php echo form_open('auth/login', array('class' => 'form col')); ?>
<p>
<label for="identity">Email:</label> <input type="text" name="identity" value="" id="identity"> </p>
<p>
<label for="password">Password:</label> <input type="password" name="password" value="" id="password"> </p>
<p>
<label for="remember">Remember Me:</label> <input type="checkbox" name="remember" value="1" id="remember"> </p>
<p><input type="submit" name="submit" value="Login ยป"></p>
<p>
Forgot password ?
</p>
<input type="hidden" name="auth_rtnurl" value="<?php echo $auth_rtnurl; ?>"/>
<input type="hidden" name="auth_conturl" value="<?php echo $auth_conturl; ?>"/>
<?php echo form_close();?>
</div>
To use the current dynamic url as form action, just use -
<?= form_open(current_url()); ?>

Codeigniter form on same page as results

I am using codeigniter and the tutorial from here. I have made a basic blog tool which works fine. However as it stands to add a new post you have to go to a separate page 'create.php' to get to the form. I would like to try and put the form on the same page as the page that will be updated i.e. 'index.php'. If I try to do this at the moment the form simply refreshes and does submit the data.
model
function insert_post($data){
$this->db->insert('posts', $data);
return;
}
Current View (admin/create.php)
<?php echo validation_errors(); ?>
<h4>Create A New Post Below</h4>
<form action="" method="post" >
<p>Title:</p>
<input type="text" name="title" size="50"/><br/>
<p>Summary:</p>
<textarea name="summary" rows="2" cols="50"></textarea><br/>
<p>Post Content:</p>
<textarea name="content" rows="6" cols="50"></textarea><br/>
<input type="submit" value="Save" />
<?php echo anchor('admin','Cancel'); ?>
</form>
View I would like the form to be on (index.php)
<?php
echo '<p>Welcome '.$username.'! All posts available for edit or deletion is listed below.</p><br/>';
echo anchor('admin/create','Create New Post');
$count = count($post['id']);
for ($i=0;$i<$count;$i++)
{
echo '<div class="postDiv">';
echo '<h4>'.$post['title'][$i];
echo '<p>'.$post['summary'][$i].'</p>';
echo '<p>'.$post['content'][$i].'</p>';
//echo anchor('blog/view/'.$post['id'][$i],' [view]');
echo anchor('admin/edit/'.$post['id'][$i],' [edit]');
echo anchor('admin/delete/'.$post['id'][$i],' [delete]</h4>');
echo '</div>';
}
?>
Controller
function create(){
$data['userId'] = $this->tank_auth->get_user_id();
$data['username'] = $this->tank_auth->get_username();
$this->form_validation->set_rules('title','title','required');
$this->form_validation->set_rules('summary','summary','required');
$this->form_validation->set_rules('content','content','required');
if($this->form_validation->run()==FALSE)
{
$this->load->view('template/admin_html_head',$data);
$this->load->view('admin/create',$data);
$this->load->view('template/html_tail',$data);
} else {
$data = $_POST;
$this->posts->insert_post($data);
redirect('admin');
}
}
This was straight forward when I used normal php but with codeigniter I am getting lost with the MVC stuff. I know this is probably a fairly basic question so please either explain your answer or give me a link to something which will explain what I need to do as I want to learn from this. I have read the codeigniter docs on validation but I dont think thats my problem?
What you are trying to do is called embedding a view. I will try to explain how but you should also check some links which might prove to be more in depth:
http://net.tutsplus.com/tutorials/php/an-introduction-to-views-templating-in-codeigniter/
Codeigniter: Best way to structure partial views
The crux of what you need to do is change the link on index.php from:
echo anchor('admin/create','Create New Post');
to
$this->load->view('admin/create');
Now this should work, but to help you on the MVC front, it helps to explain why doing it this way is wrong. The idea of MVC is to seperate the functions in your application into their distinct roles. Most people will frown at putting business logic into views unless it is very minimal. The way that we could improve upon your code is to load the view in the controller, and set it to variable.
At the bottom of the codeigniter docs for views it shows how to load into a variable:
http://ellislab.com/codeigniter/user-guide/general/views.html
if the third parameter of load->view is set to true then the function will return your view as a string instead of outputting it to the browser
$data['input_form'] = $this->load->view('admin/create', $data, true);
then in the view that you want to load that form all you need to do is echo input_form
<?php echo $input_form;?>
So that should solve your problem but there are also a few more things you can do in your view file that will improve the readability of your code.
Instead of using a count() and for loop you can use foreach which makes everything much easier
<?php foreach ($post as $post_item):?>
<div>
<h4><?php echo $post_item['title'];?></h4>
</div>
<?php endforeach;?>
It also helps to break your view files up and have more tags. It might seems like it is extra bloat, but when you have larger view files it will be very cumbersome to continue using as many echo's as you have
just add one method uri_string() in your form action, uri_string will take same url of page put in action you can submit form to same page
<?php echo validation_errors(); ?>
<h4>Create A New Post Below</h4>
<form action="<?=uri_string()?>" method="post" >
<p>Title:</p>
<input type="text" name="title" size="50"/><br/>
<p>Summary:</p>
<textarea name="summary" rows="2" cols="50"></textarea><br/>
<p>Post Content:</p>
<textarea name="content" rows="6" cols="50"></textarea><br/>
<input type="submit" value="Save" />
<?php echo anchor('admin','Cancel'); ?>
</form>
in controller little chagnes
function create(){
$data['userId'] = $this->tank_auth->get_user_id();
$data['username'] = $this->tank_auth->get_username();
$this->form_validation->set_rules('title','title','required');
$this->form_validation->set_rules('summary','summary','required');
$this->form_validation->set_rules('content','content','required');
if($this->form_validation->run()==FALSE)
{
$this->load->view('template/admin_html_head',$data);
$this->load->view('admin/create',$data);
$this->load->view('template/html_tail',$data);
} else {
$data = $this->input->post();
$this->posts->insert_post($data);
redirect('admin');
}
}
Use session library
check this another stackoverflow thread to know how to use session
In order to use session library, u need to configure encryption_key in config.php
To do that, check this out

Is a stale session stopping post variables being submitted

I have had this issue intermittently for some time, but I only just had it happen repeatedly enough to actually trouble shoot it. It happened repeatedly in FF but I have seen it in Chrome as well.
I have login form as below, it is very simple, email address and password and a submit button
<form method="post" action="login.php" id="valid" class="mainForm">
<fieldset>
<div class="">
<label for="req1">Email:</label>
<div class="loginInput"><input style="width: 100%;" type="text" name="email" class="validate" id="req1" /></div>
<div class="fix"></div>
</div>
<div class="">
<label for="req2">Password:</label>
<div class="loginInput"><input style="width: 100%;" type="password" name="password" class="validate" id="req2" /></div>
<div class="fix"></div>
</div>
<input name="action" type="hidden" value="log_in" />
<div class="">
<div class=""><input type="checkbox" id="check2" name="remember_me" value="1"/><label>Remember me</label></div>
<input type="submit" value="Log me in" class="submitForm" />
<div class="fix"></div>
</div>
</fieldset>
</form>
Submitting the above form wouldn't log me in, it just displayed the login form again as if nothing was submitted. So I amended the login.php file that is submitted to, and at the very top added print_r($_POST);
When I submitted the form again all it displayed was an empty array. It was like the form variables just weren't being sent. I tried several accounts, and got a blank array each time.
I then tried to enter an email address that I new wasn't in the database, and to my amazement the $_POST array populated with the fake email and password. I then tried a real account again and it was blank.
The last thing I did was to deleted the session cookie in FF for the site, and then try again. To my surprise I could then log in OK. I logged in and out a few times after that with no problem at all!
So my question is: What was that session cookie doing to prevent the post variables from being sent (if that was what was actually happening) and why did it populate the $_POST array if I entered a fake email address? The print_r($_POST) I did was the very first thing in the script, before any other processing or includes, yet it still was empty??
I guess I don't really know how browsers deal with session cookies, but this behaviour has me completely clueless.
Any advice on how to troubleshoot this, or general session advice.
EDIT - PHP Code for the login.php
<?php
print_r($_POST);
include '../inc/init.php';
$action = fRequest::get('action');
if ('log_out' == $action) {
fSession::destroy();
fAuthorization::destroyUserInfo();
fMessaging::create('success', '<center>You were successfully logged out</center>');
}
if (fAuthorization::checkAuthLevel('user') || fAuthorization::checkAuthLevel('buser')) {
fURL::redirect('index.php');
}
if ('log_in' == $action) {
# Set session variables etc...
}
The init.php include at the top sets the database connetion strings and starts the session etc... I am using FlourishLib Un-Framework set of classes which includes a session class.
Thanks
try this code please
$actions = array('log_in', 'log_out');
$action = fRequest::getValid('action', $actions);
if ($action == 'log_out') {
fSession::clear();
fAuthorization::destroyUserInfo();
fMessaging::create('success', URL_ROOT . 'index.php', 'You were successfully logged out');
fURL::redirect(URL_ROOT . 'index.php');
}
if ($action == 'log_in') {
if (fRequest::isPost()) {
try {
$valid_login = fRequest::get('username') == 'yourlogin';
$valid_pass = md5(fRequest::get('password')) == 'md5(youpassword)';
if (!$valid_login || !$valid_pass) {
throw new fValidationException('The login or password entered is invalid');
}
fAuthorization::setUserToken(fRequest::get('username'));
fURL::redirect(fAuthorization::getRequestedURL(TRUE, URL_ROOT . 'index.php'));
} catch (fExpectedException $e) {
fMessaging::create('error', fURL::get(), $e->getMessage());
}
}
include VIEWS_DIR . DS . basename(__FILE__);
}

Categories