I simply want to have in my function (add) the file upload process in my cake application. i have tried various tutorial across the web bur I could reach the solution to my problem. I am new to cake and I dont want to reinvent the wheel I just want to learn based on what I have implemented so far. I am truly grateful for your help.
add.ctp
<?php echo $this->Form->create('Movie'); ?>
<?php echo __('Add Movie'); ?>
<?php
echo $this->Form->hidden('movie_id');
echo $this->Form->input('title');
echo $this->Form->input('date', array(
'type' => 'date',
'label' => 'Date',
'empty' => false,
'dateFormat' => 'DMY',
'minYear'=>'1990',
'maxYear'=>date('Y'),
));
echo $this->Form->input('description');
echo $this->Form->input('file', array('type' => 'file'));?>
<?php echo $this->Form->end(__('Submit')); ?>
THE CONTROLLER
public function add() {
if ($this->request->is('post')) {
$this->Movie->create();
}
if ($this->Movie->save($this->request->data))
{
$this->Session->setFlash(__('The movie has been created'));
$this->redirect (array('action'=>'index'));
}
}
Table structure for table movies
CREATE TABLE IF NOT EXISTS `movies` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`movie_id` int(11) NOT NULL,
`title` varchar(100) NOT NULL,
`file` varchar(200) NOT NULL,
`date` date NOT NULL,
`description` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `movie_id` (`movie_id`),
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
Create Model located at /app/Model/Movies.php
<?php
class Movie extends AppModel {
}
?>
Create Controller in app/Controller/Movies.php
<?php
class MoviesController extends AppController {
public function add() {
if ($this->request->is('post')) {
$maxId = $this->Movie->find('first', array(
'order' => 'movie_id DESC',
'fields' => array('Movie.movie_id')
));
$maxId = (isset($maxId['Movie']['movie_id'])? $maxId['Movie']['movie_id'] : 0);
$this->request->data['Movie']['movie_id'] = $maxId+1;
$folderToSaveFiles = WWW_ROOT . 'img/uploads/' ;
if(!empty($this->request->data['Movie']['file']))
{
$file = $this->request->data['Movie']['file'];
$ext = substr(strtolower(strrchr($file['name'], '.')), 1);
$arr_ext = array('jpg', 'jpeg', 'gif','png');
if(in_array($ext, $arr_ext))
{
$newFilename = $this->request->data['Movie']['title'].'.'.$ext;
$result = move_uploaded_file( $file['tmp_name'], $folderToSaveFiles . $newFilename );
$this->request->data['Movie']['file'] = $newFilename;
$this->Movie->save($this->request->data);
//debug($this->request->data);
}
}
}
}
Note : Create a directory in app/webroot/img/uploads/ & upload directory must be write permission.
Related
I'm a beginner. I am using CakeDC ratings to make a star rating in my site. I managed to make it work but it is displaying radio choices.
And it show me error:
Undefined variable: item
and After pressing "Rate", the url changes to avis/post/view/redirect:1
I download the plugin and I unzip in C:\wamp\www\avis\app\Plugin
after I write CakePlugin::load('Ratings') in app/Config/bootstrap.php my database is
CREATE TABLE IF NOT EXISTS `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
CREATE TABLE IF NOT EXISTS `ratings` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` char(36) NOT NULL DEFAULT '',
`foreign_key` char(36) NOT NULL DEFAULT '',
`model` varchar(100) NOT NULL DEFAULT '',
`value` float NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `rating` (`user_id`,`model`,`foreign_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
in Post Model
public $hasMany = array(
'Rating' => array(
'className' => 'Rating',
'foreignKey' => 'foreign_key',
'dependent' => false,
)
);
in PostController
public $components = array('Paginator', 'Flash', 'Session','Ratings.Ratings');
public $actsAs = array('Ratings.Ratable');
public function index() {
$this->Post->recursive = 0;
$this->set('posts', $this->Paginator->paginate());
}
public function view($id = null) {
if (!$this->Post->exists($id)) {
throw new NotFoundException(__('Invalid post'));
}
$options = array('conditions' => array('Post.' . $this->Post->primaryKey => $id));
$this->set('post', $this->Post->find('first', $options));
}
in view
<h2><?php echo __('Post'); ?></h2>
<dl>
<dt><?php echo __('Id'); ?></dt>
<dd>
<?php echo h($post['Post']['id']); ?>
</dd>
<dt><?php echo __('Title'); ?></dt>
<dd>
<?php echo h($post['Post']['title']); ?>
</dd>
<?php
echo $this->Rating->display(array(
'item' => $post['Post']['id'],
'type' => 'radio',
'stars' => 5,
'value' => $item['rating'],
'createForm' => array(
'url' => array(
$this->passedArgs, 'rate' => $item['id'],
'redirect' => true
)
)
));
?>
</dl>
</div>
<script>
$('#ratingform').stars({
split:2,
cancelShow:false,
callback: function(ui, type, value) {
ui.$form.submit();
}
});
</script>
First Download Jquery Raty Js plugin From : https://github.com/wbotelhos/raty
Include js,css into your view
<div class="jrating" data-score="5"></div>
<script>
$('.jrating').raty({ score: function() {return $(this).attr('data-score');} });
</script>
This will create a hidden text field when you post the form
On controller :
$rating = $this->data['score'];
Now you can save rating in your table
i have 2 table:
tickets :
`CREATE TABLE IF NOT EXISTS `tickets` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nom_model` varchar(32) NOT NULL,
`is_active` tinyint(1) NOT NULL,
`date_modif` date NOT NULL,
PRIMARY KEY (`id`));`
details:
`CREATE TABLE IF NOT EXISTS `details` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ticket_id` int(11) NOT NULL,
`nom` varchar(32) NOT NULL,
`text` varchar(32) NOT NULL,
`taille` enum('8','9','10','11','12','13','14','15','16','17','18','19','20') NOT NULL,
`police` enum('Impact','courier new','times new roman','comic sans ms') NOT NULL,
`bold` int(2) NOT NULL,
`italic` int(2) NOT NULL,
PRIMARY KEY (`id`),
KEY `ticket_id` (`ticket_id`));`
the tickets have 11 zone (msg_acc, nom_buro,heure, date ....)
which are the attributes of fields nom in table details
and in one zone have (text, police, bold, italic)
therefore must save 11 rows in table (details)
i want to creat form (contains nom model in table ticket and save 11 rows in table details with foreign key ticket_id in table details is the new ticket create (nom_model) ):
I create form save 11 rows market is well but th foreing key not worked
nom_model not save in table (tickets) and the 11 rows save with ticket_id equal 0
the code in model Ticket.php
<?php
class Ticket extends AppModel
{
var $name = 'Ticket';
public $displayField='id';
public $hasMany = array(
'Detail'
);
}
?>
the code in model Detail.php
<?php
class Detail extends AppModel{
var $name = 'Detail';
public $belongsTo = array(
'Ticket'
);
}
?>
the code in controller detailsController.php
$this->set('title_for_layout', __('Add Details'));
$tickets= $this->Detail->Ticket->find('list');
if (!empty($this->request->data)) {
if($this->Detail->saveAll($this->request->data['Detail'])){
$this->Session->setFlash(__('The Model has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The Model could not be saved. Please, try again.'));
}
$this->redirect(array('action' => 'index'));
}
$this->set('tickets', $tickets);
th code in view add.ctp
<?php echo $this->form->create('Detail');?>
<fieldset>
<legend>Add New Detail</legend>
<?php
echo $this->form->input('Ticket.$i.nom_model');//not working
for($i=0;$i<$count;$i++){
echo $this->form->input("Detail.$i.name");
echo $this->form->input("Detail.$i.text");
echo $this->form->input("Detail.$i.taille");
echo $this->form->input("Detail.$i.police");
echo $this->form->input("Detail.$i.bold");
echo $this->form->input("Detail.$i.italic");
$this->form->hidden('ticket_id');} ?> </fieldset>
<?php echo $this->form->end('Submit');?>
You are saving your request data by saveAll without your associated Ticket.
The associated data of Ticked is located in $this->request->data['Ticket'] and will be ignored:
//(Line 4 of your posted controller)
$this->Detail->saveAll($this->request->data['Detail'])
Update:
Your $this->request->data should have the following structure:
Array
(
[Ticket] => Array
(
[id] => 1
...
)
[Detail] => Array
(
[0] => Array
(
[ticket_id] => 1
...
)
[1] => Array
(
[ticket_id] => 1
...
)
..........
)
)
Adapt your View, generating that datafield and you can try to save your posted data via $this->Detail->saveAll($this->request->data)
Update
Your View in basic should look like the following:
<fieldset>
<legend>Add New Detail</legend>
<?php
echo $this->form->input("Ticket.nom_model");
echo $this->form->hidden("Ticket.id", array('value' => '1'));
for($i=0;$i < $count;$i++){
echo $this->form->input("Detail.$i.name");
echo $this->form->input("Detail.$i.text");
echo $this->form->input("Detail.$i.taille");
echo $this->form->input("Detail.$i.police");
echo $this->form->input("Detail.$i.bold");
echo $this->form->input("Detail.$i.italic");
echo $this->form->hidden("Detail.$i.ticket_id", array('value' => '1'));} ?>
<?php echo $this->form->end('Submit');?>
</fieldset>
This is an example view, that references Detail to Ticket via Ticked.id = 1
Update:
You should define the foreign key from Detail to Ticket in your Models/Detail.php:
public $belongsTo = array(
'Ticket' => array(
'className' => 'Ticket',
'foreignKey' => 'ticket_id'
)
);
New to Cake, and trying to set up model associations. I'm creating an execution planner, to be used by multiple teams, aka 'groups' where the base unit of a plan is an 'event'. Each event is owned by one team, but it can have many supporting teams.
When I use $scaffold in the controllers, the model associations work as expected and when adding a new event I get a select box with all the groups to select who owns an event. However, when I bake the controller using console, the select box for group_id is blank. I've included the baked add() code from the controller, and from the baked add view. I also tried debug($this) in add.ctp, and found that the list of groups is indeed being passed to the view. I'm thus mostly confused about why it works with $scaffold, but not otherwise.
Any advice or pointers in the right direction would be greatly appreciated.
Tables:
CREATE TABLE IF NOT EXISTS `events` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`group_id` int(5) NOT NULL COMMENT 'Group that owns event',
`version` int(5) NOT NULL,
`type` varchar(5) NOT NULL,
`stime` time NOT NULL,
`etime` time NOT NULL,
`description` text NOT NULL,
`comment` text NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `events_groups` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`event_id` int(5) NOT NULL,
`group_id` int(5) NOT NULL,
PRIMARY KEY (`id`)
) ;
CREATE TABLE IF NOT EXISTS `groups` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`code` varchar(4) NOT NULL,
`name` varchar(25) NOT NULL,
`liveversion` int(4) NOT NULL,
`lastupdated` date NOT NULL,
PRIMARY KEY (`id`)
);
Models:
Event:
public $belongsTo = array(
'Prigroup' => array(
'className' => 'Group',
'foreignKey' => 'group_id',
)
);
public $hasAndBelongsToMany = array(
'Secgroup' => array(
'className' => 'Group',
'joinTable' => 'events_groups',
'foreignKey' => 'event_id',
'associationForeignKey' => 'group_id',
)
);
Group:
public $hasMany = array(
'Prievent' => array(
'className' => 'Event',
'foreignKey' => 'group_id',
)
);
public $hasAndBelongsToMany = array(
'Secevent' => array(
'className' => 'Event',
'joinTable' => 'events_groups',
'foreignKey' => 'group_id',
'associationForeignKey' => 'event_id',
)
);
EventsController Snippet:
public function add() {
if ($this->request->is('post')) {
$this->Event->create();
if ($this->Event->save($this->request->data)) {
$this->Session->setFlash(__('The event has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The event could not be saved. Please, try again.'));
}
}
$prigroups = $this->Event->Prigroup->find('list');
$secgroups = $this->Event->Secgroup->find('list');
$this->set(compact('prigroups', 'secgroups'));
}
Add view:
<?php echo $this->Form->create('Event'); ?>
<fieldset>
<legend><?php echo __('Add Event'); ?></legend>
<?php
echo $this->Form->input('group_id');
echo $this->Form->input('version');
echo $this->Form->input('type');
echo $this->Form->input('stime');
echo $this->Form->input('etime');
echo $this->Form->input('description');
echo $this->Form->input('comment');
echo $this->Form->input('Secgroup');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
Add HTML Output
<div class="input select"><label for="EventGroupId">Group</label><select name="data[Event][group_id]" id="EventGroupId">
</select></div>
Can u try something for me please? Rename the $prigroups variable to "groups" and pass it to the view. See if this is working. Otherwise use this one with your old code:
echo $this->Form->input(
'group_id',
array(
'options' => $prigroups
)
);
I also recommend you to use camel case for all those PriGroups and SecGroups. Those are two words in english so camel case advisable.
Greetings
func0der
I don't know why this doesn't work (I am using CakePHP 2.1 and also tried 2.0):
Here is Model
class User extends AppModel
{
public $validate = array('username' => array('rule' => 'email'));
}
Here is Controller
class UsersController extends AppController
{
function index()
{
$this->set('users', $this->User->find('all') );
}
function add()
{
if (!empty($this->request->data))
{
if ($this->User->save($this->request->data))
{
$this->Session->setFlash('User has been registered.');
$this->redirect(array('action' => 'index'));
}
}
}
}
Here is add View
<h1>Add Post</h1>
<?php
echo $this->Form->create('User');
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->end('Register');
?>
And it validates whatever I write... And it should check if username is email...
It's impossible! It has to work! - but it doesn't...
I also checked it with cake php 2.0 and it still does't work - please help, it is so simple i has to work...
Maybe something with my db table is wrong???
CREATE TABLE `users` (
`id` int(10) unsigned not null auto_increment,
`username` varchar(50),
`password` varchar(50),
`created` datetime,
`modified` datetime,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=9;
This is very strange - in my app folder I only add 'UserModel.php', 'UserController.php' and 'add.ctp', and a db config - all that I wrote above - and validation doesn't work!!!
I think the $validate array is not declared correctly.
Try this:
$validate = array('username' => array(
'email' => array(
'rule' => array('email')
)));
or this:
$validate = array('username' => 'email');
See http://book.cakephp.org/2.0/en/models/data-validation.html
Ok I know what is wrong:
my model filename was called 'UserModel.php' and it should be 'User.php'
At start of file 'User.php' I had to put 'App::uses('AppModel', 'Model');'
You should write in your controller ( UserController )
($this-User->set($this->request->data)
before the function validates Like you see;
function add()
{
if (!empty($this->request->data))
{ $this->User->set($this->request->data);
if ($this->User->validates())
{ $this->User->save($this->request->data)
$this->Session->setFlash('User has been registered.');
$this->redirect(array('action' => 'index'));
}
}
}
O.k... this is what I do (also changing the username to an email)
$components = array('Auth' => array('authenticate' => array('Form' => array('fields' => array('username' => 'email', 'password' => 'password')))), 'Email');
This works. In CakePHP 1.3 you had to specify both the username (email) and the password. So when I moved to CakePHP 2.1 I continued doing the same thing and had no problems with the validation.
you can see all that you need here: Cookbook
I was wondering if someone could help me out.
I am using cakePHP 1.3 and I am having trouble getting the edit view to update the main Model and a hasOne related Model. I am fairly positive this has to do with my setup of the edit.ctp view. I am using the media plugin which I got working on another model, so I don't believe that has anything to do with that. Specifically I am working on getting the Media Plugin, Monolithic Attachment Model with a hasOne relationship working.
I have checked out the cake docs
http://book.cakephp.org/#!/view/1032/Saving-Related-Model-Data-hasOne-hasMany-belongsTo read the majority of the docs in the Media Plugin this like is the most relevant
https://github.com/davidpersson/media/blob/next/docs/RECIPES
and spent extensive time searching google.
Any help would be appreciated.
Thanks,
James
Model - client.php
<?php
class Client extends AppModel {
var $name = 'Client';
var $displayField = 'name';
var $actsAs = array(
'Media.Transfer',
'Media.Coupler',
'Media.Generator'
);
[...]
var $hasOne = array(
'Logo' => array(
'className' => 'Attachment',
'foreignKey' => 'foreign_key',
'conditions' => array('Logo.model' => 'Client'),
'dependent' => true,
));
[...]
?>
Controller - clients_controller.php
<?php
class ClientsController extends AppController {
var $name = 'Clients';
[...]
function edit($id = null) {
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid client', true));
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
if ($this->Client->saveAll($this->data, array('validate'=>'first') )) {
$this->Session->setFlash(__('The client has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The client could not be saved. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->Client->recursive = 0;
$this->data = $this->Client->read(null, $id);
}
$statuses = $this->Client->Status->find('list');
$this->set(compact('statuses'));
}
[...]
?>
View - edit.ctp
<h1><?php __('Edit Clients');?></h1>
<div class="clients form">
<?php echo $this->Form->create('Client', array('type' => 'file'))."\n";?>
<fieldset>
<?php
echo $this->Form->input('Client.id')."\n";
echo $this->Form->input('Client.name')."\n";
echo $this->Form->input('Client.address1')."\n";
echo $this->Form->input('Client.address2')."\n";
[...]
echo $form->input('Logo.id')."\n";
echo $form->input('Logo.file', array('type' => 'file'))."\n";
echo $form->hidden('Logo.foreign_key')."\n";
echo $form->hidden('Logo.model', array('value' => 'Client'))."\n";
?>
</fieldset>
<?php echo $this->Form->end(__('Submit', true));?>
</div>
clients sql
CREATE TABLE `clients` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`address1` varchar(255) NOT NULL,
`address2` varchar(255) NOT NULL,
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`)
)
attachments sql
CREATE TABLE `attachments` (
`id` int(10) NOT NULL auto_increment,
`model` varchar(255) NOT NULL,
`foreign_key` int(10) NOT NULL,
`dirname` varchar(255) default NULL,
`basename` varchar(255) NOT NULL,
`checksum` varchar(255) NOT NULL,
`group` varchar(255) default NULL,
`alternative` varchar(50) default NULL,
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`)
)
var $hasOne = array(
'Logo' => array(
'className' => 'Attachment',
'foreignKey' => 'foreign_key', // 'foreign_key' ? is that a name for your fk?
'conditions' => array('Logo.model' => 'Client'),
'dependent' => true,
));
here you haven't defined the foreign_key which binds your logo to your client. look up in your database for the foreign key and put it's name here.
Thanks for all the responses. I finally got it working. It appears that for some reason the saveAll was causing me grief. When I saved the Client then saved the Logo everything worked.
I posted the code below.
Controller Code
function edit($id = null) {
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid client', true));
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
$client = $this->Client->save($this->data);
if (!empty($client)) {
$this->data['Logo']['foreign_key'] = $this->Client->id;
$this->data['Logo']['model'] = 'Client';
$this->Session->setFlash(__('The client has been saved', true));
$this->Client->Logo->save($this->data);
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The client could not be saved. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->Client->recursive = 0;
$this->data = $this->Client->read(null, $id);
}
$statuses = $this->Client->Status->find('list');
$this->set(compact('statuses'));
}