Iniquity has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/391796 )
Change subject: Add per-category editnotices, rebased 189178 ...................................................................... Add per-category editnotices, rebased 189178 This adds support for per-category editnotices using a new page_prop property, set during links update of the category page by checking if the message defining the associated editnotice exists. In addition, to avoid having to null edit the category page, a links update job is also run on creation or deletion of the editnotice. When editing a page, the categorylinks table is already queried with page and page_props to retrieve hidden categories. So this also checks for the 'editnoticecat' property to retrieve categories with a per-category editnotice, and displays it if it exists. Bug: T85372 Change-Id: Ia0042b2b5c0c38471fd936bcc470780a0c46cfd5 --- M includes/EditPage.php M includes/Title.php M includes/cache/MessageCache.php M includes/deferred/LinksUpdate.php M includes/page/WikiPage.php 5 files changed, 138 insertions(+), 6 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/96/391796/2 diff --git a/includes/EditPage.php b/includes/EditPage.php index ff224c5..ad9aaaf 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -2680,6 +2680,27 @@ Hooks::run( 'EditPage::showEditForm:initial', [ &$editPage, &$out ] ); $this->setHeaders(); + + // get categories with either "hiddencat" or "editnoticecat" properties + $categories = $this->page->getCategoriesWithProperties( + [ 'hiddencat', 'editnoticecat' ] + ); + $hiddenCategories = []; + $editnoticeCategories = []; + foreach ( $categories as $cat => $props ) { + // make list of hidden categories + if ( isset( $props['hiddencat'] ) ) { + $hiddenCategories[] = Title::makeTitle( NS_CATEGORY, $cat ); + } + // make list of categories to check for per-category editnotices + if ( isset( $props['editnoticecat'] ) ) { + $editnoticeCategories[] = $cat; + } + } + + if ( $this->showHeader( $editnoticeCategories ) === false ) { + return; + } $this->addTalkPageText(); $this->addEditNotices(); @@ -2882,7 +2903,7 @@ $out->addHTML( $this->makeTemplatesOnThisPageList( $this->getTemplates() ) ); $out->addHTML( Html::rawElement( 'div', [ 'class' => 'hiddencats' ], - Linker::formatHiddenCategories( $this->page->getHiddenCategories() ) ) ); + Linker::formatHiddenCategories( $hiddenCategories ) ) ); $out->addHTML( Html::rawElement( 'div', [ 'class' => 'limitreport' ], self::getPreviewLimitReport( $this->mParserOutput ) ) ); @@ -4543,9 +4564,9 @@ /** * @since 1.29 */ - protected function addEditNotices() { + protected function addEditNotices( $editnoticeCategories ) { $out = $this->context->getOutput(); - $editNotices = $this->mTitle->getEditNotices( $this->oldid ); + $editNotices = $this->mTitle->getEditNotices( $this->oldid, $editnoticeCategories ); if ( count( $editNotices ) ) { $out->addHTML( implode( "\n", $editNotices ) ); } else { diff --git a/includes/Title.php b/includes/Title.php index 829be44..7f7c846 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -4937,8 +4937,11 @@ * @since 1.21 * @param int $oldid Revision ID that's being edited * @return array + * @since 1.31 + * @param array $categories An array containing the names of categories + * (without namespace prefix) that are checked for per-category editnotices */ - public function getEditNotices( $oldid = 0 ) { + public function getEditNotices( $oldid = 0, $categories = null ) { $notices = []; // Optional notice for the entire namespace @@ -4960,6 +4963,30 @@ } } + // Optional notices on a per-category basis + if ( $categories === null ) { + $page = new WikiPage( $this ); + $categories = $page->getCategoriesWithProperties( 'editnoticecat' ); + } + foreach ( $categories as $cat ) { + $editnoticeCategory = 'editnotice-category-' . $cat; + $msg = wfMessage( $editnoticeCategory ); + if ( $msg->exists() ) { + $html = $msg->parseAsBlock(); + if ( trim( $html ) !== '' ) { + $notices[$editnoticeCategory] = Html::rawElement( + 'div', + [ 'class' => [ + 'mw-editnotice', + 'mw-editnotice-category', + Sanitizer::escapeClass( "mw-category-$editnoticeCategory" ) + ] ], + $html + ); + } + } + } + if ( MWNamespace::hasSubpages( $this->getNamespace() ) ) { // Optional notice for page itself and any parent page $parts = explode( '/', $this->getDBkey() ); diff --git a/includes/cache/MessageCache.php b/includes/cache/MessageCache.php index 768f980..0094914 100644 --- a/includes/cache/MessageCache.php +++ b/includes/cache/MessageCache.php @@ -566,11 +566,17 @@ /** * Updates cache as necessary when message page is changed * - * @param string $title Message cache key with initial uppercase letter - * @param string|bool $text New contents of the page (false if deleted) + * @param string $title Name of the page changed + * @param string|bool $text New contents of the page or false if deleted + * @param array $options An array of boolean options + * Set 'created' => true when the change is due to the message page being created */ public function replace( $title, $text ) { global $wgLanguageCode; + + $options += [ + 'created' => false, + ]; if ( $this->mDisable ) { return; @@ -650,6 +656,29 @@ $blobStore->updateMessage( $wgContLang->lcfirst( $msg ) ); Hooks::run( 'MessageCacheReplace', [ $title, $text ] ); + + // handle per-category editnotices + if ( ( $options['created'] || $text === false ) && + strpos( $title, 'Editnotice-category-' ) === 0 + ) { + // per-category editnotices are checked via the 'editnoticecat' page_prop, + // set in LinksUpdate if the editnotice message exists + // run a RefreshLinksJob on the associated category so that the user + // doesn't have to edit it + $category = substr( $title, 20 ); + if ( $category !== '' ) { + $categoryTitle = Title::makeTitle( NS_CATEGORY, $category ); + $jobs = []; + if ( $options['created'] ) { + // should be done quickly on creation + $jobs[] = RefreshLinksJob::newPrioritized( $categoryTitle, [] ); + } else { + // not time-sensitive on deletion + $jobs[] = RefreshLinksJob::newDynamic( $categoryTitle, [] ); + } + JobQueueGroup::singleton()->push( $jobs ); + } + } }, DeferredUpdates::PRESEND ); diff --git a/includes/deferred/LinksUpdate.php b/includes/deferred/LinksUpdate.php index 8913642..620a76b 100644 --- a/includes/deferred/LinksUpdate.php +++ b/includes/deferred/LinksUpdate.php @@ -170,6 +170,16 @@ $scopedLock = self::acquirePageLock( $this->getDB(), $this->mId ); } + # For categories, check if an associated editnotice exists + # If it does, set property so that these can be recovered when editing a page, + # without having to check all categories the page is in + if ( $this->mTitle->getNamespace() == NS_CATEGORY ) { + $editnoticeMsg = wfMessage( 'editnotice-category-' . $this->mTitle->getDBkey() ); + if ( $editnoticeMsg->exists() ) { + $this->mProperties['editnoticecat'] = ''; + } + } + // Avoid PHP 7.1 warning from passing $this by reference $linksUpdate = $this; Hooks::run( 'LinksUpdate', [ &$linksUpdate ] ); diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index 8b34928..97471c8 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -2301,6 +2301,9 @@ if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { MessageCache::singleton()->updateMessageOverride( $this->mTitle, $content ); + MessageCache::singleton()->replace( + [ 'created' => $options['created'] ] + ); } if ( $options['created'] ) { @@ -3460,6 +3463,48 @@ } /** + * Returns a list of categories with the specified page_props properties + * + * @param array|string $properties Array of page_props properties, or page_props property + * @since 1.28 + * @return array + * - If $properties was an array, array of category DB keys containing this page with + * at least one of these properties, mapped to possessed properties + * - If $properties was a string, array of category DB keys containing this page with + * the given property + */ + public function getCategoriesWithProperties( $properties ) { + $result = []; + $id = $this->getId(); + + if ( $id == 0 ) { + return []; + } + + $dbr = wfGetDB( DB_SLAVE ); + $res = $dbr->select( [ 'categorylinks', 'page_props', 'page' ], + [ 'cl_to', 'pp_propname' ], + [ 'cl_from' => $id, 'pp_page=page_id', + 'pp_propname' => $properties, + 'page_namespace' => NS_CATEGORY, 'page_title=cl_to' ], + __METHOD__ ); + + if ( $res !== false ) { + if ( is_array( $properties ) ) { + foreach ( $res as $row ) { + $result[$row->cl_to][$row->pp_propname] = true; + } + } else { + foreach ( $res as $row ) { + $result[] = $row->cl_to; + } + } + } + + return $result; + } + + /** * Auto-generates a deletion reason * * @param bool &$hasHistory Whether the page has a history -- To view, visit https://gerrit.wikimedia.org/r/391796 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia0042b2b5c0c38471fd936bcc470780a0c46cfd5 Gerrit-PatchSet: 2 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Iniquity <inite...@gmail.com> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits