Refactoring: Getting rid of an optional variable for a function - php

Here's the situation; below is a piece of PHP code which is frequently reused.
if (! isset($_REQUEST['process_form'])
{
// render form
echo "<form>";
// snipped
// important bit! Remember which id we are processing
echo "<input hidden='id' value='$id'>";
// snipped
} else {
// process the form
}
I wish to encapsulate this into a function, akin to
class ProcessForm() {
function execute(array $request, $id) { };
}
The issue here is; the $id parameter is only needed when rendering the form. When processing the form after a user input or through an AJAX handler, I don't need the $id at all.
How could I refactor to get rid of the optional variable $id?

Optional parameters in PHP works like so
function example($id = NULL)
{
if(is_null($id))
echo '$id was omitted';
}

Related

Issue with redirect() when using conditional to evaluate multiple form buttons

So I've built a small conditional to evaluate which button is pressed in my form (as there are 2). This works fine and fires off the correct method and writes the appropriate data to the DB, however my redirect is not working. It saves() to the DB and then simply stays on the page designated as the POST route.
I suspect the problem has something to do with my conditional and the use of $this.
Here is my check_submit method:
public function check_submit()
{
if(!is_null(Input::get('add_to_invoice'))){
$this->invoice_add_item();
} elseif(!is_null(Input::get('complete_invoice'))) {
$this->invoice_complete();
}
}
Here is one of the 2 methods which I am currently testing:
public function invoice_add_item()
{
$input = Request::all();
$invoice_items = new Expense;
$invoice_items->item_id = $input['item_id'];
$invoice_items->category_id = $input['category'];
$invoice_items->price = $input['price'];
$invoice_items->store_id = $input['store'];
if(Input::has('business_expense'))
{
$invoice_items->business_expense = 1;
}
else{
$invoice_items->business_expense = 0;
}
$invoice_items->save();
return redirect('/');
}
Perhaps there is a better way of handling this in my routes(web) file, but I'm not sure how to go about this.
You should add the return to the check_submit() method. Something like
public function check_submit()
{
if(!is_null(Input::get('add_to_invoice'))){
return $this->invoice_add_item();
} elseif(!is_null(Input::get('complete_invoice'))) {
return $this->invoice_complete();
}
}
Better yet, you should probably return a boolean on invoice_add_item() and based on that, redirect the user to the correct place (or with some session flash variable with an error message)

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.

pass values from a function to another function in controller

i have 2 functions in a controller,
function feed()
{
$xml = simplexml_load_file('http://localhost/feed.php');
// pass to other function
$this->purchased($xml->prices);
foreach ($xml->prices as $price) {
echo ' <tr id="'.$price->sign.'"><td class="price">'.$price->wholesale.'</td>';
}
}
in the above function i take some values from a feed and append it to a html in the front end using jquery
in the below function what i do is list down all the products purchased by a particular user. this function also refreshed every 5 seconds.
function purchased($price)
{
foreach ($price as $x)
{
$retail = $x->retail;
}
}
what i need to do is get the values returned form the function feed() to the purchased function to do some calculations .. but when i use the above method i get the bellow error
Message: Undefined variable: price
Message: Missing argument 1 for Actions::purchased()
can someone tell me how can i get the prices from the feed function and use it with the purchased function?
Not sure if I understood what are you doing and what are you trying to achieve, but..
Passing variables works only when you call function. So, when you execute feed() function, then you call purchased() function and pass variable. purchased() works, ends, and then script goes back to the feed() function.
Calling purchased() from anywhere else doesn't give you the values from feed() function.
Try to change function to:
function purchased($price = '')
{
if (!isset ($price) || empty($price)) {
$xml = simplexml_load_file('http://localhost/feed.php');
$price = $xml->prices;
}
foreach ($price as $x) {
$retail = $x->retail;
}
}

PHP Concrete 5 Pass Variables to Add.php

I'm creating a new block and I want to pass a defined variable to the block instance on add.
In my controller, I have the following:
// declare the var
public $hasMap = 0;
public function add() {
$this->set('hasMap', $this->generateMapNumber());
}
The generateMapNumber() function looks like this:
public function generateMapNumber() {
return intval(mt_rand(1,time()));
}
In my add.php form I have a hidden field:
<?php $myObj = $controller; ?>
<input type="hidden" name="hasMap" value="<?php echo $myObj->hasMap?>" />
When I create a new block, hasMap is always 0 and the hidden input value is always 0 too. Any suggestions? Thank you!
--- EDIT ---
From the concrete5 documentation:
// This...
$controller->set($key, $value)
// ... takes a string $key and a mixed $value, and makes a variable of that name
// available from within a block's view, add or edit template. This is
// typically used within the add(), edit() or view() function
Calling $this->set('name', $value) in a block controller sets a variable of that name with the given value in the appropriate add/edit/view file -- you don't need to get it from within the controller object. So just call <?php echo $hasMap; ?> in your add.php file, instead of $myObj->hasMap.
It will not be the same value, because the function will give diferrent values every timy it is called.
So here's the solution. In the controller...
public $hasMap = 0;
// no need for this:
// public function add() { }
public function generateMapNumber() {
if (intval($this->hasMap)>0) {
return $this->hasMap;
} else {
return intval(mt_rand(1,time()));
}
}
And then in the add.php file...
<?php $myObj = $controller; ?>
<input type="hidden" name="hasMap" value="<?php echo $myObj->generateMapNumber()?>" />
It works perfectly. On add, a new number is generated and on edit, the existing number is drawn from the hasMap field in the db.
Thanks for all the input. Hope that helps someone else!

codeigniter form callback value

Im carrying out some form validation with codeigniter using a custom validation callback.
$this->form_validation->set_rules('testPost', 'test', 'callback_myTest');
The callback runs in a model and works as expected if the return value is TRUE or FALSE. However the docs also say you can return a string of your choice.
For example if I have a date which is validated, but then in the same function the format of the date is changed how would I return and retrieve this new formatted value back in my controller?
Thanks for reading and appreiate the help.
I'm not entirely sure I got what you were asking, but here's an attempt.
You could define a function within the constructor that serves as the callback, and from within that function use your model. Something like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Controllername extends CI_Controller {
private $processedValue;
public function index()
{
$this->form_validation->set_rules('testpost','test','callback');
if ($this->form_validation->run()) {
//validation successful
echo $this->processedValue; //outputs the value returned by the model
} else {
//validation failed
}
}
private function callback($input)
{
$this->load->model('yourmodel');
$return = $this->yourmodel->doStuff($input);
//now you have the user's input in $input
// and the returned value in $return
//do some checks and return true/false
$this->processedValue = $return;
}
}
public function myTest($data){ // as the callback made by "callback_myTest"
// Do your stuff here
if(condition failed)
{
$this->form_validation->set_message('myTest', "Your string message");
return false;
}
else
{
return true;
}
}
Please try this one.
I looked at function _execute in file Form_validation of codeigniter. It sets var $_field_data to the result of callback gets(If the result is not boolean). There is another function "set_value". Use it with the parameter which is name of your field e.g. set_value('testPost') and see if you can get the result.
The way Tank_Auth does this in a controller is like so
$this->form_validation->set_rules('login', 'Login', 'trim|required|xss_clean');
if ($this->form_validation->run()) {
// validation ok
$this->form_validation->set_value('login')
}
Using the set_value method of form_validation is undocumented however I believe this is how they get the processed value of login after it has been trimmed and cleaned.
I don't really like the idea of having to setup a new variable to store this value directly from the custom validation function.
edit: sorry, misunderstood the question. Use a custom callback, perhaps. Or use the php $_POST collection (skipping codeigniter)...apologies haven't tested, but I hope someone can build on this...
eg:
function _is_startdate_first($str)
{
$str= do something to $str;
or
$_POST['myinput'} = do something to $str;
}
================
This is how I rename my custom callbacks:
$this->form_validation->set_message('_is_startdate_first', 'The start date must be first');
.....
Separately, here's the callback function:
function _is_startdate_first($str)
{
$startdate = new DateTime($this->input->post('startdate'), new DateTimeZone($this->tank_auth->timezone()));
$enddate = new DateTime($this->input->post('enddate'), new DateTimeZone($this->tank_auth->timezone()));
if ($startdate>$enddate) {
return false;
} else {
return true;
}
}

Categories