Apigility file upload - php

I'm new to Zend's Apigility and I have problem with file upload.
I've created a new rest service and configured fields in the admin UI as described in Apigility documentation: https://apigility.org/documentation/recipes/upload-files-to-api
When trying to obtain any data from InputFilter i get only null values.
Resource controller
public function create($data)
{
$inputFilter = $this->getInputFilter();
$data = $inputFilter->getValues();
var_dump($data);
//return $this->attachments->create($data);
}
var_dump result
array(1) {
["filedata"]=>
NULL
}
For testing purposes I'm using Postman extension for Chrome with Content-Type header set to 'multipart/form-data', and attached file to key: filedata.
I'm pretty sure, I can send files using json and base64_encode, but I would rather hold with it until it would be absolutely necessary.

For those who aren't aware, Apigility is a Zend Framework 2 based framework specifically made for Rest/Rpc API's.
To do file uploads, please refer to their documentation on the recent updates as noted by Jon Day.
Credit : https://apigility.org/documentation/recipes/upload-files-to-api
How can you allow uploading files via your API?
Answer
Zend Framework 2 provides a variety of classes surrounding file upload
functionality, including a set of validators (used to validate whether
the file was uploaded, as well as whether it meets specific criteria
such as file size, extension, MIME type, etc.), a set of filters (used
to allow renaming an uploaded file, as well as, more rarely, to
manipulate the contents of the file), and file-upload-specific inputs
for input filters (because validation of files needs to follow
different rules than regular data).
Currently the limitation is that Apigility will only accept multipart/form-data
Using Xdebug I am getting the following out :
$data_array = $inputFilter->getValues();
$image = $data_array['images_data'];
The $image array looks like this :
name = MemeCenter_1400658513231_337.jpg
type = image/jpeg
tmp_name = /tmp/phpzV3mWA
error = 0
size = 379580

Try this
Update apigility with composer. File upload is working in version 1.0.3
Use Postman to send files but with no headers.Just select form-data.It worked for me.
To move uploaded file use rename instead of move_uploaded_file.

You can use the option ('magicFile' => false) for the MimeType validator which fixes the problem without any modification at the zf library.

Related

Create file from template in PHP using Laravel for Testing

What I want to archive:
I want to write a feature test using phpunit in Laravel.
What does the controller I want to test do:
It accepts uploads of test records to store it into a database. Each record consists of two files (xml, yml) with the same file name. Both files have to be read and stored in the database. The uploaded files are never stored on the server, they are directly processes.
What I want to test:
Upload a record and check if the correct data is in the database and available over the API
Check if I get the correct error if one file (xml or yml) is missing
Check if I get the right error if the files are not a valid record
and so on ...
What is my current problem?
I would like to use a template for the xml and yml files and use Faker to generate fake data for this test. The reason: Why not? My understanding of testing is, that you should test as many cases as possible and if static data is enough why do we use Faker and Factory in the Unit tests for the database and so on?
When I look at Laravel: Testing File Uploads, they generate there testing files with UploadedFile::fake(). My understanding of those files is, that they are empty and you can't use a template or something like that, to fill it with useful data. Most solutions I found just kept real files in their project. Like this.
I could use blade for this, as shown here, but I'm not really sure if I should abuse blade like this.
I could fully generate the xml and yml files using Yaml and XMLReader/XMLWriter, but there is a lot of static text in those files and I only need to fill data into some specific points.
Questions:
So what is the best way to create such a fake file? Should I use blade or twig or some other templating engine? A small solution would be appreciated.
Or should I generate the full file by myself and why is this better?
Or is there no point in generating fake data and I should use static data instead?
Here is my current test function:
public function testFullRecordUpload() {
// Generate record files to upload
// TODO Use template files with faker, or something like that
$xml_file = UploadedFile::fake()->create('test_file.xml', $sizeInKilobytes = 566);
$yml_file = UploadedFile::fake()->create('test_file.yml', $sizeInKilobytes = 20);
// Send Files
$response = $this->json('POST', '/upload', [
'xml' => $xml_file,
'yml' => $yml_file
]);
// Check response
$response->assertOk();
// Check if the uploaded data is available over API
// TODO
}

Joomla Zoo download element wrong content-type or mime-type for vcard (.vcf)

My client is using Joomla 3.7.2 and they are using the Zoo component by YOOTheme. They have created an App I believe it's called in jargon and they've added a property (element) where you can download a file.
The App is an article type app and they've used the default download element. I added the permissions to upload certain files and I've uploaded a VCF file (a vCard file).
The problem occurs when I download that file. Joomla seems to add the Content-Type: 'text/x-vcalendar'. This should be 'text/x-vcard'. I have no idea where to change this.
I have added this mime-type to my .htaccess, so when I directly link to the file, apache does send the right content type header. Therefor I know that the problem lies in either joomla or a PHP function that returns the wrong mime type.
Where do I change the mime-type for these files?
I finally found it. There's a function in the file: /administrator/components/com_zoo/framework/helpers/filesystem.php
Within this file there's a function called getMimeMapping. In it is an array with all the file extensions and mime types used per extension:
$mimes['vcf'][] = 'text/x-vcalendar';
$mimes['vcs'][] = 'text/x-vcalendar';
$mimes['vct'][] = 'text/x-vcard';
So apparently if I use the extension vct, it will output the correct Content-Type.

PUT upload does not fill $_FILES

I'm using PUT method to upload files using dropzone.js on frontend. However when I want to work with files both Symfony's Request object and $_FILES array are empty.
I have checked everything in this huge checklist and it did not help to me since it does not says anything about uploading via PUT method.
PHP does not convert files uploaded via PUT method into $_FILES hence Symfony`s Request object is empty too.
You need to handle incoming file using following code.
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
Or using $request->getContent() in symfony.
PHP also supports PUT-method file uploads as used by Netscape Composer
and W3C's Amaya clients. See the PUT Method Support for more details.
http://php.net/manual/en/features.file-upload.post-method.php

In PHP / Zend Framework what can I expect to see from a FIle plugin, with the capture plugin, posting media in phonegap in $_FILES and posted params?

I am using Zend Framework in PHP and want to create validation on file uploads, the process these uploads for storage on the backend server. What information should I expect the FileTranser phonegap plugin to post, so that I know how to process this in the back end? Can Anyone help on this?
My code might look something like this.... but without documentation of the specifics, it's hard to write the back end code and the phonegap documentation does not give enough information.
$form = new Project_Forms_Post();
$request=$this->getRequest();
if ($this->_request->isPost() && $form->isValid($this->_request->getParams())) {
$vals = $form->getValues();
$post = new Project_Model_Post($vals);
$post->save();
}
Zend Framework actually will process the file uploads as part of the form validation, so I just need to know basically, what name or names, as if coming from a form post with a input type=file, that the File plugin would attach to files.
Thanks
After spending quite a bit of time on this, I came up with a solution, this could probably be written a little better, such as putting a condition on $upload->receive() to do something on failure, but this works for now. I am using the Zend_File_Transfer class as trying to fool the form into accepting the file transfer through a file element just did not work I think because of the php file upload security in place etc.
$upload = new Zend_File_Transfer();
$upload->addValidator('MimeType', false, array('image/png', 'image/jpeg', 'image/gif', 'video/mpeg', 'video/mp4'));
//$upload->addValidator('Size', false, 200000);
$upload->setDestination(APPLICATION_PATH . "/../public/media/tmp");
$upload->receive();
$filename = $upload->getFileName();
$mimeType = $upload->getMimeType();

Downloading a docx file in CakePHP

I am trying to make a download action that downloads a Word doc generated in the 'download' controller using PHPDOCX. So far PHPDOCX is able to save the desired .docx file in the correct folder, but something goes wrong when I try to download it. Since Media Views were deprecated, I must use the CakeResponse file method as suggested in the CakePHP 2.x Cookbook:
// In the controller:
$this->response->file($file['path'], array('download' => true, 'name' => $filename));
return $this->response;
I was able to use this method for to export an RTF with no problem (the RTF was generated using PHPRTFLite), but when I use the method for a .docx file using PHPDOCX I receive the following error in Firefox:
The character encoding declaration of the HTML document was not found
when prescanning the first 1024 bytes of the file. When viewed in a
differently-configured browser, this page will reload automatically.
The encoding declaration needs to be moved to be within the first 1024
bytes of the file.
I would like to use a document generator that accepts HTML, which is why I chose PHPDOCX. Considering the above error, I set off to define the headers and content-type using the following method:
$this->response->header(array('Content-type'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document'));
But I still receive the same error in CakePHP:
The requested file APP/files/info_sheets/filename.docx was not found or not readable
One thing I was thinking is that PHPDOCX sends many errors when it generates the document and this is interfering with the Mime-type or encoding. But according to the 2.x Cookbook:
Headers are not sent when CakeResponse::header() is called either.
They are just buffered until the response is actually sent.
Another idea is that I need to set the character encoding in the header right after the content-type:
$this->response->header(array('Content-type'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8'));
But this results in garbled text.
Does anyone have any ideas how to resolve this? The "download.ctp" view file is currently blank. Please let me know if you need additional information about this issue.
Thanks!
Chris
First of all, you might try to disable autoRender, otherwise CakePHP might still try to render your view and layout;
$this->autoRender = false;
Also, haven't tested it, but have you tried this to set the header:
// register the type
$this->response->type(array('docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'));
// set the type for the response
$this->response->type('docx');
See the documentation:
http://book.cakephp.org/2.0/en/controllers/request-response.html#dealing-with-content-types
You can modify the media.php file in the core of the framework and add the mime-type to the array that have the types.
Eg:
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'

Categories