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 Stringable;
7
8/**
9 * Settings loaded from a PHP file path as an array structure.
10 *
11 * @since 1.38
12 */
13class PhpSettingsSource implements Stringable, SettingsSource, SettingsIncludeLocator {
14    /**
15     * Path to the PHP file.
16     * @var string
17     */
18    private $path;
19
20    public function __construct( string $path ) {
21        $this->path = $path;
22    }
23
24    /**
25     * Loads an array structure from a PHP file and return
26     * for using with merge strategies to apply on configs.
27     *
28     * @throws SettingsBuilderException
29     * @return array
30     */
31    public function load(): array {
32        // NOTE: try include first, for performance reasons. If all goes well, it will
33        //       use the opcode cache, and will not touch the file system at all.
34        //       So we should only go and look at the file system if the include fails.
35
36        // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
37        $source = @( static function ( $path ) {
38            return include $path;
39        } )( $this->path );
40
41        if ( $source === false ) {
42            if ( !file_exists( $this->path ) ) {
43                throw new SettingsBuilderException(
44                    "'File: {path}' does not exist",
45                    [ 'path' => $this->path ]
46                );
47            }
48
49            if ( !is_readable( $this->path ) ) {
50                throw new SettingsBuilderException(
51                    "File '{path}' is not readable",
52                    [ 'path' => $this->path ]
53                );
54            }
55
56            if ( is_dir( $this->path ) ) {
57                throw new SettingsBuilderException(
58                    "'{path}' is a directory, not a file",
59                    [ 'path' => $this->path ]
60                );
61            }
62        }
63
64        if ( !is_array( $source ) ) {
65            throw new SettingsBuilderException(
66                "File '{path}' did not return an array",
67                [ 'path' => $this->path ]
68            );
69        }
70
71        return $source;
72    }
73
74    /**
75     * Returns this file source as a string.
76     */
77    public function __toString(): string {
78        return $this->path;
79    }
80
81    public function locateInclude( string $location ): string {
82        return SettingsFileUtils::resolveRelativeLocation( $location, dirname( $this->path ) );
83    }
84
85}