Updated 056 How to use the file field type to upload a file in JCB (markdown)

Amigo 2019-09-10 16:12:05 +02:00
parent 5ae7cc4a28
commit df38e46186

@ -49,7 +49,7 @@ As you can see when I saved the item, it did not upload anything. The file is no
Then having the image selected, then go to the code. I know where the code is for this website.
I am going into my editor and to the Admin area of this component and of this view, this model, into where it saves the values. (Follow on video). Here is 'Joomla Mount', 'administrator', 'components', 'com_demo', and then models, and 'look.php'. Double click. Go to almost the bottom of the file. [00:12:13](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h12m13s) Look for the `save function`. That is where we want to sort of poke. It is at this point where all the data from the browser is available to us and be able to access it. You could write the Helper class and put it into your Helper function, and use the same uploading class if you want to reuse it. You could also script it right in here. I like reusing scripts so the Helper class idea is more appealing because I put it there and everywhere I use this Fieldtype for file uploading, I just also use this helper class to deal with moving the data and using it.
### Var_dump Some Values - One Is The Data That Is available, Second One Is Getting The Input
### Var_dump Some Values - One Is The available Data, Second One Is Getting The Input
[00:13:07](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h13m07s)
@ -79,24 +79,24 @@ And now we can take the next step to check this array exists. There is a functio
[00:16:58](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h16m58s)
Let's copy the function and adapt it to our needs and just put it into our class. In components go to the `installer`, then, `model`, and then on `install`, and scroll down till you see one that says '`getPackageFromUpload`'. [00:17:29](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h17m29s) This is the function which is really ideal for the task. It takes care of a lot of sanitizing, it has a lot of error checks in it, and it should be useful for us in this case. We will take some stuff away and add our own short messages, so we do not have to depend on the `INSTALLER MSG`. Just copy this whole function(see video). So there are some key things I would like to change, for example, [00:18:23](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h18m23s) change the function name and call it '`myUploadFunction`' for now. We pass to it the input and do not want that to be done twice. [00:18:50](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h18m50s) We know this is going to be '`jform`', and we definitely do not want to have it '`raw`', because it is an image. We want this to be an '`array`' that we can check the values. [00:19:19](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h19m19s) We can say here set '`uploads are not enabled in php`'. We can take these messages and put them in here, because JCB is going to grab this once we put it into our component, and going to add it to our language files for our component, this is to make sure that it happens. We do not need the `zlib` because nothing is going to be unzipped. This part can be removed.(see video).
Let's copy the function and adapt it to our needs and just put it into our class. In components go to the `installer`, then, `model`, and then on `install`, and scroll down till you see one that says '`getPackageFromUpload`'. [00:17:29](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h17m29s) This is the function which is really ideal for the task. It takes care of a lot of sanitizing, it has a lot of error checks in it, and it should be useful for us in this case. We will take some stuff away and add our own short messages, so we do not have to depend on the `INSTALLER MSG`. Just copy this whole function(see video). So there are some key things I would like to change, for example, [00:18:23](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h18m23s) change the function name and call it '`myUploadFunction`' for now. We pass to it the input and do not want that to be done twice. [00:18:50](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h18m50s) We know this is going to be '`jform`', and we definitely do not want to have it '`raw`', because it is an image. We want this to be an '`array`' that we can check the values. [00:19:19](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h19m19s) We can say here set '`uploads are not enabled in php`'. We can take these messages and put them in here, because JCB is going to grab this once we put it into our component, and going to add it to our language files for our component, this is to make sure that it happens. We do not need the `zlib` because nothing is going to be unzipped. This part can be removed. (see video).
### Checking If Userfile Is An Array
[00:19:58](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h19m58s)
It is going to check if we got a set of files here. It is going to check if that `($userfile)` is an `!is_array`. If it is not, it want to say no file was selected or no file was uploaded. We can just type that in. If at this point we detect any errors, we want to erase those errors and break out of this upload. So let's see `UPLOADERROR`, `WARNINGUPLOADERROR`. I suppose we need to go look at these language strings in the language file of the installer to correctly translate these but I am not going to do that but just going to say `error`.
It is going to check if we got a set of files here. It is going to check if that `($userfile)` is an `!is_array`. If it is not, it wants to say no file was selected or no file was uploaded. We can just type that in. If at this point we detect any errors, we want to erase those errors and break out of this upload. So let's see `UPLOADERROR`, `WARNINGUPLOADERROR`. I suppose we need to go look at these language strings in the language file of the installer to correctly translate these but I am not going to do that but just going to say `error`.
### Checking The Upload Size
[00:21:02](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h21m02s)
What needs to be checked here, is the upload size. We want to make sure that our upload size is what we expected. `Is the maximum upload size too small in the php.ini`, and that is really what is happening here. Again it will give an error saying '`file too large`'. The same here, it is checking again, this time it first checked whether it is in the INI files. Here it checks the file size and that there is a file size. We can again say [00:21:57](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h21m57s) '`Upload error`' and you should just check what is the actual file language string and replace that with the English version.
What needs to be checked here, is the upload size. We want to make sure that our upload size is what we expected. `Is the maximum upload size too small in the php.ini`, and that is really what is happening here. Again it will give an error saying '`file too large`'. The same here, it is checking again, this time it first checked whether it is in the INI files. Here it checks the file size and that there is file size. We can again say [00:21:57](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h21m57s) '`Upload error`' and you should just check what is the actual file language string and replace that with the English version.
### Build An Appropriate Path, Create The Path, Create Temporal Source - Move File With Jfile Upload
[00:22:08](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h22m08s)
We `//Build appropriate paths` . We take the filename, create the path and create this `$tmp_src` which is the source path and then we move the file with the `JFile::upload`. Now at this point, the file is being uploaded to the server. [00:22:34](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h22m34s) There is still validation to do in our script that we just grabbed from the uploader class, we do this unpack. We do not need to unpack, we want to do some other things here which are more appropriate for our purpose.
We `//Build appropriate paths`. We take the filename, create the path and create this `$tmp_src` which is the source path and then we move the file with the `JFile::upload`. Now at this point, the file is being uploaded to the server. [00:22:34](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h22m34s) There is still validation to do in our script that we just grabbed from the uploader class, we do this unpack. We do not need to unpack, we want to do some other things here which are more appropriate for our purpose.
### 'Unpack the downloaded package file' Replaced By A Little Function 'checkUpload'
@ -108,30 +108,31 @@ First thing, is to move the get classes function up a few lines, and also make s
[00:23:41](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h23m41s)
Do a little check-up to make sure that the package which we are going to give back and which will be used to store in a database and all the rest is okay. Grab the result of this which is going to be true or false and check if it is false, and can say '`Upload failed`'. Then do this check. Now we have this '`checkUpload`' in place and are first going to get the format from the file. <<<<<<<<<<
Do a little check-up to make sure that the package which we are going to give back and which will be used to store in a database and all the rest is okay. Grab the result of this which is going to be true or false and check if it is false, and can say '`Upload failed`'. Then do this check. Now we have this '`checkUpload`' in place and are first going to get the format from the file.
### Use Custom Script To Validate Our Format
[00:24:32](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h24m32s)
We are going to use a little custom script here to validate our format. In my component I usually set formats that I allow. So it's a Global thing. That means in your component you would have to go and add in config drop down, with a list of Allowed Formats. To sort of sidestep that, [00:25:07](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h25m07s) instead of trying to explain all that, I'm just going to go and remove this function here(see video). You could pause this video and copy that down if you know what I'm talking about, but then in that case you don't need to pause, you know how to type it. I'm going to remove that and just add some format which I'm ok with this '.jpg'. [00:25:30](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h25m30s) I'm ok with that format and I'm also going to be ok with '.jpeg', and '.png', and then '.gif'. So those are the formats that I'm [00:25:56](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h25m56s) going to say those are fine, of course because it's really the file extension that we are checking here. We are not going to use a global value here, we are just going to use the fileFormat, allowedFormats, and then here we would going to check, is this fileFormat in allowedFormat array. If it's not, we are going to say 'Invalid file format' [00:26:27](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h26m27s) There we go and it is going to error out, but with this error out we will need to do some house cleaning. We will have to look at that at the moment.
We are going to use a little custom script here to validate our format. In my component I usually set formats that I allow. So it is a Global thing. That means in your component you would have to go and add in config drop down, with a list of Allowed Formats. To sort of sidestep that, instead of trying to explain all that, I am just going to go and remove this function here(see video). [00:25:07](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h25m07s) I am going to remove that and just add some formats that I am okay with, '`.jpg`', '`.jpeg`', and '`.png`', and then '`.gif`'. [00:25:30](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h25m30s) Those are fine, of course, because it is the file extension that we are checking here. A global value is not going to be used here, we are just going to use the `fileFormat`, `allowedFormats`, and then check, if this is a `fileFormat` in `allowedFormat array`. If it is not, then say '`Invalid file format`' [00:26:27](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h26m27s) There we go and it is going to error out, but with this error out some house cleaning is necessary.
### Passes The Destination Where We Moved The File
[00:26:40](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h26m40s)
So what I think I'll do is I'm going there also passes the destination of where we've moved the file. Then because that's where the file currently is. Here we got the temporal destination which is in the temporal path, the temporal folder of the Joomla website. It's not where we want to end up. [00:27:02](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h27m02s) It's just where we are going to keep the file until we happy that it's safe. We got it in the temporal destination, we moved it up there, and now we checked if something happened. Do check the upload. Here if we find that this 'archivename' file [00:27:26](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h27m26s) is problematic, we are going to have to remove it. We are going to have a new little class here. We are going to say removeFile. I think that's right. We are going to write this little removeFile in a moment. Let's say for some reason you'll see here, I've got a lot of validation whether the user has permission to upload stuff. I'm going to remove that now, because [00:27:58](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h27m58s) it's going to be a little bit beyond the scope of what we're explaining.
I am going to also pass it the destination of where we have moved the file because that is where the file currently is. Here we got the temporal destination(` $tmp_dest` ) which is in the temporal path( `'tmp_path'`), the temporal folder of the Joomla website. It is not where we want to end up. [00:27:02](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h27m02s) It is just where we are going to keep the file until we happy that it is safe. We got it in the temporal destination, we moved it up there, and now we checked if something happened. Do check the upload. Here if we find that this '`archivename`' file [00:27:26](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h27m26s) is problematic, we are going to have to remove it. We are going to have a new little class here. We are going to say `removeFile`. I think that is right. We are going to write this little `removeFile` in a moment. Here is a lot of validation whether the user has permission to upload stuff. It can be removed, because it is going to be a little bit beyond the scope of what is explained. <<<<<<<<<<
### Pass A Package Back
[00:28:07](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h28m07s)
Now I want to pass a package back which we are happy with, saying this is where our file is, and what its name is. We are going to do that. That's the directory, and that is the package name(see video). We are going to pass that back to the package. We could since we've got the format and maybe you want to store that. [00:28:41](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h28m41s) We could also add 'format' to the array. Everything looks good. The package name, directory path, as well as the format and we will return that back as the package and we give the package back to the model. In the save function we are going to call this 'myLoadFunction'. [00:29:17](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h29m17s) We said we are going to pass it the 'input' field, the input value, since we're already getting it, why get it again. We are going to pass that over here(see video). [00:29:44](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h29m44s) Now all that needs to be done is over here instead of this function $input->files->get('jform',null,'array') we can now do the following:
Now I want to pass a package back which we are happy with, saying this is where our file is, and what its name is. We are going to do that. That's the directory, and that is the package name(see video). We are going to pass that back to the package. We could since we've got the format and maybe you want to store that. [00:28:41](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h28m41s) We could also add 'format' to the array. Everything looks good. The package name, directory path, as well as the format and we will return that back as the package and we give the package back to the model. In the save function we are going to call this 'myLoadFunction'. [00:29:17](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h29m17s) We said we are going to pass it the 'input' field, the input value, since we're already getting it, why get it again. We are going to pass that over here(see video). [00:29:44](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h29m44s) Now all that needs to be done is over here instead of this function $input->files->get('jform',null,'array') we can now do the following:
$this->myUploadFunction($input). I will end up with that '$userfiles' package [00:30:07](https://www.youtube.com/watch?v=o482sK4DxkM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=00h30m07s) information right in this variable, and we can then just exit out to see how that will look.
### Create Remove File