Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/config/routing/admin_accounting/journal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,11 @@ admin_accounting_journal_update_info:
methods: [POST]
requirements:
id: \d+

admin_accounting_journal_upload:
path: /upload/{id}
defaults:
_controller: AppBundle\Controller\Admin\Accounting\Journal\UploadAttachmentAction
methods: [POST]
requirements:
id: \d+
100 changes: 0 additions & 100 deletions htdocs/pages/administration/compta_journal.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,103 +251,3 @@

$smarty->assign('formulaire', genererFormulaire($formulaire));
}

/**
* Upload an attachment and save it on the specific line.
* We save the uploads in a directory at the same month of the line
* and we don't forget to rename the file with the date of the line
* and a unique identifier to keep it safe.
* If the line already has an attachment, we remove it before saving
* the new one in the line.
*/ elseif ($action === 'upload_attachment') {
try {
// Bad request?
if (!isset($_GET['id']) || !($line = $compta->obtenir((int) $_GET['id']))) {
throw new Exception("Please verify parameters", 400);
}

// Test line existence
if (!$line['id']) {
throw new Exception("Not found", 404);
}

// Avoid multiple upload
if (
!isset($_FILES['file']['error'])
|| is_array($_FILES['file']['error'])
) {
throw new RuntimeException('Invalid parameters. You can\'t upload multiple files.');
}

// The directory
$directory = date('Ym', strtotime((string) $line['date_ecriture'])) . DIRECTORY_SEPARATOR;
$uploadDirectory = AFUP_CHEMIN_RACINE . 'uploads' . DIRECTORY_SEPARATOR . $directory;
if (!is_dir($uploadDirectory)) {
mkdir($uploadDirectory, 0750, true);
}

// Get the file, rename it, and move it.
// Check $_FILES['file']['error'] value.
switch ($_FILES['file']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('No file sent.');
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('Exceeded filesize limit.');
default:
throw new RuntimeException('Unknown errors.');
}

// You should also check filesize here.
if ($_FILES['upfile']['size'] > 1000000) {
throw new RuntimeException('Exceeded filesize limit.');
}

// Check MIME Type
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (false === $ext = array_search(
$finfo->file($_FILES['file']['tmp_name']),
[
'jpg' => 'image/jpeg',
'png' => 'image/png',
'pdf' => 'application/pdf',
],
true,
)) {
throw new RuntimeException('Invalid file format. Only jpg/png/pdf allowed.');
}

// Move/Rename
$filename = sprintf('%s.%s',
date('Y-m-d', strtotime((string) $line['date_ecriture'])) . '_' . $line['id'] . '_' . substr(sha1_file($_FILES['file']['tmp_name']), 0, 6),
$ext,
);
$moved = move_uploaded_file(
$_FILES['file']['tmp_name'],
$uploadDirectory . $filename,
);
if (!$moved) {
throw new RuntimeException('Failed to move uploaded file.');
}

// Remove old file if exists
if ($line['attachment_filename']) {
$oldFilename = AFUP_CHEMIN_RACINE . 'uploads' . DIRECTORY_SEPARATOR . $line['attachment_filename'];
if (is_file($oldFilename)) {
unlink($oldFilename);
}
}

// Update line
$compta->modifierColonne($line['id'], 'attachment_filename', $directory . $filename);

header('HTTP/1.1 200 OK');
header('X-Info: File uploaded \o/');
} catch (Exception $e) {
header('HTTP/1.1 400 Bad Request');
echo $e->getMessage();
}
exit;
}
2 changes: 1 addition & 1 deletion htdocs/templates/administration/compta_journal.html
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ <h2>Journal</h2>
data-position="left center"
data-tooltip="Cliquez ou déposez un fichier dans la zone pour ajouter un justificatif"
>
<form action="index.php?page=compta_journal&amp;action=upload_attachment&amp;id={$ecriture.idtmp}"
<form action="/admin/accounting/journal/upload/{$ecriture.idtmp}"
class="js-dropzone{if !$ecriture.attachment_required}--lazy{/if} dz-journal-form ui center aligned tertiary blue segment"
style="display:none;cursor: pointer"
>
Expand Down
4 changes: 4 additions & 0 deletions htdocs/templates/administration/compta_journal.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
var initDropzone = function(container) {
$('.js-dropzone', container).each(function () {
var elmt = $(this);
// Skip if already initialized
if (elmt.hasClass('dz-clickable')) {
return;
}
elmt.dropzone({
url: elmt.attr('href'),
previewTemplate: $('.js-dz-preview-template').html(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace AppBundle\Controller\Admin\Accounting\Journal;

use AppBundle\Accounting\Model\Repository\TransactionRepository;
use AppBundle\Accounting\Model\Transaction;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\Constraints\File;
use Symfony\Component\Validator\Validator\ValidatorInterface;

class UploadAttachmentAction extends AbstractController
{
public function __construct(
private readonly TransactionRepository $transactionRepository,
private readonly ValidatorInterface $validator,
#[Autowire('%kernel.project_dir%/../htdocs/uploads/')] private readonly string $uploadDir,
) {}

public function __invoke(Request $request, int $id): Response
{
$transaction = $this->transactionRepository->get($id);
if (!$transaction instanceof Transaction) {
throw $this->createNotFoundException();
}

if (!$request->files->get('file') instanceof UploadedFile) {
return new Response('No file uploaded', 400);
}

$directory = $transaction->getAccountingDate()->format('Ym') . DIRECTORY_SEPARATOR;
$targetDir = $this->uploadDir . $directory;
if (!is_dir($targetDir)) {
mkdir($targetDir, 0750, true);
}
/** @var UploadedFile $file */
$file = $request->files->get('file');

$violations = $this->validator->validate($file, [
new File(mimeTypes: ['image/jpeg', 'image/png', 'application/pdf'], maxSize: '1M'),
]);
foreach ($violations as $violation) {
return new Response($violation->getMessage(), 400);
}

$filename = sprintf('%s.%s',
$transaction->getAccountingDate()->format('Y-m-d') . '_' . $transaction->getId() . '_' . substr(sha1_file($file->getPathname()), 0, 6),
$file->guessExtension(),
);
$file->move($targetDir, $filename);

if (!empty($transaction->getAttachmentFilename())) {
$oldFilename = $this->uploadDir . $transaction->getAttachmentFilename();
if (is_file($oldFilename)) {
unlink($oldFilename);
}
}

$transaction->setAttachmentFilename($directory . $filename);
$this->transactionRepository->save($transaction);

return new Response();
}
}
Loading