MarkAHershberger has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/376162 )

Change subject: WIP :
......................................................................

WIP :

See bug for hints.
Bug: T175052

Change-Id: I601b1449b8984fc695e5e1255be257222f02b995
---
M extension.json
M src/CategoryWatch.php
M src/Hook.php
3 files changed, 260 insertions(+), 171 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CategoryWatch 
refs/changes/62/376162/1

diff --git a/extension.json b/extension.json
index 343fa1e..a55522d 100644
--- a/extension.json
+++ b/extension.json
@@ -21,11 +21,14 @@
                "CategoryWatch": "i18n"
        },
        "Hooks": {
-               "PageContentSave": [
-                       "CategoryWatch\\Hook::onPageContentSave"
+               "RecentChanges_save": [
+                       "CategoryWatch\\Hook::onRecentChangesSave"
                ],
-               "PageContentSaveComplete": [
-                       "CategoryWatch\\Hook::onPageContentSaveComplete"
+               "SendWatchlistEmailNotification": [
+                       "CategoryWatch\\Hook::onSendWatchlistEmailNotification"
+               ],
+               "UpdateUserMailerFormattedPageStatus": [
+                       
"CategoryWatch\\Hook::onUpdateUserMailerFormattedPageStatus"
                ]
        },
        "config": {
diff --git a/src/CategoryWatch.php b/src/CategoryWatch.php
index 09469c9..768e1b0 100644
--- a/src/CategoryWatch.php
+++ b/src/CategoryWatch.php
@@ -1,8 +1,12 @@
 <?php
 
 /**
- * Misc functions for category watches
+ * CategoryWatch extension
+ * - Extends watchlist functionality to include notification about membership
+ *   changes of watched categories
  *
+ * Copyright (C) 2008  Aran Dunkley
+ * Copyright (C) 2017  Sean Chen
  * Copyright (C) 2017  Mark A. Hershberger
  *
  * This program is free software: you can redistribute it and/or modify
@@ -17,56 +21,67 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See https://www.mediawiki.org/Extension:CategoryWatch
+ *     for installation and usage details
+ * See http://www.organicdesign.co.nz/Extension_talk:CategoryWatch
+ *     for development notes and disucssion
+ *
+ * @file
+ * @ingroup Extensions
+ * @author Aran Dunkley [http://www.organicdesign.co.nz/nad User:Nad]
+ * @copyright © 2008 Aran Dunkley
+ * @licence GNU General Public Licence 2.0 or later
  */
 
 namespace CategoryWatch;
 
 class CategoryWatch {
-    public $before = [];
-    public $after = [];
+       public $before = [];
+       public $after = [];
 
-    protected $count = 0;
-    protected $allParents = [];
+       protected $count = 0;
+       protected $allParents = [];
 
-    protected $wikiPage;
-    protected $editor;
-    protected $content;
-    protected $summary;
-    protected $minorEdit;
-    protected $flags;
+       protected $wikiPage;
+       protected $editor;
+       protected $content;
+       protected $summary;
+       protected $minorEdit;
+       protected $flags;
 
-    /**
-     * Construction
-     * @param WikiPage $wikiPage the page
+       /**
+        * Construction
+        * @param WikiPage $wikiPage the page
         * @param User $user who is modifying
         * @param Content $content the new article content
         * @param string $summary the article summary (comment)
         * @param bool $isMinor minor flag
         * @param int $flags see WikiPage::doEditContent documentation for 
flags' definition
         */
-    public function __construct(
-        WikiPage $wikiPage, User $user, Content $content, $summary, $isMinor, 
$flags
-    ) {
-        $this->wikiPage;
-        $this->editor;
-        $this->content;
-        $this->summary;
-        $this->minorEdit;
-        $this->flags;
+       public function __construct(
+               WikiPage $wikiPage, User $user, Content $content, $summary, 
$isMinor, $flags
+       ) {
+               $this->wikiPage;
+               $this->editor;
+               $this->content;
+               $this->summary;
+               $this->minorEdit;
+               $this->flags;
 
                $this->before = 
$this->wikiPage->getTitle()->getParentCategories();
-        $this->doAutoCat();
-    }
+               $this->doAutoCat();
+       }
 
-    /**
-     * Notify all category watchers
-     *
+       /**
+        * Notify all category watchers
+        *
         * @param Revision $revision that was created
         * @param int $baseRevId base revision
         */
-    public function notifyCategoryWatchers(
-        Revision $revision, $baseRevId
-    ) {
+       public function notifyCategoryWatchers(
+               Revision $revision, $baseRevId
+       ) {
                # Get cats after update
                $this->after = 
$this->wikiPage->getTitle()->getParentCategories();
 
@@ -88,9 +103,9 @@
                        $page     = "$pagename ($pageurl)";
 
                        if ( count( $add ) == 1 && count( $sub ) == 1 ) {
-                $this->notifyMove( $sub[0], $add[0] );
+                               $this->notifyMove( $sub[0], $add[0] );
                        } else {
-                $this->notifyAdd( $add );
+                               $this->notifyAdd( $add );
 
                                foreach ( $sub as $cat ) {
                                        $title   = Title::newFromText( $cat, 
NS_CATEGORY );
@@ -108,22 +123,34 @@
                if ( $this->shouldNotifyParentWatchers() ) {
                        $this->notifyParentWatchers();
                }
-    }
+       }
 
-    protected function shouldNotifyParentWatchers() {
-        global $wgCategoryWatchNotifyParentWatchers;
-        return $wgCategoryWatchNotifyParentWatchers;
-    }
+       /**
+        * Should watchers of parent categories be notified?
+        * @return bool
+        */
+       protected function shouldNotifyParentWatchers() {
+               global $wgCategoryWatchNotifyParentWatchers;
+               return $wgCategoryWatchNotifyParentWatchers;
+       }
 
-    protected function shouldNotifyEditor() {
-        global $wgCategoryWatchNotifyEditor;
-        return $wgCategoryWatchNotifyEditor;
-    }
+       /**
+        * Should the editor be notified of his own edits?
+        * @return bool
+        */
+       protected function shouldNotifyEditor() {
+               global $wgCategoryWatchNotifyEditor;
+               return $wgCategoryWatchNotifyEditor;
+       }
 
-    protected function useRealName() {
-        global $wgCategoryWatchNoRealName;
-        return !$wgCategoryWatchNoRealName;
-    }
+       /**
+        * Should CategoryWatch use the user's real name in email?
+        * @return bool
+        */
+       protected function useRealName() {
+               global $wgCategoryWatchNoRealName;
+               return !$wgCategoryWatchNoRealName;
+       }
 
        /**
         * Return "Category:Cat (URL)" from "Cat"
@@ -147,8 +174,8 @@
         * @param string $pageurl of page
         */
        protected function notifyWatchers(
-        $title, $editor, $message, $summary, $medit, $pageurl
-    ) {
+               $title, $editor, $message, $summary, $medit, $pageurl
+       ) {
                global $wgLang, $wgNoReplyAddress,
                        $wgEnotifRevealEditorAddress, $wgEnotifUseRealName, 
$wgPasswordSender,
                        $wgEnotifFromEditor, $wgPasswordSenderName;
@@ -262,96 +289,104 @@
        /**
         * Notify the watchers of parent categories
         */
-    protected function notifyParentWatchers() {
+       protected function notifyParentWatchers() {
                $this->allparents = 
$this->wikiPage->getTitle()->getParentCategoryTree();
-        $page = $this->wikiPage->getTitle();
-        $pageUrl = $page->getFullUrl();
-        foreach ( (array)$this->allparents as $cat ) {
-            $title   = Title::newFromText( $cat, NS_CATEGORY );
-            $message = wfMessage(
-                'categorywatch-catchange', $page,
-                $this->friendlyCat( $cat )
-            );
-            $this->notifyWatchers(
-                $title, $user, $message, $summary, $medit, $pageurl
-            );
+               $page = $this->wikiPage->getTitle();
+               $pageUrl = $page->getFullUrl();
+               foreach ( (array)$this->allparents as $cat ) {
+                       $title   = Title::newFromText( $cat, NS_CATEGORY );
+                       $message = wfMessage(
+                               'categorywatch-catchange', $page,
+                               $this->friendlyCat( $cat )
+                       );
+                       $this->notifyWatchers(
+                               $title, $user, $message, $summary, $medit, 
$pageurl
+                       );
                }
        }
 
-    /**
-     * Handle autocat option
-     */
-    protected function doAutoCat() {
-        global $wgCategoryWatchUseAutoCat;
+       /**
+        * Handle autocat option
+        */
+       protected function doAutoCat() {
+               global $wgCategoryWatchUseAutoCat;
                if ( $wgCategoryWatchUseAutoCat ) {
-            $dbr = wfGetDB( DB_SLAVE );
+                       $dbr = wfGetDB( DB_SLAVE );
 
-            # Find all users not watching the autocat
-            $like = '%' . str_replace(
-                ' ', '_', trim( wfMessage( 'categorywatch-autocat', '' 
)->text() )
-            ) . '%';
-            $res = $dbr->select( [ 'user', 'watchlist' ], 'user_id',
-                                 'wl_user IS NULL', __METHOD__, [],
-                                 [ 'watchlist' => [ 'LEFT JOIN',
-                                                    [
-                                                        'user_id=wl_user',
-                                                        'wl_tile', 
$dbr->buildLike( $like )
-                                                    ] ] ] );
+                       # Find all users not watching the autocat
+                       $like = '%' . str_replace(
+                               ' ', '_', trim( wfMessage( 
'categorywatch-autocat', '' )->text() )
+                       ) . '%';
+                       $res = $dbr->select( [ 'user', 'watchlist' ], 'user_id',
+                                                                'wl_user IS 
NULL', __METHOD__, [],
+                                                                [ 'watchlist' 
=> [ 'LEFT JOIN',
+                                                                               
                        [
+                                                                               
                                'user_id=wl_user',
+                                                                               
                                'wl_tile', $dbr->buildLike( $like )
+                                                                               
                        ] ] ] );
 
+                       # Insert an entry into watchlist for each
+                       $row = $dbr->fetchRow( $res );
+                       while ( $row ) {
+                               $user = User::newFromId( $row[0] );
+                               $name = $user->getName();
+                               $wl_title = str_replace(
+                                       ' ', '_', wfMessage( 
'categorywatch-autocat', $name )->text()
+                               );
+                               $dbr->insert(
+                                       'watchlist',
+                                       [
+                                               'wl_user' => $row[0], 
'wl_namespace' => NS_CATEGORY,
+                                               'wl_title' => $wl_title
+                                       ]
+                               );
+                               $row = $dbr->fetchRow( $res );
+                       }
+                       $dbr->freeResult( $res );
+               }
+       }
 
-            # Insert an entry into watchlist for each
-            $row = $dbr->fetchRow( $res );
-            while ( $row ) {
-                $user = User::newFromId( $row[0] );
-                $name = $user->getName();
-                $wl_title = str_replace(
-                    ' ', '_', wfMessage( 'categorywatch-autocat', $name 
)->text()
-                );
-                $dbr->insert(
-                    'watchlist',
-                    [
-                        'wl_user' => $row[0], 'wl_namespace' => NS_CATEGORY,
-                        'wl_title' => $wl_title
-                    ]
-                );
-                $row = $dbr->fetchRow( $res );
-            }
-            $dbr->freeResult( $res );
-        }
-    }
+       /**
+        * Send a notification that the page's categorization has moved.
+        * @param string $from Category moving from
+        * @param string $to Category moving to
+        */
+       protected function notifyMove( $from, $to ) {
+               $title   = Title::newFromText( $to, NS_CATEGORY );
+               $message = wfMessage(
+                       'categorywatch-catmovein', $page,
+                       $this->friendlyCat( $to ),
+                       $this->friendlyCat( $from )
+               )->text();
+               $this->notifyWatchers(
+                       $title, $user, $message, $summary, $medit, $pageurl
+               );
 
-    protected function notifyMove( $from, $to ) {
-        $title   = Title::newFromText( $add, NS_CATEGORY );
-        $message = wfMessage(
-            'categorywatch-catmovein', $page,
-            $this->friendlyCat( $add ),
-            $this->friendlyCat( $sub )
-        )->text();
-        $this->notifyWatchers(
-            $title, $user, $message, $summary, $medit, $pageurl
-        );
+               $title   = Title::newFromText( $from, NS_CATEGORY );
+               $message = wfMessage(
+                       'categorywatch-catmoveout', $page,
+                       $this->friendlyCat( $from ),
+                       $this->friendlyCat( $to )
+               )->text();
+               $this->notifyWatchers(
+                       $title, $user, $message, $summary, $medit, $pageurl
+               );
+       }
 
-        $title   = Title::newFromText( $sub, NS_CATEGORY );
-        $message = wfMessage(
-            'categorywatch-catmoveout', $page,
-            $this->friendlyCat( $sub ),
-            $this->friendlyCat( $add )
-        )->text();
-        $this->notifyWatchers(
-            $title, $user, $message, $summary, $medit, $pageurl
-        );
-    }
-
-    protected function notifyAdd( $add ) {
-        foreach ( $add as $cat ) {
-            $title   = Title::newFromText( $cat, NS_CATEGORY );
-            $message = wfMessage(
-                'categorywatch-catadd', $page,
-                $this->friendlyCat( $cat )
-            )->text();
-            $this->notifyWatchers(
-                $title, $user, $message, $summary, $medit, $pageurl
-            );
-        }
-    }
-}
\ No newline at end of file
+       /**
+        * Send a notification that a page has been added to the category
+        * @param array $add Category being added
+        */
+       protected function notifyAdd( $add ) {
+               foreach ( $add as $cat ) {
+                       $title   = Title::newFromText( $cat, NS_CATEGORY );
+                       $message = wfMessage(
+                               'categorywatch-catadd', $page,
+                               $this->friendlyCat( $cat )
+                       )->text();
+                       $this->notifyWatchers(
+                               $title, $user, $message, $summary, $medit, 
$pageurl
+                       );
+               }
+       }
+}
diff --git a/src/Hook.php b/src/Hook.php
index 15072bc..25c81d0 100644
--- a/src/Hook.php
+++ b/src/Hook.php
@@ -1,17 +1,13 @@
 <?php
 /**
- * CategoryWatch extension
- * - Extends watchlist functionality to include notification about membership
- *   changes of watched categories
+ * Hooks for CategoryWatch extension
  *
- * Copyright (C) 2008  Aran Dunkley
- * Copyright (C) 2017  Sean Chen
  * Copyright (C) 2017  Mark A. Hershberger
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,35 +15,24 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * See https://www.mediawiki.org/Extension:CategoryWatch
- *     for installation and usage details
- * See http://www.organicdesign.co.nz/Extension_talk:CategoryWatch
- *     for development notes and disucssion
- *
- * @file
- * @ingroup Extensions
- * @author Aran Dunkley [http://www.organicdesign.co.nz/nad User:Nad]
- * @copyright © 2008 Aran Dunkley
- * @licence GNU General Public Licence 2.0 or later
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-
 namespace CategoryWatch;
 
-use SpecialPage;
+use Content;
+use Status;
 use Title;
 use User;
-use UserMailer;
+use WikiPage;
 
 class Hook {
        // Instance
        protected static $watcher;
 
+       const CATWATCH = 'catwatch';
+
        /**
-     * Instantiate CategoryWatch object and get categories
+        * Instantiate CategoryWatch object and get categories
         * @see https://www.mediawiki.org/wiki/Manual:Hooks/PageContentSave
         * @param WikiPage $wikiPage the page
         * @param User $user who is modifying
@@ -60,16 +45,16 @@
         * @param Status $status Status (object)
         */
        public static function onPageContentSave(
-               $wikiPage, $user, $content, $summary, $isMinor,
-               $isWatch, $section, $flags, $status
+               WikiPage $wikiPage, User $user, Content $content, $summary, 
$isMinor,
+               $isWatch, $section, $flags, Status $status
        ) {
-        self::$watcher = new CategoryWatch(
-            $wikiPage, $user, $content, $summary, $isMinor, $flags
-        );
+               self::$watcher = new CategoryWatch(
+                       $wikiPage, $user, $content, $summary, $isMinor, $flags
+               );
        }
 
        /**
-        * the proper hook for save page request.
+        * The proper hook for save page request.
         * @see 
https://www.mediawiki.org/wiki/Manual:Hooks/PageContentSaveComplete
         * @param WikiPage $article Article edited
         * @param User $user who edited
@@ -84,9 +69,75 @@
         * @param int $baseRevId base revision
         */
        public static function onPageContentSaveComplete(
-               $article, $user, $content, $summary, $isMinor, $isWatch, 
$section,
-               $flags, $revision, $status, $baseRevId
+               WikiPage $article, User $user, Content $content, $summary, 
$isMinor, $isWatch,
+               $section, $flags, Revision $revision, Status $status, $baseRevId
        ) {
-        self::$watcher->notifyCategoryWatchers( $revision, $baseRevId );
+               self::$watcher->notifyCategoryWatchers( $revision, $baseRevId );
+       }
+
+       /**
+        * Send notifications of categorization changes
+        * Doing it here because core is hard-coded not to send notifications
+        * when rc_type == RC_CATEGORIZE
+        * @see https://www.mediawiki.org/wiki/Manual:Hooks/RecentChanges_save
+        * @param RecentChange $rc the RC object
+        */
+       public static function onRecentChangeSave( RecentChange $rc ) {
+               $attr = $rc->getAttributes();
+               if ( $attr['rc_type'] !== RC_CATEGORIZE ) {
+                       return;
+               }
+
+               $editor = $rc->getPerformer();
+               $category = $rc->getTitle();
+               $title = Title::newFromID( $attr['rc_cur_id'] );
+               $summary = $attr['rc_comment'];
+               $params = unserialize( $attr['rc_params'] );
+               $ts = $attr['rc_timestamp'];
+               $oldId = $attr['rc_last_oldid'];
+               $added = $rc->getParam( 'added' );
+               $watchers = 
MediaWikiServices::getInstance()->getWatchedItemStore()
+                                 ->updateNotificationTimestamp( $editor, 
$category, $timestamp );
+
+               $enotif = new EmailNotification();
+               $enotif->actuallyNotifyOnPageChange(
+                       $editor, $category, $ts, $summary, false, $oldId, 
$watchers, self::CATWATCH
+               );
+       }
+
+       /**
+        * Add our pagestatus to the list of valid status
+        * @param array &$fps formattedPageSatus variable
+        */
+       public static function onUpdateUserMailerFormattedPageStatus( array 
&$fps ) {
+               $fps[] = self::CATWATCH;
+       }
+
+       /**
+        * EVIL, PURE EVIL
+        */
+       protected static function accessProtected( $obj, $prop ) {
+               $reflection = new \ReflectionClass( $obj );
+               $property = $reflection->getProperty( $prop );
+               $property->setAccessible( true );
+               return $property->getValue( $obj );
+       }
+
+       /**
+        * Override actually sending email notifications
+        * @param User $watchingUser who is getting the notice
+        * @param Title $category that they are watching
+        * @param EmailNotification $enotif has useful info
+        * @return bool false when we dealt with our status
+        */
+       public static function onSendWatchlistEmailNotification(
+               User $watchingUser, Title $category, EmailNotification $enotif
+       ) {
+               if ( self::accessProtected( $enotif, 'pageStatus' ) !== 
self::CATWATCH ) {
+                       return true;
+               }
+
+               wfDebugLog( __METHOD__, "Sending an email now!" );
+               return false;
        }
 }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I601b1449b8984fc695e5e1255be257222f02b995
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CategoryWatch
Gerrit-Branch: master
Gerrit-Owner: MarkAHershberger <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to