IE8 download filename become garbage if it's a Japanese name - php

I have set up my database collation to utf8_unicode_ci, and on my CakePHP database setup.
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'xxx',
'login' => 'xxx',
'password' => 'xxx',
'database' => 'thisisdatabase',
'prefix' => '',
'encoding' => 'utf8',
);
}
I set up download binary file like this:
$this->viewClass = 'Media';
$params = array(
'id' => $download_list[0],
'download' => true,
'extension' => $download_file_ext,
'path' => $fileDownloadPath . DS,
);
$this->set($params);
When the user uploads a file, the filename will be recorded in the database as unicode-utf8. When I download through Chrome, FF, it comes out fine (the Japanese name will still be intact). But when I download through IE, the filename is garbage. Although the file itself is fine (I can open it, etc).
Anyone know how to solve this?

I am not sure about how CakePHP handles this scenario, but IE has problems with sending Unicode letters in filename header for content-disposition: attachment. So to fix this in IE, we need to url-encode the filename before setting it into the header:
$filename = 'someunicodefilename.txt';
if(// IE) {
$filename = urlencode($filename);
}
header('Content-Disposition: attachment; filename="' . $filename . '"');
So I am not sure how to achieve this in CakePHP, but you can try this:
$this->viewClass = 'Media';
$filename = 'someunicodefilename.txt';
if(// IE) {
$filename = urlencode($filename);
}
$params = array(
'id' => $download_list[0],
'name' => $filename,
'download' => true,
'extension' => $download_file_ext,
'path' => $fileDownloadPath . DS,
);
$this->set($params);

Related

PHP script to clear cache in Joomla 3.x

I created the following script and put it to cron job on server. Unfortunately it does not work.
include 'includes/defines.php';
include 'includes/framework.php';
$conf = JFactory::getConfig();
$options = array(
'defaultgroup' => '',
'storage' => $conf->get('cache_handler', ''),
'caching' => true,
'cachebase' => $conf->get('cache_path', JPATH_SITE . '/cache')
);
$cache = JCache::getInstance('', $options);
$cache->clean('cachegroup');
Do you have an idea what is wrong?

Escaping a PHP function as an Array value

I'm working on a Drupal 8 starter kit with Composer, similar to drupal-composer/drupal-project.
In my post-install script, I want to re-generate a settings.php file with my custom values.
I've seen that can be done with the drupal_rewrite_settings function.
For example, I'm rewriting the config_sync_directory value like that :
require_once $drupalRoot . '/core/includes/bootstrap.inc';
require_once $drupalRoot . '/core/includes/install.inc';
new Settings([]);
$settings['settings']['config_sync_directory'] = (object) [
'value' => '../config/sync',
'required' => TRUE,
];
drupal_rewrite_settings($settings, $drupalRoot . '/sites/default/settings.php');
Problem is I want my Drupal 8 project to have a Dotenv so the maintainers don't have to modify the settings.php but only a .env file in the root folder of the project. To make it work, my settings.php must look like this :
$databases['default']['default'] = [
'database' => getenv('MYSQL_DATABASE'),
'driver' => 'mysql',
'host' => getenv('MYSQL_HOSTNAME'),
'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
'password' => getenv('MYSQL_PASSWORD'),
'port' => '',
'prefix' => '',
'username' => getenv('MYSQL_USER'),
];
$settings['trusted_host_patterns'] = explode(',', '^'.getenv('SITE_URL').'$');
As you can see, the values are replaced by PHP functions, and I can't see a good way to print those values, to the point I'm not even sure that's possible.
So my question is : is it possible to escape a PHP function as an Array value when declaring this variable ?
Looks like it's not possible because of the way the Drupal function works.
Solution 1 by #misorude
Using the drupal_rewrite_settings function, we can add the value of settings as a String, like this :
$settings['settings']['trusted_host_patterns'] = (object) [
'value' => "FUNC[explode(',', '^'.getenv('SITE_URL').'$')]",
'required' => TRUE,
];
And after that, we can replace all occurrences of "FUNC[***]" by *** directly in the settings.php file.
Solution 2
Put all your settings in a separate file. Example here, a custom.settings.php file :
if (getenv('DEBUG') == 'true') {
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/dev.services.yml';
$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;
}
$databases['default']['default'] = [
'database' => getenv('MYSQL_DATABASE'),
'driver' => 'mysql',
'host' => getenv('MYSQL_HOSTNAME'),
'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
'password' => getenv('MYSQL_PASSWORD'),
'port' => '',
'prefix' => '',
'username' => getenv('MYSQL_USER'),
];
$settings['trusted_host_patterns'] = explode(',', '^'.getenv('SITE_URL').'$');
$settings['file_private_path'] = 'sites/default/files/private';
$settings['config_sync_directory'] = '../config/sync';
Then we can copy the default.settings.php and add our custom settings.
$fs = new Filesystem();
$settings_generated = $drupalRoot . '/sites/default/settings.php';
$settings_default = $drupalRoot . '/sites/default/default.settings.php';
$settings_custom = $drupalRoot . '/../includes/custom.settings.php';
$fs->remove($settings_generated);
$fs->dumpFile($settings_generated, file_get_contents($settings_default) . file_get_contents($settings_custom));
There's also a appendToFile method that seems way better than dumping a new file with dumpFile, but it was not working unfortunatly.

Download from S3 in Laravel works with PDF, not with JPG

Im using the following code:
$file = Storage::disk('s3')->getDriver()->readStream(attachmentPath().$attachment->filename);
return \Response::stream(function() use($file) {
fpassthru($file);
}, 200, [
'Content-Type' => $attachment->mimetype,
'Content-Description' => 'File Transfer',
'Content-Disposition' => 'attachment; filename=' . $attachment->filename,
'Content-Length' => $attachment->size
]);
The variables used respond to (with pdf or jpg as example):
"mimetype" (application/pdf or image/jpeg)
"filename" (ex: 240-ivlvei-pdf.pdf or 240-zi1gdv-ddvj63hxsaqn0az.jpg)
"size" in bytes
With PDF's, it works perfectly.
With images/gif it downloads damaged.
But can't figure out why. I assume is something to do with headers or something like that.
Any ideas?
Try using getObject method and see if it works (http://docs.aws.amazon.com/AmazonS3/latest/dev/RetrieveObjSingleOpPHP.html)
$downloader = $s3->getObject(array(
'Bucket' => $bucket,
'Key' => $object['Key'],
'SaveAs' => dirname(__FILE__)."/name_of_file.jpg"
));

How to save generated PDF with JasperReports into server Yii

I need to save my generated PDF file into my server. I am using JasperReports.
Code sample for PDF generation:
$this->widget('ext.Yiijasperserver.Yiijasperserver', array(
'path' => '/reports/Crescent/call_list_report',
'format' => 'pdf',
'out' => 'I',
'file' => 'call_list_report',
'parameter' => array(
'user_id' => $user_id,
'from_date' => $from_date,
'to_date' => $to_date,
'status_id' => $status_id
)
));
Finally i got the answer. Added below code in Yiijasperserver.php file in extension folder yii
public function run()
{
$client = new Jasper\JasperClient('localhost',
8080,
'jasperadmin',
'jaspSyo#321*',
'/jasperserver');
$report = $client->runReport($this->path, $this->format,$this->page,$this->parameter);
header('Content-type: '.$this->mimetype[$this->format]);
if($this->out=="I")
header('Content-Disposition: inline; filename="'.$this->file.'.'.$this->format.'"');
if($this->out=="D")
header('Content-Disposition: attachment; filename="'.$this->file.'.'.$this->format.'"');
$file1 = 'C:\HostingSpaces\new.pdf';//New code added
file_put_contents($file1, $report);//New code added
echo $report;
}

zf2 how to upload files, more than 1 file

I refer to http://samsonasik.wordpress.com/2012/08/31/zend-framework-2-creating-upload-form-file-validation/ and follow this, I can upload 1 file successfully by using rename filter in ZF2.
However when I use this way to upload 2 files, it goes wrong. I paste my code as following:
$this->add(array(
'name' => 'bigpicture',
'attributes' => array(
'type' => 'file'
),
'options' => array(
'label' => 'Big Pic'
)
));
$this->add(array(
'name' => 'smallpicture',
'attributes' => array(
'type' => 'file'
),
'options' => array(
'label' => 'Small Pic'
)
));
<div class="row"><?php echo $this->formRow($form->get('smallpicture')) ?></div>
<div class="row"><?php echo $this->formRow($form->get('bigpicture')) ?></div>
$data = array_merge(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($data);
if ($form->isValid()) {
$product->exchangeArray($form->getData());
$picid = $this->getProductTable()->saveProduct($product);
$pathstr = $this->md5path($picid);
$this->folder('public/images/product/'.$pathstr);
//move_uploaded_file($data['smallpicture']['tmp_name'], 'public/images/product/'.$pathstr.'/'.$picid.'_small.jpg');
//move_uploaded_file($data['bigpicture']['tmp_name'], 'public/images/product/'.$pathstr.'/'.$picid.'_big.jpg');
$fileadaptersmall = new \Zend\File\Transfer\Adapter\Http();
$fileadaptersmall->addFilter('File\Rename',array(
'source' => $data['smallpicture']['tmp_name'],
'target' => 'public/images/product/'.$pathstr.'/'.$picid.'_small.jpg',
'overwrite' => true
));
$fileadaptersmall->receive();
$fileadapterbig = new \Zend\File\Transfer\Adapter\Http();
$fileadapterbig->addFilter('File\Rename',array(
'source' => $data['bigpicture']['tmp_name'],
'target' => 'public/images/product/'.$pathstr.'/'.$picid.'_big.jpg',
'overwrite' => true
));
$fileadapterbig->receive();
}
the above are form,view,action.
using this way, only the small picture uploaed successfully. the big picture goes wrong.
a warning flashed like the following:
Warning:move_uploaded_file(C:\WINDOWS\TMP\small.jpg):failed to open stream:Invalid argument in
E:\myproject\vendor\zendframework\zendframework\library\zend\file\transfer\adapter\http.php
on line 173
Warning:move_uploaded_file():Unable to move 'C:\WINDOWS\TMP\php76.tmp'
to 'C:\WINDOWS\TEMP\big.jpg' in
E:\myproject\vendor\zendframework\zendframework\library\zend\file\transfer\adapter\http.php
on line 173
Who can tell me how to upload more than 1 file in this way. you know, the rename filter way similar to above. thanks.
I ran into the same problem with a site i did. The solution was to do the renaming in the controller itself by getting all the images and then stepping through them.
if ($file->isUploaded()) {
$pInfo = pathinfo($file->getFileName());
$time = uniqid();
$newName = $pName . '-' . $type . '-' . $time . '.' . $pInfo['extension'];
$file->addFilter('Rename', array('target' => $newName));
$file->receive();
}
Hope this helps point you in the right direction.
I encountered the same problem and i managed to make it work using the below code;
$folder = 'YOUR DIR';
$adapter = new \Zend\File\Transfer\Adapter\Http();
$adapter->setDestination($folder);
foreach ($adapter->getFileInfo() as $info) {
$originalFileName = $info['name'];
if ($adapter->receive($originalFileName)) {
$newFilePath = $folder . '/' . $newFileName;
$adapter->addFilter('Rename', array('target' => $newFilePath,
'overwrite' => true));
}
}

Categories