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 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
MultiGetList
0.00% covered (danger)
0.00%
0 / 36
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 / 25
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( $multiRes, static fn ( $v ) => $v !== false );
58        foreach ( $multiRes as $key => $value ) {
59            $idx = $cacheKeys[$key];
60            if ( $idx instanceof UUID ) {
61                $idx = $idx->getAlphadecimal();
62            }
63            $result[$idx] = $value;
64            unset( $cacheKeys[$key] );
65        }
66
67        if ( count( $cacheKeys ) === 0 ) {
68            return $result;
69        }
70        $res = $loadCallback( array_values( $cacheKeys ) );
71        if ( !$res ) {
72            // storage failure of some sort
73            return $result;
74        }
75        $invCacheKeys = [];
76        foreach ( $cacheKeys as $cacheKey => $id ) {
77            if ( $id instanceof UUID ) {
78                $id = $id->getAlphadecimal();
79            }
80            $invCacheKeys[$id] = $cacheKey;
81        }
82        foreach ( $res as $id => $row ) {
83            $this->cache->set( $invCacheKeys[$id], $row );
84            $result[$id] = $row;
85        }
86
87        return $result;
88    }
89}