mirror of
https://github.com/til-schneider/slim-wiki.git
synced 2025-08-05 08:07:35 +02:00
Showing better error message if write permissions are missing
This commit is contained in:
@@ -4,6 +4,9 @@ $i18n = array(
|
||||
'error.noJavaScript' => 'Bitte aktivieren Sie JavaScript in den Einstellungen Ihres Browser um diese Seite verwenden zu können.',
|
||||
'error.browserNotSupported' => 'Ihr Browser wird nicht unterstützt. Bitte verwenden Sie einen aktuellen Browser.',
|
||||
'error.errorLogged' => 'Es ist ein Fehler aufgetreten. Bitte prüfen Sie die Log-Datei.',
|
||||
'error.editingArticleFailed' => 'Der Artikel kann nicht bearbeitet werden.',
|
||||
'error.missingWritePermissions.article' => 'Der Server hat keine Schreibrechte für die Artikel-Datei:',
|
||||
'error.missingWritePermissions.backup' => 'Der Server hat keine Schreibrechte für die Backup-Datei:',
|
||||
'button.cancel' => 'Abbrechen',
|
||||
'button.back' => 'Zurück',
|
||||
'button.edit' => 'Bearbeiten',
|
||||
|
@@ -4,6 +4,9 @@ $i18n = array(
|
||||
'error.noJavaScript' => 'Please activate JavaScript in the settings of your browser in order to use this site.',
|
||||
'error.browserNotSupported' => 'Your browser is not supported. Please use an up-to-date browser.',
|
||||
'error.errorLogged' => 'An error has occurred. Please have a look to the log file.',
|
||||
'error.editingArticleFailed' => 'Editing article failed.',
|
||||
'error.missingWritePermissions.article' => 'The server has no write permissions for the article file:',
|
||||
'error.missingWritePermissions.backup' => 'The server has no write permissions for the backup file:',
|
||||
'button.cancel' => 'Cancel',
|
||||
'button.back' => 'Back',
|
||||
'button.edit' => 'Edit',
|
||||
|
@@ -61,19 +61,24 @@ $mode = $data['mode'];
|
||||
if ($mode != 'view') {
|
||||
// Show an error message if JavaScript is off or if the browser is not supported.
|
||||
// NOTE: In view mode we don't show an error. Instead, syntax highlighting will be off for unsupported browsers.
|
||||
?><div id="fatal-error-message"><div><?php echo $i18n['error.noJavaScript']; ?></div><a class="btn btn-default" href="<?php echo $data['requestPath']; ?>"><?php echo $i18n['button.back']; ?></a></div>
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var errElem = document.getElementById('fatal-error-message');
|
||||
if (slimwiki.supportedBrowser) {
|
||||
errElem.parentNode.removeChild(errElem);
|
||||
} else {
|
||||
errElem.firstChild.innerHTML = <?php echo json_encode($i18n['error.browserNotSupported']); ?>;
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<div id="error-alert"><div class="alert alert-warning"><?php echo $i18n['error.errorLogged']; ?></div></div>
|
||||
?><div id="fatal-error-message"><div><?php echo ($mode == 'error') ? $data['fatalErrorMessage'] : $i18n['error.noJavaScript']; ?></div>
|
||||
<a class="btn btn-default" href="<?php echo $data['requestPath']; ?>"><?php echo $i18n['button.back']; ?></a>
|
||||
</div><?php
|
||||
|
||||
if ($mode != 'error') { ?>
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var errElem = document.getElementById('fatal-error-message');
|
||||
if (slimwiki.supportedBrowser) {
|
||||
errElem.parentNode.removeChild(errElem);
|
||||
} else {
|
||||
errElem.firstChild.innerHTML = <?php echo json_encode($i18n['error.browserNotSupported']); ?>;
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<div id="error-alert"><div class="alert alert-warning"><?php echo $i18n['error.errorLogged']; ?></div></div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode == 'edit') {
|
||||
@@ -151,7 +156,7 @@ if ($mode == 'edit') {
|
||||
|
||||
?></div><?php // id="main-wrapper" ?>
|
||||
|
||||
<?php if ($mode != 'view') { ?>
|
||||
<?php if ($mode == 'edit' || $mode == 'createUser') { ?>
|
||||
<!-- build:js client/edit.js -->
|
||||
<script src="client/libs/CodeMirror/lib/codemirror.js"></script>
|
||||
<script src="client/libs/CodeMirror/addon/mode/overlay.js"></script> <!-- Allow language-in-language -->
|
||||
@@ -169,13 +174,15 @@ if ($mode == 'edit') {
|
||||
|
||||
<script src="client/js/app-edit.js"></script>
|
||||
<!-- endbuild -->
|
||||
<?php } // if ($mode != 'view') ?>
|
||||
<?php } // if ($mode == 'edit' || $mode == 'createUser') ?>
|
||||
|
||||
<?php if ($mode != 'error') { ?>
|
||||
<!-- build:js client/view.js -->
|
||||
<script src="client/libs/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<script src="client/js/app-view.js"></script>
|
||||
<!-- endbuild -->
|
||||
<?php } // if ($mode != 'error') ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -36,6 +36,32 @@ class EditorService {
|
||||
}
|
||||
}
|
||||
|
||||
public function checkForError($articleFilename) {
|
||||
function canWriteFileOrParent($filename) {
|
||||
if ($filename == '') {
|
||||
return false;
|
||||
} else if (file_exists($filename)) {
|
||||
return is_writable($filename);
|
||||
} else {
|
||||
return canWriteFileOrParent(dirname($filename));
|
||||
}
|
||||
}
|
||||
|
||||
$articleFullFilename = $this->context->getArticleBaseDir() . $articleFilename;
|
||||
if (! canWriteFileOrParent($articleFullFilename)) {
|
||||
return $this->context->getI18n()['error.missingWritePermissions.article']
|
||||
. ' <code>' . $articleFullFilename . '</code>';
|
||||
}
|
||||
|
||||
$backupFullFilename = $this->context->getDataBaseDir() . $this->getBackupFilename($articleFilename);
|
||||
if (! canWriteFileOrParent($backupFullFilename)) {
|
||||
return $this->context->getI18n()['error.missingWritePermissions.backup']
|
||||
. ' <code>' . $backupFullFilename . '</code>';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function saveArticle($articleFilename, $markdownText) {
|
||||
$this->assertLoggedIn();
|
||||
|
||||
@@ -43,23 +69,26 @@ class EditorService {
|
||||
throw new Exception("Invalid article filename: '$articleFilename'");
|
||||
}
|
||||
|
||||
// Set timezone
|
||||
$this->context->getConfig();
|
||||
|
||||
// Write article file
|
||||
$articleFullFilename = $this->context->getArticleBaseDir() . $articleFilename;
|
||||
$articleDir = dirname($articleFullFilename);
|
||||
if (! file_exists($articleDir)) {
|
||||
mkdir($articleDir, 0777, true);
|
||||
}
|
||||
if (! is_writable(file_exists($articleFullFilename) ? $articleFullFilename : $articleDir)) {
|
||||
throw new Exception("No write permissions for article file");
|
||||
}
|
||||
file_put_contents($articleFullFilename, $markdownText);
|
||||
|
||||
// Write backup file (one per day)
|
||||
$backupFullFilename = $this->context->getDataBaseDir() . 'backup/' . $articleFilename . date('_Y-m-d') . '.gz';
|
||||
$backupFullFilename = $this->context->getDataBaseDir() . $this->getBackupFilename($articleFilename);
|
||||
$backupDir = dirname($backupFullFilename);
|
||||
if (! file_exists($backupDir)) {
|
||||
mkdir($backupDir, 0777, true);
|
||||
}
|
||||
if (! is_writable(file_exists($backupFullFilename) ? $backupFullFilename : $backupDir)) {
|
||||
throw new Exception("No write permissions for backup file");
|
||||
}
|
||||
$fp = gzopen ($backupFullFilename, 'w9');
|
||||
gzwrite ($fp, $markdownText);
|
||||
gzclose($fp);
|
||||
@@ -67,6 +96,13 @@ class EditorService {
|
||||
return $this->context->getRenderService()->renderMarkdown($markdownText, true);
|
||||
}
|
||||
|
||||
private function getBackupFilename($articleFilename) {
|
||||
// Set timezone
|
||||
$this->context->getConfig();
|
||||
|
||||
return 'backup/' . $articleFilename . date('_Y-m-d') . '.gz';
|
||||
}
|
||||
|
||||
public function createUserConfig($user, $pass) {
|
||||
$type = 'sha256';
|
||||
$salt = uniqid(mt_rand(), true);
|
||||
|
@@ -58,8 +58,8 @@ class Main {
|
||||
try {
|
||||
$responseData['result'] = call_user_func_array(array($object, $methodName), $requestData['params']);
|
||||
} catch (Exception $exc) {
|
||||
$msg = "Calling RPC $objectName.$methodName failed";
|
||||
error_log($msg . ': ' . $exc->getMessage());
|
||||
$msg = "Calling RPC $objectName.$methodName failed: " . $exc->getMessage();
|
||||
error_log($msg);
|
||||
$responseData['error'] = array( 'code' => -32000, 'message' => $msg );
|
||||
}
|
||||
}
|
||||
@@ -102,10 +102,20 @@ class Main {
|
||||
} else {
|
||||
$config = $this->context->getConfig();
|
||||
|
||||
$fatalErrorMessage = null;
|
||||
if ($mode == 'edit') {
|
||||
$fatalErrorMessage = $this->context->getEditorService()->checkForError($articleFilename);
|
||||
if ($fatalErrorMessage != null) {
|
||||
$fatalErrorMessage = $this->context->getI18n()['error.editingArticleFailed'] . '<br/>' . $fatalErrorMessage;
|
||||
$mode = 'error';
|
||||
}
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$data['baseUrl'] = $baseUrl;
|
||||
$data['basePath'] = $basePath;
|
||||
$data['mode'] = $mode;
|
||||
$data['fatalErrorMessage'] = $fatalErrorMessage;
|
||||
|
||||
foreach (array('wikiName', 'footerHtml') as $key) {
|
||||
$data[$key] = $config[$key];
|
||||
|
Reference in New Issue
Block a user