EBernhardson (WMF) has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/84893


Change subject: See that a post has been edited
......................................................................

See that a post has been edited

Adds three database fields to track in what revision and by what user a post's
content was most recently edited, and some template code to display that to
a user.

Change-Id: I92577798d4f9da7fa916cd1fede93e6c171c7ee3
---
M Flow.i18n.php
M flow.sql
M includes/Model/AbstractRevision.php
M includes/Model/PostRevision.php
M includes/ParsoidUtils.php
M templates/post.html.php
6 files changed, 108 insertions(+), 27 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Flow 
refs/changes/93/84893/1

diff --git a/Flow.i18n.php b/Flow.i18n.php
index 33428b6..807a2e2 100644
--- a/Flow.i18n.php
+++ b/Flow.i18n.php
@@ -36,6 +36,7 @@
 
        'flow-edit-post-submit' => 'Submit changes',
 
+       'flow-post-edited' => 'Post {{GENDER:$1|edited}} by $1 $2',
        'flow-post-action-view' => 'Permalink',
        'flow-post-action-post-history' => 'Post history',
        'flow-post-action-censor-post' => 'Censor post',
@@ -138,6 +139,9 @@
 * $1 - username',
        'flow-reply-submit' => 'Used as label for the Submit button.',
        'flow-edit-post-submit' => 'Used as label for the Submit button.',
+       'flow-post-edited' => 'Text displayed to notify the user a post has 
been modified
+* $1 - Username that created the most recent revision of the post
+* $2 - Timestamp, relative to post creation date, of when the edit occured',
        'flow-post-action-view' => 'Used as text for the link which is used to 
view.
 {{Identical|Permalink}}',
        'flow-post-action-post-history' => 'Used as text for the link which is 
used to view post-history of the topic.',
diff --git a/flow.sql b/flow.sql
index 2cac549..349692a 100644
--- a/flow.sql
+++ b/flow.sql
@@ -119,6 +119,10 @@
        rev_mod_user_text varchar(255) binary,
        rev_mod_timestamp varchar(14) binary,
 
+       -- track who made the most recent content edit
+       rev_edit_user_id bigint unsigned,
+       rev_edit_user_text varchar(255) binary,
+
        PRIMARY KEY (rev_id)
 ) /*$wgDBTableOptions*/;
 
diff --git a/includes/Model/AbstractRevision.php 
b/includes/Model/AbstractRevision.php
index 0f48a93..5f0863d 100644
--- a/includes/Model/AbstractRevision.php
+++ b/includes/Model/AbstractRevision.php
@@ -64,6 +64,10 @@
        protected $moderatedByUserId;
        protected $moderatedByUserText;
 
+       protected $lastEditId;
+       protected $lastEditUserId;
+       protected $lastEditUserText;
+
        static public function fromStorageRow( array $row, $obj = null ) {
                if ( $obj === null ) {
                        $obj = new static;
@@ -86,6 +90,11 @@
                $obj->moderatedByUserText = $row['rev_mod_user_text'];
                $obj->moderationTimestamp = $row['rev_mod_timestamp'];
 
+               // isset required because there is a possible db migration, 
cached data will not have it
+               $obj->lastEditId = isset( $row['rev_last_edit_id'] ) ? 
UUID::create( $row['rev_last_edit_id'] ) : null;
+               $obj->lastEditUserId = isset( $row['rev_edit_user_id'] ) ? 
$row['rev_edit_user_id'] : null;
+               $obj->lastEditUserText = isset( $row['rev_edit_user_text'] ) ? 
$row['rev_edit_user_text'] : null;
+
                return $obj;
        }
 
@@ -106,6 +115,10 @@
                        'rev_mod_user_id' => $obj->moderatedByUserId,
                        'rev_mod_user_text' => $obj->moderatedByUserText,
                        'rev_mod_timestamp' => $obj->moderationTimestamp,
+
+                       'rev_last_edit_id' => $obj->lastEditId ? 
$obj->lastEditId->getBinary() : null,
+                       'rev_edit_user_id' => $obj->lastEditUserId,
+                       'rev_edit_user_text' => $obj->lastEditUserText,
                );
        }
 
@@ -123,9 +136,12 @@
                return $obj;
        }
 
+       /**
+        * Create the next revision with new content
+        */
        public function newNextRevision( User $user, $content, $comment ) {
                $obj = $this->newNullRevision( $user );
-               $obj->setContent( $content );
+               $obj->setNextContent( $user, $content );
                $obj->comment = $comment;
                return $obj;
        }
@@ -165,8 +181,14 @@
                return $this->revId;
        }
 
+       /**
+        * @param User $user The user requesting access.  When null assumes a 
user with no permissions.
+        * @param int $state One of the self::MODERATED_* constants. When null 
the internal moderation state is used.
+        * @return boolean True when the user is allowed to see the current 
revision
+        */
        // Is the user allowed to see this revision ?
        protected function isAllowed( $user = null, $state = null ) {
+               // allowing a $state to be passed is a bit hackish
                if ( $state === null ) {
                        $state = $this->moderationState;
                }
@@ -238,30 +260,44 @@
         * @throws \Exception
         */
        protected function setContent( $content ) {
+               if ( $this->content !== null ) {
+                       throw new \Exception( 'Updating content must use 
setNextContent method' );
+               }
+               // TODO: How is this guarantee of only receiving wikitext made?
+               $this->convertedContent = array( 'wikitext' => $content );
+
+               // convert content to desired storage format
+               global $wgFlowContentFormat;
+               if ( !isset( $this->convertedContent[$wgFlowContentFormat] ) ) {
+                       $this->convertedContent[$wgFlowContentFormat] =
+                               ParsoidUtils::convert(
+                                       'wikitext',
+                                       $wgFlowContentFormat,
+                                       $this->convertedContent['wikitext']
+                               );
+               }
+
+               $this->content = $this->decompressedContent = 
$this->convertedContent[$wgFlowContentFormat];
+               $this->contentUrl = null;
+
+               // should this only remove a subset of flags?
+               $this->flags = array_filter( explode( ',', 
\Revision::compressRevisionText( $this->content ) ) );
+               $this->flags[] = $wgFlowContentFormat;
+       }
+
+       /**
+        * Apply new content to a revision.
+        */
+       protected function setNextContent( User $user, $content ) {
                if ( $this->moderationState !== self::MODERATED_NONE ) {
                        throw new \Exception( 'Cannot change content of 
restricted revision' );
                }
-
-               if ( $content !== $this->getContent( null, 'wikitext') ) {
-                       $this->convertedContent['wikitext'] = $content;
-
-                       // convert content to desired storage format
-                       global $wgFlowContentFormat;
-                       if ( !isset( 
$this->convertedContent[$wgFlowContentFormat] ) ) {
-                               $this->convertedContent[$wgFlowContentFormat] =
-                                       ParsoidUtils::convert(
-                                               'wikitext',
-                                               $wgFlowContentFormat,
-                                               
$this->convertedContent['wikitext']
-                                       );
-                       }
-
-                       $this->content = $this->decompressedContent = 
$this->convertedContent[$wgFlowContentFormat];
-                       $this->contentUrl = null;
-
-                       // should this only remove a subset of flags?
-                       $this->flags = array_filter( explode( ',', 
\Revision::compressRevisionText( $this->content ) ) );
-                       $this->flags[] = $wgFlowContentFormat;
+               if ( $content !== $this->getContent() ) {
+                       $this->content = null;
+                       $this->setContent( $content );
+                       $this->lastEditId = $this->getRevisionId();
+                       $this->lastEditUserId = $user->getId();
+                       $this->lastEditUserText = $user->getName();
                }
        }
 
@@ -306,4 +342,33 @@
                }
                return true;
        }
+
+       public function isFirstRevision() {
+               return $this->prevRevision === null;
+       }
+
+       public function isOriginalContent() {
+               return $this->lastEditId === null;
+       }
+
+       /**
+        * @param $user User requesting access to last content editor
+        * @return string
+        */
+       public function getLastContentEditorName( $user = null ) {
+               // TODO: to write this function properly will need to flesh out 
how
+               // oversighting works.  Prefer to create an external security 
class that is
+               // configurable per-wiki, pass revisions into it(or wrap them 
in it for
+               // view objects?) to get possibly protected content.
+               if ( $this->isAllowed( $user ) ) {
+                       return $this->lastEditUserText;
+               } else {
+                       return '';
+               }
+       }
+
+       public function getLastContentEditId() {
+               return $this->lastEditId;
+       }
+
 }
diff --git a/includes/Model/PostRevision.php b/includes/Model/PostRevision.php
index d450452..bea549c 100644
--- a/includes/Model/PostRevision.php
+++ b/includes/Model/PostRevision.php
@@ -32,7 +32,6 @@
                $obj->prevRevId = null; // no parent revision
                $obj->comment = 'flow-rev-message-new-post';
                $obj->setContent( $content );
-
                return $obj;
        }
 
@@ -47,7 +46,6 @@
                $obj->origCreateTime = $row['tree_orig_create_time'];
                $obj->origUserId = $row['tree_orig_user_id'];
                $obj->origUserText = $row['tree_orig_user_text'];
-
                return $obj;
        }
 
diff --git a/includes/ParsoidUtils.php b/includes/ParsoidUtils.php
index c507bb7..280d272 100644
--- a/includes/ParsoidUtils.php
+++ b/includes/ParsoidUtils.php
@@ -63,6 +63,7 @@
                        true // POST
                );
 
+               wfDebugLog( __CLASS__, __FUNCTION__ . ": Roundtripping parsoid 
for $from => $to" );
                $api = new \ApiMain( $params, true );
                $api->execute();
                $result = $api->getResultData();
diff --git a/templates/post.html.php b/templates/post.html.php
index 49da763..30cef35 100644
--- a/templates/post.html.php
+++ b/templates/post.html.php
@@ -95,6 +95,7 @@
 $replyForm = '';
 
 // Build the actions for the post
+// TODO: this whole action menu building should be some sort of class and not 
a few closures in a template
 switch( $post->getModerationState() ) {
 case $post::MODERATED_NONE:
        if ( $user->isAllowed( 'flow-hide' ) ) {
@@ -146,6 +147,7 @@
 
 // The actual output
 echo Html::openElement( 'div', array(
+
        'class' => 'flow-post-container',
        'data-post-id' => $post->getRevisionId()->getHex(),
 ) );
@@ -173,8 +175,15 @@
                                        </span>
                                </span>
                        </div>
-                       <?php if ( $post->isModerated() ): ?>
-                       <?php endif; ?>
+                       <?php if ( !$post->isOriginalContent() ): ?>
+                               <div class="flow-post-edited">
+                                       <?php echo wfMessage(
+                                               'flow-post-edited',
+                                               
$post->getLastContentEditorName( $user ),
+                                               
$post->getLastContentEditId()->getHumanTimestamp()
+                                       ); ?>
+                               </div>
+                       <?php endif ?>
                </div>
                <div class="flow-post-content">
                        <?php echo $content ?>
@@ -187,7 +196,7 @@
                                        <ul>
                                                <?php
                                                foreach( $actions as $key => 
$action ) {
-                                                       echo '<li 
class="flow-action-'.$key.'">' . $action . "</li>\n";
+                                                       echo Html::rawElement( 
'li', array( 'class' => "flow-action-$key" ), $action );
                                                }
                                                ?>
                                        </ul>

-- 
To view, visit https://gerrit.wikimedia.org/r/84893
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I92577798d4f9da7fa916cd1fede93e6c171c7ee3
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: EBernhardson (WMF) <ebernhard...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to