-
Notifications
You must be signed in to change notification settings - Fork 255
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add base64 upload #495
base: master
Are you sure you want to change the base?
add base64 upload #495
Conversation
Needs tests before I'll review, sorry. |
src/File/Path/Base64Processor.php
Outdated
@@ -0,0 +1,39 @@ | |||
<?php | |||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These docblocks shouldn't be here.
@josegonzalez I added unit tests |
Looks like some code style fails. I will fix it later today. |
@josegonzalez could you review, please? |
$temp = []; | ||
$temp['name'] = $filename; | ||
$temp['data'] = $data; | ||
$data = $temp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When upload base64 $data is just a string f.ex
Y2FrZXBocA==
It's not an array and doesn't have an name.
Could you think about a better solution to this problem?
Here is the same thing https://github.com/FriendsOfCake/cakephp-upload/pull/495/files#diff-84c66ea1e7013949dabde1157612da57R122
$data['size'] and $data['type'] are not set when upload base64, when doing regular upload they are already provided by php.
Maybe implement another 2 interface?
The if's are there just to detect that were trying to upload base64
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also because of the https://github.com/FriendsOfCake/cakephp-upload/pull/495/files#diff-84c66ea1e7013949dabde1157612da57R122
When uploading base64 we can't use the size and type features to have them set in the database
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you show how this would be used in practice? It's not clear whats going on here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean with the 2 extra interfaces?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$data = $entity->get($field);
$path = $this->getPathProcessor($entity, $data, $field, $settings);
$basepath = $path->basepath();
$filename = $path->filename();
$dataFormatter = $this->getDataFormatter($field, $filename);
$data = $dataFormatter->formatData();
$files = $this->constructFiles($entity, $data, $field, $settings, $basepath);
$writer = $this->getWriter($entity, $data, $field, $settings);
$success = $writer->write($files);
if ((new Collection($success))->contains(false)) {
return false;
}
$entity->set($field, $filename);
$metaDataProcessor = $this->getGetMetaDataProcessor($files);
$entity->set(Hash::get($settings, 'fields.dir', 'dir'), $basepath);
$entity->set(Hash::get($settings, 'fields.size', 'size'), $metaDataProcessor->getSize());
$entity->set(Hash::get($settings, 'fields.type', 'type'), $metaDataProcessor->getType());
Something like this.Maybe with some better names 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could come with something better?I tried to think of a design pattern to apply, but I could only think of template or strategy but is pretty much like what we already have with the interfaces in place
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant in terms of an end user. How are you planning on using this/why should this go into the core?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using https://foliotek.github.io/Croppie/ so that the user can select his profile picture and the result is in base64.
@@ -87,7 +87,8 @@ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) | |||
continue; | |||
} | |||
|
|||
if (Hash::get((array)$entity->get($field), 'error') !== UPLOAD_ERR_OK) { | |||
$uploadValidator = $this->getUploadValidator($entity, $settings, $field); | |||
if ($uploadValidator->hasUploadFailed()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice
I'm not quite sure why this functionality needs to be added to the core? Who will want to use this? To me this is an edge-case and could be implemented with custom classes in userland code base. |
I think you are right.In this case, we can close the pull. |
Could be useful. Can we get documentation for this? |
@josegonzalez before getting the doc for this, we should decide what to do with the type and the size, right now they are not supported and if we are ok with https://github.com/FriendsOfCake/cakephp-upload/pull/495/files#diff-84c66ea1e7013949dabde1157612da57R103 |
After some googling Filesize:
Filetype:
|
Those seem reasonable to me @jorisvaesen. |
The problem is not how to determine the file size and type, is where do we put that code that does this? |
We could have a |
That will solve one problem. |
@mma can you add actual usage docs for this so I can see how we plan on presenting it's use for users? That'll give me a better idea of what the internals should look like. |
Adding a FileProcessor interface and a FileProcessor option to the config seems to me the right thing to do. Just make sure that this config option allows a callback function so an user can return the right processor based on the upload (base64, php file upload, ...) |
@josegonzalez |
{ | ||
$this->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); | ||
$this->table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); | ||
$this->data = ['data' => 'Y2FrZXBocA==', 'name' => '5a2e69ff-c2c0-44c1-94a7-d791202f0067.txt']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should keep in mind that using a custom array format like this makes validation tricker. Most validation methods for uploaded files won't be usable. I haven't reviewed the full PR but you need to ensure proper validation is done for this array format and someone can't sneak in whatever they want using this feature.
*/ | ||
public function hasUploadFailed() | ||
{ | ||
return !base64_decode($this->entity->get($this->field), true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can one do other validations like for e.g checking for particular mimetype / file type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I now see the comments regarding adding methods/interfaces for checking size and mime type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think is possible to do check on mimetype / file type without having the file already written on the disk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be possible having validation methods using the example code provided in this comment #495 (comment) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tried and it works. I wasn't aware of such method to determine the mimetype.
It should be in validation methods shouldn't it? |
I don't think it should be in validation.We want to use the methods to get the actual size and file type https://github.com/FriendsOfCake/cakephp-upload/pull/495/files#diff-84c66ea1e7013949dabde1157612da57R123 |
Just FYI, how I provide cropping feature is use js code to just generate the cropping dimensions and submit it in a separate field without touching the actual upload file. Then use the cropping data to crop on server side. Only drawback of this way is the full image is uploaded but in return it saves all the extra code for handing base64 encoded data and more importantly upload validation. |
If not in validation then how can I prevent someone from submitting a non image base64 encoded data? |
We can provided a method in ImageValidationTrait.php that uses https://secure.php.net/manual/en/function.imagecreatefromstring.php |
Unless cake's validator can be used to validate the mime type of base64 encoded data before any other processing begins, I am a big "NO" on adding this feature to the plugin. |
When you say |
Custom validation methods which will be used by Cake's |
@ADmad could you take a look over the validator when you have some time? |
It is very useful, I also really need it. I am very supportive of this. |
Settings to use it
@josegonzalez suggestions on how I could get rid of
is_string()
andisset()
On base64 we just get a long string of data with no filename, no type, no size.
Type and size column will also not be set.