ZF2 File Upload: File is empty - php

I have a problem with uploading Images in a Zend Framework 2 Application and i think i have a configuration error somewhere in my code.
This is my current Code. I created the Form and Filter like the ZfcUser Form.
Form extends ProvidesEventsForm(ZfcBase)
$file = new Element\File('image');
$file->setLabelAttributes(array('class' => 'control-label col-sm-4'));
$file->setLabel('image');
$this->add($file);
Filter extends ProvidesEventsInputFilter(ZfcBase)
$this->add(
array(
'type' => 'Zend\InputFilter\FileInput',
'name' => 'image',
'required' => true,
'validators' => array(
array(
'name' => 'File\UploadFile',
),
),
'filters' => array(
array(
'name' => 'File\RenameUpload',
'options' => array(
'target' => './public/img/uploads',
'randomize' => true,
),
),
),
)
);
In the validation process the method FileInput::isValid() is called - but the Value is always null and i have no clue why it is.
The HTML-Form is set to multipart/form-data and the Server configuration is also no problem.
The file i used for testing is only 80KB.
Anyone an idea, what is wrong?

Finally i found a solution for the Problem.
Before the Post information added to the form, they have to merged with the file information:
$files = $this->getRequest()->getFiles()->toArray();
$post = array_merge_recursive(
$this->getRequest()->getPost()->toArray(),
$files
);
$form->setData($post);

Related

Show the configuration values in the text field of form in prestashop 1.7

I am creating a module in prestashop 1.7 to save my settings.
Also I created a form to display my settings. Form sample is shown below:-
//display form function
public function renderCustomerForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->l('Customer Settings'),
'icon' => 'icon-time'
),
'input'=>array(
array(
'type' => 'text',
'label' => $this->l('BusinessCustomerFlag'),
'name' => 'C_BUSINESS_FLAG',
'lang' => false,
'required' => true
),
),
'submit' => array(
'title' => $this->l('Save'),
'name' => 'submitCustomer',
'icon' => 'process-icon-save'
)
);
I am saving this values in configuration table using configuration class functions.
I know how to retrieve it but don't know how to show in the form. Please some one guide on this will be really helpful.
Add this line to helper on your module (before generateForm):
$helper->fields_value = $this->getFormValues();
and add function to define values:
public function getFormValues()
{
$fields_value = array();
$fields_value['C_BUSINESS_FLAG'] = "some data or retrieved data";
return $fields_value;
}

Use Zend 2 Extension Validator only if file is uploaded

I would like to validate the file extension only if a file is uploaded.
I have a collection of fieldsets that include a File Input element. If I want to upload a file for only one of the fieldsets and leave the rest of the File Input elements empty the form is not validated, although they have required = false. This validation triggers the "fileExtensionNotFound" error.
Is there a way to add the AllowEmpty to or before the Extension validator?
'file' => array(
'required' => false,
'validators' => array(
array(
'name' => 'Zend\Validator\File\Extension',
'options' => array(
'extension' => array('pdf', 'xls','doc'),
)
)
)
)
I had to specify the type to be FileInput.
'file' => array(
'type' => '\Zend\InputFilter\FileInput',
'allow_empty' => true,
'required' => false,
'validators' => array(
array(
'name' => 'Zend\Validator\File\Extension',
'options' => array(
'extension' => array('pdf', 'xls','doc')
),
),
),
),

Nested Parameters/Values in POST Requests

I have been thinking about a good way to handle nested/complex values in POST requests to a apigility resource.
For example, an order might contain a collection of order items in a single POST requested that is used to create an order. Both, order and order-item do exist as a resource. However, I would very much like to have only one request that would create order and order item entities. Handling that in the resource is not a problem, but I wonder how you would configure that resource (let´s call it order-place) using the apigiliy UI - or, if at all impossible, using the configuration. Applying validators and filters is one of the key features of apigility, and i´d like to keep using that, even for complex request data.
And before you ask, using an underscore to separate the values scopes, for example order_comment and order_item_comment should not be an option.
Any ideas?:)
Addition: A sample json request payload could look like this:
{
"created_at": "2000-01-01",
"amount" : "5000.00",
"address" : {
"name": "some name",
"street": "some street"
...
},
"items" : [
{"productId":99,"qty":1}
...
]
}
Starting from Wilt's answer, I've found that the following code works as well:
# file path: /module/MyApi/config/module.config.php
// some other stuff
'MyApi\\V1\\Rest\\MyRestService\\Validator' => array(
'address' => array(
0 => array(
'name' => 'name',
'required' => true,
'filters' => array(),
'validators' => array(),
),
1 => array(
'name' => 'street',
'required' => true,
'filters' => array(),
'validators' => array(),
),
'type' => 'Zend\InputFilter\InputFilter'
),
'amount' => array(
'name' => 'amount',
'required' => true,
'filters' => array(),
'validators' => array()
)
The only problem I get is when address is passed as a field (string or numeric) rather then an array or object. In this case Apigility throws an exception:
Zend\InputFilter\Exception\InvalidArgumentException: Zend\InputFilter\BaseInputFilter::setData expects an array or Traversable argument; received string in /var/www/api/vendor/zendframework/zendframework/library/Zend/InputFilter/BaseInputFilter.php on line 175
Adding address as a further simple (required) field avoids the exception, but then Apigility doesn't see any difference whether we pass address as an array of name and street or a dummy string.
If you are using the ContentValidation module then you can configure an input filter for the nested resources by assigning it to a variable. Then you have to add a type key (essential otherwise reusing the filter won't work). Now you are able to use this variable in your input_filter_specs and you can reuse the whole filter inside another filter. So something like this in your config.php:
<?php
namespace Application;
// Your address config as if it was used independently
$addressInputFilter => array(
'name' => array(
'name' => 'name',
'required' => true,
'filters' => array(
//...
)
'validators' => array(
//...
)
),
'street' => array(
'name' => 'street',
'required' => true,
'filters' => array(
//...
)
'validators' => array(
//...
)
),
// 'type' key necessary for reusing this input filter in other configs
'type' => 'Zend\InputFilter\InputFilter'
),
'input_filter_specs' => array(
// The key for your address if you also want to be able to use it independently
'Application\InputFilter\Address'=> $addressInputFilter,
// The key and config for your other resource containing a nested address
'Application\InputFilter\ItemContainingAddress'=> array(
'address' => $addressInputFilter,
'amount' => array(
'name' => 'amount',
'required' => true,
'filters' => array(
//...
),
'validators' => array(
//...
)
)
//... your other fields
)
)

Adding a new field to an existing content-type in Drupal 7

I'm new to Drupal and I'm looking for a way to add a new field to an already installed content-type in Drupal 7. Please note that some content is already present in the database. Also, I need to do this programmatically and not via a GUI.
Googling, I have already found the following documents, which seem to be related:
https://api.drupal.org/api/drupal/modules!field!field.module/group/field/7
https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_update_N/7
Still, my ideas are a bit confused and a basic example would clarify things.
This snippet should get you started. It was found on the Drupal Stackexchange. I suggest you check there first in the future.
https://drupal.stackexchange.com/questions/8284/programmatically-create-fields-in-drupal-7
$myField_name = "my_new_field_name";
if(!field_info_field($myField_name)) // check if the field already exists.
{
$field = array(
'field_name' => $myField_name,
'type' => 'image',
);
field_create_field($field);
$field_instance = array(
'field_name' => $myField_name,
'entity_type' => 'node',
'bundle' => 'CONTENT_TYPE_NAME',
'label' => t('Select an image'),
'description' => t(''),
'widget' => array(
'type' => 'image_image',
'weight' => 10,
),
'formatter' => array(
'label' => t('label'),
'format' => 'image'
),
'settings' => array(
'file_directory' => 'photos', // save inside "public://photos"
'max_filesize' => '4M',
'preview_image_style' => 'thumbnail',
'title_field' => TRUE,
'alt_field' => FALSE,
)
);
field_create_instance($field_instance);
drupal_set_message("Field created successfully!");
}
You can execute this code countless ways. I am not privy to the requirements of your project so its hard for me to make a recommendation. You could hook this into the update/install functions, or you could build it into a page hook in a module, or you could just bootstrap any new php file in the root directory with this:
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

IsImage validator in ZF2 forms

I'm having problems implementing the IsImage File validator in a Form class in Zend Framework 2-beta5.
In general I'm having problems using any File validator in a Zend Form class in Zend framework 2.
I couldn't find any relevant documentation.
I found that for example Float validator that resides at Library/Zend/Validator
can be used with the following code:
$this->setInputFilter($inputFactory->createInputFilter(array(
'alcohol_vol' => array(
'name' => 'alcohol_vol',
'required' => true,
'validators' => array(
array(
'name' => 'Float',
),
),
),
)));
the IsImage file validator resides at /Library/Zend/Validator/File and can't find a way to use it. any information regarding the issue would be greatly appreciated.
thanks!
Kfir
Try to add this snippet under validators key, like this:
'validators' => array(
array(
'name' => '\Zend\Validator\File\IsImage',
'options' => array(
'break_chain_on_failure' => true,
),
),
),
But sometimes, depends on server configuration, IsImage might not working. Then use Extension validator instead:
'validators' => array(
array(
'name' => '\Zend\Validator\File\Extension',
'options' => array(
'extension' => array(
'png', 'jpeg', 'jpg',
),
'break_chain_on_failure' => true,
),
),
),
Upload file validate/filter should use Zend\File\Transfer but not Zend\Form
Try below way to add file validator
$fileTransfer = new Zend\File\Transfer\Transfer();
$fileTransfer->addValidators(array(
array('IsImage', true)
));
if($fileTransfer->isValid()){
$fileTransfer->receive();
}

Categories