jenkins-bot has submitted this change and it was merged.

Change subject: Add SpecialPagesWithBadges
......................................................................


Add SpecialPagesWithBadges

Caching of this query doesn't work because the query
depends on the user input.

Bug: T72209
Change-Id: I690b94af0ac11163c80e4422e6d72dacce447959
---
M client/WikibaseClient.hooks.php
M client/WikibaseClient.i18n.alias.php
M client/WikibaseClient.php
M client/i18n/en.json
M client/includes/WikibaseClient.php
A client/includes/specials/SpecialPagesWithBadges.php
M client/tests/phpunit/MockClientStore.php
A client/tests/phpunit/includes/specials/SpecialPagesWithBadgesTest.php
M repo/includes/WikibaseRepo.php
9 files changed, 417 insertions(+), 10 deletions(-)

Approvals:
  Daniel Kinzler: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/client/WikibaseClient.hooks.php b/client/WikibaseClient.hooks.php
index 0de0d8e..0725b88 100644
--- a/client/WikibaseClient.hooks.php
+++ b/client/WikibaseClient.hooks.php
@@ -601,6 +601,7 @@
 
        public static function onwgQueryPages( &$queryPages ) {
                $queryPages[] = array( 
'Wikibase\Client\Specials\SpecialUnconnectedPages', 'UnconnectedPages' );
+               $queryPages[] = array( 
'Wikibase\Client\Specials\SpecialPagesWithBadges', 'Badges' );
                return true;
        }
 
diff --git a/client/WikibaseClient.i18n.alias.php 
b/client/WikibaseClient.i18n.alias.php
index beb0626..0d60cd3 100644
--- a/client/WikibaseClient.i18n.alias.php
+++ b/client/WikibaseClient.i18n.alias.php
@@ -15,6 +15,7 @@
 /** English (English) */
 $specialPageAliases['en'] = array(
        'UnconnectedPages' => array( 'UnconnectedPages', 'WithoutConnection', 
'WithoutSitelinks' ),
+       'PagesWithBadges' => array( 'PagesWithBadges', 'QueryBadges' ),
 );
 
 /** Arabic (العربية) */
diff --git a/client/WikibaseClient.php b/client/WikibaseClient.php
index 6e79fae..0ee65c3 100644
--- a/client/WikibaseClient.php
+++ b/client/WikibaseClient.php
@@ -153,6 +153,7 @@
 
        // Special page registration
        $wgSpecialPages['UnconnectedPages'] = 
'Wikibase\Client\Specials\SpecialUnconnectedPages';
+       $wgSpecialPages['PagesWithBadges'] = 
'Wikibase\Client\Specials\SpecialPagesWithBadges';
        $wgHooks['wgQueryPages'][] = 'Wikibase\ClientHooks::onwgQueryPages';
 
        // Resource loader modules
diff --git a/client/i18n/en.json b/client/i18n/en.json
index 0e5df98..27180c0 100644
--- a/client/i18n/en.json
+++ b/client/i18n/en.json
@@ -66,12 +66,13 @@
        "wikibase-error-exceeded-entity-access-limit": "Too many {{WBREPONAME}} 
entities accessed.",
        "unconnectedpages": "Pages not connected to items",
        "unconnectedpages-summary": "This page lists pages with no connected 
data item (in namespaces that support connected items). The list is sorted by 
descending page ID, so that newer pages are listed first.",
-       "wikibase-unconnectedpages-page": "Start result list with page:",
-       "wikibase-unconnectedpages-submit": "Go",
-       "wikibase-unconnectedpages-invalid-language": "\"$1\" is not a valid 
language code.",
-       "wikibase-unconnectedpages-page-warning": "The page title could not be 
used for the query and is ignored.",
-       "wikibase-unconnectedpages-iwdata-label": "Only pages with 
interlanguage links",
        "wikibase-unconnectedpages-format-row": "($1 {{PLURAL:$1|interlanguage 
link|interlanguage links}} on the page)",
+       "pageswithbadges": "Pages with badges",
+       "pageswithbadges-summary": "This page lists pages with badges (eg. good 
article or featured article). The list is sorted by descending page ID, so that 
newer pages are listed first.",
+       "wikibase-pageswithbadges-invalid-id": "$1 is not a valid item id",
+       "wikibase-pageswithbadges-legend": "List of pages with a given badge",
+       "wikibase-pageswithbadges-badge": "Badge:",
+       "wikibase-pageswithbadges-submit": "Show pages",
        "wikibase-pageinfo-entity-id": "{{WBREPONAME}} item ID",
        "wikibase-pageinfo-entity-id-none": "None",
        "wikibase-property-render-error": "Failed to render property $1: $2",
diff --git a/client/includes/WikibaseClient.php 
b/client/includes/WikibaseClient.php
index 2254217..dd09569 100644
--- a/client/includes/WikibaseClient.php
+++ b/client/includes/WikibaseClient.php
@@ -39,9 +39,9 @@
 use Wikibase\DataModel\Services\EntityId\SuffixEntityIdParser;
 use Wikibase\DataModel\Services\Lookup\EntityLookup;
 use Wikibase\DataModel\Services\Lookup\EntityRetrievingDataTypeLookup;
-use Wikibase\DataModel\Services\Lookup\EntityRetrievingTermLookup;
 use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
 use Wikibase\DataModel\Services\Lookup\TermLookup;
+use Wikibase\DataModel\Services\Term\TermBuffer;
 use Wikibase\DirectSqlStore;
 use Wikibase\EntityFactory;
 use Wikibase\InternalSerialization\DeserializerFactory as 
InternalDeserializerFactory;
@@ -60,6 +60,7 @@
 use Wikibase\Lib\WikibaseValueFormatterBuilders;
 use Wikibase\NamespaceChecker;
 use Wikibase\SettingsArray;
+use Wikibase\Store\BufferingTermLookup;
 use Wikibase\StringNormalizer;
 
 /**
@@ -164,6 +165,13 @@
        private $dataTypeDefinitions;
 
        /**
+        * @var TermLookup|null
+        */
+       private $termLookup = null;
+
+       /**
+        * @since 0.4
+        *
         * @param SettingsArray $settings
         * @param Language $contentLanguage
         * @param DataTypeDefinitions $dataTypeDefinitions
@@ -216,10 +224,31 @@
        }
 
        /**
+        * @return TermBuffer
+        */
+       public function getTermBuffer() {
+               return $this->getBufferingTermLookup();
+       }
+
+       /**
         * @return TermLookup
         */
-       private function getTermLookup() {
-               return new EntityRetrievingTermLookup( $this->getEntityLookup() 
);
+       public function getTermLookup() {
+               return $this->getBufferingTermLookup();
+       }
+
+       /**
+        * @return BufferingTermLookup
+        */
+       public function getBufferingTermLookup() {
+               if ( !$this->termLookup ) {
+                       $this->termLookup = new BufferingTermLookup(
+                               $this->getStore()->getTermIndex(),
+                               1000 // @todo: configure buffer size
+                       );
+               }
+
+               return $this->termLookup;
        }
 
        /**
diff --git a/client/includes/specials/SpecialPagesWithBadges.php 
b/client/includes/specials/SpecialPagesWithBadges.php
new file mode 100644
index 0000000..0ac493f
--- /dev/null
+++ b/client/includes/specials/SpecialPagesWithBadges.php
@@ -0,0 +1,281 @@
+<?php
+
+
+namespace Wikibase\Client\Specials;
+
+use Html;
+use InvalidArgumentException;
+use Linker;
+use OutOfBoundsException;
+use QueryPage;
+use Skin;
+use Title;
+use Wikibase\Client\WikibaseClient;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\Lib\Store\LanguageFallbackLabelDescriptionLookupFactory;
+
+/**
+ * Show a list of pages with a given badge.
+ *
+ * @since 0.5
+ * @licence GNU GPL v2+
+ * @author Bene* < [email protected] >
+ */
+class SpecialPagesWithBadges extends QueryPage {
+
+       /**
+        * @var LanguageFallbackLabelDescriptionLookupFactory
+        */
+       private $labelDescriptionLookupFactory;
+
+       /**
+        * @var string[]
+        */
+       private $badgeIds;
+
+       /**
+        * @var string
+        */
+       private $siteId;
+
+       /**
+        * @var ItemId|null
+        */
+       private $badgeId;
+
+       /**
+        * @see SpecialPage::__construct
+        *
+        * @param string $name
+        */
+       public function __construct( $name = 'PagesWithBadges' ) {
+               parent::__construct( $name );
+
+               $wikibaseClient = WikibaseClient::getDefaultInstance();
+               $this->initServices(
+                       new LanguageFallbackLabelDescriptionLookupFactory(
+                               
$wikibaseClient->getLanguageFallbackChainFactory(),
+                               $wikibaseClient->getTermLookup(),
+                               $wikibaseClient->getTermBuffer()
+                       ),
+                       array_keys( $wikibaseClient->getSettings()->getSetting( 
'badgeClassNames' ) ),
+                       $wikibaseClient->getSettings()->getSetting( 
'siteGlobalID' )
+               );
+       }
+
+       /**
+        * @param LanguageFallbackLabelDescriptionLookupFactory 
$labelDescriptionLookupFactory
+        * @param string[] $badgeIds
+        * @param string $siteId
+        */
+       public function initServices(
+               LanguageFallbackLabelDescriptionLookupFactory 
$labelDescriptionLookupFactory,
+               array $badgeIds,
+               $siteId
+       ) {
+               $this->labelDescriptionLookupFactory = 
$labelDescriptionLookupFactory;
+               $this->badgeIds = $badgeIds;
+               $this->siteId = $siteId;
+       }
+
+       /**
+        * @see QueryPage::execute
+        *
+        * @param string $subPage
+        */
+       public function execute( $subPage ) {
+               $this->prepareParams( $subPage );
+
+               if ( $this->badgeId !== null ) {
+                       parent::execute( $subPage );
+               } else {
+                       $this->setHeaders();
+                       $this->outputHeader();
+                       $this->getOutput()->addHTML( $this->getPageHeader() );
+               }
+       }
+
+       private function prepareParams( $subPage ) {
+               $badge = $this->getRequest()->getText( 'badge', $subPage );
+
+               try {
+                       $this->badgeId = new ItemId( $badge );
+               } catch ( InvalidArgumentException $ex ) {
+                       if ( $badge ) {
+                               $this->getOutput()->addHTML(
+                                       Html::element(
+                                               'p',
+                                               array(
+                                                       'class' => 'error'
+                                               ),
+                                               $this->msg( 
'wikibase-pageswithbadges-invalid-id', $badge )
+                                       )
+                               );
+                       }
+               }
+       }
+
+       /**
+        * @see QueryPage::getPageHeader
+        *
+        * @return string
+        */
+       public function getPageHeader() {
+               return Html::openElement(
+                       'form',
+                       array(
+                               'action' => $this->getPageTitle()->getLocalURL()
+                       )
+               ) .
+               Html::openElement( 'fieldset' ) .
+               Html::element(
+                       'legend',
+                       array(),
+                       $this->msg( 'wikibase-pageswithbadges-legend' )->text()
+               ) .
+               Html::openElement( 'p' ) .
+               Html::element(
+                       'label',
+                       array(
+                               'for' => 'wb-pageswithbadges-badge'
+                       ),
+                       $this->msg( 'wikibase-pageswithbadges-badge' )->text()
+               ) . ' ' .
+               Html::rawElement(
+                       'select',
+                       array(
+                               'name' => 'badge',
+                               'id' => 'wb-pageswithbadges-badge',
+                               'class' => 'wb-select'
+                       ),
+                       $this->getOptionsHtml()
+               ) . ' ' .
+               Html::input(
+                       '',
+                       $this->msg( 'wikibase-pageswithbadges-submit' )->text(),
+                       'submit',
+                       array(
+                               'id' => 'wikibase-pageswithbadges-submit',
+                               'class' => 'wb-input-button'
+                       )
+               ) .
+               Html::closeElement( 'p' ) .
+               Html::closeElement( 'fieldset' ) .
+        Html::closeElement( 'form' );
+       }
+
+       private function getOptionsHtml() {
+               /** @var ItemId[] $badgeItemIds */
+               $badgeItemIds = array_map(
+                       function( $badgeId ) {
+                               return new ItemId( $badgeId );
+                       },
+                       $this->badgeIds
+               );
+
+               $labelLookup = 
$this->labelDescriptionLookupFactory->newLabelDescriptionLookup(
+                       $this->getLanguage(),
+                       $badgeItemIds
+               );
+
+               $html = '';
+
+               foreach ( $this->badgeIds as $badgeId ) {
+                       try {
+                               $label = $labelLookup->getLabel( new ItemId( 
$badgeId ) )->getText();
+                       } catch ( OutOfBoundsException $ex ) {
+                               // show plain id if no label has been found
+                               $label = $badgeId;
+                       }
+
+                       $html .= Html::element(
+                               'option',
+                               array(
+                                       'value' => $badgeId,
+                                       'selected' => $this->badgeId !== null 
&& $this->badgeId->getSerialization() === $badgeId
+                               ),
+                               $label
+                       );
+               }
+
+               return $html;
+       }
+
+       /**
+        * @see QueryPage::getQueryInfo
+        *
+        * @return array[]
+        */
+       public function getQueryInfo() {
+               return array(
+                       'tables' => array(
+                               'page',
+                               'page_props'
+                       ),
+                       'fields' => array(
+                               'value' => 'page_id',
+                               'namespace' => 'page_namespace',
+                               'title' => 'page_title',
+                       ),
+                       'conds' => array(
+                               'pp_propname' => 'wikibase-badge-' . 
$this->badgeId->getSerialization()
+                       ),
+                       'options' => array(), // sorting is determined 
getOrderFields(), which returns array( 'value' ) per default.
+                       'join_conds' => array(
+                               'page_props' => array( 'JOIN', array( 'page_id 
= pp_page' ) )
+                       )
+               );
+       }
+
+       /**
+        * @see QueryPage::formatResult
+        *
+        * @param Skin $skin
+        * @param object $result
+        *
+        * @return string
+        */
+       public function formatResult( $skin, $result ) {
+               $title = Title::newFromID( $result->value );
+               $out = Linker::linkKnown( $title );
+
+               return $out;
+       }
+
+       /**
+        * @see QueryPage::isSyndicated
+        *
+        * @return bool
+        */
+       public function isSyndicated() {
+               return false;
+       }
+
+       /**
+        * @see QueryPage::isCacheable
+        *
+        * @return bool
+        */
+       public function isCacheable() {
+               return false;
+       }
+
+       /**
+        * @see QueryPage::linkParameters
+        *
+        * @return array
+        */
+       public function linkParameters() {
+               return array( 'badge' => $this->badgeId->getSerialization()  );
+       }
+
+       /**
+        * @see SpecialPage::getGroupName
+        *
+        * @return string
+        */
+       protected function getGroupName() {
+               return 'pages';
+       }
+
+}
diff --git a/client/tests/phpunit/MockClientStore.php 
b/client/tests/phpunit/MockClientStore.php
index 08ded61..6a10b3f 100644
--- a/client/tests/phpunit/MockClientStore.php
+++ b/client/tests/phpunit/MockClientStore.php
@@ -90,6 +90,7 @@
         */
        public function getTermIndex() {
                // FIXME: Incomplete
+               return new MockTermIndex( array() );
        }
 
        /**
diff --git 
a/client/tests/phpunit/includes/specials/SpecialPagesWithBadgesTest.php 
b/client/tests/phpunit/includes/specials/SpecialPagesWithBadgesTest.php
new file mode 100644
index 0000000..2a9b8c9
--- /dev/null
+++ b/client/tests/phpunit/includes/specials/SpecialPagesWithBadgesTest.php
@@ -0,0 +1,92 @@
+<?php
+
+
+namespace Wikibase\Client\Tests\Specials;
+
+use Wikibase\Client\Specials\SpecialPagesWithBadges;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Services\Lookup\LabelDescriptionLookup;
+use Wikibase\DataModel\Term\Term;
+use Wikibase\Lib\Store\LanguageFallbackLabelDescriptionLookupFactory;
+use Wikibase\Test\SpecialPageTestBase;
+
+/**
+ * @covers Wikibase\Client\Specials\SpecialPagesWithBadges
+ *
+ * @group WikibaseClient
+ * @group SpecialPage
+ * @group WikibaseSpecialPage
+ * @group Wikibase
+ * @group Database
+ *
+ * @licence GNU GPL v2+
+ * @author Bene* < [email protected] >
+ */
+class SpecialPagesWithBadgesTest extends SpecialPageTestBase {
+
+       /**
+        * @return LabelDescriptionLookup
+        */
+       private function getLabelLookup() {
+               $labelLookup = $this->getMock( 
'Wikibase\DataModel\Services\Lookup\LabelDescriptionLookup' );
+               $labelLookup->expects( $this->any() )
+                       ->method( 'getLabel' )
+                       ->will( $this->returnCallback( function( ItemId $itemId 
) {
+                               return new Term( 'en', 'Label of ' . 
$itemId->getSerialization() );
+                       } ) );
+
+               return $labelLookup;
+       }
+
+       /**
+        * @return LanguageFallbackLabelDescriptionLookupFactory
+        */
+       private function getLabelDescriptionLookupFactory() {
+               $itemIds = array(
+                       new ItemId( 'Q123' ),
+                       new ItemId( 'Q456' )
+               );
+
+               $labelDescriptionLookupFactory = $this->getMockBuilder( 
'\Wikibase\Lib\Store\LanguageFallbackLabelDescriptionLookupFactory' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $labelDescriptionLookupFactory->expects( $this->once() )
+                       ->method( 'newLabelDescriptionLookup' )
+                       ->with( $this->anything(), $this->equalTo( $itemIds ) )
+                       ->will( $this->returnValue( $this->getLabelLookup() ) );
+
+               return $labelDescriptionLookupFactory;
+       }
+
+       protected function newSpecialPage() {
+               $specialPage = new SpecialPagesWithBadges();
+               $specialPage->initServices( 
$this->getLabelDescriptionLookupFactory(), array( 'Q123', 'Q456' ), 'enwiki' );
+
+               return $specialPage;
+       }
+
+       public function testExecuteWithoutAnyParams() {
+               list( $result, ) = $this->executeSpecialPage( '' );
+
+               $this->assertContains( '<select name="badge"', $result );
+               $this->assertContains( '<option value="Q123"', $result );
+               $this->assertContains( '<option value="Q456"', $result );
+
+               $this->assertContains( 'Label of Q123', $result );
+               $this->assertContains( 'Label of Q456', $result );
+       }
+
+       public function testExecuteWithValidParam() {
+               list( $result, ) = $this->executeSpecialPage( 'Q456' );
+
+               $this->assertContains( '<option value="Q456" selected=""', 
$result );
+       }
+
+       public function testExecuteWithInvalidParam() {
+               list( $result, ) = $this->executeSpecialPage( 'FooBar' );
+
+               $this->assertContains( '<p class="error"', $result );
+               $this->assertContains( 'FooBar is not a valid item id', $result 
);
+       }
+
+}
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index a844700..cfc6e7b 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -192,7 +192,7 @@
        /**
         * @var TermLookup|null
         */
-       private $termLookup;
+       private $termLookup = null;
 
        /**
         * @var ContentLanguages|null
@@ -661,7 +661,7 @@
         * @return TermBuffer
         */
        public function getTermBuffer() {
-               return $this->getTermLookup();
+               return $this->getBufferingTermLookup();
        }
 
        /**

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I690b94af0ac11163c80e4422e6d72dacce447959
Gerrit-PatchSet: 8
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Bene <[email protected]>
Gerrit-Reviewer: Addshore <[email protected]>
Gerrit-Reviewer: Bene <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to