Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
PostRevisionTopicHistoryStorage
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 9
156
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
 find
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 findMulti
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 findDescendantQuery
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 getPrimaryKeyColumns
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 insert
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 update
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 remove
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 validate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Flow\Data\Storage;
4
5use Flow\Data\ObjectStorage;
6use Flow\Exception\DataModelException;
7use Flow\Model\UUID;
8use Flow\Repository\TreeRepository;
9
10/**
11 * Query-only storage implementation provides history of all post revisions in a topic.
12 */
13class PostRevisionTopicHistoryStorage implements ObjectStorage {
14
15    /**
16     * @var ObjectStorage
17     */
18    protected $postRevisionStorage;
19
20    /**
21     * @var TreeRepository
22     */
23    protected $treeRepository;
24
25    /**
26     * @param ObjectStorage $postRevisionStorage
27     * @param TreeRepository $treeRepo
28     */
29    public function __construct( ObjectStorage $postRevisionStorage, TreeRepository $treeRepo ) {
30        $this->postRevisionStorage = $postRevisionStorage;
31        $this->treeRepository = $treeRepo;
32    }
33
34    public function find( array $attributes, array $options = [] ) {
35        $multi = $this->findMulti( [ $attributes ], $options );
36        return $multi ? reset( $multi ) : [];
37    }
38
39    /**
40     * This is called with queries for 'topic_root_id': a "virtual" column that we'll
41     *   interpret.  Based on these root ids (=topic id), we'll fetch all post revisions inside
42     *   that topic.
43     * @param array $queries
44     * @param array $options
45     * @return array
46     */
47    public function findMulti( array $queries, array $options = [] ) {
48        foreach ( $queries as $idx => $query ) {
49            if ( isset( $query['topic_root_id'] ) ) {
50                $descendantQuery = $this->findDescendantQuery( $query );
51                unset( $query['topic_root_id'] );
52                $queries[$idx] = array_merge( $query, $descendantQuery );
53            }
54        }
55
56        return $this->postRevisionStorage->findMulti( $queries, $options );
57    }
58
59    /**
60     * All queries are for roots (guaranteed in findMulti), so anything that falls
61     * through and has to be queried from storage will actually need to be doing a
62     * special condition either joining against flow_tree_node or first collecting the
63     * subtree node lists and then doing a big IN condition
64     *
65     * This isn't a hot path (should be pre-populated into index) but we still don't want
66     * horrible performance
67     *
68     * @param array $query
69     * @return array
70     * @throws \Flow\Exception\InvalidInputException
71     */
72    protected function findDescendantQuery( array $query ) {
73        $roots = [ UUID::create( $query['topic_root_id'] ) ];
74        $nodeList = $this->treeRepository->fetchSubtreeNodeList( $roots );
75
76        /** @var UUID $topicRootId */
77        $topicRootId = UUID::create( $query['topic_root_id'] );
78        $nodes = $nodeList[$topicRootId->getAlphadecimal()];
79        return [
80            'rev_type_id' => UUID::convertUUIDs( $nodes ),
81        ];
82    }
83
84    public function getPrimaryKeyColumns() {
85        return [ 'topic_root_id' ];
86    }
87
88    public function insert( array $row ) {
89        // @phan-suppress-previous-line PhanPluginNeverReturnMethod LSP violation.
90        throw new DataModelException( __CLASS__ . ' does not support insert action', 'process-data' );
91    }
92
93    public function update( array $old, array $new ) {
94        // @phan-suppress-previous-line PhanPluginNeverReturnMethod LSP violation.
95        throw new DataModelException( __CLASS__ . ' does not support update action', 'process-data' );
96    }
97
98    public function remove( array $row ) {
99        // @phan-suppress-previous-line PhanPluginNeverReturnMethod LSP violation.
100        throw new DataModelException( __CLASS__ . ' does not support remove action', 'process-data' );
101    }
102
103    public function validate( array $row ) {
104        return true;
105    }
106}