Welcome Guest, Not a member yet? Register   Sign In
How to Prevent Direct URL Access to Controller Functions when Private CI Function is Not Desired
#1

[eluser]downset[/eluser]
Hi all,

I would like to create a multi-step form approach for adding a listing to a site, e.g. main controller points to step one of the form - add listing details, and step two of the process would be a separate form to add contact details for the listing.

My CI url structure would be as follows:
Step 1: http://localhost/addlisting - used to add the initial content to the listing in a form, then once the user submits it would redirect to the another function contained in the Addlisting controller. I will also pass form data from step 1 of addlisting to the function in step 2

Step 2: http://localhost/addlisting/contactdetails - user enters contact details and submits the form. As I have passed the posted content as an array param to the Contactdetails function, I will send the form content from step 1 and step 2 to the DB all at once.

However at present there is nothing stopping a user accessing the step 2 URL directly, so they could start entering bad data into the the DB with only contact data and no listing data.

What is the best way to block direct access to step two of the form, e.g. if a user enters the direct URL.

I have looked at CI private functions using the _Contactdetails approach but this prevents me from redirecting to addlisting/Contactdetails altogether which is not desired.


I was trying someting like the following:

Code:
public function Contactdetails($data)
{
if ($data =="") {echo "you shouldn't be here";}

else{

$this->load->library('form_validation');

$this->load->view("add_contact_details.view.php");

}

but I keep getting the CI message:
Quote:Message: Missing argument 1 for AddListing::Contactdetails()


I expect because tbe method is expecting a param to be passed, but this doesn't happen if the user enters the URL directly. Although this does prevent access, it doesn't look very user friendly, and also in the case if I didn't want to pass a param to the function, this error would not occur and a user could get direct access to step 2 of the form.

One approach I could take is rather than passing data from step 1 to the addlisting function, I could pass it to a session variable. Then if a user enters the url addlisting/Contactdetails, I would check if the session variable was blank, if it is, then that means the user never went through step one, but I'm not sure how efficient this is, and could there a performance impact storing alot of array values in the CI session?

I would appreciate any help the community may have on this! Smile

Thanks in advance
#2

[eluser]WanWizard[/eluser]
I use different methods for each step, and register the current step in the session by setting this after processing a step, and before redirecting to the next step.

Then, in my 'step' methods I check if the current step in the session is equal to the current method. If not, I redirect back to the previous step (method).

This works in all situations, for example if nothing is present in the session and they request step6, this system will bubble back up to step1.
#3

[eluser]downset[/eluser]
Thanks for this help Wanwizard! Smile this approach would also work for me. In your approach do you set the values to a DB at each step, or do you pass the values as params until the end of the process?

What I am concerned about is that if I set the data from Step 1 on the DB before moving to step 2, the user could abandon the process and I could have bad data for listings in the DB with missing values for contact details, etc
#4

[eluser]CroNiX[/eluser]
To fix your original problem, give $data a default value.

Code:
public function Contactdetails($data = '')
#5

[eluser]downset[/eluser]
Thanks CroNIX Smile I previously tried this in an earlier test, but the problem I had with this approach was that I couldn't pass data to the Contactdetails function/view if I set $data = '' in the function declaration, e.g.:
Code:
//from main Addlisting controller

$data = array(
       'ListingDetail1' => $ListingDetail1,
       'ListingDetail2' => $ListingDetail2
     );

         redirect("../addlisting/contactdetails", $data);


//where $data is = ''

public function Contactdetails($data = '')
{

........

I guess because $data = '' was overriding any values being passed? unless there is another way to pass the listing data to the function?
#6

[eluser]ojcarga[/eluser]
As it is in the documentation, the redirect() function does not let you pass data as an parameter, if I am wrong, somebody tell me.
http://ellislab.com/codeigniter/user-gui...elper.html

So, in that case, what you can do is
Code:
$this->Contactdetails($data);
//instead of
redirect("../addlisting/contactdetails", $data);
Doing that, you are passing the <b>$data</b> array to the method, this is right, but if I go to http://localhost/addlisting/contactdetails directly (Step 2, i guess) then the value of $data would be '' (empty) .. right?? so there is where you validate

if <b>$data</b> is equals to '' :long:
else <b>$data</b> have something :-)


What @CroNiX said is correct, regarding to the error you are getting
Code:
Message: Missing argument 1 for AddListing::Contactdetails()

Setting a default value to <b>$data</b>, the error should not shows again.




Theme © iAndrew 2016 - Forum software by © MyBB