1

Got stuck on something. I added a verification for each request to PDFs in a specific folder. I've use .htaccess with prepend.php. It is on a Joomla website.

The goal is to allow subscribed member to see different PDFs in the folder, but reject the non-subscribed and visitor.

.htaccess

# set .pdf extension to be PHP
AddType php5-script .pdf

# match the .pdf extension
<FilesMatch "\.pdf$">
# set the prepend file setting
php_value auto_prepend_file "prepend.php"
</FilesMatch>

prepend.php

<?php

// Loading Joomla User core Files
define( '_JEXEC', 1 );
define('JPATH_BASE', '../');
require_once ( '../includes/defines.php' );
require_once ( '../includes/framework.php' );

// Create the Application
$app = JFactory::getApplication('site');

// Error Message : Please Log-in
$error = 'Veuillez vous connecter.';

// Check wether Joomla User is logged-in
$user = JFactory::getUser();

// Define user id
$ClientUserId = $user->id;

// Connect to databases
$link = mysqli_connect("localhost", "dbuser", "dbpsw", "dbname");

// Search for Account type
if($ClientUserId != 0) {
$resultabo = mysqli_query($link, "SELECT * FROM tablename WHERE user_id='$ClientUserId' ORDER BY id DESC LIMIT 1");
} else die($error);

// Controling wether the user is logged-in in a subscribed account
while($row = $resultabo->fetch_assoc()) {

    $abo = $row["account_id"];

    if($abo > 1 AND $abo < 7 ) {

        // Note : All $abo between 6 and 7 are "subscribed"

        // Sending headers to subscribed user
        header("Content-Disposition", "inline; filename=myfilename.pdf");
        header('Content-type: application/pdf');
        readfile($_SERVER['SCRIPT_FILENAME']); // serve the requested file
        exit(0);

    } elseif ($abo == 1) {

        // Note : 1 is a registered member but not subscribed

        // echo message : Your account is not subscribed to our website, please go on WebsiteName to subscribe.     
        echo "";

    } else {

        // echo message : You encountered an error during your request. Please reload the page or log-in once again.
        echo '';

    }

}

// If nothing is triggered, die.
die()

?>

<!DOCTYPE html>
<html>
<body style="background-color: white;">
</body>
</html>

Problem is : Prepend file does not get read first so I'm stuck with this. Second Problem : I remember I found a way to read the prepend.php file, but the verification didn't work.

The only way I could get this work was on my local website and with different code :

.htaccess (local)

# Adding PDF compatibility to check 
AddHandler php5-script .pdf
AddType application/x-httpd-php .html .htm

#Path of the directory where are stored the PDFs
php_value include_path "./journal/"

#Check wether or not user is logged-in & show pdf if logged-in
php_value auto_prepend_file "prepend.php"

prepend.php (local)

<?php

/* Loading Joomla User core Files */
define( '_JEXEC', 1 );
define('JPATH_BASE', '../');
require_once ( JPATH_BASE .'/includes/defines.php' );
require_once ( JPATH_BASE .'/includes/framework.php' );

/* Create the Application */
$app = JFactory::getApplication('site');

$error = "Une erreur est survenue";

/* Check wether Joomla User is logged-in */
$user = JFactory::getUser();

/* Define user id */
$ClientUserId = $user->id;

/* Connect to databases */
$link = mysqli_connect("localhost", "root", "", "dbname");

/* Search for Account type */
$resultabo = mysqli_query($link, "SELECT * FROM tablename WHERE user_id='$ClientUserId' ORDER BY id DESC LIMIT 1");

while($row = $resultabo->fetch_assoc()) {

    $abo = $row["account_id"];

    $error = "Une erreur s'est produite. Veuillez rafraîchir la page.";

        if ($abo == 1) die();

        else if($abo == 2) {

            header("Content-Disposition", "inline; filename=myfilename.myextension");
            header('Content-type: application/pdf');
            readfile($_SERVER['SCRIPT_FILENAME']); // serve the requested file
            exit(0);

        }

        else die();

}

die();

/* Old Method */
#if ($user->guest) die();
#else {
#   }

/* Sending back pdf */


?>

<html><body bgcolor="#FFFFFF"></body></html>

Thanks

Hansel F.
  • 148
  • 6
  • 1
    I don't understand. You want to prepend the execution of a PHP script before serving a PDF? When hitting a PDF file the PHP interpreter won't be called, so logically no PHP file will be prepended... – yivi Jan 09 '17 at 11:31
  • Well I wouldlike that before serving the pdf file, prepend.php runs and check wether it is a subscribed user or not. I got it working on local but couldn't get it working on actual website. – Hansel F. Jan 09 '17 at 11:37
  • 1
    The way you are doing is less than ideal. You'll only be able to do it that way by marking the PDF files as files to be handled by the PHP interpreter (which makes little sense), so the prepend directive gets executed. Much simpler, don't put the PDF files in a folder that's not accesible to the webserver, and serve all this files through a single php handler, using `readfile` (after checking the user has the requisite permissions). – yivi Jan 09 '17 at 11:41
  • 1
    Use something like this (http://stackoverflow.com/questions/13454083/secure-file-download-in-php-deny-user-without-permission) as a starting point, for example. – yivi Jan 09 '17 at 11:41
  • Ok thanks. So I would need to lead the user to a php file with a value, then it will check if the user is subscribed, and if he is, It will use the value to select the pdf good? – Hansel F. Jan 09 '17 at 11:46
  • 1
    Yup. You've got it. – yivi Jan 09 '17 at 11:47
  • 1
    I meant: "put the PDF files in a folder that's NOT accessible to the webserver", and not whatever I wrote. :P – yivi Jan 09 '17 at 11:48
  • But in a way, it isn't gonna work since if anyone get the link of the pdf, then it will kinda override the security, which is the php file. Or I should make the php file display so that people don't get the link to the pdf? – Hansel F. Jan 09 '17 at 11:51
  • 1
    Oh ok. Got the readfile() working. I will test out my verification. Thanks! – Hansel F. Jan 09 '17 at 12:40
  • There are a bunch of free or low cost extensions that will let you manage access to documents on your site using the built in access control. I'd suggest using one of those. Also you are making the whole thing way too complicated given that you have the Joomla API for managing access control. – Elin Jan 11 '17 at 07:45
  • @elin I thought of it, however I would prefer doing my own code so I learn to do this type of things. – Hansel F. Jan 12 '17 at 06:07
  • 1
    Then you should focus on using the Joomla API and learning to use that to code. That's really the best way to learn, use a framework. Use the Joomla API to access the Access controls (and also to create access rules for your documents if you want). Instead of dying you should be giving a forbidden error. – Elin Jan 13 '17 at 18:59
  • @Elin Thanks. This will definitly help me. – Hansel F. Jan 16 '17 at 08:18

0 Answers0