Skip to content

Instantly share code, notes, and snippets.

@sbrl
Last active March 5, 2018 17:59
Show Gist options
  • Save sbrl/8f8a7b9643443cbed3e7e583d2577b7f to your computer and use it in GitHub Desktop.
Save sbrl/8f8a7b9643443cbed3e7e583d2577b7f to your computer and use it in GitHub Desktop.
[JsonConfig] A simple PHP class to manage your app's settings. #settings #microlibrary
<?php
namespace SBRL\Utilities;
use \stdClass;
/**
* Handles the loading and saving of settings from a file.
* Supports loading default settings from a separate file.
* @author Starbeamrainbowlabs
* @version v0.2
* @lastModified 22nd March 2017
* @license https://www.mozilla.org/en-US/MPL/2.0/ Mozilla Public License 2.0
* Changelog:
* v0.3 - 5th March 2018
* Fix variable reference errors
* v0.2 - 22nd March 2017
* Add license
* Filled in some missing comments
* v0.1: 28th February 2017
* Initial release
*/
class JsonConfig
{
private $defaultSettings;
private $settingsFilePath = "";
/**
* The custom settings object.
* @var stdClass
*/
private $customSettings;
/**
* Creates a new JsonConfig
* @param string $settingsFilePath The path to the customised settings file.
* @param string $defaultSettingsFilePath The path to the default settings file.
*/
public function __construct($settingsFilePath, $defaultSettingsFilePath) {
$this->defaultSettings = json_decode(file_get_contents($defaultSettingsFilePath));
$this->settingsFilePath = $settingsFilePath;
$this->defaultSettingsFilePath = $defaultSettingsFilePath;
$this->customSettings = new stdClass();
if(file_exists($this->settingsFilePath)) {
$this->customSettings = json_decode(file_get_contents($this->settingsFilePath));
}
}
/**
* Gets the value identified by the specified property, in dotted notation (e.g. `Network.Firewalling.Ports.Http`)
* @param string $key The property, in dotted notation, to return.
* @return mixed The value odentified by the given dotted property notation.
*/
public function get($key) {
if(static::hasPropertyByPath($this->customSettings, $key)) {
return static::getPropertyByPath($this->customSettings, $key);
}
return static::getPropertyByPath($this->defaultSettings, $key);
}
/**
* Fetches the default value for the specified property, specified in dotted notation.
* @param string $key The key to fetch.
* @return mixed The default value of the property identified by the given dotted notation.
*/
public function getDefault($key) {
return static::getPropertyByPath($this->defaultSettings, $key);
}
/**
* Determines whether the given property has been customised or explicitly specified in the customised settings file.
* @param string $key The property, in dotted notation, to check.
* @return boolean Whether the specified properties file has been explicitly specified in the custom settings file.
*/
public function hasChanged($key) {
return static::hasPropertyByPath($this->customSettings, $key);
}
/**
* Sets the property identified by the specified dotted path.
* Does not re-save the properties back to disk!
* @param string $key The dotted path to update.
* @param mixed $value The value to set the property to.
* @return self This ConfigFile instance, to aid method chaining.
*/
public function set($key, $value) {
static::setPropertyByPath($this->customSettings, $key, $value);
}
/**
* Saves the customised settings back to the disk.
* @return boolean Whether the save was successful or not.
*/
public function save() {
return file_put_contents($this->settingsFilePath, json_encode($this->customSettings, JSON_PRETTY_PRINT));
}
/**
* Works out whether a given dotted path to a property exists on a given object.
* @param stdClass $obj The object to search.
* @param string $path The dotted path to search with. e.g. `Network.Firewall.OpenPorts`
* @return boolean Whether the given property is present in the given object.
*/
public static function hasPropertyByPath($obj, $path) {
$pathParts = explode(".", $path);
$subObj = $obj;
foreach($pathParts as $part) {
if(!isset($subObj->$part))
return false;
$subObj = $subObj->$part;
}
return true;
}
/**
* Returns the property identified by the given dotted path.
* If you're not sure whether a property exists or not, use static::hasPropertyByPath() first to check.
* @param stdClass $obj The object to fetch from.
* @param string $path The path to extract from the given object.
* @return mixed The property identified by the given object.
*/
public static function getPropertyByPath($obj, $path) {
$pathParts = explode(".", $path);
$subObj = $obj;
foreach($pathParts as $part) {
$subObj = $subObj->$part;
}
return $subObj;
}
/**
* Returns the property identified by the given dotted path.
* If you're not sure whether a property exists or not, use static::hasPropertyByPath() first to check.
* @param stdClass $obj The object to set the property on.
* @param string $path The path to set on the given object.
* @param mixed $value The value to set the given property to.
*/
public static function setPropertyByPath($obj, $path, $value) {
$pathParts = explode(".", $path);
$pathPartsCount = count($pathParts);
$subObj = $obj;
for($i = 0; $i < $pathPartsCount; $i++) {
// Set the property on the last iteration
if($i + 1 == $pathPartsCount) {
$subObj->$part = $value;
break;
}
// Create sub-objects if they dobn't exist already
if(!isset($subObj->$part)) {
$subObj->$part = new stdClass();
}
$subObj = $subObj->$part;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment