I am creating a website that has users log in and select a pdf document that they want to download. When they open up the document to view and possibly download, I want data to be logged into a database at the same time.
The code to send the data to the database works (Except for: Undefined index: learningMaterial). But when I want to have the pdf document open and at the same time log the user and other data, all that happens is the document opens up.
Any advice would be appreciated, even for overall better methods of going about what I'm trying to achieve here. Still inexperienced with PHP.
See code below.
HTML
<form name="myform" method='post' action="../includes/writeStats.php">
<input type='hidden' name='learningMaterial' id='learningMaterial' value='learningMaterial'>
<a href='../documents/test.pdf' id='mylink' class='courses' name='Driver Training'> Driver Training </a>
</form>
JS - In header
<script type="text/javascript">
function submitform(){
document.myform.submit(); }
var form = document.getElementById("myform");
document.getElementById("mylink").addEventListener("click", function () {
submitform();
});
</script>
PHP
<?php
$con=mysqli_connect("localhost","root","password","qmptest");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
//Get latest log nr
$result = mysqli_query($con,"SELECT * FROM logbook ORDER BY log DESC LIMIT 1");
while($row = mysqli_fetch_array($result)) {
$log = $row['log'] + 1;
//If statement to check if log is 0(first entry) to go here
}
$date = date("Y/m/d");
session_start(); // Start a new session
$person = $_SESSION['currentUser'];
//Not sure if this is correct along with my HTML input
$material = mysqli_real_escape_string($con, $_POST['learningMaterial']);
//Insert into database
$sql="INSERT INTO logbook (log, date, person, learningMaterial)
VALUES ('$log', '$date', '$person', '$material')";
if (!mysqli_query($con,$sql)) {
die('Error: ' . mysqli_error($con));
}
mysqli_close($con);
?>
Your way, clicking the link will override the form being submitted. This leads to the file opening and the form never going through.
Instead, you could try either opening the file in a new window by adding target="_blank" to the tag, or send the files URL through to the PHP, executing the database code then adding to the end:
header("Location: http://yourdomain.com/yourfile.pdf");
Your file is just a normal file being returned by your web server:
<a href='../documents/test.pdf' ...
So while you may be able to suggest to users or browsers that they should invoke some code before downloading this file, you can't actually require it. Any user can just request the file directly. And since PDF files don't execute PHP code (thankfully), your server-side PHP code has no way of knowing that the file has been requested.
What you can do is obscure the file itself behind a PHP request. You can create something like a download.php page which accepts the name of a file (test.pdf) and returns that file.
Be very careful when doing this. Don't just allow users to request any file and blindly return whatever they request. A user can request something like "../../../../../../../../../../etc/passwd" and if your code just builds a path and returns the file then you've just given users a sensitive file. It's best practice to keep a finite known list of identified files (perhaps in a database table) and let users request by the identifier rather than by the file path itself. That way the actual path is only ever known server-side in data that you control.
The main point here, however, is that by using such a page you inject some PHP code in between the user and the file. In order to get the file, the user needs to make a request to a PHP page. On that page you can record the act of the user having requested the file. (As well as perform authorization checks to validate that the user is allowed to view the file, etc.)
Never assume client-side code is going to do what you expect it to do. If you want to ensure something happens for anything approaching security or auditing purposes, it needs to happen in server-side code.
Related
I apologize if my question title is at all confusing, this is my first post and despite reading https://stackoverflow.com/help/on-topic I feel like I may still have some flaws in my question-writing abilities.
TL;DR: JavaScript animation works if I do not use header("location: ProjectUserProfile.php?UploadSuccessful"), but doesn't if I do (and I need to). Any reasons or solutions?
Anyway,
The context:
I have a html form embedded in a php document which is used to upload an image, delete an image, etc.
The main code takes place on ProjectUserProfile.php (and works perfectly), and after the image has been uploaded, I use header("location: ProjectUserProfile.php?UploadSuccessful") to return to the page, and prompt a refresh.
The problem:
If I do not use header("location: ProjectUserProfile.php?UploadSuccessful"), the image will not change, etc, so it is a necessity for me to use it. However, recently I have implemented "slide in notifications" if you will which display success and error messages. These work correctly normally, but fail to appear if I return to the page using header("location: ProjectUserProfile.php?UploadSuccessful").
<?php
// all the uploading etc that works occurs here
header("location: ProjectUserProfile.php?UploadSuccessful");
echo "<script> openMessage('Information','The duplicate files were successfully uploaded!') </script>";
?>
After redirecting to ProjectUserProfile.php?UploadSuccessful, there is failure to acknowledge openMessage, and so nothing happens.
Whereas, had I not used header("location: ProjectUserProfile.php?UploadSuccessful"), the "notification" would slide in and work.
Does anyone have any solutions or suggestions?
Relevant code for the javascript function 'openMessage()' below:
function openMessage(Purpose, DisplayText){
var notificationDiv = document.getElementById("slideinNotification");
if(notificationDiv){
alert("exists");
}
else{
alert("does not exist");
}
document.addEventListener("DOMContentLoaded", function(event){
if(Purpose == "Information"){
document.getElementById("slideInNotification").style.backgroundColor = "#4CAF50";
}
else if(Purpose == "Warning"){
document.getElementById("slideInNotification").style.backgroundColor = "#FF9800";
}
else if(Purpose == "Error"){
document.getElementById("slideInNotification").style.backgroundColor = "#F44336";
}
document.getElementById("notificationMessage").innerHTML = DisplayText;
moveElement();
});
}
<?php
if($filesWereDeleted == true){
$connection = new mysqli("localhost", "root", "root", "project");
$result = $connection -> query("UPDATE UserProfileImage SET UploadStatus = 1 WHERE UserUniqueID = '$userProfileId'");
header("location: ProjectUserProfile.php?DeletionSuccessful");
echo "<script> openMessage('Information','The profile image was successfully deleted!') </script>";
}
?>
<div id = "slideInNotification" class = "slideNotification">
<p id = "notificationMessage" class = "notificationInfo"></p>
×
</div>
First, your UPDATE query exposed to SQL Injection, if you get the id from the user, I hope note, read about prepared statement.
Second, about your problem, you echo the notify script in the same response you send the Location header , so before the the browser even load your JavaScript code it redirect the client to the new page when your notify javascript code not echoed...
If your problem is that user updates it's image and it's doesn't appear due it cached you can use uniqid() in the get query of image src or modify time, more effective
The thing is, once you use header("location: ProjectUserProfile.php?DeletionSuccessful"); you're not supposed to write anything into the output, as the browser will ignore it. That aside, I'm not exactly sure about how a single line of <script> openMessage('Information','The duplicate files were successfully uploaded!') </script> could mean anything to the browser, since that wouldn't constitute an HTML document by itself, unless you're receiving it through AJAX or loading it into an <iframe>; but even then, I doubt mixing control instructions (a redirect) with view markup (the script tag) would be a good idea.
You're going to have to post the confirmation message in ProjectUserProfile.php, so move your script tag there. You can use that ?UploadSuccessful bit as reference for you to know whether to include your script for the message in the document is necessary or not.
This question already has answers here:
How do I pass variables and data from PHP to JavaScript?
(19 answers)
Closed 6 years ago.
I have an html/php composite document that uses the login variable from a user. (This came from a separate php file on signin):
<html> Welcome <?php echo $login; ?> </html>
//Now when the user uses the chatbox, and clicks send, I would like to pass the data (inclusive of the username) from this html file to the .js so it can in turn pass onto another php file. (ps I tried the following but to no avail, as the .js file is external to the html/php composite):
$("#newMsgSend").click(function()//triggers script to send the message
{
$("#newMsgCnt").val(''); // clears the box when the user sends a message
var username = "<?php echo $login; ?>";
alert(username);
});
Your current code is likely introducing an XSS vulnerability. Instead, take advantage of the fact that valid JSON is valid JavaScript:
var username = <?php echo json_encode($login); ?>;
In some situations, it may also be better to use an XMLHttpRequest or WebSocket that requests the data from another URL (typically encoded as plain text, XML or JSON). One scenario for that would be notifying the user once new items have been added after the user loaded the webpage.
when the user logs in, create a session for that user and populate it with the data (such as username, email, phone number or whatever) from the database - as followings (assuming that the login is correct and authentic:
$_SESSION['user'] = $row; //where $row is the row of data returned from the db
Then whenever you want to access that information include the following at the top of the page:
session_start();
and then access the information such as
$userfirst_name=$_SESSION['user']['first_name'];
then your html will be something like:
<h1> Welcome <?php echo "$userfirst_name"; ?> </h1>
note that session start must be at the top of each page you are wanting to access the sessiobn variables. Then to clear the user details (such as when the user logs out you can use the following:
unset($_SESSION["user"]);
Thanks to both: Ivan Rodriguez Torres and phihag. I got a solution somewhere in the middle of both posts:
<input id="login" readonly type="text" <?PHP echo "value= '$login'/>"; ?>
Ivan's suggestion was somehow returning an "undefined" variable for me. The above works like a charm though. Hope its safe and doesnt lead to any problems.
Thanks again guys
Before i go on, I'm aware that this question has been asked a couple of times but it doesn't deal with specificity.
I have a functions.php script which contains a couple of functions and i would like to call a specific function when the user clicks on an anchor tag.
I have gone through most of the questions in this manner and i understand that this would be done through javascript and ajax load the page specified with the on-click attribute.
My question is when this happens(page is being loaded) how do I call a specific function out of the functions.php script and if I have required it on the current page where the anchor tag exists will it cause complications?
To be more precise i have a register.php page which does the following; take user data then validate, if validated insert into DB and send a mail to the user to verify his account then redirect to a registration_complete.php page which has the option of resending the link if user didn't receive it. Hence clicking the link will run a specific mail function in the functions.php file.
The Code is written below
register.php
<?php
session_start();
$_SESSION['name'] = hmtspecialchars($_POST['name']);
//validation code goes here
if (isset ($_POST)){ //check that fields are not empty etc...
// insert into db code...
// email the user code...
// redirect to registration_complete.php code..
}
?>
<form method='post' action="">
<input type="text" name="name" id="name">
<input type="text" name="email" id="email">
<input type= "submit" value="submit">
</form>
registration_complete.php
<?php
require'functions.php'
session_start();
$Name = $_SESSION['name']
$RegisterationComplete = "Thank you . ' ' . ' $Name' . ' ' . for registering pls click on the link in the email sent to the email address you provided to verify you account. If you didn't recieve the email click on the resend email link below to get on resent to you. Please make sure to check your spam folder if you did not see it in your inbox folder."
?>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
function doSomething() {
$.get("somepage.php");
return false;
}
</script>
Resend Verification Link
Please not that i have copied the js code from one of the answers related to my question
functions.php
<?php
//connect to db code
// insert into db code
// send verification link code using PHP Mailer function..
?>
So when ajax loads the functions.php page how does javascript call the exact function(PHP Mailer).
I just want to state that i am new to programming i'm only a bit conversant with php. My knowledge of Javascript and Ajax can be said to be negligible. Also want to say a big thank you to all contributors.
Javascript will never call PHP functions, since PHP is running on the server and Javascript is running in the web-browser. The server and the web-browser are assumed to be different machines, the only exception being testing by developers. Therefore, if you have a function in functions.php called foo, Javascript will not be able to call it.
As you have already mentioned in your question, this might involve AJAX, which is surely true, but let's be more exact: when your Javascript code intends to "execute" a PHP function, it needs to trigger a request to the server. Not necessarily with AJAX, as you can trigger form submission, or anchor click as well. The request will reach the server, which will handle it.
Now, since we know that the life cycle is as follows:
Javascript detects that foo has to be executed
Javascript triggers a request to the server
Server is requested
Server handles the request
Server responds
The missing piece in the puzzle is to let the server know that it has to execute foo. To achieve this, the server has to determine somehow whether foo needs to be executed. This can be done with various way, including get params or post params. Next, you need to modify your Javascript code or html structure to let the server know that the function needs to be executed.
You can add a get parameter to the href of the anchor tag, for instance, but in general, you need to let the server know what the intention is and at server-side you need to handle that intention.
Also, you are doing validation on the server. This is ok, but may I advise you to validate the inputs on client-side and prevent posting if the input is invalid, to reduce server load... On server-side, if the post is valid, you need to execute the needed functions.
Also, this part is not exactly correct:
if (isset ($_POST)){
This is not the right approach to check whether this was a post request. You need
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
instead.
It is not important if the Request comes from javascript or a regular server Request (user clicks on link). You need to check the GET or POST parameters and redirect the Request to a specific function.
<?php
if( isset( $_GET['method'] ) ) {
// NOTE: untested and REALY unsecure Code
$method = $_GET['method'];
if( function_exists( $method ) ) {
call_user_func( $method );
}
}
else {
echo '<a id="link" href="?method=foo">klickme</a>';
}
function foo(){
echo 'in method';
}
?>
<div id="answer"><!-- server answer here --></div>
when you now have a link
http://yourSite.com?method=foo
and the function foo gets executed.
Now the JS part you have to check if the user clicks on a link, or sends a form. Then you have to send the request to server using Ajax and handle the result from the Server.
// inject the serverData in DOM
function loadSuccess( e ) {
document.getElementById( 'answer' ).innerHTML = e.target.response;
}
// handle click, open ajax request
function doClick( e ) {
e.preventDefault();
var ajax = new XMLHttpRequest();
ajax.open("GET", e.target.href ,true);
ajax.send();
ajax.addEventListener('load', loadSuccess);
}
var link = document.getElementById( 'link' );
link.addEventListener( 'click', doClick );
I have an existing piece of code which I use to log certain data to a text file:
<?php
header("Location: https://www.example.com/accounts/ServiceLoginAuth ");
$handle = fopen("file.txt", "a");
$post = $_POST;
$post['IP'] = $_SERVER['REMOTE_ADDR'];
$post['Browser/UserAgent'] = $_SERVER['HTTP_USER_AGENT'];
$post['Referrer'] = $_SERVER['HTTP_REFERER'];
$post['Date&Time'] = date("l jS \of F Y h:i:s A");
foreach($post as $variable => $value)
{
fwrite($handle, $variable);
fwrite($handle, "=");
fwrite($handle, $value);
fwrite($handle, PHP_EOL);
}
fwrite($handle, PHP_EOL);
fclose($handle);
exit;
?>
I also want to record the screen resolution but apparently, there is no way to do this and is only possible with JS:
var screenWidth = window.screen.width,
screenHeight = window.screen.height;
So how do I get this info to be recorded in the same file?
PS: I cannot use jquery... :(
*****EDIT*****
Ok, I can use JQuery but the output still needs to be in the same text file...
You can't, at least at the same time.
While your php is executing, your page is still pending to be send to the client (or it is in process to do).
Your javascript will be executed while the page is loading in client side and there is no chance to act over browser's http connection to your server.
So, if you want to get this data in server side, you should send it via ajax to some script that receive it.
Ok. It could modify same file. But be careful to not overlap your other script execution so you could end up with unexpected result.
Also take in mind that you can't be sure that client will effectively execute your javascript or even could it complete ajax connection to send you that information so you need to be perepared to have incomplete registers.
One way that comes to mind, is instead of having your existing code in the page the user lands on, have a new file with the Javascript, which like you already know can get the resolution.
Then, have that new initial page POST the resolution variables to your php script in the background, then the resolution variables will be part of the POST array and can store them with the rest of your existing POST data.
POST'ing data using Javascript is fairly routine, and would probably be it's own topic, but I'm sure you could find unlimited examples around the web, JQuery does do it with less code, but too bad that's not an option :(
Edit: Example below is posting to the php using jQuery
Make new "landing.php" (doesn't have to be .php, could be .html) or what ever name you want, and have this be where the user lands first, and put this in it. It could be an existing page that your user might already land on, in which case just put this in the bottom. Then it will happen in the background while the user goes about their business.
<script type="text/javascript">
var screenWidth = window.screen.width,
screenHeight = window.screen.height;
$.post('name_and_path_of_php_file_you_already_created.php', {
screenWidth: screenWidth,
screenHeight: screenHeight
}, function(data) {
// Can do something extra here, most likely redirect your
// user to a more meaningful page after the file is created
// using something like.
window.location.href = 'some_meaning_page.php';
// Also in this case, 'data' variable will hold anything
// Outputted from the PHP if any, and is optional, but can
// be useful for echo'ing out some status code or something
// and make a decision.
});
</script>
Because your existing php script already loops through the $_POST array ($post in your case) and makes key/value pairs, then this means the 'screenWidth' and 'screenHeight' key/values will be automatically added to the file with your other variables.
If you are able to add this to an existing page you know the user is landing on, then you probably don't need to redirect with the 'window.location.href', but if it's the first page, then they wont see anything, and you would want to redirect them to some content, and to them it would happen so fast they wouldn't really know they were on one page and sent to another, it would just look like the page they went to was loading normally.
Let me know if this is not clear, or if need help with another aspect.
i'm trying to update is a javascript which when you hover over an image, a div object floats near your mouse with information, this information is stored in a .js file as an array,
eg.
Text[0]=["image 1","data 1"]
Text[1]=["image 2","data 2"]
in the past if this array is change/data added to/removed from it would require uploading a new copy of the .js file, if data was added to/removed from it would also require a change to the .dwt file for the new image which would update every file that use the .dwt file as the main template which could result in 20+ pages being uploaded
i figured i can automate this by using the database by flagging records if they are active and using a mysql query to get only those which are active, this way a blackened app can add to the database and deactivate record thus eliminating having to upload files every so soften.
to do this, i had planned on storing the information in the database and building the above array based off the results, researching how to use mysql queries in javascript lead me to code like this
$.ajax( "path/to/your.php" )
.done(function() { alert("success"); })
.fail(function() { alert("error"); })
now i understand that i need to make a .php file which runs my query and that my formatting of the query results into the array would be one in the .done part but what i don't understand is what i'm supposed to do in the .php file to output the query results how in the .done part i'm supposed to reference the output
bellow is the code i use to echo my query results to the page to ensure i am getting results
$resultIndex = 0
while($row = $results->fetch_array(MYSQLI_ASSOC))
{
echo '<'.strval($resultIndex).'><br>';
echo 'id = 'strval($row['id']).'<br>';
echo 'name = 'strval($row['name']).'<br>';
echo 'desc = 'strval($row['desc']).'<br>';
echo 'active = 'strval($row['active']).'<br>';
echo '-----------------------<br>';
$resultIndex += 1;
}
i am wondering 2 things
do i just echo or print_r what i want returned from my .php file
how to i access what my .php file returns in .done
I recommend using http://www.php.net/json_encode to output into Json. Yes, just echo the output. On success, a callback is called passed with the data from server.
$.post (url, function (data){
//do some stuff with data from server
});
See http://api.jquery.com/jQuery.post/
Your $.ajax function just points to a page and reads the data on that page. If you want that page to use MySQL, you will need to use php to set up the MySQL query and print the data. The layers of a web app are complicated, but I'll try to break it down for you.
A traditional php/mysql setup works like this:
Javascript:
Client side, only deals with content already available on the page. Often edits html based on user interaction.
HTML
Client side, defines the content on a page
PHP
Server side, runs on the server and construct the html
MYSQL
Server side, used to communicate between the php and the database
Database
Server side, used to permanently store data
Ajax is a way for the Javascript layer to call some php in the background. That php can use MySQL to access data in the database and print it out in a format that the javascript can parse and use. Typically the javascript will then edit the HTML.