tag is in */ public $page = null; /** * @var Integer: total amount of comments by distinct commenters that the * current page has */ public $commentTotal = 0; /** * @var String: text of the current comment */ public $text = null; /* START Anpassung znilwiki */ public $CommentUsernameKOK = null; /* 25.10.2013 von Kai-Ole Kirsten */ public $UsernameKOK = null; /* 25.10.2013 von Kai-Ole Kirsten */ /* ENDE Anpassung znilwiki */ /** * Date when the comment was posted * * @var null */ public $date = null; /** * @var Integer: internal ID number (Comments.CommentID DB field) of the * current comment that we're dealing with */ public $id = 0; /** * @var Integer: ID of the parent comment, if this is a child comment */ public $parentID = 0; /** * The current vote from this user on this comment * * @var int|boolean: false if no vote, otherwise -1, 0, or 1 */ public $currentVote = false; /** * @var string: comment score (SUM() of all votes) of the current comment */ public $currentScore = '0'; /** * Username of the user who posted the comment * * @var string */ public $username = ''; /** * IP of the comment poster * * @var string */ public $ip = ''; /** * ID of the user who posted the comment * * @var int */ public $userID = 0; /** * @TODO document * * @var int */ public $userPoints = 0; /** * Comment ID of the thread this comment is in * this is the ID of the parent comment if there is one, * or this comment if there is not * Used for sorting * * @var null */ public $thread = null; /** * Unix timestamp when the comment was posted * Used for sorting * Processed from $date * * @var null */ public $timestamp = null; /** * Constructor - set the page ID * * @param $page CommentsPage: ID number of the current page * @param IContextSource $context * @param $data: straight from the DB about the comment */ public function __construct( CommentsPage $page, $context = null, $data ) { $this->page = $page; $this->setContext( $context ); $this->username = $data['Comment_Username']; $this->ip = $data['Comment_IP']; $this->text = $data['Comment_Text']; $this->date = $data['Comment_Date']; $this->userID = $data['Comment_user_id']; $this->userPoints = $data['Comment_user_points']; $this->id = $data['CommentID']; $this->parentID = $data['Comment_Parent_ID']; $this->thread = $data['thread']; $this->timestamp = $data['timestamp']; if ( isset( $data['current_vote'] ) ) { $vote = $data['current_vote']; } else { $dbr = wfGetDB( DB_SLAVE ); $row = $dbr->selectRow( 'Comments_Vote', array( 'Comment_Vote_Score' ), array( 'Comment_Vote_ID' => $this->id, 'Comment_Vote_Username' => $this->getUser()->getName() ), __METHOD__ ); if ( $row !== false ) { $vote = $row->Comment_Vote_Score; } else { $vote = false; } } $this->currentVote = $vote; $this->currentScore = isset( $data['total_vote'] ) ? $data['total_vote'] : $this->getScore(); } public static function newFromID( $id ) { $context = RequestContext::getMain(); $dbr = wfGetDB( DB_SLAVE ); if ( !is_numeric( $id ) || $id == 0 ) { return null; } $tables = array(); $params = array(); $joinConds = array(); // Defaults (for non-social wikis) $tables[] = 'Comments'; $fields = array( 'Comment_Username', 'Comment_IP', 'Comment_Text', 'Comment_Date', 'Comment_Date AS timestamp', 'Comment_user_id', 'CommentID', 'Comment_Parent_ID', 'CommentID', 'Comment_Page_ID' ); // If SocialProfile is installed, query the user_stats table too. if ( class_exists( 'UserProfile' ) && $dbr->tableExists( 'user_stats' ) ) { $tables[] = 'user_stats'; $fields[] = 'stats_total_points'; $joinConds = array( 'Comments' => array( 'LEFT JOIN', 'Comment_user_id = stats_user_id' ) ); } // Perform the query $res = $dbr->select( $tables, $fields, array( 'CommentID' => $id ), __METHOD__, $params, $joinConds ); $row = $res->fetchObject(); if ( $row->Comment_Parent_ID == 0 ) { $thread = $row->CommentID; } else { $thread = $row->Comment_Parent_ID; } $data = array( 'Comment_Username' => $row->Comment_Username, 'Comment_IP' => $row->Comment_IP, 'Comment_Text' => $row->Comment_Text, 'Comment_Date' => $row->Comment_Date, 'Comment_user_id' => $row->Comment_user_id, 'Comment_user_points' => ( isset( $row->stats_total_points ) ? number_format( $row->stats_total_points ) : 0 ), 'CommentID' => $row->CommentID, 'Comment_Parent_ID' => $row->Comment_Parent_ID, 'thread' => $thread, 'timestamp' => wfTimestamp( TS_UNIX, $row->timestamp ) ); $page = new CommentsPage( $row->Comment_Page_ID, $context ); return new Comment( $page, $context, $data ); } /** * Parse and return the text for this comment * * @return mixed|string * @throws MWException */ function getText() { global $wgParser; $commentText = trim( str_replace( '"', "'", $this->text ) ); $comment_text_parts = explode( "\n", $commentText ); $comment_text_fix = ''; foreach ( $comment_text_parts as $part ) { $comment_text_fix .= ( ( $comment_text_fix ) ? "\n" : '' ) . trim( $part ); } if ( $this->getTitle()->getArticleID() > 0 ) { $commentText = $wgParser->recursiveTagParse( $comment_text_fix ); } else { $commentText = $this->getOutput()->parse( $comment_text_fix ); } // really bad hack because we want to parse=firstline, but don't want wrapping

tags if ( substr( $commentText, 0 , 3 ) == '

' ) { $commentText = substr( $commentText, 3 ); } if ( substr( $commentText, strlen( $commentText ) -4 , 4 ) == '

' ) { $commentText = substr( $commentText, 0, strlen( $commentText ) -4 ); } // make sure link text is not too long (will overflow) // this function changes too long links to http://www.abc....xyz.html $commentText = preg_replace_callback( "/(]*>)(.*?)(<\/a>)/i", array( 'CommentFunctions', 'cutCommentLinkText' ), $commentText ); return $commentText; } /** * Adds the comment and all necessary info into the Comments table in the * database. * * @param string $text: text of the comment * @param CommentsPage $page: container page * @param User $user: user commenting * @param int $parentID: ID of parent comment, if this is a reply * * @return Comment: the added comment */ static function add( $text, CommentsPage $page, User $user, $parentID ) { global $wgCommentsInRecentChanges; $dbw = wfGetDB( DB_MASTER ); $context = RequestContext::getMain(); wfSuppressWarnings(); $commentDate = date( 'Y-m-d H:i:s' ); wfRestoreWarnings(); // ##START## 2017-09-27 von Bernhard Linz // if ( $this->getUser()->isLoggedIn() ) { // $kok_username = $user->getName(); // $kok_username = $this->UsernameKOK; // } else { $kok_username = preg_match('/(?<=#START#).*?(?=#ENDE#)/s', $text, $result); $kok_username = $result[0]; $text = str_replace('#START#' . $result[0] . '#ENDE#', '', $text); // $kok_username = str_replace('#START#', '', $kok_username); // $kok_username = str_replace('#ENDE#', '', $kok_username); if ( $kok_username == "" ) { $kok_username = $user->getName(); } if ( $kok_username == "none" ) { $kok_username = $user->getName(); } // $kok_username = preg_replace('/<.*>/i', '', $kok_username); // $kok_username = preg_replace('/[^A-Za-z0-9. \-\@]/i', '', $kok_username); // $kok_username = str_replace("1'1", '', $kok_username); // $kok_username = str_replace('USER_NAME', '', $kok_username); // $kok_username = str_replace('DESC', '', $kok_username); // $kok_username = str_replace('(*)', '', $kok_username); // $kok_username = str_replace('EXEC', '', $kok_username); */ // } // ##ENDE## 2017-09-27 von Bernhard Linz $dbw->insert( 'Comments', array( 'Comment_Page_ID' => $page->id, //'Comment_Username' => $user->getName(), 'Comment_Username' => $kok_username, 'Comment_user_id' => $user->getId(), 'Comment_Text' => $text, 'Comment_Date' => $commentDate, 'Comment_Parent_ID' => $parentID, 'Comment_IP' => $_SERVER['REMOTE_ADDR'] ), __METHOD__ ); $commentId = $dbw->insertId(); $dbw->commit( __METHOD__ ); // misza: added this $id = $commentId; $page->clearCommentListCache(); // Add a log entry. self::log( 'add', $user, $page->id, $commentId, $text ); $dbr = wfGetDB( DB_SLAVE ); if ( class_exists( 'UserProfile' ) && $dbr->tableExists( 'user_stats' ) ) { $res = $dbr->select( // need this data for seeding a Comment object 'user_stats', 'stats_total_points', array( 'stats_user_id' => $user->getId() ), __METHOD__ ); $row = $res->fetchObject(); $userPoints = number_format( $row->stats_total_points ); } else { $userPoints = 0; } if ( $parentID == 0 ) { $thread = $id; } else { $thread = $parentID; } $data = array( 'Comment_Username' => $user->getName(), 'Comment_IP' => $context->getRequest()->getIP(), 'Comment_Text' => $text, 'Comment_Date' => $commentDate, 'Comment_user_id' => $user->getID(), 'Comment_user_points' => $userPoints, 'CommentID' => $id, 'Comment_Parent_ID' => $parentID, 'thread' => $thread, 'timestamp' => strtotime( $commentDate ) ); $page = new CommentsPage( $page->id, $context ); $comment = new Comment( $page, $context, $data ); Hooks::run( 'Comment::add', array( $comment, $commentId, $comment->page->id ) ); /* ## START Kommentar auch per Email versenden ## 11/2014 Bernhard Linz */ //$title = Title::makeTitle( NS_USER, $this->username ); $znilpageTitle = Title::newFromID( $comment->page->id ); $comment_mailto = "root@linz.email"; $comment_mailsubject = "Neuer Kommentar von: " . $kok_username . " - IP: " . $_SERVER['REMOTE_ADDR'] . " - DNS: " . gethostbyaddr($_SERVER['REMOTE_ADDR']) ; $comment_mailfrom = "MIME-Version: 1.0\r\n"; $comment_mailfrom .= "Content-type: text/html; charset=utf-8\r\n"; $comment_mailfrom .= "From: znil.net Kommentare \r\n"; // $comment_url = $znilpageTitle; $comment_url = "https://znil.net/index.php?title={$znilpageTitle}#comment-{$commentId}"; // $comment_url = "getFullURL() . "\">" . $title->getFullURL() . ""; $comment_mailtext = $commentDate . "

" . $comment_url . "


" . "IP: " . $_SERVER['REMOTE_ADDR'] . "
" . "DNS: " . gethostbyaddr($_SERVER['REMOTE_ADDR']) ."

" . $kok_username . "

" . $text; $comment_mailtext = nl2br($comment_mailtext); mail($comment_mailto, $comment_mailsubject, $comment_mailtext, $comment_mailfrom); /* ## ENDE Bernhard Linz */ return $comment; } /** * Gets the score for this comment from the database table Comments_Vote * * @return string */ function getScore() { $dbr = wfGetDB( DB_SLAVE ); $row = $dbr->selectRow( 'Comments_Vote', array( 'SUM(Comment_Vote_Score) AS CommentScore' ), array( 'Comment_Vote_ID' => $this->id ), __METHOD__ ); $score = '0'; if ( $row !== false && $row->CommentScore ) { $score = $row->CommentScore; } return $score; } /* START Anpassungen znilwiki */ /* ## START ## 25.10.2013 HinzugefĆ¼gt von Kai-Ole */ function setCommentUsernameKOK( $UsernameKOK ) { $this->CommentUsernameKOK = $UsernameKOK; } /* ## ENDE ## 25.10.2013 Kai-Ole */ /* ENDE Anpassungen znilwiki */ /** * Adds a vote for a comment if the user hasn't voted for said comment yet. * * @param $value int: upvote or downvote (1 or -1) */ function vote( $value ) { global $wgMemc; $dbw = wfGetDB( DB_MASTER ); if ( $value < -1 ) { // limit to range -1 -> 0 -> 1 $value = -1; } elseif ( $value > 1 ) { $value = 1; } if ( $value == $this->currentVote ) { // user toggling off a preexisting vote $value = 0; } wfSuppressWarnings(); $commentDate = date( 'Y-m-d H:i:s' ); wfRestoreWarnings(); if ( $this->currentVote === false ) { // no vote, insert $dbw->insert( 'Comments_Vote', array( 'Comment_Vote_id' => $this->id, 'Comment_Vote_Username' => $this->getUser()->getName(), 'Comment_Vote_user_id' => $this->getUser()->getId(), 'Comment_Vote_Score' => $value, 'Comment_Vote_Date' => $commentDate, 'Comment_Vote_IP' => $_SERVER['REMOTE_ADDR'] ), __METHOD__ ); } else { // already a vote, update $dbw->update( 'Comments_Vote', array( 'Comment_Vote_Score' => $value, 'Comment_Vote_Date' => $commentDate, 'Comment_Vote_IP' => $_SERVER['REMOTE_ADDR'] ), array( 'Comment_Vote_id' => $this->id, 'Comment_Vote_Username' => $this->getUser()->getName(), 'Comment_Vote_user_id' => $this->getUser()->getId(), ), __METHOD__ ); } $dbw->commit( __METHOD__ ); // update cache for comment list // should perform better than deleting cache completely since Votes happen more frequently $key = wfMemcKey( 'comment', 'pagethreadlist', $this->page->id ); $comments = $wgMemc->get( $key ); if ( $comments ) { foreach ( $comments as &$comment ) { if ( $comment->id == $this->id ) { $comment->currentScore = $this->currentScore; } } $wgMemc->set( $key, $comments ); } $score = $this->getScore(); $this->currentVote = $value; $this->currentScore = $score; } /** * Deletes entries from Comments and Comments_Vote tables and clears caches */ function delete() { $dbw = wfGetDB( DB_MASTER ); $dbw->delete( 'Comments', array( 'CommentID' => $this->id ), __METHOD__ ); $dbw->delete( 'Comments_Vote', array( 'Comment_Vote_ID' => $this->id ), __METHOD__ ); $dbw->commit( __METHOD__ ); // Log the deletion to Special:Log/comments. self::log( 'delete', $this->getUser(), $this->page->id, $this->id ); // Clear memcache & Squid cache $this->page->clearCommentListCache(); // Ping other extensions that may have hooked into this point (i.e. LinkFilter) Hooks::run( 'Comment::delete', array( $this, $this->id, $this->page->id ) ); } /** * Log an action in the comment log. * * @param string $action Action to log, can be either 'add' or 'delete' * @param User $user User who performed the action * @param int $pageId Page ID of the page that contains the comment thread * @param int $commentId Comment ID of the affected comment * @param string $commentText Supplementary log comment, if any */ static function log( $action, $user, $pageId, $commentId, $commentText = null ) { global $wgCommentsInRecentChanges; $logEntry = new ManualLogEntry( 'comments', $action ); $logEntry->setPerformer( $user ); $logEntry->setTarget( Title::newFromId( $pageId ) ); if ( $commentText !== null ) { $logEntry->setComment( $commentText ); } $logEntry->setParameters( array( '4::commentid' => $commentId ) ); $logId = $logEntry->insert(); $logEntry->publish( $logId, ( $wgCommentsInRecentChanges ? 'rcandudp' : 'udp' ) ); } /** * Return the HTML for the comment vote links * * @param int $voteType up (+1) vote or down (-1) vote * @return string */ function getVoteLink( $voteType ) { global $wgExtensionAssetsPath; // Blocked users cannot vote, obviously if ( $this->getUser()->isBlocked() ) { return ''; } if ( !$this->getUser()->isAllowed( 'comment' ) ) { return ''; } $voteLink = ''; if ( $this->getUser()->isLoggedIn() ) { $voteLink .= ''; } else { $login = SpecialPage::getTitleFor( 'Userlogin' ); // Anonymous users need to log in before they can vote $returnTo = $this->page->title->getPrefixedDBkey(); // Determine a sane returnto URL parameter $voteLink .= "getLocalURL( array( 'returnto' => $returnTo ) ) ) . "\" rel=\"nofollow\">"; } $imagePath = $wgExtensionAssetsPath . '/Comments/resources/images'; if ( $voteType == 1 ) { if ( $this->currentVote == 1 ) { $voteLink .= "\"+\""; } else { $voteLink .= "\"+\""; } } else { if ( $this->currentVote == -1 ) { $voteLink .= "\"+\""; } else { $voteLink .= "\"+\""; } } return $voteLink; } /** * Show the HTML for this comment and ignore section * * @param array $blockList list of users the current user has blocked * @param array $anonList map of ip addresses to names like anon#1, anon#2 * @return string html */ function display( $blockList, $anonList ) { if ( $this->parentID == 0 ) { $container_class = 'full'; } else { $container_class = 'reply'; } $output = ''; if ( in_array( $this->username, $blockList ) ) { $output .= $this->showIgnore( false, $container_class ); $output .= $this->showComment( true, $container_class, $blockList, $anonList ); } else { $output .= $this->showIgnore( true, $container_class ); $output .= $this->showComment( false, $container_class, $blockList, $anonList ); } return $output; } function displayForCommentOfTheDay() { $output = ''; $title2 = $this->page->getTitle(); if ( $this->userID != 0 ) { $title = Title::makeTitle( NS_USER, $this->username ); $commentPoster_Display = $this->username; $commentPoster = '' . $this->username . ''; if ( class_exists( 'wAvatar' ) ) { $avatar = new wAvatar( $this->userID, 's' ); $commentIcon = $avatar->getAvatarImage(); } else { $commentIcon = ''; } } else { // ##START## 27.09.2017 von Bernhard Linz $commentPoster_Display = $this->username; $commentPoster = $this->username; // $commentPoster_Display = wfMessage( 'comments-anon-name' )->plain(); // $commentPoster = wfMessage( 'comments-anon-name' )->plain(); $commentIcon = 'default_s.gif'; // ##ENDE## } $avatarHTML = ''; if ( class_exists( 'wAvatar' ) ) { global $wgUploadPath; $avatarHTML = ''; } $comment_text = substr( $this->text, 0, 50 - strlen( $commentPoster_Display ) ); if ( $comment_text != $this->text ) { $comment_text .= wfMessage( 'ellipsis' )->plain(); } $output .= '
'; $sign = ''; if ( $this->currentScore > 0 ) { $sign = '+'; } elseif ( $this->currentScore < 0 ) { $sign = '-'; // this *really* shouldn't be happening... } $output .= '' . $sign . $this->currentScore . ' ' . $avatarHTML . '' . $commentPoster . ''; $output .= '' . $comment_text . ''; $output .= '
'; return $output; } /** * Show the box for if this comment has been ignored * * @param bool $hide * @param $containerClass * @return string */ function showIgnore( $hide = false, $containerClass ) { $blockListTitle = SpecialPage::getTitleFor( 'CommentIgnoreList' ); $style = ''; if ( $hide ) { $style = " style='display:none;'"; } $output = "
\n"; $output .= wfMessage( 'comments-ignore-message' )->parse(); $output .= '' . "\n"; $output .= '
' . "\n"; return $output; } /** * Show the comment * * @param bool $hide: if true, comment is returned but hidden (display:none) * @param $containerClass * @param $blockList * @param $anonList * @return string */ function showComment( $hide = false, $containerClass, $blockList, $anonList ) { global $wgUserLevels, $wgExtensionAssetsPath; $style = ''; if ( $hide ) { $style = " style='display:none;'"; } $commentPosterLevel = ''; if ( $this->userID != 0 ) { $title = Title::makeTitle( NS_USER, $this->username ); $commentPoster = '' . $this->username . ''; $CommentReplyTo = $this->username; if ( $wgUserLevels && class_exists( 'UserLevel' ) ) { $user_level = new UserLevel( $this->userPoints ); $commentPosterLevel = "{$user_level->getLevelName()}"; } $user = User::newFromId( $this->userID ); $CommentReplyToGender = $user->getOption( 'gender', 'unknown' ); } else { // ##START## 27.09.2017 von Bernhard Linz $anonMsg = $this->msg( 'comments-anon-name' )->inContentLanguage()->plain(); //$commentPoster = $anonMsg . ' #' . $anonList[$this->username]; $commentPoster = $this->username; if ( filter_var($commentPoster, FILTER_VALIDATE_IP) !== false ){ // Wert ist eine IP-Adresse $commentPoster = $anonMsg . ' #' . $anonList[$this->username]; } $CommentReplyTo = $anonMsg; $CommentReplyToGender = 'unknown'; // Undisclosed gender as anon user $commentPoster = '' . $commentPoster . ''; // ##ENDE## } // Comment delete button for privileged users $dlt = ''; if ( $this->getUser()->isAllowed( 'commentadmin' ) ) { $dlt = ' | ' . '' . $this->msg( 'comments-delete-link' )->plain() . ''; } // Reply Link (does not appear on child comments) $replyRow = ''; if ( $this->getUser()->isAllowed( 'comment' ) ) { if ( $this->parentID == 0 ) { if ( $replyRow ) { $replyRow .= wfMessage( 'pipe-separator' )->plain(); } $replyRow .= " | id}\" data-comments-safe-username=\"" . htmlspecialchars( $CommentReplyTo, ENT_QUOTES ) . "\" data-comments-user-gender=\"" . htmlspecialchars( $CommentReplyToGender ) . '">' . wfMessage( 'comments-reply' )->plain() . ''; } } if ( $this->parentID == 0 ) { $comment_class = 'f-message'; } else { $comment_class = 'r-message'; } // Display Block icon for logged in users for comments of users // that are already not in your block list $blockLink = ''; if ( $this->getUser()->getID() != 0 && $this->getUser()->getID() != $this->userID && !( in_array( $this->userID, $blockList ) ) ) { $blockLink = ' \"\"/ "; } // Default avatar image, if SocialProfile extension isn't enabled global $wgCommentsDefaultAvatar; if ( $this->username == "BLinz" ) { $avatarImg = ''; } else { $avatarImg = ''; } // $avatarImg = ''; // If SocialProfile *is* enabled, then use its wAvatar class to get the avatars for each commenter if ( class_exists( 'wAvatar' ) ) { $avatar = new wAvatar( $this->userID, 'ml' ); $avatarImg = $avatar->getAvatarURL() . "\n"; } $output = "
" . "\n"; $output .= "
{$avatarImg}
" . "\n"; $output .= '
' . "\n"; $output .= '
' . "\n"; $output .= "{$commentPoster}"; $output .= "{$commentPosterLevel} {$blockLink}" . "\n"; wfSuppressWarnings(); // E_STRICT bitches about strtotime() $output .= '
' . wfMessage( 'comments-time-ago', CommentFunctions::getTimeAgo( strtotime( $this->date ) ) )->parse() . '
' . "\n"; wfRestoreWarnings(); $output .= '
' . "\n"; $output .= $this->getScoreHTML(); $output .= '
' . "\n"; $output .= '
' . "\n"; $output .= "
" . "\n"; $output .= $this->getText(); $output .= '
' . "\n"; $output .= '
' . "\n"; if ( $this->page->title ) { // for some reason doesn't always exist $output .= 'id}\" rel=\"nofollow\">" . $this->msg( 'comments-permalink' )->plain() . ' '; } if ( $replyRow || $dlt ) { $output .= "{$replyRow} {$dlt}" . "\n"; } $output .= '
' . "\n"; $output .= '
' . "\n"; $output .= '
' . "\n"; $output .= '
' . "\n"; return $output; } /** * Get the HTML for the comment score section of the comment * * @return string */ function getScoreHTML() { $output = ''; if ( $this->page->allowMinus == true || $this->page->allowPlus == true ) { $output .= '' . wfMessage( 'comments-score-text' )->plain() . " id}\">{$this->currentScore}"; // Voting is possible only when database is unlocked if ( !wfReadOnly() ) { // You can only vote for other people's comments, not for your own if ( $this->getUser()->getName() != $this->username ) { $output .= "id}\">"; if ( $this->page->allowPlus == true ) { $output .= $this->getVoteLink( 1 ); } if ( $this->page->allowMinus == true ) { $output .= $this->getVoteLink( -1 ); } $output .= ''; } else { $output .= wfMessage( 'word-separator' )->plain() . wfMessage( 'comments-you' )->plain(); } } } return $output; } }