Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 57
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
TopicFormatter
0.00% covered (danger)
0.00%
0 / 57
0.00% covered (danger)
0.00%
0 / 6
210
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setContentFormat
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEmptyResult
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 formatApi
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
56
 buildApiActions
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 generateTopicMetadata
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace Flow\Formatter;
4
5use Flow\Model\UUID;
6use Flow\Model\Workflow;
7use Flow\UrlGenerator;
8use IContextSource;
9
10class TopicFormatter {
11    /**
12     * @var UrlGenerator
13     */
14    protected $urlGenerator;
15
16    /**
17     * @var RevisionFormatter
18     */
19    protected $serializer;
20
21    public function __construct( UrlGenerator $urlGenerator, RevisionFormatter $serializer ) {
22        $this->urlGenerator = $urlGenerator;
23        $this->serializer = $serializer;
24    }
25
26    public function setContentFormat( $contentFormat, UUID $revisionId = null ) {
27        $this->serializer->setContentFormat( $contentFormat, $revisionId );
28    }
29
30    public function getEmptyResult( Workflow $workflow ) {
31        return [
32            'workflowId' => $workflow->getId()->getAlphadecimal(),
33            'type' => 'topic',
34            'roots' => [],
35            'posts' => [],
36            'revisions' => [],
37            'links' => [],
38            'actions' => $this->buildApiActions( $workflow ),
39        ];
40    }
41
42    public function formatApi( Workflow $listWorkflow, array $found, IContextSource $ctx ) {
43        $roots = $revisions = $posts = $replies = [];
44        foreach ( $found as $formatterRow ) {
45            $serialized = $this->serializer->formatApi( $formatterRow, $ctx );
46            if ( !$serialized ) {
47                continue;
48            }
49            $revisions[$serialized['revisionId']] = $serialized;
50            $posts[$serialized['postId']][] = $serialized['revisionId'];
51            if ( $serialized['replyToId'] ) {
52                $replies[$serialized['replyToId']][] = $serialized['postId'];
53            } else {
54                $roots[] = $serialized['postId'];
55            }
56        }
57
58        foreach ( $revisions as $i => $serialized ) {
59            $alpha = $serialized['postId'];
60            $revisions[$i]['replies'] = $replies[$alpha] ?? [];
61        }
62
63        $alpha = $listWorkflow->getId()->getAlphadecimal();
64        $workflows = [ $alpha => $listWorkflow ];
65        if ( isset( $posts[$alpha] ) ) {
66            // Metadata that requires everything to be serialized first
67            $metadata = $this->generateTopicMetadata( $posts, $revisions, $workflows, $alpha );
68            foreach ( $posts[$alpha] as $revId ) {
69                $revisions[$revId] += $metadata;
70            }
71        }
72
73        return [
74            'roots' => $roots,
75            'posts' => $posts,
76            'revisions' => $revisions,
77        ] + $this->getEmptyResult( $listWorkflow );
78    }
79
80    protected function buildApiActions( Workflow $workflow ) {
81        return [
82            'newtopic' => [
83                'url' => $this->urlGenerator
84                    ->newTopicAction( $workflow->getArticleTitle(), $workflow->getId() )
85            ],
86        ];
87    }
88
89    /**
90     * @param array $posts Map from alphadecimal postId to list of alphadecimal revisionId's
91     *  for that postId contained within $revisions.
92     * @param array $revisions Map from alphadecimal revisionId to serialized representation
93     *  of that revision.
94     * @param Workflow[] $workflows Map from alphadecimal workflowId to Workflow instance
95     * @param string $postAlphaId PostId of the topic title
96     * @return array
97     */
98    protected function generateTopicMetadata( array $posts, array $revisions, array $workflows, $postAlphaId ) {
99        $replies = -1;
100        $authors = [];
101        $stack = new \SplStack;
102        $stack->push( $revisions[$posts[$postAlphaId][0]] );
103        do {
104            $data = $stack->pop();
105            $replies++;
106            $authors[] = $data['creator']['name'];
107            foreach ( $data['replies'] as $postId ) {
108                $stack->push( $revisions[$posts[$postId][0]] );
109            }
110        } while ( !$stack->isEmpty() );
111
112        $workflow = $workflows[$postAlphaId] ?? null;
113
114        return [
115            'reply_count' => $replies,
116            // ms timestamp
117            'last_updated' => $workflow ? (int)$workflow->getLastUpdatedObj()->getTimestamp() * 1000 : null,
118        ];
119    }
120}