Upload an Existing File with PDF Core
The first way to upload a PDF file to the server is to directly upload a PDF from your computer to the server. It is important that the files uploaded in this way are only pdf files, so that PDF Core can properly handle the files. Taking an existing file on your computer and uploading it is fairly simple to do.
Server
While PDF Core handles the behind the scenes work for how to upload a file, using the uploadPdf
function, this is unable to be called directly from the client of the app. Additionally, when using PDF Core, you must call the upload function directly from the client, so there are a few things which need to be done to setup the serverside function to be able to be called.
PdfUtils Controller
The easiest way to make the upload action work is to create a PdfUtils Controller, which allows you to make the uploadPdf
action in the Router, so it can be called by the client.
The setup for this controller, should use the PdfUtils from PDF Core, with the following line:
use PdfCore\PdfUtils;
Then all you need to do is call the PdfUtils::uploadPdf($fileName)
function so that you are able to upload the PDF. It is important that the PDF that you are uploading is uploaded to the server $_FILES['pdf']
(this is done on the client side, and will be described below) because if it is not found, the uploadPdf will error, but all that you pass in as an attribute will be the new filename:
fileName
- This is a required string attribute that is the file name that the uploaded Pdf will be saved under in yourpdfDirectory
. Note: you will need to make this both at the same time unique and predictable, so that later if you need to download, preview, or clear the file, you will be able to generate the same name again.
So basically the uploadPdf
function in your Apps PdfUtils
is simply a wrapper of PdfUtils::uploadPdf($fileName)
, which also determines the name under which the pdf will be saved. For a real life example, see what JobPdfUtils::uploadPdf
did:
public function uploadPdf($object, $options) {
$this->auth(['admin', 'global-admin']);
$dept = $this->user->get('currentDept');
$jobDeptId = $object['dept'];
$name = "$dept\\$jobDeptId-supplementary-application.pdf";
PDFUtils::uploadPdf($name);
}
This basically uploads an "additional" application for each Job App department (think "branch") within a broader GC department. But each job department can only have one, so the name of the file is in a folder named after the id of the GC department, and then part of the name of the pdf is the id for the job department. This makes it very easy to be able to retrieve the proper pdf when it is needed because you know which GC department and which job department need the supplementary application in order to download/preview it (if there were multiple supplementary applications per job department, we would need to come up with a different way to save this pdf).
Router
Make sure to set up your Router.php
file as you would to allow you to directly call a POST request. For example:
$this->generateRouteGroup('jobPdfUtils', [
['/uploadPdf/', 'uploadPdf', 'POST'],
...
], false);
Client
Now that you have the back end set up, you can deal with the actual file upload, which is also fairly simple.
Template
Because PDF Core cannot handle multiple batch uploads at a time, it is best to use the FwFileUpload, which was created for single file uploads. The link given goes into deeper details about all the options, but the general use is usually sufficient for our purposes:
<FwFileUpload
@accept='.pdf'
@update={{action "uploadPdf"}}
/>
Of course, it is important to say that you accept "pdf" files and also have the update function. Often, if there is already an uploaded file, they will also use the noFileText
attribute to display text such as "File Uploaded."
Controller
The main part of getting the upload to function is actually in the clientside controller. Other than what is already done for you by the fw-file-upload
component, the controller formats the code in such a way that the server is able to retrieve the file. The fw-file-upload
update attribute passes the file that is selected as the first parameter of the action it calls, so this is an example of the things you need to do in order to properly set up, from Job App:
uploadPdf(input) {
let url = this.get('config').formUrl('jobPdfUtils', 'uploadPdf');
let formData = new FormData();
formData.append('pdf', input);
formData.append('dept', this.get('selectedDepartment.id'));
this.get('ajax').post(url, {
data: formData,
processData: false,
contentType: false
}).catch((error) => {
this.get('notifications').showError(createErrorMessage(error), 'fixed', true);
throw error;
}).then(() => {
this.set('selectedDepartment.hasPdf', true);
});
},
A couple of notes about this function, to explain how it can be duplicated for yourself:
- Note that this function uses the typical ajax method for direct calling a function to the server, which is not part of BREAD. For more information, see documentation about the ajax service and the config service. Error catching as well is fairly common, but is explained here. This should not be too new for you.
- Using the native
FormData
object allows you to upload the pdf to the$_FILES
server variable. For more information about the Form Data object, click here. It is very important that you use the name 'pdf' for this, otherwise theuploadPdf
from PdfCore will not work. - Any other information you want to be available in the
$object
variable in youruploadPdf
function can be appended to theformData
as well (notice that theselectedDepartment.id
is sent over and used in the serverside function above in creating the name to save the PDF)