• 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?

Nudaii

Well-known member
#1
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?
 

Brogan

XenForo moderator
Staff member
#2
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).
 

Nudaii

Well-known member
#3
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
 

Brogan

XenForo moderator
Staff member
#4
What is returned if you dump $whoPostedAvatar in the template?
Code:
{xen:helper dump, $whoPostedAvatar}
 

Brogan

XenForo moderator
Staff member
#6
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?
 

Nudaii

Well-known member
#7
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?
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
 

Brogan

XenForo moderator
Staff member
#8
If you dump $threadId after this line in the controller, what is returned?
PHP:
$threadId = $this->_input->filterSingle('thread_id', XenForo_Input::UINT);
 

Brogan

XenForo moderator
Staff member
#10
Then it should work.

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

Nudaii

Well-known member
#11
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' );
  }
}
?>
 

Chris D

XenForo developer
Staff member
#12
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
 

Lawrence

Well-known member
#13
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:

Nudaii

Well-known member
#18
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
 

Nudaii

Well-known member
#19
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