Getting data from the Model

AndyB

Well-known member
I'm creating this add-on which queries the database. I'm told this isn't the proper way and I should use the Model instead.

This is my directory structure at this point.

library
--Andy
----ShowDeleted
------ControllerPublic
--------ShowDeleted.php
----Route
------Prefix
--------ShowDeleted.php

library/ShowDeleted/ControllerPublic/ShowDeleted.php

PHP:
<?php

class Andy_ShowDeleted_ControllerPublic_ShowDeleted extends XenForo_ControllerPublic_Abstract
{
   public function actionIndex()
   {
     // if you are not a super admin, return
     if (!XenForo_Visitor::getInstance()->isSuperAdmin())
     {
       return;
     }
         
     //########################################
     // get data
     
     $db = XenForo_Application::getDb();
     
     $posts = $db->fetchAll("
     SELECT *
     FROM xf_post
     WHERE message_state = 'deleted'
     ORDER BY post_id DESC
     LIMIT 50");
     
     $threads = $db->fetchAll("
     SELECT *
     FROM xf_thread
     WHERE discussion_state='deleted'
     ORDER BY thread_id DESC
     LIMIT 50");
         
     //########################################
     // prepare output     
     
     $viewParams = array('posts' => $posts,'threads' => $threads,
     );
     
     return $this->responseView('Andy_ShowDeleted_ViewPublic_ShowDeleted', 'andy_showdeleted', $viewParams);
   }
}

?>
 
PHP:
$threads = $this->getModelFromCache('XenForo_Model_Thread')->getThreads(array('discussion_stats' => 'deleted', array('order' => 'thread_id', 'orderDirection' => 'DESC')));

I believe, look in XenForo/Model/Thread.php at the getThreads function and all the functions called within that function.
 
Hi Daniel,

Thank you kindly for that code, it works! The only thing missing is the Limit 50 part of it. I'll try to add Limit 50 to the array and see if that works.
 
Thanks, Daniel.

This works perfect!!

PHP:
    $threads = $this->getModelFromCache('XenForo_Model_Thread')->getThreads(
       array('discussion_state' => 'deleted',
       array('order' => 'thread_id',
       'orderDirection' => 'DESC',
       array('limit' => 50,)))
     );
 
It's the same thing. just model_post instead and getPosts.

In the following file:

library/Xenforo/Model/Post.php

there isn't a "public function getPosts".

Does this mean we can't use the Model for our database query for getting the post_id's?
 
Last edited:
Yeah if the function doesn't exist then you should extend it and make the function. use the proxy system.

Thank you for the confirmation, Daniel.

I assume the first step is to create the following directory and file:

library
--Andy
----ShowDeleted
------ControllerPublic
--------ShowDeleted.php
------Model
--------ShowDeleted.php
----Route
------Prefix
--------ShowDeleted.php
 
The query is embraced by a simple ', so in the query you can use regular ".

PHP:
<?php

class ShowDeleted_Model_ShowDeleted extends XFCP_ShowDeleted_Model_ShowDeleted
{
   public function getDeletedPosts()
   {
 
  return $this->_getDb()->fetchAll('
SELECT *
FROM xf_post
WHERE message_state = "deleted"
ORDER BY post_id DESC
LIMIT 50');
     }
   }
}

Or with flexible limit, here you see how the questionmark works as a placeholder in a query.

PHP:
<?php

class ShowDeleted_Model_ShowDeleted extends XFCP_ShowDeleted_Model_ShowDeleted
{
   public function getDeletedPosts($limit)
   {
 
  return $this->_getDb()->fetchAll('
SELECT *
FROM xf_post
WHERE message_state = "deleted"
ORDER BY post_id DESC
LIMIT ?', array($limit));
     }
   }
}
 
Another example, this shows how multiple questionmarkes are handled. They are always replaced with the array step by step.

PHP:
  return $this->_getDb()->fetchAll('
SELECT *
FROM xf_post
WHERE message_state = "deleted"
AND user_id = ?
ORDER BY post_id DESC
LIMIT ?', array($userId, $limit));
}

The array would be
array(
[0] => $userId,
[1] => $limit
)

So you see, the array is always sorted, and that's why it is possible to use a simple array to replace multiple questionmarks.
 
Hi Marcus,

Thank you kindly for the information.

I added the code you provided in the following file:

library/Andy/ShowDeleted/Model/Showdeleted.php

PHP:
<?php

class ShowDeleted_Model_ShowDeleted extends XFCP_ShowDeleted_Model_ShowDeleted
{
   public function getDeletedPosts()
   {
     return $this->_getDb()->fetchAll('
     SELECT *
     FROM xf_post
     WHERE message_state = "deleted"
     ORDER BY post_id DESC
     LIMIT 50');
   }
}

?>

However I don't know the correct code to add to the following file:

library/Andy/ShowDeleted/ControllerPublic/Showdeleted.php

PHP:
$posts = $this->getModelFromCache('Andy_ShowDeleted_Model_ShowDeleted')->getDeletedPosts(); // this does not work

Trying this I get the following Server Error:

Cannot load class using XFCP. Load the class using the correct loader first.
 
Well first, you're not calling the right class (Andy_ShowDeleted_Model_ShowDeleted). Secondly, load it using the proxy system (listeners, listen to XenForo_Model_Post and call XenForo_Model_Post as the model, yours will hook in correctly).
 
You have to do two steps:

1. Create a function in ShowDeleted_Listener
PHP:
  public static function loadClassModel($class, array &$extend)
   {
         $extend[] = 'ShowDeleted_Model_ShowDeleted';
   }

2. Set the Listener in ACP
load_class_model
hint: XenForo_Model_Post
Listener: ShowDeleted_Listener::loadClassModel


Edit: Change everything to Andy_ ..........., also my previous code
 
Thank you, Marcus. Here's what I have done so far:

library/Andy/ShowDeleted/Listener.php

PHP:
<?php

class Andy_ShowDeleted_Listener
{
   public static function loadClassModel($class, array &$extend)
   {
      $extend[] = 'Andy_ShowDeleted_Model_ShowDeleted';
   }
}
   
?>

and the Code Event Listener

pic001.webp
 
Top Bottom