Cakephp foreach data for options in select (form) - cakephp

in my project I have database
"Products" hasAndBelongsToMany "Sizes"
"ProductsSize" belongsTo "Products"
"ProductSize" belongsTo "Size"
In ProductsSize, one product_id may have many size_id.
hence, i want to do a form that have a select type input that list down all the size_id where the product_id = $id.
What i have done is:
in controller:
$size = $this->Product->ProductsSize->find('all', array(
'conditions' => array('ProductsSize.product_id' => $id),
'fields' => array('ProductsSize.size_id'),
));
in view:
<?php echo $this->form->create('Cart', array('action' => 'add')); ?>
<?php echo $this->form->input('size_id', array('label' => 'Size', 'options' => $size)); ?>
then i got error: Undefined index: ProductsSize
but when i put foreach, the data shown:
<?php foreach ($size_apparel as $size): ?>
<?php echo $size['ProductsSize']['size_id'];?><br/>
<?php endforeach; ?>
can anyone please help me to do the foreach in options.

The problem is that you are using an invalid array for the options. You are requesting:
$size = $this->Product->ProductsSize->find('all', array(
'conditions' => array('ProductsSize.product_id' => $id),
'fields' => array('ProductsSize.size_id'),
));
What you should be requesting is:
$size = $this->Product->ProductsSize->find('list', array(
'conditions' => array('ProductsSize.product_id' => $id),
));
This will return the options for the form field in the format it expects which is:
array(
{id} => {size},
{id} => {size},
{id} => {size},
{id} => {size},
...
)

I think you meant to say
<?php echo $this->form->input('size_id', array('label' => 'Size', 'options' => $size)); ?>
note 'options' instead of 'value'

$List = Set::classicExtract($size, '{n}.ProductSize.product_id');
$List will contain key value(ProductSize.product_id) pair.
OR you can change your query as
$size = $this->Product->ProductSize->find('list', array(
'conditions' => array('ProductSize.product_id' => $id),
));
Hope it will work for you

Related

Show posts that have a with a certain meta_key value or not meta_key at all

I've got this loop where I need to display all the titles of posts that have a certain meta_value, or that and don't have the meta_key 'the_status'.
My posts currently use the meta_key called 'the_status' and can have either of these meta_key values:
helping
not_helping
finished_helping
...or a post may not even have the meta_key 'the_status' at all.
Here's what I have:
<?php
$the_query = array(
'posts_per_page' => -1,
'author' => $current_user->ID,
'post_status' => 'publish',
'meta_key' => 'the_status',
'meta_value' => array('helping')
);
$help_posts = new WP_Query($the_query);
while($help_posts->have_posts()) : $help_posts->the_post();
?>
<p><?php the_title(); ?></p>
<?php
endwhile;
?>
This obviously only gives me titles of posts that have a meta_value 'helping', but it also needs to show the titles of posts that don't have a meta_key 'the_status' at all.
Thanks for reading.
replace
'meta_key' => 'the_status',
'meta_value' => array('helping')
With
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'the_status',
'compare' => 'NOT EXISTS',
'value' => '' //can be omitted in WP 3.9+
),
array(
'key' => 'the_status',
'value' => array('helping')
)

CakePHP retrieve loop data in the select array

now i got a table contact.
the contact have 2 row which is id and name.
now i got 3 user in my contact,
1 A
2 B
3 C
question.
how do i make a select input as the code of below ( in cakephp ):
<select name="contact" id="UserField">
<?php for($i=1;$i<=3; $i++) ?>
<option value="1"><?php echo $contact['Contact']['name']; ?></option>
</select>
In your controllers action you can set a list of the names
$names = $this->Contact->find('list', array(
'contain' => array(),
'fields' => array(
'Contact.id',
'Contact.name'
),
'order' => array(
'Contact.name' => 'ASC'
)
));
$this->set(compact('names'));
And then in your view
echo $this->Form->input('contact', array(
'label' => 'Contact',
'options' => $names
));

CakePHP 2.3: Save multiple forms in multiple tables all at once in 1 page

I'm trying to set up a commercial proposal system using CakePHP 2.3.
It has 5 tables which are associated (see details below).
This system will have 1 page on which are 5 forms for each table. (see details below).
Form 1: table proposals
Form 2: table clients FK proposal_id
Form 3: table products FK client_id
Form 4: table specifications FK product_id (of the product)
Form 5: table appendices FK product_id (of the product)
WHERE:
proposals hasOne clients.
----------v----------
clients beongsTo proposals AND hasMany products.
----------v----------
products belongsTo clients AND hasMany specifications & appendices.
----------v----------
specifications belongsTo products.
appendices belongsTo products.
The form 4 can have multiple row so it's inside a foreach loop to generate more input. Same for the form 5. Because 1 product can have multiple specifications and appendices.
I admit, it's pretty tricky :)
This is the solution I finally chose, but maybe there is better. For exemple, I could make a multi-step form but it seems quite difficult to put in place. Anyway, i'm open to suggestion.
Meanwhile, I'm sure we can make this work so here are the details. For each table, I have created a model and made the appropriated connections. In each model I have enable the containable behaviour: public $actsAs = array('Containable');.
Now here is the ProposalsController.php:
function admin_edit($id=null){
$this->loadModel('Proposal','Client','Product', 'Specification', 'Appendice');
$this->Proposal->contain('Proposal','Client','Product', 'Specification', 'Appendice');
if ($this->request->is('put') || $this->request->is('Post')) {
$data = $this->request->data;
if (!empty($data)) {
// Use the following to avoid validation errors:
// unset($this->Proposal->Client->validate['proposal_id']);
// $this->Proposal->saveAssociated($data);
// $this->Session->setFlash("Le contenu a bien été édité");
// $this->redirect(array('action' => 'index', $data['Product']['id']));
debug($data);
}
}
elseif($id){
$this->Proposal->id = $id;
$this->request->data = $this->Proposal->read(null,$id);
}
}
This edit action has many errors because I don't know how to set it up correctly in that case. So forgive me but I give you a raw code :). I would like this admin_function to add or edit, but again, in this case I don't know how to handle it.
And the view admin_edit.ctp :
<hr/>
<h1>Proposition</h1>
<hr/>
<?php echo $this->Form->create('Product'); ?>
<?php echo $this->Form->input('Proposal.name', array('label' => "Nom de la proposition")); ?>
<?php echo $this->Form->input('Proposal.created', array('label' => "Date de création")); ?>
<?php echo $this->Form->input('Proposal.due', array('label' => "Date d'échéance")); ?>
<?php echo $this->Form->input('Proposal.content', array('label' => "Termes & conditions")); ?>
<hr/>
<h1>Client</h1>
<hr/>
<?php echo $this->Form->input('Client.name', array('label' => "Nom du client")); ?>
<?php echo $this->Form->input('Client.project', array('label' => "Nom du projet")); ?>
<?php echo $this->Form->input('Client.address', array('label' => "Adresse")); ?>
<?php echo $this->Form->input('Client.phone', array('label' => "Téléphone")); ?>
<?php echo $this->Form->input('Client.email', array('label' => "Email")); ?>
<?php echo $this->Form->hidden('Client.proposal_id'); ?>
<hr/>
<h1>Produit</h1>
<hr/>
<?php echo $this->Form->input('Product.0.name', array('label' => "Nom du produit")); ?>
<?php echo $this->Form->input('Product.0.reference', array('label' => "Référence")); ?>
<?php echo $this->Form->input('Product.0.image', array('label' => "Image")); ?>
<?php echo $this->Form->input('Product.0.pu', array('label' => "Prix Unitaire")); ?>
<?php echo $this->Form->input('Product.0.quantity', array('label' => "Quantité")); ?>
<?php echo $this->Form->input('Product.0.ce', array('label' => "CE")); ?>
<?php echo $this->Form->input('Product.0.nf', array('label' => "NF")); ?>
<?php echo $this->Form->input('Product.0.rohs', array('label' => "RoHS")); ?>
<?php echo $this->Form->hidden('Product.0.client_id'); ?>
<hr/>
<h1>Spécifications :</h1>
<hr/>
<?php
foreach (range(0,1) as $i):
$a=$i+1;
echo '<p>Spécification '.$a.'</p>';
echo $this->Form->input('Specification.'.$i.'.name', array('label' => "Nom de la spécification"));
echo $this->Form->input('Specification.'.$i.'.value', array('label' => "Valeur de la spécification"));
echo $this->Form->hidden('Specification.'.$i.'.product_id');
endforeach;
?>
<hr/>
<h1>Annexes :</h1>
<hr/>
<?php
foreach (range(0,1) as $j):
$b=$j+1;
echo '<p>Annexe '.$b.'</p>';
echo $this->Form->input('Appendice.'.$j.'.name', array('label' => "Image"));
echo $this->Form->input('Appendice.'.$j.'.content', array('label' => "Description de l'annexe"));
echo $this->Form->hidden('Appendice.'.$j.'.product_id');
endforeach;
?>
<?php echo $this->Form->end('valider'); ?>
And finally, here is the array result of the debug($data):
array(
'Proposal' => array(
'name' => 'Proposition 3',
'created' => array(
'month' => '02',
'day' => '19',
'year' => '2013',
'hour' => '08',
'min' => '27',
'meridian' => 'am'
),
'due' => array(
'month' => '02',
'day' => '19',
'year' => '2013',
'hour' => '08',
'min' => '27',
'meridian' => 'am'
),
'content' => 'Termes & conditions'
),
'Client' => array(
'name' => 'Client 3',
'project' => 'Projet Client 3',
'address' => 'Adresse Client 3',
'phone' => 'Téléphone Client 3',
'email' => 'Email#test.com',
'proposal_id' => ''
),
'Product' => array(
(int) 0 => array(
'name' => 'Produit 3',
'reference' => 'Référence Produit 3',
'image' => 'Image Produit 3',
'pu' => '100.77',
'quantity' => '1000',
'ce' => '1',
'nf' => '0',
'rohs' => '0',
'client_id' => ''
)
),
'Specification' => array(
(int) 0 => array(
'name' => 'Specification 1',
'value' => 'Valeur 1',
'product_id' => ''
),
(int) 1 => array(
'name' => 'Specification 2',
'value' => 'Valeur 2',
'product_id' => ''
)
),
'Appendice' => array(
(int) 0 => array(
'name' => 'Image annexe 1',
'content' => 'Description de l'annexe',
'product_id' => ''
),
(int) 1 => array(
'name' => 'Image annexe 2',
'content' => 'Description de l'annexe',
'product_id' => ''
)
)
)
So in this array, everything is there. I just need to take these data and save them all in the corresponding tables. The first problem is to manage with the table's associations. Then the 2 foreach loops that generate multiple row.
I would like to save it all at once but is it even possible?
After trying many ways to get it work, I've gone completely crazy and I just lost myself. I'm really desperate on that one, i mix up everything between the saving method and the request->data that contains everything but cannot get it saved. Anyway, i'm desperately in need for help!
Thank you very much in advance for all the help you can give me, I really appreciate!
[EDIT]
I add my model to the present post for more detail.
Proposal.php:
<?php
class Proposal extends AppModel {
public $actsAs = array('Containable');
public $validate = array(
'name' => array(
'rule' => 'notEmpty',
'message' => "Veuillez préciser un titre"
)
) ;
public $hasOne = array(
'Client' => array(
'className' => 'Client',
'foreignKey' => 'proposal_id',
'dependent' => true
)
);
}
Client.php:
<?php
class Client extends AppModel {
public $actsAs = array('Containable');
public $belongsTo = array(
'Proposal' => array(
'className' => 'Proposal',
'foreignKey' => 'proposal_id'
)
);
public $hasMany = array(
'Product' => array(
'className' => 'Product',
'foreignKey' => 'client_id',
'conditions' => '',
'order' => '',
'limit' => '',
'dependent' => true
)
);
}
Product.php:
<?php
class Product extends AppModel {
public $actsAs = array('Containable');
public $belongsTo = array(
'Client' => array(
'className' => 'Client',
'foreignKey' => 'client_id'
)
);
public $hasMany = array(
'Specification' => array(
'className' => 'Specification',
'foreignKey' => 'product_id',
'conditions' => '',
'order' => '',
'limit' => '',
'dependent' => true
),
'Appendice' => array(
'className' => 'Appendice',
'foreignKey' => 'product_id',
'conditions' => '',
'order' => '',
'limit' => '',
'dependent' => true
)
);
}
Specification.php:
<?php
class Specification extends AppModel {
public $actsAs = array('Containable');
public $belongsTo = array(
'Product' => array(
'className' => 'Product',
'foreignKey' => 'product_id'
)
);
}
Appendice.php:
<?php
class Appendice extends AppModel {
public $actsAs = array('Containable');
public $belongsTo = array(
'ProductAppend' => array(
'className' => 'Product',
'foreignKey' => 'product_id'
)
);
}
What's the output when you save the data?
if (!empty($this->data)) {
$this->Proposal->save($this->data);
}
You should also check the sql-output
echo $this->element('sql_dump');
edit:
Well after your edit, on the first look it seems that your relations are wrong.
Check out the examples in the book: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
For example hasOne: the other model contains the foreign key.
As I said earlier, you should try to start with just one relation, getting it to work. Afterwords, it'll be much easier to get the other working. So try to comment-out everything except your Proposal and Client model. Then try saving just those two.

Paginator->sort using contain at CakePHP 2.2

I am using contain behavior and i want to be able to sort the data as always but I am having troubles.
It might be because the columns i want to sort are not columns on the paginate table but on the contain tables.
Subscriptions table only contains the "user_id" and the "post_id".
At the controller i have:
$this->paginate = array(
'conditions' => array('Subscription.user_id' => $this->Session->read('Auth.User.id')),
'paramType' => 'querystring',
'limit' => 20,
'contain'=> array('User', 'Post' => array('Priority', 'Status'))
);
$this->set('subscriptions', $this->paginate('Subscription'));
And in my view, this:
<!-- example of not working sort -->
<th class="td_subject"><?php echo $this->Paginator->sort('subject'); ?></th>
The data of subject, for example, is contained on the array $subscription with the normal format:
$subscription['Post']['subject']
And i print it this way:
foreach ($subscriptions as $subscription):
echo ...
echo '<td>'.h($subscription['Post']['subject'].'</td>';
echo ...
endforeach;
How can i use pagination in this case? Thanks.
Don't use contain in this case, manually join the tables:
$this->paginate = array(
'conditions' => array('Subscription.user_id' => $this->Session->read('Auth.User.id')),
'paramType' => 'querystring',
'limit' => 20,
'joins'=>array(
array(
'table'=>'users',
'alias'=>'User',
'conditions'=>array(
'Subscription.user_id = User.id
)
),
array(
'table'=>'posts',
...
),
array(
'table'=>'priorities',
...
),
array(
'table'=>'status',
...
)
)
);
Your view:
<?php echo $this->Paginator->sort('Post.subject', 'Subject'); ?>

Cakephp Undefined Index

When creating a view I am getting a undefined index error: Account on the line with $senderName['Account']['company_name']but when debugging the variable the array prints out
array(
(int) 0 => array(
'Account' => array(
'id' => '0',
'street' => 'SYSTEM',
'city' => 'SYSTEM',
'postcode' => '0',
'state' => 'SYS',
'country' => 'SYS',
'active' => true,
'company_name' => 'SYSTEM',
'abn' => '0'
),
'Template' => array(),
'User' => array(),
'Invoice' => array()
),
here is the code for my view
<?php foreach($invoice as $invoices):?>
<?php foreach($senderName as $senderName):?>
<?php foreach($receiverName as $receiverName):?>
<tr>
<tr>
<td align='center'><?php echo $senderName['Account']['company_name']; ?></td>
<td align='center'><?php echo $receiverName['Account']['company_name']; ?></td>
<td align='center'><?php echo $this->Form->Html->link($invoices['Invoice']['id'],
array('controller' => 'Invoices','action'=>'viewinvoice',$invoices['Invoice']['id'])); ?></td>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
<?php endforeach; ?>
and just in case here is my related function
$accounts2=$this->User->find('list', array(
'fields'=>array('account_id'),
'conditions' => array(
'id' => $this->Auth->user('id'))));
$invoices=$this->Invoice->find('all', array(
'conditions' => array(
'Invoice.receiver_id' => $accounts2)));
$sender=$this->Invoice->Find('list', array('fields'=>('sender_id')));
$receiver=$this->Invoice->Find('list', array('fields'=>('receiver_id')));
$senderName=$this->Account->Find('all', array(
'conditions' => array(
'id'=>array_values($sender))));
$receiverName=$this->Account->find('all', array(
'conditions' => array(
'id'=>array_values($receiver))));
debug($senderName);
$this->set('senderName', $senderName);
$this->set('accounts2', $accounts2);
$this->set('receiverName', $receiverName);
$this->set('sender',$sender);
$this->set('receiver',$receiver);
$this->set('invoice', $invoices);
}
You're computer is right. :)
$senderName['Account']['company_name']
does not exists.
$senderName['0']['Account']['company_name']
does.
The data comes in this format as they may be several account liked to senderName.
Edit:
Could you give the relationship in your models too?
I think you should review your code in view :
<?php foreach($senderName as $senderName):?>
<?php foreach($receiverName as $receiverName):?>
in foreach array_expression and value variable should be different but you have used same variable name, please use different names for this.

Resources