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