891 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			891 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Comment class
 | |
|  * Functions for managing comments and everything related to them, including:
 | |
|  * -blocking comments from a given user
 | |
|  * -counting the total amount of comments in the database
 | |
|  * -displaying the form for adding a new comment
 | |
|  * -getting all comments for a given page
 | |
|  *
 | |
|  * @file
 | |
|  * @ingroup Extensions
 | |
|  */
 | |
| class Comment extends ContextSource {
 | |
| 	/**
 | |
| 	 * @var CommentsPage: page of the page the <comments /> 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 <p> tags
 | |
| 		if ( substr( $commentText, 0 , 3 ) == '<p>' ) {
 | |
| 			$commentText = substr( $commentText, 3 );
 | |
| 		}
 | |
| 
 | |
| 		if ( substr( $commentText, strlen( $commentText ) -4 , 4 ) == '</p>' ) {
 | |
| 			$commentText = substr( $commentText, 0, strlen( $commentText ) -4 );
 | |
| 		}
 | |
| 
 | |
| 		// make sure link text is not too long (will overflow)
 | |
| 		// this function changes too long links to <a href=#>http://www.abc....xyz.html</a>
 | |
| 		$commentText = preg_replace_callback(
 | |
| 			"/(<a[^>]*>)(.*?)(<\/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 */
 | |
| 			$znilpageTitle = "";
 | |
| 			$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 <root@linz.email>\r\n";
 | |
| 			$comment_url = "<a href=\"http://znil.net/index.php?title={$znilpageTitle}#comment-{$commentId}\">http://znil.net/index.php?title={$znilpageTitle}#comment-{$commentId}</a>";
 | |
| 			$comment_mailtext = $commentDate . "<br><br>" . $comment_url . "<br><br><hr>" . "IP: " . $_SERVER['REMOTE_ADDR'] . "<br>" . "DNS: " . gethostbyaddr($_SERVER['REMOTE_ADDR']) ."<br><br>" . $kok_username . "<br><br>" . $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 .= '<a id="comment-vote-link" data-comment-id="' .
 | |
| 				$this->id . '" data-vote-type="' . $voteType .
 | |
| 				'" data-voting="' . $this->page->voting . '" href="javascript:void(0);">';
 | |
| 		} 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 .=
 | |
| 				"<a href=\"" .
 | |
| 				htmlspecialchars( $login->getLocalURL( array( 'returnto' => $returnTo ) ) ) .
 | |
| 				"\" rel=\"nofollow\">";
 | |
| 		}
 | |
| 
 | |
| 		$imagePath = $wgExtensionAssetsPath . '/Comments/resources/images';
 | |
| 		if ( $voteType == 1 ) {
 | |
| 			if ( $this->currentVote == 1 ) {
 | |
| 				$voteLink .= "<img src=\"{$imagePath}/up-voted.png\" border=\"0\" alt=\"+\" /></a>";
 | |
| 			} else {
 | |
| 				$voteLink .= "<img src=\"{$imagePath}/up-unvoted.png\" border=\"0\" alt=\"+\" /></a>";
 | |
| 			}
 | |
| 		} else {
 | |
| 			if ( $this->currentVote == -1 ) {
 | |
| 				$voteLink .= "<img src=\"{$imagePath}/down-voted.png\" border=\"0\" alt=\"+\" /></a>";
 | |
| 			} else {
 | |
| 				$voteLink .= "<img src=\"{$imagePath}/down-unvoted.png\" border=\"0\" alt=\"+\" /></a>";
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		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 = '<a href="' . $title->getFullURL() . '" title="' . $title->getText() . '" rel="nofollow">' . $this->username . '</a>';
 | |
| 			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 = '<img src="' . $wgUploadPath . '/avatars/' . $commentIcon .
 | |
| 				'" alt="" align="middle" border="0"/>';
 | |
| 		}
 | |
| 
 | |
| 		$comment_text = substr( $this->text, 0, 50 - strlen( $commentPoster_Display ) );
 | |
| 		if ( $comment_text != $this->text ) {
 | |
| 			$comment_text .= wfMessage( 'ellipsis' )->plain();
 | |
| 		}
 | |
| 
 | |
| 		$output .= '<div class="cod">';
 | |
| 		$sign = '';
 | |
| 		if ( $this->currentScore > 0 ) {
 | |
| 			$sign = '+';
 | |
| 		} elseif ( $this->currentScore < 0 ) {
 | |
| 			$sign = '-'; // this *really* shouldn't be happening...
 | |
| 		}
 | |
| 		$output .= '<span class="cod-score">' . $sign . $this->currentScore .
 | |
| 			'</span> ' . $avatarHTML .
 | |
| 			'<span class="cod-poster">' . $commentPoster . '</span>';
 | |
| 		$output .= '<span class="cod-comment"><a href="' .
 | |
| 			$title2->getFullURL() . '#comment-' . $this->id .
 | |
| 			'" title="' . $title2->getText() . '">' . $comment_text .
 | |
| 			'</a></span>';
 | |
| 		$output .= '</div>';
 | |
| 
 | |
| 		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 = "<div id='ignore-{$this->id}' class='c-ignored {$containerClass}'{$style}>\n";
 | |
| 		$output .= wfMessage( 'comments-ignore-message' )->parse();
 | |
| 		$output .= '<div class="c-ignored-links">' . "\n";
 | |
| 		$output .= "<a href=\"javascript:void(0);\" data-comment-id=\"{$this->id}\">" .
 | |
| 			$this->msg( 'comments-show-comment-link' )->plain() . '</a> | ';
 | |
| 		$output .= '<a href="' . htmlspecialchars( $blockListTitle->getFullURL() ) . '">' .
 | |
| 			$this->msg( 'comments-manage-blocklist-link' )->plain() . '</a>';
 | |
| 		$output .= '</div>' . "\n";
 | |
| 		$output .= '</div>' . "\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 = '<a href="' . htmlspecialchars( $title->getFullURL() ) .
 | |
| 				'" rel="nofollow">' . $this->username . '</a>';
 | |
| 
 | |
| 			$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 = '<b>' . $commentPoster . '</b>';
 | |
|             // ##ENDE##
 | |
| 		}
 | |
| 
 | |
| 		// Comment delete button for privileged users
 | |
| 		$dlt = '';
 | |
| 
 | |
| 		if ( $this->getUser()->isAllowed( 'commentadmin' ) ) {
 | |
| 			$dlt = ' | <span class="c-delete">' .
 | |
| 				'<a href="javascript:void(0);" rel="nofollow" class="comment-delete-link" data-comment-id="' .
 | |
| 				$this->id . '">' .
 | |
| 				$this->msg( 'comments-delete-link' )->plain() . '</a></span>';
 | |
| 		}
 | |
| 
 | |
| 		// 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 .= " | <a href=\"#end\" rel=\"nofollow\" class=\"comments-reply-to\" data-comment-id=\"{$this->id}\" data-comments-safe-username=\"" .
 | |
| 					htmlspecialchars( $CommentReplyTo, ENT_QUOTES ) . "\" data-comments-user-gender=\"" .
 | |
| 					htmlspecialchars( $CommentReplyToGender ) . '">' .
 | |
| 					wfMessage( 'comments-reply' )->plain() . '</a>';
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		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 = '<a href="javascript:void(0);" rel="nofollow" class="comments-block-user" data-comments-safe-username="' .
 | |
| 				htmlspecialchars( $this->username, ENT_QUOTES ) .
 | |
| 				'" data-comments-comment-id="' . $this->id . '" data-comments-user-id="' .
 | |
| 				$this->userID . "\">
 | |
| 					<img src=\"{$wgExtensionAssetsPath}/Comments/resources/images/block.svg\" border=\"0\" alt=\"\"/>
 | |
| 				</a>";
 | |
| 		}
 | |
| 
 | |
| 		// Default avatar image, if SocialProfile extension isn't enabled
 | |
| 		global $wgCommentsDefaultAvatar;
 | |
|         if ( $this->username == "BLinz" ) {
 | |
|             $avatarImg = '<img src="' . $wgExtensionAssetsPath . '/Comments/' . 'resources/images/bernhard2.gif' . '" alt="" border="0" />';
 | |
|         } else {
 | |
|             $avatarImg = '<img src="' . $wgExtensionAssetsPath . '/Comments/' . $wgCommentsDefaultAvatar . '" alt="" border="0" />';
 | |
|         }
 | |
| //		$avatarImg = '<img src="' . $wgExtensionAssetsPath . '/Comments/' . $wgCommentsDefaultAvatar . '" alt="" border="0" />';
 | |
| 		// 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 = "<div id='comment-{$this->id}' class='c-item {$containerClass}'{$style}>" . "\n";
 | |
| 		$output .= "<div class=\"c-avatar\">{$avatarImg}</div>" . "\n";
 | |
| 		$output .= '<div class="c-container">' . "\n";
 | |
| 		$output .= '<div class="c-user">' . "\n";
 | |
| 		$output .= "{$commentPoster}";
 | |
| 		$output .= "<span class=\"c-user-level\">{$commentPosterLevel}</span> {$blockLink}" . "\n";
 | |
| 
 | |
| 		wfSuppressWarnings(); // E_STRICT bitches about strtotime()
 | |
| 		$output .= '<div class="c-time">' .
 | |
| 			wfMessage(
 | |
| 				'comments-time-ago',
 | |
| 				CommentFunctions::getTimeAgo( strtotime( $this->date ) )
 | |
| 			)->parse() . '</div>' . "\n";
 | |
| 		wfRestoreWarnings();
 | |
| 
 | |
| 		$output .= '<div class="c-score">' . "\n";
 | |
| 		$output .= $this->getScoreHTML();
 | |
| 		$output .= '</div>' . "\n";
 | |
| 
 | |
| 		$output .= '</div>' . "\n";
 | |
| 		$output .= "<div class=\"c-comment {$comment_class}\">" . "\n";
 | |
| 		$output .= $this->getText();
 | |
| 		$output .= '</div>' . "\n";
 | |
| 		$output .= '<div class="c-actions">' . "\n";
 | |
| 		if ( $this->page->title ) { // for some reason doesn't always exist
 | |
| 			$output .= '<a href="' . htmlspecialchars( $this->page->title->getFullURL() ) . "#comment-{$this->id}\" rel=\"nofollow\">" .
 | |
| 			$this->msg( 'comments-permalink' )->plain() . '</a> ';
 | |
| 		}
 | |
| 		if ( $replyRow || $dlt ) {
 | |
| 			$output .= "{$replyRow} {$dlt}" . "\n";
 | |
| 		}
 | |
| 		$output .= '</div>' . "\n";
 | |
| 		$output .= '</div>' . "\n";
 | |
| 		$output .= '<div class="visualClear"></div>' . "\n";
 | |
| 		$output .= '</div>' . "\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 .= '<span class="c-score-title">' .
 | |
| 				wfMessage( 'comments-score-text' )->plain() .
 | |
| 				" <span id=\"Comment{$this->id}\">{$this->currentScore}</span></span>";
 | |
| 
 | |
| 			// 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 .= "<span id=\"CommentBtn{$this->id}\">";
 | |
| 					if ( $this->page->allowPlus == true ) {
 | |
| 						$output .= $this->getVoteLink( 1 );
 | |
| 					}
 | |
| 
 | |
| 					if ( $this->page->allowMinus == true ) {
 | |
| 						$output .= $this->getVoteLink( -1 );
 | |
| 					}
 | |
| 					$output .= '</span>';
 | |
| 				} else {
 | |
| 					$output .= wfMessage( 'word-separator' )->plain() . wfMessage( 'comments-you' )->plain();
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return $output;
 | |
| 	}
 | |
| }
 | 
