John Erling Blad has uploaded a new change for review. https://gerrit.wikimedia.org/r/53381
Change subject: (Bug 43994) New Special:UnconnectedPages ...................................................................... (Bug 43994) New Special:UnconnectedPages This special page "Special:UnconnectedPages" uses a page prop "wikibase_item" that holds the id for the item at the repository. Later it could be other tables that are better suited, and updated faster, than the page_props table. Change-Id: I5cfab43ee8c7feff79c8b4bda0183142dc3e2c98 --- A client/WikibaseClient.i18n.alias.php M client/WikibaseClient.i18n.php M client/WikibaseClient.php A client/includes/specials/SpecialUnconnectedPages.php 4 files changed, 312 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase refs/changes/81/53381/1 diff --git a/client/WikibaseClient.i18n.alias.php b/client/WikibaseClient.i18n.alias.php new file mode 100644 index 0000000..61ad70d --- /dev/null +++ b/client/WikibaseClient.i18n.alias.php @@ -0,0 +1,20 @@ +<?php + +/** + * Aliases for the special pages of the Wikibase extension. + * + * @since 0.1 + * + * @file + * @ingroup WikibaseRepo + * + * @licence GNU GPL v2+ + * @author John Erling Blad < jeb...@gmail.com > + */ + +$specialPageAliases = array(); + +/** English (English) */ +$specialPageAliases['en'] = array( + 'UnconnectedPages' => array( 'UnconnectedPages', 'WithoutConnection', 'WithoutSitelinks' ), +); \ No newline at end of file diff --git a/client/WikibaseClient.i18n.php b/client/WikibaseClient.i18n.php index 606d3b4..669f3d0 100644 --- a/client/WikibaseClient.i18n.php +++ b/client/WikibaseClient.i18n.php @@ -18,9 +18,11 @@ * @author Jeroen De Dauw * @author Nikola Smolenski * @author Marius Hoch + * @author Jeblad */ $messages['en'] = array( 'wikibase-client-desc' => 'Client for the Wikibase extension', + 'specialpages-group-wikibaseclient' => 'Wikidata client', 'wikibase-after-page-move' => 'You may also [$1 update] the associated Wikidata item to maintain language links on moved page.', 'wikibase-comment-remove' => 'Associated Wikidata item deleted. Language links removed.', 'wikibase-comment-linked' => 'A Wikidata item has been linked to this page.', @@ -52,6 +54,14 @@ 'wikibase-rc-hide-wikidata' => '$1 Wikidata', 'wikibase-rc-show-wikidata-pref' => 'Show Wikidata edits in recent changes', 'wikibase-watchlist-show-changes-pref' => 'Show Wikidata edits in your watchlist', + 'special-unconnectedpages' => 'Pages not connected to items', + 'wikibase-unconnectedpages-legend' => 'Unconnected pages options', + 'wikibase-unconnectedpages-page' => 'Start 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 interlanguagelinks', + 'wikibase-unconnectedpages-format-row' => '($1 interlanguagelinks on the page)', ); /** Message documentation (Message documentation) @@ -66,6 +76,7 @@ $messages['qqq'] = array( 'wikibase-client-desc' => '{{desc|name=Wikibase Client|url=http://www.mediawiki.org/wiki/Extension:Wikibase_Client}} See also [[d:Wikidata:Glossary#Wikidata|Wikidata]].', + 'specialpages-group-wikibaseclient' => 'Title of group of special pages related to Wikidata clients', 'wikibase-after-page-move' => 'Message on [[Special:MovePage]] on submit and successfully move, inviting user to update associated Wikibase repository item to maintain language links on the moved page on the client. Parameters: @@ -130,6 +141,14 @@ * $1 - a link with the text {{msg-mw|show}} or {{msg-mw|hide}}', 'wikibase-rc-show-wikidata-pref' => 'Option in the recent changes section of preferences to show wikibase changes by default in recent changes.', 'wikibase-watchlist-show-changes-pref' => 'Option in the watchlist section of preferences to always show wikibase edits by default in the watchlist.', + 'special-unconnectedpages' => 'Title of the special page for listing unconnected items.', + 'wikibase-unconnectedpages-page-warning' => 'The title that is typed in could not be used of some kind of reason. This can happen for example when the title has an interwiki prefix to another language, or a namespace that is not used for Wikibase entities.', + 'wikibase-unconnectedpages-iwdata-label' => 'Text for the checkbox. Should say that only pages without interlanguage-links should be listed.', + 'wikibase-unconnectedpages-legend' => 'Legend for the options box at the special page for pages not connected to sitelinks.', + 'wikibase-unconnectedpages-page' => 'Label for the start page field in the options box of the special page for pages not connected to sitelinks.', + 'wikibase-unconnectedpages-submit' => 'Text for the submit button in the options box of the special page for pages not connected to sitelinks.', + 'wikibase-unconnectedpages-invalid-language' => 'Warning message about invalid language used at the special page for pages not connected to sitelinks.', + 'wikibase-unconnectedpages-format-row' => 'Formating of the additional data for each row in the result set on the special page for pages not connected to sitelinks.', ); /** Afrikaans (Afrikaans) diff --git a/client/WikibaseClient.php b/client/WikibaseClient.php index 671d677..1b6d9a4 100644 --- a/client/WikibaseClient.php +++ b/client/WikibaseClient.php @@ -53,6 +53,7 @@ // i18n $wgExtensionMessagesFiles['wikibaseclient'] = $dir . 'WikibaseClient.i18n.php'; +$wgExtensionMessagesFiles['Wikibaseclientalias'] = $dir . 'WikibaseClient.i18n.alias.php'; $wgExtensionMessagesFiles['wikibaseclientmagic'] = $dir . 'WikibaseClient.i18n.magic.php'; // Autoloading @@ -80,6 +81,9 @@ $wgAutoloadClasses['Wikibase\ExternalChangesLine'] = $dir . 'includes/recentchanges/ExternalChangesLine.php'; $wgAutoloadClasses['Wikibase\ExternalRecentChange'] = $dir . 'includes/recentchanges/ExternalRecentChange.php'; $wgAutoloadClasses['Wikibase\RecentChangesFilterOptions'] = $dir . 'includes/recentchanges/RecentChangesFilterOptions.php'; + +// includes/specials +$wgAutoloadClasses['SpecialUnconnectedPages'] = $dir . 'includes/specials/SpecialUnconnectedPages.php'; // includes/store $wgAutoloadClasses['Wikibase\ClientStore'] = $dir . 'includes/store/ClientStore.php'; @@ -120,6 +124,12 @@ // api modules $wgAPIMetaModules['wikibase'] = 'Wikibase\ApiClientInfo'; +// Special page registration +$wgSpecialPages['UnconnectedPages'] = 'SpecialUnconnectedPages'; + +// Special page groups +$wgSpecialPageGroups['UnconnectedPages'] = 'wikibaseclient'; + // Resource loader modules $wgResourceModules = array_merge( $wgResourceModules, include( "$dir/resources/Resources.php" ) ); diff --git a/client/includes/specials/SpecialUnconnectedPages.php b/client/includes/specials/SpecialUnconnectedPages.php new file mode 100644 index 0000000..d963ee8 --- /dev/null +++ b/client/includes/specials/SpecialUnconnectedPages.php @@ -0,0 +1,263 @@ +<?php + +/** + * List client pages that is not connected to repository items. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @since 0.4 + * + * @file + * @ingroup WikibaseClient + * + * @licence GNU GPL v2+ + * @author John Erling Blad < jeb...@gmail.com > + */ +class SpecialUnconnectedPages extends SpecialWikibaseQueryPage { + + /** + * The title as a string to start search at + * + * @since 0.4 + * + * @var string + */ + protected $startPage = ''; + + /** + * The startPage as a title to start search at + * + * @since 0.4 + * + * @var Title + */ + protected $startTitle = null; + + /** + * The namespace to filter + * + * @since 0.4 + * + * @var string + */ + protected $namespace = null; + + /** + * If the search should only include pages with iw-links + * + * @since 0.4 + * + * @var string + */ + protected $iwData = ''; + + public function __construct() { + parent::__construct( 'UnconnectedPages' ); + + } + + /** + * @see SpecialWikibasePage::execute + * + * @since 0.2 + * + * @param string $subPage + * @return boolean + */ + public function execute( $subPage ) { + if ( !parent::execute( $subPage ) ) { + return false; + } + + # 10 seconds server-side caching max + $this->getOutput()->setSquidMaxage( 10 ); + + $output = $this->getOutput(); + $request = $this->getRequest(); + + $namespaces = \Wikibase\Settings::get( 'namespaces' ); + + $this->startPage = $request->getText( 'page', $subPage ); + if ( $this->startPage !== '' ) { + $title = \Title::newFromText( $this->startPage ); + if ( $title !== null && in_array( $title->getNamespace(), $namespaces ) ) { + $this->startTitle = $title; + } + } + + $this->iwData = $request->getText( 'iwdata', '' ); + + $out = ''; + + if ( $this->startPage !== '' && $this->startTitle === null ) { + $out .= Html::element( 'div', array(), $this->msg( 'wikibase-unconnectedpages-page-warning' )->text() ); + } + + $out .= Html::openElement( + 'form', + array( + 'action' => $this->getTitle()->getLocalURL(), + 'name' => 'unconnectedpages', + 'id' => 'wbc-unconnectedpages-form' + ) + ) + . Html::openElement( 'fieldset' ) + . Html::element( 'legend', array(), $this->msg( 'wikibase-unconnectedpages-legend' )->text() ) + . Html::openElement( 'p' ) + . Html::element( 'label', array( 'for' => 'language' ), $this->msg( 'wikibase-unconnectedpages-page' )->text() ) + . ' ' + . Html::input( + 'page', + $this->startPage, + 'text', + array( + 'id' => 'page' + ) + ) + . Html::input( + 'submit', + $this->msg( 'wikibase-unconnectedpages-submit' )->text(), + 'submit', + array( + 'id' => 'wbc-unconnectedpages-submit', + 'class' => 'wbc-input-button' + ) + ) + . ' ' + . Html::input( + 'iwdata', + 'only', + 'checkbox', + array( + 'id' => 'wbc-unconnectedpages-iwdata', + 'class' => 'wbc-input-button', + $this->iwData === 'only' ? 'checked' : 'unchecked' => '' + ) + ) + . ' ' + . Html::element( 'label', array( 'for' => 'wbc-unconnectedpages-iwdata' ), $this->msg( 'wikibase-unconnectedpages-iwdata-label' )->text() ) + . Html::closeElement( 'p' ) + . Html::closeElement( 'fieldset' ) + . Html::closeElement( 'form' ); + $output->addHTML( $out ); + + $this->showQuery(); + } + + /** + * @see SpecialWikibaseQueryPage::getResult + * + * @since 0.4 + * + * @param integer $offset + * @param integer $limit + * + * @return EntityId[] + * TODO: it's a bit odd that this returns an array of EntityId + */ + protected function getResult( $offset = 0, $limit = 0 ) { + + $dbr = wfGetDB( DB_SLAVE ); + $conds = array(); + + $namespaces = \Wikibase\Settings::get( 'namespaces' ); + if ( $this->startTitle !== null ) { + $conds[] = 'page_title >= ' . $dbr->addQuotes( $this->startTitle->getText() ); + if ( isset( $namespaces[$this->startTitle->getNamespace()] ) ) { + $conds[] = 'page_namespace = ' . $this->startTitle->getNamespace(); + } + } + if ( $this->iwData === 'only' ) { + $conds[] = 'll_from IS NOT NULL'; + } + + $rows = $dbr->select( + array( + 'page', + 'page_props', + 'langlinks' + ), + array( + 'page_namespace', + 'page_title', + 'page_id', + 'page_len', + 'page_is_redirect', + 'page_num_iwlinks' => 'count(ll_from)' + ), + array_merge( + array( + "NOT ( pp_propname <=> 'wikibase_item' )" + ), + $conds + ), + __METHOD__, + array( + 'OFFSET' => $offset, + 'LIMIT' => $limit, + 'GROUP BY' => 'page_id', + 'ORDER BY' => 'page_title ASC', + 'USE INDEX' => array( 'page_props' => 'pp_propname' ) + ), + array( + 'page' => array( 'RIGHT JOIN', 'page_id = pp_page' ), + 'langlinks' => array( 'LEFT JOIN', 'page_id = ll_from' ) + ) + ); + + $entries = array(); + foreach ( $rows as $row ) { + $title = \Title::newFromRow( $row ); + $numIWLinks = $row->page_num_iwlinks; + $entries[] = array( 'title' => $title, 'num' => $numIWLinks); + } + return $entries; + } + + /** + * @see SpecialWikibaseQueryPage::formatRow + * + * @since 0.4 + * + * @param $entry The entry is for this call a row from the select in getResult + * + * @return string|null + */ + protected function formatRow( $entry ) { + try { + $out = Linker::linkKnown( $entry['title'] ); + if ( $entry['num'] > 0 ) { + $out .= ' ' . $this->msg( 'wikibase-unconnectedpages-format-row', $entry['num'] )->text(); + } + return $out; + } catch ( MWException $e ) { + wfWarn( "Error formatting result row: " . $e->getMessage() ); + return false; + } + } + + /** + * @see SpecialWikibaseQueryPage::getTitleForNavigation + * + * @since 0.4 + * + * @return Title + */ + protected function getTitleForNavigation() { + return $this->getTitle( $this->startPage ); + } + +} \ No newline at end of file -- To view, visit https://gerrit.wikimedia.org/r/53381 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5cfab43ee8c7feff79c8b4bda0183142dc3e2c98 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: John Erling Blad <john.b...@wikimedia.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits