jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/369624 )
Change subject: New Wikidata Build - 2017-08-02T10:00:01+0000
......................................................................
New Wikidata Build - 2017-08-02T10:00:01+0000
Change-Id: I8c81465b8105cd632c37512b0a134ad0a8e4f44a
---
M composer.lock
M extensions/ArticlePlaceholder/i18n/nn.json
M extensions/Constraints/api/CheckConstraints.php
M extensions/Constraints/i18n/gl.json
M extensions/Constraints/i18n/he.json
M extensions/Constraints/i18n/hi.json
M extensions/Constraints/i18n/zh-hans.json
M extensions/Constraints/includes/ConstraintCheck/Helper/TypeCheckerHelper.php
M extensions/Constraints/package.json
M
extensions/Constraints/tests/phpunit/Checker/TypeChecker/TypeCheckerHelperTest.php
M extensions/PropertySuggester/package.json
M extensions/Quality/package.json
M extensions/Wikibase/client/i18n/din.json
M extensions/Wikibase/client/includes/Changes/ChangeHandler.php
M extensions/Wikibase/client/includes/Changes/PageUpdater.php
M extensions/Wikibase/client/includes/Changes/WikiPageUpdater.php
M extensions/Wikibase/client/includes/WikibaseClient.php
M
extensions/Wikibase/client/tests/phpunit/includes/Changes/ChangeHandlerTest.php
M extensions/Wikibase/client/tests/phpunit/includes/Changes/MockPageUpdater.php
M
extensions/Wikibase/client/tests/phpunit/includes/Changes/WikiPageUpdaterTest.php
M extensions/Wikibase/repo/includes/EditEntity.php
M extensions/Wikibase/repo/includes/EditEntityFactory.php
M extensions/Wikibase/repo/includes/Store/EntityPermissionChecker.php
M
extensions/Wikibase/repo/includes/Store/WikiPageEntityStorePermissionChecker.php
M extensions/Wikibase/repo/includes/WikibaseRepo.php
M extensions/Wikibase/repo/maintenance/dispatchChanges.php
M extensions/Wikibase/repo/tests/phpunit/includes/EditEntityTest.php
M
extensions/Wikibase/repo/tests/phpunit/includes/Store/WikiPageEntityStorePermissionCheckerTest.php
M extensions/Wikibase/view/resources/wikibase/resources.php
R extensions/Wikibase/view/resources/wikibase/wikibase.less
M package.json
M vendor/composer/installed.json
32 files changed, 348 insertions(+), 608 deletions(-)
Approvals:
Aude: Looks good to me, approved
jenkins-bot: Verified
diff --git a/composer.lock b/composer.lock
index 259e513..310f86f 100644
--- a/composer.lock
+++ b/composer.lock
@@ -756,12 +756,12 @@
"source": {
"type": "git",
"url":
"https://github.com/wikimedia/mediawiki-extensions-ArticlePlaceholder.git",
- "reference": "f1e8a1a35716239f9a78eebca09f1135935c4f17"
+ "reference": "9fde45a4bb0c062e9004c38a34f99f1c8dcab012"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-ArticlePlaceholder/zipball/f1e8a1a35716239f9a78eebca09f1135935c4f17",
- "reference": "f1e8a1a35716239f9a78eebca09f1135935c4f17",
+ "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-ArticlePlaceholder/zipball/9fde45a4bb0c062e9004c38a34f99f1c8dcab012",
+ "reference": "9fde45a4bb0c062e9004c38a34f99f1c8dcab012",
"shasum": ""
},
"require": {
@@ -790,7 +790,7 @@
],
"description": "Provides a special page with Wikibase information
about a certain topic, with invitation to create an article for the topic",
"homepage":
"https://www.mediawiki.org/wiki/Extension:ArticlePlaceholder",
- "time": "2017-07-31 10:42:11"
+ "time": "2017-08-01 20:36:04"
},
{
"name": "propertysuggester/property-suggester",
@@ -798,7 +798,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/PropertySuggester",
- "reference": "ee4c46b4a335c87855e80147b2bc85766ae15b20"
+ "reference": "283a7070fd970cfe991f9b16f47b10cb04d1c4ce"
},
"require": {
"php": ">=5.5.9",
@@ -849,7 +849,7 @@
"wikibase",
"wikidata"
],
- "time": "2017-07-26 09:44:33"
+ "time": "2017-08-01 08:45:42"
},
{
"name": "serialization/serialization",
@@ -966,7 +966,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQualityConstraints",
- "reference": "8614148918fc44218c82182610aff43fdd07f081"
+ "reference": "8c90ed7f4bc35d3b36b3823150404b8b41abfda8"
},
"require": {
"php": ">=5.5.9",
@@ -1027,7 +1027,7 @@
"support": {
"issues":
"https://phabricator.wikimedia.org/project/profile/1202/"
},
- "time": "2017-07-31 21:06:39"
+ "time": "2017-08-02 09:14:11"
},
{
"name": "wikibase/data-model",
@@ -1432,7 +1432,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQuality",
- "reference": "22aafec778ad7605863090758753c21e79ed44df"
+ "reference": "9f25f6f316e962aa4117e0922e0c041eab895b79"
},
"require": {
"php": ">=5.5.9",
@@ -1491,7 +1491,7 @@
"support": {
"issues":
"https://phabricator.wikimedia.org/project/profile/989/"
},
- "time": "2017-07-28 20:48:10"
+ "time": "2017-08-01 11:18:15"
},
{
"name": "wikibase/serialization-javascript",
@@ -1540,12 +1540,12 @@
"source": {
"type": "git",
"url":
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git",
- "reference": "aa7c10c4531cca80af5f81b817fd5b578e94942e"
+ "reference": "4331d2cd0e171070329f5af6a465bd582d5fab2c"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/aa7c10c4531cca80af5f81b817fd5b578e94942e",
- "reference": "aa7c10c4531cca80af5f81b817fd5b578e94942e",
+ "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/4331d2cd0e171070329f5af6a465bd582d5fab2c",
+ "reference": "4331d2cd0e171070329f5af6a465bd582d5fab2c",
"shasum": ""
},
"require": {
@@ -1621,7 +1621,7 @@
"wikibaserepo",
"wikidata"
],
- "time": "2017-08-01 08:03:31"
+ "time": "2017-08-02 08:09:10"
},
{
"name": "wikibase/wikimedia-badges",
diff --git a/extensions/ArticlePlaceholder/i18n/nn.json
b/extensions/ArticlePlaceholder/i18n/nn.json
index 4de7475..051d0b5 100644
--- a/extensions/ArticlePlaceholder/i18n/nn.json
+++ b/extensions/ArticlePlaceholder/i18n/nn.json
@@ -4,13 +4,18 @@
"Njardarlogar"
]
},
- "articleplaceholder-abouttopic-create-article": "Opprett ein ny
artikkel med tittelen under",
+ "createtopicpage": "Opprett side",
+ "articleplaceholder-abouttopic-create-article-title": "Opprett ein ny
artikkel",
"articleplaceholder-abouttopic-create-article-label": "Artikkeltittel",
"articleplaceholder-abouttopic-create-article-mandatory": "Tittelen til
artikkelen er påkravd",
"articleplaceholder-abouttopic-create-article-button": "Lag ein
artikkel",
+ "articleplaceholder-abouttopic-create-emtpy-article-button": "Skriv frå
botnen av",
+ "articleplaceholder-abouttopic-translate-article-label": "Kjeldespråk:",
+ "articleplaceholder-abouttopic-translate-article-button": "Set om
artikkel",
"articleplaceholder-abouttopic-create-article-submit-button": "Send",
"articleplaceholder-abouttopic-article-exists-error": "Det finst alt
ein artikkel med dette namnet",
"articleplaceholder-abouttopic-lua-reference": "Kjelder",
"articleplaceholder-abouttopic-lua-identifier": "Eksterne ressursar",
- "articleplaceholder-search-header": "Finn data om emnet"
+ "articleplaceholder-search-header": "Finn data om emnet",
+ "articleplaceholder-createpage-title": "Opprett $1"
}
diff --git a/extensions/Constraints/api/CheckConstraints.php
b/extensions/Constraints/api/CheckConstraints.php
index 49f7f57..0155a21 100644
--- a/extensions/Constraints/api/CheckConstraints.php
+++ b/extensions/Constraints/api/CheckConstraints.php
@@ -351,7 +351,10 @@
} catch ( StatementGuidParsingException $e ) {
// constraint template on talk page
$typeLabel = htmlspecialchars( $typeItemId );
- $link = $title->getTalkPage()->getFullUrl();
+ if ( !$title->canHaveTalkPage() ) {
+ throw new MWException( 'Properties
namespace must define a talk namespace' );
+ }
+ $link =
$title->getTalkPageIfDefined()->getFullUrl();
}
$result = [
diff --git a/extensions/Constraints/i18n/gl.json
b/extensions/Constraints/i18n/gl.json
index 677ee7b..476f2ee 100644
--- a/extensions/Constraints/i18n/gl.json
+++ b/extensions/Constraints/i18n/gl.json
@@ -22,6 +22,8 @@
"wbqc-constraintreport-status-exception": "Excepción",
"wbqc-constraintreport-status-todo": "Pendente",
"wbqc-constraintreport-status-bad-parameters": "Parámetros incorrectos",
+ "wbqc-constraintreport-status-deprecated": "Obsoleto",
+ "wbqc-constraintreport-status-warning": "Aviso",
"wbqc-constraintreport-result-table-header-status": "Estado",
"wbqc-constraintreport-result-table-header-claim": "Afirmación",
"wbqc-constraintreport-result-table-header-constraint": "Restrición",
@@ -31,6 +33,8 @@
"wbqc-potentialissues-short": "Problemas potenciais",
"wbqc-potentialissues-long": "Esta instrucciónten problemas
potenciais.",
"wbqc-badparameters-short": "Parámetros incorrectos",
+ "wbqc-parameterissues-short": "Problemas complexos",
+ "wbqc-problems-short": "Problemas",
"apihelp-wbcheckconstraints-param-constraintid": "Filtro opcional para
devolver só as constantes que teñen o ID de constante especificado",
"apihelp-wbcheckconstraints-example-1": "Verificar tódalas constantes
sobre os elementos Q5 e Q42.",
"apihelp-wbcheckconstraints-example-2": "Verificar tódalas constantes
nunha soa instrucción.",
diff --git a/extensions/Constraints/i18n/he.json
b/extensions/Constraints/i18n/he.json
index fb9f59b..c15c4ec 100644
--- a/extensions/Constraints/i18n/he.json
+++ b/extensions/Constraints/i18n/he.json
@@ -36,6 +36,7 @@
"wbqc-parameterissues-long": "הסוגיות האלו הן בעיות עם הגדרת האילוצים
על המאפיין, לא עם הקביעה הזאת.",
"wbqc-problems-short": "בעיות",
"wbqc-problems-long": "בקביעה הזאת יש בעיות מסוימות.",
+ "wbqc-constrainttypehelp-long": "דף עזרה עבור סוג האילוץ הזה",
"apihelp-wbcheckconstraints-description": "ביצוע בדיקות אילוצים על ישות
כלשהי והחזרת התוצאה.",
"apihelp-wbcheckconstraints-summary": "ביצוע בדיקת אילוצים על כל ישות
והחזרת התוצאה.",
"apihelp-wbcheckconstraints-param-id": "רשימת מזהי ישויות שמהן צריך
לקבל נתונים. יש להפריד את הערכים בתו '|' או חלופות.",
@@ -103,5 +104,6 @@
"wbqc-violation-message-valueType-instance": "ערכים של קביעות $1 אמורים
להיות מופעים של {{PLURAL:$3|1=$5|2=$5 או $6|אחת מהמחלקות הבאות}} (או של
{{PLURAL:$3|1=תת־מחלקה שלה|2=תת־מחלקה שלהן|אחת מהתת־מחלקות שלהן}}), אבל כעת
{{PLURAL:$3|$2 1=אינה כזאת.|2=אינה כזאת.|אינה כזאת: $4}}",
"wbqc-violation-message-valueType-subclass": "ערכים של קביעות $1 אמורים
להיות תת־מחלקות של {{PLURAL:$3|1=$5|2=$5 או $6|אחת מהמחלקות הבאות}} (או של
{{PLURAL:$3|1=תת־מחלקה שלה|2=תת־מחלקה שלהן|אחת מהתת־מחלקות שלהן}}), אבל כעת
{{PLURAL:$3|$2 1=אינה כזאת.|2=אינה כזאת.|אינה כזאת: $4}}",
"wbqc-violation-message-target-required-claim": "ל{{GRAMMAR:תחילית|$1}}
אמורה להיות {{PLURAL:$3|0=קביעה $2.|1=קביעה $2 $5.הקביעה עבור $2 עם אחד מהערכים
הבאים: $4}}",
- "wbqc-violation-message-unique-value": "ערך המאפיין הזה צריך לא להיות
נוכח בשום פריט אחר, אבל הוא
נוכח{{PLURAL:$1|1=ב{{GRAMMAR:תחילית|$3}}.|2=ב{{GRAMMAR:תחילית|$3}}
וב{{GRAMMAR:תחילית|$4}}|בפריטים הבאים: $2}}"
+ "wbqc-violation-message-unique-value": "ערך המאפיין הזה צריך לא להיות
נוכח בשום פריט אחר, אבל הוא
נוכח{{PLURAL:$1|1=ב{{GRAMMAR:תחילית|$3}}.|2=ב{{GRAMMAR:תחילית|$3}}
וב{{GRAMMAR:תחילית|$4}}|בפריטים הבאים: $2}}",
+ "wbqc-exception-message": "הישות הזאת היא חריגה ידועה עבור האילוץ הזה
והיא סומנה בתור כזאת."
}
diff --git a/extensions/Constraints/i18n/hi.json
b/extensions/Constraints/i18n/hi.json
index 20f9f29..d63b6a1 100644
--- a/extensions/Constraints/i18n/hi.json
+++ b/extensions/Constraints/i18n/hi.json
@@ -5,5 +5,6 @@
"Vishwanath"
]
},
+ "wbqc-constraintreport-status-warning": "चेतावनी",
"wbqc-violation-message-parameter-string": "\"$1\" पैरामीटर का मान एक
स्ट्रिंग होना चाहिए, \"$2\" नहीं होना चाहिए।"
}
diff --git a/extensions/Constraints/i18n/zh-hans.json
b/extensions/Constraints/i18n/zh-hans.json
index 6d4b7a4..d7a1735 100644
--- a/extensions/Constraints/i18n/zh-hans.json
+++ b/extensions/Constraints/i18n/zh-hans.json
@@ -36,6 +36,7 @@
"wbqc-parameterissues-long": "这些问题是属性上的约束定义问题,而不是此声明的问题。",
"wbqc-problems-short": "问题",
"wbqc-problems-long": "此声明有一些问题。",
+ "wbqc-constrainttypehelp-long": "此约束类型的帮助页面",
"apihelp-wbcheckconstraints-description": "在任何您希望执行检查的实体上,执行约束检查并返回结果。",
"apihelp-wbcheckconstraints-summary": "在任何您希望执行的实体上执行约束检查,并返回结果。",
"apihelp-wbcheckconstraints-param-id": "要获取数据的实体ID列表。使用“|”或替代字符分隔值。",
@@ -110,5 +111,6 @@
"wbqc-violation-message-valueType-instance":
"$1声明的值性质应为{{PLURAL:$3|1=$5|2=$5或$6|以下类之一}}(或为{{PLURAL:$3|其子类之一}}),但$2当前{{PLURAL:$3|1=并非如此。|2=并非如此。|并非如此:$4}}",
"wbqc-violation-message-valueType-subclass":
"$1声明的值的上级分类应为{{PLURAL:$3|1=$5|2=$5或$6|以下类之一}}(或为{{PLURAL:$3|其子类之一}}),但$2当前{{PLURAL:$3|1=并非如此。|2=并非如此。|并非如此:$4}}",
"wbqc-violation-message-target-required-claim":
"$1应拥有{{PLURAL:$3|0=声明$2。|1=声明$2 $5。|声明$2,并使用以下值之一:$4}}",
- "wbqc-violation-message-unique-value":
"此属性的值不得出现在其他任何项中,但却也出现在了{{PLURAL:$1|1=$3上。|2=$3和$4上。|以下项中:$2}}"
+ "wbqc-violation-message-unique-value":
"此属性的值不得出现在其他任何项中,但却也出现在了{{PLURAL:$1|1=$3上。|2=$3和$4上。|以下项中:$2}}",
+ "wbqc-exception-message": "此实体是该约束的已知例外,并已如此标记。"
}
diff --git
a/extensions/Constraints/includes/ConstraintCheck/Helper/TypeCheckerHelper.php
b/extensions/Constraints/includes/ConstraintCheck/Helper/TypeCheckerHelper.php
index d7cb13a..b3b698a 100644
---
a/extensions/Constraints/includes/ConstraintCheck/Helper/TypeCheckerHelper.php
+++
b/extensions/Constraints/includes/ConstraintCheck/Helper/TypeCheckerHelper.php
@@ -4,6 +4,7 @@
use Config;
use MediaWiki\MediaWikiServices;
+use OverflowException;
use Wikibase\DataModel\Entity\EntityId;
use Wikibase\DataModel\Entity\EntityIdValue;
use Wikibase\DataModel\Entity\PropertyId;
@@ -68,31 +69,19 @@
* of one of the item ID serializations in $classesToCheck.
* If the class hierarchy is not exhausted before
* the configured limit (WBQualityConstraintsTypeCheckMaxEntities) is
reached,
- * the injected {@link SparqlHelper} is consulted if present,
- * otherwise the check aborts and returns false.
+ * an OverflowException is thrown.
*
* @param EntityId $comparativeClass
* @param string[] $classesToCheck
* @param int &$entitiesChecked
*
* @return bool
- *
- * @throws SparqlHelperException if SPARQL is used and the query times
out or some other error occurs
+ * @throws OverflowException if $entitiesChecked exceeds the configured
limit
*/
- public function isSubclassOf( EntityId $comparativeClass, array
$classesToCheck, &$entitiesChecked = 0 ) {
+ private function isSubclassOf( EntityId $comparativeClass, array
$classesToCheck, &$entitiesChecked = 0 ) {
$maxEntities = $this->config->get(
'WBQualityConstraintsTypeCheckMaxEntities' );
if ( ++$entitiesChecked > $maxEntities ) {
- if ( $entitiesChecked === $maxEntities + 1 &&
$this->sparqlHelper !== null ) {
-
MediaWikiServices::getInstance()->getStatsdDataFactory()
- ->increment(
'wikibase.quality.constraints.sparql.typeFallback' );
- return $this->sparqlHelper->hasType(
- $comparativeClass->getSerialization(),
- $classesToCheck,
- /* withInstance = */ false
- );
- } else {
- return false;
- }
+ throw new OverflowException( 'Too many entities to
check' );
}
$item = $this->entityLookup->getEntity( $comparativeClass );
@@ -127,6 +116,39 @@
}
/**
+ * Checks if $comparativeClass is a subclass
+ * of one of the item ID serializations in $classesToCheck.
+ * If isSubclassOf() aborts due to hitting the configured limit,
+ * the injected {@link SparqlHelper} is consulted if present,
+ * otherwise the check returns false.
+ *
+ * @param EntityId $comparativeClass
+ * @param string[] $classesToCheck
+ * @param int &$entitiesChecked
+ *
+ * @return bool
+ *
+ * @throws SparqlHelperException if SPARQL is used and the query times
out or some other error occurs
+ */
+ public function isSubclassOfWithSparqlFallback( EntityId
$comparativeClass, array $classesToCheck ) {
+ try {
+ return $this->isSubclassOf( $comparativeClass,
$classesToCheck );
+ } catch ( OverflowException $e ) {
+ if ( $this->sparqlHelper !== null ) {
+
MediaWikiServices::getInstance()->getStatsdDataFactory()
+ ->increment(
'wikibase.quality.constraints.sparql.typeFallback' );
+ return $this->sparqlHelper->hasType(
+ $comparativeClass->getSerialization(),
+ $classesToCheck,
+ /* withInstance = */ false
+ );
+ } else {
+ return false;
+ }
+ }
+ }
+
+ /**
* Checks, if one of the itemId serializations in $classesToCheck
* is contained in the list of $statements
* via property $relationId or if it is a subclass of
@@ -158,7 +180,7 @@
return true;
}
- if ( $this->isSubclassOf( $comparativeClass,
$classesToCheck ) ) {
+ if ( $this->isSubclassOfWithSparqlFallback(
$comparativeClass, $classesToCheck ) ) {
return true;
}
}
diff --git a/extensions/Constraints/package.json
b/extensions/Constraints/package.json
index b85a888..8f94116 100644
--- a/extensions/Constraints/package.json
+++ b/extensions/Constraints/package.json
@@ -13,7 +13,7 @@
"devDependencies": {
"eslint-config-wikimedia": "0.4.0",
"grunt": "1.0.1",
- "grunt-banana-checker": "0.3.0",
+ "grunt-banana-checker": "0.6.0",
"grunt-eslint": "19.0.0",
"grunt-jsonlint": "1.1.0",
"grunt-stylelint": "0.6.0",
diff --git
a/extensions/Constraints/tests/phpunit/Checker/TypeChecker/TypeCheckerHelperTest.php
b/extensions/Constraints/tests/phpunit/Checker/TypeChecker/TypeCheckerHelperTest.php
index c4173a6..746cc8e 100644
---
a/extensions/Constraints/tests/phpunit/Checker/TypeChecker/TypeCheckerHelperTest.php
+++
b/extensions/Constraints/tests/phpunit/Checker/TypeChecker/TypeCheckerHelperTest.php
@@ -4,12 +4,15 @@
use PHPUnit_Framework_TestCase;
use Wikibase\DataModel\Services\Lookup\EntityLookup;
+use Wikibase\DataModel\Services\Lookup\InMemoryEntityLookup;
use Wikibase\DataModel\Statement\Statement;
use Wikibase\DataModel\Snak\PropertyValueSnak;
use Wikibase\DataModel\Entity\EntityIdValue;
use Wikibase\DataModel\Entity\ItemId;
use Wikibase\DataModel\Entity\PropertyId;
use Wikibase\DataModel\Statement\StatementList;
+use Wikibase\Repo\Tests\NewItem;
+use Wikibase\Repo\Tests\NewStatement;
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\SparqlHelper;
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\TypeCheckerHelper;
use WikibaseQuality\ConstraintReport\Tests\ConstraintParameters;
@@ -46,11 +49,14 @@
}
/**
+ * @param EntityLookup $lookup The backing lookup of the mock (defaults
to JsonFileEntityLookup).
* @return EntityLookup Expects that getEntity is called
* exactly WBQualityConstraintsTypeCheckMaxEntities times.
*/
- private function getMaxEntitiesLookup() {
- $lookup = new JsonFileEntityLookup( __DIR__ );
+ private function getMaxEntitiesLookup( EntityLookup $lookup = null ) {
+ if ( $lookup === null ) {
+ $lookup = new JsonFileEntityLookup( __DIR__ );
+ }
$maxEntities = $this->getDefaultConfig()->get(
'WBQualityConstraintsTypeCheckMaxEntities' );
$spy = $this->getMock( EntityLookup::class );
@@ -63,15 +69,20 @@
/**
* @param boolean $return
+ * @param array|null $arguments
* @return SparqlHelper expects that {@link SparqlHelper::hasType}
* is called exactly once and returns $return.
*/
- private function getSparqlHelper( $return ) {
+ private function getSparqlHelper( $return, array $arguments = null ) {
+ if ( $arguments === null ) {
+ $arguments = [ $this->anything(), $this->anything(),
$this->anything() ];
+ }
$mock = $this->getMockBuilder( SparqlHelper::class )
->disableOriginalConstructor()
->getMock();
$mock->expects( $this->once() )
->method( 'hasType' )
+ ->withConsecutive( $arguments )
->willReturn( $return );
return $mock;
}
@@ -98,31 +109,81 @@
}
public function testCheckIsSubclassOfValidWithIndirection() {
- $this->assertTrue( $this->getHelper()->isSubclassOf( new
ItemId( 'Q6' ), [ 'Q100', 'Q101' ] ) );
+ $this->assertTrue(
$this->getHelper()->isSubclassOfWithSparqlFallback( new ItemId( 'Q6' ), [
'Q100', 'Q101' ] ) );
}
public function testCheckIsSubclassOfInvalid() {
- $this->assertFalse( $this->getHelper()->isSubclassOf( new
ItemId( 'Q6' ), [ 'Q200', 'Q201' ] ) );
+ $this->assertFalse(
$this->getHelper()->isSubclassOfWithSparqlFallback( new ItemId( 'Q6' ), [
'Q200', 'Q201' ] ) );
}
public function testCheckIsSubclassCyclic() {
$helper = $this->getHelper( $this->getMaxEntitiesLookup() );
- $this->assertFalse( $helper->isSubclassOf( new ItemId( 'Q7' ),
[ 'Q100', 'Q101' ] ) );
+ $this->assertFalse( $helper->isSubclassOfWithSparqlFallback(
new ItemId( 'Q7' ), [ 'Q100', 'Q101' ] ) );
}
public function testCheckIsSubclassCyclicWide() {
$helper = $this->getHelper( $this->getMaxEntitiesLookup() );
- $this->assertFalse( $helper->isSubclassOf( new ItemId( 'Q9' ),
[ 'Q100', 'Q101' ] ) );
+ $this->assertFalse( $helper->isSubclassOfWithSparqlFallback(
new ItemId( 'Q9' ), [ 'Q100', 'Q101' ] ) );
}
public function testCheckIsSubclassCyclicWideWithSparqlTrue() {
$helper = $this->getHelper( $this->getMaxEntitiesLookup(),
$this->getSparqlHelper( true ) );
- $this->assertTrue( $helper->isSubclassOf( new ItemId( 'Q9' ), [
'Q100', 'Q101' ] ) );
+ $this->assertTrue( $helper->isSubclassOfWithSparqlFallback( new
ItemId( 'Q9' ), [ 'Q100', 'Q101' ] ) );
}
public function testCheckIsSubclassCyclicWideWithSparqlFalse() {
$helper = $this->getHelper( $this->getMaxEntitiesLookup(),
$this->getSparqlHelper( false ) );
- $this->assertFalse( $helper->isSubclassOf( new ItemId( 'Q9' ),
[ 'Q100', 'Q101' ] ) );
+ $this->assertFalse( $helper->isSubclassOfWithSparqlFallback(
new ItemId( 'Q9' ), [ 'Q100', 'Q101' ] ) );
+ }
+
+ public function testCheckIsSubclassTree() {
+ $lookup = new InMemoryEntityLookup();
+ $subclassPid = $this->getDefaultConfig()->get(
'WBQualityConstraintsSubclassOfId' );
+
+ $q1 = NewItem::withId( 'Q1' )
+ ->andStatement(
+ NewStatement::forProperty( $subclassPid )
+ ->withValue( new ItemId( 'Q2' ) )
+ )
+ ->build();
+ $lookup->addEntity( $q1 );
+ $q2 = NewItem::withId( 'Q2' )
+ ->andStatement(
+ NewStatement::forProperty( $subclassPid )
+ ->withValue( new ItemId( 'Q3' ) )
+ )
+ ->andStatement(
+ NewStatement::forProperty( $subclassPid )
+ ->withValue( new ItemId( 'Q5' ) )
+ )
+ ->build();
+ $lookup->addEntity( $q2 );
+ $q3 = NewItem::withId( 'Q3' )
+ ->andStatement(
+ NewStatement::forProperty( $subclassPid )
+ ->withValue( new ItemId( 'Q4' ) )
+ )
+ ->build();
+ $lookup->addEntity( $q3 );
+ $q4 = NewItem::withId( 'Q4' )
+ ->andStatement(
+ NewStatement::forProperty( $subclassPid )
+ ->withValue( new ItemId( 'Q3' ) )
+ )
+ ->build();
+ $lookup->addEntity( $q4 );
+
+ $sparqlHelper = $this->getSparqlHelper(
+ true,
+ [
+ $this->identicalTo( 'Q1' ),
+ $this->identicalTo( [ 'Q5' ] ),
+ $this->identicalTo( false )
+ ]
+ );
+ $helper = $this->getHelper( $this->getMaxEntitiesLookup(
$lookup ), $sparqlHelper );
+
+ $this->assertTrue( $helper->isSubclassOfWithSparqlFallback( new
ItemId( 'Q1' ), [ 'Q5' ] ) );
}
}
diff --git a/extensions/PropertySuggester/package.json
b/extensions/PropertySuggester/package.json
index bc9deeb..c0f24f3 100644
--- a/extensions/PropertySuggester/package.json
+++ b/extensions/PropertySuggester/package.json
@@ -12,7 +12,7 @@
"license": "GPL-2.0+",
"devDependencies": {
"eslint-config-wikimedia": "0.4.0",
- "grunt": "^1.0.1",
+ "grunt": "1.0.1",
"grunt-banana-checker": "0.5.0",
"grunt-eslint": "19.0.0",
"grunt-jsonlint": "1.0.7"
diff --git a/extensions/Quality/package.json b/extensions/Quality/package.json
index c8ba0d5..8e78752 100644
--- a/extensions/Quality/package.json
+++ b/extensions/Quality/package.json
@@ -11,12 +11,13 @@
"author": "BP2014N1",
"license": "GPL-2.0+",
"devDependencies": {
- "eslint-config-wikimedia": "0.4.0",
+ "eslint-config-wikimedia": "0.4.0",
"grunt": "1.0.1",
"grunt-banana-checker": "0.4.0",
"grunt-eslint": "19.0.0",
"grunt-jsonlint": "1.0.7",
"grunt-stylelint": "0.6.0",
+ "stylelint": "7.8.0",
"stylelint-config-wikimedia": "0.4.1"
}
}
diff --git a/extensions/Wikibase/client/i18n/din.json
b/extensions/Wikibase/client/i18n/din.json
index 109b122..a6ec9d3 100644
--- a/extensions/Wikibase/client/i18n/din.json
+++ b/extensions/Wikibase/client/i18n/din.json
@@ -10,6 +10,7 @@
"wikibase-dataitem": "{{WBREPONAME}} këdäŋ",
"wikibase-editlinks": "Lathë anuɛ̈tic",
"wikibase-editlinkstitle": "Lathë anuɛ̈t ë kaamëtokic",
+ "wikibase-linkitem-addlinks": "Mätë anuɛ̈t",
"wikibase-rc-hide-wikidata": "$1 {{WBREPONAME}}",
"wikibase-rc-hide-wikidata-hide": "Thaan",
"wikibase-rc-hide-wikidata-show": "Nyooth",
diff --git a/extensions/Wikibase/client/includes/Changes/ChangeHandler.php
b/extensions/Wikibase/client/includes/Changes/ChangeHandler.php
index 884c30e..d30344a 100644
--- a/extensions/Wikibase/client/includes/Changes/ChangeHandler.php
+++ b/extensions/Wikibase/client/includes/Changes/ChangeHandler.php
@@ -8,6 +8,7 @@
use MWException;
use SiteLookup;
use Title;
+use Traversable;
use Wikibase\Change;
use Wikibase\Client\Store\TitleFactory;
use Wikibase\Client\Usage\EntityUsage;
@@ -24,32 +25,6 @@
* @author Daniel Kinzler
*/
class ChangeHandler {
-
- /**
- * The change requites any rendered version of the page to be purged
from the parser cache.
- */
- const PARSER_PURGE_ACTION = 'parser';
-
- /**
- * The change requites a LinksUpdate job to be scheduled to update any
links
- * associated with the page.
- */
- const LINKS_UPDATE_ACTION = 'links';
-
- /**
- * The change requites any HTML output generated from the page to be
purged from web cached.
- */
- const WEB_PURGE_ACTION = 'web';
-
- /**
- * The change requites an entry to be injected into the recentchanges
table.
- */
- const RC_ENTRY_ACTION = 'rc';
-
- /**
- * The change requites an entry to be injected into the revision table.
- */
- const HISTORY_ENTRY_ACTION = 'history';
/**
* @var AffectedPagesFinder
@@ -157,117 +132,26 @@
wfDebugLog( __CLASS__, __FUNCTION__ . ': updating ' . count(
$usagesPerPage )
. " page(s) for change #$changeId." );
- $actionBuckets = [];
+ // Run all updates on all affected pages
+ $titlesToUpdate = $this->getTitlesForUsages( $usagesPerPage );
- /** @var PageEntityUsages $usages */
- foreach ( $usagesPerPage as $usages ) {
- $actions = $this->getUpdateActions(
$usages->getAspects() );
- $this->updateActionBuckets( $actionBuckets,
$usages->getPageId(), $actions );
- }
-
- foreach ( $actionBuckets as $action => $bucket ) {
- $this->applyUpdateAction( $action, $bucket, $change );
- }
+ $this->updater->purgeWebCache( $titlesToUpdate );
+ $this->updater->scheduleRefreshLinks( $titlesToUpdate );
+ $this->updater->injectRCRecords( $titlesToUpdate, $change );
+ // TODO: inject dummy revisions
}
/**
- * @param string[] $aspects List of usage aspects (without modifiers),
as defined by the
- * EntityUsage::..._USAGE constants.
- *
- * @return string[] List of actions, as defined by the
ChangeHandler::..._ACTION constants.
- */
- public function getUpdateActions( array $aspects ) {
- $actions = [];
- $aspects = array_flip( $aspects );
-
- $all = isset( $aspects[EntityUsage::ALL_USAGE] );
-
- if ( isset( $aspects[EntityUsage::SITELINK_USAGE] ) || $all ) {
- $actions[self::LINKS_UPDATE_ACTION] = true;
-
- // TODO: introduce an update action that updates just
the metadata
- // in the cached ParserOutput, without re-parsing the
page!
- $actions[self::PARSER_PURGE_ACTION] = true;
- }
-
- if ( isset( $aspects[EntityUsage::LABEL_USAGE] ) || $all ) {
- $actions[self::PARSER_PURGE_ACTION] = true;
- }
-
- if ( isset( $aspects[EntityUsage::TITLE_USAGE] ) || $all ) {
- $actions[self::PARSER_PURGE_ACTION] = true;
- }
-
- if ( isset( $aspects[EntityUsage::OTHER_USAGE] ) || $all ) {
- $actions[self::PARSER_PURGE_ACTION] = true;
- }
-
- // Purge caches and inject log entries if we have reason
- // to update the cached ParserOutput object in some way.
- if ( isset( $actions[self::PARSER_PURGE_ACTION] ) || isset(
$actions[self::LINKS_UPDATE_ACTION] ) ) {
- $actions[self::WEB_PURGE_ACTION] = true;
- $actions[self::RC_ENTRY_ACTION] = true;
- $actions[self::HISTORY_ENTRY_ACTION] = true;
- }
-
- return array_keys( $actions );
- }
-
- /**
- * @param array[] &$buckets Map of action names to lists of page IDs.
To be updated.
- * @param int $pageId The page ID
- * @param string[] $actions Actions to perform on the page
- */
- private function updateActionBuckets( array &$buckets, $pageId, array
$actions ) {
- foreach ( $actions as $action ) {
- $buckets[$action][] = $pageId;
- }
- }
-
- /**
- * @param string $action
- * @param int[] $pageIds
- * @param EntityChange $change
- */
- private function applyUpdateAction( $action, array $pageIds,
EntityChange $change ) {
- $titlesToUpdate = $this->getTitlesForPageIds( $pageIds );
-
- switch ( $action ) {
- case self::PARSER_PURGE_ACTION:
- $this->updater->purgeParserCache(
$titlesToUpdate );
- break;
-
- case self::WEB_PURGE_ACTION:
- $this->updater->purgeWebCache( $titlesToUpdate
);
- break;
-
- case self::LINKS_UPDATE_ACTION:
- $this->updater->scheduleRefreshLinks(
$titlesToUpdate );
- break;
-
- case self::RC_ENTRY_ACTION:
- if ( $this->injectRecentChanges ) {
- $this->updater->injectRCRecords(
$titlesToUpdate, $change );
- }
-
- break;
-
- //TODO: handling for self::HISTORY_ENTRY_ACTION goes
here.
- // should probably be
$this->updater->injectHistoryRecords() or some such.
- }
- }
-
- /**
- * @param int[] $pageIds
+ * @param Traversable $usagesPerPage A sequence of PageEntityUsages
objects
*
* @return Title[]
*/
- private function getTitlesForPageIds( array $pageIds ) {
+ private function getTitlesForUsages( $usagesPerPage ) {
$titles = [];
- foreach ( $pageIds as $id ) {
+ foreach ( $usagesPerPage as $usages ) {
try {
- $title = $this->titleFactory->newFromID( $id );
+ $title = $this->titleFactory->newFromID(
$usages->getPageId() );
$titles[] = $title;
} catch ( Exception $ex ) {
// No title for that ID, maybe the page got
deleted just now.
diff --git a/extensions/Wikibase/client/includes/Changes/PageUpdater.php
b/extensions/Wikibase/client/includes/Changes/PageUpdater.php
index ec74351..391f122 100644
--- a/extensions/Wikibase/client/includes/Changes/PageUpdater.php
+++ b/extensions/Wikibase/client/includes/Changes/PageUpdater.php
@@ -17,13 +17,6 @@
interface PageUpdater {
/**
- * Invalidates local cached of the given pages.
- *
- * @param Title[] $titles The Titles of the pages to update
- */
- public function purgeParserCache( array $titles );
-
- /**
* Invalidates external web cached of the given pages.
*
* @param Title[] $titles The Titles of the pages to update
diff --git a/extensions/Wikibase/client/includes/Changes/WikiPageUpdater.php
b/extensions/Wikibase/client/includes/Changes/WikiPageUpdater.php
index 3ab41b1..2ab62a5 100644
--- a/extensions/Wikibase/client/includes/Changes/WikiPageUpdater.php
+++ b/extensions/Wikibase/client/includes/Changes/WikiPageUpdater.php
@@ -2,7 +2,7 @@
namespace Wikibase\Client\Changes;
-use Job;
+use HTMLCacheUpdateJob;
use JobQueueGroup;
use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
use RefreshLinksJob;
@@ -95,33 +95,37 @@
}
/**
- * Invalidates local cached of the given pages.
- *
- * @param Title[] $titles The Titles of the pages to update
- */
- public function purgeParserCache( array $titles ) {
- /* @var Title $title */
- foreach ( $titles as $title ) {
- wfDebugLog( __CLASS__, __FUNCTION__ . ": purging page "
. $title->getText() );
-
- // TODO: This queues a database update for each title
separately. Batch it.
- $title->invalidateCache();
- }
- $this->incrementStats( 'ParserCache', count( $titles ) );
- }
-
- /**
* Invalidates external web cached of the given pages.
*
* @param Title[] $titles The Titles of the pages to update
*/
public function purgeWebCache( array $titles ) {
- /* @var Title $title */
- foreach ( $titles as $title ) {
- wfDebugLog( __CLASS__, __FUNCTION__ . ": purging web
cache for " . $title->getText() );
- $title->purgeSquid();
+ if ( $titles === [] ) {
+ return;
}
- $this->incrementStats( 'WebCache', count( $titles ) );
+
+ $jobs = [];
+ $titleBatches = array_chunk( $titles, $this->dbBatchSize );
+
+ /* @var Title[] $batch */
+ foreach ( $titleBatches as $batch ) {
+ wfDebugLog( __CLASS__, __FUNCTION__ . ": scheduling
HTMLCacheUpdateJob for "
+ . count( $batch ) . " titles" );
+
+ $dummyTitle = Title::makeTitle( NS_SPECIAL, 'Badtitle/'
. __CLASS__ );
+
+ $jobs[] = new HTMLCacheUpdateJob(
+ $dummyTitle, // the title will be ignored
because the 'pages' parameter is set.
+ [
+ 'pages' =>
$this->getPageParamForRefreshLinksJob( $batch ),
+ 'rootJobTimestamp' => wfTimestampNow()
+ ]
+ );
+ }
+
+ $this->jobQueueGroup->lazyPush( $jobs );
+ $this->incrementStats( 'WebCache.jobs', count( $jobs ) );
+ $this->incrementStats( 'WebCache.titles', count( $titles ) );
}
/**
@@ -130,22 +134,51 @@
* @param Title[] $titles The Titles of the pages to update
*/
public function scheduleRefreshLinks( array $titles ) {
- /* @var Title $title */
- foreach ( $titles as $title ) {
- wfDebugLog( __CLASS__, __FUNCTION__ . ": scheduling
refresh links for "
- . $title->getText() );
-
- $job = new RefreshLinksJob(
- $title,
- Job::newRootJobParams(
- $title->getPrefixedDBkey()
- )
- );
-
- $this->jobQueueGroup->push( $job );
- $this->jobQueueGroup->deduplicateRootJob( $job );
+ if ( $titles === [] ) {
+ return;
}
- $this->incrementStats( 'RefreshLinksJob', count( $titles ) );
+
+ $jobs = [];
+ $titleBatches = array_chunk( $titles, $this->dbBatchSize );
+
+ /* @var Title[] $batch */
+ foreach ( $titleBatches as $batch ) {
+ wfDebugLog( __CLASS__, __FUNCTION__ . ": scheduling
refresh links for "
+ . count( $batch ) . " titles" );
+
+ $dummyTitle = Title::makeTitle( NS_SPECIAL, 'Badtitle/'
. __CLASS__ );
+
+ $jobs[] = new RefreshLinksJob(
+ $dummyTitle, // the title will be ignored
because the 'pages' parameter is set.
+ [
+ 'pages' =>
$this->getPageParamForRefreshLinksJob( $batch ),
+ 'rootJobTimestamp' => wfTimestampNow(),
+ ]
+ );
+ }
+
+ $this->jobQueueGroup->lazyPush( $jobs );
+ $this->incrementStats( 'RefreshLinks.jobs', count( $jobs ) );
+ $this->incrementStats( 'RefreshLinks.titles', count( $titles )
);
+ }
+
+ /**
+ * @param Title[] $titles
+ *
+ * @returns array[] string $pageId => [ int $namespace, string $dbKey ]
+ */
+ private function getPageParamForRefreshLinksJob( array $titles ) {
+ $pages = [];
+
+ foreach ( $titles as $t ) {
+ $id = $t->getArticleID();
+ $pages[$id] = [
+ $t->getNamespace(),
+ $t->getDBkey()
+ ];
+ }
+
+ return $pages;
}
/**
diff --git a/extensions/Wikibase/client/includes/WikibaseClient.php
b/extensions/Wikibase/client/includes/WikibaseClient.php
index 6b2d353..9a0ba9d 100644
--- a/extensions/Wikibase/client/includes/WikibaseClient.php
+++ b/extensions/Wikibase/client/includes/WikibaseClient.php
@@ -224,9 +224,19 @@
private $repositoryDefinitions;
/**
- * @var PrefetchingTermLookup|null
+ * @var TermLookup|null
*/
private $termLookup = null;
+
+ /**
+ * @var TermBuffer|null
+ */
+ private $termBuffer = null;
+
+ /**
+ * @var PrefetchingTermLookup|null
+ */
+ private $prefetchingTermLookup = null;
/**
* @var EntityNamespaceLookup|null
@@ -423,25 +433,34 @@
* @return TermBuffer
*/
public function getTermBuffer() {
- return $this->getPrefetchingTermLookup();
+ if ( !$this->termBuffer ) {
+ $this->termBuffer = $this->getPrefetchingTermLookup();
+ }
+
+ return $this->termBuffer;
}
/**
* @return TermLookup
*/
public function getTermLookup() {
- return $this->getPrefetchingTermLookup();
+ if ( !$this->termLookup ) {
+ $this->termLookup = $this->getPrefetchingTermLookup();
+ }
+
+ return $this->termLookup;
}
/**
* @return PrefetchingTermLookup
*/
private function getPrefetchingTermLookup() {
- if ( !$this->termLookup ) {
- $this->termLookup =
$this->getEntityDataRetrievalServiceFactory()->getTermBuffer();
+ if ( !$this->prefetchingTermLookup ) {
+ // TODO: This should not assume the TermBuffer instance
to be a PrefetchingTermLookup
+ $this->prefetchingTermLookup =
$this->getEntityDataRetrievalServiceFactory()->getTermBuffer();
}
- return $this->termLookup;
+ return $this->prefetchingTermLookup;
}
/**
diff --git
a/extensions/Wikibase/client/tests/phpunit/includes/Changes/ChangeHandlerTest.php
b/extensions/Wikibase/client/tests/phpunit/includes/Changes/ChangeHandlerTest.php
index ed5d00c..a3dc146 100644
---
a/extensions/Wikibase/client/tests/phpunit/includes/Changes/ChangeHandlerTest.php
+++
b/extensions/Wikibase/client/tests/phpunit/includes/Changes/ChangeHandlerTest.php
@@ -181,66 +181,6 @@
$this->assertEquals( 1, $spy->handleChangesCallCount );
}
- public function provideGetUpdateActions() {
- return [
- 'empty' => [
- [],
- [],
- ],
- 'sitelink usage' => [
- [ EntityUsage::SITELINK_USAGE ],
- [ ChangeHandler::LINKS_UPDATE_ACTION,
ChangeHandler::PARSER_PURGE_ACTION,
- ChangeHandler::WEB_PURGE_ACTION,
ChangeHandler::RC_ENTRY_ACTION ],
- ],
- 'label usage' => [
- [ EntityUsage::LABEL_USAGE ],
- [ ChangeHandler::PARSER_PURGE_ACTION,
ChangeHandler::WEB_PURGE_ACTION,
- ChangeHandler::RC_ENTRY_ACTION ],
- [ ChangeHandler::LINKS_UPDATE_ACTION ]
- ],
- 'title usage' => [
- [ EntityUsage::TITLE_USAGE ],
- [ ChangeHandler::PARSER_PURGE_ACTION,
ChangeHandler::WEB_PURGE_ACTION,
- ChangeHandler::RC_ENTRY_ACTION ],
- [ ChangeHandler::LINKS_UPDATE_ACTION ]
- ],
- 'other usage' => [
- [ EntityUsage::OTHER_USAGE ],
- [ ChangeHandler::PARSER_PURGE_ACTION,
ChangeHandler::WEB_PURGE_ACTION,
- ChangeHandler::RC_ENTRY_ACTION ],
- [ ChangeHandler::LINKS_UPDATE_ACTION ]
- ],
- 'all usage' => [
- [ EntityUsage::ALL_USAGE ],
- [ ChangeHandler::PARSER_PURGE_ACTION,
ChangeHandler::WEB_PURGE_ACTION,
- ChangeHandler::RC_ENTRY_ACTION ],
- ],
- 'sitelink and other usage (does links update)' => [
- [ EntityUsage::SITELINK_USAGE,
EntityUsage::OTHER_USAGE ],
- [ ChangeHandler::LINKS_UPDATE_ACTION,
ChangeHandler::PARSER_PURGE_ACTION,
- ChangeHandler::WEB_PURGE_ACTION,
ChangeHandler::RC_ENTRY_ACTION ],
- ],
- ];
- }
-
- /**
- * @dataProvider provideGetUpdateActions
- */
- public function testGetUpdateActions( array $aspects, array $expected,
array $not = [] ) {
- $handler = $this->getChangeHandler();
- $actions = $handler->getUpdateActions( $aspects );
-
- sort( $expected );
- sort( $actions );
-
- // check that $actions contains AT LEAST $expected
- $actual = array_intersect( $actions, $expected );
- $this->assertEquals( array_values( $expected ), array_values(
$actual ), 'expected actions' );
-
- $unexpected = array_intersect( $actions, $not );
- $this->assertEmpty( array_values( $unexpected ), 'unexpected
actions: ' . implode( '|', $unexpected ) );
- }
-
/**
* Returns a map of fake local page IDs to the corresponding local page
names.
* The fake page IDs are the IDs of the items that have a sitelink to
the
@@ -390,42 +330,36 @@
$userEmmy2 = Title::newFromText( 'User:Emmy2'
)->getPrefixedText();
$empty = [
- 'purgeParserCache' => [],
'scheduleRefreshLinks' => [],
'purgeWebCache' => [],
'injectRCRecord' => [],
];
$emmy2PurgeParser = [
- 'purgeParserCache' => [ 'Emmy2' => true ],
- 'scheduleRefreshLinks' => [],
+ 'scheduleRefreshLinks' => [ 'Emmy2' => true ],
'purgeWebCache' => [ 'Emmy2' => true ],
'injectRCRecord' => [ 'Emmy2' => true ],
];
$userEmmy2PurgeParser = [
- 'purgeParserCache' => [ $userEmmy2 => true ],
- 'scheduleRefreshLinks' => [],
+ 'scheduleRefreshLinks' => [ $userEmmy2 => true ],
'purgeWebCache' => [ $userEmmy2 => true ],
'injectRCRecord' => [ $userEmmy2 => true ],
];
$emmyUpdateLinks = [
- 'purgeParserCache' => [ 'Emmy' => true ],
'scheduleRefreshLinks' => [ 'Emmy' => true ],
'purgeWebCache' => [ 'Emmy' => true ],
'injectRCRecord' => [ 'Emmy' => true ],
];
$emmy2UpdateLinks = [
- 'purgeParserCache' => [ 'Emmy2' => true ],
'scheduleRefreshLinks' => [ 'Emmy2' => true ],
'purgeWebCache' => [ 'Emmy2' => true ],
'injectRCRecord' => [ 'Emmy2' => true ],
];
$emmy2UpdateAll = [
- 'purgeParserCache' => [ 'Emmy2' => true ],
'scheduleRefreshLinks' => [ 'Emmy2' => true ],
'purgeWebCache' => [ 'Emmy2' => true ],
'injectRCRecord' => [ 'Emmy2' => true ],
@@ -516,7 +450,6 @@
$changes['change-enwiki-sitelink'],
[ 'q100' => [ 'enwiki' => 'Emmy' ], 'q200' => [
'enwiki' => 'Emmy2' ] ],
[
- 'purgeParserCache' => [ 'Emmy' => true,
'Emmy2' => true ],
'scheduleRefreshLinks' => [ 'Emmy' =>
true, 'Emmy2' => true ],
'purgeWebCache' => [ 'Emmy' => true,
'Emmy2' => true ],
'injectRCRecord' => [ 'Emmy' => true,
'Emmy2' => true ],
diff --git
a/extensions/Wikibase/client/tests/phpunit/includes/Changes/MockPageUpdater.php
b/extensions/Wikibase/client/tests/phpunit/includes/Changes/MockPageUpdater.php
index 34f7047..02a7028 100644
---
a/extensions/Wikibase/client/tests/phpunit/includes/Changes/MockPageUpdater.php
+++
b/extensions/Wikibase/client/tests/phpunit/includes/Changes/MockPageUpdater.php
@@ -18,21 +18,10 @@
class MockPageUpdater implements PageUpdater {
private $updates = [
- 'purgeParserCache' => [],
'purgeWebCache' => [],
'scheduleRefreshLinks' => [],
'injectRCRecord' => [],
];
-
- /**
- * @param Title[] $titles
- */
- public function purgeParserCache( array $titles ) {
- foreach ( $titles as $title ) {
- $key = $title->getPrefixedDBkey();
- $this->updates['purgeParserCache'][ $key ] = $title;
- }
- }
/**
* @param Title[] $titles
diff --git
a/extensions/Wikibase/client/tests/phpunit/includes/Changes/WikiPageUpdaterTest.php
b/extensions/Wikibase/client/tests/phpunit/includes/Changes/WikiPageUpdaterTest.php
index 2be8d28..5315a06 100644
---
a/extensions/Wikibase/client/tests/phpunit/includes/Changes/WikiPageUpdaterTest.php
+++
b/extensions/Wikibase/client/tests/phpunit/includes/Changes/WikiPageUpdaterTest.php
@@ -3,9 +3,11 @@
namespace Wikibase\Client\Tests\Changes;
use IJobSpecification;
+use HTMLCacheUpdateJob;
use Job;
use JobQueueGroup;
use PHPUnit_Framework_MockObject_MockObject;
+use MediaWiki\MediaWikiServices;
use RefreshLinksJob;
use Title;
use Wikibase\Client\Changes\WikiPageUpdater;
@@ -135,77 +137,78 @@
return $LBFactory;
}
- public function testPurgeParserCache() {
- $updater = new WikiPageUpdater(
- $this->getJobQueueGroupMock(),
- $this->getRCFactoryMock(),
- $this->getLBFactoryMock(),
- $this->getRCDupeDetectorMock()
- );
-
- $title = $this->getTitleMock( 'Foo' );
-
- $title->expects( $this->once() )
- ->method( 'invalidateCache' );
-
- $updater->purgeParserCache( [
- $title
- ] );
- }
-
public function testPurgeWebCache() {
- $updater = new WikiPageUpdater(
- $this->getJobQueueGroupMock(),
- $this->getRCFactoryMock(),
- $this->getLBFactoryMock(),
- $this->getRCDupeDetectorMock()
- );
-
- $title = $this->getTitleMock( 'Foo' );
- $title->expects( $this->once() )
- ->method( 'purgeSquid' );
-
- $updater->purgeWebCache( [
- $title
- ] );
- }
-
- public function testScheduleRefreshLinks() {
- $title = $this->getTitleMock( 'Foo' );
+ $titleFoo = $this->getTitleMock( 'Foo', 21 );
+ $titleBar = $this->getTitleMock( 'Bar', 22 );
+ $titleCuzz = $this->getTitleMock( 'Cuzz', 23 );
$jobQueueGroup = $this->getJobQueueGroupMock();
- $jobMatcher = function( RefreshLinksJob $job ) {
- $this->assertSame( 'Foo',
$job->getTitle()->getPrefixedDBkey() );
-
- $expectedSignature = Job::newRootJobParams( 'Foo' );
- $actualSignature = $job->getRootJobParams();
- $this->assertSame(
- $expectedSignature['rootJobSignature'],
- $actualSignature['rootJobSignature']
- );
-
- return true;
- };
-
- $jobQueueGroup->expects( $this->any() )
- ->method( 'push' )
- ->with( $this->callback( $jobMatcher ) );
-
- $jobQueueGroup->expects( $this->any() )
- ->method( 'deduplicateRootJob' )
- ->with( $this->callback( $jobMatcher ) );
+ $pages = [];
+ $jobQueueGroup->expects( $this->atLeastOnce() )
+ ->method( 'lazyPush' )
+ ->will( $this->returnCallback( function( array $jobs )
use ( &$pages ) {
+ /** @var Job $job */
+ foreach ( $jobs as $job ) {
+ $this->assertInstanceOf(
HTMLCacheUpdateJob::class, $job );
+ $params = $job->getParams();
+ $this->assertArrayHasKey( 'pages',
$params, '$params["pages"]' );
+ $pages += $params['pages']; // addition
uses keys, array_merge does not
+ }
+ } ) );
$updater = new WikiPageUpdater(
$jobQueueGroup,
$this->getRCFactoryMock(),
- $this->getLBFactoryMock(),
+
MediaWikiServices::getInstance()->getDBLoadBalancerFactory(),
+ $this->getRCDupeDetectorMock()
+ );
+
+ $updater->purgeWebCache( [
+ $titleFoo, $titleBar, $titleCuzz,
+ ] );
+
+ $this->assertEquals( [ 21, 22, 23 ], array_keys( $pages ) );
+ $this->assertEquals( [ 0, 'Foo' ], $pages[21], '$pages[21]' );
+ $this->assertEquals( [ 0, 'Bar' ], $pages[22], '$pages[22]' );
+ $this->assertEquals( [ 0, 'Cuzz' ], $pages[23], '$pages[23]' );
+ }
+
+ public function testScheduleRefreshLinks() {
+ $titleFoo = $this->getTitleMock( 'Foo', 21 );
+ $titleBar = $this->getTitleMock( 'Bar', 22 );
+ $titleCuzz = $this->getTitleMock( 'Cuzz', 23 );
+
+ $jobQueueGroup = $this->getJobQueueGroupMock();
+
+ $pages = [];
+ $jobQueueGroup->expects( $this->atLeastOnce() )
+ ->method( 'lazyPush' )
+ ->will( $this->returnCallback( function( array $jobs )
use ( &$pages ) {
+ /** @var Job $job */
+ foreach ( $jobs as $job ) {
+ $this->assertInstanceOf(
RefreshLinksJob::class, $job );
+ $params = $job->getParams();
+ $this->assertArrayHasKey( 'pages',
$params, '$params["pages"]' );
+ $pages += $params['pages']; // addition
uses keys, array_merge does not
+ }
+ } ) );
+
+ $updater = new WikiPageUpdater(
+ $jobQueueGroup,
+ $this->getRCFactoryMock(),
+
MediaWikiServices::getInstance()->getDBLoadBalancerFactory(),
$this->getRCDupeDetectorMock()
);
$updater->scheduleRefreshLinks( [
- $title
+ $titleFoo, $titleBar, $titleCuzz,
] );
+
+ $this->assertEquals( [ 21, 22, 23 ], array_keys( $pages ) );
+ $this->assertEquals( [ 0, 'Foo' ], $pages[21], '$pages[21]' );
+ $this->assertEquals( [ 0, 'Bar' ], $pages[22], '$pages[22]' );
+ $this->assertEquals( [ 0, 'Cuzz' ], $pages[23], '$pages[23]' );
}
public function testInjectRCRecords() {
diff --git a/extensions/Wikibase/repo/includes/EditEntity.php
b/extensions/Wikibase/repo/includes/EditEntity.php
index 6fe10e3..30250e8 100644
--- a/extensions/Wikibase/repo/includes/EditEntity.php
+++ b/extensions/Wikibase/repo/includes/EditEntity.php
@@ -106,11 +106,6 @@
private $title = null;
/**
- * @var IContextSource
- */
- private $context;
-
- /**
* @var EditFilterHookRunner
*/
private $editFilterHookRunner;
@@ -178,10 +173,6 @@
* This will detect "late" edit conflicts, i.e. someone
squeezing in an edit
* just before the actual database transaction for saving beings.
* The empty string and 0 are both treated as `false`, disabling
conflict checks.
- * @param IContextSource|null $context the context to use while
processing
- * the edit; defaults to RequestContext::getMain().
- *
- * @throws InvalidArgumentException
*/
public function __construct(
EntityTitleStoreLookup $titleLookup,
@@ -193,8 +184,7 @@
EntityDocument $newEntity,
User $user,
EditFilterHookRunner $editFilterHookRunner,
- $baseRevId = false,
- IContextSource $context = null
+ $baseRevId = false
) {
$this->newEntity = $newEntity;
@@ -211,12 +201,6 @@
$this->errorType = 0;
$this->status = Status::newGood();
-
- if ( $context === null ) {
- $context = RequestContext::getMain();
- }
-
- $this->context = $context;
$this->titleLookup = $titleLookup;
$this->entityRevisionLookup = $entityLookup;
@@ -678,56 +662,6 @@
*/
public function doesCheckForEditConflicts() {
return $this->getBaseRevisionId() !== false;
- }
-
- /**
- * Shows an error page showing the errors that occurred during
attemptSave(), if any.
- *
- * If $titleMessage is set it is made an assumption that the page is
still the original
- * one, and there should be no link back from a special error page.
- *
- * @param string|null $titleMessage Message key for the page title.
- *
- * @return bool true if an error page was shown, false if there were no
errors to show.
- */
- public function showErrorPage( $titleMessage = null ) {
- $out = $this->context->getOutput();
-
- if ( $this->status === null || $this->status->isOK() ) {
- return false;
- }
-
- if ( $titleMessage === null ) {
- $out->prepareErrorPage( wfMessage( 'errorpagetitle' ) );
- } else {
- $out->prepareErrorPage( wfMessage( $titleMessage ),
wfMessage( 'errorpagetitle' ) );
- }
-
- $this->showStatus();
-
- if ( !isset( $titleMessage ) ) {
- $out->returnToMain( '', $this->getTitle() );
- }
-
- return true;
- }
-
- /**
- * Shows any errors or warnings from attemptSave().
- *
- * @return bool true if any message was shown, false if there were no
errors to show.
- */
- private function showStatus() {
- if ( $this->status === null || $this->status->isGood() ) {
- return false;
- }
-
- $out = $this->context->getOutput();
- $text = $this->status->getHTML();
-
- $out->addHTML( Html::rawElement( 'div', [ 'class' => 'error' ],
$text ) );
-
- return true;
}
/**
diff --git a/extensions/Wikibase/repo/includes/EditEntityFactory.php
b/extensions/Wikibase/repo/includes/EditEntityFactory.php
index d88a6c5..b81e94b 100644
--- a/extensions/Wikibase/repo/includes/EditEntityFactory.php
+++ b/extensions/Wikibase/repo/includes/EditEntityFactory.php
@@ -55,11 +55,6 @@
private $editFilterHookRunner;
/**
- * @var IContextSource|null
- */
- private $context;
-
- /**
* @param EntityTitleStoreLookup $titleLookup
* @param EntityRevisionLookup $entityLookup
* @param EntityStore $entityStore
@@ -67,7 +62,6 @@
* @param EntityDiffer $entityDiffer
* @param EntityPatcher $entityPatcher
* @param EditFilterHookRunner $editFilterHookRunner
- * @param IContextSource|null $context
*/
public function __construct(
EntityTitleStoreLookup $titleLookup,
@@ -76,8 +70,7 @@
EntityPermissionChecker $permissionChecker,
EntityDiffer $entityDiffer,
EntityPatcher $entityPatcher,
- EditFilterHookRunner $editFilterHookRunner,
- IContextSource $context = null
+ EditFilterHookRunner $editFilterHookRunner
) {
$this->titleLookup = $titleLookup;
$this->entityRevisionLookup = $entityLookup;
@@ -86,7 +79,6 @@
$this->entityDiffer = $entityDiffer;
$this->entityPatcher = $entityPatcher;
$this->editFilterHookRunner = $editFilterHookRunner;
- $this->context = $context;
}
/**
@@ -112,8 +104,7 @@
$entity,
$user,
$this->editFilterHookRunner,
- $baseRevId,
- $this->context
+ $baseRevId
);
}
diff --git
a/extensions/Wikibase/repo/includes/Store/EntityPermissionChecker.php
b/extensions/Wikibase/repo/includes/Store/EntityPermissionChecker.php
index e197c8f..2242f88 100644
--- a/extensions/Wikibase/repo/includes/Store/EntityPermissionChecker.php
+++ b/extensions/Wikibase/repo/includes/Store/EntityPermissionChecker.php
@@ -20,8 +20,6 @@
const ACTION_EDIT = 'edit';
- const ACTION_CREATE = 'create';
-
const ACTION_EDIT_TERMS = 'term';
const ACTION_MERGE = 'merge';
diff --git
a/extensions/Wikibase/repo/includes/Store/WikiPageEntityStorePermissionChecker.php
b/extensions/Wikibase/repo/includes/Store/WikiPageEntityStorePermissionChecker.php
index ec93fd7..710501b 100644
---
a/extensions/Wikibase/repo/includes/Store/WikiPageEntityStorePermissionChecker.php
+++
b/extensions/Wikibase/repo/includes/Store/WikiPageEntityStorePermissionChecker.php
@@ -18,6 +18,8 @@
*/
class WikiPageEntityStorePermissionChecker implements EntityPermissionChecker {
+ const ACTION_MW_CREATE = 'create';
+
/**
* @var EntityNamespaceLookup
*/
@@ -71,7 +73,7 @@
if ( $id === null ) {
return $this->getPermissionStatusForEntityType(
$user,
- [ $action, self::ACTION_CREATE ],
+ [ $action, self::ACTION_MW_CREATE ],
$entity->getType(),
$quick
);
@@ -103,7 +105,7 @@
if ( $title === null || !$title->exists() ) {
return $this->getPermissionStatusForEntityType(
$user,
- [ $action, self::ACTION_CREATE ],
+ [ $action, self::ACTION_MW_CREATE ],
$entityId->getEntityType(),
$quick
);
@@ -178,7 +180,7 @@
}
private function getMediaWikiPermissionsToCheck( $action, $entityType )
{
- if ( $action === EntityPermissionChecker::ACTION_CREATE ) {
+ if ( $action === self::ACTION_MW_CREATE ) {
$entityTypeSpecificCreatePermission = $entityType .
'-create';
$permissions = [ 'read', 'edit', 'createpage' ];
diff --git a/extensions/Wikibase/repo/includes/WikibaseRepo.php
b/extensions/Wikibase/repo/includes/WikibaseRepo.php
index a2258a3..025bd48 100644
--- a/extensions/Wikibase/repo/includes/WikibaseRepo.php
+++ b/extensions/Wikibase/repo/includes/WikibaseRepo.php
@@ -1647,10 +1647,6 @@
* @return EditEntityFactory
*/
public function newEditEntityFactory( IContextSource $context = null ) {
- if ( $context === null ) {
- $context = RequestContext::getMain();
- }
-
return new EditEntityFactory(
$this->getEntityTitleLookup(),
$this->getEntityRevisionLookup( 'uncached' ),
@@ -1658,8 +1654,7 @@
$this->getEntityPermissionChecker(),
$this->getEntityDiffer(),
$this->getEntityPatcher(),
- $this->newEditFilterHookRunner( $context ),
- $context
+ $this->newEditFilterHookRunner( $context ?:
RequestContext::getMain() )
);
}
diff --git a/extensions/Wikibase/repo/maintenance/dispatchChanges.php
b/extensions/Wikibase/repo/maintenance/dispatchChanges.php
index 7189bda..1ca5612 100644
--- a/extensions/Wikibase/repo/maintenance/dispatchChanges.php
+++ b/extensions/Wikibase/repo/maintenance/dispatchChanges.php
@@ -232,6 +232,8 @@
if ( $wikiState ) {
$dispatchedChanges =
$dispatcher->dispatchTo( $wikiState );
$stats->updateCount(
'wikibase.repo.dispatchChanges.changes', $dispatchedChanges );
+ $stats->updateCount(
'wikibase.repo.dispatchChanges.changes-per-client.'
+
. $wikiState['chd_site'], $dispatchedChanges );
} else {
$stats->increment(
'wikibase.repo.dispatchChanges.noclient' );
// Try again later, unless we have
already reached the limit.
diff --git a/extensions/Wikibase/repo/tests/phpunit/includes/EditEntityTest.php
b/extensions/Wikibase/repo/tests/phpunit/includes/EditEntityTest.php
index abf7bcc..803aa45 100644
--- a/extensions/Wikibase/repo/tests/phpunit/includes/EditEntityTest.php
+++ b/extensions/Wikibase/repo/tests/phpunit/includes/EditEntityTest.php
@@ -142,9 +142,6 @@
array $permissions = null,
$editFilterHookRunner = null
) {
- $context = new RequestContext();
- $context->setRequest( new FauxRequest() );
-
if ( $user === null ) {
$user = User::newFromName( 'EditEntityTestUser' );
}
@@ -164,8 +161,7 @@
$entity,
$user,
$editFilterHookRunner,
- $baseRevId,
- $context
+ $baseRevId
);
}
@@ -410,36 +406,6 @@
$this->assertEquals( $expectedConflict, $status->hasMessage(
'edit-conflict' ),
"Saving should have failed late if and only if a base
rev was provided.\n$statusMessage" );
-
- $this->assertEquals( $expectedConflict,
$editEntity->showErrorPage(),
- "If and only if there was an error, an error page
should be shown.\n$statusMessage" );
- }
-
- public function testErrorPage_DoesNotDoubleEscapeHtmlCharacters() {
- $repo = $this->getMockRepository();
- $permissions = [];
- $context = new RequestContext();
- // Cannot reuse makeEditEntity because we need the access the
context
- $editEntity = new EditEntity(
- $this->getEntityTitleLookup(),
- $repo,
- $repo,
- $this->getEntityPermissionChecker( $permissions ),
- new EntityDiffer(),
- new EntityPatcher(),
- new Item(),
- $this->getUser( 'EditEntityTestUser' ),
- $this->getMockEditFitlerHookRunner(),
- false,
- $context
- );
-
- $editEntity->checkEditPermissions();
- $editEntity->showErrorPage();
- $html = $context->getOutput()->getHTML();
-
- $this->assertContains( '<li>', $html, 'Unescaped HTML' );
- $this->assertNotContains( '&lt;', $html, 'No double
escaping' );
}
public function dataCheckEditPermissions() {
@@ -724,7 +690,6 @@
$this->assertEquals( $shouldWork, $edit->getStatus()->isOK() );
$this->assertNotEquals( $shouldWork, $edit->hasError(
EditEntity::TOKEN_ERROR ) );
- $this->assertNotEquals( $shouldWork, $edit->showErrorPage() );
}
public function provideAttemptSaveWatch() {
diff --git
a/extensions/Wikibase/repo/tests/phpunit/includes/Store/WikiPageEntityStorePermissionCheckerTest.php
b/extensions/Wikibase/repo/tests/phpunit/includes/Store/WikiPageEntityStorePermissionCheckerTest.php
index 1dd8701..91d6893 100644
---
a/extensions/Wikibase/repo/tests/phpunit/includes/Store/WikiPageEntityStorePermissionCheckerTest.php
+++
b/extensions/Wikibase/repo/tests/phpunit/includes/Store/WikiPageEntityStorePermissionCheckerTest.php
@@ -184,110 +184,6 @@
}
/**
- * @dataProvider provideNonExistingEntitiesAndPermissionsThatAllowEdit
- */
- public function
testAllRequiredPermissionsAreNeededToCreateNonExistingEntity(
- EntityDocument $nonExistentEntity,
- array $groupPermissionsAllowingCreation
- ) {
- $this->anyUserHasPermissions( $groupPermissionsAllowingCreation
);
-
- $this->assertUserIsAllowedTo(
EntityPermissionChecker::ACTION_CREATE, $nonExistentEntity );
- }
-
- /**
- * @dataProvider
provideNonExistingEntitiesAndPermissionsThatDisallowEdit
- */
- public function
testAllRequiredPermissionsAreNeededToCreateNonExistingEntity_failures(
- EntityDocument $nonExistingEntity,
- array $groupPermissions
- ) {
- $this->anyUserHasPermissions( $groupPermissions );
-
- $this->assertItIsForbiddenForUserTo(
EntityPermissionChecker::ACTION_CREATE, $nonExistingEntity );
- }
-
- /**
- * TODO: should this be even tested? Is this correct behaviour? Or
should it rather refuse on PERMISSION_CREATE
- * and the existing entity?
- *
- * @dataProvider provideExistingEntitiesAndPermissionsThatAllowCreating
- */
- public function
testAllRequiredPermissionsAreNeededToCreateExistingEntity(
- EntityDocument $existingEntity,
- array $groupPermissions
- ) {
- $this->anyUserHasPermissions( $groupPermissions );
-
- $this->assertUserIsAllowedTo(
EntityPermissionChecker::ACTION_CREATE, $existingEntity );
- }
-
- public function
provideExistingEntitiesAndPermissionsThatAllowCreating() {
- return [
- 'existing item, createpage permission' => [
- $this->getExistingItem(),
- [ 'createpage' => true ]
- ],
- 'existing item, createpage and property-create
permission' => [
- $this->getExistingProperty(),
- [ 'createpage' => true, 'property-create' =>
true, ]
- ],
- ];
- }
-
- /**
- * TODO: should this be even tested? Is this correct behaviour? Or
should it rather refuse on PERMISSION_CREATE
- * and the existing entity?
- *
- * @dataProvider
provideExistingEntitiesAndPermissionsThatDisallowCreating
- */
- public function
testAllRequiredPermissionsAreNeededToCreateExistingEntity_failures(
- EntityDocument $existingEntity,
- array $groupPermissions
- ) {
- $this->anyUserHasPermissions( $groupPermissions );
-
- $this->assertItIsForbiddenForUserTo(
EntityPermissionChecker::ACTION_CREATE, $existingEntity );
- }
-
- public function
provideExistingEntitiesAndPermissionsThatDisallowCreating() {
- return [
- 'existing item, no createpage permission' => [
- $this->getExistingItem(),
- [ 'createpage' => false ]
- ],
- 'existing item, no edit permission' => [
- $this->getExistingItem(),
- [ 'edit' => false, 'createpage' => true, ]
- ],
- 'existing item, no read permission' => [
- $this->getExistingItem(),
- [ 'read' => false, 'edit' => true, 'createpage'
=> true, ]
- ],
- 'existing property, no property-create permission' => [
- $this->getExistingProperty(),
- [ 'createpage' => true, 'property-create' =>
false, ]
- ],
- 'existing property, no createpage permission' => [
- $this->getExistingProperty(),
- [ 'createpage' => false, 'property-create' =>
true, ]
- ],
- 'existing property, no createpage nor property-create
permission' => [
- $this->getExistingProperty(),
- [ 'createpage' => false, 'property-create' =>
false, ]
- ],
- 'existing property, no edit permission' => [
- $this->getExistingProperty(),
- [ 'edit' => false, 'createpage' => true,
'property-create' => true, ]
- ],
- 'existing property, no read permission' => [
- $this->getExistingProperty(),
- [ 'read' => false, 'edit' => true, 'createpage'
=> true, 'property-create' => true, ]
- ],
- ];
- }
-
- /**
* @dataProvider provideAllEntities
*/
public function testReadPermissionsAreNeededToReadAnEntity(
EntityDocument $entity ) {
diff --git a/extensions/Wikibase/view/resources/wikibase/resources.php
b/extensions/Wikibase/view/resources/wikibase/resources.php
index 253e564..07889bf 100644
--- a/extensions/Wikibase/view/resources/wikibase/resources.php
+++ b/extensions/Wikibase/view/resources/wikibase/resources.php
@@ -23,7 +23,7 @@
'position' => 'top',
'styles' => [
// Order must be hierarchical, do not order
alphabetically
- 'wikibase.css',
+ 'wikibase.less',
'../jquery/wikibase/themes/default/jquery.wikibase.aliasesview.css',
'../jquery/wikibase/themes/default/jquery.wikibase.descriptionview.css',
'../jquery/wikibase/themes/default/jquery.wikibase.entityview.css',
diff --git a/extensions/Wikibase/view/resources/wikibase/wikibase.css
b/extensions/Wikibase/view/resources/wikibase/wikibase.less
similarity index 100%
rename from extensions/Wikibase/view/resources/wikibase/wikibase.css
rename to extensions/Wikibase/view/resources/wikibase/wikibase.less
diff --git a/package.json b/package.json
index 465d91b..0724a32 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,8 @@
"test": "grunt test"
},
"devDependencies": {
- "grunt": "1.0.1",
+ "grunt": "0.4.5",
+ "grunt-cli": "0.1.13",
"grunt-contrib-clean": "0.7.0",
"grunt-contrib-jshint": "0.12.0",
"grunt-exec": "0.4.6",
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 8dbd8a9..41065a9 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -122,12 +122,12 @@
"source": {
"type": "git",
"url":
"https://github.com/wikimedia/mediawiki-extensions-ArticlePlaceholder.git",
- "reference": "f1e8a1a35716239f9a78eebca09f1135935c4f17"
+ "reference": "9fde45a4bb0c062e9004c38a34f99f1c8dcab012"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-ArticlePlaceholder/zipball/f1e8a1a35716239f9a78eebca09f1135935c4f17",
- "reference": "f1e8a1a35716239f9a78eebca09f1135935c4f17",
+ "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-ArticlePlaceholder/zipball/9fde45a4bb0c062e9004c38a34f99f1c8dcab012",
+ "reference": "9fde45a4bb0c062e9004c38a34f99f1c8dcab012",
"shasum": ""
},
"require": {
@@ -138,7 +138,7 @@
"jakub-onderka/php-parallel-lint": "0.9.2",
"wikibase/wikibase-codesniffer": "^0.1.0"
},
- "time": "2017-07-31 10:42:11",
+ "time": "2017-08-01 20:36:04",
"type": "mediawiki-extension",
"installation-source": "dist",
"autoload": {
@@ -1380,12 +1380,12 @@
"source": {
"type": "git",
"url":
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git",
- "reference": "aa7c10c4531cca80af5f81b817fd5b578e94942e"
+ "reference": "4331d2cd0e171070329f5af6a465bd582d5fab2c"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/aa7c10c4531cca80af5f81b817fd5b578e94942e",
- "reference": "aa7c10c4531cca80af5f81b817fd5b578e94942e",
+ "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/4331d2cd0e171070329f5af6a465bd582d5fab2c",
+ "reference": "4331d2cd0e171070329f5af6a465bd582d5fab2c",
"shasum": ""
},
"require": {
@@ -1418,7 +1418,7 @@
"jakub-onderka/php-parallel-lint": ">=0.3 <0.10",
"wikibase/wikibase-codesniffer": "^0.1.0"
},
- "time": "2017-08-01 08:03:31",
+ "time": "2017-08-02 08:09:10",
"type": "mediawiki-extension",
"installation-source": "dist",
"autoload": {
@@ -1638,7 +1638,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/PropertySuggester",
- "reference": "ee4c46b4a335c87855e80147b2bc85766ae15b20"
+ "reference": "283a7070fd970cfe991f9b16f47b10cb04d1c4ce"
},
"require": {
"php": ">=5.5.9",
@@ -1653,7 +1653,7 @@
"wikibase/wikibase-codesniffer": "^0.1.0",
"wikimedia/testing-access-wrapper": "~1.0"
},
- "time": "2017-05-29 17:15:29",
+ "time": "2017-08-01 08:45:42",
"type": "mediawiki-extension",
"installation-source": "source",
"autoload": {
@@ -1699,7 +1699,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQuality",
- "reference": "22aafec778ad7605863090758753c21e79ed44df"
+ "reference": "9f25f6f316e962aa4117e0922e0c041eab895b79"
},
"require": {
"php": ">=5.5.9",
@@ -1719,7 +1719,7 @@
"wikibase/data-model-serialization": ">=0.1 <3.0",
"wikibase/wikibase-codesniffer": "^0.1.0"
},
- "time": "2017-07-28 20:48:10",
+ "time": "2017-08-01 11:18:15",
"type": "mediawiki-extension",
"installation-source": "source",
"autoload": {
@@ -1768,7 +1768,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQualityConstraints",
- "reference": "8614148918fc44218c82182610aff43fdd07f081"
+ "reference": "8c90ed7f4bc35d3b36b3823150404b8b41abfda8"
},
"require": {
"php": ">=5.5.9",
@@ -1784,7 +1784,7 @@
"satooshi/php-coveralls": "master-dev",
"wikibase/wikibase-codesniffer": "^0.1.0"
},
- "time": "2017-07-31 21:06:39",
+ "time": "2017-08-02 09:14:11",
"type": "mediawiki-extension",
"installation-source": "source",
"autoload": {
--
To view, visit https://gerrit.wikimedia.org/r/369624
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I8c81465b8105cd632c37512b0a134ad0a8e4f44a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikidata
Gerrit-Branch: master
Gerrit-Owner: WikidataBuilder <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits