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 <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits