From 3fb4e8c826d76ba0b9ce84b65c7c95bca91a7ba7 Mon Sep 17 00:00:00 2001 From: Magnus Manske Date: Mon, 9 Jan 2006 21:48:49 +0000 Subject: [PATCH] Major update! Adding SpecialFilelist.php to replace both SpecialNewimages.php and SpecialImagelist.php The latter ones have been bend to load SpecialFilelist with a parameter to simulate the respective behaviour. SpecialFilelist uses mostly code from SpecialNewimages, but also from SpecialImagelist. Internally, it uses a class to structure code and handle parameters better than its predecessors. If somethings breaks, Newimages and Imagelist can be restored by outcommenting the new part (everything before the OBSOLETE line) and removing the OLD_ from the function name. If Filelist turns out to work, please remove the obsolete parts in the other two files. --- includes/SpecialFilelist.php | 441 ++++++++++++++++++++++++++++++++++ includes/SpecialImagelist.php | 14 +- includes/SpecialNewimages.php | 13 +- includes/SpecialPage.php | 3 +- languages/Language.php | 3 + 5 files changed, 471 insertions(+), 3 deletions(-) create mode 100644 includes/SpecialFilelist.php diff --git a/includes/SpecialFilelist.php b/includes/SpecialFilelist.php new file mode 100644 index 0000000000..3483dbeb8a --- /dev/null +++ b/includes/SpecialFilelist.php @@ -0,0 +1,441 @@ + + * @copyright Copyright © 2006, Magnus Manske + * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later + */ + +require_once( 'ImageGallery.php' ); + +function wfSpecialFilelist ( $par, $specialPage , $force_gallery = true ) { + + class SpecialFilelist extends SpecialPage { + + var $dbr , $sk ; + + /** + * Constructor + */ + function SpecialFilelist() { + SpecialPage::SpecialPage( 'Filelist' ); + $this->includable( false ); + } + + /** + * Get the SQL to hide bot-users + @param hide Hide the bots? (boolean) + */ + function getHideBotSQL ( $hide ) { + if ( !$hide ) { + # Don't hide bots + return "" ; + } + + global $wgGroupPermissions ; + $botconds=array(); + foreach ($wgGroupPermissions as $groupname=>$perms) { + if(array_key_exists('bot',$perms) && $perms['bot']) { + $botconds[]="ug_group='$groupname'"; + } + } + $isbotmember=$this->dbr->makeList($botconds, LIST_OR); + + /** This join, in conjunction with WHERE ug_group + IS NULL, returns only those rows from IMAGE + where the uploading user is not a member of + a group which has the 'bot' permission set. + */ + $ug = $this->dbr->tableName('user_groups'); + $joinsql=" LEFT OUTER JOIN $ug ON img_user=ug_user AND (" + . $isbotmember.')'; + return $joinsql ; + } + + /** + * Returns the latest timestamp for an image in the image table + @param params Parameters, not changed by this function (passed as refrence for speedup) + */ + function getTimeStamp ( &$params ) { + $sql="SELECT img_timestamp from " . $params['imagetable']; + if($params['hidebots']) { + $sql .= $params['botsql'].' WHERE ug_group IS NULL'; + } + if ( isset ( $params['user'] ) ) { + $sql .= " AND img_user='" . $params['user']->getID() . "'" ; + } + $sql .= ' ORDER BY img_timestamp' ; + $sql .= ' DESC' ; + $sql .= ' LIMIT 1'; + $res = $this->dbr->query($sql, 'SpecialFilelist::getTimeStamp'); + $row = $this->dbr->fetchRow($res); + if($row!==false) { + $ts=$row[0]; + } else { + $ts=false; + } + $this->dbr->freeResult($res); + + /** If we were clever, we'd use this to cache. */ + $latestTimestamp = wfTimestamp( TS_MW, $ts); + return $latestTimestamp ; + } + + /** + * Returns an array of images from the database + @param params Parameters, not changed by this function (passed as refrence for speedup) + */ + function getImages ( &$params ) { + $where = array(); + $searchpar = ''; + if ( $params['match'] != '' ) { + $nt = Title::newFromUrl( $params['match'] ); + if($nt ) { + $m = $this->dbr->strencode( strtolower( $nt->getDBkey() ) ); + $m = str_replace( '%', "\\%", $m ); + $m = str_replace( '_', "\\_", $m ); + $where[] = "LCASE(img_name) LIKE '%{$m}%'"; + $searchpar = '&wpIlMatch=' . ( $params['match'] ); + } + } + + if( $params['until'] != "" ) { + $where[] = 'img_timestamp >= ' . $this->dbr->timestamp( $params['until'] ); + } else if ( $params['date'] != "" ) { + $where[] = 'img_timestamp < ' . $this->dbr->timestamp( $params['date'] ); + } + + $sql = 'SELECT img_size, img_name, img_user, img_user_text,'. + 'img_description,img_timestamp FROM ' . $params['imagetable'] ; + + # Hide the bots? + if($params['hidebots']) { + $sql .= $params['botsql'] ; + $where[] = 'ug_group IS NULL' ; + } + + # Single user? + if ( isset ( $params['user'] ) ) { + $where[] = "img_user='" . $params['user']->getID() . "'" ; + } + + if(count($where)) { + $sql.=' WHERE '.$this->dbr->makeList($where, LIST_AND); + } + $sql.=' ORDER BY img_timestamp '. ( $params['latestfirst'] ? '' : ' DESC' ); + $sql.=' LIMIT '.($params['limit']+1); + $res = $this->dbr->query($sql, 'SpecialFilelist::getImages'); + + /** + * We have to flip things around to get the last N after a certain date + */ + $images = array(); + while ( $s = $this->dbr->fetchObject( $res ) ) { + if( $params['latestfirst'] ) { + array_unshift( $images, $s ); + } else { + array_push( $images, $s ); + } + } + $this->dbr->freeResult( $res ); + return $images ; + } + + /** + * Returns HTML for a gallery + */ + function makeGallery ( &$images , &$params ) { + global $wgLang ; + $gallery = new ImageGallery(); + $firstTimestamp = null; + $lastTimestamp = null; + $shownImages = 0; + $params['therearemore'] = false ; + foreach( $images as $s ) { + if( ++$shownImages > $params['limit'] ) { + # One extra just to test for whether to show a page link; + # don't actually show it, but remember there are more. + $params['therearemore'] = true ; + break; + } + + $name = $s->img_name; + $ut = $s->img_user_text; + + $nt = Title::newFromText( $name, NS_IMAGE ); + $img = Image::newFromTitle( $nt ); + $ul = $this->sk->makeLinkObj( Title::makeTitle( NS_USER, $ut ), $ut ); + + $gallery->add( $img, "$ul
\n".$wgLang->timeanddate( $s->img_timestamp, true )."
\n" ); + + $timestamp = wfTimestamp( TS_MW, $s->img_timestamp ); + if( empty( $firstTimestamp ) ) { + $firstTimestamp = $timestamp; + } + $lastTimestamp = $timestamp; + } + $params['lasttimestamp'] = $lastTimestamp ; + $params['firsttimestamp'] = $firstTimestamp ; + return $gallery->toHTML() ; + } + + /** + * Returns a list of files + */ + function makeList ( &$images , &$params ) { + global $wgLang ; + $firstTimestamp = null; + $lastTimestamp = null; + $shownImages = 0; + $params['therearemore'] = false ; + $out = "" ; + foreach( $images as $s ) { + if( ++$shownImages > $params['limit'] ) { + # One extra just to test for whether to show a page link; + # don't actually show it, but remember there are more. + $params['therearemore'] = true ; + break; + } + + $name = $s->img_name; + $ut = $s->img_user_text; + if ( 0 == $s->img_user ) { + $ul = $ut; + } else { + $ul = $this->sk->makeLinkObj( Title::makeTitle( NS_USER, $ut ), $ut ); + } + + $ilink = "" . strtr(htmlspecialchars( $name ), '_', ' ') . ""; + + $nb = wfMsg( "nbytes", $wgLang->formatNum( $s->img_size ) ); + $l = "(" . + $this->sk->makeKnownLinkObj( Title::makeTitle( NS_IMAGE, $name ), + wfMsg( "imgdesc" ) ) . + ") {$ilink} . . {$nb} . . {$ul} . . " . + $wgLang->timeanddate( $s->img_timestamp, true ); + + $l .= $this->sk->commentBlock( $s->img_description ); + $out .= $l . "
\n" ; + + $timestamp = wfTimestamp( TS_MW, $s->img_timestamp ); + if( empty( $firstTimestamp ) ) { + $firstTimestamp = $timestamp; + } + $lastTimestamp = $timestamp; + } + $params['lasttimestamp'] = $lastTimestamp ; + $params['firsttimestamp'] = $firstTimestamp ; + return $out ; + } + + /** + * Preparing parameter for URL + */ + function convertURLparams ( &$params ) { + $p2 = array() ; + if ( isset ( $p2['user'] ) ) { + $p2['user'] = urlencode ( $p2['user']->getName() ) ; + } + + if ( $params['gallery'] != true ) $p2['gallery'] = $params['gallery'] ? "1" : "0" ; + if ( $params['hidebots'] != true ) $p2['hidebots'] = $params['hidebots'] ? "1" : "0" ; + if ( $params['date'] != "" ) $p2['date'] = $params['date'] ; + if ( $params['until'] != "" ) $p2['until'] = $params['until'] ; + if ( $params['match'] != "" ) $p2['match'] = $params['match'] ; + $p2['limit'] = $params['limit'] ; + + return $p2 ; + } + + /** + * Return URL parameters + */ + function getURLparams ( &$params ) { + $ret = "" ; + foreach ( $params AS $k => $v ) { + if ( $v == "" ) continue ; + if ( $ret != "" ) { + $ret .= "&" ; + } + $ret .= $k . "=" . urlencode ( $v ) ; + } + return $ret ; + } + + /** + * Returns the form for keyword matching + */ + function matchform ( &$params ) { + $titleObj = Title::makeTitle( NS_SPECIAL, 'Filelist' ); + $action = $titleObj->escapeLocalURL(); + $sub = wfMsg( 'ilsubmit' ); + $p2 = $this->convertURLparams ( $params ) ; + unset ( $p2['match'] ) ; + $action .= "?" . $this->getURLparams ( $p2 ) ; + $ret = "
" . + " " . + "
" ; + return "

" . $ret . "

" ; + } + + /** + * Returns the limits links + */ + function limits ( &$params ) { + global $wgLang ; + $titleObj = Title::makeTitle( NS_SPECIAL, 'Filelist' ); + $ret = array () ; + + if ( $params['gallery'] ) { + $al = array ( 12 , 36 , 48 , 60 ) ; + } else { + $al = array ( 10 , 25 , 50 , 100 ) ; + } + + $p2 = $this->convertURLparams ( $params ) ; + + foreach ( $al AS $l ) { + $p2['limit'] = $l ; + $p = $this->getURLparams ( $p2 ) ; + + $ret[] = $this->sk->makeKnownLinkObj( $titleObj, $wgLang->formatNum( $l ), $p ) ; + } + + $text = wfMsg( "showlast", implode ( " | " , $ret ), wfMsg('bydate') ); + return $text ; + } + + /** + * Returns the option links + */ + function options ( &$params ) { + $titleObj = Title::makeTitle( NS_SPECIAL, 'Filelist' ); + $ret = array () ; + + $p2 = $this->convertURLparams ( $params ) ; + $p2['hidebots'] = $params['hidebots'] ? "0" : "1" ; + $bots = wfMsg( 'showhidebots', ($params['hidebots'] ? wfMsg('show') : wfMsg('hide'))) ; + $ret[] = $this->sk->makeKnownLinkObj( $titleObj, $bots, $this->getURLparams ( $p2 ) ); + + $p2 = $this->convertURLparams ( $params ) ; + $p2['gallery'] = $params['gallery'] ? "0" : "1" ; + $bots = $params['gallery'] ? wfMsg('filelist_show_list') : wfMsg('filelist_show_gallery') ; + $ret[] = $this->sk->makeKnownLinkObj( $titleObj, $bots, $this->getURLparams ( $p2 ) ); + + return "

" . implode ( " | " , $ret ) . "

" ; + } + + /** + * Returns the previous/next links + */ + function prevnext ( &$params ) { + global $wgLang ; + $out = "" ; + $titleObj = Title::makeTitle( NS_SPECIAL, 'Filelist' ); + + $prevLink = wfMsg( 'prevn', $wgLang->formatNum( $params['limit'] ) ); + if( $params['therearebefore'] ) { + $p2 = $this->convertURLparams ( $params ) ; + $p2['until'] = $params['firsttimestamp'] ; + unset ( $p2['date'] ) ; + $prevLink = $this->sk->makeKnownLinkObj( $titleObj, $prevLink, $this->getURLparams ( $p2 ) ); + } + + $nextLink = wfMsg( 'nextn', $wgLang->formatNum( $params['limit'] ) ); + if( $params['therearemore'] ) { + $p2 = $this->convertURLparams ( $params ) ; + $p2['date'] = $params['lasttimestamp'] ; + unset ( $p2['until'] ) ; + $nextLink = $this->sk->makeKnownLinkObj( $titleObj, $nextLink, $this->getURLparams ( $p2 ) ); + } + + $out .= $prevLink . " | " . $nextLink ; + + return "

" . $out . "

" ; + } + + /** + * main() + */ + function execute( $par = null , $specialPage , $force_gallery = true ) { + global $wgOut, $wgRequest, $wgUser; + $this->dbr =& wfGetDB( DB_SLAVE ); + $this->sk = $wgUser->getSkin(); + + # Setting a bunch of parameters to passed or default values; also some variables which makes them easier to pass to functions + $params['gallery'] = $wgRequest->getBool ( 'gallery' , $force_gallery ) ; + $params['hidebots'] = $wgRequest->getBool ( 'hidebots' , true ) ; + $params['date'] = $wgRequest->getVal ( 'date' , "" ) ; + $params['until'] = $wgRequest->getVal ( 'until' , "" ) ; + $params['match'] = $wgRequest->getVal ( 'match' , "" ) ; + $params['limit'] = $wgRequest->getInt ( 'limit' , ($params['gallery']?48:50) ) ; + $params['user'] = urldecode ( $wgRequest->getVal ( 'user' , ($par==NULL?"":$par) ) ) ; + $params['botsql'] = $this->getHideBotSQL ( $params['hidebots'] ) ; + $params['imagetable'] = $this->dbr->tableName('image'); + + # If "until" is set, "date" should be invalid; also, "latestfirst" should be true to force inverted + if ( $params['until'] != "" ) { + $params['date'] = "" ; + $params['latestfirst'] = true ; + } else { + $params['latestfirst'] = false ; + } + + # Preventing full DB scan for single user; remove this and the following line once the user field has an index + $params['user'] = "" ; + + # Set $user variable if there is a valid user requested + if ( $params['user'] != "" ) { + $user = User::newFromName ( $params['user'] ) ; + if ( 0 != $user->getID() ) { + $params['user'] = $user ; + } else { + unset ( $params['user'] ) ; + } + unset ( $user ) ; + } else { + unset ( $params['user'] ) ; + } + + # Ths following depends on the user above, so don't move it upwards! + $params['timestamp'] = $this->getTimeStamp ( $params ) ; + + $images = $this->getImages ( $params ) ; + + if ( $params['gallery'] ) { + $between = $this->makeGallery ( $images , $params ) ; + } else { + $between = $this->makeList ( $images , $params ) ; + } + + # This is strange + $params['therearebefore'] = ( $params['firsttimestamp'] != $params['timestamp'] ) ; + + $noi = count ( $images ) > $params['limit'] ? $params['limit'] : count ( $images ) ; + + $out = '

' . wfMsgForContent ( "imagelisttext" , $noi , wfMsg('bydate') ) . '

' ; + $out .= $this->matchform ( $params ) ; + $out .= $this->options ( $params ) ; + $out .= $this->limits ( $params ) ; + $out .= $this->prevnext ( $params ) ; + $out .= $between ; + $out .= $this->prevnext ( $params ) ; + + + $this->setHeaders(); + $wgOut->addHtml( $out ); + } + } # End of class + + $sp = new SpecialFilelist ; + $sp->execute( $par , $specialPage , $force_gallery) ; + +} diff --git a/includes/SpecialImagelist.php b/includes/SpecialImagelist.php index 6438e9c716..3bfa0f73a9 100644 --- a/includes/SpecialImagelist.php +++ b/includes/SpecialImagelist.php @@ -5,10 +5,22 @@ * @subpackage SpecialPage */ + +require_once ( "SpecialFilelist.php" ) ; + +function wfSpecialImagelist( $par, $specialPage ) { + wfSpecialFilelist ( $par , $specialPage , false ) ; +} + +# _____________________________________________ +# The rest of this file is obsolete +# _____________________________________________ + + /** * */ -function wfSpecialImagelist() { +function OLD_wfSpecialImagelist() { global $wgUser, $wgOut, $wgLang, $wgRequest, $wgMiserMode; $sort = $wgRequest->getVal( 'sort' ); diff --git a/includes/SpecialNewimages.php b/includes/SpecialNewimages.php index 98c6c36059..83115f0a3b 100644 --- a/includes/SpecialNewimages.php +++ b/includes/SpecialNewimages.php @@ -5,13 +5,24 @@ * @subpackage SpecialPage */ +require_once ( "SpecialFilelist.php" ) ; + +function wfSpecialNewimages( $par, $specialPage ) { + wfSpecialFilelist ( $par , $specialPage , true ) ; +} + +# _____________________________________________ +# The rest of this file is obsolete +# _____________________________________________ + + /** */ require_once( 'ImageGallery.php' ); /** * */ -function wfSpecialNewimages( $par, $specialPage ) { +function OLD_wfSpecialNewimages( $par, $specialPage ) { global $wgUser, $wgOut, $wgLang, $wgContLang, $wgRequest, $wgGroupPermissions; diff --git a/includes/SpecialPage.php b/includes/SpecialPage.php index f9a5ed923e..5c5fa771df 100644 --- a/includes/SpecialPage.php +++ b/includes/SpecialPage.php @@ -77,7 +77,8 @@ $wgSpecialPages = array( 'Userrights' => new SpecialPage( 'Userrights', 'userrights' ), 'MIMEsearch' => new SpecialPage( 'MIMEsearch' ), 'Unwatchedpages' => new SpecialPage( 'Unwatchedpages', 'unwatchedpages' ), - 'Listredirects' => new SpecialPage( 'Listredirects' ) + 'Listredirects' => new SpecialPage( 'Listredirects' ), + 'Filelist' => new SpecialPage( 'Filelist' ) ); if( !$wgDisableCounters ) { diff --git a/languages/Language.php b/languages/Language.php index 765c6f3664..cc88055e40 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -1787,6 +1787,9 @@ ta[\'ca-nstab-category\'] = new Array(\'c\',\'View the category page\');', 'newimages' => 'Gallery of new files', 'showhidebots' => '($1 bots)', 'noimages' => 'Nothing to see.', +'filelist' => 'File list', +'filelist_show_list' => 'Show text list', +'filelist_show_gallery' => 'Show thumbnails', # short names for language variants used for language conversion links. # to disable showing a particular link, set it to 'disable', e.g. -- 2.20.1