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

Getting data from the Model

Discussion in 'XenForo Development Discussions' started by AndyB, Sep 27, 2013.

  1. AndyB

    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);
       }
    }

    ?>
     
  2. Daniel Hood

    Daniel Hood Well-Known Member

    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.
     
  3. AndyB

    AndyB Well-Known Member

    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.
     
  4. Daniel Hood

    Daniel Hood Well-Known Member

    in the second argument in the getThreads call add 'limit' => 50.
     
  5. AndyB

    AndyB Well-Known Member

    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,)))
         );
     
  6. AndyB

    AndyB Well-Known Member

    Now to see if I can make a similar model query for the $posts.
     
  7. Daniel Hood

    Daniel Hood Well-Known Member

    It's the same thing. just model_post instead and getPosts.
     
  8. AndyB

    AndyB Well-Known Member

    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: Sep 27, 2013
  9. AndyB

    AndyB Well-Known Member

  10. Daniel Hood

    Daniel Hood Well-Known Member

    Yeah if the function doesn't exist then you should extend it and make the function. use the proxy system.
     
  11. AndyB

    AndyB Well-Known Member

    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
     
  12. Marcus

    Marcus Well-Known Member

    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));
         }
       }
    }
     
  13. Marcus

    Marcus Well-Known Member

    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.
     
  14. AndyB

    AndyB Well-Known Member

    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.
     
  15. Daniel Hood

    Daniel Hood Well-Known Member

    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).
     
    Marcus likes this.
  16. AndyB

    AndyB Well-Known Member

    Hi Daniel,

    I'm going to break this down as there are several things I don't understand.

    Which file requires editing?
     
  17. AndyB

    AndyB Well-Known Member

    If I understand correctly, do I need to create a Code Event Listener?
     
  18. Jeremy

    Jeremy XenForo Moderator Staff Member

    Marcus likes this.
  19. Marcus

    Marcus Well-Known Member

    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
     
  20. AndyB

    AndyB Well-Known Member

    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.jpg
     

Share This Page