codeigniter - linking files within application? - php

I'm using codeigniter to create a CSV file, and I can write successfully inside the application structure, but not outside. The reason why I want to create the file outside the application structure cause I get a 403 permissions error when linking to the file.
Either my folder permissions are wrong (I've used 777) or my code is wrong. Please help.
The application is sitting at: domain.com/mysite/ci/
The files created in: domain.com/mysite/ci/_/files/ (I can create the file here, but can't link to download it
I would like to create the file in: domain.com/mysite/downloads/ (I cannot create the file here, but I can link stuff to it to download.
CodeIgniter
$this->load->dbutil();
$this->load->helper('file');
$delimiter = ",";
$newline = "\r\n";
$query = $this->db->query("SELECT * FROM songlist");
$data = $this->dbutil->csv_from_result($query, $delimiter, $newline);
$filePath = '_/files/songlist.csv';
echo "filePath=". $filePath. "</br>";
if (! write_file($filePath, $data)){
echo 'not done';
} else {
echo anchor(base_url(). $filePath);
}
}

I think the problem is that "_" is not a valid folder for web. Try changing it.
If you want to create the file in "mysite/downloads" you filepath would be:
$filePath = '../downloads/songlist.csv';
And i see no reason you shouldn't be able to create it there.

Related

failed to open stream: Permission denied open server

My aim is to download multiple files into the folder on my localhost. I am uploading them using the HTML form.
Here is the code (really sorry that I can't give a link to the executable version of the code because it relies on too many other files and database if anyone knows the way then please let me know)
foreach ($_FILES as $value) {
$dir = '/';
$filename = $dir.basename($value['name']);
if (move_uploaded_file($value['tmp_name'],$filename)) {
echo "File was uploaded";
echo '<br>';
}
else {
echo "Upload failed";
echo '<br>';
}
}
So this little piece of code give me an error:
And here are the lines of code:
The problem is that the adress is correct, I tried enterring it into my file directory and it worked fine, I have seen some adviced on other people's related questions that // or \ should be used instead, but my version works just fine! Also I have checked what's inside the $_FILES and here it is if that's required for someone trying to help:
Thank you very much if anyone could help!!
You are trying to move the file to an invalid (or non-existent) path.
For the test you will write
$dir = 'c:/existing_dir/';
$filename = $dir.basename($value['name']);
If you want to move the file to a folder that is relative to the running file try
$dir = '../../directory/';// '../' -> one directory back
$filename = $dir.basename($value['name']);
By starting your file path with $dir = '/'; you are saying store the file on the root folder, I assume of C:
Apache if correctly configures should not allow you access to C:\
So either do
$dir = '../';
$filename = $dir.basename($value['name']);
to make it a relative path or leave the $dir = '/'; out completely

"No such file or directory" on localhost copy

EDIT: I'm pretty sure the issue has to do with the firewall, which I can't access. Marking Canis' answer as correct and I will figure something else out, possibly wget or just manually scraping the files and hoping no major updates are needed.
EDIT: Here's the latest version of the builder and here's the output. The build directory has the proper structure and most of the files, but only their name and extension - no data inside them.
I am coding a php script that searches the local directory for files, then scrapes my localhost (xampp) for the same files to copy into a build folder (the goal is to build php on the localhost and then put it on a server as html).
Unfortunately I am getting the error: Warning: copy(https:\\localhost\intranet\builder.php): failed to open stream: No such file or directory in C:\xampp\htdocs\intranet\builder.php on line 73.
That's one example - every file in the local directory is spitting the same error back. The source addresses are correct (I can get to the file on localhost from the address in the error log) and the local directory is properly constructed - just moving the files into it doesn't work. The full code is here, the most relevant section is:
// output build files
foreach($paths as $path)
{
echo "<br>";
$path = str_replace($localroot, "", $path);
$source = $hosted . $path;
$dest = $localbuild . $path;
if (is_dir_path($dest))
{
mkdir($dest, 0755, true);
echo "Make folder $source at $dest. <br>";
}
else
{
copy($source, $dest);
echo "Copy $source to $dest. <br>";
}
}
You are trying to use URLs to travers local filesystem directories. URLs are only for webserver to understand web requests.
You will have more luck if you change this:
copy(https:\\localhost\intranet\builder.php)
to this:
copy(C:\xampp\htdocs\intranet\builder.php)
EDIT
Based on your additional info in the comments I understand that you need to generate static HTML-files for hosting on a static only webserver. This is not an issue of copying files really. It's accessing the HMTL that the script generates when run through a webserver.
You can do this in a few different ways actually. I'm not sure exactly how the generator script works, but it seems like that script is trying to copy the supposed output from loads of PHP-files.
To get the generated content from a PHP-file you can either use the command line php command to execute the script like so c:\some\path>php some_php_file.php > my_html_file.html, or use the power of the webserver to do it for you:
<?php
$hosted = "https://localhost/intranet/"; <--- UPDATED
foreach($paths as $path)
{
echo "<br>";
$path = str_replace($localroot, "", $path);
$path = str_replace("\\","/",$path); <--- ADDED
$source = $hosted . $path;
$dest = $localbuild . $path;
if (is_dir_path($dest))
{
mkdir($dest, 0755, true);
echo "Make folder $source at $dest. <br>";
}
else
{
$content = file_get_contents(urlencode($source));
file_put_contents(str_replace(".php", ".html", $dest), $content);
echo "Copy $source to $dest. <br>";
}
}
In the code above I use file_get_contents() to read the html from the URL you are using https://..., which in this case, unlike with copy(), will call up the webserver, triggering the PHP engine to produce the output.
Then I write the pure HTML to a file in the $dest folder, replacing the .php with .htmlin the filename.
EDIT
Added and revised the code a bit above.

Codeigniter cannot unlink file created by codeigniter

I hope someone can help me with this.
I am creating a text file from the query results from a mysql DB. I then set the file to auto download. Once that is done I am trying to unlink the file. It fails to remove the file from the server. When I go to the location and manually try to delete the file it states that it is write protected.
I do not have root access to this system so I can not change the permissions on said file.
Here is the code, is there a way to not create a write protected file?
$leagueinfo = $this->livedraft_win_model->get_leagueinfo($sport, $leagueid);
$export = $this->my_model->get_export($sport, $leagueid);
$file_name = $leagueinfo['strat_id'] . '.IOD';
$export=strip_quotes($export);
$export = str_replace(", ",",",$export);
write_file('/tmp/' . $file_name, $export,'x+');
$data = file_get_contents('/tmp/' . $file_name, FILE_BINARY);
ob_clean();
force_download($file_name, $data);
array_map('unlink', glob("/tmp/*.IOD"));
I use the same unlink format to remove files that are uploaded to the same location and that works just fine. It is only when I try to remove the files that are created by codeigniter.
Thanks
Please try with below code.
$this->load->helper("url");
unlink(base_url('/tmp/' . $file_name));
Or try this
delete_files('/tmp/' . $file_name);
For more information please read this doc.
https://ellislab.com/codeigniter/user-guide/helpers/file_helper.html

Protect PDF docs from being directly accessed in URL

I want to protect a pdf file from being directly linked but instead have my logged in users be able to access it. I have a link which currently goes to a javascript function which posts a form:
$('nameofdoc').setProperty('value',doc);
document.getElementById('sendme').submit();
where sendme is the name of the form and nameof doc the index of the document I want to display.
This then goes to a php file:
$docpath = $holdingArray[0].$holdingArray[1];
$file = $holdingArray[0]; //file name
$filename = $holdingArray[1]; //path to the file]
header( 'Location:'.$docpath ) ;
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="'.$filename . '"');
readfile($filename)
This all works fine it loads up the file and outputs the pdf. What I can't do is protect the directory from direct linking - ie www.mydomain.com/pathToPdf/pdfname.pdf
I've thought of using .htaccess to protect the directory but it's on a shared host so I'm not sure about the security and anyway when I've tried I can't get it to work.
Any help would be great since this is my fourth day of trying to fix this.
thanks
Update
I've had a lot of help thank you but I'm not quite there yet.
I've got an .htaccess file that now launches another php file when a pdf is requested from the directory:
RewriteEngine on
RewriteRule ^(.*).(pdf)$ fileopen.php
When the fileopen.php file lauches it fails to open the pdf
$path = $_SERVER['REQUEST_URI'];
$paths = explode('/', $path);
$lastIndex = count($paths) - 1;
$fileName = $paths[$lastIndex];
$file = basename($path);
$filepath = $path;
if (file_exists($file)) {
header( 'Location: http://www.mydomain.com'.$path ) ;
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=".$file);
readfile($filepath);
}else{
echo "file not found using path ".$path." and file is ".$file;
}
The output is
file not found using path /documents/6/Doc1.pdf and file is Doc1.pdf
but the file does exist and is in that direcotry - any ideas??
OKAY I'm happy to report that Jaroslav really helped me sort out the issue. His method works well but it is tricky to get all the directory stuff lined up. In the end I spent a few hours playing about with combinations to get it working but the principle he gave works well. Thanks
The best way would be to protect that folder with htaccess, as you have mentioned. So you put all PDFs in pdf/ folder, and in the same pdf folder you out .htaccess file:
RewriteEngine on
RewriteRule .* your-php-script.php
Now no files can be accessed by url in this folder. Every request to every file in this folder will return what your-php-script.php script returns. In your-php-script.php you do something like this:
//Check if user has right to access the file. If no, show access denied and exit the script.
$path = $_SERVER['REQUEST_URI'];
$paths = explode('/', path);
$lastIndex = count($paths) - 1;
$fileName = $paths[$lastIndex]; // Maybe add some code to detect subfolder if you have them
// Check if that file exists, if no show some error message
// Output headers here
readfile($filename);
Now if user opens domain.com/pdf/nsa-secrets.pdf Apache will run your-php-script.php. Script will have variable $_SERVER['REQUEST_URI'] set to "domain.com/pdf/nsa-secrets.pdf". You take the last part (filename) and output it to a user (or not).
This will stop anyone from accessing files directly from the internet by knowing URL. If someone has direct access to files on your server, that will not stop them. On the other hand, I think any shared hosting stops users from getting files of other clients. Only way to do it is to hack the server in some way. But then we are getting very paranoid and if that may be a case for you, you shouldn't use shared hosting in the first place.
If you cannot make htaccess work, you can try to obfuscate files, so it would be difficult to spot them for someone outside. For example change file from mySecretData.pdf to djjsdmdkjeksm.pdf. This may help a little bit.
I want to protect a pdf file from being directly linked but instead have my logged in users be able to access it.
Check to ensure there is an authenticated user before streaming the PDF's content.
This is kinda sloppy but it could work assuming you can setup a MYSQL DB. It lets you pass the "password" in the URL as an MD5 string or as a clear text if you want to. Trying to setup some kind of security without using htaccess or an existing frame work is kinda clunky. This however won't even attach the file to the stream until it knows you've been "Authenticated" I think you could maybe make this a little better if you setup a login page that saved a cookie locally then you wouldn't need to pass the "passphrase" in the URL.
$file = $_GET['file'];
$pass = $_GET['pass'];
$download_folder = '../Protected';
$file = basename($file);
$filepath = "$download_folder/$file";
if (file_exists($filepath)) {
if(CheckUser($pass)){
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=$file");
session_write_close();
readfile($filepath);
} else {
echo 'Not Authenticated!';
}
} else {
echo 'No File!';
}
function CheckUser($value){
$con = mysqli_connect("test.com","test","123456","my_db");
// Check connection
if (mysqli_connect_errno()){
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT user FROM pass_table WHERE password =".md5($value).";");
while($row = mysqli_fetch_array($result)){
mysqli_close($con);
//return $row['user'];
if($row['user']){
return true;
}
}
mysqli_close($con);
return false;
}

Issues of Parse Email and Save Attachments into directory

I am using this script(http://stuporglue.org/mailreader-php-parse-e-mail-and-save-attachments-php-version-2/) to save email attachment on my server. You can also view the complete script on browser here: http://stuporglue.org/downloads/mailReader.txt
Everything works fine but there are 2 problems here.
1) The file name of the image that i saved into the directory is not an image: 1360341823_test_jpg
How to convert the file name from 1360341823_test_jpg to 1360341823_test.jpg
in the script?
2) The permission of the file that saved in the directory is 600.
How to make it default 755 or 775?
I believe this is the function to convert the image in the script.:
function saveFile($filename,$contents,$mimeType){
global $save_directory,$saved_files,$debug;
$filename = preg_replace('/[^a-zA-Z0-9_-]/','_',$filename);
$unlocked_and_unique = FALSE;
while(!$unlocked_and_unique){
// Find unique
$name = time()."_".$filename;
while(file_exists($save_directory.$name)) {
$name = time()."_".$filename;
}
// Attempt to lock
$outfile = fopen($save_directory.$name,'w');
if(flock($outfile,LOCK_EX)){
$unlocked_and_unique = TRUE;
} else {
flock($outfile,LOCK_UN);
fclose($outfile);
}
}
fwrite($outfile,$contents);
fclose($outfile);
// This is for readability for the return e-mail and in the DB
$saved_files[$name] = Array(
'size' => formatBytes(filesize($save_directory.$name)),
'mime' => $mimeType
);
}
Any help?
The original script used the data to store in the DB but I think you are trying to save it in the file. You are creating the file without extension here:
// Attempt to lock
$outfile = fopen($save_directory.$name,'w');
Either add the .jpg after the line as:
#outfile.=".jpg";
Other way if you don't want to change script then you can get use as:
$contents = file_get_contents($save_directory.$name);
$outfile = fopen($save_directory.$new_name,'w');
write($outfile,$contents);
fclose($outfile);
This would resolve your first problem and for second question kindly use the FTP or Control panel provided to access the files to change the ownership rights. If you don't know about any thing then you contact your Web Hosting Service Provider to share the ownership from 755 to 775

Categories