Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
TopicIterator
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 5
72
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
 setFrom
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 setTo
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 query
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
 transform
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Flow\Search\Iterators;
4
5use Flow\DbFactory;
6use Flow\Model\PostRevision;
7use Flow\Model\UUID;
8use Flow\Repository\RootPostLoader;
9use stdClass;
10
11class TopicIterator extends AbstractIterator {
12    /**
13     * @var PostRevision
14     */
15    protected $previous;
16
17    /**
18     * @var RootPostLoader
19     */
20    protected $rootPostLoader;
21
22    /**
23     * @var bool
24     */
25    public $orderByUUID = false;
26
27    /**
28     * @param DbFactory $dbFactory
29     * @param RootPostLoader $rootPostLoader
30     */
31    public function __construct( DbFactory $dbFactory, RootPostLoader $rootPostLoader ) {
32        parent::__construct( $dbFactory );
33        $this->rootPostLoader = $rootPostLoader;
34    }
35
36    /**
37     * Define where to start iterating (inclusive)
38     *
39     * We'll be querying the workflow table instead of the revisions table.
40     * Because it's possible to request only a couple of revisions (in between
41     * certain ids), we'll need to override the parent buildQueryConditions
42     * method to also work on the workflow table.
43     * A topic workflow is updated with a workflow_last_update_timestamp for
44     * every change made in the topic. Our UUIDs are sequential & time-based,
45     * so we can just query for workflows with a timestamp higher than the
46     * timestamp derived from the starting UUID and lower than the end UUID.
47     *
48     * @param UUID|null $revId
49     */
50    public function setFrom( UUID $revId = null ) {
51        $this->results = null;
52
53        unset( $this->conditions[0] );
54        if ( $revId !== null ) {
55            $this->conditions[0] = 'workflow_last_update_timestamp >= ' .
56                $this->dbr->addQuotes( $this->dbr->timestamp( $revId->getBinary() ) );
57        }
58    }
59
60    /**
61     * Define where to stop iterating (exclusive)
62     *
63     * We'll be querying the workflow table instead of the revisions table.
64     * Because it's possible to request only a couple of revisions (in between
65     * certain ids), we'll need to override the parent buildQueryConditions
66     * method to also work on the workflow table.
67     * A topic workflow is updated with a workflow_last_update_timestamp for
68     * every change made in the topic. Our UUIDs are sequential & time-based,
69     * so we can just query for workflows with a timestamp higher than the
70     * timestamp derived from the starting UUID and lower than the end UUID.
71     *
72     * @param UUID|null $revId
73     */
74    public function setTo( UUID $revId = null ) {
75        $this->results = null;
76
77        unset( $this->conditions[1] );
78        if ( $revId !== null ) {
79            $this->conditions[1] = 'workflow_last_update_timestamp < ' .
80                $this->dbr->addQuotes( $this->dbr->timestamp( $revId->getBinary() ) );
81        }
82    }
83
84    /**
85     * Instead of querying for revisions (which is what we actually need), we'll
86     * just query the workflow table, which will save us some complicated joins.
87     * The workflow_id for a topic title (aka root post) is the same as its
88     * collection id, so we can pass that to the root post loader and *poof*, we
89     * have our revisions!
90     *
91     * @inheritDoc
92     */
93    protected function query() {
94        if ( $this->orderByUUID ) {
95            $order = 'workflow_id ASC';
96        } else {
97            $order = 'workflow_last_update_timestamp ASC';
98        }
99        return $this->dbr->select(
100            [ 'flow_workflow' ],
101            // for root post (topic title), workflow_id is the same as its rev_type_id
102            [ 'workflow_id', 'workflow_last_update_timestamp' ],
103            [
104                'workflow_type' => 'topic'
105            ] + $this->conditions,
106            __METHOD__,
107            [
108                'ORDER BY' => $order,
109            ]
110        );
111    }
112
113    /**
114     * @inheritDoc
115     */
116    protected function transform( stdClass $row ) {
117        $root = UUID::create( $row->workflow_id );
118
119        // we need to fetch all data via rootloader because we'll want children
120        // to be populated
121        return $this->rootPostLoader->get( $root );
122    }
123}