-
-
Notifications
You must be signed in to change notification settings - Fork 178
057 Drag and Drop Upload functionality in JCB
00:00:00(Click on these time links to see Youtube video)
Those of you who have not already watch how to use the file field type to upload a file in JCB. If you haven't watched this, I would suggest that you first must come and watch this tutorial, because a lot of things that I am going to explain, I'm not going to go into depth again. Otherwise 00:00:25 it's going to take 2 hours. In this tutorial I'm going to talk about a Drag and Drop Automated Crop Functionality, which could also be used instead of this implementation(how to use the file field type to upload a file in JCB). This implementation would be much more limited. 00:00:47 You could do a crop with this(how to use the file field type to upload a file in JCB) one as well, but we haven't demonstrated that, we are going to demonstrate it in this tutorial. The library I'm going to use before I go on, let me just add a link to this video underneath the one that you watching.
The other thing you need to know about is UIKit. I suppose by now you're very familiar of UIkit. UIkit has a very nice file uploading front-end, which I have used quite often. 00:01:29 I am going to demonstrate using UIkit upload. If you know anything about JavaScript and that kind of stuff, it wouldn't be hard to plug-in Bootstraps or any other library which you want to use. JCB 00:01:47 can be scaled to be using other libraries. You can go to libraries and setup the new library and then include the files in your Admin View. At this point I'm going to use UIkit. I'm going to use the older version to UIkit in my presentation. 00:02:14 That's the one I've already got going in some of my projects. 00:02:43 Where would you like to go? You would like to go to get UIkit Version 2, to Components. You'll see there iNow s a Upload at the very bottom 00:03:00 that explains to you how to use this library.
This is the JavaScript that we will be using. It have a nice progressbar and everything. This is the HTML that we'll be using. It have a nice drag and drop and selecting area. You can give some information to the user as well as have them drop in the file right there. It works very well. I've used it for number of years. 00:03:37 It have some events. It's very similar to Version 3. If you wanted to see Version 3 option, you'd simply click on Version 3 documentation. Scroll to the bottom where it says Upload. Then Select, there is Markup for the Select. [00:04:01](https://www.youtube.com/waAnd stch?v=UvzDyVQyHDI&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h04m01s) There is the Markup for the Drag and Drop. You'd use this(see video), and then JavaScript. It's look very much the same there are a few changes. Little bit changes in the those but for the most part it's generally the same kind of approach. You would naturally be able to plug-in this if you instead want to use UIkit 3, 00:04:26 or any other library. You are going to see me making, for example, this dynamic. The URL is going to be dynamic. And whether it's going to be allowing multiple or only one. This one allowed you what type of image of file you want to permit to be uploaded. The action is where the URL is. 00:05:02 You'll see me make some of this dynamic with the script that I'm using. And of course here we are talking Ajax. You are able to upload the file without saving the item whether this area is available. You can simply use a note to add this 00:05:24 script to your page. That's what I usually do, I use a note and add this(see video). Somebody drop something here, it's going to be post to the server. If the item has an ID, I passed the ID that it gets stored in the database immediately.
Even if you save it or don't save it, the file is added to that item. If it's a new item which means no ID, we will add a hidden field to the form. We return the actual value that must go to the database, and we put it in that hidden field. When you do save the item, it does store it in the correct place. That's the approach I'm going to demonstrate to you. Step-by-step with an existing component which I've found there and which is using. It is available in JCB.
You'll see there is a new Import JCB Packages. You could either click on Import JCB Packages or you can go to Joomla Components and click on Import Components. It's really the same thing. I'm going to go back to the Dashboard and click on Import JCB packages. There has been a release fix, I think it was been in a the previous release. If you click on Import JCB Packages it didn't give you 00:06:53 this VDM Package tab. It only gave you Upload, Directory and URL. In fact it's a little broken. The best then go to Joomla Components and ensure to click on Import Components. Make sure that it gives you this VDM Packages tab. 00:07:12 This VDM Packages tab is a new extension on the Import of Components. It's the only part of the import of the components that already does validation on the package integrity. For each of these packages that are here, we do have a validation. Giving your example, Hello World is not here. If I was to select Hello World, click Get Package. It fetches it from GitHub.
It has a method of getting a hash, a checksum of the package. You can make sure that it tells you that the package PASSED checksum validation! On this point the package is on your server. You can click cancel and that will delete the package from your server. On the top of the page it tells you that the validation is passed. The actual package that we are distributing is the one you've now have. You can verify that by clicking on this link http://raw.githubusevomponent.com/vdm-oi/JCB-Packages/master/JCB_helloWorld.sha. It should open a simple text string. This text string should be the same 00:08:32 as the one you see In Data Importer. That is just a heads up and its an area which we started adding some checksum validation. It's not military grade but it's fair enough. I think anyone trying to stand in the middle of this, He's going to make quite crazy gymnastics to take care of.
The package which is being imported is displayed here, and you click Quiet, it means that you don't see all of the things it's doing. I would suggest you say No, you want to see everything. Force Local Update, means that if it finds a similar Fieldtype or Field or Admin View anything that is similar, 00:09:29 and the creation date is younger in your system, it overwrites it, because you're forced it. If it finds it and the actual current date in your system is older, the one you importing is younger it automatically update it with the latest, 00:09:52 newest version. This is how it works. That's why we telling you to make backups. The other advantages, if you get to Fieldtype that was overwritten, and it's not really what you expected, you have history, you can go back one step. I'm going to say Yes Force that and then click Continue. That simply adds 00:10:16 a whole list of what is done, what is imported, and it also moved an image, shows you that, tells you done. Hello World is now in the system.
We are going to look at something completely different. It is the Document Manager it is a paid package which we distribute. You can buy this package from us. It does have all this functionality that I'm going to demonstrate in it. I'm going to use that, and I am going to add a key and click Continue. 00:11:02 Then install this component in JCB. From there we will start demonstrating it's functionality. We have Document Manager installed. Let me quickly show you how it looks in action. I'm going to install it to this component Joomla website and demonstrate it. 00:11:32 We have Document Manager and we can create a document quite easily by clicking a new document. You'll see that there is: Allowed image formats are not set in the global settings, please notify your system administrator. You can't at this point upload anything, neither Image, neither Documents, neither any Media.
We'll go out of this and in the Options of the Component there is a Media tab, that says what type of documents you want to allow. For our purpose I'm going to say in Allow Document Format PDF for now, with the Media MP3 and with the Images jpeg. With the images in this component, I'm only having one image and I wanted to be a specific dimension, 00:12:28 I'm going to say I want the width to be 200 and the heights to be 350. It's almost like a book. A four kind of dimensions. I'm going to used that 00:12:45 to crop my image. I'm using a library which l'll show you in a moment, which gets these values to decide upon how to go ahead and crop the image if it's an image. If it's any of these it doesn't do anything. Only if it's an image it does use the crop mechanism. It does it via an Ajax. We've done that save and close. If we now 00:13:11 again click on new documents, we see this Drag and Drop area, when we looked in UIkit where we see this thing in action. It says Upload Your Image, it tells you what the dimensions should be, 00:13:35 if not the doc will be cropped to this size. That means if it's not this dimension it will be cropped to that, either large or downsize. By dropping the file or selecting a file from your computer, and formats allowed.jpeg, it tells you what formats are allowed. This is all done dynamically through this 00:13:59 Script that I'll show you in a moment. Then the same goes with the document. It tells your PDF is allowed and with the media it tells you mp3 is allowed. In the image, I'm allowing one image. Where as with the documents, I'm allowing multiple documents, and multiple media for one document. How this displays and works on the front-end? It works lovely, no problems. I'm not going to demonstrate that. That's not what this is all about. I'm going to demonstrate this functionality of uploading a file. 00:14:30 You need to use this in your own Component, you will need to extend that and use it and make it more functional as it should be in your Component.
Let's go and look at the code. We need to first focus on the document area. We'll have to look at some of its fields that is attached. Some of it is JavaScript. The Ajax area which is where everything happens. As you'll see I'm using custom code placeholders almost everywhere. Because I'm reusing a lot of the scripts everywhere under components. 00:15:15 I've therefore adapted it so that it could be used in multiple places. You'll see here I also have uploadfile, removeFile functions. It have target, type and field, filename, target, flush and type. It have values, all these values play a role within the behavior that we will eventually have 00:15:40 or been demonstrated. On a paid, I didn't demonstrate it, I just showed you how it is. I will demonstrate it still.
You will also see here I've got this setVastDevMod, which is a function that generates for us some variables. Which in this case it is called VDM. Which gets placed in a variable called VastDevMod. This formation is what is used to identify the view from which the query is made. This is a long string which really is related to the cash at that stage, of the view ID and name. 00:16:33 This is how I passed the view name and ID. So I do not really pass it via the Ajax query. I have it in session memory. Only if these keys validate it does work. Sort of another layer, and another layer. There is many layers to 00:16:54 try and make this secure. Then this adminKittwo is where I am loading all the Uikit Files. I am manually adding it to the Admin View. The admin back-end doesn't work as the Site Views where we could select a 00:17:19 library and it dynamically answer to the view on compilation. You have to manually add it to the view and you'll do it in the Custom Script of the document.
I can show you some of these Snippets and then take it further. There's in the Custom Buttons area, there is the getVDM which I have explained. Again we have some custom script. That's all that we have there. In the JavaScript area, we again have setfile which is part of the script that will have to look at. You will see I'm using setfile on different places, because we have image, documents and media. 00:18:15 They are all using the setfile method. It is a JavaScript function, and is declared in this customScript.
Individual Concepts - Notes - Main Media Uploader Note - Main Document Uploader note - Document Image Uploader note
At the bottom of the footer, we have what is known as getfile snippet which again deals with some of the automated integration of the file, when drag and drop. It immediately displays on the page, this takes care of that. We'll go and look at those individual concepts. We are also going to see, like I said previously notes. 00:18:56 There is the Main Media Uploader note and the Main Document Uploader note and the Document Image Uploader note. This is where I've added the HTML for the drag and drop that you see in the Admin View. Then we have for each of those correspondingly a hidden value for the Document Image key and 00:19:26 the Main Document key and the Main Media key. All of these are hidden fields which is where we store these values. 00:19:40 We'll look at that as well.
Let's go and see the code that is used. Let's start in the interface. Let's first look at one of these Uploading Concepts. But since I know what's happening there, I am already aware that the code is not there. It's also custom Placeholder snippet. Before we dive in, let me open the custom code area and go back into documents. We can go and look at the code snippet. 00:20:28 Let's use this Documents Uploader Note and open that. We have the Document Uploader Note, we have a div all the way down there(see video). Which has an id It has the class for the placeholder, some icons. 00:20:52 You'll see that I again have here upload your documents. I've got a span tag, that says main documents formats. It's going to be the place where we load the formats with JavaScript. Select the file from your computer. It's this snippet with a little bit of extra 00:21:29 flavor. That's all we are looking at. There are some conventions, like main documents uploader, that again upload-drop-main-documents. There are conventions which if we go over the code, eventually you'll see that those conventions is what really makes this reusable. In the scripts area I Add JavaScript to the view-footer.
The JavaScript I'm using is this uikitFileUploader custom code. Let's look at that first. We can search for it. We can open uikitFileUploader. This is the code that gets added. It have a little bit of PHP, and it is saying [arg0]_formats'. We are asking getting the global parameters of the formats we set. Remember I showed you, we set it in the global settings. We are saying document is the first parameter we are passing. 00:22:45 We are saying document formats, and we are getting the document formats. Here we have [arg2] and [arg1] progressbar. If you think about the id, it says progressbar which is the third argument that is main. Documents is the first argument because we counting from 00:23:16 zero. It's saying main documents. If you look back at our thing here it says main documents formats. This is all part of main documents. It is the way we identify the progressbar. 00:23:44 Progressbar-main-documents is an ID. There's only one of them on the page. It's targeting it here saying that's the progressbar we are going to use.
Then it have some settings. The settings is the action, we are using JRouter. JRouter is a little JavaScript trick that I wrote because often times you have this Site View or the Admin View in the back-end and in the front-end. This takes care of whether it's a back-end or front-end call, that it executes it correctly. That is your component name. The [arg1] again would be the second argument, which is in our case 00:24:52 documents. It says documents, the type. The third argument which is showing as [arg2] is main. It's passing the target as main. Raw is true, it has the token. There is our key which is being used to identify the view. It's making a query on this area. It is set dynamically.
Then over here we know that the formats must be added to this'.(<?php echo implode) area with pipe(|) between it. You remember it adds the formats with a pipe(|). We're exploding the array we have from the global parameters for documents, and it displays it in here. Again we have other. 00:25:48 This snippet, will I add under this name 'uikitFileUploader' on a GitHub gist. You could copy and paste it from there and adapted for your purpose. Again we are also imploding the formats because we want to display it, want to show the use of the formats. We have third and the second argument 00:26:16 formats, which would be documents and main. If we look at our div, we will see the formOk so tats is documents-main-formats, it's targeting this span tag, basically adding it in there. That is adding the formats html to this id.
Then if we've detected that you don't have any formats set, we are going to update the whole div, which is the upload drop area with 'allowed formats are not set in a global setting please notify system administrator'. That's the final part of our JavaScript. We have JavaScript mixed in with html taking care of some of the displays behavior on that page.
That is the reusable snippet. I'm reusing this same snippet uikitFileUploader for various areas. If we were to close out here, and I was then to open the Media Note, You'll see that it's really just using the same snippet. If you go to Script, you will see it's the same snippet. 00:27:47 I'm changing the variables I'm passing, it is saying media-media-main. Where's the other one was saying document-documents-main. The same goes with the image. The image we also have that kind of behavior. It says uikitImageUploader, this one is not using the FileUploader, it's using the ImageUploader which is a little different. 00:28:21 There is an ImageUploader and there is ImagesUploader in my custom Snippets. I'll show you why there are different. One allows one image and the file one allows more than one, this one only allows one. 00:28:45 So it has a little bit of a different flavor and behavior. I will also paste this out for you to look at. Always remember these arguments are behaving the similar way as an array. Which means that the first argument will always be 0, the second argument 1, and so forth. I'm using arguments in this snippet. Everywhere where I declare it, I am passing the three arguments that is required, use this + to pass it.
And the div looks very similar except that it now would say images. And images you will see there it's using different placeholders. You need to update those accordingly as it's needed. That's to set up the field. To set up the field you need to have that JavaScript in place and you need to have that div in place.
Regarding the hidden if I was to take one of the hidden fields, let's say the Documents Hidden field, you'll see there is some naming conventions that you need to follow. It says main-documents, it doesn't say documents. You'll see when we add the value back to the page, we're able to target it based on these naming conventions. That's quite important.
Then for some security, which is a little extra layer. Like the one guy said, that it's not that we can really stop them, we can just make it very hard. There are different encryption options. This medium encryption (local-file-key) is better than the basic. The basic stores the key in the database, which in that case means that if somebody swiped your database, they do have the key. It could happen that they are able to get hold of your database, but not all of your files. Specially those that are behind the public repository. The medium encryption option can generate a file behind the public folder, which therefore is not publicly accessible. That makes it just that little bit more difficult to get a key to open the value. 00:31:19 The reason is let's say your documents are not available to every group on your system, maybe some groups can access that document, then this is another layer of security that's already by default built into the field behavior. That is just looking at the fields.
The Admin View Documents have some Custom Script in it. We have here the setFileJS which is the JavaScript that fires when it gets the request back from the Ajax call. You'll see, let me show you if we go back on 'allcomplete' there is a function. At some point when everything is satisfied it has a setFilekey, and it passes a bunch of variables to it. It is this function that we're going to look at. 00:32:36 Let's use that setFileJS and search it. We'll see there is a setFilekey function in the document, and in your Ajax, which you're using Uikits 00:33:03 function. It has an 'allcomplete'. Even if you look at 'allcomplete' which is a place where the server has told you it's done, everything is good. You can do some house cleaning in the browser. That's what we doing. We're checking if it's done, we take away the progressbar, and if it has an error, we pop out the errors and alert. If it's successful, because we decide what this response going to be. So we will decide to give a successful 00:33:43 value in the array. Then we fire the setFilekey, which is looking at our Admin View. We are adding this custom code in here, and it is adding all this code that you see is being added. It's quite a lot of code, but it's all being added to the Admin View and it can be used for different Admin Views, 00:34:13 if it's dealing with either images, documents, or media. I'm not going to try and explain all this, it is almost as if I'm going to end up teaching you some JavaScript.
The JavaScript does some checking and validating. I'll just put it out there and when it discovers that everything is fine the file was added. Then it goes ahead, it's checking the length of the filename, see if the 'currentFileName' length is not greater than 20. If it's not an image or a document, then it must be removed. The return values are here quite key. To make sure that we have this remove file from server function in place where I showed you in the Admin 00:35:21 View where we've these remove file tasks and methods. It's querying the removeFile. It's passing all the necessary variables 00:35:42 to remove the correct file. It's also checking if a person who is trying to remove the files, is a logged in user, and on the file where we will look at in a moment, at the actual PHP. Which will again validate that the user has permission to remove the file. There are all these checks and balances across every step of the this implementation. By now you might realize this implementation is far more complicated than the normal file upload, that's simple. This really gets into the nitty gritty of some of these things, because you want to give a real easy 00:36:32 behavior for your user. But that will mean that you need to do more them and protect them. So they would not become vulnerable at any time. Once we are satisfied that the file is correct and it doesn't need to be removed, we trigger 00:36:55 a few things which puts the file in the page that we want to end up doing.
This 'setFile' is what we are moving towards, because we want to make sure that the file, after you've dragged and dropped it on the page, boom, it shows in the page once it's on the server. It's doing a little bit of checking to make sure their are all good, everything's fine. We end up with what we now called 'filename', and it get passed. 00:37:36 We are moving into 'setFile', and the 'setFile' is going to take the target and it's going to determine what kind of target it is and get the format, get the this, get the that. We can build the 'filename' correctly. I've got some functions which you may not need, 00:38:02 I mean you can look through this and decide what to keep, what to through out. We end up building a notice which has been set. 00:38:20 It triggers the 'getFile'. The 'getFile' is the other function which if you look at the Admin View, let's go back to the JavaScript. We've the 'setFile' 00:38:38 and we have the 'getFile'. The 'getFile' is getting another layer of validation and also make sure that everything is behaving as we would want and expect it to behave. The rest of the snippet is a 'removefile', and 'isJsonString'. We also have a little snippet to check if it's a JsonString 00:39:05 and if it's empty. It's all part of sanitizing and validating and making sure everything is the way we expect.
We want to look at the getFileJS which has different implementation and as you can see it is in the view footer. We have PHP in that area of the JavaScript. This is the getFile. In the getFile we have again a link that was echoed. 00:39:44 We are going to use to load the file, to make it that it can be downloaded. That's the issue. If it's a document or if it's a media, we don't want to display it but we want to have you to be able to download it. We have different behaviors for image and images, as well as for 00:40:04 documents and for media. It has different behaviors. It continues building buttons and displays. I'll pop this code also out on the Gits, and you can look at it, and see if you can make sense out of it. The DOCLINK or the DOCBUTTON is 00:40:26 the potential idea about this if we go to the Document Manager. In the Document Manager, when you create a document, you will have what we call description. If you add a document you can use those placeholders in the description. It's the beginning of 00:40:58 using these documents across the website, and not just in the component. We'll eventually write a little plugin, and if you use this placeholder which it generates. If you use that anywhere the plugin will identify it, 00:41:17 and will load either a link or a button depending on which one you're using, the button or the link. That's what it's doing. You might say I don't need placeholders and you can grab that part and take it out also then wherever the 'var placeholder' 00:41:36 is being used and need to be removed for example over there. We have a 'fileBox' that we are building. It's getting the placeholders, the download and the delete buttons, all of them get loaded into the 'fileBox'. 00:41:53 If we are having more than one file, we are treating it differently than just having one file. That is what we are doing here, the document has a little different behavior but somewhat the same. That is what the final stretch is, it is like a relay race, one carries it this far and then the other one takes it over, 00:42:17 carries it a little further. This one is at the very last end of the match. Where it is finally putting the image back into the page, and all of the nice little thrills, bells and whistles happens here. This is where you can spice it up with some JavaScript. 00:42:37 You can see I'm using Uikit to deal with most of the styling. Now you've seen the front-end as we would call it of the behavior of our Drag an Drop. 00:42:53 You've seen how I set up the field. You've seen when the Ajax has finished it's request. It runs this setFilekey. The setFilekey triggers a whole bunch of things which ends up adding the file to the page.
Let me demonstrate in our little new document some of these function which I now explained, and do exactly what it does. I've got a bunch of images, it is generic open source kind of images. I'm just going to grab one and dump it in Upload your image. You didn't see that, let me scroll down get that image, put it down a little lower, let me get another one. Let's use this house. 00:43:50 I'm going to drag it there and highlights it for a moment. It has this little Uploader because we are on local network. It's very fast. When it started it says 'Your doc images is set'. That was built by JavaScript. There is the document 00:44:10 image on display. There is 'Remove document image'. I can click that and it'll tell me are you sure you wanted to leave this document? Yes, and boom it gone. We back at Square One as if we had nothing. It doesn't only delete it from the page, it removed it from the server as well. Let's drag another one, just 00:44:33 drag it there and drops it on Uploads. There is our nicely cropped image. It crops in the center of the image, because how does it know the house is on the side. It not doing that kind of smart detection yet. We are cropping the image in the most sensible way.
With the uploading of a document, it is more or less the same. Let me just get a document. We have a document, and you can Drag and Drop it in there. Again it uploads it, and with the upload it generates those links I told you, you could 00:45:10 copy. Put it in the description if you want. You could test it. What is noteworthy here? Is that the name of the document doesn't get lost, while 00:45:25 the place where the documents are added, is in the same folder. You could add multiple documents to this document. I'll just keep on stacking them though they even have the same name. Each one will be uniquely tagged to not be the same as the other. Which means that on the server we are storing this document with a 00:45:53 long hash, sort of added onto the name. Which is an extra layer of security, that people if they could access the folder, they will at least know what the name is. Same with the image, if we were to inspect the image, you'll see 00:46:12 that the image have this huge name: /doc_image_jpegxxxxxxxxxxxxxxxxxxxxxxxxxisland jpeg. So it's no longer than same name as the one you uploaded. It changes it and preserve the name for example in the documents option. That you giving to someone the document they have, what you expect. We do 00:46:38 adapt the names for security, that you can't be allocated on the server if for some reason it is not a good document. You could test it by clicking here. And it should then bring it up in and be available as a download.
How the download works here with the document, I'm using a controller. If we hovered over this link, you will see, you can't see that. I'll just show you. I have copy the link, it's a little huge because we are using 00:47:25 an encrypted path to the file. It could sometimes being encrypted or sometimes just be basic64 encrypted. But the point is we have what we see here as a task and download document. There is a controller called download. In my component, I will show you how this download document 00:47:54 concept works, but you'll need to write that. You need to figure that one out. That's unto you, that's if you want people to download your documents. If it's just to upload images of course 00:48:09 you don't need any of this. But it is only when you are going to have a downloadable file or media.
Next one we wanted to show you here, is to upload some media file. I have a bunch of audio files, and I'm going to upload them. What I'm going to do is, I'm going to select a whole bunch of them, and then upload them all at once. This is what the Uploader can do. Let me see, there we go drop it there, I can't see it yet, but it's uploading. I need to refresh the page. Let's give it a name. 00:49:01 The Document. In Description say: More Soon. Save this. It didn't upload all of them. Interesting. 00:49:24 Let me try again. I've got 6 of them uploaded. I can see there are 6 documents and you can download them and test them. See if they are still fine. Why the home? The order of the home. We see that the media is working. Let's also do that with documents. Let's add some more documents. 00:49:57 I've got a few selected and drag and drop them there. 123 and is uploaded. I need to check some of the JavaScript. I see it didn't add the download button. Without saving, if we refresh the page, you'll see that it has all those documents there. Because it used Ajax to store them in the database. At the end of day that is the behavior we wanted here in our component. We wanted the option to upload multiple 00:50:31 documents to one document, and multiple media files. To be able to test them in the back-end, if you wanted to test any of them. Even be able to remove any of them at any time, just click on remove and it will be removed. In the front we'll be able to use the file names, and the user would be able to identify this is what I want. 00:50:59 The filenames get preserved while it is being stored in the server with this hash behind it. We are seeing the JavaScript we looked at earlier in action, it is uploading, it is deleting. This one is cropping which we will look at it a little more. That is seeing our drag and drop options in action.
Now let's go look at the server side of this implementation. The server side we have in the documents Admin View. We're opening the PHP tab, have this Ajax area. Like I showed before you would need to set up the Ajax in this area, targets the controller. In the controller it creates all these necessary script 00:51:54 to make this method. We are going to look at the inside of that custom code. Make this method available to the Ajax call. There are some values that we set because every component I used, this stuff is different. For some we're using images, documents and media as the types. For some 00:52:23 target the main and doc. The allowedView, there's only one view in this component that is allowed to use in the Uploader and that is the document view. The getViewID is the function which I get the actual view name and ID. It is using the session to throw that around to insure that nobody is able to tamper with that value through the front. Little extra little gymnastics to add another layer there.
We are going to look at this phpAjaxUploader in the custom codes area. Let's Search for it in the custom code area. Why am I using custom code? Because I'm reusing this. At the moment it doesn't look like I'm reusing it many places, it only says it's used in component. This is not the area where I'm doing my work, this is just for tutorials. I'm using a whole different developing environment 00:53:33 or rather a developing system Joomla website than this one. This one is explaining and demonstrating. I'm reusing this code in many components and we have image formats that are allowed in the system. Document formats that are allowed in the system. 00:53:57 Media formats that are allowed in the system. You can adapt this to whatever you need. At the end of the day it is up to you to decide what you want to allow and what you wouldn't. The reality is this is the available formats. If you remember in the options area of our component, it has a media area and there we have allowed documents, allowed media formats, and allowed image formats. These should be the same. It should be the same list, having the same values. But these are a field we created in Joomla, a List field. We manually added this to the components configuration area.
If you don't know what that is, let me quickly show you. In the component it has this component config. If your component doesn't show one like this, Hello World, it doesn't show a component config, you can go into the component and then in 00:55:16 settings there is this button create component config for this Joomla component. I'm going to close out, I don't want to do Hello World, I can show you with the Document Manager. We could use the same button in settings. We can edit if it hasn't have one, you can create one. You select fields 00:55:50 with their custom values and the tabs in which they should be display. As you can see I've selected Allowed Document Formats(list), which is just a list of the formats and I set it to allow multiple selection. That's how I'm doing this Allowed Media, Allowed Image, and Allowed Documents. Then here's the crop document image. If you do not know how to create a field, and how to set radio buttons, or list, then go review the videos about that. I'm not going to explain that now. That's how we deal with that and that list we have looked at now 00:56:29 is the same list as what we see here. It should be the same. Because this is the allowed, and that list shows the user what is allowed for the system. 00:57:03 This is what you could say as available formats, and then those drop downs is what you as the owner of this website, where this application will run, is what you will allow. This list should be the same as the one there, but it also is going to be use if people post a specific type, 00:57:38 as if it is allowed. We're going to be able to bounce this and make sure that security wise we are safe.
Here is the 'uploadFile'function. The 'uploadFile' starts by first getting the view ID, checking it. Then making sure that there is a view set. And that view is part of the 'allowedViews' array. The 'allowedViews' array, if you remember 00:58:08 the 'allowedView' is documents. That's why I'm saying I'm setting that outside of the custom code, because it depends on which component we are working in. If it is an 'allowedView', we then get the target, and the type and we set it to Global target in Global target type. 00:58:45 Then we check that this type, What is the format that we are talking about? That is the formats that we allow, the types, because we want to 00:59:17 validate that the person and who is uploading the things, we anticipate. It is setting the format with the type. If it's image it will be images. If it's images it will be image. If it's document it will be document, if it's documents it'll be document, and media will be media. That's the types and we are setting that is the formatType.
Then we are using a function getPackage from upload. now if you watch the previous tutorial of using the file type uploader, Then it's more or less the same kind of functio. If I scroll down, 01:00:02 We'll find 'getPackageFromUpload. The only differences we are doing the application at get and the input in the function. We are targeting files because we are passing those values in the files place. We are seeing what is the file. We are checking whether these things are allowed: warning, import file error. This kind of error, you'll see I'm not throwing it to Joomla, I'm adding it to the error message. 01:00:35 Because we are grab the value and say we are done here get out of here, if we are still going and you could go through this. the same implementation than the one we've demonstrated. The only difference though is our check method. It is a little bit more taking that view 01:01:12 and validating it. We are doing a 2nd layer of validation. Then checking whether this specific user that is now logged in has the right to edit this item. It is doing some user validation. If not, it removes the archive. We can have that remove method with a little bit of the code that you saw me take out, that is still left in. In the previous tutorial I use some of these codes. That's all the same I'm not going to go into depth. If you don't understand what I've just looked at here then please go back to the 01:01:56 the previous tutorial, watch that. It gives you enough information. In our upload file we at this point have the package. We pass the package to uploadNow. Now move the file into place. Remember we had to do that in the the previous here. I'm using a function uploadNow. In the uploadNow function, we are returning and if any error still remains, it's going to be doubt here. Where as errors that might have a occurred here, if this was false, we would use that. 01:02:36 That's the error message put it in error and pass it out. If we having any other issues, we will seen there has been an error and will pass it out, there is this error handling there.
Now in uploadPackage, we are checking whether the package is there, the package name and we're starting from that, we are building the name. Now remember I showed you or explain to you that we are using and preserving the filename but we are hiding the filename. We are using the targetType the fileFormat and then this randomkey generator. 01:03:17 Now I'm not exactly sure I think all JCB helper classes comes out with this randomkey. You could just use it in your component and you can decide how long this string should be. Then I'm using a little placeholder which is little generic placeholder VDM. I'm adding the actual name of the file after this placeholder that everything before this placeholder is really internal, my system uses this, but the client uses everything this side. If it's a document 01:03:56 we are going to need the folderpath for hiddenFilePath. Again getFolderPath is a function which I wrote. I'm not going to share that with you, but you can build your own helper class function to get the path to where you want to put the file, this is up to you. I'm using a hiddenfilepath, but there is a lot of discussion behind that. If I don't pass any values like in this case, 01:04:28 it most probably return a public path. It would be where the images go. Every documents go in a hidden area, images go public. Usually the image you wanted to load somewhere, you don't want it to be behind the root folder of your website.
We end up here with the fullPath which is the filePath and the fileName and the fileFormat. That becomes the fileName and this becomes the fileFormat. You will notice that at this stage the packagename is what it's used to build this name. We are stripping the fileFormat from that packagename making sure 01:05:19 that it doesn't have a fileFormat in it. To ensure that this file is stored in exactly the format, we detected as and not as what I said it is. We move the package. This is where it gets interesting to its final destination. If something fails at this point like it doesn't move, 01:05:45 we remove the package and we say there was an error. We are done. We are not going to worry about it. If it succeeds then if it's an image, at this stage image, we definitely want to resize it. I've a resize image helper Class. This is also something that you would need to write yourself. 01:06:12 It helps me to resize my image. I am passing it some values to target the image and resize it. It doesn't change anything with the image location or anything like that, I don't need any value back, I just need it to resize it and get it done. I don't need to know anything else.
I'm doing some encryption to see whether the basic encryption is available in this program. To use that encryption, when I start storing the documents to the database. Here is a local file, and we are checking if it's a document or a media. We are going to encrypt it. Again here we make sure that this ID value 01:07:04 is greater than zero. Because if it's still a unsaved item, we don't have any place in the database to add this. We could skip this. If we realize this file or this Upload doesn't have an ID, then we skip this function, and we rather do an image. If it's a document or if it's a media, 01:07:29 then we load the filename. We are going to pass it back to the view, taking the results as you see here formats, it's got a 'lock' value and a 'token' and 01:07:46 'link'. It has different behavior for different things. It all builds this result array and this is what we give them back. It gets started over here(see video). The fileformat is added, success, gets the filename which is this value here. Then we start building some other things which are necessary. 01:08:10 Like the 'tokenLink' for the 'link'. Because you want to have it downloadable, if it is media or document. If it's an image, we don't need any of this. We can skip that. Then the 'keyName'. We are done. Where as it is a safe item, we are going to update the database, 01:08:35 with this new 'targetType' and 'target'.
This is where the hidden field name, remember I said to you there's some convention in the hidden field name. Well this is where that convention comes into to play. The hidden field name is build up from 'target' and 'targetType'. If these two are not correct we are not going to save this value at all. We are building an object which we will take, since we have validated that this is definitely the allowed view, and this object and ID, then we update the database. We're done. 01:09:13 We've the 'fileName' and we are going to pass the 'fileName' here in the same way, and return to the browser. That's the service side of this implementation. There are some things which I haven't explained. Like 01:09:33 this resizing of the image. I didn't give much explanation. 'GetFolderPath' you don't need to write that all up. You could make this work without knowing those things. 01:09:48 You could put a hardcoded path here as the filePath. You will not have to do any cropping, let the user make sure about the cropping. 01:10:01 That is how I upload many of my documents and things. This is constantly improving, because I'm using the snippet across multiple places. It's very easy for me to come in here and say oh this is not 01:10:17 ideal and then fix it. Then I it fix it everywhere for every place it's been used. There is sometimes the need of decoupling some of these functions in some, but I'm trying to do as much as I can to not to that.
'setFileNameArray' is another function that you saw in the upload where is it 'setFileNameArray'. This 'setFileNameArray' is a key, when you realize that the actual file already exists because the ID is there. That means that there are other files possibly still already in the database. ???? So with The add and basic view we actually trigger the set filename array Function To check the database 01:11:16 For that specific Target Field get the values I decrypt them and Load new values to that And then basically Pass it back to us. Where if the item doesn't exist That means it doesn't have an ID I don't know if you remember when we 01:11:35 Did some demonstration I was Actually adding multiple Media files that only one ended up Being remembered And that sort of the downside Of the current Implementation Is that if the ID doesn't Exist We're not able to actually keep track of that 01:11:55 So it's only when the ID exist That we are able to Actually do multiple uploads at Once So I should actually Give a little bit heads up of the about that That you want to save the item You're actually ready to To expand upon it And to allow 01:12:13 Multiple upload at Once So the set filename array is Is really dealing with multiple when you are having multiple so you'll see there is image And document Is when the file I'm using the The plural to tell me That it should allow multiple 01:12:32 So if it's singular Image And document then I don't allow multiple I'm just gonna remove the old one And add the new Done And when it is plural And we are using the set filename array And we basically building It to 01:12:50 actually be Multiple And then One thing I didn't Emphasize here Is That we actually remove the files as well There is a remove file right 01:13:06 There's remove file And it also at some point does a validation To check whether the user has the Permission to remove files And And then will basically remove the file So that is Also and it's Also uses 01:13:23 Is this file name But then it passes the remove Variable to it Which then means the action is not to add but to take Away and You will see that there The action here There is the Add and there is the take away option So behave still different 01:13:41 So we still basically get back the array we still build an object and we still updated Database As well as Actually removing the file here Ok so all of this code I will dump on GitHub and the gits For you to reuse as you see fit you'll obviously have to Adapt it And Keep it under an open source licence That's Only requirement Ok well 01:14:14 That if all those things line-up and are in place Going back to our Admin View Basically That needs to be there These things Need to be here so you could Pause the film And Video 01:14:31 And just make sure that you have the same kind of Ajax Query calls option And then here I am actually Doing some opening of the files You see that I'm building but I'm called links So this is going a little Beyond Just showing you a little bit of my implementation and these links Eventually End up on the page 01:14:57 So we've go back to Our JavaScript Here Scroll down We see this get filed JS Now let's Again look at that get file JS Because You'll see that those links 01:15:13 Actually come in To play there If I Remember correctly let see here Oh I see now is not in that JavaScript Is actually down here You see that here I got a Load the links to the page document links And I'm actually adding it to a variable called document links you see 01:15:37 So in the Custom script Where is it it's not this one It's this one you'll see if I If I now search So I'll take this copy and here I'll search You'll see that I'm actually using that array And saying is this property there 01:16:03 And then creating a link And so that is how we deal with some of that And it it works very well To sort of pass value from JavaScript to PHP And have it available there Ok well I know this was a lot of 01:16:22 Things to sort of take in and I would expect you to realize that that previous implementation is So much easier But like you've seen When someone actually does create a document And they Are able to so easily Just drag and Drop stuff And it just crops and It just gives your component so much an easier you know for you feel to it 01:16:52 Instead of The olds you could still do the old select But the Drag and Drop is Becoming quite popular And this implementation is Really Very Very Yeah it's very nice to have And I'm sure from what I've shown you you should be able to get this going in your component 01:17:14 I'm not really gonna give support on to this meaning that If you get stuck you on your own Because if It is really the truth that you will need to know your JavaScript you'll need to know Your PHP and you will need to know how to debug And how to line-up these Concepts That they all 01:17:36 I work in Synergy together It's not gonna be So easy for me to Do that Specially since I usually do not see the code But if there isn't any of the code that I've share on Gits Which I will also put in the description below this video Even have that code has issues in it 01:17:57 Or errors in it that the That are like ok a very big problem or something Then please do feel free to Give me a heads up over there And we'll collaborate Improve it as Necessary At the end of the day This feature is really way behind What 01:18:19 What you really need There is a media manager in In Joomla Which is actually ideal The advantage about this way is that your user is Is never gonna interfere with other users documents or images or Stuff So if you use this concept they not ever gonna actually look on your server at a list And select stuff This is why I think people would like this 01:18:43 Because they can upload stuff in It doesn't affect other people it doesn't make you more vulnerable as the owner of the system Who uses the application So it is I think we better approach But like I said there is a media manager So if you go to content There is a media manager And there is a media file type Which 01:19:07 Works very well And And can also add These kind of functionality to your component If this is a little bit too challenge To a big of a challenge for you Anyway thanks for watching I know this might again be so such a long Tutorial But I'm trying my very best 01:19:26 To sort of get you on your feet and you to go.OK.
- Home
- Beta Testing
- Custom Code
- PHP Settings
- Demo Component
-
Tutorials
- Hello World JCB
- Intro JCB Guide
- JCB Installation Steps
- Planning Components
- Field Type Overview
- Basic Fields Creation
- Admin View Management
- Advanced Field Usage
- Admin Component Integration
- Component Setting Customization
- Scripting Components
- Component FTP Options
- Dynamic Get Method
- Site View DynamicGet
- Site View Templates
- Template Setup Guide
- Layout Configuration Steps
- Custom Admin Management
- Adding Site Views
- Custom Admin Integration
- MySQL Demo Tweaking
- Global JCB Settings
- Custom Time Field
- User Helper Integration
- Email Helper Usage
- Message Store Email
- List View Unescape
- Export Import Customization
- Overwrite Custom Fields
- List Field Filtering
- Automatic Code Import
- Manual Code Implementation
- Component Export Import
- Custom Admin Buttons
- Translation Management
- Site View Permissions
- Component SQL Updates
- Site Edit Configuration
- JCB Backup System
- Helper Structure Integration
- JCB v2.5 Upgrade
- Tab Setup Guide
- JCB v2.6 Release
- Extended HelloWorld
- Field Rule Validation
- Community Snippets Intro
- Snippet Forking Tutorial
- Pull Request Snippets
- Library Manager Area
- Excel-based Translation
- Dynamic Router Details
- Database Auto Updates
- Subform Quick Demo
- VDM Package Import
- Dynamic File Inclusion
- File Field Upload
- Drag-n-Drop Upload
- Quick HelloWorld JCB
- Non-database Fields
- Dashboard Customization
- Menu Prefix Toggle
- Community JCB Packages
- Collaborative JCB Workflow
- JCB Package Install
- JCB JAB18 Event
- Convenient New Fields
- Component Language Strings
- Library Functionality Anticipation
- Join Field Relations
- License Template Change
- Code Reusability
- Local Dev Environment
- Extended Field Types
- Joomla Custom Fields
- Custom Field Expansion
- Site View Listing
- Run Expansion Method
- Form Site View
- Field URL Update
- Additional Helper Methods
- Field Validation Rules
- New Placeholder Feature
- Component Config Params
- Per-field Default Values