9use BadMethodCallException;
18use Wikimedia\Timestamp\TimestampFormat as TS;
53 private $maxTimestamp =
null;
55 private $minTimestamp =
null;
60 parent::__construct(
'RandomInCategory' );
61 $this->dbProvider = $dbProvider;
68 $this->category = $cat;
69 $this->maxTimestamp =
null;
70 $this->minTimestamp =
null;
82 'label-message' =>
'randomincategory-category',
111 $categoryStr = $data[
'category'];
113 if ( $categoryStr ) {
114 $cat = Title::newFromText( $categoryStr,
NS_CATEGORY );
117 if ( $cat && $cat->getNamespace() !==
NS_CATEGORY ) {
119 $cat = Title::makeTitleSafe(
NS_CATEGORY, $categoryStr );
126 if ( !$this->category && $categoryStr ) {
127 $msg = $this->
msg(
'randomincategory-invalidcategory',
130 return Status::newFatal( $msg );
132 } elseif ( !$this->category ) {
138 if ( $title ===
null ) {
139 $msg = $this->
msg(
'randomincategory-nopages',
140 $this->category->getText() );
142 return Status::newFatal( $msg );
145 $query = $this->
getRequest()->getQueryValues();
146 unset( $query[
'title'] );
147 $this->
getOutput()->redirect( $title->getFullURL( $query ) );
160 $offset = mt_rand( 0, $this->maxOffset );
162 if ( mt_rand( 0, 1 ) ) {
168 $row = $this->selectRandomPageFromDB( $rand, $offset, $up, __METHOD__ );
172 $row = $this->selectRandomPageFromDB(
false, $offset, $up, __METHOD__ );
177 $row = $this->selectRandomPageFromDB( $rand, 0, $up, __METHOD__ );
182 $row = $this->selectRandomPageFromDB(
false, 0,
true, __METHOD__ );
204 if ( !$this->category instanceof
Title ) {
205 throw new BadMethodCallException(
'No category set' );
207 $dbr = $this->dbProvider->getReplicaDatabase( CategoryLinksTable::VIRTUAL_DOMAIN );
208 $queryBuilder = $dbr->newSelectQueryBuilder()
209 ->select( [
'page_title',
'page_namespace' ] )
210 ->from(
'categorylinks' )
211 ->join(
'linktarget',
null,
'cl_target_id = lt_id' )
212 ->join(
'page',
null,
'cl_from = page_id' )
213 ->where( [
'lt_title' => $this->category->getDBkey(),
'lt_namespace' =>
NS_CATEGORY ] )
214 ->andWhere( $this->extra )
215 ->orderBy(
'cl_timestamp', $up ? SelectQueryBuilder::SORT_ASC : SelectQueryBuilder::SORT_DESC )
221 $op = $up ?
'>=' :
'<=';
222 $queryBuilder->andWhere(
223 $dbr->expr(
'cl_timestamp', $op, $dbr->timestamp( $minClTime ) )
227 return $queryBuilder;
235 if ( $rand ===
false ) {
238 if ( !$this->minTimestamp || !$this->maxTimestamp ) {
240 if ( $minAndMax ===
null ) {
244 [ $this->minTimestamp, $this->maxTimestamp ] = $minAndMax;
247 $ts = ( $this->maxTimestamp - $this->minTimestamp ) * $rand + $this->minTimestamp;
249 return intval( $ts );
258 $dbr = $this->dbProvider->getReplicaDatabase( CategoryLinksTable::VIRTUAL_DOMAIN );
259 $res = $dbr->newSelectQueryBuilder()
260 ->select( [
'low' =>
'MIN( cl_timestamp )',
'high' =>
'MAX( cl_timestamp )' ] )
261 ->from(
'categorylinks' )
262 ->join(
'linktarget',
null,
'cl_target_id = lt_id' )
263 ->where( [
'lt_title' => $this->category->getDBkey(),
'lt_namespace' =>
NS_CATEGORY ] )
264 ->caller( __METHOD__ )
281 private function selectRandomPageFromDB( $rand, $offset, $up, $fname ) {
282 return $this->
getQueryBuilder( $rand, $offset, $up )->caller( $fname )->fetchRow();
295class_alias( SpecialRandomInCategory::class,
'SpecialRandomInCategory' );
wfRandom()
Get a random decimal value in the domain of [0, 1), in a way not likely to give duplicate values for ...
wfEscapeWikiText( $input)
Escapes the given text so that it may be output using addWikiText() without any linking,...
wfTimestamp( $outputtype=TS::UNIX, $ts=0)
Get a timestamp string in one of various formats.
Special page which uses an HTMLForm to handle processing.
getRequest()
Get the WebRequest being used for this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getOutput()
Get the OutputPage being used for this instance.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.