⬆️ ⬇️

Class for editing configuration files

In any web project configuration files are used. Most often, they are edited at the development stage or project transfer and then remain intact for a long time. But it happens that the config grows and parameters appear in it that have to be changed more often.

The task is quite trivial, to create a form that allows you to change the values ​​of some parameters and bring changes to the existing file. But when you often encounter the same type of task, you want to find some more or less universal solution so as not to write a dull bicycle every time.



Unfortunately, Google did not give a simple and functional solution, I don’t know if Google can hurt me for something :). Perhaps there is some solution, but I have not found a suitable one. Please do not swear much, if one does exist. I thought about it, but whatever functionality it would suit me.



Firstly, this is the output for editing only those parameters that are needed, and secondly, for some parameters to be displayed as checkboxes, radio buttons, if that fits their logic, well, it would not hurt that the parameters have a nice name for the output.



If it is clear from this:

')



You could get this:





In this case, everything was simple and reliable.



And so we begin. Configuration files often take the form of a php file with definitions of different variable constants and so on. Such a format is difficult for someone to edit with confidence, a much simpler and no less common format is when the entire configuration file is an array of data. Here you can come up with something. We will work with a maximum of two-dimensional arrays, for more depth I don’t think that the solution will be universal. In addition, the config may contain such complex data, but their editing will not be possible.



The second level data is displayed in a separate fieldset block, which allows you to visually distinguish between different sets of parameters, and this block can be minimized by a mouse click.



In order not to change the data of the array to be able to somehow describe it, we will use the usual php comments. Comments that will be on the same line as the value will describe it and create a specific behavior when creating the form. Firstly, this is a more meaningful name for the fields. We look for regular expressions for comments on the same line as the field definition.



// Parse atributes of values from config file public function getAtributes() { $conf_str = file_get_contents($this->file_name); foreach ($this->data as $n => $cf) { // First level of array if (preg_match("#" . $n . "[^\r\n]*//([^\n\r]+)[\n\r]#", $conf_str, $m)) { $this->atribute[$n] = trim($m[1]); } if (is_array($cf)) { //second level foreach ($cf as $ns => $vs) { if (preg_match("#" . $n . ".*" . $ns . "[^\r\n]*=>[^\r\n]*//([^\n\r]+)[\n\r]#isU", $conf_str, $m)) { $this->atribute[$n . "~" . $ns] = trim($m[1]); } } } } } 


we save all the data and will display in the form only those that have a description.

Further it would not be bad in this description to be able to enter some keys that will affect the type of the displayed form element. For example, to set valid values ​​for the current parameter, the format was chosen as [options | val1 | ... | val].



Parsim received comments, again regular to extract a list of values ​​from them. I decided not to add the ability to specify which type of input should be displayed, it all logically proceeds from the suggested values. If there are only 2 values ​​and they are both of Boolean type, then you can display the checkbox, if there are more values, then we output the radio buttons, and if there are a lot of them, then we draw select. For fields that do not have any options, display the universal text input.



  // Parsing options from values atribute public function parseAtribute($atribute) { $flags = array(); $flags['title'] = $atribute; //can't delete this value if (strpos($atribute, "[static]") !== false) { $flags['static'] = true; } else { $flags['static'] = false; } //can add values in this sub array if (strpos($atribute, "[dinamic]") !== false) { $flags['dinamic'] = true; } //toggled block by default if (strpos($atribute, "[hidden]") !== false) { $flags['hidden'] = true; } else { $flags['hidden'] = false; } //parsing options that can by values for curent input //select type of input if (strpos($atribute, "[options") !== false) { preg_match("#\[options\|(.+)+\]#", $atribute, $options); $options = explode("|", $options[1]); if (sizeof($options) == 2) { // if have 2 options and both its from boolean type $checkbox = true; foreach ($options as $od) { if (!in_array($od, $this->booleanValues(), true)) { $checkbox = false; } } if ($checkbox) { $flags['options']['type'] = "checkbox"; } else { $flags['options']['type'] = "radio"; } } elseif (sizeof($options) < $this->optForSelect) { $flags['options']['type'] = "radio"; } else { $flags['options']['type'] = "select"; } $flags['options']['data'] = $options; // parse labels for values and clear data foreach ($options as $n => $v) { if (preg_match("#(.*)\((.*)\)#", $v, $m)) { $flags['options']['data'][$n] = trim($m[1]); $flags['options']['labels'][$n] = $m[2]; } } } else { $flags['options'] = false; } // clear title of input $flags['title'] = trim(preg_replace("#\[[^\[\]]*\]#", "", $flags['title'])); return $flags; } 


In the variants of values, you can specify beautiful names in the usual brackets so that when creating lists or buttons to display them and not lifeless, dry digits like 0,1,2. Unfortunately, this format does not make it possible to make variants of values ​​containing the characters of brackets "(" and ")".



It was necessary to tinker a lot with the processing of checkboxes, the value either “on” or even empty is transferred from them. You have to compare with the list of collected attributes and handle the empty value as a Boolean zero. The properties of the class trueValues ​​and falseValues ​​contain values ​​that can be interpreted in the binary sense 0-1, true-false, yes-no.



  //Convert values to 0 or 1 public function toBool( $val ){ if( in_array($val, $this->trueValues) ) return 1; if( in_array($val, $this->falseValues) ) return 0; return false; } 


In order not to accidentally overwrite the data or to eliminate the influence of some bugs, when you first start the class creates a copy of the config. And at any time you can return to the original version.



Well, when all the data from the config filed you can draw a form. I had to enter into the class and output the html layout, but the whole solution consists of a single file that completely solves the task. The jquery used for certain manipulations of form elements is connected on the fly if it has not been connected before. For example, a filedset can be minimized, which makes it easier to navigate the form of large size and find the desired parameter.

For convenience, some parameter blocks can be specified initially minimized by the [hidden] option.



For the data of the second level, you can add the ability to create additional fields, the field name will be generated automatically, but you can enter your own value. If for some tasks this is required, then add the [dinamic] key in the definition of the parent field. If, however, some of the fields inside this are to remain intact, then specify the key [static] for them.



Perhaps someone will benefit from this class. I tried to make it as simple as possible to use and sufficient to be useful functionality. In the end, for work, you just need to write:



 <?php include "../configer.php"; $cf = new Configer("settings.php"); $cf->showForm(); 


Well, so that in your settings file there was a comment with the keys.



You can download the class at https://github.com/vencendor/Configer .



I will be glad to helpful comments.



UPD: Recommendations are taken into account, unfortunately at the time of the article on github.com there was no actual version of the class.

Source: https://habr.com/ru/post/315384/



All Articles