Current File : /home/jvzmxxx/wiki1/extensions/Flow/includes/WorkflowLoaderFactory.php
<?php

namespace Flow;

use Flow\Content\BoardContent;
use Flow\Model\UUID;
use Flow\Model\Workflow;
use Flow\Data\ManagerGroup;
use Flow\Exception\CrossWikiException;
use Flow\Exception\InvalidDataException;
use Flow\Exception\InvalidInputException;
use Flow\Exception\InvalidParameterException;
use Flow\Exception\InvalidTopicUuidException;
use Flow\Exception\UnknownWorkflowIdException;
use Title;

class WorkflowLoaderFactory {
	/**
	 * @var ManagerGroup
	 */
	protected $storage;

	/**
	 * @var BlockFactory
	 */
	protected $blockFactory;

	/**
	 * @var SubmissionHandler
	 */
	protected $submissionHandler;

	/**
	 * @var bool
	 */
	protected $pageMoveInProgress = false;

	/**
	 * @param ManagerGroup $storage
	 * @param BlockFactory $blockFactory
	 * @param SubmissionHandler $submissionHandler
	 */
	function __construct(
		ManagerGroup $storage,
		BlockFactory $blockFactory,
		SubmissionHandler $submissionHandler
	) {
		$this->storage = $storage;
		$this->blockFactory = $blockFactory;
		$this->submissionHandler = $submissionHandler;
	}

	public function pageMoveInProgress() {
		$this->pageMoveInProgress = true;
	}

	/**
	 * @param Title $pageTitle
	 * @param UUID|null $workflowId
	 * @return WorkflowLoader
	 * @throws InvalidInputException
	 * @throws CrossWikiException
	 */
	public function createWorkflowLoader( Title $pageTitle, $workflowId = null ) {
		if ( $pageTitle && $pageTitle->isExternal() ) {
			throw new CrossWikiException( 'Interwiki to ' . $pageTitle->getInterwiki() . ' not implemented ', 'default' );
		}

		// @todo: ideally, workflowId is always set and this stuff is done in the places that call this
		if ( $workflowId === null ) {
			if ( $pageTitle->getNamespace() === NS_TOPIC ) {
				// topic page: workflow UUID is page title
				$workflowId = self::uuidFromTitle( $pageTitle );
			} else {
				// board page: workflow UUID is inside content model
				$page = \WikiPage::factory( $pageTitle );
				$content = $page->getContent();
				if ( $content instanceof BoardContent ) {
					$workflowId = $content->getWorkflowId();
				}
			}
		}

		if ( $workflowId === null ) {
			// We failed to get a Flow content model for this title,
			// so we'll want to clear LinkCache (we're likely be in
			// the process of creating a new workflow, so we don't
			// want lingering cache data)
			// Workflow::create doesn't GAID_FOR_UPDATE to fetch the
			// article id. Let's forcibly make it look like the title
			// does not yet exist (in which case it will be
			// GAID_FOR_UPDATE when we actually want to store it)
			$title = clone $pageTitle;
			$title->resetArticleID( 0 );

			// no existing workflow found, create new one
			$workflow = Workflow::create( 'discussion', $title );
		} else {
			$workflow = $this->loadWorkflowById( $pageTitle, $workflowId );
		}

		return new WorkflowLoader(
			$workflow,
			$this->blockFactory->createBlocks( $workflow ),
			$this->submissionHandler
		);
	}

	/**
	 * @param Title|false $title
	 * @param UUID $workflowId
	 * @return Workflow
	 * @throws InvalidInputException
	 * @throws UnknownWorkflowIdException
	 */
	protected function loadWorkflowById( /* Title or false */ $title, $workflowId ) {
		/** @var Workflow $workflow */
		$workflow = $this->storage->getStorage( 'Workflow' )->get( $workflowId );
		if ( !$workflow ) {
			throw new UnknownWorkflowIdException( 'Invalid workflow requested by id', 'invalid-input' );
		}
		if ( $workflow->getWiki() !== wfWikiID() ) {
			throw new UnknownWorkflowIdException( 'The requested workflow does not exist on this wiki.' );
		}
		if ( $title !== false && $this->pageMoveInProgress === false && !$workflow->matchesTitle( $title ) ) {
			throw new InvalidDataException( 'Flow workflow is for different page', 'different-page' );
		}

		return $workflow;
	}

	/**
	 * Create a UUID for a Title object
	 *
	 * @param Title $title
	 * @return UUID
	 * @throws InvalidInputException When the Title does not represent a valid uuid
	 */
	public static function uuidFromTitle( Title $title ) {
		return self::uuidFromTitlePair( $title->getNamespace(), $title->getDbKey() );
	}

	/**
	 * Create a UUID for a ns/dbkey title pair
	 *
	 * @param integer $ns
	 * @param string $dbKey
	 * @return UUID
	 * @throws InvalidInputException When the pair does not represent a valid uuid
	 */
	public static function uuidFromTitlePair( $ns, $dbKey ) {
		if ( $ns !== NS_TOPIC ) {
			throw new InvalidParameterException( "Title is not from NS_TOPIC: $ns" );
		}

		try {
			return UUID::create( strtolower( $dbKey ) );
		} catch ( InvalidInputException $e ) {
			throw new InvalidTopicUuidException( "$dbKey is not a valid UUID", 0, $e );
		}
	}
}