How to Save Uploaded File's Name on Database - php

Cont. - Add File Uploader to Joomla Admin Component
I could able to upload file and save it on disk. But its not saving file name on the database.
How can i do it ?
Here is the controller -
class InvoiceManagerControllerInvoiceManager extends JControllerForm
{
function save(){
$file = JRequest::getVar('jform', null, 'files', 'array');
$path = JPATH_BASE;
// Make the file name safe.
jimport('joomla.filesystem.file');
$file['name']['invoice'] = JFile::makeSafe($file['name']['invoice']);
// Move the uploaded file into a permanent location.
if (isset($file['name']['invoice'])) {
// Make sure that the full file path is safe.
$filepath = JPath::clean($path. DS ."components". DS ."com_invoicemanager". DS ."files". DS .strtolower($file['name']['invoice']));
// Move the uploaded file.
JFile::upload( $file['tmp_name']['invoice'], $filepath );
}
return parent::save();
}
}
Form field in XML -
<field name="invoice" type="file"/>
UPDATE:
worked after adding following lines taken from #Andras Gera code
$data = JRequest::getVar( 'jform', null, 'post', 'array' );
$data['invoice'] = strtolower( $file['name']['invoice'] );
JRequest::setVar('jform', $data );

I've ran into the same problem, maybe we can go forward together. Here is my codes:
/administrator/components/com_comp_name/models/forms/edit.xml
<?xml version="1.0" encoding="utf-8"?>
<form addrulepath="/administrator/components/com_gonewsletter/models/rules">
<fieldset name="details">
<field
name="id"
type="hidden"
/>
<field
name="title"
type="text"
label="COM_GONEWSLETTER_EDIT_TITLE_LABEL"
description="COM_GONEWSLETTER_EDIT_TITLE_DESC"
size="40"
class="inputbox"
required="true"
default=""
/>
<field
name="date"
type="calendar"
label="COM_GONEWSLETTER_EDIT_DATE_LABEL"
description="COM_GONEWSLETTER_EDIT_DATE_DESC"
size="40"
class="inputbox"
required="true"
default=""
format="%Y-%m-%d"
/>
<field
name="published"
type="list"
label="JSTATUS"
description="COM_GONEWSLETTER_EDIT_PUBLISHED_DESC"
class="inputbox"
size="1"
default="0">
<option
value="1">JPUBLISHED</option>
<option
value="0">JUNPUBLISHED</option>
</field>
<field
type="file"
name="pdf_file"
label="COM_GONEWSLETTER_EDIT_FILE_LABEL"
default=""
description="COM_GONEWSLETTER_EDIT_FILE_DESC"
size="40"
accept="application/pdf"
class="fileuploader"
/>
<field
name="file"
type="hidden"
/>
</fieldset>
</form>
and
/administrator/components/com_comp_name/controllers/edit.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla controllerform library
jimport('joomla.application.component.controllerform');
/**
* GoNewsletter Controller
*/
class GoNewsletterControllerEdit extends JControllerForm
{
function __construct($config = array()) {
$this->view_list = 'List';
parent::__construct($config);
}
function save(){
// ---------------------------- Uploading the file ---------------------
// Neccesary libraries and variables
jimport( 'joomla.filesystem.folder' );
jimport('joomla.filesystem.file');
$data = JRequest::getVar( 'jform', null, 'post', 'array' );
// Create the gonewsleter folder if not exists in images folder
if ( !JFolder::exists( JPATH_SITE . DS . "images" . DS . "gonewsletter" ) ) {
JFolder::create( JPATH_SITE . DS . "images" . DS . "gonewsletter" );
}
// Get the file data array from the request.
$file = JRequest::getVar( 'jform', null, 'files', 'array' );
// Make the file name safe.
$filename = JFile::makeSafe($file['name']['pdf_file']);
// Move the uploaded file into a permanent location.
if ( $filename != '' ) {
// Make sure that the full file path is safe.
$filepath = JPath::clean( JPATH_SITE . DS . 'images' . DS . 'gonewsletter' . DS . strtolower( $filename ) );
// Move the uploaded file.
JFile::upload( $file['tmp_name']['pdf_file'], $filepath );
// Change $data['file'] value before save into the database
$data['file'] = strtolower( $filename );
}
// ---------------------------- File Upload Ends ------------------------
JRequest::setVar('jform', $data );
return parent::save();
}
}
If you print out the $data before send it to parent::save($data) it contains the right fields you want to save, but it doesn't. I tried to use an input type=text instead of type=file and it saves correctly.
I tried another way like: input type=file and name=pdf_file, after then I added a hidden field name=file default="". And then I've set up this hidden field value to filename without success. Maybe I was doing something wrong. Keep continue to figure out something.

You can use php move_uploaded_file() function

//import joomlas filesystem functions, we will do all the filewriting with joomlas functions
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.folder');
//this is the name of the field in the html form, filedata is the default name for swfupload
$fieldName = 'Filedata';
//the name of the file in PHP's temp directory that we are going to move to our folder
$fileTemp = $_FILES[$fieldName]['tmp_name'];
//always use constants when making file paths, to avoid the possibilty of remote file inclusion
$uploadPath = JPATH_SITE.DS.'path'.DS.'path'.DS.$fileName;
if(!JFile::upload($fileTemp, $uploadPath))
{
echo JText::_( 'ERROR MOVING FILE' );
return;
}
else
{
//Updating the db with the $fileName.
$db =& JFactory::getDBO();
$query = $db->getQuery(true);
$query->update($db->nameQuote(TABLE_PREFIX.'table_name'));
$query->set($column.' = '.$db->quote($fileName));
$query->where($db->nameQuote('id').'='.$db->quote($id));
$db->setQuery($query);
$db->query();
}
$column - db column name of the file
$fileName - file name
Query is ran if the file is successfully uploaded.

set filename in request variable as it's now a $_FILES variable
JRequest::setVar('jform[invoice]',$file['name']['invoice'] );
//full code
class InvoiceManagerControllerInvoiceManager extends JControllerForm
{
function save(){
$file = JRequest::getVar('jform', null, 'files', 'array');
$path = JPATH_BASE;
// Make the file name safe.
jimport('joomla.filesystem.file');
$file['name']['invoice'] = JFile::makeSafe($file['name']['invoice']);
// Move the uploaded file into a permanent location.
if (isset($file['name']['invoice'])) {
// Make sure that the full file path is safe.
$filepath = JPath::clean($path. DS ."components". DS ."com_invoicemanager". DS ."files". DS .strtolower($file['name']['invoice']));
// Move the uploaded file.
JFile::upload( $file['tmp_name']['invoice'], $filepath );
JRequest::setVar('jform[invoice]',$file['name']['invoice'] );
}
return parent::save();
}
}

On joomla 3.2.x, I have to override save function of my model class to save the uploaded file name to db, like this
public function save($data){
$input = JFactory::getApplication()->input;
$files = $input->files->get('jform');
$fieldName = 'thumbnail';
$data['thumbnail'] = $files[$fieldName]['name'];
return parent::save($data);
}

Related

Laravel 8 image upload: Best practices for storing and editing image files

I need assistance to more understand the concept so I can become a better developer. I want to learn how to refactor the code and erase all duplications.
What's the best practices for image uploads? Renaming them correctly?
I have a block of code that handles two attachments:
if( $request->hasFile('LFImage') ) {
$destination = public_path('app/lostFound/lostItems' . $lostFound->LFImage);
if( File::exists($destination) )
{
File::delete($destination);
}
$file = $request->file('LFImage');
$extension = $file->getClientOriginalExtension();
$filename = $lostFound->LFNumber . '-' . $lostFound->lostItem . '.' . $extension;
$file->move('app/lostFound/lostItems', $filename);
$lostFound->LFImage = $filename;
}
if( $request->hasFile('handoverStatement') ) {
$destination = public_path('app/lostFound/handoverStatements' . $lostFound->handoverStatement);
if( File::exists($destination) )
{
File::delete($destination);
}
$file = $request->file('handoverStatement');
$extension = $file->getClientOriginalExtension();
$filename = $lostFound->lostItem . '-' . $lostFound->LFNumber . '.' . $extension;
$file->move('app/lostFound/handoverStatements', $filename);
$lostFound->handoverStatement = $filename;
}
They're exactly the same except with the upload directory.
How can I make it as a one code block across the entire application with changeable file name and location depending on the form?
Some file names require random strings, how can I "Edit" the random string to the file that was uploaded?
Best practice when uploading and storing files in Laravel is using Storage.
It has all needed methods to work with files, you can save the file like this:
use Illuminate\Support\Facades\Storage;
Storage::put('images/', $request->file('LFImage'));
In the documentation provided above, you can find other examples like renaming and moving files
In order to access these files from web as well, you can use the command php artisan storage:link, which creates a symbolic link to storage folder in your public folder. After you create the symbolic link, you can generate URL to the file like this:
asset('storage/test.txt')
To avoid duplications, you can create a function in your controller to create a file. You will then just call this function with different files to keep the file creation code in one place.
you can simply write this
if ($request->hasFile('logo')) {
deleteImageFromDirectory(setting('logo'), "Settings");
$data['logo'] = uploadImageToDirectory( $request->logo , "Settings");
}
and define uploadImageToDirectory function in your helper functions or create a trait
function uploadImageToDirectory($imageFile, $directory = '' ){
$imageName = $imageFile->getClientOriginalName(); // Set Image name
$imageFile->storeAs("/Images/$directory", $imageName, 'public');
return $imageName;
}

Yii2 - How to upload & store Images in Database

I am using yii2. I am trying to select a file and then want to save it to my database table. I am using core PHP for it. Below is my code
<form action = <?=\yii\helpers\Url::toRoute(['meteracceptanceheader/import'])?> method ="post"
enctype="multipart/form-data">
.
.
.
.
.
.
.
<div class="row">
<div class="col-md-2">
Upload-Image
<input type="file" name="file"/>
<br />
<input type="submit" class="btn btn-primary pull-left" />
</div>
</div>
</form>
Controller
public function actionImport()
{
.
.
. // my other code
$file = $_FILES['file'];
$fileName = $_FILES['file']['name'];
$fileExt = explode('.',$fileName);
print_r($file);
die();
.
.
.
.
return $this->render('excel_finish', ['records_saved' => $ok_count,'status_arr'=>$status_arr]);
}
Database Table
In the above table, id is auto-increment accpt_id is the model id which I already have and file_path is the name of the file which should be saved like 123.jpg.
The file should be saved into a folder uploads/meter_acceptance/ and append with the file name.
Note:
I have already know how to upload images via the active form but here I want to do it in a traditional way.
Any help would be highly appreciated.
your controller should be like this
public function actionUpload(){
$model = new Images();
$uploadPath = Yii::getAlias('#root') .'/uploads/';
if (isset($_FILES['image'])) {
$file = \yii\web\UploadedFile::getInstanceByName('image');
$original_name = $file->baseName;
$newFileName = \Yii::$app->security
->generateRandomString().'.'.$file->extension;
// you can write save code here before uploading.
if ($file->saveAs($uploadPath . '/' . $newFileName)) {
$model->image = $newFileName;
$model->original_name = $original_name;
if($model->save(false)){
echo \yii\helpers\Json::encode($file);
}
else{
echo \yii\helpers\Json::encode($model->getErrors());
}
}
}
else {
return $this->render('upload', [
'model' => $model,
]);
}
return false;
}

Flysystem local asset from outside public folder in Laravel 4

I have the following method that will get an asset depending on which CDN is used:
public function getAsset($filename, $dir = null, $prefix = null)
{
$extension = File::extension($filename);
$name = File::name($filename);
$filename = $dir . $prefix . $name . '.' . $extension;
if(Flysystem::getDefaultConnection() == 'awss3') return Flysystem::getAdapter()->getClient()->getObjectUrl('xxxx', $filename);
if(Flysystem::getDefaultConnection() == 'local') return Flysystem::getAdapter()->getClient()->getObjectUrl($filename);
}
When 'local' storage is selected (in a config) I want to be able to get the asset from the app/storage/temp/media/ directory and display them to the as an image in a tag, how can I modify the above to work like that?
How do I even get an asset from outside the public directory anyway?

Create Folder and Insert if Not Present

I wonder whether someone may be able to help me please.
I'm using Aurigma's Image uploader software to allow users to upload images for locations they visit. The information is saved via the script shown below:
<?php
//This variable specifies relative path to the folder, where the gallery with uploaded files is located.
//Do not forget about the slash in the end of the folder name.
$galleryPath = 'UploadedFiles/';
require_once 'Includes/gallery_helper.php';
require_once 'ImageUploaderPHP/UploadHandler.class.php';
/**
* FileUploaded callback function
* #param $uploadedFile UploadedFile
*/
function onFileUploaded($uploadedFile) {
$packageFields = $uploadedFile->getPackage()->getPackageFields();
$username=$packageFields["username"];
$locationid=$packageFields["locationid"];
global $galleryPath;
$absGalleryPath = realpath($galleryPath) . DIRECTORY_SEPARATOR;
$absThumbnailsPath = $absGalleryPath . 'Thumbnails' . DIRECTORY_SEPARATOR;
if ($uploadedFile->getPackage()->getPackageIndex() == 0 && $uploadedFile->getIndex() == 0) {
initGallery($absGalleryPath, $absThumbnailsPath, FALSE);
}
$locationfolder = $_POST['locationid'];
$locationfolder = preg_replace('/[^a-z0-9_\-\.()\[\]{}]/i', '_', $locationfolder);
if (!is_dir($absGalleryPath . $locationfolder)) {
mkdir($absGalleryPath . $locationfolder, 0777);
}
$dirName = $_POST['folder'];
$dirName = preg_replace('/[^a-z0-9_\-\.()\[\]{}]/i', '_', $dirName);
if (!is_dir($absGalleryPath . $dirName)) {
mkdir($absGalleryPath . $dirName, 0777);
}
$path = rtrim($dirName, '/\\') . '/';
$originalFileName = $uploadedFile->getSourceName();
$files = $uploadedFile->getConvertedFiles();
// save converter 1
$sourceFileName = getSafeFileName($absGalleryPath, $originalFileName);
$sourceFile = $files[0];
/* #var $sourceFile ConvertedFile */
if ($sourceFile) {
$sourceFile->moveTo($absGalleryPath . $sourceFileName);
}
// save converter 2
$thumbnailFileName = getSafeFileName($absThumbnailsPath, $originalFileName);
$thumbnailFile = $files[1];
/* #var $thumbnailFile ConvertedFile */
if ($thumbnailFile) {
$thumbnailFile->moveTo($absThumbnailsPath . $thumbnailFileName);
}
//Load XML file which will keep information about files (image dimensions, description, etc).
//XML is used solely for brevity. In real-life application most likely you will use database instead.
$descriptions = new DOMDocument('1.0', 'utf-8');
$descriptions->load($absGalleryPath . 'files.xml');
//Save file info.
$xmlFile = $descriptions->createElement('file');
$xmlFile->setAttribute('name', $_POST['folder'] . '/' . $originalFileName);
$xmlFile->setAttribute('source', $sourceFileName);
$xmlFile->setAttribute('size', $uploadedFile->getSourceSize());
$xmlFile->setAttribute('originalname', $originalFileName);
$xmlFile->setAttribute('thumbnail', $thumbnailFileName);
$xmlFile->setAttribute('description', $uploadedFile->getDescription());
//Add additional fields
$xmlFile->setAttribute('username', $username);
$xmlFile->setAttribute('locationid', $locationid);
$xmlFile->setAttribute('folder', $dirName);
$descriptions->documentElement->appendChild($xmlFile);
$descriptions->save($absGalleryPath . 'files.xml');
}
$uh = new UploadHandler();
$uh->setFileUploadedCallback('onFileUploaded');
$uh->processRequest();
?>
In additon to the original script I've added code that creates a folder, with it's name based on the current 'locationid'. This is shown below.
$locationfolder = $_POST['locationid'];
$locationfolder = preg_replace('/[^a-z0-9_\-\.()\[\]{}]/i', '_', $locationfolder);
if (!is_dir($absGalleryPath . $locationfolder)) {
mkdir($absGalleryPath . $locationfolder, 0777);
}
What I like to incorporate, is a check that looks to see whether there is a folder already setup with the current 'locationid' value, if not create the folder. I'm ceratianly no expert in PHP, but I know that to check to see whether a file exists, the if(file exists....) can be used, but I just wondered whether someone could tell me please how I can implement this check for the folder name?
Many thanks
Chris
I think is_dir() is what you are looking for.
UPDATE:
The code you have:
if (!is_dir($absGalleryPath . $locationfolder)) {
mkdir($absGalleryPath . $locationfolder, 0777);
}
Does exactly what you want. It checks for the folder and if it does not exist then it creates one for you (with CHMOD 777). Don't see what your question is then...

Save 'Username' as Filename

I wonder whether someone could help me please.
I'm using Image Uploader from Aurigma, and to save the uploaded images, I've put this script together.
<?php
//This variable specifies relative path to the folder, where the gallery with uploaded files is located.
//Do not forget about the slash in the end of the folder name.
$galleryPath = 'UploadedFiles/';
require_once 'Includes/gallery_helper.php';
require_once 'ImageUploaderPHP/UploadHandler.class.php';
/**
* FileUploaded callback function
* #param $uploadedFile UploadedFile
*/
function onFileUploaded($uploadedFile) {
$packageFields = $uploadedFile->getPackage()->getPackageFields();
$userid = $packageFields["userid"];
$locationid= $packageFields["locationid"];
global $galleryPath;
$absGalleryPath = realpath($galleryPath) . DIRECTORY_SEPARATOR;
$absThumbnailsPath = $absGalleryPath . 'Thumbnails' . DIRECTORY_SEPARATOR;
if ($uploadedFile->getPackage()->getPackageIndex() == 0 && $uploadedFile->getIndex() == 0) {
initGallery($absGalleryPath, $absThumbnailsPath, FALSE);
}
$dirName = $_POST['folder'];
$dirName = preg_replace('/[^a-z0-9_\-\.()\[\]{}]/i', '_', $dirName);
if (!is_dir($absGalleryPath . $dirName)) {
mkdir($absGalleryPath . $dirName, 0777);
}
$path = rtrim($dirName, '/\\') . '/';
$originalFileName = $uploadedFile->getSourceName();
$files = $uploadedFile->getConvertedFiles();
// save converter 1
$sourceFileName = getSafeFileName($absGalleryPath, $originalFileName);
$sourceFile = $files[0];
/* #var $sourceFile ConvertedFile */
if ($sourceFile) {
$sourceFile->moveTo($absGalleryPath . $sourceFileName);
}
// save converter 2
$thumbnailFileName = getSafeFileName($absThumbnailsPath, $originalFileName);
$thumbnailFile = $files[1];
/* #var $thumbnailFile ConvertedFile */
if ($thumbnailFile) {
$thumbnailFile->moveTo($absThumbnailsPath . $thumbnailFileName);
}
//Load XML file which will keep information about files (image dimensions, description, etc).
//XML is used solely for brevity. In real-life application most likely you will use database instead.
$descriptions = new DOMDocument('1.0', 'utf-8');
$descriptions->load($absGalleryPath . 'files.xml');
//Save file info.
$xmlFile = $descriptions->createElement('file');
$xmlFile->setAttribute('name', $_POST['folder'] . '/' . $originalFileName);
$xmlFile->setAttribute('source', $sourceFileName);
$xmlFile->setAttribute('size', $uploadedFile->getSourceSize());
$xmlFile->setAttribute('originalname', $originalFileName);
$xmlFile->setAttribute('thumbnail', $thumbnailFileName);
$xmlFile->setAttribute('description', $uploadedFile->getDescription());
//Add additional fields
$xmlFile->setAttribute('userid', $userid);
$xmlFile->setAttribute('locationid', $locationid);
$xmlFile->setAttribute('folder', $dirName);
$descriptions->documentElement->appendChild($xmlFile);
$descriptions->save($absGalleryPath . 'files.xml');
}
$uh = new UploadHandler();
$uh->setFileUploadedCallback('onFileUploaded');
$uh->processRequest();
?>
What I'd like to do is replace the files element of the filename and replace it with the username, so each saved folder and associated files can be indentified to each user.
I've added a username text field to the form which this script saves from
I think I'm right in saying that this is line that needs to change $descriptions->save($absGalleryPath . 'files.xml');.
So amongst many attempts I've tried changing this to $descriptions->save($absGalleryPath . '$username.xml, $descriptions->save($absGalleryPath . $username '.xml, but none of these have worked, so I'm not quite sure what I need to change.
I just wondered whether someone could perhaps have a look at this please and let me know where I'm going wrong.
Many thanks
'$username.xml' will be interpreted as $username.xml, you need to use "$username.xml". Single quotes "disable" the variable use inside strings.
What you are tryiing can be a bad idea, as you are making so a username can't contain 'special characters' like "/". Perhaps is not a problem if you aready have a rule that stop "/" being part of a username.

Categories