CakePHP issue when downloading csv file in safari on OS X - cakephp

Following is the controller function that returns the csv file:
public function export(){
if ($this->request->is('get')) {
throw new MethodNotAllowedException();
}
$employee = $this->request->query['employee'];
$from = $this->request->query['from'];
$to = $this->request->query['to'];
$events = $this->Event->export($employee, $from, $to);
$this->response->download("export.csv");
$this->set(compact('events'));
$this->layout = 'ajax';
return;
}
Here is how I call it:
echo $this->Form->postLink(
$this->Html->image('export.png', array('width'=>'200px', 'height'=>'79px')),
array(
'controller' => 'events',
'action' => 'export',
'?' => array(
'employee'=>$_POST['data']['Event']['employee'],
'from'=>$_POST['data']['Event']['from'],
'to'=>$_POST['data']['Event']['to'],
'ext'=>'csv'
)
),
array('escape'=>false)
);
It is working all good on every platform and browser except from safari on OS X. After I try to download it on safari (only on OS X), the file is getting a .html extension.
Any help or guidance is much appreciated.

Related

Cakephp Upload Image - Can not determine the mimetype

The following validation is being done in my model
'image' => array(
'uploadErrror' => array(
'rule' => 'uploadError',
'message' => 'The image upload failed.',
'allowEmpty'=> True
),
'mimeType' => array(
'rule' => array('mimeType',array('image/gif','image/png','image/jpeg')),
'message' => 'Please only upload images (gif, png, jpg).',
'allowEmpty' => true
),
'fileSize'=> array(
'rule' => array('fileSize', '<=', '1MB'),
'message' => 'Image must be less than 1MB.',
'allowEmpty' => true
),
'processImageUpload' => array(
'rule' => 'processImageUpload',
'message' => 'Unable to process image upload.',
'allowEmpty'=> true
) )
public function processImageUpload($check = array()){
if(!is_uploaded_file($check['image']['tmp_name']))
{
return FALSE;
}
$targetdir = WWW_ROOT . 'img' . DS . 'uploads' . DS . $check['image']['name'];
if(!move_uploaded_file($check['image']['tmp_name'],$targetdir))
{
return false;
}
$this->data[$this->alias]['image'] = 'uploads' . DS . $check['image']['name'];
return true;
}
The error I am receiving is the below, I also enabled debug 2 but no further clarification was provided.
Can not determine the mimetype.
I have already tried un-commenting
extension=php_fileinfo.dll
and restarted WAMPServer fully but it still did not work.
Also in the controller class I have the following code for add
public function add() {
if ($this->request->is('post')) {
$this->Image->create();
$data = $this->request->data['Image'];
if (!$data['image']['name'])
{
$this->Session->setFlash(__('There was no image provided.'));
}
if ($this->Image->save($data)) {
$this->Session->setFlash(__('The image has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The image could not be saved. Please, try again.'));
}
}
}
Add View Code
<?php echo $this->Form->create('Image',array('type'=>'file')); ?>
<fieldset>
<legend><?php echo __('Add Image'); ?></legend>
<?php
echo $this->Form->input('description');
echo $this->Form->input('image',array('type'=>'file'));
echo $this->Form->input('property_id');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
Any suggestions would be greatly appreciated.
Not sure if this is the whole problem, but:
'mimeType' => array(
'rule' => array('mimeType',array('image/gif','image/png','image/jpeg')),
'message' => 'Please only upload images (gif, png, jpg).',
'alllowEmpty' => true
),
'alllowEmpty' has 3 L's.
The closes solution which isn't checking mime but just extension is
$ext = substr(strtolower(strrchr($check['image']['name'], '.')), 1); //get the extension
$arr_ext = array('jpg', 'jpeg', 'gif'); //set allowed extensions
if (in_array($ext, $arr_ext)) {
//upload code
}
else
{
return 'Please only upload images (gif, png, jpg).';
}
Change the text ;extension=php_fileinfo.dll into extension=php_fileinfo.dll on php.ini
It works for me. Hope it help you guys. I'm using xampp.
In general, Cake expects to find the file to check at location specified in original
$this->data[$this->alias]['image']['tmp_name'] // or whatever is the name of the field
during validation. So make sure the ...['tmp_name'] points to valid location with (still) existing uploaded file.
ORIGINAL ANSWER:
I think the problem is here (I had also similar problem):
$this->data[$this->alias]['image'] = 'uploads' . DS . $check['image']['name'];
After you move the uploaded file, you assign path infromation to $this->data[$this->alias]['image'] but CakePHP thinks that there is an array with all information about uploaded file. That is why the whole validation will fail.
To be specific, CakePHP will try to look for tmp_name in $this->data[$this->alias]['image'] but it won't find it there, after that it will try to determine mime type of "nothing" and it will fail.

Download function not working CakePHP

I read the documentation regarding file downloads, however I can't seem to get this to work.
I have read through questions here as well, and have had no luck.
My function looks as follows:
public function generate($id) {
$this->layout = 'ajax';
$this->Magazine->recursive = 2;
$DistributionLists = $this->Magazine->DistributionList->find('all',
array(
'conditions' => array(
'Magazine.id' => $id
),
'order' => array(
'DistributionList.priority ASC'
)
)
);
$this->set('magazine',$DistributionLists[0]['Magazine']['magazine_name']);
$this->set(compact('DistributionLists'));
}
public function download() {
$this->viewClass = 'Media';
$params = array(
'id' => "Magazine Distribution List.doc",
'name' => "Magazine Distribution List",
'download' => true,
'extension' => 'doc',
'path' => APP . "tmp" . DS
);
$this->set($params);
unlink(APP."tmp".DS);
$this->redirect(array('action'=>'index'));
}
public function afterFilter() {
parent::afterFilter();
if($this->action == 'generate') {
$this->redirect(array('action'=>'download'));
}
}
The reason I have an afterFilter function is because the word document that needs to be downloaded is created in the view file.
Does anyone know why this doesn't work?
You have to remove the call to the redirect method in your download method because it prevents your view from getting "rendered" due to the redirect.

CakePHP view file via Media Views doesn't work

I have CakePHP 1.3 and I have an action that is supposed to view a file, the file maybe a .pdf, .doc, .... or any document, but I get a blank page instead.
code sample:
public function view_attachments($attachment_id){
$attachment = $this->get_attachment($attachment_id);
if($attachment){
$path = pathinfo($attachment['EmailAttachment']['file']);
$this->view = 'Media';
$this->autoRender = false;
$params = array(
'id' => $path['basename'],
'name' => $path['filename'],
'download' => false,
'mimeType'=> $this->Common->get_mime_content_type($path['basename']),
'extension' => strtolower($path['extension']), // must be lower case
'path' => APP . $path['dirname'] . DS // don't forget terminal 'DS'
);
$this->set($params);
}
}
Any Ideas? Please advise.
check that media.ctp file must be blank... to get proper output...
Thanks
Checking on my own working code, the only difference I see is
$this->autoRender = false;
Of course your not supposed to have a "view_attachments.ctp" file.
Be aware that browser's can't open ".doc" natively. So even if you want him to display it, he will offer you to download it.
function download($id) {
$data = $this->OdmPieceJointe->read(null, $id);
$path = pathinfo($data['OdmPieceJointe']['fichier']);
$this->view = 'Media';
$params = array(
'id' => $path['basename'],
'name' => $path['filename'],
'download' => false,
'extension' => $path['extension'],
'path' => 'uploads/',
);
$this->set($params);
}
maybe :
Configure::write('debug', 0);

Browsers do not cache response sent by MediaView

This is my controller code:
$this->viewClass = 'Media';
$params = array(
'id' => $filename '.gif',
'name' => $filename ,
'download' => false,
'extension' => 'gif',
'path' => $folderpath,
'cache' => '+30 days',
'modified' => '#' . filemtime($pathtofile),
);
$this->set($params);
and the response:
Debug is disabled in core.php. However, the browser (Firefox, Chrome) never caches the file and always download the whole thing. Is this because of the 200 OK response? How can I fix it?
EDIT
I probably should have added a sample of the actual request URL
http://localhost/mycontroller/mymediaaction/2345
I resolved the issue by setting the name attribute to the action parameter instead of the actual file name. I still appreciate an answer with some explanation of this behavior.
The following code snippet for a controller action would either serve a 304 response or the file. I think that the checkNotModified functionality should be done by the MediaView::render function internally, similar to the AssetDispatcher. But for the time being this snippet may be of help.
$modified = #filemtime(ROOT . $dir . $filename);
$this->response->modified($modified);
if ($this->response->checkNotModified($this->request))
{
$this->autoRender = false;
$this->response->send();
}
else
{
$this->viewClass = 'Media';
$params = array('id' => $filename,
'cache' => '+1 day',
'modified' => '#' . $modified, // Must be a string to work. See MediaView->render()
'path' => ROOT . $dir);
$this->set($params);
}
return;

ie wont support dtds in feed cakephp

Ok I'm trying to create a rss feed with cakephp rss helper for some post of an app. I followed the cakephp book to the letter and it wont work with internet explorer... When I open it with Opera it work but with ie it says "Internet Explorer does not support feeds with DTDs."...
I know microsoft is not supporting dtds because a security thread but how can I fix this issue? The company where I work uses ie by standard so changing the browser is not an option...
here is the code... So you can see there is not a mayor modification in it...
default.ctp
echo $this->Rss->header();
if (!isset($documentData)) {
$documentData = array();
}
if (!isset($channelData)) {
$channelData = array();
}
if (!isset($channelData['title'])) {
$channelData['title'] = $title_for_layout;
}
$channel = $this->Rss->channel(array(), $channelData, $content_for_layout);
echo $this->Rss->document($documentData,$channel);
index.ctp
$this->set('documentData', array(
'xmlns:dc' => 'http://purl.org/dc/elements/1.1/'));
$this->set('channelData', array(
'title' => __("Most Recent Hitos", true),
'link' => $this->Html->url('/', true),
'description' => __("Most recent Hitos.", true),
'language' => 'en-us'));
foreach ($posts as $post) {
$postLink = array(
'controller' => 'soportes',
'action' => 'view',
$post['Soporte']['id']);
// You should import Sanitize
App::import('Sanitize');
// This is the part where we clean the body text for output as the description
// of the rss item, this needs to have only text to make sure the feed validates
$bodyText = preg_replace('=\(.*?\)=is', '', $post['Hito']['actividad']);
$bodyText = $this->Text->stripLinks($bodyText);
$bodyText = Sanitize::stripAll($bodyText);
$bodyText = $this->Text->truncate($bodyText, 400, array(
'ending' => '...',
'exact' => true,
'html' => true,
));
echo $this->Rss->item(array(), array(
'title' => $post['Hito']['actividad'],
'link' => $postLink,
'guid' => array('url' => $postLink, 'isPermaLink' => 'true'),
'description' => $bodyText,
'dc:creator' => $post['Hito']['user_id'],
'pubDate' => $post['Hito']['fecha_sugerida']));
}
On a very basic level it might be because of the debug level in core.php - cake outputs the render time I think - you could try setting Configure::write('debug', 0); in your controller action to see if it renders in IE? I've had issues with XML / RSS and IE due to this before.

Resources