Define a variable before including function in PHP, and use variable - php

I am Working on making the menu for our content management software using php and we are having this small issue. Since we want everything to eventually be called in chunks, were breaking certain page items into chunks and loading them via functions through an included file. Since this is hard to explain, I will post some example code of what i mean below.
This is the file page.php (removed needless html code).
This is the page the user is on:
<?php
define("CURRENT_PAGE", "page.php");
include_once("data/main.inc.php");
?><html>
Content loads here.
<? desktopMenu(); ?>
</html>
Okay and here's the function for desktopMenu() from main.inc.php:
function desktopMenu() {
// Query to get the top level navigation links with no parents
$query = mysql_query("SELECT * FROM menu WHERE p_id = '0'");
if(mysql_num_rows($query) > 0) {
while($result = mysql_fetch_array($query)) {
extract($result);
if($isparent == "1") {
// Just check if they have children items
$sub_menu_query = mysql_query("SELECT * FROM menu WHERE p_id = '$id'");
if(mysql_num_rows($sub_menu_query) > 0) {
// CODE TO SHOW THE MENU ITEM AND ITS SUBS
}
} else {
// CODE TO SHOW REGULAR MENU ITEMS
// WANT TO INSERT class='active' if the CURRENT_PAGE is this value..
echo "<li><a href='#'>link</a></li>";
}
} else {
echo "<li><a href='javascript:void(0);'>Error Loading Menu</a></li>";
}
}
I am wondering how I can get the CURRENT_PAGE on the included script so I can load the class="active" onto the correct page. I am already using the following:
$config = include('config.inc.php');
$GLOBALS = $config;
on the top of main.inc.php, above this menu function so I could set global variables and include my $config['database'] variables for calling the SQL database within a function (doesn't work otherwise).
How can I check the current_page variable so I can set it active in the menu? I have tried a few different things but nothing is showing the way we expect it to. Thanks guy.

First of all I would recommend looking at MVC architecture when building your apps. I believe the use of GLOBALS is frowned upon.
To answer your question:
Since you are defining a constant define("CURRENT_PAGE", "page.php"); then this will be globally available within the scope of the function desktopMenu()
so you may use something like:
$className = (isset(CURRENT_PAGE) && CURRENT_PAGE=='xxxxx')?'class="active"':'';
echo "<li>link</li>";
xxxx string is most likely a field output from you database as the page name which will match the defined constant.
$className = (isset(CURRENT_PAGE) && CURRENT_PAGE==$result['page_name'])?'class="active"':'';
This is the basic form and you will most likely need additional conditions for the 'active' menu switch mapping to different pages.
I've tried to answer your question with an example although the structure you have used run the app is not the recommended way to develop.
I would look at the way modern frameworks are structured (Laravel, Zend, Symphony...) and utilise these.
I would also try and automate the page mapping (e.g. look at the URL and pull out the page from a rewrite which matches to the menu in your database)
best of luck

There are multiple options. Including static functions, global variables and passing the variable or object into the function.
The consensus for various reasons is to pass the variable into the function
$myVar = new Object\Or\Data();
function myFunction($myVar) {
//do stuff with $myVar
}
//then call the function
myFunction($myVar);
There are lots of answers to this question on stackOverflow, so have a deeper search. Here is an example

I found the solution to my problem and thought I would share here. I first set the call on the page.php to use desktopMenu(CURRENT_PAGE); and then on my main.inc.php I added this line
$thispage = CURRENT_PAGE;
function desktopMenu($thispage) {
//REST OF FUNCTION
}
And I set a table variable on each menu item called menu-group, so I can define the current menu group for a menu item and have the appropriate menu item highlighted when you're on that page or one of it's sub pages.
Thanks so much for the answers guys!

Related

Prevent end user manipulating URL to change content on website, method GET PHP

I have a personal search site project I'm building, at the moment the only data that is being displayed on the website is data that is retrieved using SELECT queries and the GET method using the super global $_GET['example']. Now I don't know if I'm doing this wrong but some parts of my page are only displayed if certain GET variables in the URL are set or not empty. Below shows how my URL looks
EXAMPLE: index.php?search_category=guitar&main_category=9&postcode_val1=NP22&distance_default=100&submit=search
I have a lot of these if(isset($_GET['search_category']) type conditions in my website which are replied upon and show particular parts of content depending whether or not these are either true or false.
I have been on a lot of other websites that have similar URL's, I have tried to alter and manipulate these and the content does not break, alter or change in any way yet when i try this with my url it breaks my page and only certain parts of content gets displayed by being based on what is set. Is there some other layer of protection I should add, would using something like a rewrite rule help? The code below shows how I have wrote a drop down box based on what has been set In the URL but if a user edits the URL this is easily broken.
if(isset($_GET['search_category']) && isset($_GET['main_category']) &&
isset($_GET['postcode_val1']) && isset($_GET['distance_default']))
{
$stmt = $getFromUi->dispCategories();
echo "<option value='0'>All</option>";
echo "<option value='#'>-------------</option>";
while($row = $stmt->fetch(PDO::FETCH_OBJ))
{
$selected = '';
if(!empty($_GET['main_category']) && $_GET['main_category'] == $row->cat_id)
{
$selected = ' selected="selected"';
}
echo '<option value="'.htmlentities($row->cat_id).'"'.$selected.'>'.htmlentities($row->cat_title).'</option>';
}
}
It will break because the strict nature of logic you use on your code. The && mark with isset mean any parameter you define not set will not evaluate to true. If the parameter is quite flexible why not ||.
If you need it to still evaluate all parameter try to do limit first if condition to main determiner. like $_GET['search_category'] and use the remaining $_GET['other_parameter'] as needed inside the block code of main if.
You would need to use a post method, so that this goes through as a request instead. In my experiance, get will only fetch the url you open - not actually pass anything through unless its in the URL.
Not sure if that made any sense, but check post out.
https://www.w3schools.com/tags/ref_httpmethods.asp is a good place to start to see the difference of get vs post.

What is the proper way of only having one page with get requests php?

For instance, I have viewpost.php and it's set up as needed and I only need to change the content within divs in there.
For example, I'm going to have to do viewpost.php?id=1,2,3 etc. But should I do EVERYTHING off index.php using index.php?action=viewpost&id=1?
Then also, do I use if statements, or do I communicate with my database using those get requests?
Overall, I plan to use modrewrite anyway, but I am clueless on the proper way to set up loading multiple pages off one, or a few php files.
I have a template and I just need to fill it using database data.
Easiest way is something very basic like this (Not very secure though)
$page = $_GET["action"];
if($page == null)
{
$page = "main";
}
if (file_exists("content/$page.php"))
{
include ("content/$page.php");
}
else
{
include ("includes/404.php");
}
A better solution is to use something like http://www.smarty.net/ to handle templating and content loading. Slightly more complicated, but most likely worth the extra effort if you're doing anything beyond a very simple website.
index.php?action=viewpost&id=1 this code in index:
if(isset($_GET['action']) && isset($_GET['id']))
{
$id = $_GET['id'];
if($action == "viewpost")
{
// action is viewpost
if(!ctype_digit($id))
{
// id isnt digit
die();
}
else
{
// viewpost
include('viewpost.php');
}
}
viewpost.php could look like:
just to be sure nothing bad happens when going right to viewpost.php you could see in the url if viewpost.php exists, or just do the security here (!ctype_digit($_GET['id']))
// since its already been secured with !ctype_digit, we can run queries right away
$q_findPost = mysqli_query($mysqli, "SELECT * FROM posts WHERE id=$id");
$r = mysqli_fetch_assoc($q_findPost);
// div stuff

Organizing a PHP page with a bunch of $_POST's

I am making quite a large online points/purchasing system in PHP and just have a fundamental question.
All the relevant stuff is on a single PHP page within the site, with "includes" from other parts of the site such as shopping cart, points review, products etc..., but throughout the page there are stages where the user clicks a form submit button to pass values via $_POST.
As there is a main page for all this stuff, I have a part at the top of the page where it takes all the POST values and makes decisions based upon them, like so:
if($_POST['add']) {
$product_id = $_POST['add'];
}
if($_POST['remove']) {
$rid = $_POST['id'];
$cart->del_item($rid);
}
if($_POST['empty']){
$cart->empty_cart();
}
if($_POST['purchase']) {
foreach($cart->get_contents() as $item) {
$sql="INSERT INTO wp_scloyalty_orders VALUES (".$user_id.", ".$item['id'].")";
$result=mysql_query($sql);
}
$cart->empty_cart();
unset($_SESSION['cart']);
}
if($_POST['add']) {
query_posts('post_type=prizes&showposts=-1&p='.$product_id.'');
while (have_posts()) : the_post();
$my_meta = get_post_meta($post->ID,'_my_meta',TRUE);
if($calctotalnew > $my_meta['pointsvalue']){
$cart->add_item(get_the_id(), 1, $my_meta['pointsvalue'], get_the_title());
} else {
echo 'You do not have sufficient points to redeem this product...';
}
endwhile;
wp_reset_query();
}
So my question is... is this really a good way to organize a system, having the form actions go to the same page that the form is on, and have a load of IF statements to decide what to do with the POST values?
Thanks! :)
it's generally best to capture separate POST calls (grouped by type) in separate actions. I usually go as follows:
page 1 has a form, which will submit to eg. product.php?action=add. In product.php you can route the 'add' action to the function add_product() (or whatever). Then when the product is added, just header the user back to the main page (or whatever page you'd like). This immediately tackles the problem with refresh-posts (user refreshing the page which will send the same data again).
following mvc imagine you have a controller Product which handles all the product actions. The skeleton could look like this (assuming function action_x will be executed when yoursite.com/product/x is requested):
class Product_Controller {
function action_show() {
}
function action_update() {
}
function action_delete() {
}
}
if your framework supports a default action of some sort you could route your actions:
function action_default() {
if(method_exists(array($this, 'action_'. $_POST['action']))) {
return call_user_method('action_'. $_POST['action'], $this);
}
}
ofcourse the same can be achieved without controller classes;
if(function_exists('action_'. $_POST['action'])) {
call_user_func('action_'. $_POST['action']);
}
function action_show() { }
...
and to illustrate the discussion in the comments;
function action_update() {
// do some update logic, query an UPDATE to mysql etc.
if($result) {
// optionally save a success message
Message::add('Your record has been updated');
header('Location: main_page.php'); // or another intelligent redirect function
} else {
Message::add('Sorry, something went wrong');
header('Location: error_page.php'); // or also main_page
}
}
This will also keep your code cleaner, as updating/adding/deleting stuff is radically different from showing stuff, this will prevent you from mixing up stuff. You could even call the show function from within the update function if you want to skip the redirect.
But in the end it's a matter of choice, led by pragmatism or your framework ;)
I hope this'll explain everything a bit, don't hesitate to ask for clarification
if you want to separate the logic from the interface then you can simple create new file and put the all logical and database related code in that file and include OR require that file in the view file
like
view.php interface file and
logic.php is your logic file then
first line in view.php is
require_once(logic.php');
and all the logic is in this files
simple MVC
Well, it seems I have to explain.
It absolutely does not matter how much IF statements you have in the POST handler. Your current design is okay, and there is no reason to ask nor change it.
The only thing that you may wish to add to your design is a front controller, which will take both entity (cart) and action("add") and call add() method of $cart class. these methods you may store one under another in the class source.
Though it is quite huge improvement, requiring great rethinking of the whole site architecture. So, you may stick with your current one.
As for your other question, how to display errors, here is an answer: php redirection not working

How to show a users last visited pages in wp / buddypress?

im trying to figure out how i can show the last 3-5 or so pages within my site a person has visited. I did some searching, and I couldn't find a WP plugin that does so, if anyone knows of one, please point me in that direction :) if not, I'll have to write it from scratch, and thats where i'll need the help.
I've been trying to understand the DB and how it works. I'm assuming that this is where the magic will happen, with PHP, unless there is a javascript option using cookies to do it.
Im open to all ideas :P & Thank you
If i were to code such a plugin, i'd use the session cookies to populate an array via array_unshift() and array_pop(). it'd be as simple as :
$server_url = "http://mydomain.com";
$current_url = $server_url.$_SERVER['PHP_SELF'];
$history_max_url = 5; // change to the number of urls in the history array
//Assign _SESSION array to variable, create one if empty ::: Thanks to Sold Out Activist for the explanation!
$history = (array) $_SESSION['history'];
//Add current url as the latest visit
array_unshift($history, $current_url);
//If history array is full, remove oldest entry
if (count($history) > $history_max_url) {
array_pop($history);
}
//update session variable
$_SESSION['history']=$history;
Now i've coded this on the fly. There might be syntax errors or typos. If such a mistake appears, just put a notice and i'll modify it. The purpose of this answer is mostly to make a proof of concept. You can adapt this to your liking. Please note that i assume that session_start() is already in your code.
Hope it helps.
===============
Hey! Sorry about the late answer, i was out of town for a couple of days! :)
This addon is to answer your request for a print out solution with LI tags
Here's what i'd do :
print "<ol>";
foreach($_SESSION['history'] as $line) {
print "<li>".$line.</li>";
}
print "</ol>";
Simple as that. you should read the foreach loop here : http://www.php.net/manual/en/control-structures.foreach.php
As for the session_start();, put it before you use any $_SESSION variables.
Hope it helped! :)
I'm going to update and translate the code above for WordPress 5+ because the original question has the wordpress tag. Note that you don't need session_start() anywhere.
Here it goes, add the code below to your singular.php template (or single.php + page.php templates, depending on what you need):
/**
* Store last visited ID (WordPress ID)
*/
function so7035465_store_last_id() {
global $post;
$postId = $post->ID; // or get the post ID from your template
$historyMaxUrl = 3; // number of URLs in the history array
$history = (array) $_SESSION['history'];
array_unshift($history, $postId);
if (count($history) > $historyMaxUrl) {
array_pop($history);
}
$_SESSION['history'] = $history;
}
// Display latest viewed posts (or pages) wherever you want
echo '<ul>';
foreach ($_SESSION['history'] as $lastViewedId) {
echo '<li>' . get_permalink($lastViewedId) . '</li>';
}
echo '</ul>';
You can also store latest viewed custom post types (CPT) by placing the so7035465_store_last_id() function in your single-cpt.php template.
You can also add it to a hook or inject it in your template as an action, but that is beyond the scope of this question.

Dynamically generating page links for a CMS

I've searched far and wide and every CMS tutorial out there either doesn't explain this at all or gives you a huge chunk of code without explaining how it works. Even on stack overflow I can't find anything close to the answer, though I'd be okay with eating my words if someone could point me to the answer.
I am using PHP and mysql for this project.
I am building a CMS. Its extremely simple and I understand every concept I think I'll need except how to dynamically generate pages and page links. The way I want to do it is by having a database table that stores the name of a page and the main content of the page. That's all. Then I'd just call a script to pull the main content of a page into whatever page I happen to call. No big deal, right? Wrong.
Here's the problem. If I were to do this then I'd have to create a file for every page I want to create that calls the script that pulls the content from the correct database row. So I could add all sorts of page names and contents into the table but I don't know how to call them without manually creating new files each time I want to link to a new page.
Ideally there'd be a script that creates links to pages based on the page name row of the DB table as the pages are created. But how do you get those links with the ?=pageName at the end? If I just knew how that worked then I could figure the rest out.
UPDATE
The second answer really confirmed everything I thought I had to do but there is one catch. My plan now is to split up all the code into a series of functions and either include or require them in different templates that will be used to format the way pages are displayed. I need one look for the home page and one other design for the rest of the pages. I'm thinking that I'll have a function that says if ID is 0 then call this page template.php else call this other template file.php. But how do I pass the required variables to these new files? Do I just include the index.PHP page in them?
Bill your actually on the right track. Almost all web software today does extensive URL processing. Traditionally you would have php pages on your web root and then utilize the query string in the URL to refine the page's output. You have already arrived at why this might not be desired. So the popular alternative is the Front Controller design pattern. Basically we funnel every request to your index.php page and then route the request to internal pages or apps outside the web root. This can get complicated fast and everybody seems to implement this pattern in unique ways.
We can utilize this pattern without the routing by simply putting our app in the index page. The script below shows an example of what your trying to do in the simplest of ways. We basically have one page with our script. We can request the virtual pages by changing the id query string in our url. For example www.demo.net/?id=0 can be utilized as an index to your site. This should be the same as www.demo.net without the 'id' query. Just keep solving those problems one by one even if you don't know what the problem is. Once you start looking at other peoples code, then you can start seeing how other people solved the same problems you have.
The solution below will get you started, but then what do you do when you want an admin page? How do you authenticate the user? Do you duplicate alot of the code for yet another page? If your serious about your CMS then your going to want to implement some kind of framework underneath it. A framework to process the url, route to your application, load configuration files, and probably manage your database connection. Yea it gets complicated, but not if you solve each problem one at a time. Utilize classes or functions to share code to start. At the very least include a common "bootstrap" file at the top of your page to initialize common functionality such as a database connection. Read Stack Overflow just to keep up with whats going on. You can learn alot of terminology and probably find some answers to questions you didn't even know you wanted to ask.
Below assume we have a table with the following fields:
page_id
page_name
page_title
page_body
<?php
//<--------Move outside of web root-------------->
define('DB_HOST', 'localhost');
define('DB_USER', 'cms');
define('DB_PASS', 'changeme');
define('DB_DB', 'cms');
define('DB_TABLE', 'cms_pages');
//<---------------------------------------------->
//Display errors for development testing
ini_set('display_errors','On');
//Get the requested page id
if(isset($_GET['id']))
{
$id = $_GET['id'];
}
else
{
//Make page id '0' an index page to catch all
$id = 0;
}
//Establish a connection to MySQL
$conn = mysql_connect(DB_HOST,DB_USER,DB_PASS) or die(mysql_error());
//Select the database we will be querying
mysql_select_db(DB_DB, $conn) or die(mysql_error());
//Lets just grab the whole table
$sql = "SELECT * FROM ".DB_TABLE;
$resultset = mysql_query($sql, $conn) or die(mysql_error());
//The Select Query succeeded, but returned 0 result.
if (mysql_num_rows($resultset)==0)
{
echo "<pre>Add some Pages to my CMS</pre>";
exit;
}
//This is our target array we need to fill with arrays of pages
$result = array();
//Convert result into an array of associative arrays
while($row = mysql_fetch_assoc($resultset))
{
$result[] = $row;
}
//We now have all the information needed to build our app
//Page name - Short name for buttons, etc.
$name = "";
//Page title - The page content title
$title = "";
//Page body - The content you have stored in a table
$body = "";
//Page navigation - Array of formatted links
$nav = array();
//Process all pages in one pass
foreach($result as $row)
{
//Logic to match the requested page id
if($row['page_id'] == $id)
{
//Requested Page
$name = $row['page_name'];
$title = $row['page_title'];
$body = $row['page_body'];
$page = "<b>$name</b>";
}
else
{
//Not the requested page
$page = $row['page_name'];
}
//Build the navigation array preformatted with list items
$url = "./?id=" . $row['page_id'];
$nav[] = "<li>$page</li>";
}
?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>SimpleCMS | <?php echo $title; ?></title>
</head>
<body>
<div>
<div id="navigation" style="float:left;">
<ul>
<?php
foreach($nav as $item)
{
echo $item;
}
?>
</ul>
</div>
<div id="content"><?php echo $body;?></div>
</div>
</body>
</html>
I think you need to read about $_GET.
I also recommend a decent PHP book. Forget online tutorials; they are (for the most part) utterly useless.

Categories