Your IP : 216.73.216.54


Current Path : /var/www/html/mediawiki-1.43.1/extensions/MissedPages/includes/
Upload File :
Current File : /var/www/html/mediawiki-1.43.1/extensions/MissedPages/includes/SpecialMissedPages.php

<?php

namespace MediaWiki\Extension\MissedPages;

use Davaxi\Sparkline;
use Html;
use MediaWiki\Widget\TitleInputWidget;
use OOUI\ActionFieldLayout;
use OOUI\ButtonInputWidget;
use OOUI\HorizontalLayout;
use SpecialPage;
use stdClass;
use TablePager;
use Title;

/**
 * Special Page for MissedPages extension.
 */
class SpecialMissedPages extends SpecialPage {

	/** @var string The user right required to add redirects. */
	protected $redirectRight = 'edit';

	/** @var string The user right required to ignore pages in the missed pages log. */
	protected $ignoreRight = 'block';

	/** @var string The user right required to delete pages from the missed pages log. */
	protected $deleteRight = 'delete';

	/** @var MissedPages */
	protected $log;

	/**
	 * SpecialPage constructor.
	 * @param string $name
	 */
	public function __construct( $name = 'MissedPages' ) {
		parent::__construct( $name );
	}

	/**
	 * @return string
	 */
	protected function getGroupName() {
		return 'other';
	}

	/**
	 * Show the page to the user.
	 *
	 * @param string $sub The subpage string argument (if any).
	 */
	public function execute( $sub ) {
		$this->getOutput()->enableOOUI();
		$out = $this->getOutput();

		$out->setPageTitle( $this->msg( 'missedpages-special-page-title' ) );
		$out->addHelpLink( 'Help:Extension:MissedPages' );
		$out->addModules( 'ext.missedpages' );

		$out->addHTML( $this->getNavLinks( $sub ) );

		if ( in_array( $sub, [ 'recent', 'ignored' ] ) ) {
			$pagerClass = 'MediaWiki\\Extension\\MissedPages\\' . ucfirst( $sub ) . 'Pager';
			/** @var TablePager One of RecentPager or IgnoredPager. */
			$pager = new $pagerClass( $this->getContext(), $this->getLinkRenderer() );
			$out->addParserOutputContent( $pager->getFullOutput() );
			return;
		}

		$this->log = new MissedPages();

		// Save any submitted data.
		if ( $this->getRequest()->wasPosted() ) {
			$postVals = $this->getRequest()->getValues();
			$redirect = false;
			if ( isset( $postVals['redirect'] ) && $this->getUser()->isAllowed( $this->redirectRight ) ) {
				$redirectTarget = $postVals['redirect_target'][$postVals['redirect']];
				$this->log->redirect(
					$postVals['redirect'],
					$redirectTarget,
					$this->getUser()
				);
				$redirect = true;
			}
			if ( isset( $postVals['ignore'] ) && $this->getUser()->isAllowed( $this->ignoreRight ) ) {
				$this->log->ignore( $postVals['ignore'] );
				$redirect = true;
			}
			if ( isset( $postVals['delete'] ) && $this->getUser()->isAllowed( $this->deleteRight ) ) {
				$this->log->delete( $postVals['delete'] );
				$redirect = true;
			}
			if ( $redirect ) {
				// @TODO Add confirmation message.
				$out->redirect( $this->getPageTitle()->getCanonicalURL() );
				return;
			}
		}

		// Build the output.
		$rows = [];
		foreach ( $this->log->getLogEntries() as $logEntry ) {
			$rows[] = $this->getTableRow( $logEntry );
		}
		$headers = Html::rawElement( 'tr', [],
			Html::element( 'th', [], $this->msg( 'missedpages-trend' )->plain() )
			. Html::element( 'th', [], $this->msg( 'missedpages-count' )->plain() )
			. Html::element( 'th', [], $this->msg( 'missedpages-page' )->plain() )
			. Html::element( 'th', [], $this->msg( 'missedpages-actions' )->plain() )
		);
		$table = Html::rawElement(
			'table',
			[ 'class' => 'mw-datatable ext-missedpages' ],
			$headers . implode( "\n", $rows )
		);
		$form = Html::rawElement( 'form', [
			'method' => 'post',
			'action' => $this->getPageTitle()->getInternalURL(),
			'class' => 'ext-missedpages',
		], $table );
		$out->addHTML( $form );
	}

	/**
	 * Get the HTML for the MissedPages navigation menu.
	 * @param string $currentSubPage The current subpage name, or empty for the default page.
	 * @return string
	 */
	protected function getNavLinks( $currentSubPage ) {
		// Map subpage names to link targets.
		$links = [
			'' => $this->getPageTitle(),
			'recent' => $this->getPageTitle()->getSubpage( 'recent' ),
			'ignored' => $this->getPageTitle()->getSubpage( 'ignored' ),
		];
		// Build HTML for each link.
		$navLinks = [];
		foreach ( $links as $name => $target ) {
			$msg = $this->msg( 'missedpages-nav' . ( $name ? "-$name" : '' ) );
			$navLinks[] = $name === strval( $currentSubPage )
				? Html::element( 'strong', [], $msg )
				: $this->getLinkRenderer()->makeLink( $target, $msg );
		}
		// Combine all links as one list.
		$pipeList = $this->getLanguage()->pipeList( $navLinks );
		return "[ $pipeList ]";
	}

	/**
	 * Get one TR for the given entry.
	 *
	 * @param stdClass $logEntry
	 * @return string
	 */
	protected function getTableRow( stdClass $logEntry ) {
		$sparkline = new Sparkline();
		$dayCounts = $this->log->getDayCounts( $logEntry->mp_page_title );
		$sparkline->setData( $dayCounts );
		$imgParams = [
			'class' => 'sparkline',
			'src' => 'data:image/png;base64,' . $sparkline->toBase64(),
			'title' => $this->msg( 'missedpages-sparkline-title',
				number_format( array_sum( $dayCounts ) ),
				number_format( count( $dayCounts ) )
			),
		];
		$sparklineImage = Html::element( 'img', $imgParams );
		$sparklineCell = Html::rawElement( 'td', [], $sparklineImage );

		$countCell = Html::rawElement( 'td', [], $logEntry->count );
		$pageLink = $this->getLinkRenderer()->makeLink( Title::newFromText( $logEntry->mp_page_title ) );
		$pageCell = Html::rawElement( 'td', [], $pageLink );

		$ignoreButton = new ButtonInputWidget( [
			'type' => 'submit',
			'name' => 'ignore',
			'value' => $logEntry->mp_page_title,
			'label' => $this->msg( "missedpages-ignore" )->plain(),
			'title' => $this->msg( "missedpages-ignore-desc" )->plain(),
			// This isn't really the same as blocking a user, but it's a similar level of responsibility.
			'disabled' => !$this->getUser()->isAllowed( $this->ignoreRight ),
		] );
		$deleteButton = new ButtonInputWidget( [
			'type' => 'submit',
			'name' => 'delete',
			'value' => $logEntry->mp_page_title,
			'label' => $this->msg( "missedpages-delete" )->plain(),
			'title' => $this->msg( "missedpages-delete-desc" )->plain(),
			'disabled' => !$this->getUser()->isAllowed( $this->deleteRight ),
		] );
		$disableRedirectField = !$this->getUser()->isAllowed( $this->redirectRight );
		$redirectField = new ActionFieldLayout(
			new TitleInputWidget( [
				'name' => 'redirect_target[' . $logEntry->mp_page_title . ']',
				'infusable' => true,
				'disabled' => $disableRedirectField,
			] ),
			new ButtonInputWidget( [
				'type' => 'submit',
				'name' => 'redirect',
				'value' => $logEntry->mp_page_title,
				'label' => $this->msg( 'missedpages-redirect' )->plain(),
				'title' => $this->msg( 'missedpages-redirect-desc' )->plain(),
				'disabled' => $disableRedirectField
			] )
		);
		$fields = new HorizontalLayout( [
			'items' => [ $redirectField, $ignoreButton, $deleteButton ],
		] );

		$actionCell = Html::rawElement( 'td', [], $fields->toString() );
		return Html::rawElement( 'tr', [], $sparklineCell . $countCell . $pageCell . $actionCell );
	}

}