prevent direct access to PDF link for guest users - .htaccess

I have a joomla site. And have some pdf files into the root of the website.
Is there a way to protect the DIRECT ACCESS to the pdf's for the GUESTS(public) users.. and allow for REGISTERED users?
I tried with htaccess(deny) but registered users can't view the pdf directly too..
Searched but didn't find nothing about this.. PLEASE can somebody help.
Thank you

You must use document management plug-in if you wont want to write your own php codes.SO, DOCman is a powerful document management solution for Joomla. You can check it from following link.
http://extensions.joomla.org/extensions/directory-a-documentation/downloads/10958

Create a file called download.php
Add the following code to download.php file enclose with php tag
define('_JEXEC', 1);
define('DS', DIRECTORY_SEPARATOR);
if (file_exists(dirname(__FILE__) . '/defines.php')) {
include_once dirname(__FILE__) . '/defines.php';
}
if (!defined('_JDEFINES')) {
define('JPATH_BASE', dirname(__FILE__));
require_once JPATH_BASE.'/includes/defines.php';
}
require_once JPATH_BASE.'/includes/framework.php';
// Mark afterLoad in the profiler.
JDEBUG ? $_PROFILER->mark('afterLoad') : null;
// Instantiate the application.
$app = JFactory::getApplication('site');
// Initialise the application.
$app->initialise();
$user = JFactory::getUser();
$getfile = JRequest::getVar('file',null,'get','string');
if($getfile){
if($user->get('id') == 0){
die('permission denied');
}
$link = "/files/".$getfile.".pdf"; // Locate the pdf file
$file = JPATH_SITE.$link;
header("Content-Type: application/octet-stream");
$filename = $getfile.'.pdf';
header("Content-Disposition: attachment; filename=".urlencode($filename));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
}
$app->close();
URL example :- www.example.com/download.php?file=filename
And make sure you have change the $link variable as you need.

In .htacess file you have to add the following code
deny from all
And it should be located under the invoice folder where the pdf files is located.
If you use deny from all then file do not have download access for the particular directory where the htacess file is located.
To allow download access for registered user the below controller has to be called instead of direct file path url.
URL example :- www.example.com/index.php?option=com_temp&task=temp.downloadmypdf&file=filename
public function downloadmypdf(){
$user = JFactory::getUser();
$getfile = JRequest::getVar('file');
if($user->get('id') == 0){
die('permission denied');
}
$link = "/invoice/".$getfile.".pdf";
$file = JPATH_SITE.$link;
header("Content-Type: application/octet-stream");
$filename = $getfile.'.pdf';
header("Content-Disposition: attachment; filename=".urlencode($filename));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
JFactory::getApplication()->close();
}
Credits goes to Ashlin rejo.

Related

download files outside the document root using PHP

I'm trying to download a file using readfile(); in PHP but I'm having trouble, here's my code:
<?php
$getdir = $_GET['dir'];
$getdoctype = $_GET['doctype'];
$getfile = $_GET['filename'];
$dir = "/var/www/uploads/$getdir/$getdoctype/";
$type = mime_content_type( $dir . '/' . $getfile );
$contents = file_get_contents($dir . '/' . $getfile);
if (file_exists($getfile)) {
header('Content-Type: ' . $type);
header('Content-Disposition: attachment;filename=' . $getfile);
readfile($getfile);
}
else{
echo "File Not Found";
}
?>
What am I doing wrong? I want to download the file thats stored in $getfile variable. I want to use all filetypes and all filesizes so thats why I did it like this.
The error I keep getting when I click on the file is: "File Not Found" as per my code. But it does exist.
Please also keep in mind that the website that host these files is SSL enabled
You should try replace this code:
file_exists($getfile) => file_exists($dir . '/' . $getfile)
readfile($getfile); => readfile($dir . '/' . $getfile);
But it's very dangerous use $_GET parameters to load file from filesystem, don't use this code on public website.
Your not pointing to the file correctly.
<?php
$getdir = $_GET['dir'];
$getdoctype = $_GET['doctype'];
$getfile = $_GET['filename'];
$dir = "/var/www/uploads/$getdir/$getdoctype/";
if (file_exists($dir . $getfile)) {
$type = mime_content_type( $dir . $getfile );
header('Content-Type: ' . $type);
header('Content-Disposition: attachment;filename=' . $getfile);
readfile($dir . $getfile);
}
else{
echo "File Not Found";
}
?>

Joomla Exporting Or Downloading Reports To CSV

I have the following code in my inventory section when i run this code it save an excel file but the result showing the whole html file not my data.
<?php
$csv = NULL;
$arr = array("product_name","product_sku","product_in_stock","virtuemart_product_id","product_price_display","product_instock_value");
$csv = "Product Name, Product SKU, In Stock, Booked ordered products, Cost Price, Stock Value \n";
$c=0;
while(list($key,$value)=each($arr)){
$c++;
$cc=1;
foreach ($this->inventorylist as $key => $product){
$cc++;
$csv .= join(',',array($product->product_name.",".$product->product_sku.",".$product->product_in_stock.",".$product->virtuemart_product_id.",".$product->product_price_display.",".$product->product_instock_value))." \n";
}
}
JResponse::clearHeaders();
JResponse::setHeader('Content-Type', 'application/vnd.ms-excel', true);
JResponse::setHeader('Content-Disposition', 'csv; filename=inventory_report.csv; size='.strlen($csv), true);
JResponse::sendHeaders();
Any help will be appreciated.
Thanks
Khalique
Here's the brute force solution just to get you going:
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");
// Echo the csv content.
echo "foo,bar\n1,2";
// Close the application gracefully.
JFactory::getApplication()->close();
A slightly cleaner way without using views, but including &format=raw in the URL is:
$app = JFactory::getApplication();
$doc = JFactory::getDocument();
$doc->setMimeEncoding('application/vnd.ms-excel');
$app->setHeader(
'Content-disposition',
'attachment; filename="inventory_report.csv"',
true
);
echo "foo,bar\n1,2";
But the best way is to use a download view based on the raw document type. You can find an example of this in com_banners:
Controller: https://github.com/joomla/joomla-cms/blob/staging/administrator/components/com_banners/controllers/tracks.raw.php
View: https://github.com/joomla/joomla-cms/blob/staging/administrator/components/com_banners/views/tracks/view.raw.php
You might also gain some extra insight from this discussion https://groups.google.com/forum/#!topic/joomla-dev-general/dRa_39AGDBY

Magento: Browser detection to load right language

How do I implement a browser detection into Magento to load the right language.
Example:
If a US User is surfing to my Magento shop, Magento should load the path: ..myshop../usa/
usa=storecode
If a japanese User is surfing to my Magento shop, Magento should load the path: ..myshop../jp/
jp=storecode
and so on
I guess I have to adapt the .htaccess with rewrite Urls, but I never did that before. How do I have to do it?
How does the code of browser detection look like and where do I have to put it? In the header.phtml?
thank you very very much in advance!
Edit:
index.php in CE 1.7.0.2 looks like this
/**
* Error reporting
*/
error_reporting(E_ALL | E_STRICT);
/**
* Compilation includes configuration file
*/
define('MAGENTO_ROOT', getcwd());
$compilerConfig = MAGENTO_ROOT . '/includes/config.php';
if (file_exists($compilerConfig)) {
include $compilerConfig;
}
$mageFilename = MAGENTO_ROOT . '/app/Mage.php';
$maintenanceFile = 'maintenance.flag';
if (!file_exists($mageFilename)) {
if (is_dir('downloader')) {
header("Location: downloader");
} else {
echo $mageFilename." was not found";
}
exit;
}
if (file_exists($maintenanceFile)) {
include_once dirname(__FILE__) . '/errors/503.php';
exit;
}
require_once $mageFilename;
#Varien_Profiler::enable();
if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) {
Mage::setIsDeveloperMode(true);
}
#ini_set('display_errors', 1);
umask(0);
/* Store or website code */
$mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : '';
/* Run store or run website */
$mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store';
Mage::run($mageRunCode, $mageRunType);
But this Link describes the follwing code which you cannot simply replace:
require_once 'app/Mage.php';
/* Determine correct language store based on browser */
function getStoreForLanguage()
{
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
foreach (explode(",", strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])) as $accept) {
if (preg_match("!([a-z-]+)(;q=([0-9.]+))?!", trim($accept), $found)) {
$langs[] = $found[1];
$quality[] = (isset($found[3]) ? (float) $found[3] : 1.0);
}
}
// Order the codes by quality
array_multisort($quality, SORT_NUMERIC, SORT_DESC, $langs);
// get list of stores and use the store code for the key
$stores = Mage::app()->getStores(false, true);
// iterate through languages found in the accept-language header
foreach ($langs as $lang) {
$lang = substr($lang,0,2);
if (isset($stores[$lang]) && $stores[$lang]->getIsActive()) return $stores[$lang];
}
}
return Mage::app()->getStore();
}
/* Auto redirect to language store view if request is for root */
if ($_SERVER['REQUEST_URI'] === '/') {
header('Location: '.getStoreForLanguage()->getBaseUrl());
exit;
}
#Varien_Profiler::enable();
#Mage::setIsDeveloperMode(true);
#ini_set('display_errors', 1);
umask(0);
Mage::run();
Can anybody help me to find out where to put it or where to adapt the index.php
Thank you again!
The request the browser sends has a field called "Accept-Language" header. It's formatting isn't so intuitive and if you wanted to do it correctly, is beyond the ability of the htaccess file and mod_rewrite to parse properly. Here's a typical "Accept-Language" request header:
Accept-Language: da, en-gb;q=0.8, en;q=0.7
Which means: "I prefer Danish, but will accept British English and other types of English"
So you can't simply look for the first two letters of the field. If you don't have Danish, then you've got to continue parsing to find the right language. Magento probably has some ways of dealing with this, for example: http://www.magentocommerce.com/wiki/multi-store_set_up/how_to_automatically_redirect_to_a_store_view_based_on_the_browser_language
Just paste the following code after require_once $mageFilename; in your CE 1.7.0.2 index.php:
/* Determine correct language store based on browser */
function getStoreForLanguage()
{
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
foreach (explode(",", strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])) as $accept) {
if (preg_match("!([a-z-]+)(;q=([0-9.]+))?!", trim($accept), $found)) {
$langs[] = $found[1];
$quality[] = (isset($found[3]) ? (float) $found[3] : 1.0);
}
}
// Order the codes by quality
array_multisort($quality, SORT_NUMERIC, SORT_DESC, $langs);
// get list of stores and use the store code for the key
$stores = Mage::app()->getStores(false, true);
// iterate through languages found in the accept-language header
foreach ($langs as $lang) {
$lang = substr($lang,0,2);
if (isset($stores[$lang]) && $stores[$lang]->getIsActive()) return $stores[$lang];
}
}
return Mage::app()->getStore();
}
/* Auto redirect to language store view if request is for root */
if ($_SERVER['REQUEST_URI'] === '/') {
header('Location: '.getStoreForLanguage()->getBaseUrl());
exit;
}
Make sure you don't delete or overwrite any code in your index.php file and you should be fine!

downloading files as a corrupted files in kohana

hi guys i'm facing problem with file upload and download in kohana
my controller is like this:
class Controller_Test extends Controller
{
public function action_display()
{
$type = $_FILES['file']['type'];
switch ($type)
{
case 'image/gif':
$otype='.gif'; break;
case 'image/jpeg':
case 'image/pjpeg':
$otype= '.jpg'; break;
case 'image/png':
$otype= '.png'; break;
case 'application/octet-stream':
$otype='.doc'; break;
case 'txt': $otype='.txt'; break;
case 'application/pdf': $otype='.pdf'; break;
}
//rename the file
$name = time() . '_' . mt_rand(1000,9999).$otype;
$directory = $_SERVER['DOCUMENT_ROOT'].URL::base().'media';
//uploading a file
$filename = Upload::save($_FILES['file'], $name, $directory);
$this->auto_render = false;
$this->response->send_file($filename);
}//action
}//controller
when i call this function file uploaded fine
but downloading file as a corrupted file
help me how to solve this..
thanks in advance.
You shouldn't add URL::base() inside the path name as that could add something like "http://..." inside the file path. Try removing URL::base() and try again.
To start, there's some simple debug checks you can do here.
Is $directory valid?
is $filename a valid file path, or is it FALSE? (See http://kohanaframework.org/3.2/guide/api/Upload#save)
I'm going to assume $directory is invalid.
You want to use the absolute path constants to build directory paths. Instead of using $_SERVER['DOCUMENT_ROOT'].URL::base() (which is wrong in any case)
Rather use APPPATH or DOCROOT, eg $directory = APPPATH.'media'; see https://github.com/kohana/kohana/blob/3.2/master/index.php#L57-74

Webforms in excel instead of e-mail

A client of mine asked me if i can find a solution for this problem.
His website (still a WIP) http://welkommagazine.nl/luuk/ has a form. The form obviously uses a sendmail script to send the form to e-mail. From thereon he manually copy/pastes all the submissions to excel.
What he wants is that the forms online automaticcaly are added to an excel document to save him a lot of work.
Now i am not a programmer, but a designer.. I think this can be done, but i have absolutely no clue how. I googled alot for it and the only thing i found was a dreamweaverplugin.
Is there a way to do this, if so, how?
Not a programmer's response, but...
I think an easy solution is to use Google docs. You can set-up a Google Spreadsheet and associate a form to it. Whenever a user fills the form , his data is added to the spreadsheet.
Your client may download that anytime.
There are some other providers on the market, some free, some not. E.g: wufoo.com
Found the answer myself. I wrote a PHP code snippet which actually stores the fields comma seperated in a CSV file and sends an email to a desired adress with the filled in fields.
if(isset($_POST['Submit'])){
$pakket = $_POST['pakket'];
$extragidsen = $_POST['extragidsen'];
$naambedrijf = $_POST['naambedrijf'];
$err = '';
if(trim($pakket)==''){
$err .= '-Please enter a name';
}
if(empty($extragidsen)){
$err .= '-Please enter an email address';
}
if(strlen($naambedrijf)==0){
$err .= '-Please enter a comment';
}
if($err!=''){
echo $err;
}
else{
$filename = 'file.csv';
$somecontent = $pakket . ',' . $extragidsen . ',' . $naambedrijf . "\n";
// Let's make sure the file exists and is writable first.
if (is_writable($filename)) {
// In our example we're opening $filename in append mode.
// The file pointer is at the bottom of the file hence
// that's where $somecontent will go when we fwrite() it.
if (!$handle = fopen($filename, 'a')) {
echo "Cannot open file ($filename)";
exit;
}
// Write $somecontent to our opened file.
if (fwrite($handle, $somecontent) === FALSE) {
echo "Cannot write to file ($filename)";
exit;
}
//--------------------------Set these paramaters--------------------------
// Subject of email sent to you.
$subject = 'Inschrijving welkom';
// Your email address. This is where the form information will be sent.
$emailadd = 'luuk#luukratief.com';
// Where to redirect after form is processed.
$url = 'http://www.google.com';
// Makes all fields required. If set to '1' no field can not be empty. If set to '0' any or all fields can be empty.
$req = '0';
// --------------------------Do not edit below this line--------------------------
$text = "Results from form:\n\n";
$space = ' ';
$line = '
';
foreach ($_POST as $key => $value)
{
if ($req == '1')
{
if ($value == '')
{echo "$key is empty";die;}
}
$j = strlen($key);
if ($j >= 20)
{echo "Name of form element $key cannot be longer than 20 characters";die;}
$j = 20 - $j;
for ($i = 1; $i ';
fclose($handle);
} else {
echo "The file $filename is not writable";
}
}
}
Maybe the code aint that clean as it can be, but eh it works.
Feel free to clean up the code if you want to :)
I guessed I would answer this myself for the community...
BTW u need to set "write" rights to "file.csv"
cheers

Resources