CMSimple_XH 開発者ドキュメント
Controller.php
1 <?php
2 
16 namespace XH;
17 
30 {
40  public function initTemplatePaths()
41  {
42  global $pth, $cf, $tx;
43 
44  $pth['folder']['templates'] = $pth['folder']['base'] . 'templates/';
45  $template = $tx['subsite']['template'] == ''
46  ? $cf['site']['template']
47  : $tx['subsite']['template'];
48  $pth['folder']['template'] = $pth['folder']['templates'] . $template . '/';
49  $pth['file']['template'] = $pth['folder']['template'] . 'template.htm';
50  $pth['file']['stylesheet'] = $pth['folder']['template'] . 'stylesheet.css';
51  $pth['folder']['menubuttons'] = $pth['folder']['template'] . 'menu/';
52  $pth['folder']['templateimages'] = $pth['folder']['template'] . 'images/';
53  $pth['folder']['templateflags'] = $pth['folder']['template'] . 'flags/';
54  }
55 
66  public function handleSearch()
67  {
68  global $pth, $tx, $title, $o;
69 
70  if (file_exists($pth['file']['search'])) {
71  // For compatibility with modified search functions and search plugins.
72  include $pth['file']['search'];
73  } else {
74  $title = $tx['title']['search'];
75  $search = $this->makeSearch();
76  $o .= $search->render();
77  }
78  }
79 
87  public function makeSearch()
88  {
89  global $search;
90 
91  return new Search(stsl($search));
92  }
93 
104  public function handleMailform()
105  {
106  global $cf, $tx, $title, $o;
107 
108  if ($cf['mailform']['email'] != '') {
109  $title = $tx['title']['mailform'];
110  $o .= "\n" . '<div id="xh_mailform">' . "\n";
111  $o .= '<h1>' . $title . '</h1>' . "\n";
112  $mailform = $this->makeMailform();
113  $o .= $mailform->process();
114  $o .= '</div>' . "\n";
115  } else {
116  shead(404);
117  }
118  }
119 
125  public function makeMailform()
126  {
127  return new Mailform();
128  }
129 
143  public function handleSitemap()
144  {
145  global $cl, $cf, $tx, $title, $o;
146 
147  $title = $tx['title']['sitemap'];
148  $pages = array();
149  $o .= '<h1>' . $title . '</h1>' . "\n";
150  for ($i = 0; $i < $cl; $i++) {
151  if (!hide($i) || $cf['show_hidden']['pages_sitemap'] == 'true') {
152  $pages[] = $i;
153  }
154  }
155  $o .= li($pages, 'sitemaplevel');
156  }
157 
163  public function handlePasswordForgotten()
164  {
165  $passwordForgotten = $this->makePasswordForgotten();
166  $passwordForgotten->dispatch();
167  }
168 
174  public function makePasswordForgotten()
175  {
176  return new PasswordForgotten();
177  }
178 
190  public function handleLoginAndLogout()
191  {
192  global $adm, $login, $logout, $keycut, $f;
193 
194  $adm = gc('status') == 'adm' && logincheck();
195  $keycut = stsl($keycut);
196  if ($login && $keycut == '' && !$adm) {
197  $login = null;
198  $f = 'login';
199  }
200 
201  if ($login && !$adm) {
202  $this->handleLogin();
203  } elseif ($logout && $adm) {
204  $this->handleLogout();
205  }
206  }
207 
219  public function handleLogin()
220  {
221  global $f, $pth, $keycut, $login, $adm, $edit, $cf;
222 
223  if (password_verify($keycut, $cf['security']['password'])) {
224  setcookie('status', 'adm', 0, CMSIMPLE_ROOT);
225  XH_startSession();
226  session_regenerate_id(true);
227  $_SESSION['xh_password'] = $cf['security']['password'];
228  $_SESSION['xh_user_agent'] = md5($_SERVER['HTTP_USER_AGENT']);
229  $adm = true;
230  $edit = true;
231  $written = XH_logMessage('info', 'XH', 'login', 'login from ' . $_SERVER['REMOTE_ADDR']);
232  if (!$written) {
233  e('cntwriteto', 'log', $pth['file']['log']);
234  }
235  } else {
236  $login = null;
237  $f = 'xh_login_failed';
238  XH_logMessage('warning', 'XH', 'login', 'login failed from ' . $_SERVER['REMOTE_ADDR']);
239  }
240  }
241 
253  public function handleLogout()
254  {
255  global $adm, $f, $logout, $tx, $o;
256 
257  if ($logout != 'no_backup') {
258  $o .= XH_backup();
259  }
260  $adm = false;
261  setcookie('status', '', 0, CMSIMPLE_ROOT);
262  XH_startSession();
263  session_regenerate_id(true);
264  unset($_SESSION['xh_password']);
265  $o .= XH_message('success', $tx['login']['loggedout']);
266  $f = 'xh_loggedout';
267  }
268 
274  public function handleKeepAlive()
275  {
276  XH_startSession();
277  header('Content-Type: text/plain');
278  XH_exit();
279  }
280 
293  public function setFrontendF()
294  {
296 
297  if ($xhpages) {
298  $f = 'xhpages';
299  } elseif (($su == '' || $su == 'sitemap') && $sitemap) {
300  $f = 'sitemap';
301  } elseif (($su == '' || $su == 'mailform')
302  && ($mailform || $function == 'mailform')
303  ) {
304  $f = 'mailform';
305  } elseif ($function == 'search') {
306  $f = 'search';
307  } elseif ($function == 'forgotten') {
308  $f = 'forgotten';
309  }
310  }
311 
338  public function setBackendF()
339  {
340  global $function, $validate, $xh_do_validate, $settings, $xh_backups,
341  $xh_pagedata, $sysinfo, $phpinfo, $file, $userfiles, $images,
342  $downloads, $f, $xh_change_password, $xh_plugins;
343 
344  if ($function == 'save') {
345  $f = 'save';
346  } elseif ($downloads || $function == 'downloads') {
347  $f = 'downloads';
348  } elseif ($images || $function == 'images') {
349  $f = 'images';
350  } elseif ($userfiles) {
351  $f = 'userfiles';
352  } elseif ($file) {
353  $f = 'file';
354  } elseif ($phpinfo) {
355  $f = 'phpinfo';
356  } elseif ($sysinfo) {
357  $f = 'sysinfo';
358  } elseif ($xh_pagedata) {
359  $f = 'xh_pagedata';
360  } elseif ($xh_backups) {
361  $f = 'xh_backups';
362  } elseif ($settings) {
363  $f = 'settings';
364  } elseif ($xh_do_validate) {
365  $f = 'do_validate';
366  } elseif ($validate) {
367  $f = 'validate';
368  } elseif ($xh_change_password) {
369  $f = 'change_password';
370  } elseif ($xh_plugins) {
371  $f = 'xh_plugins';
372  }
373  }
374 
382  public function wantsSavePageData()
383  {
384  global $s;
385 
386  return $s > -1 && isset($_POST['save_page_data']);
387  }
388 
400  public function handleSavePageData()
401  {
403 
404  $_XH_csrfProtection->check();
405  $postData = $_POST;
406  unset($postData['save_page_data'], $postData['xh_csrf_token']);
407  $postData = array_map('stsl', $postData);
408  $successful = $pd_router->update($s, $postData);
409  if (isset($_GET['xh_pagedata_ajax'])) {
410  if ($successful) {
411  echo XH_message('info', $tx['message']['pd_success']);
412  } else {
413  header('HTTP/1.0 500 Internal Server Error');
414  echo XH_message('fail', $tx['message']['pd_fail']);
415  }
416  XH_exit();
417  } else {
418  if (!$successful) {
419  e('cntsave', 'content', $pth['file']['content']);
420  }
421  }
422  }
423 
433  public function handlePagedataEditor()
434  {
435  global $o;
436 
437  $pageDataEditor = $this->makePageDataEditor();
438  $o .= $pageDataEditor->process();
439  }
440 
446  public function makePageDataEditor()
447  {
448  return new PageDataEditor();
449  }
450 
460  public function handleFileView()
461  {
462  global $pth, $file, $o;
463 
464  if ($file === 'log') {
465  $o .= XH_logFileView();
466  } else {
467  header('Content-Type: text/plain; charset=utf-8');
468  echo rmnl(file_get_contents($pth['file'][$file]));
469  XH_exit();
470  }
471  }
472 
481  public function handleFileBackup()
482  {
483  global $file, $_XH_csrfProtection;
484 
485  $_XH_csrfProtection->check();
486  if ($file == 'content') {
487  $suffix = stsl($_POST['xh_suffix']);
488  if (preg_match('/^[a-z_0-9-]{1,20}$/i', $suffix)) {
489  XH_extraBackup($suffix);
490  }
491  }
492  }
493 
503  public function handleFileEdit()
504  {
505  global $file, $action, $o;
506 
507  $map = array(
508  'config' => 'XH\CoreConfigFileEdit',
509  'language' => 'XH\CoreLangFileEdit',
510  'content' => 'XH\CoreTextFileEdit',
511  'template' => 'XH\CoreTextFileEdit',
512  'stylesheet' => 'XH\CoreTextFileEdit'
513  );
514  $fileEditor = isset($map[$file])
515  ? $this->makeFileEditor($map[$file])
516  : null;
517  if ($action == 'save') {
518  $o .= $fileEditor->submit();
519  } else {
520  $o .= $fileEditor->form();
521  }
522  }
523 
531  protected function makeFileEditor($class)
532  {
533  return new $class;
534  }
535 
544  public function outputAdminScripts()
545  {
546  global $tx, $o;
547 
548  $interval = 1000 * (ini_get('session.gc_maxlifetime') - 1);
549  $o .= <<<EOT
550 <script type="text/javascript">
551 if (document.cookie.indexOf('status=adm') == -1) {
552  document.write('<div class="xh_warning">{$tx['error']['nocookies']}<\/div>');
553 }
554 </script>
555 <noscript><div class="xh_warning">{$tx['error']['nojs']}</div></noscript>
556 <script type="text/javascript">
557 setInterval(function() {
558  var request = new XMLHttpRequest();
559 
560  request.open("GET", "?xh_keep_alive");
561  request.send(null);
562 }, $interval);
563 </script>
564 EOT;
565  }
566 
577  public function setFunctionsAsPermitted()
578  {
579  global $edit, $normal;
580 
581  if (XH_ADM) {
582  if ($edit) {
583  setcookie('mode', 'edit', 0, CMSIMPLE_ROOT);
584  }
585  if ($normal) {
586  setcookie('mode', '', 0, CMSIMPLE_ROOT);
587  }
588  if (gc('mode') == 'edit' && !$normal) {
589  $edit = true;
590  }
591  } else {
592  if (gc('status') != '') {
593  setcookie('status', '', 0, CMSIMPLE_ROOT);
594  }
595  if (gc('mode') == 'edit') {
596  setcookie('mode', '', 0, CMSIMPLE_ROOT);
597  }
598  }
599  }
600 
609  public function handleSaveRequest()
610  {
611  global $text, $_XH_csrfProtection;
612 
613  $_XH_csrfProtection->check();
614  XH_saveEditorContents($text);
615  }
616 
629  public function wantsEditContents()
630  {
631  global $edit, $f, $download;
632 
633  return $edit && (!$f || $f == 'save') && !$download;
634  }
635 
645  public function outputEditContents()
646  {
647  global $s, $tx, $o;
648 
649  if ($s > -1) {
650  $o .= XH_contentEditor();
651  } else {
652  $o .= XH_message('info', $tx['error']['cntlocateheading']) . "\n";
653  }
654  }
655 
661  public function isFilebrowserMissing()
662  {
663  return $this->needsFilebrowser()
664  && $this->isExternalMissing('filebrowser');
665  }
666 
674  public function isPagemanagerMissing()
675  {
676  global $f;
677 
678  return $f == 'xhpages'
679  && $this->isExternalMissing('pagemanager');
680  }
681 
700  private function needsFilebrowser()
701  {
703 
704  return $images || $downloads || $userfiles || $media
705  || $edit && (!$f || $f == 'save') && !$download;
706  }
707 
718  private function isExternalMissing($name)
719  {
720  global $pth, $cf;
721 
722  return $cf[$name]['external']
723  && !file_exists($pth['folder']['plugins'] . $cf[$name]['external']);
724  }
725 
737  public function reportMissingExternal($name)
738  {
739  global $cf, $tx, $e;
740 
741  $e .= '<li>' . sprintf($tx['error']['no' . $name], $cf[$name]['external'])
742  . '</li>' . "\n";
743  }
744 
761  public function verifyAdm()
762  {
763  global $adm, $edit, $tx, $s, $o, $f, $title;
764 
765  if (!XH_ADM && $adm) {
766  $s = -1;
767  $adm = $edit = false;
768  $o = '';
769  $f = 'login';
770  $title = utf8_ucfirst($tx['menu']['login']);
771  loginforms();
772  }
773  }
774 
782  public function renderErrorMessages()
783  {
784  global $e;
785 
786  if ($e) {
787  return '<div class="xh_warning">' . "\n"
788  . '<ul>' . "\n" . $e . '</ul>' . "\n" . '</div>' . "\n";
789  } else {
790  return '';
791  }
792  }
793 
808  public function sendStandardHeaders()
809  {
810  global $sl, $cf, $tx;
811 
812  $file = $line = null; // for unit test mocking of headers_sent()
813  if (!headers_sent($file, $line)) {
814  header('Content-Type: text/html; charset=UTF-8');
815  header("Content-Language: $sl");
816  if ($cf['security']['frame_options'] != '') {
817  header('X-Frame-Options: ' . $cf['security']['frame_options']);
818  }
819  } else {
820  $location = $file . ':' . $line;
821  XH_exit(str_replace('{location}', $location, $tx['error']['headers']));
822  }
823  }
824 }
$download
Definition: cms.php:535
$action
Definition: cms.php:460
$userfiles
Definition: cms.php:587
XH_logMessage($type, $module, $category, $description)
Definition: functions.php:1523
$function
Definition: cms.php:473
$login
Definition: cms.php:486
loginforms()
Definition: functions.php:1556
makeFileEditor($class)
Definition: Controller.php:531
$su
Definition: cms.php:778
$e
Definition: cms.php:127
li(array $ta, $st)
Definition: tplfuncs.php:217
XH_saveEditorContents($text)
Definition: adminfuncs.php:976
$s
Definition: cms.php:953
rmnl($t)
Definition: functions.php:559
logincheck()
Definition: functions.php:1498
$xhpages
Definition: cms.php:724
utf8_ucfirst($string)
Definition: utf8.php:118
XH_startSession()
Definition: functions.php:2662
$i
Definition: cms.php:193
$settings
Definition: cms.php:675
$logout
Definition: cms.php:512
$title
Definition: cms.php:100
$cf
Definition: cms.php:272
$f
Definition: cms.php:836
$sitemap
Definition: cms.php:687
$normal
Definition: cms.php:617
hide($i)
Definition: functions.php:1100
setFunctionsAsPermitted()
Definition: Controller.php:577
$search
Definition: cms.php:652
if(!isset($cf['folders']['content'])) if($cf['site']['timezone'] !=='' &&function_exists('date_default_timezone_set')) $sl
Definition: cms.php:331
$file
Definition: cms.php:640
XH_exit($status=0)
Definition: functions.php:2401
XH_contentEditor()
Definition: adminfuncs.php:875
XH_logFileView()
Definition: adminfuncs.php:392
reportMissingExternal($name)
Definition: Controller.php:737
$media
Definition: cms.php:574
$o
Definition: cms.php:113
const CMSIMPLE_ROOT($temp as $i)
Definition: cms.php:747
e($et, $ft, $fn)
Definition: functions.php:655
$validate
Definition: cms.php:709
foreach(XH_plugins() as $plugin) $_XH_csrfProtection
Definition: cms.php:879
$tx
Definition: cms.php:363
stsl($t)
Definition: functions.php:606
const XH_ADM
Definition: cms.php:897
handlePasswordForgotten()
Definition: Controller.php:163
$keycut
Definition: cms.php:500
XH_extraBackup($suffix)
shead($s)
Definition: functions.php:1144
$text
Definition: cms.php:698
$pth
Definition: cms.php:230
$images
Definition: cms.php:561
XH_backup()
Definition: functions.php:1826
$pd_router
Definition: cms.php:929
$downloads
Definition: cms.php:548
$edit
Definition: cms.php:602
$mailform
Definition: cms.php:524
$cl
Definition: cms.php:918
$adm
Definition: cms.php:823
gc($s)
Definition: functions.php:1484
XH_message($type, $message)
Definition: functions.php:1806