Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 39 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
WorkflowLoaderFactory | |
0.00% |
0 / 39 |
|
0.00% |
0 / 6 |
380 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
pageMoveInProgress | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
createWorkflowLoader | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
56 | |||
loadWorkflowById | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
42 | |||
uuidFromTitle | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
uuidFromTitlePair | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
12 |
1 | <?php |
2 | |
3 | namespace Flow; |
4 | |
5 | use Flow\Content\BoardContent; |
6 | use Flow\Data\ManagerGroup; |
7 | use Flow\Exception\CrossWikiException; |
8 | use Flow\Exception\InvalidDataException; |
9 | use Flow\Exception\InvalidInputException; |
10 | use Flow\Exception\InvalidParameterException; |
11 | use Flow\Exception\InvalidTopicUuidException; |
12 | use Flow\Exception\UnknownWorkflowIdException; |
13 | use Flow\Model\UUID; |
14 | use Flow\Model\Workflow; |
15 | use MediaWiki\MediaWikiServices; |
16 | use MediaWiki\Title\Title; |
17 | use MediaWiki\WikiMap\WikiMap; |
18 | |
19 | class WorkflowLoaderFactory { |
20 | /** |
21 | * @var ManagerGroup |
22 | */ |
23 | protected $storage; |
24 | |
25 | /** |
26 | * @var BlockFactory |
27 | */ |
28 | protected $blockFactory; |
29 | |
30 | /** |
31 | * @var SubmissionHandler |
32 | */ |
33 | protected $submissionHandler; |
34 | |
35 | /** |
36 | * @var bool |
37 | */ |
38 | protected $pageMoveInProgress = false; |
39 | |
40 | /** |
41 | * @param ManagerGroup $storage |
42 | * @param BlockFactory $blockFactory |
43 | * @param SubmissionHandler $submissionHandler |
44 | */ |
45 | public function __construct( |
46 | ManagerGroup $storage, |
47 | BlockFactory $blockFactory, |
48 | SubmissionHandler $submissionHandler |
49 | ) { |
50 | $this->storage = $storage; |
51 | $this->blockFactory = $blockFactory; |
52 | $this->submissionHandler = $submissionHandler; |
53 | } |
54 | |
55 | public function pageMoveInProgress() { |
56 | $this->pageMoveInProgress = true; |
57 | } |
58 | |
59 | /** |
60 | * @param Title $pageTitle |
61 | * @param UUID|null $workflowId |
62 | * @return WorkflowLoader |
63 | * @throws InvalidInputException |
64 | * @throws CrossWikiException |
65 | */ |
66 | public function createWorkflowLoader( Title $pageTitle, $workflowId = null ) { |
67 | if ( $pageTitle->isExternal() ) { |
68 | throw new CrossWikiException( 'Interwiki to ' . $pageTitle->getInterwiki() . ' not implemented ', 'default' ); |
69 | } |
70 | |
71 | if ( $pageTitle->getNamespace() < 0 ) { |
72 | throw new InvalidDataException( 'Can not load workflow for special (< 0) namespace', 'invalid-title' ); |
73 | } |
74 | |
75 | // @todo: ideally, workflowId is always set and this stuff is done in the places that call this |
76 | if ( $workflowId === null ) { |
77 | if ( $pageTitle->getNamespace() === NS_TOPIC ) { |
78 | // topic page: workflow UUID is page title |
79 | $workflowId = self::uuidFromTitle( $pageTitle ); |
80 | } else { |
81 | // board page: workflow UUID is inside content model |
82 | $page = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $pageTitle ); |
83 | $content = $page->getContent(); |
84 | if ( $content instanceof BoardContent ) { |
85 | $workflowId = $content->getWorkflowId(); |
86 | } |
87 | } |
88 | } |
89 | |
90 | if ( $workflowId === null ) { |
91 | // We failed to get a Flow content model for this title, |
92 | // so we'll want to clear LinkCache (we're likely be in |
93 | // the process of creating a new workflow, so we don't |
94 | // want lingering cache data) |
95 | // Workflow::create doesn't READ_LATEST to fetch the |
96 | // article id. Let's forcibly make it look like the title |
97 | // does not yet exist (in which case it will be |
98 | // READ_LATEST when we actually want to store it) |
99 | $title = clone $pageTitle; |
100 | $title->resetArticleID( 0 ); |
101 | |
102 | // no existing workflow found, create new one |
103 | $workflow = Workflow::create( 'discussion', $title ); |
104 | } else { |
105 | $workflow = $this->loadWorkflowById( $pageTitle, $workflowId ); |
106 | } |
107 | |
108 | return new WorkflowLoader( |
109 | $workflow, |
110 | $this->blockFactory->createBlocks( $workflow ), |
111 | $this->submissionHandler |
112 | ); |
113 | } |
114 | |
115 | /** |
116 | * @param Title|false $title |
117 | * @param UUID $workflowId |
118 | * @return Workflow |
119 | * @throws InvalidDataException |
120 | * @throws UnknownWorkflowIdException |
121 | */ |
122 | public function loadWorkflowById( /* Title or false */ $title, $workflowId ) { |
123 | /** @var Workflow $workflow */ |
124 | $workflow = $this->storage->getStorage( 'Workflow' )->get( $workflowId ); |
125 | if ( !$workflow ) { |
126 | throw new UnknownWorkflowIdException( 'Invalid workflow requested by id', 'invalid-input' ); |
127 | } |
128 | if ( $workflow->getWiki() !== WikiMap::getCurrentWikiId() ) { |
129 | throw new UnknownWorkflowIdException( 'The requested workflow does not exist on this wiki.' ); |
130 | } |
131 | if ( $title !== false && $this->pageMoveInProgress === false && !$workflow->matchesTitle( $title ) ) { |
132 | throw new InvalidDataException( 'Flow workflow is for different page', 'different-page' ); |
133 | } |
134 | |
135 | return $workflow; |
136 | } |
137 | |
138 | /** |
139 | * Create a UUID for a Title object |
140 | * |
141 | * @param Title $title |
142 | * @return UUID |
143 | * @throws InvalidInputException When the Title does not represent a valid uuid |
144 | */ |
145 | public static function uuidFromTitle( Title $title ) { |
146 | return self::uuidFromTitlePair( $title->getNamespace(), $title->getDBkey() ); |
147 | } |
148 | |
149 | /** |
150 | * Create a UUID for a ns/dbkey title pair |
151 | * |
152 | * @param int $ns |
153 | * @param string $dbKey |
154 | * @return UUID |
155 | * @throws InvalidInputException When the pair does not represent a valid uuid |
156 | */ |
157 | public static function uuidFromTitlePair( $ns, $dbKey ) { |
158 | if ( $ns !== NS_TOPIC ) { |
159 | throw new InvalidParameterException( "Title is not from NS_TOPIC: $ns" ); |
160 | } |
161 | |
162 | try { |
163 | return UUID::create( strtolower( $dbKey ) ); |
164 | } catch ( InvalidInputException $e ) { |
165 | throw new InvalidTopicUuidException( "$dbKey is not a valid UUID", 'invalid-input', $dbKey ); |
166 | } |
167 | } |
168 | } |