Downloading files using media view in CakePHP - php

I want to download 4 different files through 4 different links. I am using the Media view to download the files, but I have to hardcode the file name in the download functions in the controller:
function download () {
$this->view = 'Media';
$params = array(
'id' => 'example.zip',
'name' => 'example',
'download' => true,
'extension' => 'zip',
'path' => APP . 'files' . DS
);
$this->set($params);
}
This works fine for one file. Now, for links number 2,3,4, do I need to create 3 different actions and give different file names in them, or is there a way in which I can use download() to only download the respective file depending on which link has been clicked?

That's what variables are for. Generic example:
function download($fileId) {
$file = // find the file you want to serve based on $fileId
$pathInfo = pathinfo($file['path']);
$this->view = 'Media';
$params = array(
'id' => $file['name'],
'name' => $pathInfo['filename'],
'extension' => $pathInfo['extension'],
'download' => true,
'path' => APP . 'files' . DS
);
$this->set($params);
}

In CakePhp 2.x you will get error The view for YourController::download() was not found.
Use viewClass field in CakePHP 2.x:
$this->viewClass = 'Media';
See Media Views — CakePHP Cookbook v2.x documentation
UPD: Media Views are deprecated since CakePHP 2.3, and CakeResponse::file() should be used:
$this->response->file($file['path'], array('download' => true, 'name' => 'foo'));
return $this->response;

Related

How to set URL for elfinder in yii2?

I am using this module in yii2 framework but unable to set the correct URL
https://github.com/simialbi/yii2-elfinder
'connectionSets' => [
'default' => [ // like elfinder roots
[
'class' => 'simialbi\yii2\elfinder\ElFinderConfigurationLocalFileSystem',
'path' => '#webroot/uploads',
'URL' => '#web/file/files' // HERE PROBLEM
]
]
],
This is how I have defined URL 'URL' => '#web/file/files' where file is my controller and files is my action .
Could you please let me know how exactly this URL show be passed in yii2 basic template .
127.0.0.1:8080/project/elfinder/proxy/index?baseUrl=QHdlYi9maWxlL2ZpbGVz&path=/NewFolder/file_example_PNG_500kB.png&_t=1587811929
URL point to web directory where files are stored (so this is the same directory as path, but as URL visible from web). In your case it probably should be #web/uploads.
I just figured it out .
Step 1 :- You need to set the URL managers properly
'urlManager' => [
'controller/action/<file:.*>' => 'controller/action',
]
Step 2 :- Create an action and add this code
public function actionYourActionName($file)
{
$image_path = YOUR_UPLOAD_PATH . basename($file);
if (file_exists($image_path)) {
return \yii::$app->response->sendFile($image_path, $file, [
'inline' => true //OPTIONAL
]);
}
return "What exception you want to throw";
}

How can I automatically save images in different folder with CK Finder 3

I am having difficulty getting this newer version of CKFinder (CKFinder 3) to work like how the old version did. The system used to automatically detect image files and store them in an "images" subfolder and for all other files, in a "files" subfolder.
It now seems the images subfolder only gets files to saved to it when you navigate to the folder in the "browse server" popup window and add files after clicking on the images folder. Uploading and clicking "Send to server" also sends all files to the "files" subfolder regardless of filetype.
The major problem with this is it ignores the file-size rules that are set-up for images, unless you navigate to the images folder, and then it will enforce it. It also is much less convenient as the user will not likely navigate to the subfolder each time.
Currently I have setup the config.php for CKFinder 3 like so:
$config['backends'][] = array(
'name' => 'default',
'adapter' => 'local',
'baseUrl' => $baseDir, // "/mywebsite/sites/default/uploads/"
//'root' => '', // Can be used to explicitly set the CKFinder user files directory.
'chmodFiles' => 0777,
'chmodFolders' => 0755,
'filesystemEncoding' => 'UTF-8',
);
/*================================ Resource Types =====================================*/
// https://ckeditor.com/docs/ckfinder/ckfinder3-php/configuration.html#configuration_options_resourceTypes
$config['defaultResourceTypes'] = '';
$config['resourceTypes'][] = array(
'name' => 'Files', // Single quotes not allowed.
'directory' => '/files/',
'maxSize' => '10M',
'allowedExtensions' => '7z,aiff,asf,avi,bmp,csv,doc,docx,fla,flv,gz,gzip,mid,mov,mp3,mp4,mpc,mpeg,mpg,ods,odt,pdf,ppt,pptx,pxd,qt,ram,rar,rm,rmi,rmvb,rtf,sdc,sitd,swf,sxc,sxw,tar,tgz,tif,tiff,txt,vsd,wav,wma,wmv,xls,xlsx,zip,gif,jpeg,jpg,png,svg',
'deniedExtensions' => '',
'backend' => 'default',
);
$config['resourceTypes'][] = array(
'name' => 'Images',
'directory' => '/images/',
'maxSize' => '500K',
'allowedExtensions' => 'bmp,gif,jpeg,jpg,png,svg',
'deniedExtensions' => '',
'backend' => 'default',
);
Any help is appreciated, thank you!!
The system used to automatically detect image files and store them in an "images" subfolder and for all other files, in a "files" subfolder.
This is not correct, CKFinder never worked like this. Although, you can achieve such behavior using a connector plugin.
Let's say I want all the uploaded images to be placed in Images:/ and other files should go to Files:/.
<?php
// plugins/MyPlugin/MyPlugin.php
namespace CKSource\CKFinder\Plugin\MyPlugin;
use CKSource\CKFinder\CKFinder;
use CKSource\CKFinder\Event\BeforeCommandEvent;
use CKSource\CKFinder\Event\CKFinderEvent;
use CKSource\CKFinder\Image;
use CKSource\CKFinder\Plugin\PluginInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MyPlugin implements PluginInterface, EventSubscriberInterface
{
public function setContainer(CKFinder $app) {}
public function getDefaultConfig() {
return [];
}
public static function getSubscribedEvents()
{
return [
CKFinderEvent::BEFORE_COMMAND_FILE_UPLOAD => 'handleBeforeFileUpload',
CKFinderEvent::BEFORE_COMMAND_QUICK_UPLOAD => 'handleBeforeFileUpload'
];
}
public function handleBeforeFileUpload(BeforeCommandEvent $event) {
$request = $event->getRequest();
/** #var \Symfony\Component\HttpFoundation\File\UploadedFile $uploadedFile */
$uploadedFile = $request->files->get('upload');
if ($uploadedFile && $uploadedFile->isValid()) {
$resourceType = 'Files';
if (Image::isSupportedExtension($uploadedFile->getClientOriginalExtension())) {
$resourceType = 'Images';
}
$request->query->set('type', $resourceType);
$request->query->set('currentFolder', '/');
}
}
}
Save the above plugin code as plugins/MyPlugin/MyPlugin.php and enable it in config.php:
$config['plugins'] = ['MyPlugin'];

function download in CakePHP 1.2 - vCard file

I'm doing some simple content maintenance on a site built on CakePHP 1.2. I did not develop the site. I'm unable to set up a localhost instance of the site because the framework is ancient, and I'm a hack. Consequently, I'm unable to test before deployment. Not a best case scenario, but it is what it is.
The text content updates are complete. However, the client has requested that a .vcf file be linked to for download from a static .thtml file.
My first attempt to implement this saw plain text returned when the a href was clicked.
In consulting the 1.2 manual I see there's a Media Views function:
function download () {
$this->view = 'Media';
$params = array(
'id' => 'example.zip',
'name' => 'example',
'download' => true,
'extension' => 'zip',
'path' => APP . 'files' . DS
);
$this->set($params);
}
which I have mod'd thus:
function download () {
$this->view = 'Media';
$params = array(
'id' => 'emp-name.vcf',
'name' => 'emp-name',
'download' => true,
'extension' => '.vcf',
'path' => APP . '/webroot/files' . DS
);
$this->set($params);
}
Can someone confirm that I'm heading in the right direction with this by adding this function to /app/controllers/pages_controller.php
As I say, I'm unable to test before deployment, and am concerned about breakage. Yes, I'm making .baks to fall back on.
tia
update:
Pushed /app/controller/pages_controller.php live.
Nothing broke, but the .vcf still displays as text when the link is clicked.
Maybe this controller isn't affecting the page: /app/views/pages/contact.thtml ?

cakephp upload plugin - define what directory to save files in

I'm using cakephp-upload plugin of jose gonzalez to upload images to our app. By default, they're being saved in a directory like this: webroot/files/user/photo/{user_id} which is fine, except for when we want to display such images using $this->Html->image() which searches for images in the webroot/img directory.
I have already tried to display the images with
echo $this->Html->image('../files/user/photo/' .
$user['User']['photo_dir'] . '/' .
$user['User']['photo']);
which works but I was wondering if there's some way to tell this plugin to save into the img directory? The documentation doesn't mention any of that.
And also, is there any way to tell the $this->Form->input('User.photo', array('type' => 'file')); to accept only image files?
as you can see in this file, path is set like:
public $defaults = array(
'rootDir' => null,
'pathMethod' => 'primaryKey',
'path' => '{ROOT}webroot{DS}files{DS}{model}{DS}{field}{DS}',
...
you could change it to make:
'path' => '{ROOT}webroot{DS}img{DS}'
and for your second question, you could use accept attribute, like:
$this->Form->input('User.photo',
array(
'type' => 'file',
'options' => array('accept' => 'image/*')
)
);

open up pdf files in webroot within browser cakephp

I want to open up pdfs in browser with cakephp. I am saving the files within webroot/files folder. I know how to use media which is direct downloads. but how do I open pdfs in browser directly ?
As per the MediaView book page, simply set autoRender to false and set a view variable named download to false in your controller. Also make sure to specify the mimeType as most browsers will force downloads for unknown mime types.
Example:
function download () {
$this->view = 'Media';
$this->autoRender = false; // Disable auto-render.
$params = array(
'download' => false, // Don't force download.
'id' => 'example.docx',
'name' => 'example',
'extension' => 'docx',
'mimeType' => array('docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'), // extends internal list of mimeTypes
'path' => APP . 'files' . DS
);
$this->set($params);
}

Categories