* Introduce ImageQueryPage class which uses galleries instead of boring old lists
* (bug 9069) Use galleries in query pages dedicated to images [uncategorised images, most linked-to images and unused files at the moment]
* (bug 9397) Introduce "sp-contributions-footer" and "sp-contributions-footer-anon"
messages, shown at the end of Special:Contributions as appropriate for the target
* (bug 8421) Expose current action in JavaScript globals (as 'wgAction')
+* (bug 9069) Use galleries in query pages dedicated to images
== Bugfixes since 1.9 ==
* (bug 7292) Fix site statistics when moving pages in/out of content namespaces
'ProtectionForm' => 'includes/ProtectionForm.php',
'QueryPage' => 'includes/QueryPage.php',
'PageQueryPage' => 'includes/QueryPage.php',
+ 'ImageQueryPage' => 'includes/ImageQueryPage.php',
'RawPage' => 'includes/RawPage.php',
'RecentChange' => 'includes/RecentChange.php',
'Revision' => 'includes/Revision.php',
--- /dev/null
+<?php
+
+/**
+ * Variant of QueryPage which uses a gallery to output results, thus
+ * suited for reports generating images
+ *
+ * @package MediaWiki
+ * @author Rob Church <robchur@gmail.com>
+ */
+class ImageQueryPage extends QueryPage {
+
+ /**
+ * Format and output report results using the given information plus
+ * OutputPage
+ *
+ * @param OutputPage $out OutputPage to print to
+ * @param Skin $skin User skin to use
+ * @param Database $dbr Database (read) connection to use
+ * @param int $res Result pointer
+ * @param int $num Number of available result rows
+ * @param int $offset Paging offset
+ */
+ protected function outputResults( $out, $skin, $dbr, $res, $num, $offset ) {
+ if( $num > 0 ) {
+ $gallery = new ImageGallery();
+ $gallery->useSkin( $skin );
+
+ # $res might contain the whole 1,000 rows, so we read up to
+ # $num [should update this to use a Pager]
+ for( $i = 0; $i < $num && $row = $dbr->fetchObject( $res ); $i++ ) {
+ $image = $this->prepareImage( $row );
+ if( $image instanceof Image )
+ $gallery->add( $image, $this->getCellHtml( $row ) );
+ }
+
+ $out->addHtml( $gallery->toHtml() );
+ }
+ }
+
+ /**
+ * Prepare an image object given a result row
+ *
+ * @param object $row Result row
+ * @return Image
+ */
+ private function prepareImage( $row ) {
+ $namespace = isset( $row->namespace ) ? $row->namespace : NS_IMAGE;
+ $title = Title::makeTitleSafe( $namespace, $row->title );
+ return ( $title instanceof Title && $title->getNamespace() == NS_IMAGE )
+ ? new Image( $title )
+ : null;
+ }
+
+ /**
+ * Get additional HTML to be shown in a results' cell
+ *
+ * @param object $row Result row
+ * @return string
+ */
+ protected function getCellHtml( $row ) {
+ return '';
+ }
+
+}
+
+?>
\ No newline at end of file
$num = $dbr->numRows($res);
$this->preprocessResults( $dbr, $res );
-
- $sk = $wgUser->getSkin( );
-
- if($shownavigation) {
- $wgOut->addHTML( $this->getPageHeader() );
-
- # if list is empty, show it
- if( $num == 0 ) {
- $wgOut->addHTML( '<p>' . wfMsgHTML('specialpage-empty') . '</p>' );
+ $sk = $wgUser->getSkin();
+
+ # Top header and navigation
+ if( $shownavigation ) {
+ $wgOut->addHtml( $this->getPageHeader() );
+ if( $num > 0 ) {
+ $wgOut->addHtml( '<p>' . wfShowingResults( $offset, $num ) . '</p>' );
+ # Disable the "next" link when we reach the end
+ $paging = wfViewPrevNext( $offset, $limit, $wgContLang->specialPage( $sname ),
+ wfArrayToCGI( $this->linkParameters() ), ( $num < $limit ) );
+ $wgOut->addHtml( '<p>' . $paging . '</p>' );
+ } else {
+ # No results to show, so don't bother with "showing X of Y" etc.
+ # -- just let the user know and give up now
+ $wgOut->addHtml( '<p>' . wfMsgHtml( 'specialpage-empty' ) . '</p>' );
return;
}
-
- $top = wfShowingResults( $offset, $num);
- $wgOut->addHTML( "<p>{$top}\n" );
-
- # often disable 'next' link when we reach the end
- $atend = $num < $limit;
-
- $sl = wfViewPrevNext( $offset, $limit ,
- $wgContLang->specialPage( $sname ),
- wfArrayToCGI( $this->linkParameters() ), $atend );
- $wgOut->addHTML( "<br />{$sl}</p>\n" );
}
- if ( $num > 0 ) {
- $s = array();
- if ( ! $this->listoutput )
- $s[] = $this->openList( $offset );
-
- # Only read at most $num rows, because $res may contain the whole 1000
- for ( $i = 0; $i < $num && $obj = $dbr->fetchObject( $res ); $i++ ) {
- $format = $this->formatResult( $sk, $obj );
- if ( $format ) {
- $attr = ( isset ( $obj->usepatrol ) && $obj->usepatrol &&
- $obj->patrolled == 0 ) ? ' class="not-patrolled"' : '';
- $s[] = $this->listoutput ? $format : "<li{$attr}>{$format}</li>\n";
+
+ # The actual results; specialist subclasses will want to handle this
+ # with more than a straight list, so we hand them the info, plus
+ # an OutputPage, and let them get on with it
+ $this->outputResults( $wgOut,
+ $wgUser->getSkin(),
+ $dbr, # Should use a ResultWrapper for this
+ $res,
+ $dbr->numRows( $res ),
+ $offset );
+
+ # Repeat the paging links at the bottom
+ if( $shownavigation ) {
+ $wgOut->addHtml( '<p>' . $paging . '</p>' );
+ }
+
+ return $num;
+ }
+
+ /**
+ * Format and output report results using the given information plus
+ * OutputPage
+ *
+ * @param OutputPage $out OutputPage to print to
+ * @param Skin $skin User skin to use
+ * @param Database $dbr Database (read) connection to use
+ * @param int $res Result pointer
+ * @param int $num Number of available result rows
+ * @param int $offset Paging offset
+ */
+ protected function outputResults( $out, $skin, $dbr, $res, $num, $offset ) {
+ global $wgContLang;
+
+ if( $num > 0 ) {
+ $html = array();
+ if( !$this->listoutput )
+ $html[] = $this->openList( $offset );
+
+ # $res might contain the whole 1,000 rows, so we read up to
+ # $num [should update this to use a Pager]
+ for( $i = 0; $i < $num && $row = $dbr->fetchObject( $res ); $i++ ) {
+ $line = $this->formatResult( $skin, $row );
+ if( $line ) {
+ $attr = ( isset( $obj->usepatrol ) && $obj->usepatrol && $obj->patrolled == 0 )
+ ? ' class="not-patrolled"'
+ : '';
+ $html[] = $this->listoutput
+ ? $format
+ : "<li{$attr}>{$line}</li>\n";
}
}
-
- if($this->tryLastResult()) {
- // flush the very last result
- $obj = null;
- $format = $this->formatResult( $sk, $obj );
- if( $format ) {
- $attr = ( isset ( $obj->usepatrol ) && $obj->usepatrol &&
- $obj->patrolled == 0 ) ? ' class="not-patrolled"' : '';
- $s[] = "<li{$attr}>{$format}</li>\n";
+
+ # Flush the final result
+ if( $this->tryLastResult() ) {
+ $row = null;
+ $line = $this->formatResult( $skin, $row );
+ if( $line ) {
+ $attr = ( isset( $obj->usepatrol ) && $obj->usepatrol && $obj->patrolled == 0 )
+ ? ' class="not-patrolled"'
+ : '';
+ $html[] = $this->listoutput
+ ? $format
+ : "<li{$attr}>{$line}</li>\n";
}
}
-
- $dbr->freeResult( $res );
- if ( ! $this->listoutput )
- $s[] = $this->closeList();
- $str = $this->listoutput ? $wgContLang->listToText( $s ) : implode( '', $s );
- $wgOut->addHTML( $str );
+
+ if( !$this->listoutput )
+ $html[] = $this->closeList();
+
+ $html = $this->listoutput
+ ? $wgContLang->listToText( $html )
+ : implode( '', $html );
+
+ $out->addHtml( $html );
}
- if($shownavigation) {
- $wgOut->addHTML( "<p>{$sl}</p>\n" );
- }
- return $num;
}
function openList( $offset ) {
/**
* @addtogroup SpecialPage
*/
-class MostimagesPage extends QueryPage {
+class MostimagesPage extends ImageQueryPage {
function getName() { return 'Mostimages'; }
function isExpensive() { return true; }
";
}
- function formatResult( $skin, $result ) {
- global $wgLang, $wgContLang;
-
- $nt = Title::makeTitle( $result->namespace, $result->title );
- $text = $wgContLang->convert( $nt->getPrefixedText() );
-
- $plink = $skin->makeKnownLink( $nt->getPrefixedText(), $text );
-
- $nl = wfMsgExt( 'nlinks', array( 'parsemag', 'escape'),
- $wgLang->formatNum ( $result->value ) );
- $nlink = $skin->makeKnownLink( $nt->getPrefixedText() . '#filelinks', $nl );
-
- return wfSpecialList($plink, $nlink);
+ function getCellHtml( $row ) {
+ global $wgLang;
+ return wfMsgExt( 'nlinks', array( 'parsemag', 'escape' ),
+ $wgLang->formatNum( $row->value ) ) . '<br />';
}
+
}
/**
* @author Rob Church <robchur@gmail.com>
*/
-class UncategorizedImagesPage extends QueryPage {
+class UncategorizedImagesPage extends ImageQueryPage {
function getName() {
return 'Uncategorizedimages';
WHERE cl_from IS NULL AND page_namespace = {$ns} AND page_is_redirect = 0";
}
- function formatResult( $skin, $row ) {
- global $wgContLang;
- $title = Title::makeTitleSafe( NS_IMAGE, $row->title );
- $label = htmlspecialchars( $wgContLang->convert( $title->getText() ) );
- return $skin->makeKnownLinkObj( $title, $label );
- }
}
function wfSpecialUncategorizedimages() {
/**
* @addtogroup SpecialPage
*/
-class UnusedimagesPage extends QueryPage {
+class UnusedimagesPage extends ImageQueryPage {
function getName() {
return 'Unusedimages';
}
}
- function formatResult( $skin, $result ) {
- global $wgLang, $wgContLang;
- $title = Title::makeTitle( NS_IMAGE, $result->title );
-
- $imageUrl = htmlspecialchars( Image::imageUrl( $result->title ) );
- $dirmark = $wgContLang->getDirMark(); // To keep text in correct order
-
- $return =
- # The 'desc' linking to the image page
- '('.$skin->makeKnownLinkObj( $title, wfMsg('imgdesc') ).') ' . $dirmark .
-
- # Link to the image itself
- '<a href="' . $imageUrl . '">' . htmlspecialchars( $title->getText() ) .
- '</a> . . ' . $dirmark .
-
- # Last modified date
- $wgLang->timeanddate($result->value) . ' . . ' . $dirmark .
-
- # Link to username
- $skin->makeLinkObj( Title::makeTitle( NS_USER, $result->img_user_text ),
- $result->img_user_text) . $dirmark .
-
- # If there is a description, show it
- $skin->commentBlock( $wgContLang->convert( $result->img_description ) );
-
- return $return;
- }
-
function getPageHeader() {
return wfMsg( "unusedimagestext" );
}