Laravel 5.1 File not deleting from folder - laravel-5.1

I want to delete a pdf file form my database as well as my public/uploads folder. It is deleting from the database but not from my public folder.
This is my controller:
public function deleteArticle($id) {
$article = Article::findOrFail($id);
File::delete($article->document);
$article->delete();
return redirect()->back();
}
/*This handles the posting of the file into the folder and storing of the url into the datab
$file = Input::file('document');
$file->move('uploads', $file->getClientOriginalName());
$document = asset('uploads/'.$file->getClientOriginalName());
$newArticle->document = $document;

As you are currently saving a url to the database ( by using the asset() function ) you can't delete the file by using that information.
It is usually enough to save just the document name in the database.
$document = $file->getClientOriginalName();
$newArticle->document = $document;
To delete the file you can then call:
File::delete(public_path('uploads/'.$article->document);
To Link to your file you can use the asset() method
asset('uploads/'.$article->document);

Storing the full URL in database is a bad idea. It will very hard to maintain files later. The best way is store only the filename with extension.
If you only have the filename in database, you can delete the file in this way:
$article = Article:findOrFail($id);
$document = $article->document; // take the image name from database
File::delete('uploads/'.$document); // delete the file
$article->delete() // delete the record from database
Edit
If you still want to use URL in database you can get the image name by using substr() and strpos() function. Example:
$image = substr($article->document,0,strpos("uploads/"));
You can get only the document name from URL and use it to delete the file.
To store only the filename follow this:
$document = $request->file('document')->getClientOriginalName();

Related

How to avoid photos from being replaced Firebase Storage [duplicate]

With the new Firebase API you can upload files into cloud storage from client code. The examples assume the file name is known or static during upload:
// Create a root reference
var storageRef = firebase.storage().ref();
// Create a reference to 'mountains.jpg'
var mountainsRef = storageRef.child('mountains.jpg');
// Create a reference to 'images/mountains.jpg'
var mountainImagesRef = storageRef.child('images/mountains.jpg');
or
// File or Blob, assume the file is called rivers.jpg
var file = ...
// Upload the file to the path 'images/rivers.jpg'
// We can use the 'name' property on the File API to get our file name
var uploadTask = storageRef.child('images/' + file.name).put(file);
With users uploading their own files, name conflicts are going to be an issue. How can you have Firebase create a filename instead of defining it yourself? Is there something like the push() feature in the database for creating unique storage references?
Firebase Storage Product Manager here:
TL;DR: Use a UUID generator (in Android (UUID) and iOS (NSUUID) they are built in, in JS you can use something like this: Create GUID / UUID in JavaScript?), then append the file extension if you want to preserve it (split the file.name on '.' and get the last segment)
We didn't know which version of unique files developers would want (see below), since there are many, many use cases for this, so we decided to leave the choice up to developers.
images/uuid/image.png // option 1: clean name, under a UUID "folder"
image/uuid.png // option 2: unique name, same extension
images/uuid // option 3: no extension
It seems to me like this would be a reasonable thing to explain in our documentation though, so I'll file a bug internally to document it :)
This is the solution for people using dart
Generate the current date and time stamp using:-
var time = DateTime.now().millisecondsSinceEpoch.toString();
Now upload the file to the firebase storage using:-
await FirebaseStorage.instance.ref('images/$time.png').putFile(yourfile);
You can even get the downloadable url using:-
var url = await FirebaseStorage.instance.ref('images/$time.png').getDownloadURL();
First install uuid - npm i uuid
Then define the file reference like this
import { v4 as uuidv4 } from "uuid";
const fileRef = storageRef.child(
`${uuidv4()}-${Put your file or image name here}`
);
After that, upload with the file with the fileRef
fileRef.put(Your file)
In Android (Kotlin) I solved by combining the user UID with the milliseconds since 1970:
val ref = storage.reference.child("images/${auth.currentUser!!.uid}-${System.currentTimeMillis()}")
code below is combination of file structure in answer from #Mike McDonald , current date time stamp in answer from # Aman Kumar Singh , user uid in answer from #Damien : i think it provides unique id, while making the firebase storage screen more readable.
Reference ref = firebaseStorage
.ref()
.child('videos')
.child(authController.user.uid)
.child(DateTime.now().millisecondsSinceEpoch.toString());

How to save created excel file to local server in MVC

I have a codes in my controller that let me creates an excel file. Now what I want is to save the excel file in my local server or server. How to do that?
I want the excel file saved in this location: http://localhost/reportrepository/filename.xlsx
Here are my codes algo:
try
{
var workbook = new Workbook();
// some other codes that creates the workbook....
// save workbook here to local server....
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
Your code can access the server's file system normally. The tricky part is to figure out how to access your web application's directory structure. Try something like this:
string workingDirectory = Request.Params["APPL_PHYSICAL_PATH"];
string workbookPath = workingDirectory + #"\ReportRepository\filename.xls";
workbook.SaveAs(workbookPath, ...);

Create and download word file from template in MVC

I have kept a word document (.docx) in one of the project folders which I want to use as a template.
This template contains custom header and footer lines for user. I want to facilitate user to download his own data in word format. For this, I want to write a function which will accept user data and referring the template it will create a new word file replacing the place-holders in the template and then return the new file for download (without saving it to server). That means the template needs to be intact as template.
Following is what I am trying. I was able to replace the placeholder. However, I am not aware of how to give the created content as downloadable file to user. I do not want to save the new content again in the server as another word file.
public void GenerateWord(string userData)
{
string templateDoc = HttpContext.Current.Server.MapPath("~/App_Data/Template.docx");
// Open the new Package
Package pkg = Package.Open(templateDoc, FileMode.Open, FileAccess.ReadWrite);
// Specify the URI of the part to be read
Uri uri = new Uri("/word/document.xml", UriKind.Relative);
PackagePart part = pkg.GetPart(uri);
XmlDocument xmlMainXMLDoc = new XmlDocument();
xmlMainXMLDoc.Load(part.GetStream(FileMode.Open, FileAccess.Read));
xmlMainXMLDoc.InnerXml = ReplacePlaceHoldersInTemplate(userData, xmlMainXMLDoc.InnerXml);
// Open the stream to write document
StreamWriter partWrt = new StreamWriter(part.GetStream(FileMode.Open, FileAccess.Write));
xmlMainXMLDoc.Save(partWrt);
partWrt.Flush();
partWrt.Close();
pkg.Close();
}
private string ReplacePlaceHoldersInTemplate(string toReplace, string templateBody)
{
templateBody = templateBody.Replace("#myPlaceHolder#", toReplace);
return templateBody;
}
I believe that the below line is saving the contents in the template file itself, which I don't want.
xmlMainXMLDoc.Save(partWrt);
How should I modify this code which can return the new content as downloadable word file to user?
I found the solution Here!
This code allows me to read the template file and modify it as I want and then to send response as downloadable attachment.

Create proper parameter for an Action Method during runtime?

Here is the situation.
I have an action method, which returns a file, called "GetDocument" in "Documents" controller. It has one parameter of type Document, which contains document path, title, type etc.
I have a View for an entity, which has some documents attached with it. For example, a news story, with attached documents. On this view I show various links for the documents which the end user should be able to download.
The question is: How do I create such links which pass proper "Document" object to the "GetDocument" Action Method?
Edit: I do not want to show full path of the document to the user. In fact, I would like that I store documents in App_Data folder, so that they cannot be downloaded otherwise.
Thanks!
You could use an ActionLink:
#Html.ActionLink(
"Download",
"GetDocument",
new {
path = "report.pdf",
type = "application/pdf"
}
)
and then:
public ActionResult GetDocument(Document doc)
{
var appData = Server.MapPath("~/App_Data");
var file = Path.Combine(appData, doc.Path);
file = Path.GetFullPath(file);
if (!file.StartsWith(appData))
{
// Ensure there are no cheaters trying to read files
// outside of the App_Data folder like "../web.config"
throw new HttpException(403, "Forbidden");
}
if (!File.Exists(file))
{
return HttpNotFound();
}
return File(file, doc.Type, Path.GetFileName(file));
}
why would your controller need to know about the full document when the action is called? surely your documents have ids. take the id, ask your repository for the domain object, and then get the file.

How do I get "happy" names using Amazon S3 plugin for Grails (via Jets3t)

References:
http://www.grails.org/plugin/amazon-s3
http://svn.codehaus.org/grails-plugins/grails-amazon-s3/trunk/grails-app/services/org/grails/s3/S3AssetService.groovy
http://svn.codehaus.org/grails-plugins/grails-amazon-s3/trunk/grails-app/domain/org/grails/s3/S3Asset.groovy
By "happy" names, I mean the real name of the file I'm uploading... for instance, if I'm putting a file called "foo.png" I'd expect the url to the file to be /foo.png. Currently, I'm just getting what appears to be a GUID (with no file extension) for the file name.
Any ideas?
You can set the key field on the S3Asset object to achieve what you need.
I'll update the doco page with more information on this.
With length, inputstream and fileName given from the uploaded file, you should achieve what you want with the following code :
S3Service s3Service = new RestS3Service(new AWSCredentials(accessKey, secretKey))
S3Object up = new S3Object(s3Service.getBucket("myBucketName"), fileName)
up.setAcl AccessControlList.REST_CANNED_PUBLIC_READ
up.setContentLength length
up.setContentType "image/jpeg"
up.setDataInputStream inputstream
up = s3Service.putObject(bucket, up)
I hope it helps.
Actual solution (as provided by #leebutts):
import java.io.*;
import org.grails.s3.*;
def s3AssetService;
def file = new File("foo.png"); //assuming this file exists
def asset = new S3Asset(file);
asset.mimeType = extension;
asset.key = "foo.png"
s3AssetService.put(asset);

Resources