Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
MultiGetList
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 3
210
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
 getByKey
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
90
1<?php
2
3namespace Flow\Repository;
4
5use Flow\Data\FlowObjectCache;
6use Flow\Exception\InvalidParameterException;
7use Flow\Model\UUID;
8
9class MultiGetList {
10
11    /**
12     * @var FlowObjectCache
13     */
14    protected $cache;
15
16    public function __construct( FlowObjectCache $cache ) {
17        $this->cache = $cache;
18    }
19
20    /**
21     * @param string $treeType
22     * @param array $ids
23     * @param callable $loadCallback
24     * @return array
25     * @throws InvalidParameterException
26     */
27    public function get( $treeType, array $ids, $loadCallback ) {
28        $cacheKeys = [];
29        foreach ( $ids as $id ) {
30            if ( $id instanceof UUID ) {
31                $cacheId = $id;
32            } elseif ( is_scalar( $id ) ) {
33                $cacheId = UUID::create( $id );
34            } else {
35                $type = get_debug_type( $id );
36                throw new InvalidParameterException( "Not scalar: $type" );
37            }
38            // @phan-suppress-next-line PhanTypeMismatchArgumentNullable
39            $cacheKeys[ TreeCacheKey::build( $treeType, $cacheId ) ] = $id;
40        }
41        return $this->getByKey( $cacheKeys, $loadCallback );
42    }
43
44    /**
45     * @param array $cacheKeys
46     * @param callable $loadCallback
47     * @return array
48     */
49    public function getByKey( array $cacheKeys, $loadCallback ) {
50        if ( !$cacheKeys ) {
51            return [];
52        }
53        $result = [];
54        $multiRes = $this->cache->getMulti( array_keys( $cacheKeys ) );
55        // Memcached BagOStuff only returns found keys, but the redis bag
56        // returns false for not found keys.
57        $multiRes = array_filter(
58            $multiRes,
59            static function ( $val ) {
60                return $val !== false;
61            }
62        );
63        foreach ( $multiRes as $key => $value ) {
64            $idx = $cacheKeys[$key];
65            if ( $idx instanceof UUID ) {
66                $idx = $idx->getAlphadecimal();
67            }
68            $result[$idx] = $value;
69            unset( $cacheKeys[$key] );
70        }
71
72        if ( count( $cacheKeys ) === 0 ) {
73            return $result;
74        }
75        $res = $loadCallback( array_values( $cacheKeys ) );
76        if ( !$res ) {
77            // storage failure of some sort
78            return $result;
79        }
80        $invCacheKeys = [];
81        foreach ( $cacheKeys as $cacheKey => $id ) {
82            if ( $id instanceof UUID ) {
83                $id = $id->getAlphadecimal();
84            }
85            $invCacheKeys[$id] = $cacheKey;
86        }
87        foreach ( $res as $id => $row ) {
88            $this->cache->set( $invCacheKeys[$id], $row );
89            $result[$id] = $row;
90        }
91
92        return $result;
93    }
94}