mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-12-14 23:19:30 +00:00
Merge branch 'master' into settings-bundle
This commit is contained in:
commit
3e657a7cac
305 changed files with 7543 additions and 4274 deletions
|
|
@ -52,7 +52,6 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||
use InvalidArgumentException;
|
||||
use Omines\DataTablesBundle\DataTableFactory;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
|
@ -61,6 +60,8 @@ use Symfony\Component\HttpFoundation\Request;
|
|||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||
use Symfony\Component\Validator\ConstraintViolationInterface;
|
||||
use Symfony\Component\Validator\ConstraintViolationListInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
use function Symfony\Component\Translation\t;
|
||||
|
|
@ -74,15 +75,10 @@ abstract class BaseAdminController extends AbstractController
|
|||
protected string $attachment_class = '';
|
||||
protected ?string $parameter_class = '';
|
||||
|
||||
/**
|
||||
* @var EventDispatcher|EventDispatcherInterface
|
||||
*/
|
||||
protected EventDispatcher|EventDispatcherInterface $eventDispatcher;
|
||||
|
||||
public function __construct(protected TranslatorInterface $translator, protected UserPasswordHasherInterface $passwordEncoder,
|
||||
protected AttachmentSubmitHandler $attachmentSubmitHandler,
|
||||
protected EventCommentHelper $commentHelper, protected HistoryHelper $historyHelper, protected TimeTravel $timeTravel,
|
||||
protected DataTableFactory $dataTableFactory, EventDispatcherInterface $eventDispatcher, protected LabelExampleElementsGenerator $barcodeExampleGenerator,
|
||||
protected DataTableFactory $dataTableFactory, protected EventDispatcherInterface $eventDispatcher, protected LabelExampleElementsGenerator $barcodeExampleGenerator,
|
||||
protected LabelGenerator $labelGenerator, protected EntityManagerInterface $entityManager)
|
||||
{
|
||||
if ('' === $this->entity_class || '' === $this->form_class || '' === $this->twig_template || '' === $this->route_base) {
|
||||
|
|
@ -96,7 +92,6 @@ abstract class BaseAdminController extends AbstractController
|
|||
if ('' === $this->parameter_class || ($this->parameter_class && !is_a($this->parameter_class, AbstractParameter::class, true))) {
|
||||
throw new InvalidArgumentException('You have to override the $parameter_class value with a valid Parameter class in your subclass!');
|
||||
}
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
protected function revertElementIfNeeded(AbstractDBElement $entity, ?string $timestamp): ?DateTime
|
||||
|
|
@ -192,10 +187,8 @@ abstract class BaseAdminController extends AbstractController
|
|||
}
|
||||
|
||||
//Ensure that the master picture is still part of the attachments
|
||||
if ($entity instanceof AttachmentContainingDBElement) {
|
||||
if ($entity->getMasterPictureAttachment() !== null && !$entity->getAttachments()->contains($entity->getMasterPictureAttachment())) {
|
||||
$entity->setMasterPictureAttachment(null);
|
||||
}
|
||||
if ($entity instanceof AttachmentContainingDBElement && ($entity->getMasterPictureAttachment() !== null && !$entity->getAttachments()->contains($entity->getMasterPictureAttachment()))) {
|
||||
$entity->setMasterPictureAttachment(null);
|
||||
}
|
||||
|
||||
$this->commentHelper->setMessage($form['log_comment']->getData());
|
||||
|
|
@ -283,10 +276,8 @@ abstract class BaseAdminController extends AbstractController
|
|||
}
|
||||
|
||||
//Ensure that the master picture is still part of the attachments
|
||||
if ($new_entity instanceof AttachmentContainingDBElement) {
|
||||
if ($new_entity->getMasterPictureAttachment() !== null && !$new_entity->getAttachments()->contains($new_entity->getMasterPictureAttachment())) {
|
||||
$new_entity->setMasterPictureAttachment(null);
|
||||
}
|
||||
if ($new_entity instanceof AttachmentContainingDBElement && ($new_entity->getMasterPictureAttachment() !== null && !$new_entity->getAttachments()->contains($new_entity->getMasterPictureAttachment()))) {
|
||||
$new_entity->setMasterPictureAttachment(null);
|
||||
}
|
||||
|
||||
$this->commentHelper->setMessage($form['log_comment']->getData());
|
||||
|
|
@ -333,8 +324,8 @@ abstract class BaseAdminController extends AbstractController
|
|||
try {
|
||||
$errors = $importer->importFileAndPersistToDB($file, $options);
|
||||
|
||||
foreach ($errors as $name => $error) {
|
||||
foreach ($error as $violation) {
|
||||
foreach ($errors as $name => ['violations' => $violations]) {
|
||||
foreach ($violations as $violation) {
|
||||
$this->addFlash('error', $name.': '.$violation->getMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -344,6 +335,7 @@ abstract class BaseAdminController extends AbstractController
|
|||
}
|
||||
}
|
||||
|
||||
ret:
|
||||
//Mass creation form
|
||||
$mass_creation_form = $this->createForm(MassCreationForm::class, ['entity_class' => $this->entity_class]);
|
||||
$mass_creation_form->handleRequest($request);
|
||||
|
|
@ -356,11 +348,14 @@ abstract class BaseAdminController extends AbstractController
|
|||
$results = $importer->massCreation($data['lines'], $this->entity_class, $data['parent'] ?? null, $errors);
|
||||
|
||||
//Show errors to user:
|
||||
foreach ($errors as $error) {
|
||||
if ($error['entity'] instanceof AbstractStructuralDBElement) {
|
||||
$this->addFlash('error', $error['entity']->getFullPath().':'.$error['violations']);
|
||||
} else { //When we don't have a structural element, we can only show the name
|
||||
$this->addFlash('error', $error['entity']->getName().':'.$error['violations']);
|
||||
foreach ($errors as ['entity' => $new_entity, 'violations' => $violations]) {
|
||||
/** @var ConstraintViolationInterface $violation */
|
||||
foreach ($violations as $violation) {
|
||||
if ($new_entity instanceof AbstractStructuralDBElement) {
|
||||
$this->addFlash('error', $new_entity->getFullPath().':'.$violation->getMessage());
|
||||
} else { //When we don't have a structural element, we can only show the name
|
||||
$this->addFlash('error', $new_entity->getName().':'.$violation->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -371,11 +366,10 @@ abstract class BaseAdminController extends AbstractController
|
|||
$em->flush();
|
||||
|
||||
if (count($results) > 0) {
|
||||
$this->addFlash('success', t('entity.mass_creation_flash', ['%COUNT%' => count($results)]));
|
||||
$this->addFlash('success', t('entity.mass_creation_flash', ['%COUNT%' => count($results)]));
|
||||
}
|
||||
}
|
||||
|
||||
ret:
|
||||
return $this->render($this->twig_template, [
|
||||
'entity' => $new_entity,
|
||||
'form' => $form,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
/**
|
||||
* @see \App\Tests\Controller\KiCadApiControllerTest
|
||||
*/
|
||||
#[Route('/kicad-api/v1')]
|
||||
class KiCadApiController extends AbstractController
|
||||
{
|
||||
|
|
@ -62,7 +65,7 @@ class KiCadApiController extends AbstractController
|
|||
#[Route('/parts/category/{category}.json', name: 'kicad_api_category')]
|
||||
public function categoryParts(?Category $category): Response
|
||||
{
|
||||
if ($category) {
|
||||
if ($category !== null) {
|
||||
$this->denyAccessUnlessGranted('read', $category);
|
||||
} else {
|
||||
$this->denyAccessUnlessGranted('@categories.read');
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ class LogController extends AbstractController
|
|||
|
||||
if (EventUndoMode::UNDO === $mode) {
|
||||
$this->undoLog($log_element);
|
||||
} elseif (EventUndoMode::REVERT === $mode) {
|
||||
} else {
|
||||
$this->revertLog($log_element);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class OAuthClientController extends AbstractController
|
|||
}
|
||||
|
||||
#[Route('/{name}/check', name: 'oauth_client_check')]
|
||||
public function check(string $name, Request $request): Response
|
||||
public function check(string $name): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('@system.manage_oauth_tokens');
|
||||
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ class PartController extends AbstractController
|
|||
$this->em->flush();
|
||||
if ($mode === 'new') {
|
||||
$this->addFlash('success', 'part.created_flash');
|
||||
} else if ($mode === 'edit') {
|
||||
} elseif ($mode === 'edit') {
|
||||
$this->addFlash('success', 'part.edited_flash');
|
||||
}
|
||||
|
||||
|
|
@ -358,11 +358,11 @@ class PartController extends AbstractController
|
|||
$template = '';
|
||||
if ($mode === 'new') {
|
||||
$template = 'parts/edit/new_part.html.twig';
|
||||
} else if ($mode === 'edit') {
|
||||
} elseif ($mode === 'edit') {
|
||||
$template = 'parts/edit/edit_part_info.html.twig';
|
||||
} else if ($mode === 'merge') {
|
||||
} elseif ($mode === 'merge') {
|
||||
$template = 'parts/edit/merge_parts.html.twig';
|
||||
} else if ($mode === 'update_from_ip') {
|
||||
} elseif ($mode === 'update_from_ip') {
|
||||
$template = 'parts/edit/update_from_ip.html.twig';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -207,6 +207,11 @@ class ProjectController extends AbstractController
|
|||
//Preset the BOM entries with the selected parts, when the form was not submitted yet
|
||||
$preset_data = new ArrayCollection();
|
||||
foreach (explode(',', (string) $request->get('parts', '')) as $part_id) {
|
||||
//Skip empty part IDs. Postgres seems to be especially sensitive to empty strings, as it does not allow them in integer columns
|
||||
if ($part_id === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$part = $entityManager->getRepository(Part::class)->find($part_id);
|
||||
if (null !== $part) {
|
||||
//If there is already a BOM entry for this part, we use this one (we edit it then)
|
||||
|
|
@ -214,7 +219,7 @@ class ProjectController extends AbstractController
|
|||
'project' => $project,
|
||||
'part' => $part
|
||||
]);
|
||||
if ($bom_entry) {
|
||||
if ($bom_entry !== null) {
|
||||
$preset_data->add($bom_entry);
|
||||
} else { //Otherwise create an empty one
|
||||
$entry = new ProjectBOMEntry();
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ use Symfony\Component\HttpFoundation\Response;
|
|||
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
/**
|
||||
* @see \App\Tests\Controller\ScanControllerTest
|
||||
*/
|
||||
#[Route(path: '/scan')]
|
||||
class ScanController extends AbstractController
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Component\Runtime\SymfonyRuntime;
|
||||
use App\Services\Attachments\AttachmentSubmitHandler;
|
||||
use App\Services\Attachments\AttachmentURLGenerator;
|
||||
use App\Services\Attachments\BuiltinAttachmentsFinder;
|
||||
|
|
@ -86,7 +87,7 @@ class ToolsController extends AbstractController
|
|||
'php_post_max_size' => ini_get('post_max_size'),
|
||||
'kernel_runtime_environment' => $this->getParameter('kernel.runtime_environment'),
|
||||
'kernel_runtime_mode' => $this->getParameter('kernel.runtime_mode'),
|
||||
'kernel_runtime' => $_SERVER['APP_RUNTIME'] ?? $_ENV['APP_RUNTIME'] ?? 'Symfony\\Component\\Runtime\\SymfonyRuntime',
|
||||
'kernel_runtime' => $_SERVER['APP_RUNTIME'] ?? $_ENV['APP_RUNTIME'] ?? SymfonyRuntime::class,
|
||||
|
||||
//DB section
|
||||
'db_type' => $DBInfoHelper->getDatabaseType() ?? 'Unknown',
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||
use RuntimeException;
|
||||
use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EnumType;
|
||||
|
|
@ -59,11 +58,8 @@ use Symfony\Component\Validator\Constraints\Length;
|
|||
#[Route(path: '/user')]
|
||||
class UserSettingsController extends AbstractController
|
||||
{
|
||||
protected EventDispatcher|EventDispatcherInterface $eventDispatcher;
|
||||
|
||||
public function __construct(protected bool $demo_mode, EventDispatcherInterface $eventDispatcher)
|
||||
public function __construct(protected bool $demo_mode, protected EventDispatcherInterface $eventDispatcher)
|
||||
{
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
#[Route(path: '/2fa_backup_codes', name: 'show_backup_codes')]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue