Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 81
0.00% covered (danger)
0.00%
0 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialStructuredDiscussions
0.00% covered (danger)
0.00%
0 / 81
0.00% covered (danger)
0.00%
0 / 12
756
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setParameter
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 getTypes
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 getFormFields
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
6
 preHtml
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 alterForm
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDisplayFormat
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPostUrl
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 getWorkflowUrl
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 onSubmit
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
72
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * A special page that redirects to a workflow or PostRevision given a UUID
5 */
6
7namespace Flow\Specials;
8
9use Flow\Container;
10use Flow\Data\ObjectManager;
11use Flow\Exception\FlowException;
12use Flow\Model\UUID;
13use Flow\Model\Workflow;
14use Flow\Repository\TreeRepository;
15use HTMLForm;
16use MediaWiki\SpecialPage\FormSpecialPage;
17use MediaWiki\Status\Status;
18
19class SpecialStructuredDiscussions extends FormSpecialPage {
20
21    /**
22     * The type of content, e.g. 'post', 'workflow'
23     * @var string
24     */
25    protected $type;
26
27    /**
28     * Flow UUID
29     * @var string
30     */
31    protected $uuid;
32
33    public function __construct() {
34        parent::__construct( 'StructuredDiscussions' );
35    }
36
37    /**
38     * @inheritDoc
39     */
40    public function execute( $par ) {
41        parent::execute( $par );
42        $this->addHelplink( 'Help:Structured_Discussions' );
43    }
44
45    /**
46     * Initialize $this->type and $this-uuid using the subpage string.
47     * @param string|null $par
48     */
49    protected function setParameter( $par ) {
50        $tokens = $par !== null ? explode( '/', $par, 2 ) : [];
51        $this->type = $tokens[0] ?? '';
52        if ( count( $tokens ) > 1 ) {
53            $this->uuid = $tokens[1];
54        }
55    }
56
57    /**
58     * Get the mapping between display text and value for the type dropdown.
59     * @return array
60     */
61    protected function getTypes() {
62        $mapping = [
63            'flow-special-type-post' => 'post',
64            'flow-special-type-workflow' => 'workflow',
65        ];
66
67        $types = [];
68        foreach ( $mapping as $msgKey => $option ) {
69            $types[$this->msg( $msgKey )->escaped()] = $option;
70        }
71        return $types;
72    }
73
74    protected function getFormFields() {
75        return [
76            'type' => [
77                'id' => 'mw-flow-special-type',
78                'name' => 'type',
79                'type' => 'select',
80                'label-message' => 'flow-special-type',
81                'options' => $this->getTypes(),
82                'default' => $this->type === '' ? 'post' : $this->type,
83            ],
84            'uuid' => [
85                'id' => 'mw-flow-special-uuid',
86                'name' => 'uuid',
87                'type' => 'text',
88                'label-message' => 'flow-special-uuid',
89                'default' => $this->uuid,
90            ],
91        ];
92    }
93
94    /**
95     * Description shown at the top of the page
96     * @return string
97     */
98    protected function preHtml() {
99        return '<p>' . $this->msg( 'flow-special-desc' )->escaped() . '</p>';
100    }
101
102    protected function alterForm( HTMLForm $form ) {
103        $form->setMethod( 'get' ); // This also submits the form every time the page loads.
104    }
105
106    /**
107     * @return string
108     */
109    protected function getDisplayFormat() {
110        return 'ooui';
111    }
112
113    /**
114     * Get the URL of a UUID for a PostRevision.
115     * @return string|null
116     */
117    protected function getPostUrl() {
118        try {
119            $postId = UUID::create( $this->uuid );
120            /** @var TreeRepository $treeRepo */
121            $treeRepo = Container::get( 'repository.tree' );
122            $rootId = $treeRepo->findRoot( $postId );
123            /** @var ObjectManager $om */
124            $om = Container::get( 'storage.workflow' );
125            $workflow = $om->get( $rootId );
126            if ( $workflow instanceof Workflow ) {
127                /** @var UrlGenerator $urlGenerator */
128                $urlGenerator = Container::get( 'url_generator' );
129                return $urlGenerator->postLink(
130                    null,
131                    $rootId,
132                    $postId
133                )->getFullUrl();
134            } else {
135                return null;
136            }
137        } catch ( FlowException $e ) {
138            return null; // The UUID is invalid or has no root post.
139        }
140    }
141
142    /**
143     * Get the URL of a UUID for a workflow.
144     * @return string|null
145     */
146    protected function getWorkflowUrl() {
147        try {
148            $rootId = UUID::create( $this->uuid );
149            /** @var ObjectManager $om */
150            $om = Container::get( 'storage.workflow' );
151            $workflow = $om->get( $rootId );
152            if ( $workflow instanceof Workflow ) {
153                /** @var UrlGenerator $urlGenerator */
154                $urlGenerator = Container::get( 'url_generator' );
155                return $urlGenerator->workflowLink(
156                    null,
157                    $rootId
158                )->getFullUrl();
159            } else {
160                return null;
161            }
162        } catch ( FlowException $e ) {
163            return null; // The UUID is invalid or has no root post.
164        }
165    }
166
167    /**
168     * Set redirect and return true if $data['uuid'] or $this->par exists and is
169     * a valid UUID; otherwise return false or a Status object encapsulating any
170     * error, which causes the form to be shown.
171     * @param array $data
172     * @return bool|Status
173     */
174    public function onSubmit( array $data ) {
175        if ( !empty( $data['type'] ) && !empty( $data['uuid'] ) ) {
176            $this->setParameter( $data['type'] . '/' . $data['uuid'] );
177        }
178
179        // Assume no data has been passed in if there is no UUID.
180        if ( $this->uuid === null ) {
181            return false; // Display the form.
182        }
183
184        switch ( $this->type ) {
185            case 'post':
186                $url = $this->getPostUrl();
187                break;
188            case 'workflow':
189                $url = $this->getWorkflowUrl();
190                break;
191            default:
192                $url = null;
193                break;
194        }
195
196        if ( $url ) {
197            $this->getOutput()->redirect( $url );
198            return true;
199        } else {
200            $this->getOutput()->setStatusCode( 404 );
201            return Status::newFatal( 'flow-special-invalid-uuid' );
202        }
203    }
204
205    protected function getGroupName() {
206        return 'redirects';
207    }
208}