I have a problem uploading a file can you help me? when I upload a smaller file it runs smoothly but when I upload a larger file it's problematic, does anyone know the solution? this is the controller part:
$title = $this->request->getPost('title');
$kategori = $this->request->getPost('kategori');
$seo = str_replace(" ", "-", strtolower($kategori));
$deskripsi = $this->request->getPost('deskripsi');
$data=array();
$file = $this->request->getFile('imagefile');
$data=array();
if ($file->getSize() > 0){
$image=$file->getRandomName();
$file->move('./uploads/peta/',$image);
$data = array(
'title' => $title,
'kategori' => $kategori,
'seo' => $seo,
'deskripsi' => $deskripsi,
'file' => $image
);
}else{
$data = array(
'title' => $title,
'kategori' => $kategori,
'seo' => $seo,
'deskripsi' => $deskripsi
);
}
Use $files->hasFile('') to check whether file exist. And then check other file properties as mentioned below.
$files = $this->request->getFiles();
if ($files->hasFile('imagefile'))
{
$file = $files->getFile('imagefile');
// Generate a new secure name
$name = $file->getRandomName();
// Move the file to it's new home
$file->move('/path/to/dir', $name);
echo $file->getSize(); // 1.23
echo $file->getExtension(); // jpg
echo $file->getType(); // image/jpg
}
You need to check if the file is set before trying to call file methods. It seems that the file isn't being sent over your request. As you said, it works with smaller files so please check the php.ini file to see your max_upload_size settings and post_max_size settings. Change the maximum upload file size
Otherwise, to ensure your code won't fail on posts, you can do this:
if (!empty($file) && $file->getSize() > 0){
$image=$file->getRandomName();
$file->move('./uploads/peta/',$image);
$data = array(
'title' => $title,
'kategori' => $kategori,
'seo' => $seo,
'deskripsi' => $deskripsi,
'file' => $image
);
}else{
$data = array(
'title' => $title,
'kategori' => $kategori,
'seo' => $seo,
'deskripsi' => $deskripsi
);
}
This will check if there is a file before trying to use it.
Related
I am trying to download a large list of mp4 files by looping through them and using file_put_contents() to save to a directory. The problem is that only the last item in the video list is getting downloaded.
Here is my code:
<?php
$i = 0;
foreach ($response['videos'] as $row){
$i++;
if($row['status'] != 'failed') {
$videoId= '';
$videoName = '';
$videoId = $row['key'];
$videoName = $row['title'];
$filename = '';
$filename = str_replace(' ','-',$videoName); // remove spaces from filename created by name
// Initialize a file URL to the variable
$url = "";
$url = "http://content.jwplatform.com/videos/{$videoId}.mp4";
// Use file_get_contents() function to get the file
// from url and use file_put_contents() function to
// save the file
if (file_put_contents("Videos/".$filename.$i.".mp4", file_get_contents($url)))
{
echo "File downloaded successfully.";
//sleep(5);
}
else
{
echo "File downloading failed.";
}
}
}
?>
I tried to use a CURL function to do this instead of file_put_contents() and it successfully placed all of the files to my Videos directory, but they were all empty files. I believe they were empty because these mp4 URLs are secure videos, so when you open them in the browser they actually bring you to a different secure URL to view and download the video. The CURL function could not get the file data successfully, but it seems like file_get_contents() does get it successfully (only the last item though).
In my code above, I believe what is happening is the variables in the loop are getting overridden over and over until it reaches the last item and then it executes the file_put_contents() function. If that is the case, how can I ensure that it executes the function on each loop so all of the files are downloaded?
Edits:
Here is some of the output of var_export($response['videos'])
array ( 0 => array ( 'key' => 'eewww123', 'title' => 'Video Name Example 1', 'description' => NULL, 'date' => 1604004019, 'updated' => 1640011490, 'expires_date' => NULL, 'tags' => NULL, 'link' => NULL, 'author' => NULL, 'size' => '240721720', 'duration' => '229.79', 'md5' => 'f0023423423423423423', 'views' => 0, 'status' => 'ready', 'error' => NULL, 'mediatype' => 'video', 'sourcetype' => 'file', 'sourceurl' => NULL, 'sourceformat' => NULL, 'upload_session_id' => NULL, 'custom' => array ( ), ), 1 => array ( 'key' => 'rr33445', 'title' => 'Another Video Name Example 1', 'description' => '', 'date' => 1594316349, 'updated' => 1640011493, 'expires_date' => NULL, 'tags' => NULL, 'link' => '', 'author' => NULL, 'size' => '525702235', 'duration' => '840.90', 'md5' => '0044455sfsdgsdfs3245', 'views' => 0, 'status' => 'ready', 'error' => NULL, 'mediatype' => 'video', 'sourcetype' => 'file', 'sourceurl' => NULL, 'sourceformat' => NULL, 'upload_session_id' => NULL, 'custom' => array ( ), ), )
None of the rows have a failed status, and there are about 30 rows in total but I have some other video lists to download with 900+ rows.
I enabled error reporting and I see
Fatal error: Allowed memory size of 268435456 bytes exhausted (tried
to allocate 132120608 bytes)
on the line where my file_put_contents() function is.
Here is the CURL function I used that worked to download all of the filenames successfully but all of the files were empty:
function multiple_download(array $urls, $save_path = 'Videos') {
$multi_handle = curl_multi_init();
$file_pointers = [];
$curl_handles = [];
// Add curl multi handles, one per file we don't already have
foreach ($urls as $key => $url) {
$file = $save_path . '/' . basename($url);
if(!is_file($file)) {
$curl_handles[$key] = curl_init($url);
$file_pointers[$key] = fopen($file, "w");
curl_setopt($curl_handles[$key], CURLOPT_FILE, $file_pointers[$key]);
curl_setopt($curl_handles[$key], CURLOPT_HEADER, 0);
curl_setopt($curl_handles[$key], CURLOPT_CONNECTTIMEOUT, 60);
curl_multi_add_handle($multi_handle,$curl_handles[$key]);
}
}
// Download the files
do {
curl_multi_exec($multi_handle,$running);
} while ($running > 0);
// Free up objects
foreach ($urls as $key => $url) {
curl_multi_remove_handle($multi_handle, $curl_handles[$key]);
curl_close($curl_handles[$key]);
fclose ($file_pointers[$key]);
}
curl_multi_close($multi_handle);
}
multiple_download($videoURLS);
$videoURLs is an array that I built containing all the unique URLs using the first PHP function above (with the other part commented out).
It turns out the issue was that file_get_contents was exhausting the memory size. From this post, I used the following function
function custom_put_contents($source_url='',$local_path=''){
$time_limit = ini_get('max_execution_time');
$memory_limit = ini_get('memory_limit');
set_time_limit(0);
ini_set('memory_limit', '-1');
$remote_contents=file_get_contents($source_url);
$response=file_put_contents($local_path, $remote_contents);
set_time_limit($time_limit);
ini_set('memory_limit', $memory_limit);
return $response;
}
This effectively sets the memory to unlimited so the file can be retrieved and then it restores the memory back to original state after it is done. With this function I was able to download the files.
You must use a flag to append to the file instead of overwrite.
See documentation https://www.php.net/manual/fr/function.file-put-contents.php
Flag FILE_APPEND
Edit: if all file have the same name, it is possible it overwrite them. You must provide diferent name in your loop.
foreach ($response['videos'] as $key => $row) {
...
if (file_put_contents("Videos/" . $filename .$key ".mp4", file_get_contents($url))) {
...
Using the $key of the loop in your file name make it uniq and will not be overwritten
I'm trying to create an Admin Controller with a csv file uploader to process it like an array.
I can't find an efficient way to do it, I tried to use $this-> fields_form, but nothing is showing up.
Then I did a tpl file with an input file, called in initContent, but I don't know how to retrieve my file in the controller.
I need to create multiple object of different classes that I made, thanks to the csv file.
Does somebody have some documentation that could help me, I've already search through prestashop dev doc, stack overflow, ect but I've didn't see anything that could help me (maybe I didn't search the good way ?)
Waiting for your help guys !
Update :
Update :
Just found a way to upload my file, but it's upload as .tmp and can't be processed as a csv file, how can I convert a tmp file to a csv ?
Here is my code :
public function __construct()
{
parent::__construct();
// Base
$this->bootstrap = true; // use Bootstrap CSS
$this->fields_options = array(
'general' => array(
'title' => $this->l('Upload DB'),
'fields' => array(
'DB_BULB_DATA' => array(
'title' => $this->l('Upload DB'),
'type' => 'file',
'name' => 'DB_BULB_DATA'
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
);
if(isset($_FILES['DB_BULB_DATA'])){
$headers = fgetcsv(fopen($_FILES['DB_BULB_DATA']['tmp_name'], "r+"));
print_r($headers);
}
}
There is no file type name csvfile , you need to use filed type file and then hadel the csv file after upload, check file extension then process the data.
Just find out how to do it, I feel dummy 😅
I just needed to save my tmp file as a csv to be able to use it then.
Here is the full code :
<?php
class Admin<YourModuleName>Upload<YourThings>DatabaseController extends ModuleAdminController
{
public function __construct()
{
parent::__construct();
// Base
$this->bootstrap = true; // use Bootstrap CSS
$this->name = "Admin<YourModuleName>Upload<YourThings>Database";
$this->fields_options = array(
'general' => array(
'title' => $this->l('Upload DB'),
'fields' => array(
'DB_<YourThings>_DATA' => array(
'title' => $this->l('Upload DB'),
'type' => 'file',
'name' => 'DB_<YourThings>_DATA'
),
),
'submit' => array('title' => $this->l('Save')),
),
);
}
public function initContent()
{
parent::initContent();
unset($_FILES);
}
public function postProcess()
{
$fileName = '<YourThings>Db.csv';
if (!file_exists(_PS_MODULE_DIR_ . '<YourModuleName>/upload/' . $fileName)) {
if (isset($_FILES['DB_<YourThings>_DATA'])) {
$tmpPath = $_FILES['DB_<YourThings>_DATA']["tmp_name"];
move_uploaded_file($tmpPath, _PS_MODULE_DIR_ . '<YourModuleName>/upload/' . $fileName);
$uploadCsv = file(_PS_MODULE_DIR_ . '<YourModuleName>/upload/' . $fileName, FILE_SKIP_EMPTY_LINES);
$Db = array_map("str_getcsv", $uploadCsv, array_fill(0, count($uploadCsv), ';'));
$keys = array_shift($Db);
foreach ($Db as $i => $row) {
$Db[$i] = array_combine($keys, $row);
}
print_r($Db);
}
} else {
$uploadCsv = file(_PS_MODULE_DIR_ . '<YourModuleName>/upload/' . $fileName, FILE_SKIP_EMPTY_LINES);
$Db = array_map("str_getcsv", $uploadCsv, array_fill(0, count($uploadCsv), ';'));
$keys = array_shift($Db);
foreach ($Db as $i => $row) {
$Db[$i] = array_combine($keys, $row);
}
print_r($Db);
}
unset($_FILES['DB_<YourThings>_DATA']);
}
}
This question have been asked many times in SO, but still I cannot figure it out why is this not working for me.
I am working on E-Commerce Laravel Project.
The issue is that, when the admin uploads the image file of the product, get the error of:
Can't write image data to path
(http://example.com/ankur/images/uploads/products/img-newprod-540-350-350.jpg)
Here's the controller snippet of storing the image and related entries:
public function storeGeneral(Request $request)
{
$this->validate($request, [
'code' => 'required|alpha_dash|unique:products',
'name' => 'required',
'description' => 'string',
'details' => 'string',
'price' => 'required|regex:/^\d*(\.\d{2})?$/',
'tax_amount' => 'required|regex:/^\d*(\.\d{2})?$/',
'net_price' => 'required|regex:/^\d*(\.\d{2})?$/',
'weight' => 'required|integer',
'image_file' => 'image|mimes:jpeg,jpg,JPG'
]);
if ($request->ajax() ) {
if ($request->file('image_file' ) ) {
$request['img_code'] = 'img-' . $request->get('code' );
$product = Product::create($request->all() );
$product->categories()->attach($request->input('category_id') );
Session::put('product_last_inserted_id', $product->id);
$mgCode = DB::table('products')->latest()->limit(1)->pluck('img_code');
$imageType = [
'product' => [
'height' => 350,
'width' => 350
],
'carousel' => [
'height' => 163,
'width' => 163
],
'cart' => [
'height' => 64,
'width' => 64
]
];
foreach($imageType as $key => $value)
{
$fileName = Safeurl::make($mgCode );
$image = Image::make($request->file('image_file' ) );
//$path = public_path( 'images/uploads/products/' );
$path = url('/images/uploads/products/');
if ($key == 'product') {
$image->resize($value['width'], $value['height'] );
$image->save($path.'/'.$fileName."-". $value['width'] ."-".$value['height'] .".jpg", 100 );
} else if ($key == 'carousel' ) {
$image->resize($value['width'], $value['height'] );
$image->save($path.'/'.$fileName."-". $value['width'] ."-".$value['height'] .".jpg", 100 );
} else if ($key == 'cart' ) {
$image->resize($value['width'], $value['height'] );
$image->save($path.'/'.$fileName."-". $value['width'] ."-".$value['height'] .".jpg", 100 );
}
}
} else {
$product = Product::create($request->all() );
Session::put('product_last_inserted_id', $product->id);
}
return response(['status' => 'success', 'msg' => 'The product has been added successfully.']);
}
return response(['status' => 'failed', 'msg' => 'The product could not be added successfully.']);
}
The folder permission that I have is 0777 for the images directory and it's sub directories.
But still I get the above mentioned error exception.
EDIT 1:
This is the folder structure in my hosting account file manager which is inside the public_html directory:
Can anybody help me out with this.
Thanks in advance.
I have somehow figured it out.
Instead of using url() or base_path(), I used public_path().
Code that I used:
$path = public_path('../../public_html/ankur/images/uploads/products');
Worked like a charm.
You are trying to save image using url. Instead of url try following
$path = base_path().'/images/uploads/products';
You can not save the image using http path. You have to use base_path() or manual type full server directory path /home/webtuningtechnology/public_html/images/ like this
I want to have a multiple file upload code.
For example:
Koala.jpg
Penguins.jpg
Jellyfish.jpg
There is input text where the user can set the new name of the image.
The user will now upload the images and the inputted text for new image name is "Animals"
Now, what I want is when this uploaded the output should be Animals1.jpg, Animals2.jpg, Animals3.jpg.
The problem is when I tried to upload all these images, only one image is uploading.
I tried to make research and applied some codes on my program, but still not working.
Controller
public function do_upload() {
$config = array(
'image_library' => 'gd2',
'file_name' => $this->input->post('finame'),
'upload_path' => './public/img/uploads',
'upload_url' => base_url().'public/img/uploads',
'allowed_types' => 'gif|jpg|jpeg',
'max_size' => '1024KB',
'max_width' => '1024',
'max_height' => '768',
'maintain_ratio'=> TRUE,
'overwrite' => false,
);
$this->load->library('upload', $config);
if (!$this->upload->do_upload()) {
$error_msg = "<div class='alert alert-error'>".$this->upload->display_errors()."</div>";
$error = array('error' => $error_msg);
}
else {
$upload_data = $this->upload->data();
$data['thumbnail_name'] = $upload_data['raw_name']. '_thumb' .$upload_data['file_ext'];
$file_array = array(
'image' => $data['thumbnail_name'],
'image_name' => $upload_data['file_name'],
//'description' => "",
'date_created' => date('Y-m-d H:i:s', now()),
'date_modified' => date('Y-m-d H:i:s', now()),
'author' => $this->session->userdata('username'),
'size' => $upload_data['file_size'],
'type' => $upload_data['image_type'],
'width' => $upload_data['image_width'],
'height' => $upload_data['image_height'],
//'document_name' => $field,
//'department' => $field2,
//'notes' => "",
);
$this->session->set_userdata('image_print', $file_array);
$this->load->database();
$this->db->insert('tbl_image', $file_array);
$data = array('upload_data' => $this->upload->data());
$user_level['records']=$this->user_model->get_records();
$this->load->view('v_dashboard/page/header_view', $user_level);
$this->load->view('v_document/upload/upload_result_view', $data);
$this->load->view('v_dashboard/page/footer_view');
}
}
I have this on my HTML
<label for="file"><strong>Select File To Upload:</strong></label>
<input type="file" name="userfile[]" multiple class="btn transcolor btn-file"/>
<br/><br/>
By the way, I'm using BLOB on my database.
I tried to refer to this links
Ellislab
GitHub
StackOverflow
StackOverflow
CodingLikeASir
You have to run the for loop till the count of the uploaded image file.
Like this:
for ($i=0; $i < count($_FILES['userfile']['name']); $i++)
{
// function to add the image name one by one into database.
}
I have one form. When user submit the form, I will store the data on database and generate the pdf of the same. Here what I want to do is:
Download PDF file;
Save the PDF in a folder.
Downloading the PDF is working perfectly, but it is not being saved in a folder.
public function get_pdf() {
$count = 1;
for ($i = 0; $i < count($_POST['description']); $i++) {
$table_data[] = array(
'serial' => $count,
'description' => $_POST['description'][$i],
'unit' => $_POST['unit'][$i],
'quantity' => $_POST['quantity'][$i],
'rate' => $_POST['rate'][$i],
'amount' => $_POST['amount'][$i]
);
$count++;
}
if (!empty($table_data)) {
// loading pdf library //
$this->load->library('cezpdf');
// field names //
$table_data_field = array(
'serial' => 'S.No.',
'description' => 'Work Description',
'unit' => 'Unit',
'quantity' => 'Quantity',
'rate' => 'Rate',
'amount' => 'Amount'
);
$this->cezpdf->ezTable($table_data, $table_data_field, 'Quotation', array('width' => 500, 'justification' => 'center'));
ob_start();
$this->cezpdf->ezStream();
$data = ob_get_contents();
ob_end_clean();
// save the quotation file on client folder //
move_uploaded_file('Quotation', FCPATH . '/quotation/' . $data);
// force to download the file //
$this->load->helper('download');
force_download('Quotation.pdf', $data);
}
}
Please help me on this. I use CodeIgniter.
Firstly, I don't think you ought to be using move_uploaded_file, and secondly, the name of your file contains the contents of the PDF, not a filename.