Fileinput issue in ActiveForm when updating via Yii 2 - file-upload

I am using Yii2 framwork. My file upload function worked well when I upload a single img, while when I click the posed article and I only want to update the post again(Suppose I didn't want to update the img, I only want to update other contents). But I found my uploaded file were replaced with an empty value(varchar type) when I click view. my uploaded img can't show out.
I do tried to fixed by myself as below, But the existing file value can't be saved when I click the submit button.
<?php
if (($post->file) != "") {
echo $form->field($post, 'file')->textInput()->hint('My currently uploaded file')->label('My Photo') ;
}
else{
echo $form->field($post, 'file')->fileInput()->hint('To upload a new file')->label('My Photo') ;
}
?>
When I click submit button, my existing file was gone.
Is there any good way to fix it.
Thanks for your opinions in advance.

Use another variable in your model for upload a file.
For example use file_field name for get file from submitted and store in file field.
class PostModel extends Model
{
/**
*
* #var UploadedFile
*/
public $file_field;
public function rules() {
return [
['file_field', 'file'],
];
}
}
echo $form->field($post, 'file_field')->fileInput()->hint('To upload a new file')->label('My Photo') ;
$post->file_field = UploadedFile::getInstance($post, 'file_field');
For upload new file check the file_field:
if ($post->file_field) {
// $post->file old file
// Save $post->file_field and store name in $post->file
}

Add a rule to your model rules:
[['file'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg'],
and check for an empty upload in your controller:
if (Yii::$app->request->isPost) {
$ok = true;
// process your other fields...
...
// process image file only if there is one
$post->file= UploadedFile::getInstance($post, 'file');
if ($post->file && $post->upload()) {
}
if ($ok) {
return $this->redirect(...);
}
}
See Yii2 docs and the Yii2 guide for detailed infos about file upload.

Related

using S3 Laravel8 create a unique folder with every upload file

I have this code is working perfectly fine, But I want when I upload the image 1st time to create a new folder and store the image, as I want 2nd time when I upload a new file to create a new unique folder and store the file...
Please help me with this if someone knows how to do this because I am new to Laravel.
public function storemultipleImages(Request $request)
{
$this->validate($request, ['image' => 'required|image']);
if ($request->hasfile('image')) {
$file = $request->file('image');
$name = time() . $file->getClientOriginalName();
$filePath = 'poster_art_1/' . $name;
Storage::disk('s3')->put($filePath, file_get_contents($file));
return back()->with('success', 'Image Uploaded successfully');
}
}

How to download file from Sanity via HTTP?

I would like to know if there is possibility to download file from Sanity with HTTP request?
I only have reference ID:
{
file: {
asset: {
_ref: "file-fxxxxxxxxxxxxxxxxxxxx-xlsx"
_type: "reference"
}
}
}
I would like to do this is this scenario:
<a href="https://cdn.sanity.io/assets/clientID/dataset/file-xxxxxxxxxxx-xlsx">
Download File
</a>
You can, indeed 🎉 With a bit of custom code you can do it just from the _ref, which is the file document's _id
Creating the URL from the _ref/_id of the file
The _ref/_id structure is something like this: file-{ID}-{EXTENSION} (example: file-207fd9951e759130053d37cf0a558ffe84ddd1c9-mp3).
With this, you can generate the downloadable URL, which has the following structure: https://cdn.sanity.io/files/{PROJECT_ID}/{DATASET}/{ID_OF_FILE}.{EXTENSION}. Here's some pseudo Javascript code for the operation:
const getUrlFromId = ref => {
// Example ref: file-207fd9951e759130053d37cf0a558ffe84ddd1c9-mp3
// We don't need the first part, unless we're using the same function for files and images
const [_file, id, extension] = ref.split('-');
return `https://cdn.sanity.io/files/${PROJECT_ID}/${DATASET}/${id}.${extension}`
}
Querying the URL directly
However, if you can query for the file's document with GROQ that'd be easier:
*[(YOUR FILTER HERE)] {
file->{ url } // gets the URL from the referenced file
}
You can do the same with images, too.

Laravel 5 issues uploading/saving pdf

I'm using Laravel 5.6, jQuery 3.3.1, bootstrap 3.3.7, and PHP 7.1.4
I need to be able to allow users to upload files and pictures, basically jpg, gif, png, and pdf. I am using the public disk and storing the files in storage/app/public/folder_name where folder_name is defined in an env file
FILESYSTEM_DRIVER=public
PO_FILE_FOLDER=purchase_orders
INSURANCE_FILE_FOLDER=insurance
NOTE_FILE_FOLDER=notes
RENTAL_AGREEMENT_FILE_FOLDER=rental_agreements
SIGNATURES=signatures
They are then defined in config/app
'insurance_file_folder' => env('INSURANCE_FILE_FOLDER', ''),
'po_file_folder' => env('PO_FILE_FOLDER', ''),
'note_file_folder' => env('NOTE_FILE_FOLDER', ''),
'rental_agreement_file_folder' => env('RENTAL_AGREEMENT_FILE_FOLDER', ''),
'max_image_width' => env('MAX_IMAGE_WIDTH', 500),
'filesystem_driver' => env('FILESYSTEM_DRIVER', 'local'),
When I upload image files they upload to the appropriate folder but when I try to upload pdf files the system creates a new folder named as what I'm naming the file and the pdf is in the new folder with a random name. I'm using the exact same code to upload both images and pdf files so I can't figure out why it works for one but not the other.
Here is my controller code
public function store(PurchaseOrderRequest $poRequest, Customer $customer)
{
$purchaseOrder = $customer->purchaseOrders()->create($poRequest->except('attachment'));
if ($poRequest->hasFile('attachment')) {
$purchaseOrder->saveFile(config('app.po_file_folder', ''), $poRequest->file('attachment'));
}
return redirect()->action('CustomerController#edit', $customer)->with('alert', 'Purchase Order created.');
}
My model PurchaseOrder saveFile code
public function saveFile($folder_name, $file)
{
// if file submited then check if file already exists, if so delete file and create new file
$file_name = $this->createFileName();
File::removeFiles($folder_name.'/'.$file_name, FALSE);
$file_name = $file_name.'.'.$file->getClientOriginalExtension();
$file = File::resize($file);
$this->attachment_path = $folder_name.'/'.$file_name;
Storage::disk(config('app.filesystem_driver', ''))->put($this->attachment_path, $file);
$this->save();
}
public function createFileName()
{
$file_name = 'po_'.$this->customer->code.'-'.$this->customer->id.'_'.$this->po_number.'-'.$this->id;
return $file_name;
}
My File helper code
public static function resize($file)
{
$resized_file = $file;
if (strtolower($resized_file->getClientOriginalExtension()) != 'pdf') {
// resize file if it is not pdf (file is photo)
// get image size then resize largest size to size limit - dont upsize if image is smaller than max size
list($width, $height) = getimagesize($resized_file);
if ($width > $height) {
$resized_file = Image::make($resized_file)->resize(config('app.max_image_width', ''), null, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})->encode($resized_file->getClientOriginalExtension(), 60);
} else {
$resized_file = Image::make($resized_file)->resize(null, config('app.max_image_width', ''),function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})->encode($resized_file->getClientOriginalExtension(), 60);
}
}
return $resized_file;
}
public static function removeFiles($file_name, $ext_included = FALSE)
{
if ($ext_included == TRUE) {
// remove specific file
if (Storage::disk(config('app.filesystem_driver', ''))->exists($file_name)) {
Storage::delete($file_name);
}
} else {
// remove file with any extension
$ext = array('.pdf', '.jpg', '.jpeg', '.gif', '.png');
for ($cnt = 0; $cnt <= 4; ++$cnt) {
if (Storage::disk(config('app.filesystem_driver', ''))->exists($file_name.$ext[$cnt])) {
Storage::delete($file_name.$ext[$cnt]);
}
}
}
}
I realize the code may be a little confusing use the env variables but I'm trying to limit the pain in the event I need to change the folder name or move the files outside of the app. The application will have very few users maybe 3 or 4 and I don't anticipate a lot of files being uploaded which is why I'm storing the files in the application structure.
This is my first Laravel app and I put this code together using the docs and many a many different tutorials. It took a while but eventually I got it to work for images. So if you see things that don't look standard or good practice I welcome any pointers.
Thanks for taking the time to read this, any help is appreciated!
I had to use two different approaches to saving files in the system based on if the file was an image or pdf. I do some processing (resizing) on images before putting them into my storage folders with Intervention Image. This in turn returns a different object type than the raw uploaded file, because of this some of the commands to add the file (after processing) will not work.
So if I'm storing a pdf file I use:
$file->storeAs($folder_name, $file_name, config('app.filesystem_driver', ''));
If I'm storing an image that I have used Intervention Image on then I use:
Storage::disk(config('app.filesystem_driver', ''))->put($this->attachment_path, $file);
I couldn't find one command that worked for both so I just check the extension before storing. Not sure if this is the "right way" but it got the job done.

How To Count Views On Click Of A Button Or Web Page Is There Any Extension

I am a newbie interested to know are there any extension to count views on click of a button as to know no. of registered users or visiters to web page to know the view count on click of a image is there any extension.
Plz let me know if any
thanx :)
I think , there is no need of any extension. Make a Ajax call on click button or image you are interested.
Improved:
I supposed you have Site as controller and index as action. then, please keep this code on views/site/index.php .
Yii::app()->clientScript->registerScript('logo_as_image_script', '$(document).ready(function() {
$("#logo_as_image").click(function() {
$.post("'.Yii::app()->createAbsoluteUrl('site/index').'",
{
clicked: "1"
},
function(data, status) {
alert("Data: " + data + "\nStatus: " + status);
});
});
});');
Yii::app()->clientScript->registerCoreScript('jquery');
echo CHtml::image(Yii::app()->baseUrl . '/images/logo.png', 'Logo as Image', array('id' => 'logo_as_image'));
And, keep this code on SiteController.php .
public function actionIndex()
{
// keep record of data ; do more filtering ; other manupulation
if(isset($_POST['clicked'])){
$nextCount = Yii::app()->user->getState('clickCount')+1;
Yii::app()->user->setState('clickCount',$nextCount );
echo $nextCount;
Yii::app()->end();
}
#other codes here.
$this->render('index');
}
Lets assume that you want to store how many registered users have accessed the page at :
www.something.com/something/someaction
then visit the controller and add the code like so :
public function actionSomeAction()
{
$model = new CountDbModel();
if(!Yii::app()->user->isGuest){
$model->page = 'This page name here.';
$model->user_id = Yii::app()->user->id;
$model->count = #Add the value here.
#You other code here....
$this->render('whateverView',array('model'=>$blah));
}
}
I hope it helped.

Kendo Async Upload : File displays even after clicking Remove

I am uploading files through Kendo Upload. On uploading a file and then clicking on remove, the RemoveCircular method of controller is called and it duly deletes the file from server.
However the Filename and Remove button are still displayed though they should be removed as well.
Is there anything I'm missing here? Thanks for help.
The code in .cshtml is as below.
<div class="controls-trck">
#(Html.Kendo().Upload()
Name("UploadCircular")
.HtmlAttributes(new { style = "width:220px" })
.Multiple(false)
.Async(a => a
.Save("SaveCircular", "DB0010062")
.Remove("RemoveCircular", "DB0010062")
.AutoUpload(false)
)
)
</div>
Code in Controller:
public ActionResult RemoveCircular(string[] fileNames)
{
foreach (var fullName in fileNames)
{
//Delete Files
}
return Content("");
}
It looks like empty response is treated like as an unsuccessful response. Try to return empty JSON instead.