source: trunk/includes/system.php@ 809

Last change on this file since 809 was 809, checked in by chronos, 11 years ago
  • Property svn:executable set to *
File size: 19.1 KB
RevLine 
[291]1<?php
2
[455]3include_once('Database.php');
[577]4include_once('Application.php');
[291]5
[577]6class System extends Application
[291]7{
8 var $Database;
9 var $Config;
[545]10 var $ModuleManager;
11 var $PathItems;
[561]12 var $Menu;
[577]13 var $DoNotShowPage;
[807]14 var $OnPageNotFound;
[798]15
[455]16 function __construct()
17 {
18 $this->Config = array();
[561]19 $this->Menu = array();
20 $this->RSSChannels = array();
[577]21 $this->DoNotShowPage = false;
[807]22 $this->OnPageNotFound = array();
[455]23 }
[798]24
[291]25 function Init()
26 {
[618]27 global $Config, $LocaleManager;
[798]28
[291]29 $this->Config = $Config;
[538]30 $this->Database = new Database();
31 $this->Database->Connect($this->Config['Database']['Host'],
[507]32 $this->Config['Database']['User'], $this->Config['Database']['Password'],
33 $this->Config['Database']['Database']);
34 $this->Database->charset($this->Config['Database']['Charset']);
[455]35 $this->Database->ShowSQLQuery = $this->Config['Web']['ShowSQLQuery'];
36 $this->Database->ShowSQLError = $this->Config['Web']['ShowSQLError'];
[726]37 $this->Database->LogSQLQuery = $this->Config['Web']['LogSQLQuery'];
[545]38 $this->ModuleManager = new AppModuleManager();
[798]39
[618]40 $this->PathItems = ProcessURL();
41 // Initialize locale
42 $LocaleManager = new LocaleManager($this);
43 $LocaleManager->Dir = dirname(dirname(__FILE__)).'/locale';
44 $LocaleManager->Available = array(
45 'cs' => array('Code' => 'cs', 'Title' => 'Česky'),
46 'en' => array('Code' => 'en', 'Title' => 'English'),
47 );
48 $Code = $Config['Web']['Locale'];
[798]49 if (isset($_SESSION))
[630]50 if(array_key_exists('Locale', $_SESSION)) $Code = $_SESSION['Locale'];
[798]51 if (isset($_GET))
[630]52 if(array_key_exists('locale', $_GET)) $Code = $_GET['locale'];
[798]53
[618]54 //echo(phpinfo());
55 if(!array_key_exists($Code, $LocaleManager->Available)) $Code = 'en';
56 $_SESSION['Locale'] = $Code;
[798]57 $LocaleManager->LoadLocale($Code);
58
[548]59 $this->Menu = array
[798]60 (
[691]61 /* array(
[610]62 'Title' => T('Files'),
[548]63 'Hint' => 'Stahování různých pomocných souborů a programů',
64 'Link' => $this->Link('/download.php'),
65 'Permission' => LICENCE_ANONYMOUS,
66 'Icon' => '',
67 ),
[691]68 */
[548]69 array(
[610]70 'Title' => T('Instructions'),
[548]71 'Hint' => 'Informace k překladu hry',
72 'Link' => $this->Link('/info.php'),
73 'Permission' => LICENCE_ANONYMOUS,
74 'Icon' => '',
75 ),
76 array(
[610]77 'Title' => T('Data source'),
[548]78 'Hint' => 'Informace o překladových skupinách',
79 'Link' => $this->Link('/TranslationList.php?action=grouplist'),
80 'Permission' => LICENCE_ANONYMOUS,
81 'Icon' => '',
82 ),
83 array(
[610]84 'Title' => T('Presentation'),
[548]85 'Hint' => 'Prezentace a motivace překladu',
86 'Link' => $this->Link('/promotion.php'),
87 'Permission' => LICENCE_ANONYMOUS,
88 'Icon' => '',
[798]89 ),
[548]90 array(
[610]91 'Title' => T('IRC chat'),
[548]92 'Hint' => 'IRC chat pro překladatele',
93 'Link' => 'http://embed.mibbit.com/?server=game.zdechov.net%3A6667&amp;channel=%23wowpreklad&amp;forcePrompt=true&amp;charset=utf-8',
94 'Permission' => LICENCE_ANONYMOUS,
95 'Icon' => '',
96 ),
97 array(
[610]98 'Title' => T('Administration'),
[548]99 'Hint' => 'Volby pro správu',
100 'Link' => $this->Link('/admin/'),
101 'Permission' => LICENCE_ADMIN,
102 'Icon' => '',
103 ),
[798]104 );
[577]105 }
[798]106
[577]107 function Run()
108 {
109 global $System, $ScriptStartTime, $TranslationTree, $User, $StopAfterUpdateManager,
110 $UpdateManager, $Config, $DatabaseRevision;
111
112 $ScriptStartTime = GetMicrotime();
113
[805]114 if(GetRemoteAddress() != '') session_start();
[577]115
116 if(!isset($Config)) die('Systém není nainstalován. Pokračujte v instalaci <a href="admin/install.php">zde</a>.');
117 date_default_timezone_set($Config['Web']['Timezone']);
[798]118
[577]119 $this->Init();
120
121 // Check database persistence structure
122 $UpdateManager = new UpdateManager();
123 $UpdateManager->Database = $this->Database;
124 $UpdateManager->Revision = $DatabaseRevision;
125 if(!$UpdateManager->IsInstalled()) die('Systém vyžaduje instalaci databáze.');
126 if(!$UpdateManager->IsUpToDate()) die('Systém vyžaduje aktualizaci databáze.');
127
128 // SQL injection hack protection
129 foreach($_POST as $Index => $Item)
130 {
131 if(is_array($_POST[$Index]))
132 foreach($_POST[$Index] as $Index2 => $Item2) $_POST[$Index][$Index2] = addslashes($Item2);
133 else $_POST[$Index] = addslashes($_POST[$Index]);
134 }
135 foreach($_GET as $Index => $Item) $_GET[$Index] = addslashes($_GET[$Index]);
[798]136
[577]137 // TODO: Global initialized variable should be removed
138 $TranslationTree = GetTranslationTree();
[798]139
[577]140 // Initialize application modules
141 $this->ModuleManager->RegisterModule(new ModuleError($System));
142 $this->ModuleManager->Modules['Error']->ShowError = $Config['Web']['ShowPHPError'];
143 $this->ModuleManager->RegisterModule(new ModuleLog($System));
144 $this->ModuleManager->RegisterModule(new ModuleUser($System));
145 $this->ModuleManager->RegisterModule(new ModuleAoWoW($System));
146 $this->ModuleManager->RegisterModule(new ModuleReferrer($System));
[711]147 $this->ModuleManager->Modules['Referrer']->Excludes[] = $System->Config['Web']['Host'];
[577]148 $this->ModuleManager->RegisterModule(new ModuleTeam($System));
149 $this->ModuleManager->RegisterModule(new ModuleDictionary($System));
150 $this->ModuleManager->RegisterModule(new ModuleTranslation($System));
151 $this->ModuleManager->RegisterModule(new ModuleImport($System));
152 $this->ModuleManager->RegisterModule(new ModuleExport($System));
153 $this->ModuleManager->RegisterModule(new ModuleServer($System));
154 $this->ModuleManager->RegisterModule(new ModuleClientVersion($System));
155 $this->ModuleManager->RegisterModule(new ModuleShoutBox($System));
156 $this->ModuleManager->RegisterModule(new ModuleNews($System));
157 $this->ModuleManager->RegisterModule(new ModuleWiki($System));
158 $this->ModuleManager->RegisterModule(new ModuleSearch($System));
159 $this->ModuleManager->RegisterModule(new ModuleFrontPage($System));
[691]160 $this->ModuleManager->RegisterModule(new ModuleDownload($System));
[748]161 $this->ModuleManager->RegisterModule(new ModuleForum($System));
[800]162 $this->ModuleManager->RegisterModule(new ModuleRedirection($System));
[577]163 $this->ModuleManager->StartAll();
[798]164
165 $this->BaseView = new BaseView($this);
[577]166 if($this->DoNotShowPage == false)
167 {
168 $this->ShowPage();
[798]169 }
[291]170 }
[798]171
[291]172 function GetMicrotime()
173 {
174 list($Usec, $Sec) = explode(' ', microtime());
175 return ((float)$Usec + (float)$Sec);
[417]176 }
[798]177
[417]178 function Link($Target)
179 {
[545]180 return($this->Config['Web']['BaseURL'].$Target);
[798]181 }
182
[545]183 function RegisterPage($Path, $Handler)
184 {
[573]185 if(is_array($Path))
[545]186 {
187 $Page = &$this->Pages;
188 $LastKey = array_pop($Path);
189 foreach($Path as $PathItem)
190 {
[798]191 $Page = &$Page[$PathItem];
[545]192 }
193 if(!is_array($Page)) $Page = array('' => $Page);
194 $Page[$LastKey] = $Handler;
195 } else $this->Pages[$Path] = $Handler;
196 }
[798]197
[549]198 function RegisterMenuItem($MenuItem, $Pos = NULL)
[548]199 {
[549]200 if(is_null($Pos)) $this->Menu[] = $MenuItem;
201 else {
202 array_splice($this->Menu, $Pos, 0, array($MenuItem));
203 }
[548]204 }
[798]205
[545]206 function SearchPage($PathItems, $Pages)
207 {
[800]208 if(count($PathItems) == 0) $PathItems = array('');
209 $PathItem = $PathItems[0];
[545]210 if(array_key_exists($PathItem, $Pages))
211 {
[798]212 if(is_array($Pages[$PathItem]))
[545]213 {
214 array_shift($PathItems);
215 return($this->SearchPage($PathItems, $Pages[$PathItem]));
[798]216 } else
[589]217 {
[798]218 if(count($PathItems) == 1) return($Pages[$PathItem]);
[589]219 else return(''); // Unexpected subpages
220 }
[545]221 } else return('');
222 }
[798]223
[545]224 function PageNotFound()
225 {
[591]226 // Send correct HTTP status code to signal unknown page
227 if(array_key_exists('SERVER_PROTOCOL', $_SERVER))
228 Header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
[590]229 if(array_key_exists('HTTP_REFERER', $_SERVER)) $Referer = ' Referer: '.$_SERVER['HTTP_REFERER'];
[798]230 else $Referer = '';
231 if(isset($this->ModuleManager->Modules['Log']))
[589]232 $this->ModuleManager->Modules['Log']->WriteLog('Stránka "'.
[600]233 implode('/', $this->PathItems).'" nenalezena'.$Referer, LOG_TYPE_PAGE_NOT_FOUND);
[610]234 return(ShowMessage(sprintf(T('Page "%s" not found'), implode('/', $this->PathItems)), MESSAGE_CRITICAL));
[545]235 }
[798]236
[545]237 function ShowPage()
238 {
[636]239 $Output = '';
[545]240 /* @var $Page Page */
[589]241 $ClassName = $this->SearchPage($this->PathItems, $this->Pages);
[800]242 if(($ClassName != '') and (class_exists($ClassName)))
[545]243 {
244 $Page = new $ClassName($this);
[577]245 $Output = $Page->GetOutput();
[636]246 $this->BaseView->Title = $Page->Title;
[798]247 if($Page->RawPage == false) $Output = $this->BaseView->ShowPage($Output);
[636]248 } else {
[807]249 if((count($this->OnPageNotFound) == 2)
250 and method_exists($this->OnPageNotFound[0], $this->OnPageNotFound[1]))
251 $Output = $this->BaseView->ShowPage(call_user_func_array($this->OnPageNotFound, array()));
252 else
253 {
254 $Output = $this->PageNotFound();
255 $this->BaseView->Title = T('Page not found');
256 $Output = $this->BaseView->ShowPage($Output);
257 }
258 }
[636]259 echo($Output);
[545]260 }
[798]261}
[577]262
263class BaseView extends View
264{
[798]265 var $Title;
266
[577]267 function ShowTopBar()
268 {
[618]269 global $LocaleManager;
[798]270
[577]271 $Output = '<div class="Menu">';
272 if(!$this->System->User->Licence(LICENCE_USER))
273 $Output .= '<div class="advert">'.$this->System->Config['Web']['Advertisement'].'</div>';
[618]274 $Output .= '<span class="MenuItem"></span><span class="MenuItem2">';
[577]275 if($this->System->User->Licence(LICENCE_USER))
276 {
277 //$DbResult = $System->Database->query('SELECT `Id`, `Name` FROM `Team` WHERE `Id`='.$this->System->User->Team);
278 //$Team = $DbResult->fetch_assoc();
279 //$Output .= ''<span class="MenuItem">Moje překlady: <a href="">Dokončené</a> <a href="">Rozpracované</a> <a href="">Exporty</a> Tým: <a href="">'.$Team['name'].'</a></span>';
[618]280 $Output .= $this->System->User->Name.' <a href="'.$this->System->Link('/?action=logout').'">'.T('Logout').'</a>'.
[609]281 ' <a href="'.$this->System->Link('/user.php?user='.$this->System->User->Id).'">'.T('My page').'</a>'.
282 ' <a href="'.$this->System->Link('/Options.php').'">'.T('Options').'</a>'.
[577]283 ' <a title="Vámi přeložené texty" href="'.$this->System->Link('/TranslationList.php?user='.
[610]284 $this->System->User->Id.'&amp;group=0&amp;state=2&amp;text=&amp;entry=').'">'.T('Translated').'</a>'.
[577]285 ' <a title="Vaše rozpracované text" href="'.$this->System->Link('/TranslationList.php?user='.
[610]286 $this->System->User->Id.'&amp;group=0&amp;state=3&amp;text=&amp;entry=').'">'.T('Unfinished').'</a>'.
[618]287 ' <a title="Nikým nepřeložené texty" href="'.
288 $this->System->Link('/TranslationList.php?user=0&amp;group=0&amp;state=1&amp;text=&amp;entry=').'">'.T('Untranslated').'</a>';
[577]289 } else
290 {
[712]291 $Output .= '<a href="'.$this->System->Link('/login/').'">'.T('Login').'</a>&nbsp;'.
[618]292 '<a href="'.$this->System->Link('/registrace.php').'">'.T('Registration').'</a>';
[577]293 }
[809]294 //$Output .= ' <form action="?setlocale" method="get">';
295 $Output .= ' <select onchange="window.location=\'?locale=\'+this.value">';
[618]296 foreach($LocaleManager->Available as $Locale)
297 {
298 if($Locale['Code'] == $LocaleManager->CurrentLocale->Texts->Code) $Selected = ' selected="selected"';
299 else $Selected = '';
300 $Output .= '<option title="" value="'.$Locale['Code'].'"'.$Selected.' onchange="this.form.submit()">'.$Locale['Title'].'</option>';
301 }
[809]302 $Output .= '</select><noscript><span><input type="submit" value="Submit"/></span></noscript>';
303 //$Output .= '</form>';
[618]304 $Output .= '</span></div>';
[577]305 return($Output);
306 }
[798]307
[577]308 function ShowLoginBox()
309 {
310 $Output = '';
311 if($this->System->User->Licence(LICENCE_USER))
312 {
313 // $Output .= 'Jste přihlášen jako: <b>'.$tUser->Id.'</b> <a href="index.php?Logout">Odhlásit</a>';
314 } else
315 {
[622]316 $Output .= '<strong>'.T('Login').':</strong>
[577]317 <form action="" method="post">
318 <table>
319 <tr>
320 <td><input type="text" name="LoginUser" size="13" /></td>
321 </tr>
322 <tr>
323 <td><input type="password" name="LoginPass" size="13" /></td>
324 </tr>
325 <tr>
[622]326 <th><input type="submit" value="'.T('Do login').'" /></th>
[577]327 </tr>
328 </table>
329 </form>';
330 }
331 return($Output);
332 }
[798]333
[577]334 function ShowSearchBox()
335 {
[610]336 $Output = '<strong>'.T('Search').':</strong>'.
[798]337 '<form action="'.$this->System->Link('/search/').'" method="get"><div>'.
[577]338 '<table>'.
339 '<tr>'.
340 '<td><input type="text" name="text" size="13" /></td>'.
341 '</tr>'.
342 '<tr>'.
[610]343 '<th><input type="submit" value="'.T('Do search').'" /></th>'.
[577]344 '</tr>'.
345 '</table></div>'.
346 '</form>';
347 return($Output);
348 }
[798]349
[577]350 function ShowMainMenu()
351 {
[603]352 $Output = '<strong>'.T('Menu').':</strong>'.
[577]353 '<div class="verticalmenu"><ul>';
354 foreach($this->System->Menu as $MenuItem)
355 if($this->System->User->Licence($MenuItem['Permission']))
356 {
357 if(isset($MenuItem['Click'])) $OnClick = ' onclick="'.$MenuItem['Click'].'"';
358 else $OnClick = '';
359 if($MenuItem['Icon'] != '') $Icon = '<img src="'.$this->System->Link('/images/menu/'.$MenuItem['Icon']).'"/>';
360 else $Icon = '';
361 $Output .= '<li>'.$Icon.'<a class="verticalmenua" title="'.$MenuItem['Hint'].'" href="'.
362 $MenuItem['Link'].'"'.$OnClick.'>'.$MenuItem['Title'].'</a></li>';
363 }
364 $Output .= '</ul></div>';
365 return($Output);
366 }
[798]367
[577]368 function ShowTranslatedMenu()
369 {
370 global $TranslationTree;
[798]371
[609]372 $Output = '<strong>'.T('Translate groups').':</strong><br /><div id="TranslationMenu">';
[577]373 $DbResult = $this->System->Database->select('Group', '`Id`, `Name`', '1 ORDER BY `Name`');
374 while($Group = $DbResult->fetch_assoc())
375 {
376 $Output .= '<div id="menuitem-group'.$Group['Id'].'" onmouseover="show(\'group'.$Group['Id'].'\')" onmouseout="hide(\'group'.$Group['Id'].'\')">'.
[649]377 '<a href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;action=filter').'">'.str_replace(' ','&nbsp;',$Group['Name']).'</a></div>'.
[577]378 '<div id="group'.$Group['Id'].'" class="hidden-menu-item" onmouseover="show(\'group'.$Group['Id'].'\')" onmouseout="hide(\'group'.$Group['Id'].'\')">';
379 $Output .= '&nbsp;<a title="Zde můžete začít překládat" href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;state=1&amp;user=0&amp;entry=&amp;text=').'">Nepřeložené</a><br />'.
380 '&nbsp;<a title="Přeložené texty, můžete zde hlasovat, nebo opravovat překlady" href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;state=2&amp;user=0&amp;entry=&amp;text=').'">Přeložené</a><br />';
381 if($this->System->User->Licence(LICENCE_USER))
382 {
383 $Output .= '&nbsp;<a title="Nedokončené překlady" href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;state=3').'">Rozepsané</a><br />
384 &nbsp;<a title="Všechny překlady, které jste přeložil" href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;state=1&amp;user='.$this->System->User->Id).'&amp;entry=&amp;text=">Vlastní</a><br />';
385 }
386 $Output .= '&nbsp;<a title="Sestavit speciální filtr" href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;action=filter').'">Filtr</a><br />';
387 $Output .= '</div>';
388 }
389 $Output .= '</div>';
390 return($Output);
391 }
[798]392
[577]393 function ShowHeader()
394 {
[809]395 $Output = ''.
396 '<!DOCTYPE html>'.
397 '<html>'.
[577]398 '<head>'.
[809]399 '<meta http-equiv="content-type" content="text/html; charset='.$this->System->Config['Web']['Charset'].'" />'.
[577]400 '<meta name="keywords" content="wow, quest, questy, questů, preklad, mangos, překlad, překládání, přeložený, přeložení, čeština, world of warcraft, open source, free, addon" />'.
[765]401 '<meta name="description" content="'.$this->System->Config['Web']['Description'].'" />'.
[577]402 '<meta name="robots" content="all" />'.
403 '<link rel="stylesheet" href="'.$this->System->Link('/style/style.css').'" type="text/css" media="all" />'.
404 '<script type="text/javascript" src="'.$this->System->Link('/style/global.js').'"></script>'.
405 '<link rel="shortcut icon" href="'.$this->System->Link('/images/favicon.ico').'" />';
[581]406 $Output .= $this->System->ModuleManager->Modules['News']->ShowRSSHeader();
[636]407 $Title = $this->System->Config['Web']['Title'];
408 if($this->Title != '') $Title = $this->Title.' - '.$Title;
409 $Output .= '<title>'.$Title.'</title>'.
[577]410 '</head><body>';
[798]411
[577]412 $Output .= $this->ShowTopBar();
413 $Output .= '<table class="page"><tr><td class="menu">';
414 $Output .= $this->ShowMainMenu();
415 $Output .= $this->System->ModuleManager->Modules['User']->ShowOnlineList();
416 $Output .= '<br />';
417 $Output .= $this->ShowSearchBox();
[708]418
[577]419 $Output .= '</td><td id="border-left"></td><td class="content">';
420 return($Output);
421 }
[798]422
[577]423 function ShowFooter()
424 {
425 global $ScriptStartTime, $Revision, $ReleaseTime;
[798]426
[577]427 $ScriptGenerateDuration = round(GetMicrotime() - $ScriptStartTime, 2);
[798]428
[577]429 $Output = '</td>'.
430 '<td class="menu2">';
431 $Output .= $this->ShowTranslatedMenu();
432 $Output .= '</td>'.
433 '</tr><tr>'.
[609]434 '<td colspan="4" class="page-bottom">'.T('Version').': '.$Revision.' ('.HumanDate($ReleaseTime).')'.
435 ' &nbsp; <a href="http://svn.zdechov.net/trac/wowpreklad/browser/trunk">'.T('Source code').'</a> &nbsp; '.
436 '<a href="http://svn.zdechov.net/trac/wowpreklad/log/trunk?verbose=on">'.T('Changelog').'</a> &nbsp; '.
[577]437 $this->System->Config['Web']['WebCounter'];
[798]438
[577]439 $Output .= '</td></tr>';
440 if($this->System->Config['Web']['ShowRuntimeInfo'] == true)
[622]441 $Output .= '<tr><td colspan="3" style="text-align: center;">'.T('Generating duration').': '.
442 $ScriptGenerateDuration.' s / '.ini_get('max_execution_time').' s &nbsp;&nbsp; '.T('Used memory').': '.
[577]443 HumanSize(memory_get_peak_usage(FALSE)).' / '.ini_get('memory_limit').'B &nbsp;&nbsp; <a href="http://validator.w3.org/check?uri='.
[805]444 htmlentities('http://'.$_SERVER['HTTP_HOST'].GetRequestURI().'?'.$_SERVER['QUERY_STRING']).'">HTML validator</a></td></tr>';
[577]445 $Output .= '</table>'.
446 '</body>'.
447 '</html>';
448 return($Output);
449 }
[798]450
[577]451 function ShowPage($Content)
452 {
453 $Output = $this->ShowHeader().$Content.$this->ShowFooter();
[807]454 if($this->System->Config['Web']['FormatOutput'])
455 $Output = $this->FormatOutput($Output);
[577]456 return($Output);
457 }
[798]458
[577]459 function FormatOutput($s)
460 {
461 $out = '';
462 $nn = 0;
463 $n = 0;
464 while($s != '')
465 {
466 $start = strpos($s, '<');
467 $end = strpos($s, '>');
468 if($start != 0)
469 {
470 $end = $start - 1;
471 $start = 0;
472 }
473 $line = trim(substr($s, $start, $end + 1));
474 if(strlen($line) > 0)
475 if($line[0] == '<')
476 {
477 if($s[$start + 1] == '/')
478 {
479 $n = $n - 2;
480 $nn = $n;
481 } else
482 {
483 if(strpos($line, ' ')) $cmd = substr($line, 1, strpos($line, ' ') - 1);
484 else $cmd = substr($line, 1, strlen($line) - 2);
485 //echo('['.$cmd.']');
486 if(strpos($s, '</'.$cmd.'>')) $n = $n + 2;
487 }
488 }// else $line = '['.$line.']';
489 //if($line != '') echo(htmlspecialchars(str_repeat(' ',$nn).$line."\n"));
490 if($line != '') $out .= (str_repeat(' ', $nn).$line."\n");
491 $s = substr($s, $end + 1, strlen($s));
492 $nn = $n;
493 }
494 return($out);
[798]495 }
[577]496}
Note: See TracBrowser for help on using the repository browser.