I'm having an issue with afterfind() and none of what I'm reading has solved it. It has to do with the afterfind not working for related models which I am aware many people have brought up but I haven't found a solution. All the posts I see are also from 2009-2010.
User.php Model
function afterFind($results, $primary = false) {
parent::afterFind($results, $primary);
if($primary){
foreach($results as $key => $val){
if (isset($val['User']['id'])){
$results[$key]['User']['online'] = $this->UsersOnline->find('count',
array('conditions' => array('UsersOnline.user_id =' => $val['User']['id'])));
// THIS WORKS PERFECTLY FOR USER MODEL PAGES
}
}
}
else {
foreach($results as $key => $val){
$key['User']['online'] = $this->UsersOnline->find('count',
array('conditions' => array('UsersOnline.user_id =' => 1)));
// THIS IS THE PART THAT IS INCORRECT, AND THIS IS THE "BEST" SOLUTION
// I'VE FOUND ONLINE BUT IT IS NOT WORKING
/**
* I've also tried these
*
* $results[$key]['online']
* $results[$val]['online']
* $results[$key][$val]['online']
* $results['0']['User']['online']
*
* and about 5 other things
*/
}
}
return $results;
} // end afterfind
I have tried many combinations of code in the "else" statement but I get one of three errors which are Uninitialized string offset: 0
, Cannot use string offset as an array
or Column User.online not found
.
EDIT: Maybe this will provide a little more insight into the issue.
I'm trying to view the ARTICLES VIEW.CTP. It displays the article at the top with $article['User']
information (trying to include $article['User']['online']
). Below the post are the article comments ( foreach $article['Comment'] as $comment
).
This is my ARTICLES.PHP CONTROLLER
public function view($page = null, $id = null) {
// $this->Article->recursive = 3;
$this->Article->id = $id;
if (!$this->Article->exists()) {
$this->Session->setFlash('This article does not exist');
$this->redirect(array('controller'=>'articles', 'action' => 'index'), null, true);
}
$this->Article->contain(array(
'User' => array(
'fields'=>array('User.username', 'User.signature', 'User.online'),
'UserAvatar' => array(
'fields'=>array('UserAvatar.file')
)
),
'Comment' => array(
'fields'=>array('Comment.content', 'Comment.created', 'Comment.title'),
'User' => array(
'fields'=>array('User.username', 'User.signature', 'User.online'),
'UserAvatar' => array(
'fields'=>array('UserAvatar.file')
)
)
)
));
$this->set('article', $this->Article->read(null, $id));
} // end view function
With the code as is (looking at the "contain" conditions, I am returned an error message " Column User.online does not exist
". However, when I remove User.online from the contain on both the Comment array and the User array and INSTEAD set $this->Article->recursive = 3
, I receive no error message. With recursive = 3, if I print_r($article['User'])
or print_r($comment['User'])
on articles view.ctp, the arrays both show the correct value for online.
The exact print for both $article['User'] and $comment['User'] with recursive = 3 is
Array
(
[id] => this
[username] => this
[password] => ****
[UserAvatar] => Array
(
[id] => this
[column] => value
[column] => value
)
[OTHER USER RELATED MODELS] => Array
(
[column] => value
)
[online] => 1
[type] => 1
)
If I echo $article['User']['online']
with recursive = 3, I get the correct value (3 is needed in order for UserAvatar info to display).
I don't understand why, then, with the contain, does it say that User.online cannot be found? I have actAs = 'Containable'
in my AppModel because I use that property on nearly all models.
Here is my most updated USER.PHP MODEL afterfind()
function afterFind($results, $primary = false) {
parent::afterFind($results, $primary);
if($primary){
foreach($results as $key => $val){
if (isset($val['User']['id'])){
$results[$key]['User']['online'] = $this->UsersOnline->find('count', array('conditions' => array('UsersOnline.user_id =' => $val['User']['id'])));
}
} // end for each
} // end if primary
else{
foreach($results as $key => $val){
if(isset($results['0']['User']['id'])){
$results['0']['User']['online'] = "1";
$results['User']['online'] = $results['0']['User']['online'];
$results['0']['User']['type'] = '1';
}
elseif(isset($results['User']['id'])){
$results['User']['online'] = "1";
$results[$key]['User']['online'] = $results['User']['online'];
$results['User']['type'] = '2';
} // end elseif
// everything returns as type 1 so this may be irrelevant
} // end for each
} // end if not primary
return $results;
} // end afterfind
POSSIBLE SOLUTION: After tinkering a little bit more I found out that the following works (Articles model) but this is not ideal because it retrieves all data from User and UserAvatar whereas I would like to fetch data only for specified fields. However, when I use the fields option, User.online is not recognized. Any ideas?
$this->Article->contain(array(
'User' => array(
'UserAvatar'
),
'Comment' => array(
'User' => array(
'UserAvatar'
)
)
));
$this->set('article', $this->Article->read(null, $id));
Try following foreach
foreach($results as &$val){
$val['User']['online'] = $this->UsersOnline->find('count', array(
'conditions' => array('UsersOnline.user_id' => 1)
));
}
Please note that this will only return the count where user_id=1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.