many fixes in design and add shirt story type for creation book

This commit is contained in:
2026-05-01 20:51:42 +03:00
parent 9294399517
commit ce6fffaa57
24 changed files with 1167 additions and 735 deletions
+99 -42
View File
@@ -26,13 +26,19 @@ class ExportController extends BaseController {
$this->redirect('/books');
}
// Для автора - все главы
$chapters = $chapterModel->findByBook($book_id);
// Для автора - все главы или контент рассказа
if ($book['is_short_story']) {
$chapters = [];
$is_short_story = true;
} else {
$chapters = $chapterModel->findByBook($book_id);
$is_short_story = false;
}
// Получаем информацию об авторе
$author_name = $this->getAuthorName($book['user_id']);
$this->handleExport($book, $chapters, false, $author_name, $format);
$this->handleExport($book, $chapters, false, $author_name, $format, $is_short_story);
}
public function exportShared($share_token, $format = 'pdf') {
@@ -45,13 +51,19 @@ class ExportController extends BaseController {
$this->redirect('/');
}
// Для публичного доступа - только опубликованные главы
$chapters = $chapterModel->getPublishedChapters($book['id']);
// Для публичного доступа - только опубликованные главы или контент рассказа
if ($book['is_short_story']) {
$chapters = [];
$is_short_story = true;
} else {
$chapters = $chapterModel->getPublishedChapters($book['id']);
$is_short_story = false;
}
// Получаем информацию об авторе
$author_name = $this->getAuthorName($book['user_id']);
$this->handleExport($book, $chapters, true, $author_name, $format);
$this->handleExport($book, $chapters, true, $author_name, $format, $is_short_story);
}
private function getAuthorName($user_id) {
@@ -68,21 +80,20 @@ class ExportController extends BaseController {
return "Неизвестный автор";
}
private function handleExport($book, $chapters, $is_public, $author_name, $format) {
private function handleExport($book, $chapters, $is_public, $author_name, $format, $is_short_story = false) {
switch ($format) {
case 'pdf':
$this->exportPDF($book, $chapters, $is_public, $author_name);
$this->exportPDF($book, $chapters, $is_public, $author_name, $is_short_story);
break;
case 'docx':
$this->exportDOCX($book, $chapters, $is_public, $author_name);
$this->exportDOCX($book, $chapters, $is_public, $author_name, $is_short_story);
break;
case 'html':
$this->exportHTML($book, $chapters, $is_public, $author_name);
$this->exportHTML($book, $chapters, $is_public, $author_name, $is_short_story);
break;
case 'txt':
$this->exportTXT($book, $chapters, $is_public, $author_name);
$this->exportTXT($book, $chapters, $is_public, $author_name, $is_short_story);
break;
default:
$_SESSION['error'] = "Неверный формат экспорта";
@@ -93,8 +104,7 @@ class ExportController extends BaseController {
}
}
function exportPDF($book, $chapters, $is_public, $author_name) {
function exportPDF($book, $chapters, $is_public, $author_name, $is_short_story = false) {
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
@@ -157,8 +167,17 @@ class ExportController extends BaseController {
$pdf->Ln(10);
}
// Интерактивное оглавление
$chapterLinks = [];
// Если это рассказ - сразу выводим контент
if ($is_short_story && !empty($book['content'])) {
$pdf->SetFont('dejavusans', '', 11);
$pdf->writeHTML($book['content'], true, false, true, false, '');
$pdf->Ln(8);
}
// Интерактивное оглавление (только для обычных книг)
if (!$is_short_story) {
$chapterLinks = [];
if (!empty($chapters)) {
if (!empty($chapters)) {
$pdf->SetFont('dejavusans', 'B', 14);
$pdf->Cell(0, 10, 'Оглавление', 0, 1, 'C');
@@ -220,7 +239,7 @@ class ExportController extends BaseController {
exit;
}
function exportDOCX($book, $chapters, $is_public, $author_name) {
function exportDOCX($book, $chapters, $is_public, $author_name, $is_short_story = false) {
$phpWord = new PhpWord();
@@ -271,8 +290,19 @@ class ExportController extends BaseController {
$section->addTextBreak(2);
}
// Интерактивное оглавление
if (!empty($chapters)) {
// Если это рассказ - сразу выводим контент
if ($is_short_story && !empty($book['content'])) {
$paragraphs = $this->htmlToParagraphs($book['content']);
foreach ($paragraphs as $paragraph) {
if (!empty(trim($paragraph))) {
$section->addText($paragraph);
$section->addTextBreak(1);
}
}
}
// Интерактивное оглавление (только для обычных книг)
if (!$is_short_story && !empty($chapters)) {
$section->addText('Оглавление', ['bold' => true, 'size' => 14], ['alignment' => 'center']);
$section->addTextBreak(1);
@@ -286,10 +316,13 @@ class ExportController extends BaseController {
}
// Разделитель
$section->addPageBreak();
if (!$is_short_story) {
$section->addPageBreak();
}
// Главы с закладками
foreach ($chapters as $index => $chapter) {
// Главы с закладками (только для обычных книг)
if (!$is_short_story) {
foreach ($chapters as $index => $chapter) {
// Добавляем закладку для главы
$section->addBookmark("chapter_{$chapter['id']}");
@@ -332,7 +365,7 @@ class ExportController extends BaseController {
exit;
}
function exportHTML($book, $chapters, $is_public, $author_name) {
function exportHTML($book, $chapters, $is_public, $author_name, $is_short_story = false) {
$html = '<!DOCTYPE html>
<html lang="ru">
@@ -514,8 +547,13 @@ class ExportController extends BaseController {
$html .= '</div>';
}
// Интерактивное оглавление
if (!empty($chapters)) {
// Если это рассказ - выводим контент сразу
if ($is_short_story && !empty($book['content'])) {
$html .= '<div class="chapter-content">' . $book['content'] . '</div>';
}
// Интерактивное оглавление (только для обычных книг)
if (!$is_short_story && !empty($chapters)) {
$html .= '<div class="table-of-contents">';
$html .= '<h3>Оглавление</h3>';
$html .= '<ul>';
@@ -554,7 +592,7 @@ class ExportController extends BaseController {
exit;
}
function exportTXT($book, $chapters, $is_public, $author_name) {
function exportTXT($book, $chapters, $is_public, $author_name, $is_short_story = false) {
$content = "=" . str_repeat("=", 80) . "=\n";
$content .= str_pad($book['title'], 80, " ", STR_PAD_BOTH) . "\n";
$content .= str_pad($author_name, 80, " ", STR_PAD_BOTH) . "\n";
@@ -578,20 +616,39 @@ class ExportController extends BaseController {
$content .= "\n";
}
// Оглавление
if (!empty($chapters)) {
$content .= "ОГЛАВЛЕНИЕ:\n";
$content .= str_repeat("-", 60) . "\n";
foreach ($chapters as $index => $chapter) {
$chapter_number = $index + 1;
$content .= "{$chapter_number}. {$chapter['title']}\n";
}
$content .= "\n";
}
$content .= str_repeat("-", 144) . "\n\n";
foreach ($chapters as $index => $chapter) {
// Если это рассказ - выводим контент сразу
if ($is_short_story && !empty($book['content'])) {
$content .= "СОДЕРЖАНИЕ РАССКАЗА:\n";
$content .= str_repeat("-", 60) . "\n\n";
$plainText = $this->htmlToPlainText($book['content']);
$paragraphs = explode("\n", $plainText);
foreach ($paragraphs as $paragraph) {
$trimmed = trim($paragraph);
if (!empty($trimmed)) {
$wrapped = wordwrap($trimmed, 144);
$content .= $wrapped . "\n\n";
}
}
}
// Оглавление (только для обычных книг)
if (!$is_short_story && !empty($chapters)) {
$content .= "ОГЛАВЛЕНИЕ:\n";
$content .= str_repeat("-", 60) . "\n";
foreach ($chapters as $index => $chapter) {
$chapter_number = $index + 1;
$content .= "{$chapter_number}. {$chapter['title']}\n";
}
$content .= "\n";
}
$content .= str_repeat("-", 144) . "\n\n";
// Главы (только для обычных книг)
if (!$is_short_story) {
foreach ($chapters as $index => $chapter) {
$content .= $chapter['title'] . "\n";
$content .= str_repeat("-", 60) . "\n\n";