Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
ImportSource
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 11
380
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getScriptUser
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHeader
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTopics
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTopic
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
56
 getPost
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getThreadData
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getPageData
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getFromPage
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getApiKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getObjectKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Flow\Import\LiquidThreadsApi;
4
5use Flow\Import\IImportSource;
6use MediaWiki\User\User;
7
8class ImportSource implements IImportSource {
9    // Thread types defined by LQT which are returned via api
10    private const THREAD_TYPE_NORMAL = 0;
11    private const THREAD_TYPE_MOVED = 1;
12    private const THREAD_TYPE_DELETED = 2;
13    private const THREAD_TYPE_HIDDEN = 4;
14
15    /**
16     * @var ApiBackend
17     */
18    protected $api;
19
20    /**
21     * @var string
22     */
23    protected $pageName;
24
25    /**
26     * @var CachedThreadData
27     */
28    protected $threadData;
29
30    /**
31     * @var CachedPageData
32     */
33    protected $pageData;
34
35    /**
36     * @var int
37     */
38    protected $cachedTopics = 0;
39
40    /**
41     * @var User Used for scripted actions and occurances (such as suppression)
42     *  where the original user is not available.
43     */
44    protected $scriptUser;
45
46    /**
47     * @param ApiBackend $apiBackend
48     * @param string $pageName
49     * @param User $scriptUser
50     */
51    public function __construct( ApiBackend $apiBackend, $pageName, User $scriptUser ) {
52        $this->api = $apiBackend;
53        $this->pageName = $pageName;
54        $this->scriptUser = $scriptUser;
55
56        $this->threadData = new CachedThreadData( $this->api );
57        $this->pageData = new CachedPageData( $this->api );
58    }
59
60    /**
61     * Returns a system user suitable for assigning programatic actions to.
62     *
63     * @return User
64     */
65    public function getScriptUser() {
66        return $this->scriptUser;
67    }
68
69    /**
70     * @inheritDoc
71     */
72    public function getHeader() {
73        return new ImportHeader( $this->api, $this, $this->pageName );
74    }
75
76    /**
77     * @inheritDoc
78     */
79    public function getTopics() {
80        return new TopicIterator( $this, $this->threadData, $this->pageName );
81    }
82
83    /**
84     * @param int $id
85     * @return ImportTopic|null
86     */
87    public function getTopic( $id ) {
88        // reset our internal cached data every 100 topics. Otherwise imports
89        // of any considerable size will take up large amounts of memory for
90        // no reason, running into swap on smaller machines.
91        $this->cachedTopics++;
92        if ( $this->cachedTopics > 100 ) {
93            $this->threadData->reset();
94            $this->pageData->reset();
95            $this->cachedTopics = 0;
96        }
97
98        $data = $this->threadData->get( $id );
99        switch ( $data['type'] ) {
100            // Standard thread
101            case self::THREAD_TYPE_NORMAL:
102                $topic = new ImportTopic( $this, $data );
103                if ( $topic->isRedirectToFlow() ) {
104                    // This topic is was already imported in a previous run
105                    // so don't try to import it again
106                    return null;
107                }
108                return $topic;
109
110            // The topic no longer exists at the queried location, but
111            // a stub was left behind pointing to it. This modified
112            // version of ImportTopic gracefully adjusts the #REDIRECT
113            // into a template to keep a similar output to lqt.
114            case self::THREAD_TYPE_MOVED:
115                return new MovedImportTopic( $this, $data );
116
117            // To get these back from the api we would have to send the `showdeleted`
118            // query param.  As we are not requesting them, just ignore for now.
119            case self::THREAD_TYPE_DELETED:
120                return null;
121
122            // Was assigned but never used by LQT.
123            case self::THREAD_TYPE_HIDDEN:
124                return null;
125        }
126    }
127
128    /**
129     * @param int $id
130     * @return ImportPost
131     */
132    public function getPost( $id ) {
133        return new ImportPost( $this, $this->threadData->get( $id ) );
134    }
135
136    /**
137     * @param int $id
138     * @return array
139     */
140    public function getThreadData( $id ) {
141        if ( is_array( $id ) ) {
142            return $this->threadData->getMulti( $id );
143        } else {
144            return $this->threadData->get( $id );
145        }
146    }
147
148    /**
149     * @param int[]|int $pageIds
150     * @return array
151     */
152    public function getPageData( $pageIds ) {
153        if ( is_array( $pageIds ) ) {
154            return $this->pageData->getMulti( $pageIds );
155        } else {
156            return $this->pageData->get( $pageIds );
157        }
158    }
159
160    /**
161     * @param string $pageName
162     * @param int $startId
163     * @return array
164     */
165    public function getFromPage( $pageName, $startId = 0 ) {
166        return $this->threadData->getFromPage( $pageName, $startId );
167    }
168
169    /**
170     * Gets a unique identifier for the wiki being imported
171     * @return string Usually either a string 'local' or an API URL
172     */
173    public function getApiKey() {
174        return $this->api->getKey();
175    }
176
177    /**
178     * Returns a key uniquely representing an object determined by arguments.
179     * Parameters: Zero or more strings that uniquely represent the object
180     * for this ImportSource
181     *
182     * @param mixed ...$args
183     * @return string Unique key
184     */
185    public function getObjectKey( ...$args ): string {
186        return implode( ':', [ 'lqt-api', $this->getApiKey(), ...$args ] );
187    }
188}