2016-11-29 22:27:19 +00:00
< ? php
2025-03-29 10:50:03 +00:00
2022-02-14 20:48:15 -08:00
/**
* Provides static methods to get and set configuration values from the `core/config.php` file .
2020-12-13 20:42:04 -08:00
*
2022-02-14 20:48:15 -08:00
* @ package NamelessMC\Core
* @ author Samerton
2022-06-13 02:21:21 +00:00
* @ version 2.0 . 0
2022-02-14 20:48:15 -08:00
* @ license MIT
2020-12-13 20:42:04 -08:00
*/
2024-03-09 03:19:55 -08:00
class Config
{
2022-06-13 02:21:21 +00:00
private static ? array $_config_cache = null ;
2022-08-06 00:59:54 -07:00
/**
* @ return bool Whether `/core` folder is writable to create `config.php` file in ,
2024-03-09 03:19:55 -08:00
* or if the file exists and is writable .
2022-08-06 00:59:54 -07:00
*/
2024-03-09 03:19:55 -08:00
public static function writeable () : bool
{
2022-08-06 00:59:54 -07:00
clearstatcache ();
if ( self :: exists ()) {
return is_writable ( ROOT_PATH . '/core/config.php' );
}
return is_writable ( ROOT_PATH . '/core' );
}
2022-06-13 02:21:21 +00:00
/**
* @ return bool Whether config file exists
*/
2024-03-09 03:19:55 -08:00
public static function exists () : bool
{
2022-06-13 02:21:21 +00:00
return file_exists ( ROOT_PATH . '/core/config.php' );
}
/**
2024-03-09 03:19:55 -08:00
* Read `core/config.php` file and load into cache .
2022-06-13 02:21:21 +00:00
*
* @ return array The entire config array
*/
2024-03-09 03:19:55 -08:00
public static function all () : array
{
2022-06-13 02:21:21 +00:00
if ( self :: $_config_cache !== null ) {
return self :: $_config_cache ;
}
if ( ! self :: exists ()) {
2022-08-29 23:59:19 +02:00
throw new RuntimeException ( 'Config file does not exist. If this happened during installation, please restart the installation in a new private/incognito browser window.' );
2022-06-13 02:21:21 +00:00
}
2022-08-06 00:59:54 -07:00
return self :: $_config_cache = require ( ROOT_PATH . '/core/config.php' );
2022-06-13 02:21:21 +00:00
}
/**
* Overwrite new `core/config.php` file .
*
* @ param array $config New config array to store .
*/
2024-03-09 03:19:55 -08:00
public static function write ( array $config ) : void
{
2022-08-06 00:59:54 -07:00
$contents = '<?php' . PHP_EOL . PHP_EOL . 'return ' . self :: arrayToString ( $config ) . ';' ;
2022-06-13 02:21:21 +00:00
if ( file_put_contents ( ROOT_PATH . '/core/config.php' , $contents ) === false ) {
throw new RuntimeException ( 'Failed to write to config file' );
}
if ( function_exists ( 'opcache_invalidate' )) {
opcache_invalidate ( ROOT_PATH . '/core/config.php' , true );
}
self :: $_config_cache = $config ;
}
2021-04-12 18:36:34 -07:00
/**
* Get a config value from `core/config.php` file .
2021-10-29 22:09:38 -07:00
*
2024-03-09 03:19:55 -08:00
* @ param string $path `.` seperated path of key to get from config file .
* @ param mixed $fallback Value to return if option is not present in config file . If set to null , false is returned .
2022-02-14 20:48:15 -08:00
* @ throws RuntimeException If the config file is not found .
2024-03-09 03:19:55 -08:00
* @ return false | mixed Returns false if key doesn ' t exist , otherwise returns the value .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public static function get ( string $path , $fallback = null )
{
2022-06-13 02:21:21 +00:00
$config = self :: all ();
2020-12-13 19:38:04 +01:00
2022-06-12 21:21:07 -06:00
$parsed_path = self :: parsePath ( $path );
2020-12-13 19:38:04 +01:00
2022-06-12 21:21:07 -06:00
if ( ! is_array ( $parsed_path )) {
return $config [ $parsed_path ] ? ? false ;
}
foreach ( $parsed_path as $bit ) {
2022-06-13 02:21:21 +00:00
if ( isset ( $config [ $bit ])) {
$config = $config [ $bit ];
} else {
$not_matched = true ;
2020-12-13 19:38:04 +01:00
}
2022-06-13 02:21:21 +00:00
}
2021-04-12 18:36:34 -07:00
2022-06-13 02:21:21 +00:00
if ( ! isset ( $not_matched )) {
return $config ;
2020-12-13 19:38:04 +01:00
}
2021-06-27 12:13:52 +01:00
2022-06-22 04:41:15 +00:00
return $fallback ? ? false ;
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
/**
* Write a value to `core/config.php` file .
2021-12-07 22:14:12 -08:00
*
2024-03-09 03:19:55 -08:00
* @ param string $key `.` seperated path of key to set .
* @ param mixed $value Value to set under $key .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public static function set ( string $key , $value ) : void
{
2022-06-13 02:21:21 +00:00
$config = self :: all ();
2020-12-13 19:38:04 +01:00
2022-06-12 20:35:45 -06:00
$path = self :: parsePath ( $key );
2020-12-13 19:38:04 +01:00
2020-12-13 20:42:04 -08:00
if ( ! is_array ( $path )) {
2022-06-13 02:21:21 +00:00
$config [ $key ] = $value ;
2020-12-13 19:38:04 +01:00
} else {
2022-06-13 02:21:21 +00:00
$loc = & $config ;
2021-12-07 20:51:29 -08:00
foreach ( $path as $step ) {
2020-12-13 19:38:04 +01:00
$loc = & $loc [ $step ];
}
2022-08-06 00:59:54 -07:00
// Check if it is a string here so that `null` is not converted to `''`
2022-08-06 20:34:26 +01:00
$loc = ! is_string ( $value ) ? $value : addslashes ( $value );
2020-12-13 19:38:04 +01:00
}
2022-07-21 17:10:47 +01:00
static :: write (( array ) $config );
2021-12-07 22:14:12 -08:00
}
2021-08-24 18:29:03 +01:00
/**
* Write multiple values to `core/config.php` file .
*
* @ param array $values Array of key / value pairs
*/
2024-03-09 03:19:55 -08:00
public static function setMultiple ( array $values ) : void
{
2022-06-13 02:21:21 +00:00
$config = self :: all ();
2021-08-24 18:29:03 +01:00
foreach ( $values as $key => $value ) {
2022-06-12 20:35:45 -06:00
$path = self :: parsePath ( $key );
2021-08-24 18:29:03 +01:00
if ( ! is_array ( $path )) {
2022-06-13 02:21:21 +00:00
$config [ $key ] = $value ;
2021-08-24 18:29:03 +01:00
} else {
2022-06-13 02:21:21 +00:00
$loc = & $config ;
2021-12-07 20:51:29 -08:00
foreach ( $path as $step ) {
2021-08-24 18:29:03 +01:00
$loc = & $loc [ $step ];
}
2022-08-06 20:34:26 +01:00
$loc = ! is_string ( $value ) ? $value : addslashes ( $value );
2021-08-24 18:29:03 +01:00
}
}
2022-07-21 17:10:47 +01:00
static :: write (( array ) $config );
2021-08-24 18:29:03 +01:00
}
2022-06-12 20:35:45 -06:00
/**
* Parse a string path to an array of config paths .
* Will log a warning if a legacy path ( using `/` is used ) .
*
2024-03-09 03:19:55 -08:00
* @ param string $path Path to parse .
2022-06-12 20:35:45 -06:00
* @ return string | array Path split into sections or plain string if no section seperator was found .
*/
2024-03-09 03:19:55 -08:00
private static function parsePath ( string $path )
{
2022-06-12 20:35:45 -06:00
if ( str_contains ( $path , '.' )) {
return explode ( '.' , $path );
}
// TODO: Remove for 2.1.0
if ( str_contains ( $path , '/' )) {
ErrorHandler :: logWarning ( " Legacy config path: { $path } . Please use periods to seperate paths. " );
2024-03-09 03:19:55 -08:00
2022-06-12 20:35:45 -06:00
return explode ( '/' , $path );
}
return $path ;
}
2022-06-22 04:41:15 +00:00
/**
* Converts an array to a string to be inserted into the config file , with shorthand array syntax .
*
* @ link https :// gist . github . com / Bogdaan / ffa287f77568fcbb4cffa0082e954022
2024-03-09 03:19:55 -08:00
* @ param array $config Config array to convert to string .
2022-06-22 04:41:15 +00:00
* @ return string PHP code for the config array
*/
2024-03-09 03:19:55 -08:00
private static function arrayToString ( array $config ) : string
{
2022-06-22 04:41:15 +00:00
$export = var_export ( $config , true );
$export = preg_replace ( " /^(' '*)(.*)/m " , '$1$1$2' , $export );
$array = preg_split ( " / \r \n | \n | \r / " , $export );
$array = preg_replace ([ " / \ s*array \ s \ ( $ / " , " / \ )(,)? $ / " , " / \ s=> \ s $ / " ], [ null , ']$1' , ' => [' ], $array );
2024-03-09 03:19:55 -08:00
return implode ( PHP_EOL , array_filter ([ '[' ] + ( $array ? : [])));
2022-06-22 04:41:15 +00:00
}
2017-02-21 13:36:45 +01:00
}