HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

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

R_JR_J Ex-FanboyMunich Admin

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

  • hgtonighthgtonight ∞ · New Moderator

    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?

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • R_JR_J Ex-Fanboy Munich Admin

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

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

    Doesn't work either :-(

  • hgtonighthgtonight ∞ · New Moderator

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

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • R_JR_J Ex-Fanboy Munich 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 Ex-Fanboy Munich 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 Detroit 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 Ex-Fanboy Munich 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 Detroit 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 Ex-Fanboy Munich 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 Ex-Fanboy Munich 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 Ex-Fanboy Munich 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.