Jump to content
Larry Ullman's Book Forums

Chapter 5 view_pdf.php


Recommended Posts

Hi Larry,

I used your view_pdf.php script from Chapter 5 as template for a view_video.php script (below) to view uploaded MP4 videos instead of PDF files (I only changed the PDF variable to MP4 per your script). The script executes perfectly fine except it inserts a duplicate record into the MariaDB "history" table with exactly the same timestamps every time a video is viewed. I only added a "video" ENUM value to the "type" column so to have the following types: page, pdf, video.

Any suggestions as I could not find any solution on the web.

Thank you.

 

<?php

// This pages retrieves and shows a video.

// Require the configuration before any PHP code as the configuration controls error reporting:
require('./includes/config.inc.php');
// The config file also starts the session.

// Require the database connection:
require(MYSQL);

// Assume invalid info:
$valid = false;

// Validate the video ID:
if (isset($_GET['id']) && (strlen($_GET['id']) === 63) && (substr($_GET['id'], 0, 1) !== '.') ) {

	// Identify the file:
	$file = VIDEOS_DIR . $_GET['id'];

	// Check that the video exists and is a file:
	if (file_exists ($file) && (is_file($file)) ) {

		// Get the info:
		$q = 'SELECT id, title, description, file_name FROM videos WHERE tmp_name="' . escape_data($_GET['id'], $dbc) . '"';
		$r = mysqli_query($dbc, $q);
		if (mysqli_num_rows($r) === 1) { // OK!
	
			// Fetch the info:
			$row = mysqli_fetch_array($r, MYSQLI_ASSOC);
	
			// Indicate that the file reference is fine:
			$valid = true;
			
			// Only display the video to a user whose account is active:
			if (isset($_SESSION['user_not_expired'])) {

				// Bonus material! Referenced in Chapter 5.
				// Record this visit to the history table:
				$q = "INSERT INTO history (user_id, type, item_id) VALUES ({$_SESSION['user_id']}, 'video', {$row['id']})";
				$r = mysqli_query($dbc, $q);
	
				// Send the content information:
				header('Content-type:video/mp4'); 
				header('Content-Disposition:inline;filename="' . $row['file_name'] . '"'); 
				$fs = filesize($file);
				header("Content-Length:$fs\n");

				// Send the file:
				readfile ($file);
				exit();
				
			} else { // Inactive account!
	
				// Display an HTML page instead:
				$page_title = $row['title'];
				include('./templates/header.html');
				echo "<h1>$page_title</h1>";
	
				// Change the message based upon the user's status:
				if (isset($_SESSION['user_id'])) {
					echo '<div class="alert"><h4>Expired Account</h4>Thank you for your interest in this content, but your account is no longer current. Please <a href="renew.php">renew your account</a> in order to access this file.</div>';
				} else { // Not logged in.
					echo '<div class="alert">Thank you for your interest in this content. You must be logged in as a registered user to access this file.</div>';
				}
	
				// Complete the page:
				echo '<div>' . htmlspecialchars($row['description']) . '</div>';
				include('./templates/footer.html');	
	
			} // End of user IF-ELSE.
					
		} // End of mysqli_num_rows() IF.

	} // End of file_exists() IF.
	
} // End of $_GET['id'] IF.

// If something didn't work...
if (!$valid) {
	$page_title = 'Error!';
	include('./templates/header.html');
	echo '<div class="alert alert-danger">This page has been accessed in error.</div>';
	include('./templates/footer.html');	
}
?>

 

Link to comment
Share on other sites

Hmmm...this is a tough one. There's only one INSERT query in this page being executed. So either this script is being run twice for each video view--which is possible--or the same query is being executed elsewhere in your application, which is easy to check. 

Link to comment
Share on other sites

Hi Larry,

Thank you very much for your response. I have checked both the videos.php and view_video.php scripts again and also compared them to the original pdfs.php and view_pdf.php scripts, which execute perfectly. Apart from the variable and Content-type changed from "pdf" to "mp4" and "application/pdf" to "video/mp4" in the video scripts, the pdf and video scripts are identical. If the view script is executed twice, shouldn't two videos instead of one open up? (I added the target="_blank" element to open the pdfs and videos in a new tab).

Link to comment
Share on other sites

My theory is there may be something about how videos are served to and loaded from the browser that causes the double insert. But that's just a wild guess. You'll really need to do some detective work here.

I'd start by making sure no other script in your application runs the same INSERT query. Unlikely, but best to rule out the obvious.

Then confirm that you're actually getting duplicate inserts and not just making a mistake when viewing your data in the database. 

Then make sure you don't have duplicate references to the script. 

If you're still not finding it, then start playing with the script to see if you can isolate a cause. Do you get duplicates regardless of what browser you use? Do you get duplicates regardless of the video size? 

Link to comment
Share on other sites

 Share

×
×
  • Create New...