]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/page/ImageHistoryPseudoPager.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / page / ImageHistoryPseudoPager.php
1 <?php
2 /**
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  * http://www.gnu.org/copyleft/gpl.html
17  *
18  * @file
19  */
20
21 class ImageHistoryPseudoPager extends ReverseChronologicalPager {
22         protected $preventClickjacking = false;
23
24         /**
25          * @var File
26          */
27         protected $mImg;
28
29         /**
30          * @var Title
31          */
32         protected $mTitle;
33
34         /**
35          * @since 1.14
36          * @var ImagePage
37          */
38         public $mImagePage;
39
40         /**
41          * @since 1.14
42          * @var File[]
43          */
44         public $mHist;
45
46         /**
47          * @since 1.14
48          * @var int[]
49          */
50         public $mRange;
51
52         /**
53          * @param ImagePage $imagePage
54          */
55         public function __construct( $imagePage ) {
56                 parent::__construct( $imagePage->getContext() );
57                 $this->mImagePage = $imagePage;
58                 $this->mTitle = $imagePage->getTitle()->createFragmentTarget( 'filehistory' );
59                 $this->mImg = null;
60                 $this->mHist = [];
61                 $this->mRange = [ 0, 0 ]; // display range
62
63                 // Only display 10 revisions at once by default, otherwise the list is overwhelming
64                 $this->mLimitsShown = array_merge( [ 10 ], $this->mLimitsShown );
65                 $this->mDefaultLimit = 10;
66                 list( $this->mLimit, /* $offset */ ) =
67                         $this->mRequest->getLimitOffset( $this->mDefaultLimit, '' );
68         }
69
70         /**
71          * @return Title
72          */
73         public function getTitle() {
74                 return $this->mTitle;
75         }
76
77         public function getQueryInfo() {
78                 return false;
79         }
80
81         /**
82          * @return string
83          */
84         public function getIndexField() {
85                 return '';
86         }
87
88         /**
89          * @param object $row
90          * @return string
91          */
92         public function formatRow( $row ) {
93                 return '';
94         }
95
96         /**
97          * @return string
98          */
99         public function getBody() {
100                 $s = '';
101                 $this->doQuery();
102                 if ( count( $this->mHist ) ) {
103                         if ( $this->mImg->isLocal() ) {
104                                 // Do a batch existence check for user pages and talkpages
105                                 $linkBatch = new LinkBatch();
106                                 for ( $i = $this->mRange[0]; $i <= $this->mRange[1]; $i++ ) {
107                                         $file = $this->mHist[$i];
108                                         $user = $file->getUser( 'text' );
109                                         $linkBatch->add( NS_USER, $user );
110                                         $linkBatch->add( NS_USER_TALK, $user );
111                                 }
112                                 $linkBatch->execute();
113                         }
114
115                         $list = new ImageHistoryList( $this->mImagePage );
116                         # Generate prev/next links
117                         $navLink = $this->getNavigationBar();
118                         $s = $list->beginImageHistoryList( $navLink );
119                         // Skip rows there just for paging links
120                         for ( $i = $this->mRange[0]; $i <= $this->mRange[1]; $i++ ) {
121                                 $file = $this->mHist[$i];
122                                 $s .= $list->imageHistoryLine( !$file->isOld(), $file );
123                         }
124                         $s .= $list->endImageHistoryList( $navLink );
125
126                         if ( $list->getPreventClickjacking() ) {
127                                 $this->preventClickjacking();
128                         }
129                 }
130                 return $s;
131         }
132
133         public function doQuery() {
134                 if ( $this->mQueryDone ) {
135                         return;
136                 }
137                 $this->mImg = $this->mImagePage->getPage()->getFile(); // ensure loading
138                 if ( !$this->mImg->exists() ) {
139                         return;
140                 }
141                 $queryLimit = $this->mLimit + 1; // limit plus extra row
142                 if ( $this->mIsBackwards ) {
143                         // Fetch the file history
144                         $this->mHist = $this->mImg->getHistory( $queryLimit, null, $this->mOffset, false );
145                         // The current rev may not meet the offset/limit
146                         $numRows = count( $this->mHist );
147                         if ( $numRows <= $this->mLimit && $this->mImg->getTimestamp() > $this->mOffset ) {
148                                 $this->mHist = array_merge( [ $this->mImg ], $this->mHist );
149                         }
150                 } else {
151                         // The current rev may not meet the offset
152                         if ( !$this->mOffset || $this->mImg->getTimestamp() < $this->mOffset ) {
153                                 $this->mHist[] = $this->mImg;
154                         }
155                         // Old image versions (fetch extra row for nav links)
156                         $oiLimit = count( $this->mHist ) ? $this->mLimit : $this->mLimit + 1;
157                         // Fetch the file history
158                         $this->mHist = array_merge( $this->mHist,
159                                 $this->mImg->getHistory( $oiLimit, $this->mOffset, null, false ) );
160                 }
161                 $numRows = count( $this->mHist ); // Total number of query results
162                 if ( $numRows ) {
163                         # Index value of top item in the list
164                         $firstIndex = $this->mIsBackwards ?
165                                 $this->mHist[$numRows - 1]->getTimestamp() : $this->mHist[0]->getTimestamp();
166                         # Discard the extra result row if there is one
167                         if ( $numRows > $this->mLimit && $numRows > 1 ) {
168                                 if ( $this->mIsBackwards ) {
169                                         # Index value of item past the index
170                                         $this->mPastTheEndIndex = $this->mHist[0]->getTimestamp();
171                                         # Index value of bottom item in the list
172                                         $lastIndex = $this->mHist[1]->getTimestamp();
173                                         # Display range
174                                         $this->mRange = [ 1, $numRows - 1 ];
175                                 } else {
176                                         # Index value of item past the index
177                                         $this->mPastTheEndIndex = $this->mHist[$numRows - 1]->getTimestamp();
178                                         # Index value of bottom item in the list
179                                         $lastIndex = $this->mHist[$numRows - 2]->getTimestamp();
180                                         # Display range
181                                         $this->mRange = [ 0, $numRows - 2 ];
182                                 }
183                         } else {
184                                 # Setting indexes to an empty string means that they will be
185                                 # omitted if they would otherwise appear in URLs. It just so
186                                 # happens that this  is the right thing to do in the standard
187                                 # UI, in all the relevant cases.
188                                 $this->mPastTheEndIndex = '';
189                                 # Index value of bottom item in the list
190                                 $lastIndex = $this->mIsBackwards ?
191                                         $this->mHist[0]->getTimestamp() : $this->mHist[$numRows - 1]->getTimestamp();
192                                 # Display range
193                                 $this->mRange = [ 0, $numRows - 1 ];
194                         }
195                 } else {
196                         $firstIndex = '';
197                         $lastIndex = '';
198                         $this->mPastTheEndIndex = '';
199                 }
200                 if ( $this->mIsBackwards ) {
201                         $this->mIsFirst = ( $numRows < $queryLimit );
202                         $this->mIsLast = ( $this->mOffset == '' );
203                         $this->mLastShown = $firstIndex;
204                         $this->mFirstShown = $lastIndex;
205                 } else {
206                         $this->mIsFirst = ( $this->mOffset == '' );
207                         $this->mIsLast = ( $numRows < $queryLimit );
208                         $this->mLastShown = $lastIndex;
209                         $this->mFirstShown = $firstIndex;
210                 }
211                 $this->mQueryDone = true;
212         }
213
214         /**
215          * @param bool $enable
216          */
217         protected function preventClickjacking( $enable = true ) {
218                 $this->preventClickjacking = $enable;
219         }
220
221         /**
222          * @return bool
223          */
224         public function getPreventClickjacking() {
225                 return $this->preventClickjacking;
226         }
227
228 }