Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
TopicIterator
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 7
182
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
 current
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 key
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 next
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
 rewind
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 valid
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 loadMore
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace Flow\Import\LiquidThreadsApi;
4
5use ArrayIterator;
6use Iterator;
7
8class TopicIterator implements Iterator {
9    /**
10     * @var ImportSource
11     */
12    protected $importSource;
13
14    /**
15     * @var CachedThreadData Access point for api data
16     */
17    protected $threadData;
18
19    /**
20     * @var int|false|null Lqt id of the current topic, false if no current topic, null if unknown.
21     */
22    protected $current = false;
23
24    /**
25     * @var ImportTopic The current topic.
26     */
27    protected $currentTopic = null;
28
29    /**
30     * @var string Name of the remote page the topics exist on
31     */
32    protected $pageName;
33
34    /**
35     * @var Iterator A list of topic ids.  Iterator used to simplify maintaining
36     *  an explicit position within the list.
37     */
38    protected $topicIdIterator;
39
40    /**
41     * @var int The maximum id received by self::loadMore
42     */
43    protected $maxId;
44
45    /**
46     * @param ImportSource $source
47     * @param CachedThreadData $threadData
48     * @param string $pageName
49     */
50    public function __construct( ImportSource $source, CachedThreadData $threadData, $pageName ) {
51        $this->importSource = $source;
52        $this->threadData = $threadData;
53        $this->pageName = $pageName;
54        $this->topicIdIterator = new ArrayIterator( $threadData->getTopics() );
55        $this->rewind();
56    }
57
58    /**
59     * @return ImportTopic|null
60     */
61    public function current() {
62        if ( $this->current === false ) {
63            return null;
64        }
65        return $this->currentTopic;
66    }
67
68    /**
69     * @return int
70     */
71    public function key() {
72        return $this->current;
73    }
74
75    public function next() {
76        if ( !$this->valid() ) {
77            return;
78        }
79
80        $lastOffset = $this->key();
81        do {
82            while ( $this->topicIdIterator->valid() ) {
83                $topicId = $this->topicIdIterator->current();
84                $this->topicIdIterator->next();
85
86                // this topic id has been seen before.
87                if ( $topicId <= $lastOffset ) {
88                    continue;
89                }
90
91                // hidden and deleted threads come back as null
92                $topic = $this->importSource->getTopic( $topicId );
93                if ( $topic === null ) {
94                    continue;
95                }
96
97                $this->current = $topicId;
98                $this->currentTopic = $topic;
99                return;
100            }
101        } while ( $this->loadMore() );
102
103        // nothing found, nothing more to load
104        $this->current = false;
105    }
106
107    public function rewind() {
108        $this->current = null;
109        $this->topicIdIterator->rewind();
110        $this->next();
111    }
112
113    /**
114     * @return bool
115     */
116    public function valid() {
117        return $this->current !== false;
118    }
119
120    /**
121     * @return bool True when more topics were loaded
122     */
123    protected function loadMore() {
124        try {
125            // + 1 to not return the existing max topic
126            $output = $this->threadData->getFromPage( $this->pageName, $this->maxId + 1 );
127        } catch ( ApiNotFoundException $e ) {
128            // No more results, end loop
129            return false;
130        }
131
132        $this->maxId = max( array_keys( $output ) );
133        $this->topicIdIterator = new ArrayIterator( $this->threadData->getTopics() );
134        $this->topicIdIterator->rewind();
135
136        // Keep looping until we get a not found error
137        return true;
138    }
139}