Kill the execution of controller after $this->load->view, Codeigniter - php

Hi I am using codeigniter for site and i am calling a function in a controller through a form in my php page the function call is:
Gear.php:
foreach ($gearArray as $key => $value) {
echo '<tr><td><img id="leftimg" src="'.base_url().''.$value["Product_Image_URL"].'"></td>';
echo '<td>'.$value["Description"].'';
echo '<form method="post" id="addtocart" action="'.site_url('GearController/addorUpdate').'">';
echo '<input type="hidden" name="desc1" value="'.$value["Name"].'">';
echo '<input type="hidden" name="cost1" value="'.$value["Price"].'">';
echo '<input type="submit" value="Add To Cart">';
echo '</form></td>';
}
echo '</table>';
?>
From this the method inside the GearController is called through
action="'.site_url('GearController/addorUpdate').'"
inside the function which is an add to cart function, i am checking whether the item is already in the cart or not and then updating it,once updated i am trying to redirect to a page using:
GearController.php:
public function addorUpdate(){
$this->load->helper('form');
$this->load->library('form_validation');
$this->load->model('CartModel','cart');
$boolean = FALSE;
$Description = $this->input->post('desc1');
$data['cartArray'] = $this->cart->return_cart();
foreach ($data['cartArray'] as $value) {
if($Description==$value['Description']){
$boolean = TRUE;
}
}
if($boolean==TRUE){
$this->updateCart($Description);
}
}
public function updateCart($Description){
$updatearray = array(
'Quantity'=>'Quantity+1',
'Price' => 'Price * Quantity',
);
$this->load->model('CartModel','cart');
$update_order = $this->cart->update_cart($updatearray,$Description);
$data['cartArray'] = $this->cart->return_cart();
$this->load->helper('url');
$this->load->view('cart',$data);
}
The problem here is that everything works fine, the page gets redirected but within seconds it displays a blank screen. I tried return, die and exit. None of it helps. It seems like the controller is executing the code under the $this->load->view. I am telling this because i previously had a function under the
if($boolean==TRUE){
$this->updateCart($Description);
}
That particular code was executed after the redirect. Could someone please help?

This sound like you might have what is call a BOM character at the start of your view file. This character is usually invisible. Make sure that there are not (apparently) black characters at the beginning.
You can also test that updateCart($Description) is running by temporarily putting this code as the first line of the function echo "This is updateCart; Then comment out all the other code in that function. If you see that text on the screen you know the function runs.

This doesn't answer your question but it's bugging me so...
Instead of this mess
foreach ($data['cartArray'] as $value) {
if($Description==$value['Description']){
$boolean = TRUE;
}
}
if($boolean==TRUE){
$this->updateCart($Description);
}
You could simply do this
if(in_array( $Description, array_column($data['cartArray'],'Description'))){
$this->updateCart($Description);
}
You can test it with this code (mockup)
$Description = 'foo';
$data = ['cartArray' => [
['Description' => 'foo'],
['Description' => 'bar'],
]
];
if(in_array( $Description, array_column($data['cartArray'],'Description'))){
echo "found";
}
Outputs
found
Test it here
https://3v4l.org/W5oB5
I think in_array is pretty self evident but here is array_column which is highly useful and often overlooked.

Related

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.

PHP class, html forum, print $_POST Array on page

i am beginner php programmer, iv been trying to create a small program that takes input from a forum and then after submission i want it to be printed on the screen. simple and easy i thought, iv been trying and suspiciously it seems to work fine for 1 text field, when i added the remaining 2 text fields called [fam][user] my code stops returning the content to the screen. also i started to recieve an error of an unindex array, therefore i had to use isset to counter this problem, and also, why does my code call the destructor although i never implicitly set my destructor. i dont know how to ask these questions because the errors arent consistent.
code doesnt print my [name][fam][user]
code prints [name] when everything about [fam][user] are ommited from the code.
-code sometimes called the destructor
-code doesnt clear html previous input(e.g, when working with the one text field, lets say i input the [name] john, and click submit it
displays submit, then,i refresh the page, and the name john is still
displayed, why doesnt the destructor clear the memory of name from my
submission.
<form class="nameform" action="book.php" method="post">
<input type="text" name="Name" value="1">
<input type="text" name="Fam" value="2">
<input type="text" name="User" value="3">
<input type="button" name="submit" value="Submit">
</form>
private $name; private $familyName; private $userName;
function __construct($names,$familyNames,$userNames)
{
$this->name = $names;
$this->familyName = $familyNames;
$this->userName = $userNames;
}
function getName()
{
return $this->name;
}
function getFamilyName()
{
return $this->familyName;
}
function getUserName()
{
return $this->userName;
}
public function __destruct()
{
echo "destroyed again";
$this->name;
$this->familyName;
$this->userName;
}
}
if(!isset( $_POST["Name"])||!isset($_POST["Fam"])||!isset($_POST["User"]))
{
echo "Please fill in the data";
} else {
$p1 = new Person($_POST["Name"],$_POST["Fam"],$_POST["User"]);
print $p1->getName();
print $p1->getFamilyName();
print $p1->getUserName();
print_r($_POST);
}
// $n = $_POST["Name"];
// $f = $_POST["Fam"];
// $u = $_POST["User"];
// $p1 = new Person($_POST["Name"],$_POST["Fam"],$_POST["User"]);
?>
code doesnt print my [name][fam][user]
You never echo them out of the destuctor
public function __destruct()
{
echo "destroyed again";
$this->name; //<---- does nothing
$this->familyName;
$this->userName;
}
So I am not sure what this is supposed to do. You have them down at the bottom
print $p1->getName();
print $p1->getFamilyName();
print $p1->getUserName();
But the only thing you'll get from the destruct method is
"destroyed again"
And you will only see that if everything in the form is set. Which it always is when the form is submitted, because type text is always submitted with its form.
Which brings me to this, you should be checking empty instead of isset there
if ('POST' === $_SERVER['REQUEST_METHOD']) { //check if POST
if(empty($_POST["Name"])||empty($_POST["Fam"])||empty($_POST["User"])){
echo "Please fill in the data";
} else {
$p1 = new Person($_POST["Name"],$_POST["Fam"],$_POST["User"]);
print $p1->getName();
print $p1->getFamilyName();
print $p1->getUserName();
print_r($_POST);
}
}
Note that anything falsy will be empty, false, [], '', 0, '0', null etc.
I don't know if this solves all of you problems, but these things could produce some of the behaviour you are experiencing.
Another more advance way to check these is like this:
if ('POST' === $_SERVER['REQUEST_METHOD']) { //check if POST
$post = array_filter( $_POST, function($item){
return strlen($item); //any thing of a length of 0 is removed
});
if(count($post) != count($_POST)){
foreach(array_diff_key( $_POST, $post) as $missing=>$empty) {
echo "Please fill in $missing\n";
}
}else{
$p1 = new Person($_POST["Name"],$_POST["Fam"],$_POST["User"]);
print $p1->getName();
print $p1->getFamilyName();
print $p1->getUserName();
print_r($_POST);
}
}
Output
Please fill in Name
Please fill in Fam
You can test it online Here
Cheers!

Session flashdata doesn´t work on form submit

I am using the ion-auth "library" for codeigniter (https://github.com/benedmunds/CodeIgniter-Ion-Auth) and I am getting a trouble with the flashdata. This is a sumary of code:
public function reset_password($code = NULL)
{
if (!$code)show_404();
$this->user = $this->ion_auth->forgotten_password_check($code);
if ($this->user)
{
//setting the rules
if ($this->form_validation->run() == false)
{
//more code
$this->_get_csrf_nonce();
/*
One of the things this function (_get_csrf_nonce) makes is:
$this->session->set_flashdata('csrfkey', $key);
$this->session->set_flashdata('csrfvalue', $value);
*/
//The next thing is load the view with the form
}
else //form is running
{
echo "flashdata csrfkeyvalue: ".$this->session->flashdata('csrfvalue')."<br>";
die;
//more code, but not important by the moment
}
}
}
Well, the echo of $this->session->flashdata('csrfvalue') when the form is submited allways show nothing.
If I make something like:
private function _get_csrf_nonce(){
/*$this->load->helper('string');
$key = random_string('alnum', 8);
$value = random_string('alnum', 20);
$this->session->set_flashdata('csrfkey', $key);*/
$this->session->set_flashdata('csrfvalue', $value);
redirect(base_url("auth/test"));
//return array($key => $value);
}
public function test()
{
echo "flashdata csrfkeyvalue: ".$this->session->flashdata('csrfvalue')."<br>";
}
In this case... it works. The view I am using to the form is very very similar from this: https://github.com/benedmunds/CodeIgniter-Ion-Auth/blob/2/views/auth/reset_password.php
Thanks.
SOLUTION
After fighting a little, I was looking for something that could make a new request between the view of form was loaded and the form was submited... finally, I discover (I didn´t remember) a javascript that is request though a controller (to translate some texts, based on this tutorial: http://www.student.kuleuven.be/~r0304874/blog/international-javascript-files-in-codeigniter.html). I was loaded in this way:
<script src="<?=site_url('jsloader/login.js');?>" type="text/javascript"></script>
Thanks.

Onclick Action in Yii

I'm totally new to Yii and I need help please even if it looks trivial. I have a page where I generate a table from my database, I added a search option and I need to generate the result as a table also.
The problem is that when I click the button nothing happens.
I also tried using submit but it didn't work.
This is my code:
...views/supermarkets/index.php:
<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
use app\views\supermarkets\search;
?>
<h1>Supermarkets</h1>
<ul>
<p>
Search by Name
</p>
<INPUT TYPE = "Text" VALUE ="" NAME = "searchname">
<button onclick="myFunction($_POST['searchname'])">Search</button>
<h3> </h3>
<?php
$array = (array) $supermarkets;
function myFunction($sname){
if (isset($sname) && $sname!='') {
$row = Yii::app()->db->createCommand(array(
'select' => '*',
'from' => 'supermarkets',
'where' => array('like', 'Name','%'.$sname.'')
))->queryRow();
$array = (array) $row;
}
echo $array;
$this->render('index',array('supermarkets' => $array));
}
function build_table($array){
// start table
$html = '<table class="altrowstable" id="alternatecolor">';
// header row
$html .= '<tr>';
foreach($array[0] as $key=>$value){
$html .= '<th>' . $key . '</th>';
}
$html .= '</tr>';
// data rows
foreach( $array as $key=>$value){
$html .= '<tr>';
foreach($value as $key2=>$value2){
$html .= '<td>' . $value2 . '</td>';
}
$html .= '</tr>';
}
// finish table and return it
$html .= '</table>';
return $html;
}
echo build_table($array);
?>
<?= LinkPager::widget(['pagination' => $pagination]) ?>
Even in the debug it doesn't pass through myFunction. Any suggestions please?
You should follow proper Yii syntax, ie define your function inside controller and call that function by creating button on index.php or other view file like:
Button on view file:
<?= Html::a('Search', ['search-function', 'Name' => $this->$sname], ['class' => 'btn btn-success']) ?>
And in your controller:
//As you define your function
public function actionSearchFunction($sname){
if (isset($sname) && $sname!='') {
$row = Yii::app()->db->createCommand(array(
'select' => '*',
'from' => 'supermarkets',
'where' => array('like', 'Name','%'.$sname.'')
))->queryAll();
$array = (array) $row;
I will explain you step by step. First, Note that everything inside <?php ?> tag will be generate at the server BEFORE rendering of the view. So, you can't execute php code on the client. If you need to execute some server code from client, You need to use Ajax(asynchronous JavaScript and XML). I recommend you to learn ajax, because this is very useful in web applications. OK, let's solve your problem. First step is to define an event for button click. You have myFunction already and I change it to this:
<button onclick="myFunction();">Search</button>
And I change your input to this:
<input type="text" value ="" name="searchname", id="searchname">
Now, I write myFunction() body in the <script></script> tag:
<script>
function myFunction()
{
$.ajax({
url: '<?php echo Yii::app()->baseUrl . '/supermarkets/sample' ?>',
type: 'post',
data: {searchname: $("#searchname").val()},
success: function (data) {
alert(data);
}
});
}
</script>
Now, you need to define an action in your controller for ajax request. I supposed you have SupermarketsController. Try to write actionSample() in it like this:
public function actionSample()
{
$array = (array) $supermarkets;
$sname = $_POST['searchname'];
...
echo "ok";
}
You can access the search input value in that function and all of your php code must be there. at the last line of that action, you must echo something(data or message). Everything you put after echo, you can get it as data parameter of success event of ajax request. In my example, you will see "ok" alert in your browser. I hope my explanation can help you to learn ajax. Note you need to include jquery library for using ajax. Good luck friend :)

Search Text from Content and replace by php script as PLUGINs

I am trying to build a wordpress-like plugin for my own CMS using str_replace. So when user saves something like '[do_something]' into page content, it will be replaced by a prebuild function.
example:
<?php function do_something() {
// search database and display something
}
<?php
echo str_replace("[do_something]","<?php do_something(); ?>",$page_content);
?>
However using echo it returns
"<?php do_something(); ?>"
as text instead of php script and fails to execute.
Any suggestion?
UPDATED
So finally, I have come up with this:
function plugin($page_content){
$plugins = array(
'[function1]' => 'function1();',
'[function2]' => 'fucntion2();'
);
foreach($plugins as $plugin => $function) {
if (strpos($page_content, $plugin) !== false) {
eval($function);
break;
}
}
}
:)
Try this:
<?php
eval(str_replace('[do_something]', 'do_something();', $page_content));
?>
But please remember that using eval especially with user's input is a very bad practise.

Categories