Page MenuHomeWickedGov Phorge

PageRedirectHelper.php
No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None

PageRedirectHelper.php

<?php
namespace MediaWiki\Rest\Handler\Helper;
use MediaWiki\Languages\LanguageConverterFactory;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\Page\PageIdentity;
use MediaWiki\Page\PageReference;
use MediaWiki\Page\RedirectStore;
use MediaWiki\Rest\RequestInterface;
use MediaWiki\Rest\Response;
use MediaWiki\Rest\ResponseFactory;
use MediaWiki\Rest\Router;
use MediaWiki\Title\TitleFormatter;
use MediaWiki\Title\TitleValue;
/**
* Helper class for handling page redirects, for use with REST Handlers that provide access
* to resources bound to MediaWiki pages.
*
* @since 1.41
*/
class PageRedirectHelper {
private RedirectStore $redirectStore;
private TitleFormatter $titleFormatter;
private ResponseFactory $responseFactory;
private Router $router;
private string $path;
private RequestInterface $request;
private LanguageConverterFactory $languageConverterFactory;
private bool $followWikiRedirects = false;
private string $titleParamName = 'title';
private bool $useRelativeRedirects = true;
public function __construct(
RedirectStore $redirectStore,
TitleFormatter $titleFormatter,
ResponseFactory $responseFactory,
Router $router,
string $path,
RequestInterface $request,
LanguageConverterFactory $languageConverterFactory
) {
$this->redirectStore = $redirectStore;
$this->titleFormatter = $titleFormatter;
$this->responseFactory = $responseFactory;
$this->router = $router;
$this->path = $path;
$this->request = $request;
$this->languageConverterFactory = $languageConverterFactory;
}
/**
* @param bool $useRelativeRedirects
*/
public function setUseRelativeRedirects( bool $useRelativeRedirects ): void {
$this->useRelativeRedirects = $useRelativeRedirects;
}
/**
* @param bool $followWikiRedirects
*/
public function setFollowWikiRedirects( bool $followWikiRedirects ): void {
$this->followWikiRedirects = $followWikiRedirects;
}
/**
* Check for Page Normalization Redirects and create a Permanent Redirect Response
* @param PageIdentity $page
* @param ?string $titleAsRequested
* @return Response|null
*/
public function createNormalizationRedirectResponseIfNeeded(
PageIdentity $page,
?string $titleAsRequested
): ?Response {
if ( $titleAsRequested === null ) {
return null;
}
$normalizedTitle = $this->titleFormatter->getPrefixedDBkey( $page );
// Check for normalization redirects
if ( $titleAsRequested !== $normalizedTitle ) {
$redirectTargetUrl = $this->getTargetUrl( $normalizedTitle );
return $this->responseFactory->createPermanentRedirect( $redirectTargetUrl );
}
return null;
}
/**
* Check for Page Wiki Redirects and create a Temporary Redirect Response
* @param PageIdentity $page
* @return Response|null
*/
public function createWikiRedirectResponseIfNeeded( PageIdentity $page ): ?Response {
$redirectTargetUrl = $this->getWikiRedirectTargetUrl( $page );
if ( $redirectTargetUrl === null ) {
return null;
}
return $this->responseFactory->createTemporaryRedirect( $redirectTargetUrl );
}
/**
* @param PageIdentity $page
* @return string|null
*/
public function getWikiRedirectTargetUrl( PageIdentity $page ): ?string {
$redirectTarget = $this->redirectStore->getRedirectTarget( $page );
if ( $redirectTarget === null ) {
return null;
}
if ( $redirectTarget->isSameLinkAs( TitleValue::newFromPage( $page ) ) ) {
// This can happen if the current page is virtual file description
// page backed by a remote file repo (T353688).
return null;
}
return $this->getTargetUrl( $redirectTarget );
}
/**
* Check if a page with a variant title exists and create a Temporary Redirect Response
* if needed.
*
* @param PageIdentity $page
* @param string|null $titleAsRequested
*
* @return Response|null
*/
private function createVariantRedirectResponseIfNeeded(
PageIdentity $page, ?string $titleAsRequested
): ?Response {
if ( $page->exists() ) {
// If the page exists, there is no need to generate a redirect.
return null;
}
$redirectTargetUrl = $this->getVariantRedirectTargetUrl(
$page,
$titleAsRequested
);
if ( $redirectTargetUrl === null ) {
return null;
}
return $this->responseFactory->createTemporaryRedirect( $redirectTargetUrl );
}
/**
* @param PageIdentity $page
* @param string $titleAsRequested
*
* @return string|null
*/
private function getVariantRedirectTargetUrl(
PageIdentity $page, string $titleAsRequested
): ?string {
$variantPage = null;
if ( $this->hasVariants() ) {
$variantPage = $this->findVariantPage( $titleAsRequested, $page );
}
if ( !$variantPage ) {
return null;
}
return $this->getTargetUrl( $variantPage );
}
/**
* @param string|LinkTarget|PageReference $title
* @return string The target to use in the Location header. Will be relative,
* unless setUseRelativeRedirects( false ) was called.
*/
public function getTargetUrl( $title ): string {
if ( !is_string( $title ) ) {
$title = $this->titleFormatter->getPrefixedDBkey( $title );
}
$pathParams = [ $this->titleParamName => $title ];
if ( $this->useRelativeRedirects ) {
return $this->router->getRoutePath(
$this->path,
$pathParams,
$this->request->getQueryParams()
);
} else {
return $this->router->getRouteUrl(
$this->path,
$pathParams,
$this->request->getQueryParams()
);
}
}
/**
* Use this function for endpoints that check for both
* normalizations and wiki redirects.
*
* @param PageIdentity $page
* @param string|null $titleAsRequested
* @return Response|null
*/
public function createRedirectResponseIfNeeded(
PageIdentity $page,
?string $titleAsRequested
): ?Response {
if ( $titleAsRequested !== null ) {
$normalizationRedirectResponse = $this->createNormalizationRedirectResponseIfNeeded(
$page, $titleAsRequested
);
if ( $normalizationRedirectResponse !== null ) {
return $normalizationRedirectResponse;
}
}
if ( $this->followWikiRedirects ) {
$variantRedirectResponse = $this->createVariantRedirectResponseIfNeeded( $page, $titleAsRequested );
if ( $variantRedirectResponse !== null ) {
return $variantRedirectResponse;
}
$wikiRedirectResponse = $this->createWikiRedirectResponseIfNeeded( $page );
if ( $wikiRedirectResponse !== null ) {
return $wikiRedirectResponse;
}
}
return null;
}
private function hasVariants(): bool {
return $this->languageConverterFactory->getLanguageConverter()->hasVariants();
}
/**
* @param string $titleAsRequested
* @param PageReference $page
*
* @return ?PageReference
*/
private function findVariantPage( string $titleAsRequested, PageReference $page ): ?PageReference {
$originalPage = $page;
$languageConverter = $this->languageConverterFactory->getLanguageConverter();
// @phan-suppress-next-line PhanTypeMismatchArgumentSuperType
$languageConverter->findVariantLink( $titleAsRequested, $page, true );
if ( $page === $originalPage ) {
// No variant link found, $page was not updated.
return null;
}
return $page;
}
}

File Metadata

Mime Type
text/x-php
Expires
Aug 17 2026, 17:48 (10 w, 2 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
e3/bd/bcff004e85374152b87a7a26c51d
Default Alt Text
PageRedirectHelper.php (6 KB)

Event Timeline