I downloaded a javascript for resizing images and it works perfect! Only it is returning the cropped image as a JSON/Encoded object.
When I decode the data[1] and save it in the “traditional” way (fopen/fwrite) everything works fine. But of course no laminas filtering and validation.
How do I pas the cropped (encoded) image to my form validation? In my controller I used the default code, that works with a normal input and no cropping/resizing.
Is there a way to merge/replace the cropped image in the $post data? So that the normal validation is followed?
$form = new UploadForm('profielfoto', $options);
$request = $this->getRequest();
if ($request->isPost()) {
// Make certain to merge the $_FILES info!
$post = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($post);
if ($form->isValid()) {
$data = $form->getData();
Array ( [profielfoto_values] => {"data":"data:image/jpeg;base64,/9j/4AA………../9k=","name":"weg-is-weg.jpg","imageOriginalWidth":1119,"imageOriginalHeight":1069,"imageWidth":1064,"imageHeight":1016,"width":500,"height":500,"left":-281,"top":-258} [submit] => Upload profielfoto [profielfoto] => Array ( [name] => [full_path] => [type] => [tmp_name] => [error] => 4 [size] => 0 ) )
This is a normal PHP array, so you can do what you want.
The form or input filter does not care where the data comes from, how it was compiled or whether this data has been processed beforehand.
Another option use a custom filter within the input filter to to crop the images. This can be done via different libraries. For example:
Yes, i can decode the base64 to get the cropped image, but is it possible to get the file to the “usual” filters of my form (see below)?
In my controller I below works with a “normal” selected file via the input
// Make certain to merge the $_FILES info!
$post = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$tmp = explode(',',$post['profielfoto']);
$imgdata = base64_decode($tmp[1]);
$form->setData($post);
The form:
class UploadForm extends Form {
//$name is het naamelement van het formulier
public function __construct($name = null, $options = []) {
parent::__construct($name, $options);
$this->addElements();
$this->addInputFilter( $options ["user"]);
}
public function addElements(){
$this->add([
'name' => 'profielfoto',
'type' => File::class,
'options' => [
'label' => 'Profielfoto',
],
'attributes' => [
'id' => 'profielfoto',
],
]);
$this->add([
'name' => 'submit',
'type' => Submit::class,
'attributes' => [
'value' => 'Upload profielfoto',
'id' => 'submitbutton',
],
]);
}
public function addInputFilter($user)
{
$inputFilter = new InputFilter\InputFilter();
// File Input
$fileInput = new InputFilter\FileInput('profielfoto');
$fileInput->setRequired(false);
$fileInput->getFilterChain()->attachByName(
'filerenameupload',
[
'target' => './public/img/profielfoto/'.$user.'.png',
'overwrite' => true,
]
);
$inputFilter->add($fileInput);
$this->setInputFilter($inputFilter);
}
This would work if the image data is saved in the file system beforehand. You can use different validators to check if the saved file is an image or more. But this means that you bypass the entire normal upload process of a file. Which also means that you do not have access to standard functions or the standard PHP checks for uploads - which are also used in the file filters of laminas-filter.
So the best way is to “receive” the encode array/file in the controller, decode it and then get it through a filter different from the normal form filter? Is it save to decode and filter/validate it after decoding?
The question is, what exactly does the JavaScript in the browser? Cropping the image to fixed specifications or the user can determine it himself?
If fixed specifications are used then crop the image on the server and you can use all upload checks from PHP.
Otherwise, overwrite the setData method of your form class and check and make the corresponding conversions there. Reduce the code in the controller to a minimum.
This also allows simple testing of the form.
Yes, the javascript crops and resizes the image and shows an adjusted version (after aprove) op the canvas. How to overwrite the setdata (with the decoded file)?
public function setData($data)
{
// Check if `profielfoto_values` is present and JSON format
if (…) {
// Do everything here that is necessary
}
return parent::setData($data);
}
Yeah, (i think) that is what I mean
I feel like a total noob, but how to get the file to the addInputFilter function and to new InputFilter\FileInput(‘profielfoto’);
public function addInputFilter($user)
{
$inputFilter = new InputFilter\InputFilter();
// File Input
$fileInput = new InputFilter\FileInput('profielfoto');
$fileInput->setRequired(false);
$fileInput->getFilterChain()->attachByName(
'filerenameupload',
[
'target' => './public/img/profielfoto/'.$user.'.png',
'overwrite' => true,
]
);
$inputFilter->add($fileInput);
$this->setInputFilter($inputFilter);
}
public function setData($data)
{
$tmp = explode(',',$data);
$data['profielfoto'] = base64_decode($tmp[1]);
// Check if `profielfoto_values` is present and JSON format
//if (…) {
// Do everything here that is necessary
//}
//return parent::setData($data);
}