PHP MVC passing form values to controller and model - php

I'm trying to send POST values to the controller and then pass it to the model in PHP but I'm not sure how to go about doing this.
This part of the controller is to see if the user requests for a view like ?action=game. This works.
But I'm trying to modify it to allow $_POST to be sent to it and then to the model.
function __construct()
{
if(isset($_GET['action']) && $_GET['action']!="" )
{
$url_view = str_replace("action/","",$_GET['action']);
if(file_exists("views/" . $url_view . ".php" ))
{
$viewname = $url_view;
$this->get_view($viewname . ".php");
}
else
{
$this->get_view('error.php');
}
}
else
{
$this->get_view('home.php');
}
}
Here's what I got. In the registration form page, the action of the form is ?process=register but it doesn't work.
if(isset($_POST['process']) == 'register)
{
$this->get_view('register.php')
}
Get_view function determines what model to bind with the view
function get_view($view_name)
{
$method_name = str_replace(".php","",$view_name);
if(method_exists($this->model,$method_name))
{
$data = $this->model->$method_name();
} else {
$data = $this->model->no_model();
}
$this->load->view($view_name,$data);
}

Since the action of your form is ?process=register, then process is still in the $_GET superglobal. What you can do to make it use post is add a hidden input field containing process.
With this:
<form method="post" action="script.php?process=register">
The form is POST'ed to script.php?process=register so you have $_GET['process'], not $_POST['process'].
Try this instead:
<form method="post" action="script.php">
<input type="hidden" name="process" action="register" />
To have $_POST['process']. Alternatively, you could keep the "process" in the GET and switch your if statement to check $_GET instead of $_POST.

Related

Is it possible to redirect to another function within a function in PHP?

I am adding a delete button to certain rows of a table (not all). The table is already inside a form, so my thinking is to do a check to see if my button was clicked inside the function that the form submits to and redirect to a delete function if it was. I can't figure out if it's possible to do that or what other options there are.
I tried using a link for the delete, but that doesn't get the information across. I tried using another form, but that's a form within a form. If there is another way to do this, I'm happy to learn it.
Here is parts of the form:
echo '<form action="#/job/addorupdate" id="jobform" name="jobform" method="post" accept-charset="utf-8">';
echo '<input type="hidden" name="id" value="228828">';
if ($id > 0) {
echo '<button style="color:red;border:none;font-weight:bold;cursor:pointer;" type="submit" value="' . $id . '" name="idOfRow">X</button>';
}
echo '</form>';
Here is the function it goes to:
public function addOrUpdate(){ // addOrUpdate a job - control
if ($this->input->post('idOfRow')) {
// This is where I want to do the redirect
}
.
.
}
The solution was to replace the button with a link and use that to call the delete function.
echo ' X';
public function addOrUpdate(){ // addOrUpdate a job - control
if ($this->input->post('idOfRow')) {
$delete=deleteRow($this->input->post('idOfRow'));
if($delete == 1){
header('location:location.php'); // add redirect location here.
}
}
}
//Create One New function
public function deleteRow($DeleteInput){
if ($DeleteInput) {
//add sql function to delete
if(delete == true){
return 1;
}
else {
return false;
}
}
}

Why does CI create a new row instead of updating?

I'm creating a UI in my application which will allow the user to decide the state of received content, this includes updating it. How does CI handle this?
I've tried the different update methods provided in the query builder part of the documentation, including replace and update, I pass on the data from the view to the controller, to the model in the form of an array. Yet still, when I try it, it creates a new row with that single value and with all other columns empty.
view.php
<form action="Application/Update" method="get">
<input type="hidden" name="mar-id" value="<?php echo $row['id']; ?>">
<input type="hidden" name="mar-read" value="New-value">
<?php echo anchor('http://localhost/dir/dir/dir/index.php/Application/Update', 'update'); ?>
</form>
controller.php
public function Update() {
$this->load->helper('url');
$this->load->model('Main');
$id = $this->input->post('mar-id');
$value = $this->input->post('mar-read');
$mar = $this->Main->Update($id, $value);
if ($mar == TRUE) {
redirect('http://localhost/dir/dir/dir/index.php/Application/Otherpage', 'refresh');
}
else {
redirect('http://localhost/dir/dir/dir/index.php/Application/Otherpage');
}
}
model.php
public function Update($id, $value) {
$data = array(
'status' => $value
);
$this->db->where('id', $id);
$update = $this->db->update('table', $data);
}
As I said, I expect the row to be updated based on the row-id provided. Instead it creates a completely new row with that single value. It doesn't return any error messages though.
There are a number of mistakes here.
SO to date we have established that performing var_dumps in the controller results in NULL for all your "POST" values.
I've assumed the following for simplicity.
Controller Name is: Program.php (Application is NOT an Allowed controller name as it's a foldername)
Model Name is: Mdl_update.php
View is: update_view.php
Issue #1:
Your Form has an issue where you are using an anchor tag which is just a link. It does nothing in submitting any data from the form.
So we have to remove the Anchor Tag and replace it with a Form Submit. You have to Submit the form to get any chance of sending the form data.
For testing your GET and POST I've added in Two different Forms.
In update_view.php
<!-- Set the Method to GET -->
<form action="program/update" method="get">
<input type="hidden" name="mar-id" value="<?php echo $row['id']; ?>">
<input type="hidden" name="mar-read" value="New-value">
<input type = "submit" name="update" value="Update with GET">
</form>
<!-- Set the Method to POST as this is what the Controller is Expecting -->
<form action="program/update" method="post">
<input type="hidden" name="mar-id" value="<?php echo $row['id']; ?>">
<input type="hidden" name="mar-read" value="New-value">
<input type = "submit" name="update" value="Update with POST">
</form>
What I used to display the Form in the controller by simply calling the program/index in the Program controller.
public function index() {
$this->load->helper('url');
$data['row'] = array('id' => 2);
$data = $this->load->view('update_view', $data, TRUE);
echo $data;
}
So your Controller is looking for POST and not GET. This can be proven by changing the controller up a bit for debugging.
public function update() {
$this->load->helper('url');
$this->load->model('mdl_update');
$id = $this->input->post('mar-id');
$value = $this->input->post('mar-read');
echo '<h2>POST Values</h2>';
var_dump($id);
var_dump($value);
// ****************************
// These are added in for debugging/Demonstration to show values for the form using the GET method.
$id_get = $this->input->get('mar-id');
$value_get = $this->input->get('mar-read');
echo '<h2>GET Values</h2>';
var_dump($id_get);
var_dump($value_get);
// ****************************
exit('Stopped for Debugging: Method '. __METHOD__.' at Line: '.__LINE__); // Added for Debug
$mar = $this->mdl_update->Update($id, $value);
if ($mar == TRUE) {
redirect(base_url('program/otherpage'), 'refresh');
} else {
redirect(base_url('program/otherpage'));
}
}
So you are looking for POST Data when your form method is set to GET. Please be aware of what you are setting. They must match.
If you want to use GET, you need to use $this->input->get()
The code above will let you test both.
So you now have a POST and GET Form and the controller is setup to demonstrate the two different types. Choose Either GET or POST!. That is up to you on which one you choose.
Issue #2: Expecting a return value from your Model when you are not returning anything.
In your Controller you have the line...
$mar = $this->mdl_update->Update($id, $value);
And in your Model you have...
public function update ($id,$value) {
$data = array(
'status' => $value
);
$this->db->where('id', $id);
$this->db->update('db_table', $data);
}
Your Model Method is not returning anything.
You should always look up what your return values are. I am expecting that your intention was to return the value of the update. Looking through the CI Code itself it appears that if things go wrong it will return FALSE (if the database debug is disabled - learnt something new)
I've added in some debug to assist in viewing what is going on here.
public function update($id, $value) {
$data = array(
'status' => $value
);
$this->db->where('id', $id);
$update_result = $this->db->update('db_table', $data);
echo $this->db->last_query(); // Added for DEBUG
return $update_result;
}
Now I cannot get your code to create new rows as you claim. It's impossible, with this code, to add new rows. So thats happening from something you haven't shown us but that is an aside and not important here.
If we alter the controller to view the model etc (I am only showing the changes ) we would change
exit('Stopped for Debugging: Method '. __METHOD__.' at Line: '.__LINE__);
$mar = $this->mdl_update->Update($id, $value);
To this
$mar = $this->mdl_update->Update($id, $value);
var_dump($mar);
exit('Stopped for Debugging: Method '. __METHOD__.' at Line: '.__LINE__);
If you run this and submit either the GET ( Results are NULL ) or POST, the update will always return TRUE. So your redirect etc needs to be looked at on how you decide on one or the other.
I think you should set your table columns to not allow them to be NULL AND add in some "Validation" in your controller.
ISSUE 3: No Form Validation
CodeIgniter has a Form Validation Class that I suggest you read. This is getting way too long to go into that here...
So as you go through this, you can add/remove debugging to test what is going on and progress it along the way as I have hopefully shown.
if anything is unclear, just ask. I'm sure I may have left something out.

how to call a PHP function from a form button

I have a form in my index.html that looks like this:
<form name="form" method="post" action="send.php">
.
.
.
.
Inside my send.php I have to functions, function generatekey () and function postData(), how call I call the postData() function from my action attribute in my form?
you can also make your action like this:
<form name="form" method="post" action="send.php?postData">
and in your send.php you can do this:
if(isset($_GET['postData'])){
postData();
}
Add a unique hidden field in your form like:
<input type="hidden" name="action" value="postData" />
send.php
<?php
function generatekey () {
// action
}
function postData() {
// action
}
if ( $_POST[ 'action' ] == 'postData' ) {
postData();
}
?>
Or read your submit value, if it's unique.
Basically there is no "easy" way to do that, you need to write some code in your script that will decide what function to call and when, like:
if($_POST['submit'){
postData();
}
Another option is to use one of the many MVC framework out there like Codeigniter or laravel.

how to call different action methods of one controller from one form in kohana 3.0

I have one form with two buttons (add1,add2). So when I click on button add1, I want to call action_add1() and clicking button add2 calls action_add2(). Both functions are part of Controller_Welcome.
How can I achieve this?
class Controller_Welcome extends Controller
{
public function action_add1()
{
//some logic
}
public function action_add2()
{
//some logic
}
}
public function action_form()
{
$action = $this->request->query('action');
if ($action && method_exists($this, 'action_'.$action))
{
$action = 'action_'.$action;
return $this->$action();
}
}
No Javascript required, just send form data to welcome/form with action param as button name.
With JavaScript:
<input type="submit" name="add1" />
<input type="submit" name="add2" />
$('input:submit').click(function() {
$('#myForm').setAttribute('action', 'add_' + this.name);
$('#myForm').submit();
return false;
});
I'm not sure of the exact syntax, but the main idea is here.

Using $_POST += array() for default values

I'm finishing up a small contact form and had a question about providing default values for $_POST. The reason I'm asking about default values is because within my form I have fields like this:
<input type="text" name="fullname" value="<?php echo $_POST['fullname']; ?>" />
Clearly I would like to retain the submitted value if I do not permit the data to clear. This raises errors when the page is first loaded, since there is no value for $_POST['fullname'].
To my question: is there anything I should be concerend about providing default values to the $_POST array like I'm doing in the next code-sample:
$_POST += array(
'fullname' = '',
);
If $_POST['fullname'] already exists, it will be retained - if it doesn't, it will be created within the array. This way, upon loading the form, blank values will be presented in the input fields.
Don't worry, all
I sanitize my data
Thank you for the help
Even if you are doing so, put that data in your container, do not modify superglobals. Create class that'll contain your data - then you'll have the interface do sanitize, manipulate and get it te proper way. Import data from $_POST and then validate, if all necessary values are in.
As for code:
<?php
class PostData
{
private $data;
public function __construct(array $data)
{
$this->data = is_array($data)
? $data
: array();
}
public function set($key, $value)
{
$this->data[$key] = $value;
}
public function get($key, $default, $escaping)
{
if(isset($this->data[$key]))
{
switch($escaping)
{
case 'htmlspecialchars':
{
return htmlspecialchars($this->data[$key]);
break;
}
case 'mysql_real_escape_string':
{
return mysql_real_escape_string($this->data[$key]);
break;
}
// and so on, your invention goes here
default:
{
return $this->data[$key];
}
}
}
else
{
return $default;
}
}
}
$postData = new PostData($_POST);
Create function:
function displayValue($field) {
if(isset($_POST[$field])) {
echo 'value="' . htmlentities($_POST[$field]) . '"';
}
}
And then use like:
<input type="text" name="fullname" <?php displayValue('fullname'); ?> />
You can also do it like this:
<?php echo empty($_POST['fullname']) ? null : $_POST['fullname']; ?>

Categories