C. Scott Ananian has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/403318 )
Change subject: Always return some category name, even if it's just a placeholder ...................................................................... Always return some category name, even if it's just a placeholder This further decouples Parsoid deploys of new linter categories from Linter extension deploys which name them. If Parsoid logs lints from an as-yet-unknown category, we will just give them the special temporary name LINT@nnn with the numeric db identifier. This allows the API and UX to query/display/etc them with this placeholder name while we are waiting for the "official" name/l10n/etc to be deployed. Add some new methods to allow enumerating all category ids from the database, even those which aren't yet officially named. Change-Id: Ic917fa3abb61d2f784d839f8f9e5e866640d2d4d --- M i18n/en.json M i18n/qqq.json M includes/ApiQueryLintErrors.php M includes/CategoryManager.php M includes/Database.php M includes/SpecialLintErrors.php M includes/TotalsLookup.php 7 files changed, 101 insertions(+), 25 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Linter refs/changes/18/403318/1 diff --git a/i18n/en.json b/i18n/en.json index 2ef9756..07a34ba 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -68,6 +68,7 @@ "linter-heading-high-priority": "High priority", "linter-heading-medium-priority": "Medium priority", "linter-heading-low-priority": "Low priority", + "linter-heading-placeholder-priority": "Not yet categorized", "multi-part-template-block": "Output not from a single template", "pageinfo-linter": "Lint errors", "apihelp-query+linterrors-description": "Get a list of lint errors", diff --git a/i18n/qqq.json b/i18n/qqq.json index a650798..3ccaa5b 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -72,6 +72,7 @@ "linter-heading-high-priority": "Heading on [[Special:LintErrors]]", "linter-heading-medium-priority": "Heading on [[Special:LintErrors]]", "linter-heading-low-priority": "Heading on [[Special:LintErrors]]", + "linter-heading-placeholder-priority": "Heading on [[Special:LintErrors]]", "multi-part-template-block": "Table cell on [[Special:LintErrors]] indicating that content block is not produced by a single template", "pageinfo-linter": "Heading on ?action=info for a page if it has lint errors", "apihelp-query+linterrors-description": "{{doc-apihelp-description|query+linterrors}}", diff --git a/includes/ApiQueryLintErrors.php b/includes/ApiQueryLintErrors.php index f057c0c..62f5976 100644 --- a/includes/ApiQueryLintErrors.php +++ b/includes/ApiQueryLintErrors.php @@ -98,13 +98,18 @@ } public function getAllowedParams() { - $visibleCats = ( new CategoryManager() )->getVisibleCategories(); + $categoryMgr = new CategoryManager(); + $visibleCats = $categoryMgr->getVisibleCategories(); + $placeholderCats = $categoryMgr->getPlaceholderCategories( + $this->getDB() + ); + $allCats = array_merge($visibleCats, $placeholderCats); return [ 'categories' => [ - ApiBase::PARAM_TYPE => $visibleCats, + ApiBase::PARAM_TYPE => $allCats, ApiBase::PARAM_ISMULTI => true, // Default is to show all categories - ApiBase::PARAM_DFLT => implode( '|', $visibleCats ), + ApiBase::PARAM_DFLT => implode( '|', $allCats ), ], 'limit' => [ ApiBase::PARAM_DFLT => 10, diff --git a/includes/CategoryManager.php b/includes/CategoryManager.php index 6d1256d..bb1bb6d 100644 --- a/includes/CategoryManager.php +++ b/includes/CategoryManager.php @@ -56,6 +56,21 @@ */ private $hasNameParam = []; + /** + * Special form for "numeric category" names, a special form which allows + * naming/querying new Parsoid categories prior to the Linter extension + * being updated with information about them. + * + * @var string + */ + const NUMERIC_CATID_PREFIX = 'LINT@'; + /** + * A regexp to rest for "numeric category" names. + * + * @var string + */ + const NUMERIC_CATID_REGEX = '/^' . self::NUMERIC_CATID_PREFIX . '([0-9]+)$/'; + public function __construct() { global $wgLinterCategories; foreach ( $wgLinterCategories as $name => $info ) { @@ -124,8 +139,52 @@ } /** - * Whether this category has a hardcoded id and can be - * inserted into the database + * Categories present in the database which are not yet given + * official names or l10n by the Linter extension. + * + * @param IDatabase $db + * @return string[] + */ + public function getPlaceholderCategories( $db ) { + return array_diff( + $this->getDatabaseCategories( $db ), + $this->getVisibleCategories() + ); + } + + /** + * All categories, prioritized or not. + * + * @param IDatabase $db + * @return string[] + */ + public function getAllCategories ( $db ) { + return array_merge( + $this->getVisibleCategories(), + $this->getPlaceholderCategories( $db ) + ); + } + + /** + * All categories present in the database. + * + * @param IDatabase $db + * @return string[] + */ + public function getDatabaseCategories( $db ) { + $rows = $db->select( 'linter', ['linter_cat'], [], __METHOD__, [ + 'DISTINCT', + 'ORDER BY' => 'linter_cat' + ], [] ); + $cats = []; + foreach ( $rows as $row ) { + $cats[] = $this->getCategoryName( $row->linter_cat ); + } + return $cats; + } + + /** + * Whether this category has a known category id * * @param string $name * @return bool @@ -135,8 +194,10 @@ } /** + * Returns the category name, or a special "numeric category" name if + * the linter extension does not (yet) know about this category id. + * * @param int $id - * @throws MissingCategoryException if we can't find the name for the id * @return string */ public function getCategoryName( $id ) { @@ -145,7 +206,7 @@ return $flip[$id]; } - throw new MissingCategoryException( "Could not find name for id $id" ); + return self::NUMERIC_CATID_PREFIX . $id; } /** @@ -179,6 +240,15 @@ return $this->categoryIds[$name]; } + // Names in a special "LINT@NNN" form are special; they map directly + // to category ID <NNN>. This allows use of the API to query for + // these lints even before the Linter extension knows a proper + // name for them, and they'll show up in the UI under this temporary + // category name as well. + if ( preg_match( self::NUMERIC_CATID_REGEX, $name, $matches ) ) { + return (int)$matches[1]; + } + // Use hint from Parsoid, if available. if ( $hint !== null ) { return $hint; diff --git a/includes/Database.php b/includes/Database.php index 0febbdd..65b7af6 100644 --- a/includes/Database.php +++ b/includes/Database.php @@ -81,15 +81,7 @@ * @return LintError|bool false on error */ public static function makeLintError( $row ) { - try { - $name = ( new CategoryManager() )->getCategoryName( $row->linter_cat ); - } catch ( MissingCategoryException $e ) { - LoggerFactory::getInstance( 'Linter' )->error( - 'Could not find name for id: {linter_cat}', - [ 'linter_cat' => $row->linter_cat ] - ); - return false; - } + $name = ( new CategoryManager() )->getCategoryName( $row->linter_cat ); return new LintError( $name, [ (int)$row->linter_start, (int)$row->linter_end ], @@ -250,11 +242,7 @@ // Initialize zero values $ret = array_fill_keys( $this->categoryManager->getVisibleCategories(), 0 ); foreach ( $rows as $row ) { - try { - $catName = $this->categoryManager->getCategoryName( $row->linter_cat ); - } catch ( MissingCategoryException $e ) { - continue; - } + $catName = $this->categoryManager->getCategoryName( $row->linter_cat ); $ret[$catName] = (int)$row->count; } diff --git a/includes/SpecialLintErrors.php b/includes/SpecialLintErrors.php index 2f33fab..951140a 100644 --- a/includes/SpecialLintErrors.php +++ b/includes/SpecialLintErrors.php @@ -58,6 +58,8 @@ $catManager = new CategoryManager(); if ( in_array( $par, $catManager->getVisibleCategories() ) ) { $this->category = $par; + } else if ( preg_match( CategoryManager::NUMERIC_CATID_REGEX, $par, $m ) ) { + $this->category = $catManager->getCategoryName( (int)$m[1] ); } if ( !$this->category ) { @@ -105,6 +107,13 @@ $this->displayList( 'high', $totals, $catManager->getHighPriority() ); $this->displayList( 'medium', $totals, $catManager->getMediumPriority() ); $this->displayList( 'low', $totals, $catManager->getLowPriority() ); + + // Are there any uncategorized issues in the DB? + $placeholderCats = + $catManager->getPlaceholderCategories( wfGetDB( DB_REPLICA ) ); + if ( count($placeholderCats) > 0 ) { + $this->displayList( 'placeholder', $totals, $placeholderCats ); + } } /** @@ -133,7 +142,8 @@ } protected function getSubpagesForPrefixSearch() { - return ( new CategoryManager() )->getVisibleCategories(); + $db = wfGetDB( DB_REPLICA ); + return ( new CategoryManager() )->getAllCategories( $db ); } } diff --git a/includes/TotalsLookup.php b/includes/TotalsLookup.php index 386b3ee..6bab88f 100644 --- a/includes/TotalsLookup.php +++ b/includes/TotalsLookup.php @@ -58,15 +58,16 @@ * @return array */ public function getTotals() { - $cats = $this->catManager->getVisibleCategories(); + $db = wfGetDB( DB_REPLICA ); + $cats = $this->catManager->getAllCategories( $db ); $fetchedTotals = false; $totals = []; foreach ( $cats as $cat ) { $totals[$cat] = $this->cache->getWithSetCallback( $this->makeKey( $cat ), WANObjectCache::TTL_INDEFINITE, - function ( $oldValue, &$ttl, &$setOpts, $oldAsOf ) use ( $cat, &$fetchedTotals ) { - $setOpts += MWDatabase::getCacheSetOptions( wfGetDB( DB_REPLICA ) ); + function ( $oldValue, &$ttl, &$setOpts, $oldAsOf ) use ( $db, $cat, &$fetchedTotals ) { + $setOpts += MWDatabase::getCacheSetOptions( $db ); if ( $fetchedTotals === false ) { $fetchedTotals = ( new Database( 0 ) )->getTotals(); } -- To view, visit https://gerrit.wikimedia.org/r/403318 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic917fa3abb61d2f784d839f8f9e5e866640d2d4d Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Linter Gerrit-Branch: master Gerrit-Owner: C. Scott Ananian <canan...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits