How to `$DiscussionView = $DiscussionController->Index($DiscussionID);`?

I would like to have the result of /discussion/11/blablubb&DeliveryType=VIEW inside of a variable in PHP. So I thought that this should be a call to the DiscussionControllers function Index, with the $DiscussionID as a parameter, and the DeliveryMethod set accordingly. When I do that...

    public function discussionController_myPlugin_create($Sender, $Args){
        $DiscussionID = $Args[0] + 0;

$DiscussionModel = new DiscussionModel();
$Discussion = $DiscussionModel->GetID($DiscussionID);
decho($Discussion); // just a test to ensure the discussion id is not the problem

        $DiscussionController = new DiscussionController();
        $DiscussionController->DeliveryType('VIEW');
// everything is fine until here...
        $DiscussionView = $DiscussionController->Index($DiscussionID);
decho($DiscussionView); // that line is never reached. The above line breaks my code
    }

... nothing happens :(

Obviously I cannot use $DiscussionView = $DiscussionController->Index($DiscussionID); but what could I do instead of that? Using file_get_contents('/discussion/11/blablubb&DeliveryType=VIEW'); instead looks kind of foolish to me.

Best Answer

Answers

  • Your decho never executes because DiscussionController::Index() calls the render method which will spit out a bunch of HTML and then end the PHP process.

    Do you want to render the view and get the contents in a string for further manipulation?

    Or do you just want the page to render exactly the same as the default discussion view?

  • R_JR_J Admin

    The first one: get the contents in a string and work with that

  • R_JR_J Admin
    ob_start();
            $DiscussionController->Index($DiscussionID);
    $DiscussionView = ob_get_clean();
    decho($DiscussionView);
    

    Doesn't work either :-(

  • You should be able to use the Gdn_Controller::FetchView()like $html = $this->FetchView('index','discussion','vanilla');

  • R_JR_J Admin

    Still not sure how to get me results... :(

    Using $this gives me
    The Plugin object does not have a "xFetchView" method.
    I understand that

    Using $Sender gives me another error
    DiscussionController->CanEditComments not found
    Could $Sender be right? I might have to set $Sender->DeliveryType beforehand, I think. But anyway - it is not working for any other reason that I do not understand.

    Using $DiscussionController gives me a "Whoops, view not found"

  • R_JR_J Admin

    I'm slightly disappointed. Normally Garden is way more easy... :-/

    I think I will work through DiscussionController::Index and see what is stored to "$this" in that function. I hope it would be enough to fill $Sender with that information.

  • LincLinc Admin

    Can you back up and start with what you're trying to do? I think you presented the issue about 2 steps down the rabbit hole and you may already be off in the wrong tunnel.

  • R_JR_J Admin

    Today I have made it. Don't know why it didn't work at the first try. In the end it is as easy as expected ;)

        public function discussionController_refreshOnPreview_create($Sender, $Args){
            $DiscussionID = $Args[0] + 0;
            $LastCommentID = $Args[1] + 0;
    
            $Sender->DeliveryType('VIEW');
            ob_start();
            $Sender->Index($DiscussionID);
            $HtmlOut = ob_get_clean();
            // echo $HtmlOut;
    
            $doc = new DOMDocument();
            $doc->loadHTML($HtmlOut);
            $xpath = new DOMXpath($doc);
    
            foreach($xpath->query("//li[@id='Comment_{$LastCommentID}']/following-sibling::li") as $el){
                // create new dom document from each $el and return that...
            }
    

    See what I'm doing? I'm building a Refresh On Preview plugin that will append new comments to a discussion when the user presses [Preview]. It's almost finished :)

  • LincLinc Admin
    edited July 2014

    Have you looked at DiscussionController->GetNew()? It seems to me this would mostly be done in Javascript with a call to that endpoint.

    We don't do this sort of thing in core currently because of scaling concerns. Calling arbitrary ranges of comments means far less effective caching.

  • R_JR_J Admin

    Caching is the reason why I pass LastCommentID and call index. I think that way is the best way in terms of resource usage.

  • R_JR_J Admin

    I thought that querying the complete discussion index will be easier to cache, but since it is combined with UserDiscussion, it will be a different query for each user and thus not being a real advantage. At least that's what I think now...

    Maybe it would be better to get all comments and transform only the new comments to html like that:

    public function discussionController_refreshOnPreview_create($Sender, $Args){
        $DiscussionID = $Args[0] + 0;
        $LastCommentID = $Args[1] + 0;
    
        $CommentModel = new CommentModel();
        $Comments = $CommentModel->Get($DiscussionID);
    
        $Result = '';
    
        foreach ($Comments as $Comment) {
            $CommentID = $Comment->CommentID;
            if ($CommentID > $LastCommentID) {
                $Result .= $CommentID; // some function that converts a comment into it's view: discussion/helper_functions/WriteComment?
            }
        }
        return json_encode(array('LastCommentID' => $CommentID, 'UnreadComments' => $Result));
    }
    

    I think I'll try my luck that way. Looks like the best solution to me right now.

  • R_JR_J Admin

    Yes, I took that road and now I'm quite proud: http://vanillaforums.org/addon/discussionrefresh-plugin

    Although I feel a little unease because it relies on js and I'm still struggling with that.

Sign In or Register to comment.