404 lines
14 KiB
PHP
404 lines
14 KiB
PHP
<?php
|
|
|
|
namespace BRSystems\Core\Library\cINI;
|
|
|
|
use BRSystems\Core\Library\cJSON\cJSON;
|
|
|
|
/**
|
|
* initialization file handler
|
|
*
|
|
* @category LIB INI
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @since Version 1.0.1
|
|
*/
|
|
class cINI
|
|
{
|
|
private $_read_only = true;
|
|
private $_nLine = "\r\n";
|
|
private $_ini_data;
|
|
private $_ini_file;
|
|
|
|
const key_clone = '%CLONE%';
|
|
const key_empty = '%E%';
|
|
const key_comment = '%C%';
|
|
|
|
/**
|
|
* Class constructor
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category LIB INI
|
|
* @param string|bool $sFileName - ini file name
|
|
* @param string|bool $readOnly - readonly mode
|
|
*/
|
|
public function __construct($sFileName = false, $readOnly = true)
|
|
{
|
|
$this->_ini_data = [];
|
|
if ($sFileName) $this->loadIni($sFileName, $readOnly);
|
|
$this->_read_only = $readOnly;
|
|
|
|
if (
|
|
isset($_SERVER['HTTP_USER_AGENT'])
|
|
&& strpos(strtolower($_SERVER['HTTP_USER_AGENT']), "windows", 0) === false
|
|
) {
|
|
$this->_nLine = "\n";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to read INI into array
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category LIB INI
|
|
* @param string|bool $sFileName - ini file name
|
|
* @param bool $readOnly - readonly mode
|
|
* @return bool - status if load successful
|
|
*/
|
|
public function loadIni($sFileName = false, $readOnly = true){
|
|
|
|
// Load data from ini
|
|
if(file_exists($sFileName) && is_readable($sFileName)){
|
|
$this->_ini_file = $sFileName;
|
|
$this->_read_only = $readOnly;
|
|
if($readOnly){
|
|
$this->_ini_data = parse_ini_file($sFileName, true);
|
|
}else{
|
|
$this->customINIRead($sFileName);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Function to read INI into array
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category LIB INI
|
|
* @param string|bool $sFileName - ini file name
|
|
* @return bool - status if load successful
|
|
*/
|
|
private function customINIRead($sFileName){
|
|
|
|
|
|
$sSection = "";
|
|
$this->_ini_data = array();
|
|
|
|
// Open file
|
|
$oFile = @fopen($sFileName, "r");
|
|
while(!feof($oFile)){
|
|
|
|
// Read each line
|
|
$sLine = trim(@fgets($oFile));
|
|
$len = strlen($sLine);
|
|
|
|
if($len == 0){
|
|
// Save blank spaces
|
|
if($sSection)
|
|
$this->_ini_data[$sSection]['d'][] = self::key_empty;
|
|
else
|
|
$this->_ini_data[] = self::key_empty;
|
|
}else{
|
|
if($sLine[0] == ';'){
|
|
// Save full row comments
|
|
if($sSection)
|
|
$this->_ini_data[$sSection]['d'][$sLine] = self::key_comment;
|
|
else
|
|
$this->_ini_data[$sLine] = self::key_comment;
|
|
}else{
|
|
$sComment = '';
|
|
// Check if row has comments
|
|
$pos = strpos($sLine,';');
|
|
if($pos != false){
|
|
// Remove comment from line
|
|
$sComment = trim(substr($sLine, $pos));
|
|
$sLine = trim(substr($sLine, 0, $pos-1));
|
|
$len = strlen($sLine);
|
|
}
|
|
|
|
// Check for section
|
|
if(($sLine[0] == '[') && ($sLine[$len-1] == ']')){
|
|
$sSection = substr($sLine,1,$len-2);
|
|
if(!isset($this->_ini_data[$sSection]))
|
|
$this->_ini_data[$sSection] = array(
|
|
'd' => array(),
|
|
'c' => $sComment,
|
|
);
|
|
continue;
|
|
}
|
|
// Separate var name from value
|
|
$t = explode("=", $sLine);
|
|
if(!!$t && count($t) > 1){
|
|
$sVar = trim($t[0]);
|
|
$sVal = trim(trim($t[1]), "'\"");
|
|
|
|
// Check for multidimensional subs
|
|
$pos = strpos($sVar, '[');
|
|
if($pos != false){
|
|
$sSubsection = trim(substr($sVar, 0, $pos));
|
|
$sVar = trim(substr($sVar, $pos+1, strlen($sVar)-$pos-2));
|
|
|
|
// Add values
|
|
if($sSection)
|
|
if($sVar)
|
|
$this->_ini_data[$sSection]['d'][$sSubsection][$sVar] = array(
|
|
'v' => $sVal,
|
|
'c' => $sComment,
|
|
);
|
|
else
|
|
$this->_ini_data[$sSection]['d'][$sSubsection][] = array(
|
|
'v' => $sVal,
|
|
'c' => $sComment,
|
|
);
|
|
else
|
|
$this->_ini_data[$sSubsection] = array(
|
|
$sVar => array(
|
|
'v' => $sVal,
|
|
'c' => $sComment,
|
|
)
|
|
);
|
|
|
|
// No subsection found
|
|
}else{
|
|
if($sSection)
|
|
$this->_ini_data[$sSection]['d'][$sVar] = array(
|
|
'v' => $sVal,
|
|
'c' => $sComment,
|
|
);
|
|
else
|
|
$this->_ini_data[$sVar] = array(
|
|
'v' => $sVal,
|
|
'c' => $sComment,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Close file
|
|
@fclose($oFile);
|
|
}
|
|
|
|
/**
|
|
* Function to get section variable
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category LIB INI
|
|
* @param string $sSection - section name
|
|
* @param string $sKey - variable key name
|
|
* @param bool $bJSONDecode - decode via JOSN decode
|
|
* @return mixed - found value/s
|
|
*/
|
|
public function getV($sSection, $sKey, $bJSONDecode = false){
|
|
|
|
if($sSection && $sKey && !!$this->_ini_data){
|
|
if($this->_read_only){
|
|
if(!empty($this->_ini_data[$sSection][$sKey])){
|
|
if(!$bJSONDecode) return $this->_ini_data[$sSection][$sKey];
|
|
else return cJSON::decode($this->_ini_data[$sSection][$sKey], true);
|
|
}
|
|
}else{
|
|
if(!empty($this->_ini_data[$sSection]['d'][$sKey])){
|
|
// Check if key found
|
|
if(isset($this->_ini_data[$sSection]['d'][$sKey]['v'])){
|
|
if(!$bJSONDecode) return $this->_ini_data[$sSection]['d'][$sKey]['v'];
|
|
else return cJSON::decode($this->_ini_data[$sSection]['d'][$sKey]['v'], true);
|
|
}else{
|
|
$data = array();
|
|
foreach($this->_ini_data[$sSection]['d'][$sKey] as $k=>$v)
|
|
$data[$k] = $v['v'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Function to set section variable
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category LIB INI
|
|
* @param string $sKey - variable key name
|
|
* @param string $sVal - variable value
|
|
* @param string|bool $sSection - section name
|
|
* @param string|bool $sComment - comment
|
|
* @return mixed - found value/s
|
|
*/
|
|
public function setV($sKey, $sVal, $sSection = false, $sComment = false){
|
|
|
|
$bBefore = true;
|
|
if($sKey && $sVal){
|
|
if(!$this->_read_only){
|
|
$dataArray = &$this->_ini_data;
|
|
if($sSection){
|
|
$bBefore = false;
|
|
if(!isset($this->_ini_data[$sSection]['d']))
|
|
$this->_ini_data[$sSection]['d'] = array();
|
|
$dataArray = &$this->_ini_data[$sSection]['d'];
|
|
|
|
|
|
// Subsection support to be added
|
|
}
|
|
if($bBefore)
|
|
$dataArray = array($sKey => array('v' => $sVal)) + $dataArray;
|
|
else
|
|
$dataArray[$sKey]['v'] = $sVal;
|
|
if($sComment)
|
|
$dataArray[$sKey]['c'] = "; {$sComment}";
|
|
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Function to get section variable
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category LIB INI
|
|
* @param array $sSectionDirectLoad - section to direct setup ar constants
|
|
* @param array $sDomains - domain name constant setup
|
|
* @return void
|
|
*/
|
|
public function loadSystemConstants($sSectionDirectLoad = array('system', 'version_control'), $sDomains = array('domain_cfg', 'domain_cfg_json')){
|
|
|
|
if($this->_read_only){
|
|
if(!!$sDomains){
|
|
foreach($sDomains as $v){
|
|
if(!empty($this->_ini_data[$v])){
|
|
$domain_cfg = &$this->_ini_data[$v];
|
|
|
|
// use default in case no HOST found - cron for example
|
|
$sHostKey = (!empty($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'default');
|
|
|
|
if(!empty($domain_cfg[$sHostKey])){
|
|
$connection_cfg = &$domain_cfg[$sHostKey];
|
|
if(substr($v, -5) == '_json') {
|
|
if(substr($connection_cfg,0,6) == 'clone:'){
|
|
$sHostKeyClone = substr($connection_cfg, 6);
|
|
if(!empty($domain_cfg[$sHostKeyClone]))
|
|
$domain_cfg[$sHostKey] = $domain_cfg[$sHostKeyClone];
|
|
}
|
|
if(!empty($domain_cfg[$sHostKey]))
|
|
$domain_cfg[$sHostKey] = cJSON::decode($domain_cfg[$sHostKey], true);
|
|
}
|
|
foreach($domain_cfg[$sHostKey] as $k => $vv)
|
|
if(!defined($k))
|
|
define($k, $vv);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!!$sSectionDirectLoad){
|
|
foreach($sSectionDirectLoad as $v){
|
|
if(!empty($this->_ini_data[$v]))
|
|
foreach($this->_ini_data[$v] as $k=>$vv)
|
|
if(!defined($k))
|
|
define($k, $vv);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Function to write ini data to file
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category LIB INI
|
|
* @param string|bool $newFile - new file path
|
|
* @return mixed
|
|
*/
|
|
public function writeDataToFile($newFile = false){
|
|
|
|
if($this->_read_only)
|
|
return false;
|
|
|
|
$spLen = 45;
|
|
$spSecLen = 45;
|
|
$sFileContent = "";
|
|
$num_regex = "/^[\-\+]?[\d\,]*\.?[\d]*$/";
|
|
|
|
if(!!$this->_ini_data){
|
|
foreach($this->_ini_data as $k=>$v){
|
|
|
|
// Comment found
|
|
if($v == self::key_comment){
|
|
$sFileContent .= "{$k}{$this->_nLine}";
|
|
continue;
|
|
}
|
|
// Empty line found
|
|
if($v == self::key_empty){
|
|
$sFileContent .= "{$this->_nLine}";
|
|
continue;
|
|
}
|
|
|
|
// New section found
|
|
if(!!$v && !empty($v['d'])){
|
|
// Add section
|
|
$sLine = "[{$k}]";
|
|
if(isset($v['c']) && $v['c'])
|
|
$sLine = str_pad($sLine, $spSecLen) . $v['c'];
|
|
$sFileContent .= "{$sLine}{$this->_nLine}";
|
|
|
|
foreach($v['d'] as $kk=>$vv){
|
|
|
|
// Comment found
|
|
if($vv == self::key_comment){
|
|
$sFileContent .= "{$kk}{$this->_nLine}";
|
|
continue;
|
|
}
|
|
// Empty line found
|
|
if($vv == self::key_empty){
|
|
$sFileContent .= "{$this->_nLine}";
|
|
continue;
|
|
}
|
|
|
|
// Write each section variable
|
|
if(isset($vv['v'])){
|
|
|
|
$sLine = "{$kk} = " . (!preg_match($num_regex, $vv['v']) ? "'{$vv['v']}'" : $vv['v']);
|
|
if(isset($vv['c']) && $vv['c'])
|
|
$sLine = str_pad($sLine, $spLen) . $vv['c'];
|
|
|
|
$sFileContent .= "{$sLine}{$this->_nLine}";
|
|
|
|
// Write each subsection variable
|
|
}elseif(is_array($vv)){
|
|
foreach($vv as $kkk=>$vvv){
|
|
|
|
$sLine = "{$kk}[{$kkk}] = " . (!preg_match($num_regex, $vvv['v']) ? "'{$vvv['v']}'" : $vvv['v']);
|
|
if($vvv['c'])
|
|
$sLine = str_pad($sLine, $spLen) . $vvv['c'];
|
|
|
|
$sFileContent .= "{$sLine}{$this->_nLine}";
|
|
}
|
|
}
|
|
|
|
}
|
|
}else{
|
|
$sFileContent .= "{$k} = " . (!preg_match($num_regex, $v['v']) ? "'{$v['v']}'" : $v['v']) . "{$v['c']}{$this->_nLine}";
|
|
}
|
|
}
|
|
}
|
|
if(!$newFile)
|
|
$newFile = $this->_ini_file;
|
|
|
|
// Replace all ending empty new lines
|
|
$sFileContent = preg_replace('/[\r\n]*$/','', $sFileContent) . $this->_nLine;
|
|
|
|
if(file_exists($newFile) && is_writable($newFile) || !file_exists($newFile)){
|
|
$oFile = @fopen($newFile, "w+");
|
|
@fwrite($oFile, $sFileContent);
|
|
@fclose($oFile);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|