TODO: We should find something better than BaseFrameworkSystem as a type-hint
[shipsimu.git] / ship-simu / inc / config / class_FrameworkConfiguration.php
1 <?php
2 /**
3  * A class for the configuration stuff implemented in a singleton design paddern
4  *
5  * NOTE: We cannot put this in inc/classes/ because it would be loaded (again)
6  * in the class loader. See inc/loader/class_ClassLoader.php for instance
7  *
8  * @see                 ClassLoader
9  * @author              Roland Haeder <webmaster@ship-simu.org>
10  * @version             0.0
11  * @copyright   Copyright(c) 2007, 2008 Roland Haeder, this is free software
12  * @license             GNU GPL 3.0 or any newer version
13  *
14  * This program is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26  */
27 class FrameworkConfiguration {
28         /**
29          * Include files which shall be included before the main loader.
30          */
31         private $moreIncPre = null;
32
33         /**
34          * Include files which shall be included after the main loader.
35          */
36         private $moreIncPost = null;
37
38         /**
39          * The framework's main configuration array which will be initialized with
40          * hard-coded configuration data and might be overwritten/extended by
41          * config data from the database.
42          */
43         private $config = array();
44
45         /**
46          * The configuration instance itself
47          */
48         private static $cfgInstance = null;
49
50         // Some constants for the configuration system
51         const EXCEPTION_CONFIG_ENTRY_IS_EMPTY      = 0xc00;
52         const EXCEPTION_CONFIG_ENTRY_WAS_NOT_FOUND = 0xc01;
53
54         /**
55          * Private constructor
56          */
57         private function __construct () {
58                 // Initialize both include lists
59                 $this->moreIncPre  = new ArrayObject();
60                 $this->moreIncPost = new ArrayObject();
61         }
62
63         /**
64          * "Create" a configuration instance
65          */
66         public final static function createFrameworkConfiguration ($enableDebug = false) {
67                 /**
68                  * For singleton design pattern because we only need a one-time-run
69                  * through the initial configuration.
70                  */
71                 if (is_null(self::$cfgInstance))  {
72                         // CFG: DEBUG-LEVEL
73                         @error_reporting(E_ALL | E_STRICT);
74
75                         /**
76                          * Shall we enable the debug mode?
77                          */
78                         if ($enableDebug) {
79                                 define('DEBUG_MODE', true);
80                         }
81
82                         /**
83                          * Crate a config instance
84                          */
85                         self::$cfgInstance = new FrameworkConfiguration();
86                 }
87
88                 /**
89                  * Return the instance
90                  */
91                 return self::$cfgInstance;
92         }
93
94         /**
95          * Getter for an instance of this class
96          *
97          * @return      $cfgInstance    An instance of this class
98          */
99         public final static function getInstance () {
100                 return self::$cfgInstance;
101         }
102
103         /**
104          * Setter for default time zone (must be correct!)
105          *
106          * @param               $zone   The time-zone string (e.g. Europe/Berlin)
107          * @return      void
108          */
109         public final function setDefaultTimezone ($zone) {
110                 // At least 5.1.0 is required for this!
111                 if (version_compare(phpversion(), "5.1.0")) {
112                         @date_default_timezone_set($zone);
113                 }
114         }
115
116         /**
117          * Setter for runtime magic quotes
118          */
119         public final function setMagicQuotesRuntime ($enableQuotes) {
120                 // Cast it to boolean
121                 $enableQuotes = (boolean) $enableQuotes;
122
123                 // Set it
124                 @set_magic_quotes_runtime($enableQuotes);
125         }
126
127         /**
128          * A private include loader
129          *
130          * @param               $arrayObject            The array object with all include files
131          * @return      void
132          */
133         private function loadIncludes (ArrayObject $arrayObject) {
134                 // Load only if there are includes defined
135                 if (!is_null($arrayObject)) {
136                         for ($idx = $arrayObject->getIterator(); $idx->valid(); $idx->next()) {
137                                 // Get include file
138                                 $inc = $idx->current();
139
140                                 // Is the file name really set?
141                                 if (!empty($inc)) {
142                                         // Base path added? (Uni* / Windows)
143                                         if ((substr($inc, 0, 1) != "/") && (substr($inc, 1, 1) != ":")) {
144                                                 // Generate FQFN
145                                                 $fqfn = sprintf("%s/inc/extra/%s", PATH, $inc);
146                                         } else {
147                                                 // Base path is already added
148                                                 $fqfn = $inc;
149                                         }
150                                 }
151
152                                 // Include them all here
153                                 require($fqfn);
154                         }
155                 }
156         }
157
158         /**
159          * Load all includes before main loader and clears the array after usage
160          *
161          * @return      void
162          */
163         public function loadPreIncludes () {
164                 $this->loadIncludes($this->moreIncPre);
165                 unset($this->moreIncPre);
166         }
167
168         /**
169          * Load all includes after main loader and clears the array after usage
170          *
171          * @return      void
172          */
173         public function loadPostIncludes () {
174                 $this->loadIncludes($this->moreIncPost);
175                 unset($this->moreIncPost);
176         }
177
178         /**
179          * Define the database type which must be valid and will not be verified.
180          *
181          * @param               $type   The database type. See path inc/database/.
182          * @return      void
183          */
184         public function defineDatabaseType ($type) {
185                 // Is it defined or not?
186                 if (!defined('_DB_TYPE')) {
187                         // Cast to string
188                         $type = (string) $type;
189
190                         // Set the constant
191                         define('_DB_TYPE', $type);
192                 } else {
193                         // Already defined! But we cannot throw an exception here... :(
194                         ApplicationEntryPoint::app_die(sprintf("[%s:] Please define the database type only once in your application!",
195                                 __CLASS__
196                         ));
197                 }
198         }
199
200         /**
201          * Define the local file path
202          *
203          * @param               $path   The database type. See path inc/database/.
204          * @return      void
205          */
206         public function definePath ($path) {
207                 // Cast to string
208                 $path = (string) $path;
209
210                 // Is it defined or not?
211                 if (!is_dir($path)) {
212                         // Is not a valid path
213                         ApplicationEntryPoint::app_die(sprintf("[%s:] Invalid path (not found) specified. Please make sure it is created.",
214                                 __CLASS__
215                         ));
216                 } elseif (!defined('PATH')) {
217                         // Set the constant
218                         define('PATH', $path);
219                 } else {
220                         // Already defined! But we cannot throw an exception here... :(
221                         ApplicationEntryPoint::app_die(sprintf("[%s:] Please define the local file path only once in your application.",
222                                 __CLASS__
223                         ));
224                 }
225         }
226
227         /**
228          * Read a configuration element.
229          *
230          * @param               $cfgEntry       The configuration element
231          * @return      $cfgValue       The fetched configuration value
232          * @throws      ConfigEntryIsEmptyException     If $cfgEntry is empty
233          * @throws      ConfigEntryNotFoundException    If a configuration element
234          *                                                                      was not found
235          */
236         public function readConfig ($cfgEntry) {
237                 // Cast to string
238                 $cfgEntry = (string) $cfgEntry;
239
240                 // Is a valid configuration entry provided?
241                 if (empty($cfgEntry)) {
242                         // Entry is empty
243                         throw new ConfigEntryIsEmptyException(__CLASS__, self::EXCEPTION_CONFIG_ENTRY_IS_EMPTY);
244                 } elseif (!isset($this->config[$cfgEntry])) {
245                         // Entry was not found!
246                         throw new ConfigEntryNotFoundException(array(__CLASS__, $cfgEntry), self::EXCEPTION_CONFIG_ENTRY_WAS_NOT_FOUND);
247                 }
248
249                 // Debug message
250                 if ((defined('DEBUG_CONFIG')) || (defined('DEBUG_ALL'))) {
251                         echo "[".__METHOD__."] Configuration entry ".$cfgEntry." requested.<br />\n";
252                 }
253
254                 // Return the requested value
255                 return $this->config[$cfgEntry];
256         }
257
258         /**
259          * Set a configuration entry.
260          *
261          * @param               $cfgEntry       The configuration entry we want to add/change
262          * @param               $cfgValue       The configuration value we want to set
263          * @return      void
264          * @throws      ConfigEntryIsEmptyException     If $cfgEntry is empty
265          */
266         public final function setConfigEntry ($cfgEntry, $cfgValue) {
267                 // Cast to string
268                 $cfgEntry = (string) $cfgEntry;
269                 $cfgValue = (string) $cfgValue;
270
271                 // Is a valid configuration entry provided?
272                 if (empty($cfgEntry)) {
273                         // Entry is empty
274                         throw new ConfigEntryIsEmptyException(__CLASS__, self::EXCEPTION_CONFIG_ENTRY_IS_EMPTY);
275                 }
276
277                 // Set the configuration value
278                 $this->config[$cfgEntry] = $cfgValue;
279
280                 // Resort the array
281                 ksort($this->config);
282         }
283
284         /**
285          * Compatiblity method to return this class' name
286          *
287          * @return      __CLASS__               This class' name
288          */
289         public function __toString () {
290                 return get_class($this);
291         }
292 } // END - class
293
294 // [EOF]
295 ?>