I want to set a default 'selected' for my checkbox in zend 2.
i tried adding a default
'value'=>'selected'
but it does not seem to work.
$this->add(array(
'type' => 'Zend\Form\Element\Checkbox',
'name' => 'receiveNewsletters',
'options' => array(
'value_options' => array(
'1' => 'Untick if you do not want to receive promotional emails',
),
'attributes' => array(
'value'=>'selected',
),
),
));
The value should be the checked_value. By default it is '1'
$this->add(array(
'type' => 'Zend\Form\Element\Checkbox',
'name' => 'receiveNewsletters',
'options' => array(
'label' => 'Untick if you do not want to receive promotional emails',
),
'attributes' => array(
'value' => '1',
),
));
Related
In Cakephp I need to get the tutors who teach a subject 'primary English'. Instead I get all the tutors with any subject so the condition gets ignored with no error. There is a habtm relationship between tutors and subjects they teach.
$this->Tutor->Behaviors->load('Containable');
$tutors=$this->Tutor->find('all',array(
'contain' => array('Subject',array( 'conditions'=> array('Subject.name' => 'Primary English'))),
'contain' => array('Subject'),
'recursive' =>-1,
// 'order'=> $orderoptions,
'fields'=>array('Tutor.last_name', 'Tutor.first_name','Tutor.id' ),
));
debug( $tutors);
array(
(int) 0 => array(
'Tutor' => array(
'last_name' => 'Wyers',
'first_name' => 'Adele',
'id' => '13'
),
'Subject' => array()
),
(int) 1 => array(
'Tutor' => array(
'last_name' => 'Payet',
'first_name' => 'Allison',
'id' => '7'
),
'Subject' => array(
(int) 0 => array(
'id' => '4',
'name' => 'English - Year 11',
'TutorsSubject' => array(
'id' => '30',
'tutor_id' => '7',
'subject_id' => '4'
)
),
Remove 'recursive' => -1. This prevents it from selecting relationships recursively. If this still doesn't work then put 'recursive' => 2 in.
I am using cakephp 2.5.2
I have 5 tables
1- users
2- projects
3- tags
4- project_tags
5- images
a user can have many projects
a project can have many (tags,images)
I have 2 questions
$projects = $this->Project->find('all',array('conditions'=>array('User.id'=>$this->Auth->user('id'))));
debug($projects);exit();
this gives
array(
(int) 0 => array(
'Project' => array(
'id' => '1',
'name' => 'project 1'
),
'User' => array(
'password' => '*****',
'id' => '1',
'name' => 'User 1',
'email' => 'user1#gmail.com'
),
'Image' => array(),
'ProjectTag' => array(
(int) 0 => array(
'id' => '1',
'project_id' => '1',
'tag_id' => '1'
),
(int) 1 => array(
'id' => '2',
'project_id' => '1',
'tag_id' => '8'
),
(int) 2 => array(
'id' => '3',
'project_id' => '1',
'tag_id' => '6'
),
(int) 3 => array(
'id' => '4',
'project_id' => '1',
'tag_id' => '10'
),
(int) 4 => array(
'id' => '5',
'project_id' => '1',
'tag_id' => '4'
)
)
),
(int) 1 => array(
'Project' => array(
'id' => '2',
'name' => 'project 2'
),
'User' => array(
'password' => '*****',
'id' => '1',
'name' => 'user 1',
'email' => 'user1#gmail.com'
),
'Image' => array(),
'ProjectTag' => array(
(int) 0 => array(
'id' => '6',
'project_id' => '2',
'tag_id' => '1'
),
(int) 1 => array(
'id' => '7',
'project_id' => '2',
'tag_id' => '8'
),
(int) 2 => array(
'id' => '8',
'project_id' => '2',
'tag_id' => '4'
)
)
)
)
I need Project & ProjectTag array while do not want user and images array
I tried recursive -1,0,1,2 but could not get what I needed
My Question Number 2 is
How can I find projects which has tag = 'html'
$projects = $this->Project->find('all',array('conditions'=>array('Tag.tag'=>'HTML')));
it says
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Tag.tag' in 'where clause'
First off, just a note. ALWAYS use $recursive=-1;. It's ideal just to set this in the AppModel, then never mess with recursive again. If you want to get additional data, use CakePHP's Containable Behavior, not recursive.
Overall issue - you cannot add conditions against a recursive (or contained) model, which is what you appear to be doing in both of your questions. If you want to condition against a model other than the one you're doing the find on, you need to either use JOINs or swap your query to run on the other model.
Answer to Question 1
Change this:
$projects = $this->Project->find('all',array(
'conditions'=>array(
'User.id'=>$this->Auth->user('id')
)
));
To this:
$projects = $this->Project->find('all',array(
'conditions'=>array(
'user_id'=>$this->Auth->user('id') // <-- notice this
),
'contain' => array(
'ProjectTag' => array(
'Tag' // <-- optional, as you didn't mention you needed
)
)
));
Answer to Question 2:
There are a number of ways to do this. I would suggest this one using joins:
$projects = $this->Project->find('all', array(
'fields' => array(
'Project.*',
'Tag.*'
),
'joins'=>array(
array(
'table' => 'tags',
'alias' => 'Tag',
'type' => 'inner',
'conditions' => array(
'Tag.project_id = Project.id',
'Tag.tag' => 'HTML'
)
)
)
));
Another way would be to swap your query to run on Tags and just use contain to contain the projects for that tag. I like the join better because if you ever way to extend it to retrieve projects for more than just one tag, your data will still be in an easy-to use manner, as opposed to Containable, which would put your projects in different arrays under their corresponding tag.
If you want to optimize your queries in CakePHP, turn off recursive (set it to -1), then use the containable behavior to pick and choose exactly which data you need.
As for your specific query, associated models are by default gotten by left joins, which means if you did your query from projects, you will get all projects plus any tags they have that have "html" in their tag field. The easiest way to fix this problem, is to do your search from tags instead:
$tags = $this->Tag->find('first', array('conditions' => array('tag' => 'html'), 'contain' => array('Project')));
This will get the tag that has 'html' for its tag field, and all the projects associated with it.
I have a site with the usual sort of sellers, items and images. The models look like this:
class Seller extends AppModel {
$hasMany = array('Item');
...
}
class Item extends AppModel {
$belongsTo = array('Seller')
$hasMany = array('Image');
...
}
class Image extends AppModel {
$belongsTo = array('Item');
...
}
My problem is that when I retrieve a list of Items, the data comes out in a different format depending on whether I am getting a list of all Items (to display to the public) in the ItemsController, or the details of a Seller and their Items in the SellersController.
Briefly Item->find('all') retrieves an array of
array( 'Item' => array( <item stuff> ),
'Images' => array of array( <image stuff> ) );
whereas the Seller->find('first', ...) retrieves the Items as
array( 'Seller' => array( <seller stuff> ),
'Item' => array of array ( <item stuff>
'Images' => array of array( <image stuff> ) );
In the 2nd case the Images element is nested within the Item part. Having the data formatted so differently makes it harder to re-use View code. Also my Item afterFind() won't work properly has problems when the Images bit isn't where it expects it to be.
QUESTION
Is there a simple way to prevent the 'Images' part being nested within the 'Item' part in the 2nd situation?
I am using Cake 2.4
Formats in More Detail
All items:
// in ItemsController.php
debug($this->Item->find('all'));
produces this:
array(
(int) 0 => array(
'Item' => array(
'id' => '1',
'title' => 'tom item 1',
'seller_id' => '1'
),
'Seller' => array(
'id' => '1',
'name' => 'tom'
),
'Images' => array(
(int) 0 => array(
'id' => '1',
'item_id' => '1',
'path' => 'tom_1_1'
),
(int) 1 => array(
'id' => '2',
'item_id' => '1',
'path' => 'tom_1_2'
)
)
),
(int) 1 => array(
'Item' => array(
'id' => '2',
'title' => 'tom item 2',
'seller_id' => '1'
),
'Seller' => array(
'id' => '1',
'name' => 'tom'
),
'Images' => array(
(int) 0 => array(
'id' => '3',
'item_id' => '2',
'path' => 'tom_2_1'
),
(int) 1 => array(
'id' => '4',
'item_id' => '2',
'path' => 'tom_2_2'
)
)
),
...
A single Seller + associated Items:
// In SellersController.php
debug($this->Seller->find('first',
array('conditions' => array('id' => $id), 'recursive' => 2)));
produces:
array(
'Seller' => array(
'id' => '1',
'name' => 'tom'
),
'Item' => array(
(int) 0 => array(
'id' => '1',
'title' => 'tom item 1',
'seller_id' => '1',
'Seller' => array(
'id' => '1',
'name' => 'tom'
),
// Look! 'Images' is WITHIN 'Item !!!
'Images' => array(
(int) 0 => array(
'id' => '1',
'item_id' => '1',
'path' => 'tom_1_1'
),
(int) 1 => array(
'id' => '2',
'item_id' => '1',
'path' => 'tom_1_2'
)
)
),
(int) 1 => array(
'id' => '2',
'title' => 'tom item 2',
'seller_id' => '1',
'Seller' => array(
'id' => '1',
'name' => 'tom'
),
'Images' => array(
(int) 0 => array(
'id' => '3',
'item_id' => '2',
'path' => 'tom_2_1'
),
(int) 1 => array(
'id' => '4',
'item_id' => '2',
'path' => 'tom_2_2'
)
)
),
....
This is the expected and correct behavior as Image is not directly associated with Seller, but with Item.
Imagine, how would you determine the proper association when Image would be defined on the same level as Item? That would indicate an association with Seller which doesn't exist.
If you want a different structure, format it in your afterFind callback or wherever it's appropriate. However, I wouldn't recommend trying to work against the CakePHP standards. In case applicable, adapt your view code.
Your question is not clear to me. If just wants to prevent Image to coming in 2nd case, try this
$this->Seller->Item->unbindModel(array(
'hasMany' => array('Image')
));
$result = $this->Seller->find('first',
array('conditions' => array('id' => $id), 'recursive' => 2)));
debug($result);
I add the checkbox functionality from the yii-booster. But the widget renders the model view without the needed boxes. What's wrong?
Widjet code in view
<?php
$this->widget('bootstrap.widgets.TbExtendedGridView',array(
'id'=>'docs-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'type'=>'bordered condensed',
'template' => "{items}",
'bulkActions' => array(
'actionButtons' => array(
array(
'buttonType' => 'button',
'type' => 'primary',
'size' => 'small',
'label' => 'Choose',
'click' => 'js:function(values){console.log(values);}'
)
),
// if grid doesn't have a checkbox column type, it will attach
// one and this configuration will be part of it
'checkBoxColumnConfig' => array(
'name' => 'id'
),
),
));
If you are using bulkActions, you have to use 'columns' to list out the columns you want to display instead of using 'template'.
'columns' => array(
'id',
'title',
...
),
the problem has been in the wrong hierarchy from the example:
The 'checkBoxColumnConfig' attribute must be outside of the 'actionButtons' attribute:
'bulkActions' => array(
'actionButtons' => array(
/*array(
'buttonType' => 'button',
'type' => 'primary',
'size' => 'small',
'label' => 'Выбрать отмеченные',
'click' => 'js:function(values){console.log(values);}'
)
),*/
// if grid doesn't have a checkbox column type, it will attach
// one and this configuration will be part of it
),
'checkBoxColumnConfig' => array(
'name' => 'id'
),
...
));
but now the widget doesn't work when i uncomment the array part inside 'actionButtons':
array(
'buttonType' => 'button',
'type' => 'primary',
'size' => 'small',
'label' => 'Выбрать отмеченные',
'click' => 'js:function(values){console.log(values);}'
)
what might be a cause?
'Tag' => array(
(int) 0 => array(
'id' => '1',
'name' => 'kannada',
'MoviesTag' => array(
'id' => '60',
'movie_id' => '2',
'tag_id' => '1'
)
)
)
I want to fetch Movie from movie_id of Tag in containable.. How to fetch that?
In your Tag controller try something like this:
$this->Tag->find('all'); // this will return tag with movie detail
OR
if you want to use Containable behavior then try this:
$this->Tag->attach->behaviors('Containable');
$this->Tag->recursive = -1;
$this->Tag->find('all', array(
'fields' => array('Tag.id', 'Tag.name'),
'contain' => array(
'Movie'
)
));