zend-framework2zend-form2zend-file

getdata on File input to return only filename, not array of details


I have a form that has a fieldset with a file upload field in it. When I do a var_dump on $form->getData() I am being shown an array of data for the file field:

array (size=13)
  'logo' => 
    array (size=5)
      'name' => string 'my-image.gif' (length=12)
      'type' => string 'image/gif' (length=9)
      'tmp_name' => string 'C:\xampp\htdocs\images\my-image.gif' (length=35)
      'error' => int 0
      'size' => int 391
  //... other fields here

How do get the element to return only the name when I call getData?

e.g.

array (size=13)
  'logo' => string 'my-image.gif' (length=12)
  //... other fields here

I am using the form for other things and have already overridden getData so would like to keep the answer located in the fieldset.


Solution

  • You can override the getData() method in your form.

    public function getData()
    {
        $data = parent::getData();
        $logo = $data['logo'];
        $data['logo'] = $logo['name'];
        return $data;
    }
    

    Add all necessary precautions to ensure the existence of the keys in the arrays.

    Supplements for a fieldset

    Using a fileset, you can use a Filter to change the return file structure :

    namespace your\namespace;
    
    use Zend\Filter;
    
    class FilterFileName extends Filter\AbstractFilter
    {
    public function filter($value)
    {
            if (! is_scalar($value) && ! is_array($value)) {
                return $value;
            }
            if (is_array($value)) {
                if (! isset($value['name'])) {
                    return $value;
                }
                $return = $value['name'];
            } else {
                $return = $value;
            }
            return $return;
        }
    }
    

    Your fieldset class must implement InputFilterProviderInterface

    use your\namespace\FilterFileName;
    
    class YourFieldset extends ZendFiedset implements InputFilterProviderInterface
    {
        public function __construct()
        {
            // your code ... like :
            parent::__construct('logo');
    
            $file_element = new Element\File('my-element-file');
            $file_element->setLabel('Chooze')
                ->setAttribute('id', 'my-element-file')
                ->setOption('error_attributes', [
                   'class' => 'form-error'
            ]);
            $this->add($file_element);            
        }
        public function getInputFilterSpecification()
        {
            return [
                'element-file' => [
                    'name' => 'my-element-file',
                    'filters' => [
                        ['name' => FilterFileName::class]
                    ]
                ]
            ];
        }
    }
    

    You can chain multiple filters, eg to rename the file before.