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