diff --git a/src/Controller/PartListsController.php b/src/Controller/PartListsController.php
index e544c481..a714f7eb 100644
--- a/src/Controller/PartListsController.php
+++ b/src/Controller/PartListsController.php
@@ -22,6 +22,7 @@ declare(strict_types=1);
namespace App\Controller;
+use App\DataTables\ErrorDataTable;
use App\DataTables\Filters\PartFilter;
use App\DataTables\Filters\PartSearchFilter;
use App\DataTables\PartsDataTable;
@@ -33,6 +34,7 @@ use App\Entity\Parts\Supplier;
use App\Form\Filters\PartFilterType;
use App\Services\Parts\PartsTableActionHandler;
use App\Services\Trees\NodesListBuilder;
+use Doctrine\DBAL\Exception\DriverException;
use Doctrine\ORM\EntityManagerInterface;
use Omines\DataTablesBundle\DataTableFactory;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -41,6 +43,7 @@ use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
+use Symfony\Contracts\Translation\TranslatorInterface;
class PartListsController extends AbstractController
{
@@ -48,11 +51,14 @@ class PartListsController extends AbstractController
private NodesListBuilder $nodesListBuilder;
private DataTableFactory $dataTableFactory;
- public function __construct(EntityManagerInterface $entityManager, NodesListBuilder $nodesListBuilder, DataTableFactory $dataTableFactory)
+ private TranslatorInterface $translator;
+
+ public function __construct(EntityManagerInterface $entityManager, NodesListBuilder $nodesListBuilder, DataTableFactory $dataTableFactory, TranslatorInterface $translator)
{
$this->entityManager = $entityManager;
$this->nodesListBuilder = $nodesListBuilder;
$this->dataTableFactory = $dataTableFactory;
+ $this->translator = $translator;
}
/**
@@ -144,7 +150,21 @@ class PartListsController extends AbstractController
->handleRequest($request);
if ($table->isCallback()) {
- return $table->getResponse();
+ try {
+ return $table->getResponse();
+ } catch (DriverException $driverException) {
+ if ($driverException->getCode() === 1139) {
+
+ //Show only the part after "1139"
+ $regex_message = preg_replace('/^.*1139 /', '', $driverException->getMessage());
+
+ $errors = $this->translator->trans('part.table.invalid_regex') . ': ' . $regex_message;
+
+ return ErrorDataTable::errorTable($this->dataTableFactory, $request, $errors);
+ } else {
+ throw $driverException;
+ }
+ }
}
return $this->render($template, array_merge([
diff --git a/src/DataTables/ErrorDataTable.php b/src/DataTables/ErrorDataTable.php
new file mode 100644
index 00000000..29888f17
--- /dev/null
+++ b/src/DataTables/ErrorDataTable.php
@@ -0,0 +1,85 @@
+.
+ */
+
+namespace App\DataTables;
+
+use App\DataTables\Column\RowClassColumn;
+use App\Entity\Parts\Part;
+use Omines\DataTablesBundle\Adapter\ArrayAdapter;
+use Omines\DataTablesBundle\Column\TextColumn;
+use Omines\DataTablesBundle\DataTable;
+use Omines\DataTablesBundle\DataTableFactory;
+use Omines\DataTablesBundle\DataTableTypeInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class ErrorDataTable implements DataTableTypeInterface
+{
+ public function configureOptions(OptionsResolver $optionsResolver): void
+ {
+ $optionsResolver->setRequired('errors');
+ $optionsResolver->setAllowedTypes('errors', ['array', 'string']);
+ $optionsResolver->setNormalizer('errors', function (OptionsResolver $optionsResolver, $errors) {
+ if (is_string($errors)) {
+ $errors = [$errors];
+ }
+
+ return $errors;
+ });
+ }
+
+ public function configure(DataTable $dataTable, array $options)
+ {
+ $optionsResolver = new OptionsResolver();
+ $this->configureOptions($optionsResolver);
+ $options = $optionsResolver->resolve($options);
+
+ $dataTable
+ ->add('dont_matter_we_only_set_color', RowClassColumn::class, [
+ 'render' => function ($value, $context) {
+ return 'table-warning';
+ },
+ ])
+
+ ->add('error', TextColumn::class, [
+ 'label' => 'error_table.error',
+ 'render' => function ($value, $context) {
+ return ' ' . $value;
+ },
+ ])
+ ;
+
+ //Build the array containing data
+ $data = [];
+ foreach ($options['errors'] as $error) {
+ $data[] = ['error' => $error];
+ }
+
+ $dataTable->createAdapter(ArrayAdapter::class, $data);
+ }
+
+ public static function errorTable(DataTableFactory $dataTableFactory, Request $request, $errors): Response
+ {
+ $error_table = $dataTableFactory->createFromType(self::class, ['errors' => $errors]);
+ $error_table->handleRequest($request);
+ return $error_table->getResponse();
+ }
+}
\ No newline at end of file
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 788f7474..9f7464c2 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -10960,31 +10960,31 @@ Element 3
-
+
attachment.max_file_size
Maximum file size
-
+
user.saml_user
SSO / SAML user
-
+
user.saml_user.pw_change_hint
Your user uses single sign-on (SSO). You can not change the password and 2FA settings here. Configure them on your central SSO provider instead!
-
+
login.sso_saml_login
Single Sign-On Login (SSO)
-
+
login.local_login_hint
The form below is only for log in with a local user. If you want to log in via single sign-on, press the button above.
@@ -11188,106 +11188,118 @@ Element 3
-
+
measurement_unit.new
New Measurement Unit
-
+
measurement_unit.edit
Edit Measurement Unit
-
+
user.aboutMe.label
About Me
-
+
storelocation.owner.label
Owner
-
+
storelocation.part_owner_must_match.label
Part Lot owner must match storage location owner
-
+
part_lot.owner
Owner
-
+
part_lot.owner.help
Only the owner can withdraw or add stock to this lot.
-
+
log.element_edited.changed_fields.owner
Owner
-
+
log.element_edited.changed_fields.instock_unknown
Amount unknown
-
+
log.element_edited.changed_fields.needs_refill
Refill needed
-
+
part.withdraw.access_denied
Not allowed to do the desired action. Please check your permissions and the owner of the part lots.
-
+
part.info.amount.less_than_desired
Less than desired
-
+
log.cli_user
CLI user
-
+
log.element_edited.changed_fields.part_owner_must_match
Part owner must match storage location owner
-
+
part.filter.lessThanDesired
- In stock less than desired (total amount < min. amount)
+
-
+
part.filter.lotOwner
Lot owner
-
+
user.show_email_on_profile.label
Show email on public profile page
+
+
+ error_table.error
+ An error occured during your request.
+
+
+
+
+ part.table.invalid_regex
+ Invalid Regex expression
+
+
diff --git a/translations/security.en.xlf b/translations/security.en.xlf
index 03d410c0..2c9d8957 100644
--- a/translations/security.en.xlf
+++ b/translations/security.en.xlf
@@ -8,7 +8,7 @@
-
+
saml.error.cannot_login_local_user_per_saml
You can not login as local user via SSO! Use your local user password instead.
diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf
index a24e6a0d..1f3438de 100644
--- a/translations/validators.en.xlf
+++ b/translations/validators.en.xlf
@@ -300,19 +300,19 @@
-
+
validator.attachment.name_not_blank
Set a value here, or upload a file to automatically use its filename as name for the attachment.
-
+
validator.part_lot.owner_must_match_storage_location_owner
The owner of this lot must match the owner of the selected storage location (%owner_name%)!
-
+
validator.part_lot.owner_must_not_be_anonymous
A lot owner must not be the anonymous user!