Some fixes
This commit is contained in:
parent
971b163367
commit
76d33237b2
|
|
@ -28,7 +28,7 @@ if (!$bookModel->userOwnsBook($book_id, $user_id)) {
|
||||||
redirect('books.php');
|
redirect('books.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Получаем информацию о книге перед удалением (для сообщения)
|
// Получаем информацию о книге перед удалением
|
||||||
$book = $bookModel->findById($book_id);
|
$book = $bookModel->findById($book_id);
|
||||||
if (!empty($book['cover_image'])) {
|
if (!empty($book['cover_image'])) {
|
||||||
$cover_path = COVERS_PATH . $book['cover_image'];
|
$cover_path = COVERS_PATH . $book['cover_image'];
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
require_once 'config/config.php';
|
require_once 'config/config.php';
|
||||||
require_login();
|
require_login();
|
||||||
|
|
||||||
// Подключаем функции для обложек
|
|
||||||
|
|
||||||
$user_id = $_SESSION['user_id'];
|
$user_id = $_SESSION['user_id'];
|
||||||
$bookModel = new Book($pdo);
|
$bookModel = new Book($pdo);
|
||||||
|
|
||||||
|
|
@ -99,8 +97,6 @@ $page_title = $is_edit ? "Редактирование книги" : "Созда
|
||||||
include 'views/header.php';
|
include 'views/header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!-- Остальная часть формы остается той же, но добавляем поле обложки -->
|
|
||||||
|
|
||||||
<form method="post" enctype="multipart/form-data">
|
<form method="post" enctype="multipart/form-data">
|
||||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||||
|
|
||||||
|
|
@ -147,7 +143,7 @@ include 'views/header.php';
|
||||||
placeholder="Номер по порядку в серии"
|
placeholder="Номер по порядку в серии"
|
||||||
min="1"
|
min="1"
|
||||||
style="width: 100%; margin-bottom: 1.5rem;">
|
style="width: 100%; margin-bottom: 1.5rem;">
|
||||||
<!-- ПОЛЕ ДЛЯ ОБЛОЖКИ -->
|
<!-- Обложка -->
|
||||||
<div style="margin-bottom: 1.5rem;">
|
<div style="margin-bottom: 1.5rem;">
|
||||||
<label for="cover_image" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
<label for="cover_image" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||||
Обложка книги
|
Обложка книги
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ include 'views/header.php';
|
||||||
</article>
|
</article>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
<!-- Модальное окно для удаления всех книг -->
|
<!-- Подтверждение удаления всех книг -->
|
||||||
<dialog id="deleteAllDialog" style="border-radius: 8px; padding: 20px; max-width: 500px; background-color: #fff;">
|
<dialog id="deleteAllDialog" style="border-radius: 8px; padding: 20px; max-width: 500px; background-color: #fff;">
|
||||||
<h3 style="margin-top: 0;">Удалить все книги?</h3>
|
<h3 style="margin-top: 0;">Удалить все книги?</h3>
|
||||||
<p>Это действие удалит все ваши книги и все связанные с ними главы. Это действие нельзя отменить.</p>
|
<p>Это действие удалит все ваши книги и все связанные с ними главы. Это действие нельзя отменить.</p>
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ if (!$chapterModel->userOwnsChapter($chapter_id, $user_id)) {
|
||||||
redirect('books.php');
|
redirect('books.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Получаем информацию о главе перед удалением (для редиректа)
|
|
||||||
$chapter = $chapterModel->findById($chapter_id);
|
$chapter = $chapterModel->findById($chapter_id);
|
||||||
$book_id = $chapter['book_id'];
|
$book_id = $chapter['book_id'];
|
||||||
|
|
||||||
|
|
@ -39,6 +39,5 @@ if ($chapterModel->delete($chapter_id)) {
|
||||||
$_SESSION['error'] = "Ошибка при удалении главы";
|
$_SESSION['error'] = "Ошибка при удалении главы";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Редирект обратно к списку глав книги
|
|
||||||
redirect("chapters.php?book_id=$book_id");
|
redirect("chapters.php?book_id=$book_id");
|
||||||
?>
|
?>
|
||||||
|
|
@ -23,7 +23,6 @@ if ($chapter_id) {
|
||||||
$is_edit = true;
|
$is_edit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверяем, что book_id указан и пользователь имеет доступ к книге
|
|
||||||
if (!$book_id) {
|
if (!$book_id) {
|
||||||
$_SESSION['error'] = "Не указана книга";
|
$_SESSION['error'] = "Не указана книга";
|
||||||
redirect('books.php');
|
redirect('books.php');
|
||||||
|
|
@ -47,8 +46,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
// Обработка автосохранения
|
// Обработка автосохранения
|
||||||
if (isset($_POST['autosave']) && $_POST['autosave'] === 'true') {
|
if (isset($_POST['autosave']) && $_POST['autosave'] === 'true') {
|
||||||
// Автосохранение работает только для существующих глав
|
// Автосохранение работает только для существующих глав
|
||||||
|
// Если это не редактирование, игнорируем автосохранение
|
||||||
if (!$is_edit) {
|
if (!$is_edit) {
|
||||||
// Если это не редактирование, игнорируем автосохранение
|
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
echo json_encode(['success' => false, 'message' => 'Автосохранение недоступно для новых глав']);
|
echo json_encode(['success' => false, 'message' => 'Автосохранение недоступно для новых глав']);
|
||||||
exit;
|
exit;
|
||||||
|
|
@ -200,7 +200,6 @@ include 'views/header.php';
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- Основные кнопки формы - Сохранить, Отмена и Предпросмотр -->
|
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button type="submit" form="main-form" class="contrast">
|
<button type="submit" form="main-form" class="contrast">
|
||||||
<?= $is_edit ? '💾 Сохранить изменения' : '📝 Создать главу' ?>
|
<?= $is_edit ? '💾 Сохранить изменения' : '📝 Создать главу' ?>
|
||||||
|
|
@ -215,13 +214,12 @@ include 'views/header.php';
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Скрытая форма для предпросмотра -->
|
<!-- Форма для предпросмотра -->
|
||||||
<form method="post" action="preview.php" target="_blank" id="preview-form" style="display: none;">
|
<form method="post" action="preview.php" target="_blank" id="preview-form" style="display: none;">
|
||||||
<input type="hidden" name="content" id="preview-content">
|
<input type="hidden" name="content" id="preview-content">
|
||||||
<input type="hidden" name="title" id="preview-title" value="<?= e($chapter['title'] ?? 'Новая глава') ?>">
|
<input type="hidden" name="title" id="preview-title" value="<?= e($chapter['title'] ?? 'Новая глава') ?>">
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- Дополнительные кнопки (вне основной формы) -->
|
|
||||||
<?php if ($is_edit): ?>
|
<?php if ($is_edit): ?>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<a href="chapter_edit.php?book_id=<?= $book_id ?>" role="button">
|
<a href="chapter_edit.php?book_id=<?= $book_id ?>" role="button">
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ if (!$book_id) {
|
||||||
$bookModel = new Book($pdo);
|
$bookModel = new Book($pdo);
|
||||||
$chapterModel = new Chapter($pdo);
|
$chapterModel = new Chapter($pdo);
|
||||||
|
|
||||||
// Проверяем права доступа к книге
|
|
||||||
if (!$bookModel->userOwnsBook($book_id, $user_id)) {
|
if (!$bookModel->userOwnsBook($book_id, $user_id)) {
|
||||||
$_SESSION['error'] = "У вас нет доступа к этой книге";
|
$_SESSION['error'] = "У вас нет доступа к этой книге";
|
||||||
redirect('books.php');
|
redirect('books.php');
|
||||||
|
|
|
||||||
|
|
@ -55,10 +55,7 @@ if ($book) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$author_name = $author_info['display_name'] ?? $author_info['username'] ?? 'Неизвестный автор';
|
$author_name = $author_info['display_name'] ?? $author_info['username'] ?? 'Неизвестный автор';
|
||||||
// Функция для очистки имени файла
|
|
||||||
// function cleanFilename($filename) {
|
|
||||||
// return preg_replace('/[^a-zA-Z0-9_\-]/', '_', $filename);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Функция для преобразования Markdown в чистый текст с форматированием абзацев
|
// Функция для преобразования Markdown в чистый текст с форматированием абзацев
|
||||||
function markdownToPlainText($markdown) {
|
function markdownToPlainText($markdown) {
|
||||||
|
|
@ -98,7 +95,7 @@ function markdownToPlainText($markdown) {
|
||||||
|
|
||||||
return $text;
|
return $text;
|
||||||
}
|
}
|
||||||
// Улучшенная функция для разбивки Markdown на абзацы с сохранением структуры
|
// Функция для разбивки Markdown на абзацы с сохранением структуры
|
||||||
function markdownToParagraphs($markdown) {
|
function markdownToParagraphs($markdown) {
|
||||||
// Нормализуем переносы строк
|
// Нормализуем переносы строк
|
||||||
$text = str_replace(["\r\n", "\r"], "\n", $markdown);
|
$text = str_replace(["\r\n", "\r"], "\n", $markdown);
|
||||||
|
|
@ -239,9 +236,6 @@ switch ($format) {
|
||||||
case 'docx':
|
case 'docx':
|
||||||
exportDOCX($book, $chapters, $is_public, $author_name);
|
exportDOCX($book, $chapters, $is_public, $author_name);
|
||||||
break;
|
break;
|
||||||
case 'odt':
|
|
||||||
exportODT($book, $chapters, $is_public, $author_name);
|
|
||||||
break;
|
|
||||||
case 'html':
|
case 'html':
|
||||||
exportHTML($book, $chapters, $is_public, $author_name);
|
exportHTML($book, $chapters, $is_public, $author_name);
|
||||||
break;
|
break;
|
||||||
|
|
@ -317,7 +311,7 @@ function exportPDF($book, $chapters, $is_public, $author_name) {
|
||||||
$pdf->Ln(10);
|
$pdf->Ln(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Интерактивное оглавление - СОЗДАЕМ ССЫЛКИ
|
// Интерактивное оглавление
|
||||||
$chapterLinks = [];
|
$chapterLinks = [];
|
||||||
if (!empty($chapters)) {
|
if (!empty($chapters)) {
|
||||||
$pdf->SetFont('dejavusans', 'B', 14);
|
$pdf->SetFont('dejavusans', 'B', 14);
|
||||||
|
|
@ -433,7 +427,7 @@ function exportDOCX($book, $chapters, $is_public, $author_name) {
|
||||||
|
|
||||||
foreach ($chapters as $index => $chapter) {
|
foreach ($chapters as $index => $chapter) {
|
||||||
$chapter_number = $index + 1;
|
$chapter_number = $index + 1;
|
||||||
// Создаем гиперссылку на заголовок главы - ИСПРАВЛЕННЫЙ СИНТАКСИС
|
// Создаем гиперссылку на заголовок главы
|
||||||
$section->addLink("chapter_{$chapter['id']}", "{$chapter_number}. {$chapter['title']}", null, null, true);
|
$section->addLink("chapter_{$chapter['id']}", "{$chapter_number}. {$chapter['title']}", null, null, true);
|
||||||
$section->addTextBreak(1);
|
$section->addTextBreak(1);
|
||||||
}
|
}
|
||||||
|
|
@ -443,9 +437,9 @@ function exportDOCX($book, $chapters, $is_public, $author_name) {
|
||||||
// Разделитель
|
// Разделитель
|
||||||
$section->addPageBreak();
|
$section->addPageBreak();
|
||||||
|
|
||||||
// Главы с закладками - ДОБАВЛЯЕМ ПРАВИЛЬНЫЕ ЗАКЛАДКИ
|
// Главы с закладками
|
||||||
foreach ($chapters as $index => $chapter) {
|
foreach ($chapters as $index => $chapter) {
|
||||||
// Добавляем закладку для главы ПЕРЕД заголовком
|
// Добавляем закладку для главы
|
||||||
$section->addBookmark("chapter_{$chapter['id']}");
|
$section->addBookmark("chapter_{$chapter['id']}");
|
||||||
|
|
||||||
// Заголовок главы
|
// Заголовок главы
|
||||||
|
|
@ -588,7 +582,7 @@ function exportHTML($book, $chapters, $is_public, $author_name) {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
/* Улучшаем отображение абзацев */
|
/* Отображение абзацев */
|
||||||
.chapter-content p {
|
.chapter-content p {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
text-align: justify;
|
text-align: justify;
|
||||||
|
|
@ -720,7 +714,7 @@ function exportTXT($book, $chapters, $is_public, $author_name) {
|
||||||
|
|
||||||
if (!empty($book['description'])) {
|
if (!empty($book['description'])) {
|
||||||
$content .= "ОПИСАНИЕ:\n";
|
$content .= "ОПИСАНИЕ:\n";
|
||||||
// Увеличиваем ширину до 144 символов (80 * 1.8)
|
// Ширина до 144 символов
|
||||||
$content .= wordwrap($book['description'], 144) . "\n\n";
|
$content .= wordwrap($book['description'], 144) . "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue