Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ExternalStoreMemory
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 5
156
0.00% covered (danger)
0.00%
0 / 1
 fetchFromURL
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 batchFetchFromURLs
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 store
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 clear
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 getURLComponents
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21/**
22 * External storage in PHP process memory for testing.
23 *
24 * In this system, each store "location" is separate PHP array.
25 * URLs are of the form "memory://location/id". The id/value pairs
26 * at each location are segregated by DB domain ID.
27 *
28 * @see ExternalStoreAccess
29 * @ingroup ExternalStorage
30 * @since 1.33
31 */
32class ExternalStoreMemory extends ExternalStoreMedium {
33    /** @var array[] Map of (location => DB domain => id => value) */
34    private static $data = [];
35    /** @var int */
36    private static $nextId = 0;
37
38    public function fetchFromURL( $url ) {
39        [ $location, $id ] = self::getURLComponents( $url );
40        if ( $id === null ) {
41            throw new UnexpectedValueException( "Missing ID in URL component." );
42        }
43
44        return self::$data[$location][$this->dbDomain][$id] ?? false;
45    }
46
47    public function batchFetchFromURLs( array $urls ) {
48        $blobs = [];
49        foreach ( $urls as $url ) {
50            $blob = $this->fetchFromURL( $url );
51            if ( $blob !== false ) {
52                $blobs[$url] = $blob;
53            }
54        }
55
56        return $blobs;
57    }
58
59    public function store( $location, $data ) {
60        $index = ++self::$nextId;
61        self::$data[$location][$this->dbDomain][$index] = $data;
62
63        return "memory://$location/$index";
64    }
65
66    /**
67     * Remove all data from memory for this domain
68     */
69    public function clear() {
70        foreach ( self::$data as &$dataForLocation ) {
71            unset( $dataForLocation[$this->dbDomain] );
72        }
73        unset( $dataForLocation );
74        self::$data = array_filter( self::$data, 'count' );
75        self::$nextId = 0;
76    }
77
78    /**
79     * @param string $url
80     * @return array (location, ID or null)
81     */
82    private function getURLComponents( $url ) {
83        // @phan-suppress-next-line PhanSuspiciousBinaryAddLists It's intentional
84        [ $proto, $path ] = explode( '://', $url, 2 ) + [ null, null ];
85        if ( $proto !== 'memory' ) {
86            throw new UnexpectedValueException( "Got URL of protocol '$proto', not 'memory'." );
87        } elseif ( $path === null ) {
88            throw new UnexpectedValueException( "URL is missing path component." );
89        }
90
91        $parts = explode( '/', $path );
92        if ( count( $parts ) > 2 ) {
93            throw new UnexpectedValueException( "Too components in URL '$path'." );
94        }
95
96        return [ $parts[0], $parts[1] ?? null ];
97    }
98}