9use BadMethodCallException;
18use Wikimedia\Timestamp\TimestampFormat as TS;
53 private $maxTimestamp =
null;
55 private $minTimestamp =
null;
60 parent::__construct(
'RandomInCategory' );
67 $this->category = $cat;
68 $this->maxTimestamp =
null;
69 $this->minTimestamp =
null;
81 'label-message' =>
'randomincategory-category',
110 $categoryStr = $data[
'category'];
112 if ( $categoryStr ) {
113 $cat = Title::newFromText( $categoryStr,
NS_CATEGORY );
116 if ( $cat && $cat->getNamespace() !==
NS_CATEGORY ) {
118 $cat = Title::makeTitleSafe(
NS_CATEGORY, $categoryStr );
125 if ( !$this->category && $categoryStr ) {
126 $msg = $this->
msg(
'randomincategory-invalidcategory',
129 return Status::newFatal( $msg );
131 } elseif ( !$this->category ) {
137 if ( $title ===
null ) {
138 $msg = $this->
msg(
'randomincategory-nopages',
139 $this->category->getText() );
141 return Status::newFatal( $msg );
144 $query = $this->
getRequest()->getQueryValues();
145 unset( $query[
'title'] );
146 $this->
getOutput()->redirect( $title->getFullURL( $query ) );
159 $offset = mt_rand( 0, $this->maxOffset );
161 if ( mt_rand( 0, 1 ) ) {
167 $row = $this->selectRandomPageFromDB( $rand, $offset, $up, __METHOD__ );
171 $row = $this->selectRandomPageFromDB(
false, $offset, $up, __METHOD__ );
176 $row = $this->selectRandomPageFromDB( $rand, 0, $up, __METHOD__ );
181 $row = $this->selectRandomPageFromDB(
false, 0,
true, __METHOD__ );
203 if ( !$this->category instanceof
Title ) {
204 throw new BadMethodCallException(
'No category set' );
206 $dbr = $this->dbProvider->getReplicaDatabase( CategoryLinksTable::VIRTUAL_DOMAIN );
207 $queryBuilder = $dbr->newSelectQueryBuilder()
208 ->select( [
'page_title',
'page_namespace' ] )
209 ->from(
'categorylinks' )
210 ->join(
'linktarget',
null,
'cl_target_id = lt_id' )
211 ->join(
'page',
null,
'cl_from = page_id' )
212 ->where( [
'lt_title' => $this->category->getDBkey(),
'lt_namespace' =>
NS_CATEGORY ] )
213 ->andWhere( $this->extra )
214 ->orderBy(
'cl_timestamp', $up ? SelectQueryBuilder::SORT_ASC : SelectQueryBuilder::SORT_DESC )
220 $op = $up ?
'>=' :
'<=';
221 $queryBuilder->andWhere(
222 $dbr->expr(
'cl_timestamp', $op, $dbr->timestamp( $minClTime ) )
226 return $queryBuilder;
234 if ( $rand ===
false ) {
237 if ( !$this->minTimestamp || !$this->maxTimestamp ) {
239 if ( $minAndMax ===
null ) {
243 [ $this->minTimestamp, $this->maxTimestamp ] = $minAndMax;
246 $ts = ( $this->maxTimestamp - $this->minTimestamp ) * $rand + $this->minTimestamp;
248 return intval( $ts );
257 $dbr = $this->dbProvider->getReplicaDatabase( CategoryLinksTable::VIRTUAL_DOMAIN );
258 $res = $dbr->newSelectQueryBuilder()
259 ->select( [
'low' =>
'MIN( cl_timestamp )',
'high' =>
'MAX( cl_timestamp )' ] )
260 ->from(
'categorylinks' )
261 ->join(
'linktarget',
null,
'cl_target_id = lt_id' )
262 ->where( [
'lt_title' => $this->category->getDBkey(),
'lt_namespace' =>
NS_CATEGORY ] )
263 ->caller( __METHOD__ )
280 private function selectRandomPageFromDB( $rand, $offset, $up, $fname ) {
281 return $this->
getQueryBuilder( $rand, $offset, $up )->caller( $fname )->fetchRow();
294class_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.