wikimedia/mediawiki-extensions-Wikibase

View on GitHub
repo/includes/Specials/SpecialWikibaseRepoPage.php

Summary

Maintainability
A
50 mins
Test Coverage
<?php

namespace Wikibase\Repo\Specials;

use MediaWiki\Title\Title;
use RuntimeException;
use Wikibase\DataModel\Entity\EntityDocument;
use Wikibase\DataModel\Entity\EntityId;
use Wikibase\DataModel\Entity\ItemId;
use Wikibase\Lib\FormatableSummary;
use Wikibase\Lib\Store\EntityTitleLookup;
use Wikibase\Lib\UserInputException;
use Wikibase\Repo\EditEntity\EditEntity;
use Wikibase\Repo\EditEntity\EditEntityStatus;
use Wikibase\Repo\EditEntity\MediaWikiEditEntityFactory;
use Wikibase\Repo\SummaryFormatter;
use Wikibase\Repo\WikibaseRepo;
use Wikimedia\Assert\Assert;

/**
 * Abstract base class for special pages of the WikibaseRepo extension.
 *
 * @license GPL-2.0-or-later
 * @author Bene* < benestar.wikimedia@gmail.com >
 */
abstract class SpecialWikibaseRepoPage extends SpecialWikibasePage {

    /** @var string[] */
    private $tags;

    /**
     * @var SpecialPageCopyrightView
     */
    private $copyrightView;

    /**
     * @var SummaryFormatter
     */
    protected $summaryFormatter;

    /**
     * @var EntityTitleLookup
     */
    private $entityTitleLookup;

    /**
     * @var MediaWikiEditEntityFactory
     */
    private $editEntityFactory;

    /**
     * @var EditEntity
     */
    private $editEntity = null;

    /**
     * @param string $title The title of the special page
     * @param string $restriction The required user right
     * @param string[] $tags List of tags to add to edits
     * @param SpecialPageCopyrightView $copyrightView
     * @param SummaryFormatter $summaryFormatter
     * @param EntityTitleLookup $entityTitleLookup
     * @param MediaWikiEditEntityFactory $editEntityFactory
     */
    public function __construct(
        $title,
        $restriction,
        array $tags,
        SpecialPageCopyrightView $copyrightView,
        SummaryFormatter $summaryFormatter,
        EntityTitleLookup $entityTitleLookup,
        MediaWikiEditEntityFactory $editEntityFactory
    ) {
        parent::__construct( $title, $restriction );
        $this->tags = $tags;
        $this->copyrightView = $copyrightView;
        $this->summaryFormatter = $summaryFormatter;
        $this->entityTitleLookup = $entityTitleLookup;
        $this->editEntityFactory = $editEntityFactory;
    }

    /**
     * @param EntityId|null $id
     * @param int $baseRev
     * @return EditEntity
     */
    protected function prepareEditEntity( EntityId $id = null, $baseRev = 0 ) {
        $this->editEntity = $this->editEntityFactory->newEditEntity(
            $this->getContext(),
            $id,
            $baseRev,
            $this->getRequest()->wasPosted()
        );

        return $this->editEntity;
    }

    /**
     * Returns the EditEntity interactor.
     *
     * @note Call only after calling prepareEditEntity() first.
     *
     * @return EditEntity
     */
    protected function getEditEntity() {
        if ( !$this->editEntity ) {
            throw new RuntimeException( 'Call prepareEditEntity() before calling getEditEntity()' );
        }

        return $this->editEntity;
    }

    /**
     * Parses an entity id.
     *
     * @param string $rawId
     *
     * @return EntityId
     * @throws UserInputException
     */
    protected function parseEntityId( $rawId ) {
        // TODO inject this!
        $idParser = WikibaseRepo::getEntityIdParser();

        try {
            $id = $idParser->parse( $rawId );
        } catch ( RuntimeException $ex ) {
            throw new UserInputException(
                'wikibase-wikibaserepopage-invalid-id',
                [ $rawId ],
                "Entity ID \"$rawId\" is not valid"
            );
        }

        return $id;
    }

    /**
     * Parses an item id.
     *
     * @param string $rawId
     *
     * @return ItemId
     * @throws UserInputException
     */
    protected function parseItemId( $rawId ) {
        $id = $this->parseEntityId( $rawId );

        if ( !( $id instanceof ItemId ) ) {
            throw new UserInputException(
                'wikibase-wikibaserepopage-not-itemid',
                [ $rawId ],
                "Entity ID \"$rawId\" does not refer to an Item"
            );
        }

        return $id;
    }

    /**
     * @param EntityId $id
     *
     * @return null|Title
     */
    protected function getEntityTitle( EntityId $id ) {
        return $this->entityTitleLookup->getTitleForId( $id );
    }

    /**
     * Saves the entity using the given summary.
     *
     * @note Call prepareEditEntity() first.
     *
     * @param EntityDocument $entity
     * @param FormatableSummary $summary
     * @param string $token Edit token to check. An empty string is guaranteed to be invalid.
     * @param int $flags The edit flags (see WikiPage::doEditContent)
     *
     * @return EditEntityStatus
     */
    protected function saveEntity(
        EntityDocument $entity,
        FormatableSummary $summary,
        $token,
        $flags = EDIT_UPDATE
    ) {
        $status = $this->getEditEntity()->attemptSave(
            $entity,
            $this->summaryFormatter->formatSummary( $summary ),
            $flags,
            $token,
            null,
            $this->tags
        );

        return $status;
    }

    /**
     * Redirect to the page of the entity that was successfully edited.
     *
     * @param EditEntityStatus $status A status as returned by {@link self::saveEntity()}.
     * The status must be {@link StatusValue::isOK() OK}.
     */
    protected function redirectToEntityPage( EditEntityStatus $status ): void {
        Assert::parameter( $status->isOK(), '$status', 'must be OK' );
        $title = $this->getEntityTitle( $status->getRevision()->getEntity()->getId() );
        $savedTempUser = $status->getSavedTempUser();
        $redirectUrl = '';
        if ( $savedTempUser !== null ) {
            $this->getHookRunner()->onTempUserCreatedRedirect(
                $this->getRequest()->getSession(),
                $savedTempUser,
                $title->getPrefixedDBkey(),
                '',
                '',
                $redirectUrl
            );
        }
        if ( !$redirectUrl ) {
            $redirectUrl = $title->getFullURL();
        }
        $this->getOutput()->redirect( $redirectUrl );
    }

    /**
     * @param string|null $saveMessageKey Defaults to "wikibase-<special page name>-submit".
     *
     * @return string HTML
     */
    protected function getCopyrightHTML( $saveMessageKey = null ) {
        if ( $saveMessageKey === null ) {
            $saveMessageKey = 'wikibase-' . strtolower( $this->getName() ) . '-submit';
        }

        return $this->copyrightView->getHtml( $this->getLanguage(), $saveMessageKey );
    }

}