1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Passing ThreadId to Model or a better method?

Discussion in 'XenForo Development Discussions' started by Nudaii, Feb 4, 2016.

  1. Nudaii

    Nudaii Well-Known Member

    Howdy i am working on an addon which i have got working all except the ability to automatically pick up the threadID

    If i manually add a number to the model query it works as it should, of course what i need is for it to automatically detect the ID of the thread.

    Code:
    <?php
      class RRWS_WhoPostAvatar_ControllerPublic_Index extends XFCP_RRWS_WhoPostAvatar_ControllerPublic_Index
    {
    
    public function actionIndex()
    {
    $response = parent::actionIndex();
    
    $threadId = $this->_input->filterSingle('thread_id', XenForo_Input::UINT);
    
    $response->params += array('whoPostedAvatar' => $this->_getWhoPostAvatarModel()->getAllAvatars());
    
    return $response;
    }
          protected function _getWhoPostAvatarModel()
        {
            return $this->getModelFromCache ( 'RRWS_WhoPostAvatar_Model_Model' );
        }
    }
    ?>
    Like below if i have
    Code:
    <?php
    class RRWS_WhoPostAvatar_Model_Model extends XenForo_Model
    {
      //Lets Poke the Database
      public function getAllAvatars()
      {
      return $this->fetchAllKeyed('SELECT DISTINCT(xf_user.username), xf_thread_user_post.user_id,xf_user.user_id FROM xf_thread_user_post INNER JOIN xf_user ON xf_thread_user_post.user_id=xf_user.user_id WHERE xf_thread_user_post.thread_id = 60 ', 'user_id'
      );
      }
    
    }
    ?>
    
    
    any suggestions on how this can be accomplished?

    @Lawrence any ideas friend?
     
  2. Brogan

    Brogan XenForo Moderator Staff Member

    A basic model function would be something like this:
    PHP:
    public function myFunction($threadId)
    {
        
    $db $this->_getDb();

        
    $db->query("
            UPDATE table
            SET something = 0
            WHERE thread_id = ?
        "
    $threadId);
    }

    And you would pass $threadId to your model using something like this in your controller:
    PHP:
    $myModel $this->_getMyModel();

    ...

    $myModel->myFunction($threadId);

    ...

    protected function 
    _getMyModel()
    {
        return 
    $this->getModelFromCache('My_Model');
    }
    Depending on how you have defined the code for getting the model in the controller (which essentially depends on how many times you call it).
     
    SneakyDave likes this.
  3. Nudaii

    Nudaii Well-Known Member

    thanks brogan! i am heading in right direction now. i pribably have put code in wrong manner (new to php and xenforo addons)

    Model
    Code:
    <?php
    class RRWS_WhoPostAvatar_Model_Model extends XenForo_Model
    {
      //Lets Poke the Database
      public function getAllAvatars($threadId){
      $db = $this->_getDb();
      $db->query("SELECT DISTINCT(xf_user.username), xf_thread_user_post.user_id,xf_user.user_id FROM xf_thread_user_post
      INNER JOIN xf_user ON xf_thread_user_post.user_id=xf_user.user_id WHERE xf_thread_user_post.thread_id = ?", $threadId);
    }
    }
    ?>
    
    
    controller
    Code:
    <?php
      class RRWS_WhoPostAvatar_ControllerPublic_Index extends XFCP_RRWS_WhoPostAvatar_ControllerPublic_Index
    {
    
    public function actionIndex()
    {
    $response = parent::actionIndex();
    $threadId = $this->_input->filterSingle('thread_id', XenForo_Input::UINT);
    $myModel = $this->_getWhoPostAvatarModel();
    $myModel->getAllAvatars($threadId);
    $response->params += array('whoPostedAvatar' => $this->_getWhoPostAvatarModel()->getAllAvatars($threadId));
    return $response;
    }
      protected function _getWhoPostAvatarModel()
      {
      return $this->getModelFromCache ( 'RRWS_WhoPostAvatar_Model_Model' );
      }
    }
    ?>
    
    in template thread_view
    Code:
    <ul>
    <xen:foreach loop="$whoPostedAvatar" value="$who">
    <fieldset>
    <li>
    {$who.username}
    {$who.user_id}
    </dd>
    </dl>
    <dl class="ctrlUnit"></dl>
    </li>
    </fieldset>
    <br />
    </xen:foreach>
    </ul>
    
    error given

    Code:
    Invalid argument supplied for foreach() in /home/****/development/library/XenForo/Template/Abstract.php(265) : eval()'d code, line 576:
    575: ';
    576: foreach ($whoPostedAvatar AS $who)
    577: {
    
    
    Can you see where i went wrong? i greatly appreciate any help
     
  4. Brogan

    Brogan XenForo Moderator Staff Member

    What is returned if you dump $whoPostedAvatar in the template?
    Code:
    {xen:helper dump, $whoPostedAvatar}
     
  5. Nudaii

    Nudaii Well-Known Member

    null, which is odd, as if i have a number manually in query it exports the proper array
     
  6. Brogan

    Brogan XenForo Moderator Staff Member

    Presumably if you dump it in the controller it returns an array?
    PHP:
    Zend_Debug::dump($whoPostedAvatar);
    How are you then passing it to the template from your controller?
     
  7. Nudaii

    Nudaii Well-Known Member

    I think you mean this part of code by your latter statement?

    Code:
    $response->params += array('whoPostedAvatar' => $this->_getWhoPostAvatarModel()->getAllAvatars()); 
    if i have a threadid number set manually in the model sql query the dump looks like this

    Code:
    
    array(2) {
      [1] => array(2) {
        ["username"] => string(4) "RRWS"
        ["user_id"] => int(1)
      }
      [2] => array(2) {
        ["username"] => string(4) "Test"
        ["user_id"] => int(2)
      }
    }
    
    which is correctly querying who posted and their user_id and username. via
    {$who.username}
    {$who.user_id}
    , just cant get it to work when i pass the $threadId to it.. umm
     
  8. Brogan

    Brogan XenForo Moderator Staff Member

    If you dump $threadId after this line in the controller, what is returned?
    PHP:
    $threadId $this->_input->filterSingle('thread_id'XenForo_Input::UINT);
     
  9. Nudaii

    Nudaii Well-Known Member

    int(60) (when viewing threadID 60)
     
  10. Brogan

    Brogan XenForo Moderator Staff Member

    Then it should work.

    What do your controller and model look like now, using the $threadId method I outlined earlier?
     
  11. Nudaii

    Nudaii Well-Known Member

    Model
    Code:
    <?php
    class RRWS_WhoPostAvatar_Model_Model extends XenForo_Model
    {
      //Lets Poke the Database
      public function getAllAvatars($threadId){
      $db = $this->_getDb();
      $db->query("SELECT DISTINCT(xf_user.username), xf_thread_user_post.user_id,xf_user.user_id FROM xf_thread_user_post
      INNER JOIN xf_user ON xf_thread_user_post.user_id=xf_user.user_id WHERE xf_thread_user_post.thread_id = ?", $threadId);
    }
    }
    ?>
    
    
    controller
    Code:
    <?php
      class RRWS_WhoPostAvatar_ControllerPublic_Index extends XFCP_RRWS_WhoPostAvatar_ControllerPublic_Index
    {
    
    public function actionIndex()
    {
    $response = parent::actionIndex();
    $threadId = $this->_input->filterSingle('thread_id', XenForo_Input::UINT);
    $myModel = $this->_getWhoPostAvatarModel();
    $myModel->getAllAvatars($threadId);
    $response->params += array('whoPostedAvatar' => $this->_getWhoPostAvatarModel()->getAllAvatars($threadId));
    return $response;
    }
      protected function _getWhoPostAvatarModel()
      {
      return $this->getModelFromCache ( 'RRWS_WhoPostAvatar_Model_Model' );
      }
    }
    ?>
    
     
  12. Chris D

    Chris D XenForo Developer Staff Member

    The Model function doesn't appear to be returning anything. Even so, you should be using one of the "fetch" methods on the Db object rather than just query. The query method performs the query, but it returns a statement object rather than the result of the query in any reasonable format. If you use one of the fetch methods, e.g. fetchRow or fetchAll it will format the results of the query for you appropriately.
    • fetchOne - returns the first field of the first row returned as a single value
    • fetchRow - returns an array containing all fields from the first row returned
    • fetchAll - returns an array containing all rows each of which is an array containing all fields
     
    SneakyDave likes this.
  13. Lawrence

    Lawrence Well-Known Member

    Hi, are you extending controller public thread? If so, your RRWS_WhoPostAvatar_ControllerPublic_Index, should reflect that for clarity:
    RRWS_WhoPostAvatar_ControllerPublic_Thread

    Also, you want a list of who posted avatars displayed at the top, or below the list of posts when viewing a thread, right?

    As the thread_view template uses {$thread} we know its in$response
    $threadId = $response['thread']['thread_id'];

    Before retrieving the thread id, do a sanity check first:
    PHP:
            if (isset($response->params['forum']) && !empty($response->params['forum']))
            {
                    
    $threadId $response['thread']['thread_id'];
                    
    // rest of your code here
            
    }
    Now that you have a valid thread id, the query is rather simple for the (// rest of code here) to retrieve distinct poster_ids, and then their avatars, :) Personally, I would use 2 separate queries as they would execute rather quickly. After I retrieved the poster_ids, I would filter out the ones that already have been fetched for the page of posts being currently viewed, as the avatar info has already been loaded, and you never know, the second query may not even need to be run.
     
    Last edited: Feb 4, 2016
    Nudaii likes this.
  14. Nudaii

    Nudaii Well-Known Member

    i'll try that method now! and yes want the avatars above thread:D
     
  15. Nudaii

    Nudaii Well-Known Member

    thanks all, got it working,l now to style it!
     
    Lawrence likes this.
  16. Nudaii

    Nudaii Well-Known Member

    Lawrence and NixFifty like this.
  17. Lawrence

    Lawrence Well-Known Member

    It looks really great, :) Is the number in the red circle the number of posts a member made in that thread?
     
    Nudaii likes this.
  18. Nudaii

    Nudaii Well-Known Member

    yep :) need to restyle it to allow for mega posters XD had no idea some were in triple digits lol

    and some threads the posters are in 4 digits xD
     
  19. Nudaii

    Nudaii Well-Known Member

    some more styling tweaks, also added in option for neutral characters (which only doesnt show there as no neutral characters found for that story screenshot.png
     
  20. Nudaii

    Nudaii Well-Known Member

    few more tweaks

    smaller avatars for threads with more characters.

    screenshot.png
     

Share This Page