I am having some issues sorting the table data by a field of a different model.
From here: http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html
It says I can add in the 'model' option but when I try:
echo $this->Paginator->sort('unit', 'Unit', array('model' => 'Unit'));
I get this error:
Warning (2): array_filter() expects parameter 1 to be array, null given [CORE/Cake/View/Helper/PaginatorHelper.php, line 395]
Warning (2): array_merge() [function.array-merge]: Argument #1 is not an array [CORE/Cake/View/Helper/PaginatorHelper.php, line 395]
Any idea what is going on here? The Main / default model is Card and I need to order by the Unit model for one of the column headings.
Thanks
If you are showing records in a list out of some tables, then you can use it via:
<?php echo $this->Paginator->sort('Unit.unit', 'Unit');
It will perfectly work without passing third argument model option.
Just a reminder for newer Versions: Associated models are not automatically loaded in CakePHP3s Paginator. Make sure you include the 'sortWhitelist' Option, see https://book.cakephp.org/3.0/en/controllers/components/pagination.html#control-which-fields-used-for-ordering
Please try below code
echo $this->Paginator->sort('Unit.unit', 'Unit', array('model' => 'Unit'));
Let me know if any.
Related
I have a one-to-many relationship where one House can have many Pictures. The models that I have are "House" and "Picture". I am using CakePHP 1.2 and I can upload one picture successfully by using this:
echo $form->input('Picture.filename', array('type' => 'file', 'label' => __l('Image')));
In my houses_controller.php file, I have this code to save the picture and corresponding association with its house:
$this->House->Picture->save($this->data['Picture']);
But I need to save several pictures now. I read the documentation at https://book.cakephp.org/1.2/en/The-Manual/Core-Helpers/Form.html and based on that information, I am trying to use this:
echo $form->input('Picture.0.filename', array('type' => 'file', 'label' => __l('Image 1'));
echo $form->input('Picture.1.filename', array('type' => 'file', 'label' => __l('Image 2'));
Then my houses_controller.php file has this:
$this->House->Picture->saveAll($this->data['Picture']);
I see that one new record is saved in my pictures table, but I was expecting to see two new entries in my table because I should have added two pictures, not only one. Any ideas about why this may not be saving two pictures for me? Thank you.
Solution:
$this->Deal->Picture->save($this->data['Picture'][0]);
$this->Deal->Picture->save($this->data['Picture'][1]);
Using $this->data['Picture'] was not sufficient because the array was returning multiple elements, so I had to reference each with the corresponding index such as $this->data['Picture'][0] for the first element, $this->data['Picture'][1] for the second one, etc.
NOTE: It was not saving two records for me, even thought I was using save() twice. But that was another issue. You can read the answers at Save multiple times in Cakephp for the corresponding solution. Basically you need to use create() before you use save().
How can I dynamically build the contain in the new cakephp 3 query builder. This is what I have now:
$query = $dbTable->find()
->select($contain['select']['fields'])
->contain(function($q) use($array,$contain){
$new = [];
foreach($array as $v){
if(isset($contain['contains'][$v])){
$fields = $contain['contains'][$v];
$new[$v] = $q->select($fields);
}
}
return $new;
});
But I am getting several errors with this:
Warning (2): Illegal offset type in isset or empty [CORE\src\ORM\EagerLoader.php, line 198]
Warning (2): strpos() expects parameter 1 to be string, object given [CORE\src\ORM\EagerLoader.php, line 203]
Warning (2): Illegal offset type [CORE\src\ORM\EagerLoader.php, line 223]
Warning (2): Illegal offset type [CORE\src\ORM\EagerLoader.php, line 224]
As already mentioned by Lorenzo, that's not how it works, contain() doesn't accept callables, just look at the docs:
http://api.cakephp.org/3.0/class-Cake.ORM.Query.html#_contain
Also your code would invoke select() multiple times on one and the same query, that wouldn't work anyways.
However, looking at your code it seems that you could simply make use of the fields option, ie build a simple array to pass to contain(). This is shown in the docs, the example however will trigger an error as it seems to be necessary to explicitly set the foreign key field too:
$query->contain([
'Articles' => [
'fields' => ['foreign_key_column_name', 'title']
]
]);
You cannot use contain with a closure inside. If you believe this is a good idea (I think it could be) then open a enhancement request on github.
To get all fields in the table Articles do this in your controller.
$query = $this->modelName->find('all')
->contain('Articles');
If you want a expecify field use this:
$query = $this->modelName->find('list', [
'keyField' => 'id',
'valueField' => 'author.name'
])->contain(['Articles']);
To more informations about: https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html
I would like find all relations by code:
$this->set('types', $this->Project->ProjectType->find('all', array(
'recursive' => 2)));
I get error when I set recursive to 2:
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'I18n__name.content' in 'field list'
Model ProjectType using Translate Behavior for content field (text type).
Other recursive works good.
How return results for recursive = 2?
Just don't use recursive at all.
Set it to public $recursive = -1; in your AppModel, and don't change it after that. Then use CakePHP's Containable Behavior to retrieve associated data.
Recursive will give you more headaches than it's worth. If Containable wasn't so easy/awesome, maybe we'd be stuck using recursive, but... it IS awesome and it IS easy :)
I habve a view from table which is working fine with pagination (Paginator->sort()) when I am using it as a view. But when i changed is as a element, it will throw errors:
Warning (2): array_merge() [function.array-merge]: Argument #1 is not an array [CORE\cake\libs\view\helpers\paginator.php, line 194]<br>
Warning (2): array_merge() [function.array-merge]: Argument #2 is not an array [CORE\cake\libs\view\helpers\paginator.php, line 194]<br>
Warning (2): array_merge() [function.array-merge]: Argument #1 is not an array [CORE\cake\libs\view\helpers\paginator.php, line 378]<br>
Warning (2): array_merge() [function.array-merge]: Argument #2 is not an array [CORE\cake\libs\view\helpers\paginator.php, line 378]<br>
The code is exacty same as before, but I changed of course some of the code as follows:
Model:Added next statement
var $helpers = array('Paginator');
Controller: changed the paginate clause to return values to element
return $collaborations = $this->paginate('Collaboration');
Element: added request action into start of the element and the other line is how I call the parination sort
<?php $collaborations = $this->requestAction('/collaborations/calendar'); ?>
<?php echo $this->Paginator->sort('Pvm','Collaboration.start_date'); ?>
Why can't my pagination sort functionality work? Do I have declare something else? I did some Googling and I figured out that paginator might have problem to see/find datamodel (to be declared somewhere) or it would need some parameters to be assigned into it?
Thanks in advance :)
Check cakephp book: http://book.cakephp.org/1.3/en/view/1231/Pagination
You have to set up the paginate variable in your controller and then use the method paginate to populate the data in the view.
Helpers should be configured in the controller not in the model.
Example, your controller class should look like:
class ColaborationController extends AppController {
var $paginate = array( 'limit'=>25, 'order'=>array('Colaboration.start_date'=>'asc'));
function some_action() {
$this->set('collaborations', $this->paginate('Collaboration'));
}
}
And your view:
<?php echo $this->Paginator->sort('Pvm','collaboration.start_date'); ?>
I got bored trying to resolve this problem. I changed the whole application logic around and now it works fine. No problems with paginations in elements (no pagination elements at all) and I don't have to use requestAction method - I read that it is not good for performance and should be avoided. Thanks all for your help :)
I've got the following relationship set-up between two models
Story belongsTo StoryType
StoryType hasMany Story
I've set-up a form to select the StoryType for each story using the following code:
echo $this->Form->input('Story.story_type_id', array('tabindex' => 2));
with this code in the controller to populate the list
$this->set('story_types', $this->Story->StoryType->find('list', array ('order' => 'title')));
But it's not populating the select box with anything. I know that the find() option is working because doing a debug within the controller produces this:
Array
(
[1] => First Person
[3] => Third Person
)
The weird thing is that it's exactly the same code, just querying other models, to populate select lists for things like users and genres, it's just the story types that isn't working.
Any ideas? Cheers.
You don't mention which version of CakePHP you're using, but try setting storyTypes rather than story_types:
$this->set( 'storyTypes', $this->Story->StoryType->find( 'list', array( 'order' => 'title' ) ) );
Older versions of CakePHP (pre-1.3) modified set variable names to headlessCamelCase and, even if you're using 1.3.x, there may be a little bit of that infrastructure lingering. It's a bit of a reach, but it's easy enough to test and it seems plausible that this could be the root of your problem.
I'll be curious to see what you find out.
This is a little hacky, but I think it will work:
echo $this->Form->input('Story.story_type_id', array('tabindex' => 2, 'options' => $story_types));
here's what you should really do .. (esp, for version 2.x) - in case if some people are facing the same problem.
[inside your constroller action]
$oneOfTheColumns = 'title'; //just for sake of making it clear - if you have to order the results
$storyTypes = $this->Story->StoryType('find', array('order'=>$oneOfTheColumns));
$this->set(compact('storyTypes'));
[inside your view]
echo $this->Form->input('StoryType');