Codeigniter: write_file() returns false - javascript

public function ExportCSV()
{
// THIS PART IS WORKING
$this->load->dbutil();
$this->load->helper('file');
$delimiter = ',';
$newline = "\n";
$enclosure = '"';
$filename = "tamp.csv";
$query = "SELECT politician.id, politician.ident, party.abbr, politician.id_image, politician.name, politician.surname, politician.personal_birth, politician.home_city, politician.political_function
FROM politician
INNER JOIN party
WHERE party.id = politician.id_party
LIMIT 10000";
$result = $this->db->query($query);
$data = $this->dbutil->csv_from_result($result, $delimiter, $newline, $enclosure);
// data IS CORRECT
// THIS PART NOT WORKING: write_file() returns false
if ( ! write_file(APPPATH."/assets/media/upload/tamp.csv", $data, 'r+'))
{
echo 'Unable to write the file';
}
else
{
echo 'File written!';
}
}
The variable $data contains the correct output but the write_file() returns false.
The directory /assets/ is in the main directory of the codeigniter project.
My questions are:
Is this function returning false because I don't have the permission to write in this directory?
If yes, what should I do?
In which directory should I write this file as I would like it public?

When creating a file with write_file make sure your folder/directory is there where you would like to create file
Then I would recommend using FCPATH
$data = "Some file data";
if (write_file(FCPATH . '/document/text.txt', $data) == FALSE)
{
echo 'Unable to write the file';
} else {
echo 'File written!';
}
My directory
application
document
system
index.php

Related

PHP - Create a directory listing of specified folder

I've got small piece of code which I'm using to scan a certain directory on my server for all the files and folders inside. But there's a catch... It can only scan the specified folder, and no sub-directories. Let's say share/ is the root directory for this scan, if there are files in any sub-directory like share/folder/file.png they won't be listed, where the entire purpose of my project is to create an HTML file explorer.
This is the code I'm using to receive the list of files from the server to later display it in the browser using JavaScript:
<?php
$listFiles = array();
if ($handle = opendir('./share')) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
$listFiles[] = $entry;
}
}
closedir($handle);
}
$FS_files = json_encode($listFiles);
?>
And then I "push" it rude to my actual JavaScript code like this:
let FS_files = <?php echo $FS_files ?>
The code I above basically generates an array of file names from scanned directory. What I wanna know is how can I get an entire JSON tree of files in this directory and all folders inside it, or possibly change my code so it works that way?
<?php
function scanFolder($dir) {
$result = array();
$cdir = scandir($dir);
foreach ($cdir as $key => $value) {
if (!in_array($value,array(".",".."))) {
if (is_dir($dir . DIRECTORY_SEPARATOR . $value)) {
$result[$value] = scanFolder($dir . DIRECTORY_SEPARATOR . $value);
} else {
$result[] = $value;
}
}
}
return $result;
}
$FS_files = json_encode(scanFolder("./share"));
?>
The function scans the folder and checks each entry with is_dir. If its true, this folder is scanned with the same function.

Active PHP code using JavaScript and URL

I have a self destruct PHP code that would delete all files and folders in my domain's directory.
<?Php
$dir = 'C:\wamp64\www\FileDirectory' . DIRECTORY_SEPARATOR . 'Files';
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
if ($file->isDir()){
rmdir($file->getRealPath());
} else {
unlink($file->getRealPath());
}
}
rmdir($dir);
$filename = 'C:\wamp64\www\FileDirectory\Files';
if (file_exists($filename)) {
echo "The Directory has not been deleted";
} else {
echo "All Files And Folders Are Deleted";
}
?>
I need a way to only activate this code when I type in extra code to the end of my URL. I thought you could do that with JavaScript but I'm not too certain. Please let me know if I can do this. If I have to use a different code to do so, it's not a big deal.
Use $_GET['parameter'] to get parameter from get method:
http://example.com/index.php?doClean=1
if (isset($_GET['doClean'])) {
// Your code goes here
}

How to use the extra params in ExtJS Upload Widget by Ivan Novakov

I am using this upload widget in my web application.
I am using the FormDataUploader and I am able to upload files to a server directory quite well. However, I wanted to send extra parameters as well to the php file handling the upload. This is what I attempted:
var uploadPanel = Ext.create('Ext.ux.upload.Panel', {
uploader : 'Ext.ux.upload.uploader.FormDataUploader',
uploaderOptions : {
url : 'uploadGallery.php'
},
synchronous : true,
uploadParams : {
ID_Person : ID_Person,
ID_CI : ID_CI
}
});
As you can see, I used the uploadParams, however, my PHP couldn't seem to receive it. In my php file, I have:
$ID_Person = $_GET['ID_Person'];
$ID_CI = $_GET['ID_CI'];
However, my PHP seems to be unable to get these params.
What I did next was to use the default ExtJS Uploader as such:
var uploadPanel = Ext.create('Ext.ux.upload.Panel', {
uploaderOptions : {
url : 'uploadExtJS.php'
},
synchronous : true,
uploadParams : {
ID_Person : ID_Person,
ID_CI : ID_CI
}
});
At first, I used the old PHP file which was able to get the extra params I sent. However, it seems that I needed to use a different PHP file for the ExtJS uploader.
This is what my PHP file looks like:
<?php
/**
* Example processing of raw PUT/POST uploaded files.
* File metadata may be sent through appropriate HTTP headers:
* - file name - the 'X-File-Name' proprietary header
* - file size - the standard 'Content-Length' header or the 'X-File-Size' proprietary header
* - file type - the standard 'Content-Type' header or the 'X-File-Type' proprietary header
*
* Raw data are read from the standard input.
* The response should be a JSON encoded string with these items:
* - success (boolean) - if the upload has been successful
* - message (string) - optional message, useful in case of error
*/
require __DIR__ . '_common.php';
$config = require __DIR__ . '_config.php';
error_reporting(-1);
ini_set('display_errors', 'On');
/*
* You should check these values for XSS or SQL injection.
*/
if (!isset($_SERVER['HTTP_X_FILE_NAME'])) {
_error('Unknown file name');
}
$fileName = $_SERVER['HTTP_X_FILE_NAME'];
if (isset($_SERVER['HTTP_X_FILENAME_ENCODER']) && 'base64' == $_SERVER['HTTP_X_FILENAME_ENCODER']) {
$fileName = base64_decode($fileName);
}
$fileName = htmlspecialchars($fileName);
$mimeType = htmlspecialchars($_SERVER['HTTP_X_FILE_TYPE']);
$size = intval($_SERVER['HTTP_X_FILE_SIZE']);
$inputStream = fopen('php://input', 'r');
// $outputFilename = $config['upload_dir'] . '/' . $fileName;
$outputFilename = 'gallery' . '/' . $fileName;
$realSize = 0;
$data = '';
if ($inputStream) {
if (! $config['fake']) {
$outputStream = fopen($outputFilename, 'w');
if (! $outputStream) {
_error('Error creating local file');
}
}
while (! feof($inputStream)) {
$bytesWritten = 0;
$data = fread($inputStream, 1024);
if (! $config['fake']) {
$bytesWritten = fwrite($outputStream, $data);
} else {
$bytesWritten = strlen($data);
}
if (false === $bytesWritten) {
_error('Error writing data to file');
}
$realSize += $bytesWritten;
}
if (! $config['fake']) {
fclose($outputStream);
}
} else {
_error('Error reading input');
}
if ($realSize != $size) {
_error('The actual size differs from the declared size in the headers');
}
_log(sprintf("[raw] Uploaded %s, %s, %d byte(s)", $fileName, $mimeType, $realSize));
_response();
However, I am getting an Internal Server 500 Error - Meaning that there was something probably wrong with my php file.
I mainly have two questions:
How do I make the uploadParams work with the FormDataUploader?
How do I write a PHP uploader for an ExtJS Data Uploader?
Got it to work.
The uploadExtJS.php file should look like:
<?php
/**
* Example processing of raw PUT/POST uploaded files.
* File metadata may be sent through appropriate HTTP headers:
* - file name - the 'X-File-Name' proprietary header
* - file size - the standard 'Content-Length' header or the 'X-File-Size' proprietary header
* - file type - the standard 'Content-Type' header or the 'X-File-Type' proprietary header
*
* Raw data are read from the standard input.
* The response should be a JSON encoded string with these items:
* - success (boolean) - if the upload has been successful
* - message (string) - optional message, useful in case of error
*/
// require __DIR__ . '_common.php';
// $config = require __DIR__ . '_config.php';
require_once '_common.php';
$config = require_once '_config.php';
error_reporting(-1);
ini_set('display_errors', 'On');
/*
* You should check these values for XSS or SQL injection.
*/
if (!isset($_SERVER['HTTP_X_FILE_NAME'])) {
_error('Unknown file name');
}
$fileName = $_SERVER['HTTP_X_FILE_NAME'];
if (isset($_SERVER['HTTP_X_FILENAME_ENCODER']) && 'base64' == $_SERVER['HTTP_X_FILENAME_ENCODER']) {
$fileName = base64_decode($fileName);
}
$fileName = htmlspecialchars($fileName);
$mimeType = htmlspecialchars($_SERVER['HTTP_X_FILE_TYPE']);
$size = intval($_SERVER['HTTP_X_FILE_SIZE']);
$inputStream = fopen('php://input', 'r');
$outputFilename = $config['upload_dir'] . '/' . $fileName;
// $outputFilename = 'gallery' . '/' . $fileName;
$realSize = 0;
$data = '';
if ($inputStream) {
if (! $config['fake']) {
$outputStream = fopen($outputFilename, 'w');
if (! $outputStream) {
_error('Error creating local file');
}
}
while (! feof($inputStream)) {
$bytesWritten = 0;
$data = fread($inputStream, 1024);
if (! $config['fake']) {
$bytesWritten = fwrite($outputStream, $data);
} else {
$bytesWritten = strlen($data);
}
if (false === $bytesWritten) {
_error('Error writing data to file');
}
$realSize += $bytesWritten;
}
if (! $config['fake']) {
fclose($outputStream);
}
} else {
_error('Error reading input');
}
if ($realSize != $size) {
_error('The actual size differs from the declared size in the headers');
}
_log(sprintf("[raw] Uploaded %s, %s, %d byte(s)", $fileName, $mimeType, $realSize));
_response(true, "okay");
_common.php looks like:
<?php
function _log($value){
error_log(print_r($value, true));
}
function _response($success = true, $message = 'OK'){
$response = array(
'success' => $success,
'message' => $message
);
echo json_encode($response);
exit();
}
function _error($message){
return _response(false, $message);
}
_config.php should look like:
<?php
return array(
'upload_dir' => 'gallery',
'fake' => false
);
?>
and now I'm working on using a unique name using uniqid() and microtime(), as well as saving the images to a subdirectory (or any folder under your main upload/gallery folder) using the uploadParams() property.
EDIT 1: RENAMING THE UPLOADED FILE
just change this line:
$fileName = htmlspecialchars($fileName);
to:
$fileName = uniqid() . '_' . microtime();
EDIT 3: TO GET THE CUSTOM SUB DIRECTORY FROM YOUR ADDITIONAL PARAMS
First, make sure than when you create your Upload Dialog from your ExtJS web app, you do this:
var uploadPanel = Ext.create('Ext.ux.upload.Panel', {
uploaderOptions : {
url : 'uploadExtJS.php'
},
synchronous : true,
uploadParams : {
ID_1 : ID_1,
ID_2 : ID_2 // you can put waaay more if you want
}
});
and in your uploadExtJS.php, do this (between the part where you define your new file name and the part where you check for input stream)
$fileName = uniqid() . '_' . microtime();
$mimeType = htmlspecialchars($_SERVER['HTTP_X_FILE_TYPE']);
$size = intval($_SERVER['HTTP_X_FILE_SIZE']);
$ID_1 = $_GET['ID_1'];
$ID_2 = $_GET['ID_2'];
$newFilePath = $config['upload_dir'] . '/' . $ID_1 . '/' . $ID_2;
if (!file_exists($newFilePath)) {
mkdir($newFilePath, 0777, true);
}
$inputStream = fopen('php://input', 'r');
$outputFilename = $newFilePath . '/' . $fileName;
$realSize = 0;
$data = '';
As you can see, I defined a $newFilePath variable, checked if it was existing before making it, then uploaded to that directory.
Hope this helps anyone who encounters the issue in the future.

Need Help Handling a XML HTTP File Upload Request

So, I looked up a tutorial for uploading and sending files to a server with an XML HTTP Request. I followed the tutorial, however, I think I must be missing something. While the file appears to be uploaded and sent, nothing in the "handler" file is ever accessed. Is there a PHP function I need to write to process it? For context, here is what I wrote:
$(document).ready(function()
{
$('#upload-button').click(function(event)
{
$('#upload-button').removeClass("btn-danger");
});
$( "#report-form" ).submit(function( event )
{
var form = document.getElementById('report-form');
var fileSelect = document.getElementById('file-select');
var uploadButton = document.getElementById('upload-button');
event.preventDefault(); // Stop the event from sending the way it usually does.
uploadButton.value = 'Submitting...'; // Change text.
var files = fileSelect.files;
var maxfiles = <?php echo $config['Report_MaxFiles'] ?>;
var mfs = <?php echo $config['Report_MaxFileSize'] ?>;
if(files.length > maxfiles) // Make sure it's not uploading too many.
{
uploadButton.value = 'You uploaded too many files. The limit is ' + maxfiles + '.'; // Update button text.
$('#upload-button').addClass('btn-danger'); // Make the button red, if so.
return;
}
var formData = new FormData(); // Make a "form data" variable.
for (var i = 0; i < files.length; i++) {
var file = files[i];
// Add the file to the request.
if(file.size / 1000 > mfs)
{
uploadButton.value = 'One of the files is too big. The file size limit is ' + (mfs) + 'kb (' + (mfs / 1000) + 'mb).';
$('#upload-button').addClass('btn-danger');
return;
}
formData.append('files[]', file, file.name); // Not really sure what this does, to be honest,
// but I think it makes a file array.
}
var xhr = new XMLHttpRequest(); // Construct an XML HTTP Request
xhr.open('POST', 'assets/class/FileHandler.php', true); // Open a connection with my handler PHP file.
xhr.onload = function ()
{
if (xhr.status === 200)
{
uploadButton.value = 'Files Submitted!'; // NOTE: I do get this message.
}
else
{
uploadButton.value = 'An error occurred.';
$('#upload-button').addClass("btn-danger");
}
};
xhr.send(formData); // I think this is where it dies.
});
});
At the "send(formData)" line, I'm not actually sure if it's sending. Do I set up some sort of listener in FileHandler.php that is activated when the files are sent via XML HTTP request? Or more specifically, how to I save the uploaded files to the server using my FileHandler.php file?
EDIT: I haven't been able to come up with any other PHP code in the FileHandler.php file than this, which I thought might be called when the form is sent (but it isn't):
EDIT 2: Okay, now I have something, but it isn't working (didn't expect it to). I think I may be using the variables wrong:
<?php
$uploaddir = 'data/reports/uploads/' . $_POST['id'] . "/";
$uploadfile = $uploaddir . basename($_FILES['files']['name']);
echo "<script>console.log('RECEIVED');</script>";
echo '<pre>';
if (move_uploaded_file($_FILES['files']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "Possible file upload attack!\n";
}
echo 'Here is some more debugging info:';
print_r($_FILES);
print "</pre>";
It's not saving the file to the directory, nor is it printing the script message. How do I get my report.php file to execute these things in FileHandler.php?
Thanks to the help and patience of #Florian Lefèvre, I got it fixed. :)
The problem was with the path. It wasn't locating the path to the folder data/uploads/ and wasn't making the directory. Here is what I did:
$uploaddir = '../../data/reports/uploads/' . $_POST['id'] . "/";
echo "NAME: " . $_FILES['files']['name'][0] . "\n";
foreach($_FILES['files']['name'] as $filenumber => $filename)
{
$uploadfile = $uploaddir . basename ($filename);
echo "UploadDir " . $uploaddir . "\n";
echo "UploadFile " . $uploadfile . "\n";
echo '<pre>';
echo "MKDir for UploadDir which is: ". $uploaddir . "\n";
mkdir ($uploaddir);
if (move_uploaded_file ($_FILES['files']['tmp_name'][$filenumber], $uploadfile))
{
echo "File is valid, and was successfully uploaded.\n";
}
else
{
echo "Possible file upload attack!\n";
}
echo 'Here is some more debugging info:';
print "</pre>";
}
var_dump ($_FILES);
I haven't gotten rid of some of the debug stuff yet, but that's the general solution.

Multiple files in to folder

Hello I have a view file and controller, what makes multiple inputs where I can upload files in to folder, but its uploading only one file in to folder. I know what is problem, but I dont know how to fix this or how to do this.
My Controller:
public function uploadFile() {
$filename = '';
if ($this->request->is('post')) { // checks for the post values
$uploadData = $this->data['files'];
//print_r($this->data['files']); die;
if ( $uploadData['size'] == 0 || $uploadData['error'] !== 0) { // checks for the errors and size of the uploaded file
echo "Failide maht kokku ei tohi olla üle 5MB";
return false;
}
$filename = basename($uploadData['name']); // gets the base name of the uploaded file
$uploadFolder = WWW_ROOT. 'files'; // path where the uploaded file has to be saved
$filename = $filename; // adding time stamp for the uploaded image for uniqueness
$uploadPath = $uploadFolder . DS . $filename;
if( !file_exists($uploadFolder) ){
mkdir($uploadFolder); // creates folder if not found
}
if (!move_uploaded_file($uploadData['tmp_name'], $uploadPath)) {
return false;
}
echo "Sa sisestasid faili(d): $filename";
}
}
My View file:
<?php
echo $this->Form->create('uploadFile', array( 'type' => 'file'));
?>
<div class="input_fields_wrap">
<label for="uploadFilefiles"></label>
<input type="file" name="data[files]" id="uploadFilefiles">
</div>
<button type="button" class="add_field_button">+</button> <br><br>
<form name="frm1" method="post" onsubmit="return greeting()">
<input type="submit" value="Submit">
</form>
<?php
echo $this->Html->script('addFile');
And this script what Im using in View :
$(document).ready(function() {
var max_fields = 3;
var wrapper = $(".input_fields_wrap");
var add_button = $(".add_field_button");
var x = 1;
$(add_button).click(function(e){
e.preventDefault();
if(x < max_fields){
x++;
$(wrapper).append("<div><input type='file' name='data[files]' id='uploadFilefiles'/><a href='#' class='remove_field'>Kustuta</a></div>");
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('div').remove(); x--;
})
});
I think that, the problem is in input names. If Im doing more inputs, then the inputs names are same, and thanks to this its uploading only one file in to webroot/files folder, but I want these all.
Can anybody help me or give me some tips.
Thanks !
Here is someone with almost exactly the same issue as you have:
Create multiple Upload File dynamically
Try doing the same. I haven't programmed PHP for quite some time, but I guess you should replace data[files] to just data[], so it creates a new array item for each field. Now you are giving each field the same name.
Then you can loop over them in your controller by using:
foreach($_FILES['data'] as $file){
//do stuff with $file
}
EDIT 2:
As you are saying, you want to upload the files (not to a db). So I guess this should work:
public function uploadFile() {
$filename = '';
if ($this->request->is('post')) { // checks for the post values
$uploadData = $this->data;
foreach($uploadData as $file){
if ( $file['size'] == 0 || $file['error'] !== 0) { // checks for the errors and size of the uploaded file
echo "Failide maht kokku ei tohi olla üle 5MB";
return false;
}
$filename = basename($file['name']); // gets the base name of the uploaded file
$uploadFolder = WWW_ROOT. 'files'; // path where the uploaded file has to be saved
$filename = $filename; // adding time stamp for the uploaded image for uniqueness
$uploadPath = $uploadFolder . DS . $filename;
if( !file_exists($uploadFolder) ){
mkdir($uploadFolder); // creates folder if not found
}
if (!move_uploaded_file($file['tmp_name'], $file)) {
return false;
}
echo "Sa sisestasid faili(d): $filename";
}
}
}
Try this function:
function multi_upload($file_id, $folder="", $types="") {
$all_types = explode(",",strtolower($types));
foreach($_FILES[$file_id]['tmp_name'] as $key => $tmp_name ){
if(!$_FILES[$file_id]['name'][$key]){
$return[$key]= array('','No file specified');
continue;
}
$file_title = $_FILES[$file_id]['name'][$key];
$ext_arr = pathinfo($file_title, PATHINFO_EXTENSION);
$ext = strtolower($ext_arr); //Get the last extension
//Not really uniqe - but for all practical reasons, it is
$uniqer = substr(md5(uniqid(rand(),1)),0,5);
$file_name = $uniqer . '_' . $file_title;//Get Unique Name
if($types!=''){
if(in_array($ext,$all_types));
else {
$result = "'".$_FILES[$file_id]['name'][$key]."' is not a valid file."; //Show error if any.
$return[$key]= array('',$result);
continue;
}
}
//Where the file must be uploaded to
if($folder) $folder .= '/';//Add a '/' at the end of the folder
$uploadfile = $folder . $file_name;
$result = '';
//Move the file from the stored location to the new location
if (!move_uploaded_file($_FILES[$file_id]['tmp_name'][$key], $uploadfile)) {
$result = "Cannot upload the file '".$_FILES[$file_id]['name'][$key]."'"; //Show error if any.
if(!file_exists($folder)) {
$result .= " : Folder don't exist.";
} elseif(!is_writable($folder)) {
$result .= " : Folder not writable.";
} elseif(!is_writable($uploadfile)) {
$result .= " : File not writable.";
}
$file_name = '';
}
else {
if(!$_FILES[$file_id]['size']) { //Check if the file is made
#unlink($uploadfile);//Delete the Empty file
$file_name = '';
$result = "Empty file found - please use a valid file."; //Show the error message
}
else {
#chmod($uploadfile,0777);//Make it universally writable.
}
}
$return[$key]=array($file_name,$result);
}
return $return;
}
html: <input type="file" name="data_file[]" id="uploadFilefiles">
Call by multi_upload("data_file","upload_to_folder","pdf,jpg,txt,bmp")

Categories