improve link building (QUERY_STRING and PATH_INFO are now allowed)
[GitHub/Stricted/Domain-Control-Panel.git] / lib / system / DNS.class.php
1 <?php
2 namespace dns\system;
3
4 if (!defined('DNS_VERSION')) define('DNS_VERSION', '3.0.0 Beta');
5
6 /**
7 * @author Jan Altensen (Stricted)
8 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
9 * @copyright 2014-2016 Jan Altensen (Stricted)
10 */
11 class DNS {
12 /**
13 * module name
14 *
15 * @var string
16 */
17 protected static $module = '';
18
19 /**
20 * database object
21 *
22 * @var object
23 */
24 protected static $dbObj = null;
25
26 /**
27 * session object
28 *
29 * @var object
30 */
31 protected static $sessionObj = null;
32
33 /**
34 * template object
35 *
36 * @var object
37 */
38 protected static $tplObj = null;
39
40 /**
41 * language array
42 *
43 * @var array
44 */
45 protected static $language = array();
46
47 /**
48 * language code
49 *
50 * @var string
51 */
52 protected static $languageCode = '';
53
54 /**
55 * init main system
56 */
57 public function __construct($module = '') {
58 self::$module = $module;
59 spl_autoload_register(array('dns\system\DNS', 'autoload'));
60 set_exception_handler(array('dns\system\DNS', 'handleException'));
61 set_error_handler(array('dns\system\DNS', 'handleError'), E_ALL);
62
63 $this->initDB();
64 self::buildOptions();
65 $this->initSession();
66 $this->initLanguage();
67 $this->initTPL();
68
69 AclHandler::getInstance();
70
71 $requestHandler = RequestHandler::getInstance();
72 $requestHandler->setRoutes($module);
73 $requestHandler->handle();
74 }
75
76 /**
77 * get database
78 */
79 public static function getDB() {
80 return self::$dbObj;
81 }
82
83 /**
84 * init database
85 */
86 protected function initDB() {
87 require(DNS_DIR.'/config.inc.php');
88 self::$dbObj = new DB($driver, $host, $user, $pass, $db, $port);
89 }
90
91 /**
92 * init session system
93 */
94 protected function initSession() {
95 self::$sessionObj = new SessionHandler();
96 }
97
98 /**
99 * return session object
100 */
101 public static function getSession() {
102 return self::$sessionObj;
103 }
104
105 /*
106 * autoload class files from namespace uses
107 *
108 * @param string $className
109 */
110 public static function autoload ($className) {
111 $namespaces = explode('\\', $className);
112 if (count($namespaces) > 1) {
113 $abbreviation = array_shift($namespaces);
114 if ($abbreviation == "dns") {
115 $classPath = DNS_DIR.'/lib/'.implode('/', $namespaces).'.class.php';
116 if (file_exists($classPath)) {
117 require_once($classPath);
118 }
119 }
120 else if ($abbreviation == "Mso") {
121 array_shift($namespaces);
122
123 $classPath = DNS_DIR.'/vendor/idna-convert/src/'.implode('/', $namespaces).'.php';
124 if (file_exists($classPath)) {
125 require_once($classPath);
126 }
127 }
128 else if ($abbreviation == "Zend") {
129 $classPath = DNS_DIR.'/vendor/Zend/'.implode('/', $namespaces).'.php';
130 if (file_exists($classPath)) {
131 require_once($classPath);
132 }
133 }
134 else if ($abbreviation == "Interop") {
135 $classPath = DNS_DIR.'/vendor/Interop/'.implode('/', $namespaces).'.php';
136 if (file_exists($classPath)) {
137 require_once($classPath);
138 }
139 }
140 }
141 }
142
143 /**
144 * Calls the show method on the given exception.
145 *
146 * @param \Exception $e
147 */
148 public static final function handleException(\Exception $e) {
149 try {
150 if ($e instanceof SystemException) {
151 $e->show();
152 exit;
153 }
154
155 // repack Exception
156 self::handleException(new SystemException($e->getMessage(), $e->getCode(), '', $e));
157 }
158 catch (\Exception $exception) {
159 die("<pre>DNS::handleException() Unhandled exception: ".$exception->getMessage()."\n\n".$exception->getTraceAsString());
160 }
161 }
162
163 /**
164 * Catches php errors and throws instead a system exception.
165 *
166 * @param integer $errorNo
167 * @param string $message
168 * @param string $filename
169 * @param integer $lineNo
170 */
171 public static final function handleError($errorNo, $message, $filename, $lineNo) {
172 if (error_reporting() != 0) {
173 $type = 'error';
174 switch ($errorNo) {
175 case 2:
176 $type = 'warning';
177 break;
178 case 8:
179 $type = 'notice';
180 break;
181 }
182
183 throw new SystemException('PHP '.$type.' in file '.$filename.' ('.$lineNo.'): '.$message, 0);
184 }
185 }
186
187 /**
188 * Returns true if the debug mode is enabled, otherwise false.
189 *
190 * @return boolean
191 */
192 public static function debugModeIsEnabled() {
193 // try to load constants
194 if (!defined('ENABLE_DEBUG')) {
195 self::buildOptions();
196 }
197
198 if (defined('ENABLE_DEBUG') && ENABLE_DEBUG) {
199 return true;
200 }
201
202 return false;
203 }
204
205 /**
206 * init language system
207 */
208 protected function initLanguage () {
209 /*
210 * @TODO: activate this later
211 * self::buildlanguage();
212 */
213 $availableLanguages = array("de", "en");
214 $languageCode = 'de';
215
216 if (isset($_GET['l'])) {
217 $code = strtolower($_GET['l']);
218 if (in_array($code, $availableLanguages)) {
219 $languageCode = $code;
220 }
221 else if (array_key_exists($code, $availableLanguages)) {
222 $languageCode = $availableLanguages[$code];
223 }
224 }
225 else if (self::getSession()->language !== null) {
226 $code = strtolower(self::getSession()->language);
227 if (in_array($code, $availableLanguages)) {
228 $languageCode = $code;
229 }
230 else if (array_key_exists($code, $availableLanguages)) {
231 $languageCode = $availableLanguages[$code];
232 }
233 }
234 else if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) && $_SERVER['HTTP_ACCEPT_LANGUAGE']) {
235 $acceptedLanguages = explode(',', str_replace('_', '-', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])));
236 foreach ($acceptedLanguages as $acceptedLanguage) {
237 $code = strtolower(preg_replace('%^([a-z]{2}).*$%i', '$1', $acceptedLanguage));
238 if (in_array($code, $availableLanguages)) {
239 $languageCode = $code;
240 break;
241 }
242 }
243 }
244
245 self::$languageCode = $languageCode;
246
247 // @TODO: remove this later
248 /* try to load module language files */
249 if (!empty(self::$module)) {
250 $basedir = DNS_DIR.'/'.self::$module.'/lang/';
251 $file = $basedir.$languageCode.'.lang.php';
252 self::getSession()->register('language', $languageCode);
253
254 if (file_exists($file)) {
255 require_once($file);
256 if (isset($lang) && !empty($lang) && is_array($lang)) {
257 $this->language = array_merge($this->language, $lang);
258 }
259 }
260 }
261
262 /* load default language files */
263 $basedir = DNS_DIR.'/lang/';
264 $file = $basedir.$languageCode.'.lang.php';
265 self::getSession()->register('language', $languageCode);
266
267 if (file_exists($file)) {
268 require_once($file);
269 if (isset($lang) && !empty($lang) && is_array($lang)) {
270 self::$language = array_merge(self::$language, $lang);
271 }
272 }
273
274 return;
275 }
276
277 /**
278 * Executes template scripting in a language variable.
279 *
280 * @param string $item
281 * @param array $variables
282 * @return string result
283 */
284 public static function getLanguageVariable ($item, array $variables = array()) {
285 $lang = self::$language;
286
287 if ($lang == null) {
288 return $item;
289 }
290
291 if (!empty($variables)) {
292 self::getTPL()->assign($variables);
293 }
294
295 if (isset($lang[$item])) {
296 if (strpos($lang[$item], self::getTPL()->left_delimiter) !== false && strpos($lang[$item], self::getTPL()->right_delimiter) !== false) {
297 $data = str_replace("\$", '$', $lang[$item]);
298 $dir = self::getTPL()->getTemplateDir();
299
300 if (is_array($dir)) {
301 $dir = $dir[0];
302 }
303
304 $filename = "lang.".self::$languageCode.".".sha1($item).".tpl";
305 if (file_exists($dir.$filename)) {
306 $mtime = filemtime($dir.$filename);
307 $maxLifetime = 3600;
308
309 if ($mtime === false || ($maxLifetime > 0 && (time() - $mtime) > $maxLifetime)) {
310 @unlink($dir.$filename);
311 }
312 }
313
314 if (!file_exists($dir.$filename)) {
315 $h = fopen($dir.$filename, "a+");
316 fwrite($h, '{* '.$item.' *}'.$lang[$item]);
317 fclose($h);
318 }
319
320 return self::getTPL()->fetch($filename);
321 }
322
323 return $lang[$item];
324 }
325
326 return $item;
327 }
328
329 /**
330 * init template engine
331 */
332 protected function initTPL () {
333 require(DNS_DIR.'/config.inc.php');
334
335 if (self::getSession()->tpl !== null && !empty(self::getSession()->tpl)) {
336 $tpl = self::getSession()->tpl;
337 }
338
339 if (!file_exists(DNS_DIR.'/vendor/smarty/libs/Smarty.class.php')) {
340 throw new SystemException('Unable to find Smarty');
341 }
342
343 require_once(DNS_DIR.'/vendor/smarty/libs/Smarty.class.php');
344 self::$tplObj = new \Smarty;
345
346 if (!empty(self::$module)) {
347 // try first to load the template from module then from core
348 self::getTPL()->addTemplateDir(DNS_DIR.'/'.self::$module."/templates/".$tpl);
349 }
350
351 self::getTPL()->addTemplateDir(DNS_DIR."/templates/".$tpl);
352 self::getTPL()->setCompileDir(DNS_DIR.(empty(self::$module) ? '' : '/'.self::$module)."/templates/compiled/".$tpl);
353 self::getTPL()->setPluginsDir(array(
354 DNS_DIR."/vendor/smarty/libs/plugins",
355 DNS_DIR."/lib/system/template/plugins"
356 ));
357 self::getTPL()->loadFilter('pre', 'hascontent');
358
359 if (!ENABLE_DEBUG) {
360 self::getTPL()->loadFilter('output', 'trimwhitespace');
361 }
362
363 /* assign language variables */
364 self::getTPL()->assign(array(
365 "isReseller" => User::isReseller(),
366 "isAdmin" => User::isAdmin(),
367 'baseurl' => RequestHandler::getInstance()->getBaseUrl()
368 ));
369
370 /*self::getTPL()->assign("version", mb_substr(sha1(DNS_VERSION), 0, 8));*/
371
372 }
373
374 /**
375 * get template engine
376 */
377 public static function getTPL () {
378 return self::$tplObj;
379 }
380
381 /**
382 * Creates a random hash.
383 *
384 * @return string
385 */
386 public static function generateRandomID() {
387 return sha1(microtime() . uniqid(mt_rand(), true));
388 }
389
390 /**
391 * Creates an UUID.
392 *
393 * @return string
394 */
395 public static function generateUUID() {
396 return strtoupper(sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535)));
397 }
398
399 /**
400 * build options from database
401 *
402 * @param boolean $force
403 */
404 public static function buildOptions ($force = false) {
405 $file = DNS_DIR."/options.inc.php";
406 if (!file_exists($file) || (filemtime($file) + 86400) < time() || $force === true) {
407 if (file_exists($file)) {
408 @unlink($file);
409 }
410
411 @touch($file);
412 $options = self::getDB()->query("select * from dns_options");
413 $content = "<?php\n/* generated at ".gmdate('r')." */\n";
414
415 while ($row = self::getDB()->fetch_array($options)) {
416 $content .= "if (!defined('".strtoupper($row['optionName'])."')) define('".strtoupper($row['optionName'])."', ".((is_bool($row['optionValue']) || is_numeric($row['optionValue'])) ? intval($row['optionValue']) : "'".addcslashes($row['optionValue'], "'\\")."'").");\n";
417 }
418
419 $handler = fOpen($file, "a+");
420 fWrite($handler, $content);
421 fClose($handler);
422 }
423
424 require_once($file);
425 }
426
427 /**
428 * build language files from database
429 *
430 * @param boolean $force
431 */
432 public static function buildlanguage ($force = false) {
433 $availableLanguages = array("de", "en");
434 foreach ($availableLanguages as $languageID => $languageCode) {
435
436 $file = DNS_DIR."/lang/".$languageCode.".lang.php";
437 if (!file_exists($file) || (filemtime($file) + 86400) < time() || $force === true) {
438 if (file_exists($file)) {
439 @unlink($file);
440 }
441
442 @touch($file);
443
444 $items = self::getDB()->query("select * from dns_language where languageID = ?", array($languageID));
445 $content = "<?php\n/**\n* language: ".$languageCode."\n* encoding: UTF-8\n* generated at ".gmdate("r")."\n* \n* DO NOT EDIT THIS FILE\n*/\n";
446 $content .= "\$lang = array();\n";
447 while ($row = self::getDB()->fetch_array($items)) {
448 print_r($row);
449 $content .= "\$lang['".$row['languageItem']."'] = '".str_replace("\$", '$', $row['languageValue'])."';\n";
450 }
451
452 $handler = fOpen($file, "a+");
453 fWrite($handler, $content);
454 fClose($handler);
455 }
456 }
457 }
458 }