I found this php project on github. Vanilla Kit [https://github.com/syndicatefx/vanilla-kit] , is a very simple php powered dynamic website template, I liked the clean folder structure and hence decided to use/try it.
This is the index page on the root directory which is pretty much simple. It calls the page requested by the user (in the folder pages) and replaces the variable $page with page name requested for and displays it.
<?php
// Defualt page will always be pages/homepage.html, if not, change this to the name of the file you have created to be the homepage.
$page = 'homepage';
// Get pages based on user input
if (!empty($_GET['name'])) {
//Assign a variable to a sanitised version of the data passed in the URL
$tmp_page = basename($_GET['name']);
//If the file exists, update $page
if (file_exists("pages/{$tmp_page}.php"))
$page = $tmp_page;
//If the file does not exist, include notfound page and exit
elseif(!file_exists($tmp_page)){
include 'pages/notfound.php';
exit;
}
}
// Include $page (declared default)
include ("pages/$page.php");
?>
The default page which is the homepage fetches products from the products table and displays it.
<?php
// Edit this page's title, description and keywords for SEO
$pagetitle = 'Welcome';
$pagedescription = 'description goes here...';
$pagekeywords = 'keywords,go,here';
// Add a class to body for more CSS power
$bodyclass = 'home';
// Do Not Remove
include 'inc/header.php';
?>
<?php
$dbquery = "SELECT * FROM lbtbl_products";
$productresult = $dbconnect->query($dbquery);
if ($productresult->num_rows > 0) {
while($row = $productresult->fetch_assoc()) { ?>
<div class="prod-cnt prod-box">
<form method="post" action="cartupdate.php">
<h3 class="prod-title">
<?php echo $row["lbproductName"]; ?>
</h3>
<p><?php echo $row["lbproductDescription"];?></p>
<div class="price-cnt">
<div class="prod-price"><img src="images/common/rupees.png" width="7" height="10"/> <?php echo $row["lbproductPrice"];?></div>
Qty <input type="text" name="product_qty" value="1" size="3" />
<button class="add_to_cart">Add To Cart</button>
<input type="hidden" name="product_code" value="<?php echo $row["lbproductSku"];?>" />
<input type="hidden" name="type" value="add" />
<input type="hidden" name="return_url" value="<?php echo $current_url;?>" />
</div>
</form>
</div>
<?php }
} else {
echo "0 results";
}
$dbconnect->close(); ?>
<?php include 'inc/footer.php'; ?>
Everything works fine up till now.
Now, to display the product details I have a page name productdetails.php which is saved in the pages directory as all other pages. The link on the 'homepage' to view the product detail is
<?php echo $row["lbproductName"]; ?>
But once clicked a 404 not found page is displayed. But if I move the productdetails.php page to the root directory it works. Can anyone help/suggest with a solution. My best guess it has something to do with index.php code after the comment // Get pages based on user input.
Try and share the results.
<?php echo $row["lbproductName"]; ?>
And in your product detail page you should run your select query with $_GET['id'].
It may work, try and share the results.
Related
Being near the finish line of a project I've been working on for the last couple of weeks, I recently uploaded it for the 1st time to my server to check for any issues. Although almost everything worked flawlessly, there is one issue I can't wrap my head around!
Description:
It's an online store that stores the user's cart in the $_SESSION['id'] variable. Everything is handled with POST requests. Upon clicking the <input type="submit" name="Submit" value="Add to cart" id="addToCart"> Button, the form checks if the product ID is already present in $_SESSION['id']. If that is the case, break is called to prevent adding the product multiple times. As the form's action directs back to the same file, it should in theory just refresh. To circumvent then annoying notification a user gets upon refreshing the page/using the back button after the POST request (and to prevent the form to be sent multiple times), I resulted to a Post/Redirect/Get code snippet from this Stackoverflow post. As (I believe) my shared hosting at one.com runs Apache, I used the rewrite approach.
Situation on XAMPP:
Visitor navigates to /sub/0.php (the site of the 1st product), selects his clothes size and hits Add to cart. After that, the product ID gets appended to $_SESSION['id'], the page refreshes with ?status=success at the end and a small shopping cart appears on the top right corner.
Situation on the production server (error messages turned on):
Visitor navigates to /sub/0.php (the site of the 1st product), selects his clothes size and hits Add to cart. The product ID gets appended correctly (I can check on cart.php and it shows up), though upon refresh there is EITHER
a blank page
a blank page showing just a "0" (this seems to be the ID of the 1st product I add to the cart, I once added the product with ID 3 first and it then displayed a 3)
the warning "Already in cart". This is the weird part! The warning is in the code within the if(isset($_SESSION['id'])) statement, so it should only be visible after the button was pressed. "Already in cart" even shows when the page is reloaded. I have to manually click in the URL bar and hit Enter to get the view. In this video, you can see in detail what I mean.
What's wrong with my code, why does it work on XAMPP but doesn not work on the production server? The PGR doesn't seem to work at all (or the code never gets as far as to even execute the PGR due to the break being called), it also doesn't append the status=success behind the URL.
I'm really at a loss here, every input would be greatly appreciated!
Here's all the code for a product's site:
<?php
session_start();
$id=0;
include (__DIR__."/../includes/php/database.php");
if (isset($_POST['Sumbit'])) {
// echo "submitted";
if (isset($_SESSION['id'])) {
if (gettype($_SESSION['id'])=="string") { //if there are already multiple IDs stored withinSESSION['id'] --> String
for ($i=0; $i < strlen($_SESSION['id']); $i++) {
if ($id == $_SESSION['id'][$i]) { //if there are multiple IDs already in cart and one of them matches with $id (--> multiple items are in the cart, but the current one is not)
echo "<script>alert('Already in Cart!')</script>"; //before implementing PRG, this alert appeared always when trying to add the product twice. Since I implemented PRG, it wasn't triggered once in XAMPP
$alreadyInCart=true;
break;
}
}
if (!isset($alreadyInCart)) { //if already some IDs stored within$_SESSION['id'], but$id is not(--> more than 1 other products are in the cart, but the current one is not)
$_SESSION['id'].=$id;
$_SESSION['size'].=$_POST['Size'];
}
}else{ //if$_STRING['id'] isn't a 'string' (it's an 'integer' --> just one item in the cart), there's no need (nor possibility) to loop.
echo $_SESSION['id'];
if($id==$_SESSION['id']){ //Just one item in cart, but that matches with$id (--> current item already in cart)
$alreadyInCart=true;
echo "<script>alert('Nur 1 Artikel im Warebkorb-Already in Cart!')</script>"; //before implementing PRG, this alert appeared always when trying to add the product twice. Since I implemented PRG, it wasn't triggered once in XAMPP
}else{ //Just 1 item in cart but $id doesn't match with $_SESSION['id'](--> current item not yet in cart)
$_SESSION['id'].=$id;
$_SESSION['size'].=$_POST['Size'];
}
}
}else{ //If $_SESSION['id'] doesn't even exist yet --> = instead of .=
$_SESSION['id']=$id;
$_SESSION['size']=$_POST['Size'];
}
// Post redirect get https://en.wikipedia.org/wiki/Post/Redirect/Get
$get_info = "?status=success";
header("Location: ".$_SERVER['REQUEST_URI'].$get_info);
echo $_GET['status'];
exit();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="theme-color" content="#000000" />
<title>CNTRST</title>
<link rel="stylesheet" type="text/css" href="../includes/css/styles1.css">
<link rel="stylesheet" type="text/css" href="../includes/fonts/fonts.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script type="text/javascript" src="../includes/js/main.js"></script>
<link id="essential" rel="stylesheet" type="text/css" href="../includes/css/sub_styles.css">
<?php
if (isset($_SESSION['id'])) {
if (isset($_GET['status']) && $_GET['status']=="success") {
echo '<script type="text/javascript" src="../includes/js/cart.js"></script>';
}
}
?>
</head>
<body>
<div class="content">
<?php
if (isset($_SESSION['id'])) {
include(__DIR__)."/../includes/php/cart_icon.php";
}
?>
<img id="logo" src="../includes/media/img/icons/logo.svg"></img>
<div class="slideshow">
<img src="../includes/media/img/slideshow/bg.png" id="slideshow_bg">
<img class="slideshow_objects" src="../<?php echo $product->product_image; ?>">
</div>
<div class="description">
<h1><?php echo $product->product_name; ?></h1>
<h2></h2>
<ul>
<?php echo $product->product_desc; ?>
</ul>
<strong id="price"><?php echo $product->product_price; ?> <span class="currency">€</span></strong>
<form action="<?php echo $id ?>.php" method="post">
<fieldset>
<label for="Size">Size</label>
<select name="Size" id="Size">
<option value="0">XS </option>
<option value="1">S </option>
<option value="2">M </option>
<option value="3">L </option>
<option value="4">XL </option>
<option value="5">XXL </option>
</select>
<input type="hidden" name="Product_Name" value="Marble print"><br>
<input type="submit" name="Sumbit" value="Add to cart" id="addToCart">
</fieldset>
</form>
</div>
</div>
<?php include "../includes/php/footer.php" ?>
</div>
</body>
</html>
EDIT:
Upon adding error_reporting(E_ALL); ini_set('display_errors', '1'); at the top of the code, I didn't receive a blank page, but an error message stating:
Warning: Cannot modify header information - headers already sent by (output started at /customers/6/5/2/cntrst.at/httpd.www/includes/php/database.php:1) in /customers/6/5/2/cntrst.at/httpd.www/sub/0.php on line 40 Notice: Undefined index: status in /customers/6/5/2/cntrst.at/httpd.www/sub/0.php on line 41
database.php contains:
<?php
ini_set('session.cache_limiter','public');
session_cache_limiter(false);
$host = 'localhost';
$db = 'DB_NAME';
$user = 'root';
$pass = '';
$charset = 'utf8';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$con = new PDO($dsn, $user, $pass, $opt);
if (isset($cart)) {
}else{
$product = $con->query("
SELECT * FROM products
WHERE id=$id
");
$product = $product->fetch(PDO::FETCH_OBJ);
}
?>
All my pages homepage.php, about.php, contact.php are in a folder pages. The index.php on the root directory controls what pages to load based on user input.
<?php
// Defualt page will always be pages/homepage.html, if not, change this to the name of the file you have created to be the homepage.
$page = 'homepage';
// Get pages based on user input
if (!empty($_GET['name'])) {
//Assign a variable to a sanitised version of the data passed in the URL
$tmp_page = basename($_GET['name']);
//If the file exists, update $page
if (file_exists("pages/{$tmp_page}.php"))
$page = $tmp_page;
//If the file does not exist, include notfound page and exit
elseif(!file_exists($tmp_page)){
include 'pages/notfound.php';
exit;
}
}
// Include $page (declared default)
include ("pages/$page.php");
?>
The default page on the index.php is the homepage.php which fetches products from the products table and displays it.
The homepage.php in the folder pages.
<?php
$dbquery = "SELECT * FROM lbtbl_products";
$productresult = $dbconnect->query($dbquery);
if ($productresult->num_rows > 0) {
while($row = $productresult->fetch_assoc()) { ?>
<div class="prod-cnt prod-box">
<form method="post" action="cartupdate.php">
<h3 class="prod-title">
<?php echo $row["lbproductName"]; ?>
</h3>
<p><?php echo $row["lbproductDescription"];?></p>
<div class="price-cnt">
<div class="prod-price"><img src="images/common/rupees.png" width="7" height="10"/> <?php echo $row["lbproductPrice"];?></div>
Qty <input type="text" name="product_qty" value="1" size="3" />
<button class="add_to_cart">Add To Cart</button>
<input type="hidden" name="product_code" value="<?php echo $row["lbproductSku"];?>" />
<input type="hidden" name="type" value="add" />
</div>
</form>
</div>
<?php }
} else {
echo "0 results";
}
$dbconnect->close(); ?>
Everything works fine up till now.
What I need to do is display product details when a user clicks the product so I added a productdetails.php to the pages directory which gets the ID of the product and displays the details.
The problem:- If the productdetails.php is saved on the root directory it works perfectly but when I move the productdetails.php to the pages folder (where all other pages homepage, aboutus, contactus resides) a 404, not found error is shown.
I know it has something to do with the index.php. Can anyone help?
Use this type URL
www.abc.com/productdetails?product_id=1
Then your routing system search productdetails.php are exist in pages directory. If exist then load the page and then you can find the product by using the product id $_GET['product_id']
Maybe it will work
to be honest this is more of a how to then help with code i already have. So i hope this is okay, else of course i will delete my question again. Anyway here goes i have a site with boxes, with a picture headline and a submit button. All the info in these boxes is being delivered, from my database. And of course in my database i also have a id cell, and if i try to echo out the id cell with the rest of the info in the box it shows up fine. But when i try to assign the id output variable to a header location, i do for some weird reason always get the id 3. Eventhough the id´s shows up perfectly fine, in the boxes. I have included my php code and i am still a beginner to php so sorry for this noob question. :)
session_start();
include 'connection.php';
$sqlSelect = mysqli_query($con,"SELECT * FROM inspi");
while ($feed=mysqli_fetch_array($sqlSelect))
{
$id = $feed['id'];
if(isset($_POST['readArticle']))
{
$id = $_SESSION['id'];
header("Location:"."redirect.php?".SID.$idArticle);
}
?>
<div class="contentBoxOne">
<img width="100%" height="170px" src="userpics/<?php echo $feed['image']; ?>">
<div class="line"></div>
<form method="post" action="">
<input type="submit" name="readArticle" class="readArticle" value="Læs nu!">
</form>
<?php $idArticle= $feed['id'];?>
<h2><?php echo $feed['headline'];?></h2>
</div>
You are setting $idArticle at the bottom of the loop but trying to use it at the top so it will be pulling it from the previous result. Try:
while ($feed=mysqli_fetch_assoc($sqlSelect)){
$idArticle= $feed['id'];
$sid = $_SESSION['id'];
if(isset($_POST['readArticle']))
{
header("Location:"."redirect.php?".$sid.$idArticle);
}
//rest of code
}
You will have to put div inside the loop.
I also replaced the header redirect with form action attribute (you may want to replace method POST with GET instead).
ID is passed with a hidden field
<?php
include 'connection.php';
$sqlSelect = mysqli_query($con,"SELECT * FROM inspi");
while ($feed=mysqli_fetch_assoc($sqlSelect))
{
$id = (int)$feed['id'];
?>
<div class="contentBoxOne">
<img width="100%" height="170px" src="userpics/<?php echo $feed['image']; ?>">
<div class="line"></div>
<form method="post" action="redirect.php">
<input type="hidden" name="id" value="<?php echo $id; ?>">
<input type="submit" name="readArticle" class="readArticle" value="Læs nu!">
</form>
<h2><?php echo $feed['headline']; ?></h2>
debug: <pre><?php print_r($feed); ?></pre>
</div>
<?php } // end of while loop ?>
I am looking to develop a website containing stages. I want for example to pass by the stage 2 only when i click on the finish button in the page of stage 1 so the stage 2 page can't be accessible by its url or whatever only if the user pass by another page.
Is there a method to do this ??? i am a beginner in security so please try to help me, thanks in advance coders
Make use of sessions to develop this model.
index.php
<?php
#extract($_POST);
if(isset($sub))
{
session_start();
$_SESSION['authenticate']=true;
header("location:test1.php");
exit;
}
?>
<form action='' method="post">
<input type="SUBMIT" name="sub" value="Finish" />
</form>
open.php
<?php
session_start();
if(!isset($_SESSION['authenticate']))
{
echo "You are not allowed to access";
}
else { echo "You came from index.php ! so you are a valid user"; }
session_destroy(); //<-- I added this so you can test your example multiple times.
I think, this show work :)
Use can either redirect your user directly from index.php to open.php
header('Location : open.php');
Or,
in open.php, put this
if($_SERVER['HTTP_REFERER'] == 'index.php page's full link') {
//Do or Show whatever you want to show here
} else {
// Tell the user that you are not authorized
}
If that doesn't work, echo $_SERVER['HTTP_REFERER'] and see what link it gives you. And put that link where specified above.
Cool? :)
Edit (As per the comments) --
Lets say you have a form in your form in stage1.php
<form method="post" action="">
<span class="error"><?php echo $error; ?></span>
Name: <input type="text" name="name"><br/>
Email: <input type="text" name="email"><br/>
<input type="submit" name="submit" value="Submit">
</form>
use this php in stage1.php
if (isset($_POST['name'])||isset($_POST['email'])) {
if (!empty($_POST["name"])||!empty($_POST["email"])) {
$error = "Please fill in all the fields correctly";
}
else {
$name = $_POST['name'];
$email = $_POST['email'];
//You can also save the above Variables Globally by $GLOBALS['name'] = $_POST['name'];
//So that you can use the details when you reach the final stage
header('Location : stage2 page's link');
}
}
?>
and in Page 2 lets say you have another form, then there also check
<?php
if(!empty($name)||!empty($email)) {
//the above is check for global variables email and name are not empty - means stage 2 was filled properly
//Do things for the second page's form like you did for stage 1
} else {
header('Location : stage1 page's link');
//redirect back to stage 1.
}
?>
I've searched high and low both on Google and this site for an answer to this question with no luck.
I'm working on a custom CMS for future customers who want to do their own maintenance. Here's the code that loads the current page content into the textarea from the database:
if(isset($_GET['id'])) {
$id = $_GET['id'];
$content = mysql_query("SELECT title, content FROM pages WHERE id=".$id);
$search = mysql_num_rows($content);
if($search > 0){
while($page = mysql_fetch_array($content)) { ?>
<h1>Editing <?php echo $page['title']; ?></h1>
<form id="editform" action="save.php?id=<?php echo $_GET['id']; ?>" method="post">
<textarea id="editor" name="content"><?php echo $page['content']; ?></textarea>
</form>
<?php }
}
} ?>
Here's the code in save.php:
<?php
if(isset($_POST['content'])){
$content = $_POST['content'];
$id = $_GET['id'];
echo $content;
mysql_query("UPDATE pages SET content=".$content." WHERE id=".$id);
}
?>
The problem is that the POST['content'] keeps getting the original content, not the edited one that the user just submitted.
How do I fix this?
The data should be passed automatically when the form is posted. Here is the "Integration" page page from the Developers Guide that explains this:
http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Integration
Are you sure that the query is being run successfully and that the content field is being updated? I ask because the code you posted says that in save.php, you are using:
$id = $_GET['id'];
This would seem to cause a problem, because you are using method="post" in your form, not method="get".
Could you also post the code you are using to replace the textarea with CKEditor. Are you using the PHP method:
<?php
$CKEditor = new CKEditor();
$CKEditor->basePath = '/ckeditor/';
$CKEditor->replace("content");
?>
Or the JavaScript method:
<script language="Javascript">
<!--
CKEDITOR.replace( 'content' );
//-->
</script>
Be Well,
Joe
Follow up to question in comments
Hi Purmou,
I didn't notice that you were including the id in the form action, sorry about that. If you did want to use it as a $_POST variable instead, you could include it as a hidden field like this:
<form id="editform" action="save.php?id=<?php echo $_GET['id']; ?>" method="post">
<input type="hidden" id="id" name="id" value="<?php echo $_GET['id']; ?>" />
<textarea id="editor" name="content"><?php echo $page['content']; ?></textarea>
There is some good documentaion about loading the editor via PHP in the _samples folder of the CKEditor install:
http://YourSite.com/ckeditor/_samples/php/
http://YourSite.com/ckeditor/_samples/php/replace.php, has the basic settings:
<?php
// Include the CKEditor class.
include_once "ckeditor/ckeditor.php";
// Create a class instance.
$CKEditor = new CKEditor();
// Path to the CKEditor directory.
$CKEditor->basePath = '/ckeditor/';
// Replace a textarea element with an id (or name) of "textarea_id".
$CKEditor->replace("textarea_id");
?>
Similar to the JavaScript method, you can add config options before you replace the textarea. An example from the "advanced.php" file:
$CKEditor->config['width'] = 600;
To use the PHP method with your specific code, do this:
if(isset($_GET['id'])) {
$id = $_GET['id'];
$content = mysql_query("SELECT title, content FROM pages WHERE id=".$id);
$search = mysql_num_rows($content);
if($search > 0){
while($page = mysql_fetch_array($content)) { ?>
<h1>Editing <?php echo $page['title']; ?></h1>
<form id="editform" action="save.php?id=<?php echo $_GET['id']; ?>" method="post">
<textarea id="content" name="content"><?php echo $page['content']; ?></textarea>
</form>
<?php }
include_once "ckeditor/ckeditor.php";
$CKEditor = new CKEditor();
$CKEditor->basePath = '/ckeditor/';
$CKEditor->replace("content");
}
} ?>
I changed the textarea id from "editor" to "content". I would recommend against using "editor" for the id or name, because it's used in the CKEditor code to refer to the CKEditor instance.
You can do config settings in the page where you load the editor or in the config.js file or in your own custom config file.
I spent some time trying to catch the value of the form content field after the form is submitted, but was only able to see it before CKEditor had updated the contents.
Be Well,
Joe