Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
57.14% covered (warning)
57.14%
16 / 28
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
PhpSettingsSource
57.14% covered (warning)
57.14%
16 / 28
25.00% covered (danger)
25.00%
1 / 4
15.38
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 load
60.00% covered (warning)
60.00%
15 / 25
0.00% covered (danger)
0.00%
0 / 1
8.30
 __toString
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 locateInclude
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Settings\Source;
4
5use MediaWiki\Settings\SettingsBuilderException;
6use Wikimedia\AtEase\AtEase;
7
8/**
9 * Settings loaded from a PHP file path as an array structure.
10 *
11 * @since 1.38
12 */
13class PhpSettingsSource implements SettingsSource, SettingsIncludeLocator {
14    /**
15     * Path to the PHP file.
16     * @var string
17     */
18    private $path;
19
20    /**
21     * @param string $path
22     */
23    public function __construct( string $path ) {
24        $this->path = $path;
25    }
26
27    /**
28     * Loads an array structure from a PHP file and return
29     * for using with merge strategies to apply on configs.
30     *
31     * @throws SettingsBuilderException
32     * @return array
33     */
34    public function load(): array {
35        // NOTE: try include first, for performance reasons. If all goes well, it will
36        //       use the opcode cache, and will not touch the file system at all.
37        //       So we should only go and look at the file system if the include fails.
38
39        $source = AtEase::quietCall( static function ( $path ) {
40            return include $path;
41        }, $this->path );
42
43        if ( $source === false ) {
44            if ( !file_exists( $this->path ) ) {
45                throw new SettingsBuilderException(
46                    "'File: {path}' does not exist",
47                    [ 'path' => $this->path ]
48                );
49            }
50
51            if ( !is_readable( $this->path ) ) {
52                throw new SettingsBuilderException(
53                    "File '{path}' is not readable",
54                    [ 'path' => $this->path ]
55                );
56            }
57
58            if ( is_dir( $this->path ) ) {
59                throw new SettingsBuilderException(
60                    "'{path}' is a directory, not a file",
61                    [ 'path' => $this->path ]
62                );
63            }
64        }
65
66        if ( !is_array( $source ) ) {
67            throw new SettingsBuilderException(
68                "File '{path}' did not return an array",
69                [ 'path' => $this->path ]
70            );
71        }
72
73        return $source;
74    }
75
76    /**
77     * Returns this file source as a string.
78     *
79     * @return string
80     */
81    public function __toString(): string {
82        return $this->path;
83    }
84
85    public function locateInclude( string $location ): string {
86        return SettingsFileUtils::resolveRelativeLocation( $location, dirname( $this->path ) );
87    }
88
89}