How to kick one or more Comments from CommentModel::Get
R_J
Admin
I have $Comments and want to delete some $Comment from them. The code by now is that:
$CommentID = 100; // <- just some arbitrary number
$CommentModel = new CommentModel();
$Comments = $CommentModel->Get($DiscussionID);
foreach ($Comments as $Comment) {
if ($Comment->CommentID <= $CommentID) {
$unset($Comment); // not working, because it does not change $Comments
$Comment = NULL; // not working for the same reason
}
}
The code in the loop doesn't work. It's obvious because they do not refer to the $Comments scope but only to the $Comment.
But there seems to be also another problem. Each $Comment is stored in an array [_Result] which is protected.
So I assumed I would have to "clone" the $Comments object, but a $MyComments = clone $Comments, also cloned the protected array.
This problem is far beyond my PHP knowledge. Can anyone guide me on how to achieve something like that?
Yes, I know I could try to achieve something like that with an $Offset in the Get-function, but I'd prefer getting all comments and sorting them out afterwards...
Best Answer
-
R_J
Admin
YEAH! Garden is just too awesome:
$Comments = $CommentModel->Get($DiscussionID); $CommentsFiltered = array(); foreach ($Comments as $Comment) { if ($Comment->CommentID > $CommentID) { $CommentsFiltered[] = $Comment; } } $Comments->ImportDataset($CommentsFiltered);And that's it!
2
Answers
You want to remove the comment permanently from the db or just from your $Comments object?
If it is the latter, something like this should work:
foreach ($Comments as $Index => $Comment) { if ($Comment->CommentID <= $CommentID) { $unset($Comments[$Index]); } }Yes, I just want to remove one or more comments from the $Comments object.
Your code gives that error message
Fatal error: Cannot use object of type Gdn_DataSet as arrayI just tested this code against 2.0.18.10:
$DiscussionID = 17; $Limit = 30; $CommentID = 100; $CommentModel = new CommentModel(); $Comments = $CommentModel->Get($DiscussionID, $Limit)->Result(); decho($Comments); foreach ($Comments as $Index => $Comment) { if ($Comment->CommentID <= $CommentID) { unset($Comments[$Index]); } } decho($Comments);Output from my install is:
DEBUG: Array ( [0] => stdClass Object ( [CommentID] => 24 [DiscussionID] => 17 [InsertUserID] => 1 [UpdateUserID] => [DeleteUserID] => [Body] => gvfsdg sdfsdf ad [Format] => Html [DateInserted] => 2014-01-20 19:16:18 [DateDeleted] => [DateUpdated] => [InsertIPAddress] => 127.0.0.1 [UpdateIPAddress] => [Flag] => 0 [Score] => [Attributes] => [InsertName] => hgtonight [InsertEmail] => hgtonight@daklutz.com [InsertPhoto] => [UpdateName] => [UpdateEmail] => [UpdatePhoto] => ) [1] => stdClass Object ( [CommentID] => 25 [DiscussionID] => 17 [InsertUserID] => 1 [UpdateUserID] => [DeleteUserID] => [Body] => a fdsf dasf da f [Format] => Html [DateInserted] => 2014-01-20 19:16:20 [DateDeleted] => [DateUpdated] => [InsertIPAddress] => 127.0.0.1 [UpdateIPAddress] => [Flag] => 0 [Score] => [Attributes] => [InsertName] => hgtonight [InsertEmail] => hgtonight@daklutz.com [InsertPhoto] => [UpdateName] => [UpdateEmail] => [UpdatePhoto] => ) [2] => stdClass Object ( [CommentID] => 26 [DiscussionID] => 17 [InsertUserID] => 1 [UpdateUserID] => [DeleteUserID] => [Body] => a fd adf ad [Format] => Html [DateInserted] => 2014-01-20 19:16:22 [DateDeleted] => [DateUpdated] => [InsertIPAddress] => 127.0.0.1 [UpdateIPAddress] => [Flag] => 0 [Score] => [Attributes] => [InsertName] => hgtonight [InsertEmail] => hgtonight@daklutz.com [InsertPhoto] => [UpdateName] => [UpdateEmail] => [UpdatePhoto] => ) ) DEBUG: Array ( )Get()->Result() does the job but I can't use it with my plugin by now
/plugins/DiscussionRefresh/class.discussionrefresh.php:<?php if (!defined('APPLICATION')) exit(); $PluginInfo['DiscussionRefresh'] = array( 'Name' => 'Discussion Refresh', 'Description' => 'Shows comments that have been posted to a discussion between opening it and pressing preview button', 'Version' => '0.1', 'RequiredApplications' => array('Vanilla' => '2.0.18'), 'HasLocale' => FALSE, 'Author' => "Robin", 'RegisterPermissions' => FALSE ); class DiscussionRefreshPlugin extends Gdn_Plugin { // route all requests to /discussion/discussionrefreh/... to function Controller_... public function DiscussionController_DiscussionRefresh_Create($Sender, $Args) { return $this->Dispatch($Sender); } // default action is to return comments of a given discussion public function Controller_Index($Sender) { //get all comments of a discussion and return only the latest $Args = $Sender->RequestArgs; // no request, no result if (count($Args) == 0) return FALSE; $DiscussionID = $Args[0]; $CommentID = $Args[1]; // check for proper discussionid if (!is_numeric($DiscussionID)) return FALSE; $CommentModel = new CommentModel(); $Comments = $CommentModel->Get($DiscussionID)->Result(); // if no comment id is given, return all comments if (!is_numeric($CommentID)) $CommentID = 0; decho($Comments); foreach ($Comments as $Index => $Comment) { if ($Comment->CommentID <= $CommentID) { unset($Comments[$Index]); } } decho($Comments); $Sender->SetData('CommentData', $Comments, TRUE); //$Sender->DeliveryType = 'VIEW'; //&DeliveryMethod=JSON $Sender->Render($Sender->FetchViewLocation('comments', 'discussion')); } }I need an object, as far as I can see, if I want to reuse the standard comment views
Ahh... now there is the rub. The default view assumes a gdn_dataset object is being passed. It calls Result on the passed object. You could create a wrapper object that contains a Result method on it that just returns the array. Something like this:
class CommentSliceWrapper { private $_Comments; public function SetData($commentArray) { $this->_Comments = $commentArray; } public function Result() { return $this->_Comments; } }The bigger question I am asking, is why not retrieve the entire discussion view (which will handle the entire rendering of the view) and then slice it in JS?
I just found that function in class.dataset.php and now I'm trying to go that way:
/** * Allows you to fill this object's result set with a foreign data set in * the form of an array of associative arrays (or objects). * * @param array $Resultset The array of arrays or objects that represent the data to be traversed. */ public function ImportDataset($Resultset) { ...I took your advice to fetch all comments for the caching benefit. But returning all comments and throwing most of them away after transfering them to the client would be a waste of bandwidth. It also takes longer to render each comment instead of just rendering what is needed.
Good point on the rendering aspect.
YEAH! Garden is just too awesome:
$Comments = $CommentModel->Get($DiscussionID); $CommentsFiltered = array(); foreach ($Comments as $Comment) { if ($Comment->CommentID > $CommentID) { $CommentsFiltered[] = $Comment; } } $Comments->ImportDataset($CommentsFiltered);And that's it!
@hgtonight: thanks for your help, again!
And I'm happy Garden has a simple way to solve a problem that I still could not solve with simple php...