Skip to content

Commit e438f68

Browse files
committed
Improve reporting
1 parent 029f72c commit e438f68

4 files changed

Lines changed: 56 additions & 151 deletions

File tree

Packages/Application/Sfi.Umo/Classes/Controller/BackendController.php

Lines changed: 21 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ function arrayDeepSet(&$array, $path, $value)
6868

6969
class BackendController extends AbstractModuleController
7070
{
71+
const INTERNAL_SIGNED_PDFS_RUN_MARKER = 'Генерация внутренних подписанных PDF запущена.';
7172

7273
/**
7374
* @Flow\Inject
@@ -138,13 +139,10 @@ class BackendController extends AbstractModuleController
138139
/**
139140
* @return void
140141
*/
141-
public function indexAction()
142+
public function indexAction(bool $showInternalSignedPdfsLog = false)
142143
{
143-
$logPath = $this->getInternalSignedPdfsLogPath();
144-
145-
$this->view->assign('internalSignedPdfsBasePath', $this->getInternalSignedPdfsBasePath());
146-
$this->view->assign('internalSignedPdfsLogPath', $logPath);
147-
$this->view->assign('internalSignedPdfsLog', $this->readLogTail($logPath));
144+
$this->view->assign('showInternalSignedPdfsLog', $showInternalSignedPdfsLog);
145+
$this->view->assign('internalSignedPdfsLog', $showInternalSignedPdfsLog ? $this->readLastInternalSignedPdfsRunLog($this->getInternalSignedPdfsLogPath()) : '');
148146
}
149147

150148
/**
@@ -166,73 +164,17 @@ public function generateSignedPdfsAction()
166164
*/
167165
public function generateInternalSignedPdfsAction()
168166
{
169-
$basePath = $this->getInternalSignedPdfsBasePath();
170-
$logPath = $this->getInternalSignedPdfsLogPath();
171-
172-
if (!$this->appendInternalSignedPdfsLog(sprintf('Запуск генерации внутренних подписанных PDF из интерфейса. Папка: %s', $basePath))) {
173-
$this->addFlashMessage(
174-
'Не удалось записать лог внутренних подписанных PDF: %s',
175-
'Ошибка записи лога',
176-
\Neos\Error\Messages\Message::SEVERITY_WARNING,
177-
[$logPath]
178-
);
179-
}
180-
167+
$this->appendInternalSignedPdfsLog(self::INTERNAL_SIGNED_PDFS_RUN_MARKER, true);
181168
Scripts::executeCommandAsync('sfi.sfi:signature:generateinternalsignedpdfs', $this->flowSettings, []);
182-
$this->addFlashMessage(sprintf('Генерация внутренних подписанных PDF запущена в фоновом режиме. Результаты будут сохранены в %s/*/signed/. Лог: %s', $basePath, $logPath));
183-
$this->redirect('index');
184-
}
185-
186-
/**
187-
* Check internal signed PDF input folders without generating files
188-
*
189-
* @return void
190-
*/
191-
public function dryRunInternalSignedPdfsAction()
192-
{
193-
$basePath = $this->getInternalSignedPdfsBasePath();
194-
$logPath = $this->getInternalSignedPdfsLogPath();
195-
196-
$this->appendInternalSignedPdfsLog(sprintf('Проверка внутренних PDF без генерации запущена из интерфейса. Папка: %s', $basePath));
197-
198-
$bufferLevel = ob_get_level();
199-
ob_start();
200-
201-
try {
202-
Scripts::executeCommand('sfi.sfi:signature:generateinternalsignedpdfs', $this->flowSettings, true, ['dry-run' => 'true']);
203-
$output = trim($this->collectOutputBuffer($bufferLevel));
204-
205-
$this->appendInternalSignedPdfsLog($output !== '' ? "Результат проверки:\n" . $output : 'Результат проверки: команда не вернула вывода.');
206-
$this->addFlashMessage(sprintf('Проверка внутренних PDF завершена. Результат записан в лог: %s', $logPath));
207-
} catch (\Exception $exception) {
208-
$output = trim($this->collectOutputBuffer($bufferLevel));
209-
$message = 'Ошибка проверки внутренних PDF: ' . $exception->getMessage();
210-
if ($output !== '') {
211-
$message .= "\nВывод команды:\n" . $output;
212-
}
213-
$this->appendInternalSignedPdfsLog($message);
214-
$this->addFlashMessage(
215-
'Проверка внутренних PDF завершилась с ошибкой. Подробности записаны в лог: %s',
216-
'Ошибка проверки',
217-
\Neos\Error\Messages\Message::SEVERITY_ERROR,
218-
[$logPath]
219-
);
220-
}
221-
222-
$this->redirect('index');
223-
}
224-
225-
protected function getInternalSignedPdfsBasePath(): string
226-
{
227-
return rtrim(FLOW_PATH_WEB, '/') . '/umo/internal';
169+
$this->redirect('index', null, null, ['showInternalSignedPdfsLog' => true]);
228170
}
229171

230172
protected function getInternalSignedPdfsLogPath(): string
231173
{
232174
return rtrim(FLOW_PATH_DATA, '/') . '/Logs/InternalSignedPdfs/generation.log';
233175
}
234176

235-
protected function appendInternalSignedPdfsLog(string $message): bool
177+
protected function appendInternalSignedPdfsLog(string $message, bool $truncate = false): bool
236178
{
237179
$message = trim($message);
238180
if ($message === '') {
@@ -250,58 +192,38 @@ protected function appendInternalSignedPdfsLog(string $message): bool
250192
$entry .= $timestamp . ' ' . $line . PHP_EOL;
251193
}
252194

253-
return @file_put_contents($this->getInternalSignedPdfsLogPath(), $entry, FILE_APPEND | LOCK_EX) !== false;
195+
$flags = $truncate ? LOCK_EX : FILE_APPEND | LOCK_EX;
196+
return @file_put_contents($this->getInternalSignedPdfsLogPath(), $entry, $flags) !== false;
254197
}
255198

256-
protected function readLogTail(string $logPath, int $maxBytes = 65536): string
199+
protected function readLastInternalSignedPdfsRunLog(string $logPath): string
257200
{
258201
if (!is_file($logPath)) {
259202
return '';
260203
}
261204

262-
$size = filesize($logPath);
263-
if ($size === false) {
205+
$contents = file_get_contents($logPath);
206+
if ($contents === false) {
264207
return '';
265208
}
266209

267-
$handle = fopen($logPath, 'rb');
268-
if ($handle === false) {
210+
$lines = preg_split('/\r\n|\r|\n/', trim($contents));
211+
if (!is_array($lines)) {
269212
return '';
270213
}
271214

272-
if ($size > $maxBytes) {
273-
fseek($handle, -$maxBytes, SEEK_END);
274-
}
275-
276-
$contents = stream_get_contents($handle);
277-
fclose($handle);
278-
279-
if ($contents === false) {
280-
return '';
281-
}
282-
283-
if ($size > $maxBytes) {
284-
$firstLineBreak = strpos($contents, "\n");
285-
if ($firstLineBreak !== false) {
286-
$contents = substr($contents, $firstLineBreak + 1);
215+
$startIndex = null;
216+
foreach ($lines as $index => $line) {
217+
if (strpos($line, self::INTERNAL_SIGNED_PDFS_RUN_MARKER) !== false) {
218+
$startIndex = $index;
287219
}
288-
$contents = "... показаны последние строки лога\n" . $contents;
289220
}
290221

291-
return $contents;
292-
}
293-
294-
protected function collectOutputBuffer(int $bufferLevel): string
295-
{
296-
$output = '';
297-
while (ob_get_level() > $bufferLevel) {
298-
$buffer = ob_get_clean();
299-
if ($buffer !== false) {
300-
$output = $buffer . $output;
301-
}
222+
if ($startIndex === null) {
223+
return '';
302224
}
303225

304-
return $output;
226+
return implode(PHP_EOL, array_slice($lines, $startIndex));
305227
}
306228

307229
protected $collectionByType = [

Packages/Application/Sfi.Umo/README.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,10 @@ PDF-файлы должны лежать прямо в той же папке,
5252
## Как запустить генерацию
5353

5454
1. Откройте модуль импорта УМО в административной части сайта.
55-
2. Если нужно сначала проверить, какие файлы будут найдены, нажмите кнопку `Проверить внутренние PDF без генерации`.
56-
3. Для запуска генерации нажмите кнопку `Генерировать внутренние подписанные PDF`.
57-
4. Генерация запустится в фоновом режиме.
55+
2. Нажмите кнопку `Генерировать внутренние подписанные PDF`.
56+
3. Генерация запустится в фоновом режиме.
5857

59-
Внизу страницы модуля показывается путь к рабочей папке, путь к логу и последние строки лога. После запуска генерации можно нажимать `Обновить лог`, чтобы увидеть текущий результат.
60-
61-
Лог записывается в файл в папке логов приложения:
62-
63-
```text
64-
Data/Logs/InternalSignedPdfs/generation.log
65-
```
58+
После запуска под кнопками появится журнал последней генерации. Если результат еще не обновился, обновите страницу через несколько секунд.
6659

6760
## Что появится в результате
6861

Packages/Application/Sfi.Umo/Resources/Private/Templates/Backend/Index.html

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,29 +34,19 @@
3434
<div><f:form.submit class="button" value="Генерировать внутренние подписанные PDF"/></div>
3535
</f:form>
3636

37-
<br/>
38-
39-
<f:form
40-
method="post"
41-
action="dryRunInternalSignedPdfs"
42-
controller="Backend"
43-
package="Sfi.Umo"
44-
>
45-
<div><f:form.submit class="button" value="Проверить внутренние PDF без генерации"/></div>
46-
</f:form>
47-
48-
<h2>Внутренние подписанные PDF</h2>
49-
<p>Папка с исходными файлами: <code>{internalSignedPdfsBasePath}</code></p>
50-
<p>Лог генерации: <code>{internalSignedPdfsLogPath}</code></p>
51-
52-
<f:link.action action="index" class="button">Обновить лог</f:link.action>
53-
54-
<f:if condition="{internalSignedPdfsLog}">
55-
<f:then>
56-
<pre style="margin-top: 16px; padding: 12px; max-height: 480px; overflow: auto; background: #f7f7f7; border: 1px solid #ccc; white-space: pre-wrap;">{internalSignedPdfsLog}</pre>
57-
</f:then>
58-
<f:else>
59-
<p>Лог пока пуст. Нажмите кнопку проверки или генерации, чтобы создать первую запись.</p>
60-
</f:else>
37+
<f:if condition="{showInternalSignedPdfsLog}">
38+
<section style="margin-top: 24px; max-width: 980px; padding: 16px; color: #222; background: #fff; border: 1px solid #d6d6d6;">
39+
<h2 style="margin: 0 0 8px; color: #222;">Внутренние подписанные PDF</h2>
40+
<p style="margin: 0 0 12px; color: #222;">Генерация запущена. Если результат еще не появился, обновите страницу через несколько секунд.</p>
41+
42+
<f:if condition="{internalSignedPdfsLog}">
43+
<f:then>
44+
<pre style="margin: 0; padding: 12px; max-height: 360px; overflow: auto; color: #222; background: #f7f7f7; border: 1px solid #ccc; white-space: pre-wrap;">{internalSignedPdfsLog}</pre>
45+
</f:then>
46+
<f:else>
47+
<p style="margin: 0; color: #222;">Журнал генерации появится здесь.</p>
48+
</f:else>
49+
</f:if>
50+
</section>
6151
</f:if>
6252
</f:section>

Packages/Sites/Sfi.Sfi/Classes/Sfi/Sfi/Command/SignatureCommandController.php

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -184,18 +184,18 @@ public function generateInternalSignedPdfsCommand(bool $force = false, bool $dry
184184
$logFile = $this->getInternalSignedPdfsLogPath();
185185

186186
if (!is_dir($internalBasePath)) {
187-
$this->log($logFile, $dryRun, 'Internal UMO folder does not exist: %s', [$internalBasePath]);
187+
$this->log($logFile, $dryRun, 'Папка с внутренними PDF не найдена.');
188188
return;
189189
}
190190

191-
$this->log($logFile, $dryRun, 'Starting internal signed PDF generation. Base path: %s', [$internalBasePath]);
191+
$this->log($logFile, $dryRun, 'Обработка файлов началась.');
192192

193193
$items = $this->collectInternalSignatureItems($internalBasePath, $logFile, $dryRun);
194194
$total = count($items);
195-
$this->log($logFile, $dryRun, 'Found %d internal PDF files to process.', [$total]);
195+
$this->log($logFile, $dryRun, 'Найдено PDF-файлов: %d', [$total]);
196196

197197
if ($total === 0) {
198-
$this->log($logFile, $dryRun, 'Nothing to do.');
198+
$this->log($logFile, $dryRun, 'Подходящих PDF-файлов не найдено.');
199199
return;
200200
}
201201

@@ -209,61 +209,61 @@ public function generateInternalSignedPdfsCommand(bool $force = false, bool $dry
209209
$progress = sprintf('[%d/%d]', $index + 1, $total);
210210

211211
if (!$force && file_exists($outputPath)) {
212-
$this->log($logFile, $dryRun, '%s SKIP (exists): %s', [$progress, $displayPath]);
212+
$this->log($logFile, $dryRun, '%s Уже готово: %s', [$progress, $displayPath]);
213213
$skipped++;
214214
continue;
215215
}
216216

217217
if ($dryRun) {
218-
$this->log($logFile, $dryRun, '%s DRY-RUN: would generate %s', [$progress, $displayPath]);
218+
$this->log($logFile, $dryRun, '%s Будет создано: %s', [$progress, $displayPath]);
219219
$processed++;
220220
continue;
221221
}
222222

223223
try {
224224
$pdfContent = $this->generateSignedPdfContent($item, 120);
225225
} catch (\Exception $e) {
226-
$this->log($logFile, $dryRun, '%s ERROR: %s -- %s', [$progress, $displayPath, $e->getMessage()]);
226+
$this->log($logFile, $dryRun, '%s ОШИБКА: %s -- %s', [$progress, $displayPath, $e->getMessage()]);
227227
$errors++;
228228
continue;
229229
}
230230

231231
if (strlen($pdfContent) < 5 || substr($pdfContent, 0, 5) !== '%PDF-') {
232-
$this->log($logFile, $dryRun, '%s ERROR: %s -- Response is not a valid PDF (%d bytes)', [$progress, $displayPath, strlen($pdfContent)]);
232+
$this->log($logFile, $dryRun, '%s ОШИБКА: сервис подписи вернул некорректный PDF для файла %s (%d байт)', [$progress, $displayPath, strlen($pdfContent)]);
233233
$errors++;
234234
continue;
235235
}
236236

237237
$outputDir = dirname($outputPath);
238238
if (!is_dir($outputDir)) {
239239
if (!mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
240-
$this->log($logFile, $dryRun, '%s ERROR: %s -- Could not create directory: %s', [$progress, $displayPath, $outputDir]);
240+
$this->log($logFile, $dryRun, '%s ОШИБКА: не удалось создать папку signed для файла %s', [$progress, $displayPath]);
241241
$errors++;
242242
continue;
243243
}
244244
}
245245

246246
$bytesWritten = file_put_contents($outputPath, $pdfContent);
247247
if ($bytesWritten === false) {
248-
$this->log($logFile, $dryRun, '%s ERROR: %s -- Failed to write file', [$progress, $displayPath]);
248+
$this->log($logFile, $dryRun, '%s ОШИБКА: не удалось сохранить подписанный PDF для файла %s', [$progress, $displayPath]);
249249
$errors++;
250250
continue;
251251
}
252252

253-
$this->log($logFile, $dryRun, '%s OK: %s (%s)', [$progress, $displayPath, $this->formatBytes($bytesWritten)]);
253+
$this->log($logFile, $dryRun, '%s Готово: %s (%s)', [$progress, $displayPath, $this->formatBytes($bytesWritten)]);
254254
$processed++;
255255
}
256256

257257
$this->log($logFile, $dryRun, '');
258-
$this->log($logFile, $dryRun, '--- Summary ---');
259-
$this->log($logFile, $dryRun, 'Total: %d', [$total]);
260-
$this->log($logFile, $dryRun, 'Generated: %d', [$processed]);
261-
$this->log($logFile, $dryRun, 'Skipped: %d', [$skipped]);
262-
$this->log($logFile, $dryRun, 'Errors: %d', [$errors]);
258+
$this->log($logFile, $dryRun, 'Итог:');
259+
$this->log($logFile, $dryRun, 'Всего: %d', [$total]);
260+
$this->log($logFile, $dryRun, 'Создано: %d', [$processed]);
261+
$this->log($logFile, $dryRun, 'Пропущено: %d', [$skipped]);
262+
$this->log($logFile, $dryRun, 'Ошибок: %d', [$errors]);
263263

264264
if ($dryRun) {
265265
$this->log($logFile, $dryRun, '');
266-
$this->log($logFile, $dryRun, 'This was a dry run. Remove --dry-run to actually generate files.');
266+
$this->log($logFile, $dryRun, 'Это была проверка без создания файлов.');
267267
}
268268
}
269269

@@ -398,7 +398,7 @@ protected function collectInternalSignatureItems(string $internalBasePath, strin
398398

399399
$items[] = [
400400
'relativePath' => $relativePath,
401-
'displayPath' => $relativePath . ' -> internal/' . $relativeFolderPath . '/signed/' . $filename,
401+
'displayPath' => $relativeFolderPath . '/' . $filename,
402402
'outputPath' => $outputPath,
403403
'url' => self::encodeURI($sourceUrlPrefix . $sourceUrl),
404404
'signDate' => $metadata['signDate']->format('d.m.Y'),

0 commit comments

Comments
 (0)