简体   繁体   中英

CakePHP 2.2.4: Afterfind Setup

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM