I’ve been stuck for a couple of months on an old cakephp 1.2 I don’t understand the logic of this framework and I am totally lost ....
I have a form to add/remove from my table called contract (see below)
As you can see, I want to be able to add 1 zone per form. I managed to create a table of performances with their own zone here.
array(
'files' => '',
'Contract' => array(
'name' => '',
'beggin' => '',
'end' => '',
'content1' => '<p><br></p>',
'content2' => '<p><br></p>',
'content3' => '',
'content4' => '',
'content5' => '',
'content7' => '',
'content8' => ''
),
'Zone' => array(
(int) 0 => array(
'zone_name' => 'Bat A',
'id_prestation' => array(
(int) 0 => '10',
(int) 1 => '11'
)
),
(int) 1 => array(
'zone_name' => 'Bat B',
'id_prestation' => array(
(int) 0 => '10',
(int) 1 => '12',
(int) 2 => '13',
(int) 3 => '14'
)
)
)
)
so far, I have no difficulties.
the relation between the tables Contract and Prestation is a $hasAndBelongsToMany
here is my form :
My problem is that when the form is submitted, the data are not saved.
Could someone please explain what is it that i’m doing wrong and explain what i should do plz ?
Below is all my codes that you may need to get what i’m trying to explain:
<?php
class Contract extends AppModel {
public $hasMany = array('Document', 'Statu');
public $hasAndBelongsToMany = array('Prestation');
public $belongsTo = array('Client', 'Residence'); public function contracts() {
return $this->find(
'all',
array(
'conditions' => array(
'Contract.is_active' => false
)
)
);
}
}
My function of adding a new contract:
public function add() { if ($this->request->is(array('post', 'put')))
{
// TODO: Rewrite or remove the two next conditions when client and residences will be re-implemented.
// SUPPRESSION DU CLIENT
if (!empty($this->request->data['Contract']['client_id'])) {
unset($this->request->data['Client']);
} else {
unset($this->request->data['Contract']['client_id']);
} // SUPPRESSION DE LA RESIDENCE
if (!empty($this->request->data['Contract']['residence_id'])) {
unset($this->request->data['Residence']);
} else {
unset($this->request->data['Contract']['residence_id']);
} // AJOUT DU STATUS
// AJOUT DES PRESTATIONS
if (!empty($this->request->data['Zone'])) {
foreach ($this->request->data['Zone'] as $key => $zone) {
$this->request->data['Zone'][$key] = $zone;
}
}
$this->request->data['Statu'] = array( 0 => array( 'status' => 'proposed' ) ); // AJOUT DU CONTRAT
$this->Contract->create(); $this->request->data['Contract']['is_active'] = false;
if ($this->Contract->saveAll($this->request->data))
{
$this->Session->setFlash(__('Contrat enregistré.'));
return $this->redirect(array('controller' => 'contracts', 'action' => 'index'));
} $this->Session->setFlash(__("Impossible d'enregistrer le devis."));
}
else
{
$this->set( 'clients', $this->Client->find('list') );
$this->set( 'residences', $this->Residence->find('list') );
$this->set( 'prestations', $this->Prestation->find('list') );
}
}
Thank you for your help
Related
I've got the following models:
Run->hasMany ActualResult
ActualResult belongs to Status
When I view an ActualResult, Cake gets the corresponding Status without straight out of the box.
When I view a Run, I want to paginate the ActualResults. I have managed to get this to almost work with the following code in RunsController::view():
public function view($id = null) {
if (!$this->Run->exists($id)) {
throw new NotFoundException(__('Invalid run'));
}
$this->Run->contain ( 'Pack', 'User', 'Status');
$options = array('conditions' => array('Run.' . $this->Run->primaryKey => $id));
$run = $this->Run->find('first', $options);
$this->set('run', $run);
// Paginate the ActualResults
$this->paginate = array(
'contain' => array('Status'),
'order' => 'ActualResult.format',
'limit'=>5 ,
'conditions' => array('ActualResult.run_id' => $id)
);
$actualResults = $this->Paginator->paginate('ActualResult');
$this->set('actualResults',$actualResults);
}
The problem is that I get a warning:
Warning (512): Model "ActualResult" is not associated with model "Status" [CORE\Cake\Model\Behavior\ContainableBehavior.php, line 343
Something v. similar works for me in another model association, and as mentioned view() in ActualResultController works fine, so I am stumped.
Can anyone help?
Here are the model assocations:
In Run.php:
public $hasMany = array(
'ActualResult' => array(
'className' => 'actual_result',
'foreignKey' => 'run_id',
'dependent' => true,
'finderQuery' => 'SELECT ActualResult.*, Txn.name, Status.name FROM actual_results AS ActualResult, txns as Txn, codes AS Status WHERE ActualResult.run_id = {$__cakeID__$} and Txn.id = ActualResult.txn_id and (Status.code = ActualResult.status and Status.code_type = "ARS");'
)
);
In ActualResult.php
public $belongsTo = array(
'Run' => array(
'className' => 'Run',
'foreignKey' => 'run_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Status' => array(
'class`enter code here`Name' => 'Code',
'foreignKey' => 'status',
'conditions' => 'code_type = "ARS"',
'fields' => '',
'order' => ''
)
);
I had this validation rule for a long time and it always used to work correctly, but not any more.
public $validate = array(
'email'=>array(
'email'=>array(
'rule'=>array('email', true),
'message'=>'E-mail is not correct'
),
'isUnique'=>array(
'rule'=>'isUnique',
'message'=>'This email adddress is already in use'
),
'notEmpty'=>array(
'rule'=>'notEmpty',
'message'=>'Insert email address'
)
)
I have been testing many possible ways, but none of them seem to work. Any help is much appreciated.
Here is the add function from the controller:
public function add() {
if ($this->request->is('post')) {
if( $this->request->data[ 'User' ][ 'email' ] != $this->data[ 'User' ][ 'email_confirmation' ] ) {
$this->User->invalidate( 'email_confirmation', __('Emails dont match'));
}else{
//generate password
$generatedPassword = $this->getRandomString(6);
$this->request->data['User']['password'] = $generatedPassword;
if ($this->User->save($this->request->data)) {
$name = $this->request->data['User']['name'];
$email = $this->request->data['User']['email'];
$password = $generatedPassword;
$this->Session->setFlash(__('User has been saved'), 'positive_notification');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('User has not been saved'), 'negative_notification');
}
}}}
And here is the beforeSave()
public function beforeSave($options = Array()){
if(isset($this->data['User']['password'])){
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
}
if(isset($this->data[$this->alias]['password1'])){
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password1']);
}
return true;
}
Here is the query that is being executed while saving:
INSERT INTO `schedule`.`users` (`employee_nr`, `name`, `surname`, `email`, `phone`, `address`, `post_nr`, `city`, `role`, `company_id`, `password`) VALUES ('1', 'Name', 'Surname', 'email#email.com', '11223344', '', '', '', 'employee', 54, '389be16c83bf2e65a64f727465ec0c37a77552a5')
Test isUnique by using in you controller to see why it is not working. isUnique validation rule uses isUnique model method.
try this
public $validate = array(
'email' => array(
'rule1' => array(
'rule' => 'email',
'message' => 'Please enter a valid email address.'
),
'rule2' => array(
'rule' => 'isUnique',
'message' => 'That email address exists.'
)
),
How can I keep the same checkboxes checked after submit? All the other input fields on the form automatically keeps the values. I thought this would also go for checkboxes, but nope.
echo $this->Form->input('type_id', array(
'multiple' => 'checkbox',
'options' => array(
'1' => 'Til salgs',
'2' => 'Ønskes kjøpt',
'3' => 'Gis bort'
),
'div' => false,
'label' => false
));
I believe this can be done in the controller, but how?
Edit:
Since I posted this question I've changed to CakeDcs Search plugin, because I've gotten this to work with that before. Still... I can't get it to work this time.
Adding model and controller code:
AppController
public $components = array('DebugKit.Toolbar',
'Session',
'Auth' => array(
'loginAction' => '/',
'loginRedirect' => '/login',
'logoutRedirect' => '/',
'authError' => 'Du må logge inn for å vise denne siden.',
'authorize' => array('Controller'),
),
'Search.Prg'
);
public $presetVars = true; //Same as in model filterArgs(). For Search-plugin.
AdsController
public function view() {
$this->set('title_for_layout', 'Localtrade Norway');
$this->set('show_searchbar', true); //Shows searchbar div in view
$this->log($this->request->data, 'debug');
//Setting users home commune as default filter when the form is not submitted.
$default_filter = array(
'Ad.commune_id' => $this->Auth->user('User.commune_id')
);
$this->Prg->commonProcess(); //Search-plugin
$this->paginate = array(
'conditions' => array_merge($default_filter, $this->Ad->parseCriteria($this->passedArgs)), //If Ad.commune_id is empty in second array, then the first will be used.
'fields' => $this->Ad->setFields(),
'limit' => 3
);
$this->set('res', $this->paginate());
}
Model
public $actsAs = array('Search.Searchable');
public $filterArgs = array(
'search_field' => array('type' => 'query', 'method' => 'filterSearchField'),
'commune_id' => array('type' => 'value'),
'type_id' => array('type' => 'int')
);
public function filterSearchField($data) {
if (empty($data['search_field'])) {
return array();
}
$str_filter = '%' . $data['search_field'] . '%';
return array(
'OR' => array(
$this->alias . '.title LIKE' => $str_filter,
$this->alias . '.description LIKE' => $str_filter,
)
);
}
/**
* Sets the fields which will be returned by the search.
*
* #access public
* #return array Database table fields
* #author Morten Flydahl
*
*/
public function setFields() {
return array(
'Ad.id',
'Ad.title',
'Ad.description',
'Ad.price',
'Ad.modified',
'User.id',
'User.first_name',
'User.middle_name',
'User.last_name',
'User.link',
'User.picture_url',
'Commune.name',
'Type.id',
'Type.name'
);
}
You have to set manually the selected option of the input, as an array with "keys = values = intval(checkbox id)"
I cannot explain why this format, but this is the only way I get it to work.
Here is my code:
echo $this->Form->create('User');
// Read the submitted value
$selected = $this->Form->value('User.Albums');
// Formats the value
if (empty($selected)) {
$selected = array(); // avoid mess
} else {
$selected = array_map('intval', $selected);
$selected = array_combine ($selected, $selected);
}
// Renders the checkboxes
echo $this->Form->input('Albums',array(
'type' => 'select',
'multiple' => 'checkbox',
'options' => $albums, // array ( (int)id => string(label), ... )
'selected' => $selected, // array ( (int)id => (int)id, ... )
));
Hope this helps.
++
I have got two Models in CakePHP 2.2.1:
class Episode extends AppModel {
public $hasAndBelongsToMany = array(
'Tags' => array('className' => 'Tag')
);
}
and
class Tag extends AppModel {
public $hasAndBelongsToMany = array(
'Episode' => array('className' => 'Episode')
);
}
And I want to insert an Episode and a Tag at the same time and link them to each other. From the documentation I got that this would be the right code which I execute inside a controller method:
$this->Tag->create();
$this->Tag->save(array(
'name' => 'Test Tag'
));
$tagid = $this->Tag->getInsertID();
var_dump($tagid); // works
$this->Episode->create();
$this->Episode->save(array(
'Episode' => array(
'title' => 'Test with Tag'
),
'Tags' => array(
'Tag' => array($tagid)
)
));
I get no error message and both records are created, but there is no row inserted into the episodes_tags table. CakePHP does these queries:
Nr Query Err Aff Rws Took (ms)
1 INSERT INTO `pottcast`.`tags` (`name`) VALUES ('Test Tag') 1 1 0
2 INSERT INTO `pottcast`.`episodes` (`title`) VALUES ('Test with Tag') 1 1 0
3 SELECT `EpisodesTag`.`tag_id` FROM `pottcast`.`episodes_tags` AS `EpisodesTag` WHERE `EpisodesTag`.`episode_id` = 9 0 0 0
What did I do wrong?
Try This :
In Episode Model:
public $hasAndBelongsToMany = array(
'Tag' => array(
'className' => 'Tag',
'joinTable' => 'episodes_tags',
'foreignKey' => 'episode_id',
'associationForeignKey' => 'tag_id',
'unique' => 'keepExisting',
));
In your controller:
$this->Episode->save(array(
'Episode' => array(
'title' => 'Test with Tag'
),
'Tag' => array(
'Tag' => $tagid
)
));
Ask if not work for you.
I have a a controller referral_medium_controller.php with the following content
<?php
class ReferralMediumsController extends AppController
{
var $name = 'ReferralMediums';
function admin_index()
{
//Checking that only super administrators can actually add new interest options
if ($this->Auth->user('user_type_id') != ConstUserTypes::Admin) {
$this->cakeError('error404');
}
$this->pageTitle = __l('Referral Mediums');
$this->ReferralMediums->recursive = 0;
$this->set('ReferralMediums', $this->paginate());
}
function admin_view($id = null)
{
//Checking that only super administrators can actually add new interest options
if ($this->Auth->user('user_type_id') != ConstUserTypes::Admin) {
$this->cakeError('error404');
}
$this->pageTitle = __l('Referral Mediums?');
if (is_null($id)) {
$this->cakeError('error404');
}
$referralMedium = $this->ReferralMediums->find('first', array(
'conditions' => array(
'ReferralMedium.id = ' => $id
) ,
'fields' => array(
'ReferralMedium.id',
'ReferralMedium.created',
'ReferralMedium.modified',
'ReferralMedium.referral_medium',
'ReferralMedium.is_active',
) ,
'recursive' => -1,
));
if (empty($referralMedium)) {
$this->cakeError('error404');
}
$this->pageTitle.= ' - ' . $referralMedium['ReferralMedium']['id'];
$this->set('ReferralMediums', $referralMedium);
}
function admin_add()
{
//Checking that only super administrators can actually add new interest options
if ($this->Auth->user('user_type_id') != ConstUserTypes::Admin) {
$this->cakeError('error404');
}
$this->pageTitle = __l('Add Referral Medium');
if (!empty($this->data)) {
$this->ReferralMedium->create();
if ($this->ReferralMedium->save($this->data)) {
$this->Session->setFlash(__l('Referral Medium has been added') , 'default', null, 'success');
$this->redirect(array(
'action' => 'index'
));
} else {
$this->Session->setFlash(__l('Referral Medium could not be added. Please, try again.') , 'default', null, 'error');
}
}
}
function admin_edit($id = null)
{
//Checking that only super administrators can actually add new interest options
if ($this->Auth->user('user_type_id') != ConstUserTypes::Admin) {
$this->cakeError('error404');
}
$this->pageTitle = __l('Edit Referral Medium');
if (is_null($id)) {
$this->cakeError('error404');
}
if (!empty($this->data)) {
if ($this->ReferralMedium->save($this->data)) {
$this->Session->setFlash(__l('Referral Medium has been updated') , 'default', null, 'success');
$this->redirect(array(
'action' => 'index'
));
} else {
$this->Session->setFlash(__l('Referral Medium could not be updated. Please, try again.') , 'default', null, 'error');
}
} else {
$this->data = $this->ReferralMedium->read(null, $id);
if (empty($this->data)) {
$this->cakeError('error404');
}
}
$this->pageTitle.= ' - ' . $this->data['ReferralMedium']['id'];
}
function admin_delete($id = null)
{
//Checking that only super administrators can actually add new interest options
if ($this->Auth->user('user_type_id') != ConstUserTypes::Admin) {
$this->cakeError('error404');
}
if (is_null($id)) {
$this->cakeError('error404');
}
if ($this->ReferralMedium->del($id)) {
$this->Session->setFlash(__l('Referral Medium deleted') , 'default', null, 'success');
$this->redirect(array(
'action' => 'index'
));
} else {
$this->cakeError('error404');
}
}
}
?>
a model referral_model.php with the following content
<?php
class ReferralMedium extends AppModel
{
var $name = 'ReferralMedium';
var $useTable="referral_mediums";
//$validate set in __construct for multi-language support
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $hasOne = array(
'UserProfile' => array(
'className' => 'UserProfile',
'foreignKey' => 'referral_medium_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => ''
)
);
var $hasMany = array(
'UserProfile' => array(
'className' => 'UserProfile',
'foreignKey' => 'referral_medium_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
function __construct($id = false, $table = null, $ds = null)
{
parent::__construct($id, $table, $ds);
$this->validate = array(
'referral_medium' => array(
'rule' => 'notempty',
'allowEmpty' => false,
'message' => __l('Required')
) ,
);
}
}
?>
a add view referral_mediums/admin_add.ctp with the following code
<?php /* SVN: $Id: $ */ ?>
<div class="referralMedium form">
<?php echo $form->create('ReferralMedium', array('class' => 'normal'));?>
<fieldset>
<h2><?php echo __l('Add Referral Medium');?></h2>
<?php
echo $form->input('referral_medium');
echo $form->input('is_active');
?>
</fieldset>
<div class="submit-block clearfix">
<?php echo $form->submit(__l('Add'));?>
</div>
<?php echo $form->end();?>
</div>
Now all works fine except if I click on the add button in the add form I get redirected to admin/referral_media/add instead of admin/referral_medium/add and I can't find the problem. I would be greatful I someone could help me with this.
the plural of medium is media, not mediums. The controller name is plural, so it's referral_media. So you'll need to change your controller name (and the file name).
Or change Config/bootstrap.php so it won't make controller names plural anymore.