Samwilson has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/324657

Change subject: Add new special page for searching assessments
......................................................................

Add new special page for searching assessments

This adds Special:PageAssessments with a basic search form
and results table. The special page can also be transcluded,
in which case the search form isn't shown (all search and sort
parameters must be provided in the transclusion).

Bug: T120407
Change-Id: I6ee898059ffc62bb5f2788ad83a49b650cdb1335
---
M extension.json
M i18n/en.json
M i18n/qqq.json
A src/NamespaceSelect.php
A src/Pager.php
A src/SpecialPage.php
6 files changed, 304 insertions(+), 3 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/PageAssessments 
refs/changes/57/324657/1

diff --git a/extension.json b/extension.json
index 49a9529..bd8ccd7 100644
--- a/extension.json
+++ b/extension.json
@@ -19,7 +19,10 @@
                "PageAssessmentsHooks": "PageAssessments.hooks.php",
                "PageAssessmentsBody": "PageAssessmentsBody.php",
                "ApiQueryPageAssessments": "api/ApiQueryPageAssessments.php",
-               "ApiQueryProjectPages": "api/ApiQueryProjectPages.php"
+               "ApiQueryProjectPages": "api/ApiQueryProjectPages.php",
+               "PageAssessments\\SpecialPage": "src/SpecialPage.php",
+               "PageAssessments\\Pager": "src/Pager.php",
+               "PageAssessments\\NamespaceSelect": "src/NamespaceSelect.php"
        },
        "ExtensionMessagesFiles": {
                "PageAssessmentsMagic": "PageAssessments.i18n.magic.php"
@@ -47,6 +50,9 @@
                "localBasePath": "",
                "remoteExtPath": "examples/PageAssessments"
        },
+       "SpecialPages": {
+               "PageAssessments": "PageAssessments\\SpecialPage"
+       },
        "config": {
                "PageAssessmentsOnTalkPages": true
        },
diff --git a/i18n/en.json b/i18n/en.json
index f5a0313..2125fc9 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -16,5 +16,13 @@
        "apihelp-query+projectpages-param-limit": "The maximum number of pages 
to return.",
        "apihelp-query+projectpages-example-simple-1": "Get first 10 pages 
associated with any WikiProject.",
        "apihelp-query+projectpages-example-simple-2": "Get first 10 pages 
associated with WikiProject <kbd>Medicine</kbd>, including assessment data.",
-       "apihelp-query+projectpages-example-generator": "Get page info for 
first 10 pages associated with WikiProject <kbd>Textile Arts</kbd>."
+       "apihelp-query+projectpages-example-generator": "Get page info for 
first 10 pages associated with WikiProject <kbd>Textile Arts</kbd>.",
+       "pageassessments-special": "Page assessments",
+       "pageassessments-project": "Project",
+       "pageassessments-page-namespace": "Page namespace",
+       "pageassessments-page-title": "Page title",
+       "pageassessments-search": "Search",
+       "pageassessments-importance": "Importance",
+       "pageassessments-class": "Class",
+       "pageassessments-timestamp": "Timestamp"
 }
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 6caf8ec..def5a22 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -16,5 +16,14 @@
        "apihelp-query+projectpages-param-limit": 
"{{doc-apihelp-param|query+projectpages|limit}}",
        "apihelp-query+projectpages-example-simple-1": 
"{{doc-apihelp-example|query+projectpages}}",
        "apihelp-query+projectpages-example-simple-2": 
"{{doc-apihelp-example|query+projectpages}}",
-       "apihelp-query+projectpages-example-generator": 
"{{doc-apihelp-example|query+projectpages}}"
+       "apihelp-query+projectpages-example-generator": 
"{{doc-apihelp-example|query+projectpages}}",
+       "pageassessments-special": "Name of the Special page",
+       "pageassessments-project": "Form label for the WikiProject search field 
and the results table column header",
+       "pageassessments-page-namespace": "Form label for the page namespace 
dropdown select field",
+       "pageassessments-page-title": "Form label for the page title search 
field and the results table column header",
+       "pageassessments-search": "Search form submit button label",
+       "pageassessments-importance": "Label for the search form and the 
results table column header",
+       "pageassessments-class": "Label for the search form and the results 
table column header",
+       "pageassessments-timestamp": "Label for the search form and the results 
table column header"
+
 }
diff --git a/src/NamespaceSelect.php b/src/NamespaceSelect.php
new file mode 100644
index 0000000..49a09b4
--- /dev/null
+++ b/src/NamespaceSelect.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace PageAssessments;
+
+use HTMLSelectNamespace;
+use MediaWiki\Widget\NamespaceInputWidget;
+use MWNamespace;
+
+/**
+ * This is an HTML form field for selecting non-talk namespaces. It excludes 
all namespaces with
+ * an even-numbered ID.
+ *
+ * It only overrides the OOUI widget because that's all that the 
PageAssessments special page needs.
+ */
+class NamespaceSelect extends HTMLSelectNamespace {
+
+       /**
+        * Get the widget for selecting one or all non-talkspace namespace(s).
+        * @param string $value The currently selected value.
+        * @return NamespaceInputWidget
+        */
+       public function getInputOOUI( $value ) {
+               $nsIds = array_keys( MWNamespace::getCanonicalNamespaces() );
+               $excludedNsIds = array_filter( $nsIds, function( $ns ) {
+                       return MWNamespace::isTalk( $ns );
+               } );
+               $widget = new NamespaceInputWidget( [
+                       'value' => $value,
+                       'name' => $this->mName,
+                       'id' => $this->mID,
+                       'includeAllValue' => $this->mAllValue,
+                       'exclude' => $excludedNsIds,
+               ] );
+               return $widget;
+       }
+
+}
diff --git a/src/Pager.php b/src/Pager.php
new file mode 100644
index 0000000..30e34a6
--- /dev/null
+++ b/src/Pager.php
@@ -0,0 +1,149 @@
+<?php
+namespace PageAssessments;
+
+use LikeMatch;
+use MediaWiki\MediaWikiServices;
+use TablePager;
+use Title;
+
+class Pager extends TablePager {
+
+       /** @var boolean Should field sorting be enabled? */
+       protected $sortable;
+
+       /**
+        * All parameters for the main paged query.
+        * @return string[]
+        */
+       public function getQueryInfo() {
+               $info = [
+                       'tables' => [ 'page_assessments', 
'page_assessments_projects', 'page', 'revision' ],
+                       'fields' => [
+                               'project' => 'pap_project_title',
+                               'page' => 'pa_class',
+                               'importance' => 'pa_importance',
+                               'timestamp' => 'rev_timestamp',
+                               'page_title' => 'page_title',
+                               'page_revision' => 'pa_page_revision',
+                               'page_namespace' => 'page_namespace',
+                       ],
+                       'conds' => [],
+                       'options' => [],
+                       'join_conds' => [
+                               'page_assessments_projects' => [ 'JOIN', 
'pa_project_id = pap_project_id' ],
+                               'page' => [ 'JOIN', 'pa_page_id = page_id' ],
+                               'revision' => [ 'JOIN', 'page_id = rev_page AND 
pa_page_revision = rev_id' ],
+                       ],
+               ];
+               // Project.
+               $project = $this->getRequest()->getVal( 'project', false );
+               if ( !empty( $project ) ) {
+                       $info['conds']['pap_project_title'] = $project;
+               }
+               // Namespace (if its set, it's either an integer >= 0, 'all', 
or the empty string).
+               $namespace = $this->getRequest()->getVal( 'namespace', false );
+               if ( $namespace !== 'all' && $namespace !== '' ) {
+                       $info['conds']['page_namespace'] = $namespace;
+               }
+               $pageTitle = $this->getRequest()->getVal( 'page_title', false );
+               if ( !empty( $pageTitle ) ) {
+                       $title = Title::newFromText( $pageTitle )->getDBkey();
+                       $db = $this->getDatabase();
+                       $info['conds'][] = 'page_title'.$db->buildLike( new 
LikeMatch( $title ) );
+               }
+               return $info;
+       }
+
+       /**
+        * Should the table be sortable? It's not when transcluded.
+        * @param boolean $sortable Whether to sort or not.
+        */
+       public function setSortable( $sortable ) {
+               $this->sortable = (bool)$sortable;
+       }
+
+       /**
+        * Return true if the named field should be sortable by the UI, false 
otherwise.
+        * @param string $field The field in question; matches one returned by 
self::getFieldNames().
+        * @return boolean
+        */
+       public function isFieldSortable( $field ) {
+               // Done enable sorting for transcluded pagers, because the 
sorting links will not be to
+               // the current page.
+               if ( $this->sortable === false ) {
+                       // Strict check, to avoid false negative when this 
method is used in parent::__construct
+                       return false;
+               }
+               $sortable = [
+                       'project',
+                       'page',
+                       'timestamp',
+               ];
+               return in_array( $field, $sortable );
+       }
+
+       /**
+        * Format a table cell. The return value should be HTML, but use an 
empty
+        * string not &#160; for empty cells. Do not include the <td> and </td>.
+        *
+        * The current result row is available as $this->mCurrentRow, in case 
you
+        * need more context.
+        *
+        * @param string $name The database field name
+        * @param string $value The value retrieved from the database
+        * @return string
+        */
+       public function formatValue( $name, $value ) {
+               $renderer = MediaWikiServices::getInstance()->getLinkRenderer();
+               $pageTitle = Title::newFromText(
+                       $this->mCurrentRow->page_title,
+                       $this->mCurrentRow->page_namespace
+               );
+
+               // Page title.
+               if ( $name === 'page' ) {
+                       return $renderer->makeKnownLink( $pageTitle );
+               }
+
+               // Timestamp of assessed revision.
+               if ( $name === 'timestamp' ) {
+                       $lang = $this->getLanguage();
+                       $ts = $lang->userTimeAndDate( 
$this->mCurrentRow->timestamp, $this->getUser() );
+                       $linkQuery = [ 'oldid' => 
$this->mCurrentRow->page_revision ];
+                       return $renderer->makeKnownLink( $pageTitle, $ts, [], 
$linkQuery );
+               }
+
+               // All field names from self::getFieldNames() have been taken 
care of above,
+               // so this shouldn't be used.
+               return $value;
+       }
+
+       /**
+        * An array mapping database field names to a textual description of the
+        * field name, for use in the table header. The description should be 
plain
+        * text, it will be HTML-escaped later.
+        *
+        * @return array
+        */
+       public function getFieldNames() {
+               return [
+                       'project' => wfMessage( 'pageassessments-project' 
)->text(),
+                       'page' => wfMessage( 'pageassessments-page-title' 
)->text(),
+                       'importance' => wfMessage( 'pageassessments-importance' 
)->text(),
+                       'class' => wfMessage( 'pageassessments-class' )->text(),
+                       'timestamp' => wfMessage( 'pageassessments-timestamp' 
)->text(),
+               ];
+       }
+
+       /**
+        * The database field name used as a default sort order.
+        *
+        * @protected
+        *
+        * @return string
+        */
+       public function getDefaultSort() {
+               return 'project';
+       }
+
+}
diff --git a/src/SpecialPage.php b/src/SpecialPage.php
new file mode 100644
index 0000000..609a171
--- /dev/null
+++ b/src/SpecialPage.php
@@ -0,0 +1,92 @@
+<?php
+
+namespace PageAssessments;
+
+use HTMLForm;
+use HTMLTextField;
+use SpecialPage as MediaWikiSpecialPage;
+
+/**
+ *
+ */
+class SpecialPage extends MediaWikiSpecialPage {
+
+       /**
+        * Create this special page, giving it a name and making it 
transcludable.
+        */
+       public function __construct() {
+               parent::__construct();
+               $this->mName = 'PageAssessments';
+               $this->mIncludable = true;
+       }
+
+       /**
+        * Returns the name that goes in the \<h1\> in the special page itself, 
and
+        * also the name that will be listed in Special:Specialpages.
+        *
+        * Overridden here because we want proper sentence casing, rather than 
'PageAssessments'.
+        *
+        * @return string
+        */
+       function getDescription() {
+               return $this->msg( 'pageassessments-special' )->text();
+       }
+
+       /**
+        * Output the special page.
+        * @param string $parameters The parameters to the special page.
+        */
+       public function execute( $parameters ) {
+               // Set up.
+               $out = $this->getOutput();
+               $out->setPageTitle( $this->getDescription() );
+               $this->addHelpLink( 'Help:Extension:PageAssessments' );
+
+               // Output form.
+               if ( !$this->including() ) {
+                       $form = $this->getForm();
+                       $form->show();
+               }
+
+               // Output results (request also has 'title' when this special 
page is not transcluded).
+               $queryValues = $this->getRequest()->getQueryValues();
+               unset( $queryValues['title'] );
+               if ( count( $queryValues ) > 0 ) {
+                       $pager = new Pager();
+                       $pager->setSortable( !$this->including() );
+                       $out->addParserOutput( $pager->getFullOutput() );
+               }
+       }
+
+       /**
+        * Get the search form.
+        * @return HTMLForm
+        */
+       protected function getForm() {
+               $formDescriptor = [
+                       'project' => [
+                               'class' => HTMLTextField::class,
+                               'name' => 'project',
+                               'label-message' => 'pageassessments-project',
+                       ],
+                       'namespace' => [
+                               'class' => NamespaceSelect::class,
+                               'name' => 'namespace',
+                               'label-message' => 
'pageassessments-page-namespace',
+                       ],
+                       'page_title' => [
+                               'class' => HTMLTextField::class,
+                               'name' => 'page_title',
+                               'label-message' => 'pageassessments-page-title',
+                       ],
+               ];
+               $form = HTMLForm::factory( 'ooui', $formDescriptor, 
$this->getContext() );
+               $form->setMethod( 'get' );
+               $form->setSubmitTextMsg( 'pageassessments-search' );
+               $form->setSubmitCallback( function() {
+                       // No callback required, but HTMLForm says we have to 
set one.
+               } );
+               return $form;
+       }
+
+}

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6ee898059ffc62bb5f2788ad83a49b650cdb1335
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/PageAssessments
Gerrit-Branch: master
Gerrit-Owner: Samwilson <s...@samwilson.id.au>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to