I would like to attach an uploaded file (pdf) to a normal create function, but it doesn't really work. I have model, controller, form modified, and it says uploading, model validates, but still, no pdf in db. I have set field as blob. what can be wrong?
model:
use yii\web\UploadedFile;
class MyModel extends \yii\db\ActiveRecord {
public $file;
...
public function rules() {
return [
[['file'], 'file', 'skipOnEmpty' => true, 'extensions' => 'pdf'],
...
_form:
$form = ActiveForm::begin([
'enableClientValidation' => false,
'options' => ['enctype' => 'multipart/form-data'],
]
...
<?= $form->field($model, 'file')->fileInput() ?>
controller:
use yii\web\UploadedFile;
public function actionCreate() {
$model = new MyModel;
try {
if ($model->load($_POST)) {
$model->file = UploadedFile::getInstance($model, 'file');
if ($model->save()) {
...
This is how it works for file uploading
$model->file = UploadedFile::getInstance($model, 'file');//Get the uploaded file
$model->file->saveAs('uploads/' . $model->file->name);//Save uploaded file at your desired location
$user->image = $model->file->name;//image is my database field name,to only save the name of the uploaded file
I hope this will make it clear and solve your problem
Related
So I started to play around with cakePHP after i did the blog tutorial (yes im new), and i would like to do something complicated. Like, theres a comment form, which is simple it contains Name and the Comment. And I would like to send the data to another application in the same host, which is save this comment in the DB. Currently the Comments/add.ctp saves it.
Thanks for any advice!
So theres the CommentsControll.php
<?php
class CommentsController extends AppController{
public $components = 'Session'
public function add(){
if($this->request->is('POST')){
$this->Comment->create();
if($this->Comment->save($this->request->data)){
$this->Session->setFlash('Your comment is saved!')
}
}
}
}
?>
And theres the Comments/add.ctp file
<?php
echo $this->Form->create('Comment');
echo $this->Form->input('name', array(
'label' => 'Your Name'
));
echo $this->Form->input('commenttext',array(
'label' => 'Your Comment'
));
echo $this->Form->end('Submit');
?>
Solution HttpSocket
CakePHP includes an HttpSocket class which can be used easily for making requests. It is a great way to communicate with external webservices, or remote apis.
// in your controller
App::uses('HttpSocket', 'Network/Http'); // This should be at the top of your Controller
class CommentsController extends AppController{
public $components = 'Session'
public function add(){
if($this->request->is('POST')){
$this->Comment->create();
$HttpSocket = new HttpSocket();
$response = $HttpSocket->post('http://example.com/add', $this->request->data));
// Get the status code for the response.
$code = $results->code;
if($code == 200) {
$this->Session->setFlash('Your comment is saved!');
} else {
$this->Session->setFlash('Opps! Somthing is wrong!');
}
}
}
}
Also see here CakePHP HttpSocket
I have 4 different types of file to download image/doc/pdf/xls. I want to download the file once I clicked on file link.
//controller
public function sendFile($id) {
$file = $this->Attachment->getFile($id);
$this->response->file($file['path']);
// Return response object to prevent controller from trying to render
// a view
return $this->response;
}
//view
<?php echo $file->name; ?>
No need to return the response - see this.
Simply use
public function send_file($id = null) {
...
$this->autoRender = false;
$this->response->file($file['path']);
}
In your view you need to link to this controller action, though (if you think about it):
$this->Html->link('Download', array(
'controller' => 'controller_name', 'action' => 'send_file', $id
));
Also note the conventions I corrected for you - the docs tell you that as well.
just to complete and add some notes on Mark's answer
Simply use
public function send_file($file_name = null) {
//local machine to the file
//e.g. c:\wamp\www\project\...
$path_local = 'path to the file'.$file_name;
//live path to the file
//e.g. \var\...
$path_live = 'path to the file'.$file_name;
$this->autoRender = false;
//if you trying to test it from localhost set the localhost path
//other wise live path
$this->response->file($path_live or $path_local, array('download' => true));
}
In your view you need to link to this controller action, though (if you think about it):
$this->Html->link('Download', array(
'controller' => 'controller_name', 'action' => 'send_file', $file_name
));
Also note the conventions I corrected for you - the docs tell you that as well.
I am using cakephp 2.3 and want to generate list of users in json format.
controller name: users
method: list
Earlier, I have done it in cake 1.3.x and when user tries access method via url in browser then output comes as download file but when i am doing it in cakephp 2.3 then it is showing me json output on browser page itself instead of download file.
here is my code:
Controller:
<?php
App::uses('AppController', 'Controller');
class UsersController extends AppController {
public $helpers = array('Form', 'Html', 'Js', 'Time');
public $components = array('RequestHandler');
var $layout = 'js/default';
public function list() {
$this->log("i got data in user add:");
$this->log($this->request->data);
$posts['id']['name']='kapil';
$this->set(compact('posts'));
}
}
list.ctp file
<?php echo json_encode(compact('posts')); ?>
view/js/default.ctp
<?php echo $scripts_for_layout; ?>
<?php echo $this->fetch('content'); ?>
when i try to access my function in browser then i get this output
url: http://localhost/project/users/list
{"posts":{"id":{"name":"aditya"}}}
This output is correct but should come in download file format. I don't know what is wrong here.
If you are trying to force download, your code must make use of Response object.
Here is an example taken from CsvExport Behavior:
public function export() {
$this->autoRender = false;
$modelClass = $this->modelClass;
$this->response->type('Content-Type: text/csv');
$this->response->download( strtolower( Inflector::pluralize( $modelClass ) ) . '.csv' );
$this->response->body( $this->$modelClass->exportCSV() );
}
So your code would look like this :
public function list() {
$this->autoRender = false;
$this->log("i got data in user add:");
$this->log($this->request->data);
$posts['id']['name']='kapil';
$this->set(compact('posts'));
$modelClass = $this->modelClass;
$this->response->type('Content-Type: application/json');
$this->response->download('list.json');
}
Hope this helps!
i am new to cake and using version 2.
i have models
hgcylinder.php
class HgCylinder extends AppModel {
//put your code here
var $name= "HgCylinder";
var $belongsTo = array('HgKeyGase');
}
hgkeygase.php
class HgKeyGase extends AppModel {
//put your code here
var $name= "HgKeyGase";
public $belongsTo = array(
'HgKeyColor' => array(
'className' => 'HgKeyColor',
'foreignKey' => 'hg_key_color_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
Controller HgCylindersController.php
<?php
class HgCylindersController extends AppController
{
var $name = "HgCylinders";
// var $scaffold;
function index()
{
$this->set('hey',$this->HgCylinder->find('all'));
}
public function edit($id = null) {
$this->HgCylinder->id = $id;
if ($this->request->is('post')) {
var_dump($this->request->data);
exit;
if ($this->HgCylinder->save($this->request->data)) {
$this->Session->setFlash(__('Cylinder has been updated successfull'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The cylinder could not be saved. Please, try again.'));
}
} else {
$this->request->data = $this->HgCylinder->read(null, $id);
}
$hg_key_gase_id = $this->HgCylinder->HgKeyGase->find('list');
$this->set(compact('hg_key_gase_id'));
}
}
?>
View : edit.ctp
<?php
echo $this->form->create('HgCylinder',array('action'=>'edit'));
echo $this->form->input('hg_key_gase_id',);
echo $this->form->input("capacityM3");
echo $this->form->input("weightEmpty");
echo $this->form->input("weightFilled");
echo $this->form->input("isFilled");
echo $this->form->end('Add');
?>
my problem is hg_key_gase_id is become select list with no options. if i changed the name to "hgKeyGas" in view and controller it shows the options from the hg_key_gases table. but on saving does not saving the value of hg_key_gase_id field in hg_cylinders table instead it stores null in this field.
second i want to know that it is necessary to have variable name passing to view from controller exactly same for as field in table.
try to stick to conventions.
so its
$hgKeyGases = $this->HgCylinder->HgKeyGase->find('list');
$this->set(compact('hgKeyGases'));
the pluralized form will be able to populate your select box (as documented in the cook book)
also use $this->Form->input() (note the capital F). $name is not necessary.
dont use read(), use find(first) instead. dont set the action (the form will post to itself by default).
and most importantly. ALWAYS respect the casing of files in your filesystem. especially if you plan on deploying on NIX systems (which are case sensitive).
so it would be HgCylinder.php and HgKeyGase.php as Model class files.
last tip: use baking (cake bake via shell console) to bake your crud files. this way you learn how its done the right way. it would have also answered your question itself by the way.
the documentation can be found here: http://book.cakephp.org/2.0/en/index.html
maybe you found an old outdated version, the 2.x one is the one you should have used.
In a download page for a blob from a database, how would I make it so that no other output is sent? Right now it's sending the header, debug info, and a footer. How do I make it so that none of that is sent, just for that view?
you can create an clear layout (e.g. empty.ctp ) in you layouts folder, only with
<?php echo $content_for_layout ?>
and then in you action where you're getting your blob data use that layout
$this->layout = 'empty.ctp';
and also to disable debugging, in your controllers use
Configure::write('debug',0);
if you're unable to create new layout you could try this.
$this->layout = null;
$this->render("view_name");
If you're using this to download files, you should use the Media view in cakePHP
http://book.cakephp.org/view/1094/Media-Views
$this->view = 'Media';
$params = array(
'id' => 'example.zip',
'name' => 'example',
'download' => true,
'extension' => 'zip', // must be lower case
'path' => APP . 'files' . DS // don't forget terminal 'DS'
);
CakePhp 2.3 users :
use Sending files from the Book
CakePhp 2.x users :
use '$this->viewClass' instead of '$this->view'
copy-paste ready full solution, right in any controller file:
<?php
public function download($file) {
$fsTarget = APP.WEBROOT_DIR.DS.'files'.DS.$file; // files located in 'files' folder under webroot
if (false == file_exists($fsTarget)){
throw new NotFoundException(__('Invalid file'));
}
$pathinfo = pathinfo($fsTarget);
$this->viewClass = 'Media';
$params = array(
'id' => $file,
'name' => $pathinfo['filename'], // without extension
'download' => true,
'extension' => $pathinfo['extension'], // must be lower case
'path' => dirname($fsTarget) . DS // don't forget terminal 'DS'
);
$this->set($params);
}
Hope this helps!