Form redirection with multiple variables - php

I found a wonderful example on form redirection when there is an error with the form elements. In validation.php the system checks if there is an error and if it's true it redirects the user to the form page.
My question is what if I have more than one form element?
As you see I renamed user_name to app_name and I added a new variable (adtext) so now I get two error messages when both form elements have some error (right now they not equal to a certain word), but I don't know what to do with the $query_string variable so the url would contain the second variable and its value as well.
This is how the url of the form page (adparameters.php) looks like when I click the submit button and there is an error with $appname:
/adparameters.php?appname=aa&error=App%20name%20is%20requiredAd%20text%20is%20required
<?php
# validate.php
$appname = trim($_POST['appname']);
$adtext = trim($_POST['adtext']);
$error = '';
if ($appname != 'myapp') $error = 'App name is required<br />';
if ($adtext != 'mytext') $error = $error . 'Ad text is required<br />';
$query_string = '?appname=' . $appname;
$server_dir = $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\') . '/';
header('HTTP/1.1 303 See Other');
if ($error != '') {
// Back to register page
$next_page = 'adparameters.php';
// Add error message to the query string
$query_string .= '&error=' . $error;
// This message asks the server to redirect to another page
header('Location: http://' . $server_dir . $next_page . $query_string);
}
// If Ok then go to confirmation
else $next_page = 'confirmation.php';
/*
Here is where the PHP sql data insertion code will be
*/
// Redirect to confirmation page
header('Location: http://' . $server_dir . $next_page . $query_string);
?>
The greatness of this code is that if I type something in the first input type object and it doesn't equal 'myapp' it is still filled with the text after redirection. That's what I want with the second object as well.

Best practice would be to send them in a $_SESSION.
session_start();
$_SESSION['form'] = array();
$_SESSION['form']['myapp'] = 'App Error Code';
$_SESSION['form']['adtext'] = 'AdText Error Code';
Then on the new page you would get the values as an array;
session_start();
$form_error = $_SESSION['form']['myapp'];
$form_error = $_SESSION['attext']['myapp'];
If you insist on using GET parameters why not append them on with the & character.
?field1=one&field2=two

I woldn't do it the way you do it but if you want it like that just change few things
if ($appname != 'myapp') $error = 'App name is required<br />';
if ($adtext != 'mytext') $error .= 'Ad text is required<br />';//note contatenation
$query_string = '?appname=' . $appname .'&addtext='.$adtext;

Related

Why is my returnurl getting $ (dollar signs) in from on the forward slash hashed code (%2F)?

I have a php function to autolog in users via SSO to wordpress. It works fine but when users have a link in Excel or Word it redirects them to a login and then I need to return them via returnurl.
The link in Excel and Word spits out this for the returnurl
returnurl%3dhttps$%3A$%2F$%2Fsiteurl%2ecom$%2Fhome$%2Fcatalog$%2Ftransactional-connectivity$%2F
So the problem here is the $%2F should just be %2F for the forward slashes. Well you notice that everything is prefixed with a "$" but the forward slash can't deal with it because it doesn't compute on redirect and knocks user back to the home page instead of the page they clicked on.
The part of the PHP code I wrote that handles this is in this function -
function safe_SSO() {
global $wpdb;
$wpprefix = $wpdb->prefix;
$url = 'https://'.$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
session_set_cookie_params(60 * 60 * 24 * 365);
session_start();
define('SAFE_APP_ID', get_option('AppID'));
define('SAFE_KEY', get_option('AppKey'));
$safeurl = 'https://safe.siteurl.com/login/sso/SSOService?app=' . SAFE_APP_ID;
define('HOME', urlencode($url));
define('SAFE_REDIRECT', $safeurl . "&returnurl=" . urlencode($url));
if(is_user_logged_in()) {
$current_user = wp_get_current_user();
}
else if(!is_user_logged_in()) {
// Start authentication and authorization
if (!isset($_SESSION['USER_ID']) && !isset($_POST['digest'])) {
// We've got no session and we've not returned from SAFE, so let's redirect to SAFE
header('Location: ' . SAFE_REDIRECT);
die();
}
if (!isset($_SESSION['USER_ID']) && isset($_POST['digest'])) {
// We've got no session but we've got a response from SAFE - let's check it
$safe_uid = $_POST['uid'];
$safe_name = $_POST['firstname'] . ' ' . $_POST['lastname'];
$safe_time = $_POST['time'];
$safe_email = $_POST['email'];
$safe_digest = $_POST['digest'];
$safe_returnurl = $_POST['returnurl'];

PHP - Merging Form to Show Results on One Page Causing Issues

I previously had a HTML file containing a form separately from a PHP file containing the script which actions the form results - this worked perfectly without errors.
The problem with this is that the page would redirect to the PHP script whereas I prefer that the form results are shown on the same page so that the user can "search" again. When adding the PHP script on to the end of my HTML page and thus converting the HTML page to a PHP page, the following issues arise:
1) Error "Notice: Undefined index: product_sku in /my_api.php on line 16" is shown.
2) I added an if statement which will echo the text "Product SKU xxx does not exist in the database." if the variable that contains the results isn't set. This now shows permanently.
Screenshot of the results:
I assume these errors both occur because the form hasn't been submitted yet and therefore the posted form data and script results are not yet set. The results when submitting the form are still correct for both successful and unsuccessful queries, so the question is what do I need to do to do to have these two errors hidden before the form is submitted?
Please see my code below:
<html>
<head>
<title>My API</title>
<link rel="stylesheet" type="text/css" href=/api.css">
</head>
<body>
Enter a product SKU to get the price
<form class="get_price" action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<input type="text" name="product_sku">
<input type="submit" class="form_submit">
</form>
</body>
</html>
<?php
/* Call form Submission SKU Field */
$product_sku = $_POST['product_sku'];
/* Variables */
$callbackURL = "Edited";
$temporaryCredentialsRequestURL = "https://ts564737-container.zoeysite.com/oauth/initiate?oauth_callback=" . URLencode($callbackURL);
$adminAuthorizationURL = 'https://ts564737-container.zoeysite.com/admin/oauth_authorize';
$accessTokenRequestURL = 'https://ts564737-container.zoeysite.com/oauth/token';
$URL = 'https://ts564737-container.zoeysite.com';
$apiURL = $URL . '/api/rest';
$consumerKey = 'Edited';
$consumerSecret = 'Edited';
/* Create/Resume Session */
session_start();
if (!isset($_GET['oauth_token']) && isset($_SESSION['state']) && $_SESSION['state'] == 1) {
$_SESSION['state'] = 0;
}
try {
/* Variables */
$authType = ($_SESSION['state'] == 2) ? OAUTH_AUTH_TYPE_AUTHORIZATION : OAUTH_AUTH_TYPE_URI;
$oauthClient = new OAuth($consumerKey, $consumerSecret, OAUTH_SIG_METHOD_HMACSHA1, $authType);
$oauthClient->enableDebug();
if (!isset($_GET['oauth_token']) && !$_SESSION['state']) {
$requestToken = $oauthClient->getRequestToken($temporaryCredentialsRequestURL);
$_SESSION['secret'] = $requestToken['oauth_token_secret'];
$_SESSION['state'] = 1;
header('Location: ' . $adminAuthorizationURL . '?oauth_token=' . $requestToken['oauth_token']);
} else if ($_SESSION['state'] == 1) {
$oauthClient->setToken($_GET['oauth_token'], $_SESSION['secret']);
$accessToken = $oauthClient->getAccessToken($accessTokenRequestURL);
$_SESSION['state'] = 2;
$_SESSION['token'] = $accessToken['oauth_token'];
$_SESSION['secret'] = $accessToken['oauth_token_secret'];
header('Location: ' . $callbackURL);
} else {
$oauthClient->setToken($_SESSION['token'], $_SESSION['secret']);
$resourceURL = "$apiURL/products/?order=entity_id&filter[0][attribute]=sku&filter[0][in][0]=" . $product_sku;
//echo $resourceURL;
//exit;
$oauthClient->fetch($resourceURL, array(), 'GET', array('Content-Type' => 'application/json', 'Accept' => 'application/json'));
$productList = json_decode($oauthClient->getLastResponse());
}
} catch (OAuthException $e) {
echo '<pre>';print_r($e);echo '</pre>';
}
/* Get price of the product SKU */
if ($productList) {
foreach ($productList as $product) {
echo '<br><br>Price of <b>' . $product_sku . '</b> is <span style="color: #ff0000; font-weight: bold;">£' . round($product->price, 2) . '</span>';
}
} else {
echo '<br><br>Product SKU <b>' . $product_sku . '</b> does not exist in the database.';
}
?>
Thank you.
You have a couple options
Rather than move your code to the form (because separating logic and view is a good idea) you could store the results of the query in the session and then redirect back to the form. Make the form a PHP page and then output what is in session for the results.
//Whatever come back from your query even an array
$_SESSION['query_result'] = "...";
//You can redirect by putting
//this at the end of the script
//This url should be what you have in the browser when on the form.
$urlForForm = 'www.sitename.com/products/search';
header('Location: '.$urlForForm);
Then change the html page to a php and have in there
<?php session_start();?>
<!--HTML FORM-->
<?php
//Check that value exists
if(isset($_SESSION['query_result'])){
//If it does output it
echo $_SESSION['query_result'];
//unset it so it does not keep showing up
unset($_SESSION['query_result']);
}
?>
If you want to keep them together as mentioned you could check if the value is set for that index
if(isset($_POST['product_sku'])){//Do stuff with SKU}
Or rather then checking specifically for a value to be set you could use $_SERVER['REQUEST_METHOD']=='POST' as a global check on the output logic. The only way you would have a POST request method is if the form was submitted.
if($_SERVER['REQUEST_METHOD']=='POST'){
//All your form processing and posting code.
//Will only run when form is submitted
}
You can avoid this using the following snippet.
$product_sku = "";
if(isset($_POST['product_sku'])){
$product_sku = $_POST['product_sku'];
}else {
echo "product doesn't exist in the database";
}
This way the error will only be shown when the form is not submitted, once the form is submitted the error will be gone.

How to do restricted URL in Array and Checkout Page

I want to restrict page of Check_out.php and my_account.php. I have added these restriction on top.php like this!
$current = $_SERVER['PHP_SELF'];
$url = "http://" . $_SERVER['HTTP_HOST'] . $current;
$restricted = array("<a href='" . BASE_URL . "products/check_out.php'>Check Out</a>,
<a href='" . BASE_URL . "users/my_account.php'>My Account</a>");
$public_pages = array("login.php","signup.php");
It is not working fine! without login. Check out page is still opening!
Link below, when user clicked on it.
It need to check the condition like If user login then it goes to check_out page. Otherwise it goes to singup.page
<li> Check Out </li>
Here is the code of condition, what i have done right now!
if ($obj_user->login && in_array($current, $public_pages)) {
$_SESSION['ref_url'] = $url;
$_SESSION['msg'] = "You must <a href='" . BASE_URL . "/process/process_logout.php'>LOGOUT</a> to view this page";
header("Location:" . BASE_URL . "msg.php");
}
if (!$obj_user->login && in_array($current, $restricted)) {
$_SESSION['ref_url'] = $url;
$_SESSION['msg'] = "You must <a href='" . BASE_URL . "/login.php'>LOGIN</a> to view this page";
header("Location:" . BASE_URL . "/msg.php");
}
?>
In Check_out.php , I have already set the table which displayed quantity, product name and total price
thanks!
change your first line to this
$current = basename($_SERVER['PHP_SELF']);
change $restricted array to this
$restricted = array('check_out.php','my_account.php');
In any of your none public php file add a check if your user is login if not then redirect to signup page.
Add your check in the top most of any none public php file.
//Make sure your session has started
//Check the user if he/she is not logged in, assuming this will return true or false if the users session is set.
if(!$obj_user->login){
//redirect to the sign up page e.g
header("Location: signup.php");
}

Remove query from URL before $_SERVER['HTTP_REFERER']

On success or fail of a form submission I am using the following. The resulting url appears as http://example.com/directory/?success=false
The problem I am having is that when a user attempts to submit the form again after correcting validation error the resulting url becomes http://example.com/directory/?success=false?success=true - I need it to clear any querystring first. How could I do this?
PHP
# Redirect user to error message
header('Location: ' . $_SERVER['HTTP_REFERER'] . '?success=false');
}
You could use explode() to break the $_SERVER['HTTP_REFERRER'] string to get rid of the existing $_GET arguments:
$bits = explode('?',$_SERVER['HTTP_REFERRER']);
$redirect = $bits[0];
# Redirect user to error message
header('Location: ' . $redirect . '?success=true');
How about something like this:
$i = strchr($_SERVER['HTTP_REFERER'], "?");
$address = substr($_SERVER['HTTP_REFERER'], 0, $i);
header('Location: ' . $address . '?success=false');

Strategy to pass data from included PHP file

The following code presents a way that I am currently rendering my pages through index.php. The problem is that I'm not sure how to re-think this so I can pass a page title before the template has been included.
How other way I could do this? This is just my index page, please ask if more code needed.
include($cms->GetTheme() . "/head.php"); This should get the Title information before being included, but I'm not sure how to pass data there from later included page.
include('config/config.inc.php');
$cms = new cms();
if(($_SERVER['REQUEST_METHOD'] === 'GET' || $_SERVER['REQUEST_METHOD'] === 'POST') && !empty($_GET['page'])) {
include($cms->GetTheme() . "/head.php");
$cms->IncludeModule($_GET['page']); <- actual page being included
include($cms->GetTheme() . "/foot.php");
} // end (GET || POST) && GET
else { // just index.php
include($cms->GetTheme() . "/head.php");
foreach($cms->GetModuleList() as $module) {
echo " $module <br />";
}
include($cms->GetTheme() . "/foot.php");
} // end ELSE
Example page being included. The $this->SetTitle($module_name); I would use to set the page title.
<?php
$module_name = 'Log out user';
$module_directory = 'admin';
$this->SetTitle($module_name); // setting page title
if(count(get_required_files()) < 2) {
header('Location: index.php');
}
else {
if(isset($_SESSION['user'])) {
$this->DestroyUser();
echo "You have been logged out! Please navigate to the Login Page.";
}
else {
header('Location: index.php?page=login');
}
}
?>
There are echos all over the place. Try and limit the places where you do that by storing the output, rather than printing it all out straight away.
In your module for example, you could do $this->content = "You have been logged out..."
Then you can change the order of execution:
$cms->IncludeModule($_GET['page']);
include($cms->GetTheme() . "/head.php");
echo $cms->content;
include($cms->GetTheme() . "/foot.php");

Categories