1: <?php
2:
3: /*
4: * Copyright (C) 2014 Everton
5: *
6: * This program is free software: you can redistribute it and/or modify
7: * it under the terms of the GNU General Public License as published by
8: * the Free Software Foundation, either version 3 of the License, or
9: * (at your option) any later version.
10: *
11: * This program is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: * GNU General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
17: * along with this program. If not, see <http://www.gnu.org/licenses/>.
18: */
19:
20: /**
21: * Cria um objeto para armazenar e manipular configurações em arquivos INI.
22: * @todo Métodos para adicionar e excluir configurações.
23: * @todo Possibilitar instância sem necessidade de carregar configurações de arquivo INI.
24: *
25: */
26: class Config{
27: /**
28: *
29: * @var array Armazena a configuração
30: */
31: protected $config = array();
32:
33: /**
34: *
35: * @var string O caminho para o arquivo INI.
36: */
37: protected $source = NULL;
38:
39: /**
40: * Construtor da classe. Recebe como parâmetro obrigatório o nome do arquivo INI com as configurações. $filename será interpretado com {@link http://php.net/manual/en/function.realpath.php realpath()} e armazenado em {@link Config::source}.
41: *
42: * @param string $filename Um nome/caminho de arquivo INI com configurações.
43: * @throws Exception
44: */
45: public function __construct($filename) {
46: if(!is_file($filename)){
47: throw new Exception("$filename não é um arquivo válido.");
48: }else{
49: try{
50: $config = parse_ini_file($filename, true);
51: $this->source = realpath($filename);
52: } catch (Exception $ex) {
53: throw $ex;
54: }
55:
56: if(!$this->buildConfArray($config)){
57: throw new Exception('Ocorreu um erro ao construir a configuração.');
58: }
59: }
60: }
61:
62: /**
63: * Constrói o array com as configurações que será armazenado em {@link Config::config}.
64: *
65: * @param array $config O array retornado por {@link http://php.net/manual/en/function.parse-ini-file.php parse_ini_file()}.
66: * @return boolean
67: */
68: protected function buildConfArray($config){
69: if(count($config) == 0){
70: return false;
71: }
72:
73: foreach ($config as $key => $value){
74: if(is_array($value)){
75: $this->config[$key] = $this;
76: if(count($value) > 0){
77: foreach ($value as $subkey => $subvalue){
78: $this->config[$subkey] = $subvalue;
79: }
80: }
81: }else{
82: $this->config[$key] = $value;
83: }
84: }
85: return true;
86: }
87:
88: /**
89: * Converte o conteúdo de {@link Config::config} para uma string.
90: * Essa string não pode ser usada para criar um novo arquivo INI.
91: *
92: * @return string Retorna uma string com o conteúdo de {@link Config::config}.
93: */
94: public function __toString() {
95: $config = $this->config;
96: $section = false;
97: $previous_section = NULL;
98: $str = '';
99:
100: foreach ($config as $key => $value){
101: if($value === $this){
102: if($previous_section === $this){
103: $str .= "\t[vazio]".PHP_EOL;
104: }
105: $previous_section = $value;
106: $str .= "$key :".PHP_EOL;
107: $section = true;
108: }else{
109: $previous_section = NULL;
110: if($section){
111: $tab = "\t";
112: }else{
113: $tab = '';
114: }
115: $str .= "$tab$key : $value".PHP_EOL;
116: }
117: }
118:
119: return $str;
120: }
121:
122: /**
123: * Exibe a string gerada por {@link Config::__toString()}
124: */
125: public function show(){
126: echo $this->__toString();
127: }
128:
129: /**
130: * Método mágico usado para retornar as configurações.
131: * Para saber mais sobre métodos mágicos no PHP acesse {@link http://php.net/manual/pt_BR/language.oop5.magic.php o manual do PHP}.
132: * @param string $name O nome da configuração desejada.
133: * @return mixed Retorna o valor da configuração desejada.
134: * @throws Exception
135: */
136: public function __get($name) {
137: if(array_key_exists($name, $this->config)){
138: return $this->config[$name];
139: }else{
140: throw new Exception("$name não é uma configuração válida!");
141: }
142: }
143:
144: /**
145: * Método mágico usado para definir valores nas configurações.
146: * Para saber mais sobre métodos mágicos no PHP acesse {@link http://php.net/manual/pt_BR/language.oop5.magic.php o manual do PHP}.
147: *
148: * @param string $name A configuração desejada.
149: * @param mixed $value O valor da configuração.
150: * @return mixed Retorna o valor configurado em caso de sucesso ou FALSE em caso de erro.
151: * @throws Exception
152: */
153: public function __set($name, $value) {
154: if(array_key_exists($name, $this->config)){
155: if($this->config[$name] === $this){
156: throw new Exception("$name é uma seção de configuração e não pode ser modificada!");
157: }else{
158: $method_name = "validate_$name";
159: if(method_exists($this, $method_name)){
160: if($this->$method_name($value)){
161: $this->config[$name] = $value;
162: }else{
163: throw new Exception("O valor \"$value\" é inválido para $name!");
164: }
165: }else{
166: $this->config[$name] = $value;
167: }
168: }
169: }else{
170: throw new Exception("$name não é uma configuração válida!");
171: }
172: return $this->config[$name];
173: }
174:
175: /**
176: * Salva o conteúdo de {@link Config} em um arquivo INI.
177: *
178: * @param string $filename Opcional. O nome/caminho do arquivo de configuração. Se omitido, o armazenado em {@link Config::source} será utilizado.
179: * @return integer Retorna o número de bytes escritos em caso de sucesso.
180: * @throws Exception
181: */
182: public function save($filename = NULL){
183: if($filename === NULL){
184: $filename = $this->source;
185: }
186:
187: $data = $this->prepareToSave();
188:
189: $save = file_put_contents($filename, $data);
190: if($save == false){
191: throw new Exception("Não foi possível salvar a configuração em $filename");
192: }else{
193: return $save;
194: }
195: }
196:
197: /**
198: * Método para retornar o arquivo INI fonte das configurações, armazenado em {@link Config::source}.
199: * @return string Retorna o arquivo INI de onde as configurações foram lidas.
200: */
201: public function getSource(){
202: return $this->source;
203: }
204:
205: /**
206: * Cria uma string com o conteúdo de {@link Config::config} que possa ser gravada num arquivo INI.
207: * @return string Retorna uma string para ser gravada em arquivos INI.
208: */
209: protected function prepareToSave(){
210: $config = $this->config;
211: $previous_section = NULL;
212: $str = '';
213:
214: foreach ($config as $key => $value){
215: if($value === $this){
216: if($previous_section === $this){
217: //nothing
218: }
219: $previous_section = $value;
220: $str .= "[$key]".PHP_EOL;
221: }else{
222: $previous_section = NULL;
223: $str .= "$key = $value".PHP_EOL;
224: }
225: }
226:
227: return $str;
228: }
229:
230: }