mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-07-03 06:54:34 +02:00
Merge remote-tracking branch 'origin/l10n_master' into l10n_master
This commit is contained in:
commit
8343fffc1c
140 changed files with 3217 additions and 4762 deletions
|
@ -110,9 +110,12 @@ $(document).on("ajaxUI:start ajaxUI:reload", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
//Register bootstrap select picker
|
//Register bootstrap select picker
|
||||||
$(document).on("ajaxUI:reload", function () {
|
$(document).on("ajaxUI:reload ajaxUI:start", function () {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
$(".selectpicker").selectpicker();
|
$(".selectpicker").selectpicker({
|
||||||
|
dropdownAlignRight: 'auto',
|
||||||
|
container: '#content',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//Use bootstrap tooltips for the most tooltips
|
//Use bootstrap tooltips for the most tooltips
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
"phpstan/phpstan": "^0.12.8",
|
"phpstan/phpstan": "^0.12.8",
|
||||||
"phpstan/phpstan-doctrine": "^0.12.9",
|
"phpstan/phpstan-doctrine": "^0.12.9",
|
||||||
"phpstan/phpstan-symfony": "^0.12.4",
|
"phpstan/phpstan-symfony": "^0.12.4",
|
||||||
|
"psalm/plugin-symfony": "^1.1",
|
||||||
"roave/security-advisories": "dev-master",
|
"roave/security-advisories": "dev-master",
|
||||||
"symfony/debug-pack": "*",
|
"symfony/debug-pack": "*",
|
||||||
"symfony/maker-bundle": "^1.13",
|
"symfony/maker-bundle": "^1.13",
|
||||||
|
|
635
composer.lock
generated
635
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -2,26 +2,14 @@ doctrine:
|
||||||
orm:
|
orm:
|
||||||
auto_generate_proxy_classes: false
|
auto_generate_proxy_classes: false
|
||||||
metadata_cache_driver:
|
metadata_cache_driver:
|
||||||
type: service
|
type: pool
|
||||||
id: doctrine.system_cache_provider
|
pool: doctrine.system_cache_pool
|
||||||
query_cache_driver:
|
query_cache_driver:
|
||||||
type: service
|
type: pool
|
||||||
id: doctrine.system_cache_provider
|
pool: doctrine.system_cache_pool
|
||||||
result_cache_driver:
|
result_cache_driver:
|
||||||
type: service
|
type: pool
|
||||||
id: doctrine.result_cache_provider
|
pool: doctrine.result_cache_pool
|
||||||
|
|
||||||
services:
|
|
||||||
doctrine.result_cache_provider:
|
|
||||||
class: Symfony\Component\Cache\DoctrineProvider
|
|
||||||
public: false
|
|
||||||
arguments:
|
|
||||||
- '@doctrine.result_cache_pool'
|
|
||||||
doctrine.system_cache_provider:
|
|
||||||
class: Symfony\Component\Cache\DoctrineProvider
|
|
||||||
public: false
|
|
||||||
arguments:
|
|
||||||
- '@doctrine.system_cache_pool'
|
|
||||||
|
|
||||||
framework:
|
framework:
|
||||||
cache:
|
cache:
|
||||||
|
|
|
@ -4,4 +4,4 @@ webpack_encore:
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
# Preload in production
|
# Preload in production
|
||||||
preload: false
|
preload: true
|
|
@ -8,7 +8,7 @@ webpack_encore:
|
||||||
# crossorigin: 'anonymous'
|
# crossorigin: 'anonymous'
|
||||||
|
|
||||||
# preload all rendered script and link tags automatically via the http2 Link header
|
# preload all rendered script and link tags automatically via the http2 Link header
|
||||||
#preload: false
|
preload: false
|
||||||
|
|
||||||
# Throw an exception if the entrypoints.json file is missing or an entry is missing from the data
|
# Throw an exception if the entrypoints.json file is missing or an entry is missing from the data
|
||||||
# strict_mode: false
|
# strict_mode: false
|
||||||
|
|
|
@ -187,6 +187,10 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
|
||||||
label: "perm.revert_elements"
|
label: "perm.revert_elements"
|
||||||
bit: 10
|
bit: 10
|
||||||
alsoSet: ["read", "edit", "create", "delete", "show_history"]
|
alsoSet: ["read", "edit", "create", "delete", "show_history"]
|
||||||
|
show_private:
|
||||||
|
label: "perm.attachment_show_private"
|
||||||
|
bit: 12
|
||||||
|
alsoSet: ["read"]
|
||||||
|
|
||||||
parts_order:
|
parts_order:
|
||||||
<<: *PART_ATTRIBUTE
|
<<: *PART_ATTRIBUTE
|
||||||
|
|
|
@ -33,6 +33,8 @@ services:
|
||||||
bind:
|
bind:
|
||||||
bool $demo_mode: '%demo_mode%'
|
bool $demo_mode: '%demo_mode%'
|
||||||
bool $gpdr_compliance : '%gpdr_compliance%'
|
bool $gpdr_compliance : '%gpdr_compliance%'
|
||||||
|
bool $kernel_debug: '%kernel.debug%'
|
||||||
|
string $kernel_cache_dir: '%kernel.cache_dir%'
|
||||||
|
|
||||||
# makes classes in src/ available to be used as services
|
# makes classes in src/ available to be used as services
|
||||||
# this creates a service per class whose id is the fully-qualified class name
|
# this creates a service per class whose id is the fully-qualified class name
|
||||||
|
|
59
psalm.xml
59
psalm.xml
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<psalm
|
<psalm
|
||||||
|
errorLevel="5"
|
||||||
totallyTyped="false"
|
totallyTyped="false"
|
||||||
resolveFromConfigFile="true"
|
resolveFromConfigFile="true"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
@ -7,49 +8,49 @@
|
||||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||||
>
|
>
|
||||||
<projectFiles>
|
<projectFiles>
|
||||||
<directory name="src" />
|
<directory name="src"/>
|
||||||
<ignoreFiles>
|
<ignoreFiles>
|
||||||
<directory name="vendor" />
|
<directory name="vendor"/>
|
||||||
</ignoreFiles>
|
</ignoreFiles>
|
||||||
</projectFiles>
|
</projectFiles>
|
||||||
|
|
||||||
<issueHandlers>
|
<issueHandlers>
|
||||||
<LessSpecificReturnType errorLevel="info" />
|
<LessSpecificReturnType errorLevel="info"/>
|
||||||
|
|
||||||
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
||||||
|
|
||||||
<DeprecatedMethod errorLevel="info" />
|
<DeprecatedMethod errorLevel="info"/>
|
||||||
<DeprecatedProperty errorLevel="info" />
|
<DeprecatedProperty errorLevel="info"/>
|
||||||
<DeprecatedClass errorLevel="info" />
|
<DeprecatedClass errorLevel="info"/>
|
||||||
<DeprecatedConstant errorLevel="info" />
|
<DeprecatedConstant errorLevel="info"/>
|
||||||
<DeprecatedFunction errorLevel="info" />
|
<DeprecatedFunction errorLevel="info"/>
|
||||||
<DeprecatedInterface errorLevel="info" />
|
<DeprecatedInterface errorLevel="info"/>
|
||||||
<DeprecatedTrait errorLevel="info" />
|
<DeprecatedTrait errorLevel="info"/>
|
||||||
|
|
||||||
<InternalMethod errorLevel="info" />
|
<InternalMethod errorLevel="info"/>
|
||||||
<InternalProperty errorLevel="info" />
|
<InternalProperty errorLevel="info"/>
|
||||||
<InternalClass errorLevel="info" />
|
<InternalClass errorLevel="info"/>
|
||||||
|
|
||||||
<MissingClosureReturnType errorLevel="info" />
|
<MissingClosureReturnType errorLevel="info"/>
|
||||||
<MissingReturnType errorLevel="info" />
|
<MissingReturnType errorLevel="info"/>
|
||||||
<MissingPropertyType errorLevel="info" />
|
<MissingPropertyType errorLevel="info"/>
|
||||||
<InvalidDocblock errorLevel="info" />
|
<InvalidDocblock errorLevel="info"/>
|
||||||
<MisplacedRequiredParam errorLevel="info" />
|
<MisplacedRequiredParam errorLevel="info"/>
|
||||||
|
|
||||||
<PropertyNotSetInConstructor errorLevel="info" />
|
<PropertyNotSetInConstructor errorLevel="info"/>
|
||||||
<MissingConstructor errorLevel="info" />
|
<MissingConstructor errorLevel="info"/>
|
||||||
<MissingClosureParamType errorLevel="info" />
|
<MissingClosureParamType errorLevel="info"/>
|
||||||
<MissingParamType errorLevel="info" />
|
<MissingParamType errorLevel="info"/>
|
||||||
|
|
||||||
<RedundantCondition errorLevel="info" />
|
<RedundantCondition errorLevel="info"/>
|
||||||
|
|
||||||
<DocblockTypeContradiction errorLevel="info" />
|
<DocblockTypeContradiction errorLevel="info"/>
|
||||||
<RedundantConditionGivenDocblockType errorLevel="info" />
|
<RedundantConditionGivenDocblockType errorLevel="info"/>
|
||||||
|
|
||||||
<UnresolvableInclude errorLevel="info" />
|
<UnresolvableInclude errorLevel="info"/>
|
||||||
|
|
||||||
<RawObjectIteration errorLevel="info" />
|
<RawObjectIteration errorLevel="info"/>
|
||||||
|
|
||||||
<InvalidStringClass errorLevel="info" />
|
<InvalidStringClass errorLevel="info"/>
|
||||||
</issueHandlers>
|
</issueHandlers>
|
||||||
</psalm>
|
<plugins><pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin"/></plugins></psalm>
|
||||||
|
|
|
@ -197,7 +197,7 @@ abstract class BaseAdminController extends AbstractController
|
||||||
//We can not use dynamic form events here, because the parent entity list is build from database!
|
//We can not use dynamic form events here, because the parent entity list is build from database!
|
||||||
$form = $this->createForm($this->form_class, $entity, [
|
$form = $this->createForm($this->form_class, $entity, [
|
||||||
'attachment_class' => $this->attachment_class,
|
'attachment_class' => $this->attachment_class,
|
||||||
'parameter_class' => $this->parameter_class
|
'parameter_class' => $this->parameter_class,
|
||||||
]);
|
]);
|
||||||
} elseif ($form->isSubmitted() && ! $form->isValid()) {
|
} elseif ($form->isSubmitted() && ! $form->isValid()) {
|
||||||
$this->addFlash('error', 'entity.edit_flash.invalid');
|
$this->addFlash('error', 'entity.edit_flash.invalid');
|
||||||
|
|
|
@ -72,7 +72,7 @@ class FootprintController extends BaseAdminController
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse
|
* @return \Symfony\Component\HttpFoundation\RedirectResponse
|
||||||
*/
|
*/
|
||||||
public function delete(Request $request, Footprint $entity, StructuralElementRecursionHelper $recursionHelper)
|
public function delete(Request $request, Footprint $entity, StructuralElementRecursionHelper $recursionHelper): \Symfony\Component\HttpFoundation\RedirectResponse
|
||||||
{
|
{
|
||||||
return $this->_delete($request, $entity, $recursionHelper);
|
return $this->_delete($request, $entity, $recursionHelper);
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ class FootprintController extends BaseAdminController
|
||||||
*
|
*
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public function edit(Footprint $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
|
public function edit(Footprint $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
|
||||||
{
|
{
|
||||||
return $this->_edit($entity, $request, $em, $timestamp);
|
return $this->_edit($entity, $request, $em, $timestamp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,10 @@ class AttachmentFileController extends AbstractController
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('read', $attachment);
|
$this->denyAccessUnlessGranted('read', $attachment);
|
||||||
|
|
||||||
|
if ($attachment->isSecure()) {
|
||||||
|
$this->denyAccessUnlessGranted('show_private', $attachment);
|
||||||
|
}
|
||||||
|
|
||||||
if ($attachment->isExternal()) {
|
if ($attachment->isExternal()) {
|
||||||
throw new RuntimeException('You can not download external attachments!');
|
throw new RuntimeException('You can not download external attachments!');
|
||||||
}
|
}
|
||||||
|
@ -97,6 +101,10 @@ class AttachmentFileController extends AbstractController
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('read', $attachment);
|
$this->denyAccessUnlessGranted('read', $attachment);
|
||||||
|
|
||||||
|
if ($attachment->isSecure()) {
|
||||||
|
$this->denyAccessUnlessGranted('show_private', $attachment);
|
||||||
|
}
|
||||||
|
|
||||||
if ($attachment->isExternal()) {
|
if ($attachment->isExternal()) {
|
||||||
throw new RuntimeException('You can not download external attachments!');
|
throw new RuntimeException('You can not download external attachments!');
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ use App\Services\LogSystem\EventUndoHelper;
|
||||||
use App\Services\LogSystem\TimeTravel;
|
use App\Services\LogSystem\TimeTravel;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Omines\DataTablesBundle\DataTableFactory;
|
use Omines\DataTablesBundle\DataTableFactory;
|
||||||
use phpDocumentor\Reflection\Element;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
@ -100,7 +99,7 @@ class LogController extends AbstractController
|
||||||
/**
|
/**
|
||||||
* @Route("/undo", name="log_undo", methods={"POST"})
|
* @Route("/undo", name="log_undo", methods={"POST"})
|
||||||
*/
|
*/
|
||||||
public function undoRevertLog(Request $request, EventUndoHelper $eventUndoHelper)
|
public function undoRevertLog(Request $request, EventUndoHelper $eventUndoHelper): \Symfony\Component\HttpFoundation\RedirectResponse
|
||||||
{
|
{
|
||||||
$mode = EventUndoHelper::MODE_UNDO;
|
$mode = EventUndoHelper::MODE_UNDO;
|
||||||
$id = $request->request->get('undo');
|
$id = $request->request->get('undo');
|
||||||
|
|
|
@ -44,7 +44,12 @@ namespace App\Controller;
|
||||||
|
|
||||||
use App\DataTables\LogDataTable;
|
use App\DataTables\LogDataTable;
|
||||||
use App\Entity\Parts\Category;
|
use App\Entity\Parts\Category;
|
||||||
|
use App\Entity\Parts\Footprint;
|
||||||
use App\Entity\Parts\Part;
|
use App\Entity\Parts\Part;
|
||||||
|
use App\Entity\Parts\PartLot;
|
||||||
|
use App\Entity\Parts\Storelocation;
|
||||||
|
use App\Entity\Parts\Supplier;
|
||||||
|
use App\Entity\PriceInformations\Orderdetail;
|
||||||
use App\Exceptions\AttachmentDownloadException;
|
use App\Exceptions\AttachmentDownloadException;
|
||||||
use App\Form\Part\PartBaseType;
|
use App\Form\Part\PartBaseType;
|
||||||
use App\Services\Attachments\AttachmentManager;
|
use App\Services\Attachments\AttachmentManager;
|
||||||
|
@ -57,6 +62,7 @@ use App\Services\Parameters\ParameterExtractor;
|
||||||
use App\Services\PricedetailHelper;
|
use App\Services\PricedetailHelper;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Omines\DataTablesBundle\DataTableFactory;
|
use Omines\DataTablesBundle\DataTableFactory;
|
||||||
|
use Proxies\__CG__\App\Entity\Parts\Manufacturer;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
|
@ -135,7 +141,7 @@ class PartController extends AbstractController
|
||||||
'pictures' => $this->partPreviewGenerator->getPreviewAttachments($part),
|
'pictures' => $this->partPreviewGenerator->getPreviewAttachments($part),
|
||||||
'timeTravel' => $timeTravel_timestamp,
|
'timeTravel' => $timeTravel_timestamp,
|
||||||
'description_params' => $parameterExtractor->extractParameters($part->getDescription()),
|
'description_params' => $parameterExtractor->extractParameters($part->getDescription()),
|
||||||
'comment_params' => $parameterExtractor->extractParameters($part->getComment())
|
'comment_params' => $parameterExtractor->extractParameters($part->getComment()),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -235,13 +241,42 @@ class PartController extends AbstractController
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted('create', $new_part);
|
$this->denyAccessUnlessGranted('create', $new_part);
|
||||||
|
|
||||||
$cid = $request->get('cid', 1);
|
$cid = $request->get('category', null);
|
||||||
|
$category = $cid ? $em->find(Category::class, $cid) : null;
|
||||||
$category = $em->find(Category::class, $cid);
|
|
||||||
if (null !== $category && null === $new_part->getCategory()) {
|
if (null !== $category && null === $new_part->getCategory()) {
|
||||||
$new_part->setCategory($category);
|
$new_part->setCategory($category);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$fid = $request->get('footprint', null);
|
||||||
|
$footprint = $fid ? $em->find(Footprint::class, $cid) : null;
|
||||||
|
if (null !== $footprint && null === $new_part->getFootprint()) {
|
||||||
|
$new_part->setFootprint($footprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
$mid = $request->get('manufacturer', null);
|
||||||
|
$manufacturer = $mid ? $em->find(Manufacturer::class, $mid) : null;
|
||||||
|
if (null !== $manufacturer && null === $new_part->getManufacturer()) {
|
||||||
|
$new_part->setManufacturer($manufacturer);
|
||||||
|
}
|
||||||
|
|
||||||
|
$store_id = $request->get('storelocation', null);
|
||||||
|
$storelocation = $store_id ? $em->find(Storelocation::class, $store_id): null;
|
||||||
|
if (null !== $storelocation && $new_part->getPartLots()->isEmpty()) {
|
||||||
|
$partLot = new PartLot();
|
||||||
|
$partLot->setStorageLocation($storelocation);
|
||||||
|
$partLot->setInstockUnknown(true);
|
||||||
|
$new_part->addPartLot($partLot);
|
||||||
|
}
|
||||||
|
|
||||||
|
$supplier_id = $request->get('supplier', null);
|
||||||
|
$supplier = $supplier_id ? $em->find(Supplier::class, $supplier_id): null;
|
||||||
|
if (null !== $supplier && $new_part->getOrderdetails()->isEmpty()) {
|
||||||
|
$orderdetail = new Orderdetail();
|
||||||
|
$orderdetail->setSupplier($supplier);
|
||||||
|
$new_part->addOrderdetail($orderdetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$form = $this->createForm(PartBaseType::class, $new_part);
|
$form = $this->createForm(PartBaseType::class, $new_part);
|
||||||
|
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
|
@ -62,9 +62,11 @@ class TypeaheadController extends AbstractController
|
||||||
/**
|
/**
|
||||||
* @Route("/builtInResources/search/{query}", name="typeahead_builtInRessources", requirements={"query"= ".+"})
|
* @Route("/builtInResources/search/{query}", name="typeahead_builtInRessources", requirements={"query"= ".+"})
|
||||||
*
|
*
|
||||||
|
* @param string $query
|
||||||
|
* @param BuiltinAttachmentsFinder $finder
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function builtInResources(Request $request, string $query, BuiltinAttachmentsFinder $finder)
|
public function builtInResources(string $query, BuiltinAttachmentsFinder $finder)
|
||||||
{
|
{
|
||||||
$array = $finder->find($query);
|
$array = $finder->find($query);
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ declare(strict_types=1);
|
||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use App\Entity\Attachments\UserAttachment;
|
use App\Entity\Attachments\UserAttachment;
|
||||||
use App\Entity\Parameters\PartParameter;
|
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
use App\Form\Permissions\PermissionsType;
|
use App\Form\Permissions\PermissionsType;
|
||||||
use App\Form\UserAdminForm;
|
use App\Form\UserAdminForm;
|
||||||
|
@ -69,7 +68,7 @@ class UserController extends AdminPages\BaseAdminController
|
||||||
protected $route_base = 'user';
|
protected $route_base = 'user';
|
||||||
protected $attachment_class = UserAttachment::class;
|
protected $attachment_class = UserAttachment::class;
|
||||||
//Just define a value here to prevent error. It is not used.
|
//Just define a value here to prevent error. It is not used.
|
||||||
protected $parameter_class = "not used";
|
protected $parameter_class = 'not used';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="user_edit")
|
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="user_edit")
|
||||||
|
|
|
@ -43,7 +43,7 @@ declare(strict_types=1);
|
||||||
namespace App\DataFixtures;
|
namespace App\DataFixtures;
|
||||||
|
|
||||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||||
use Doctrine\Common\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
|
|
||||||
class AppFixtures extends Fixture
|
class AppFixtures extends Fixture
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,7 @@ use App\Entity\Parts\MeasurementUnit;
|
||||||
use App\Entity\Parts\Storelocation;
|
use App\Entity\Parts\Storelocation;
|
||||||
use App\Entity\Parts\Supplier;
|
use App\Entity\Parts\Supplier;
|
||||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||||
use Doctrine\Common\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace App\DataFixtures;
|
||||||
|
|
||||||
use App\Entity\UserSystem\Group;
|
use App\Entity\UserSystem\Group;
|
||||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||||
use Doctrine\Common\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
|
|
||||||
class GroupFixtures extends Fixture
|
class GroupFixtures extends Fixture
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,16 +89,16 @@ class PartFixtures extends Fixture
|
||||||
|
|
||||||
$orderdetail = new Orderdetail();
|
$orderdetail = new Orderdetail();
|
||||||
$orderdetail->setSupplier($manager->find(Supplier::class, 1));
|
$orderdetail->setSupplier($manager->find(Supplier::class, 1));
|
||||||
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(1.0)->setPrice("10.0"));
|
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(1.0)->setPrice('10.0'));
|
||||||
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(10.0)->setPrice("15.0"));
|
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(10.0)->setPrice('15.0'));
|
||||||
$part->addOrderdetail($orderdetail);
|
$part->addOrderdetail($orderdetail);
|
||||||
|
|
||||||
$orderdetail = new Orderdetail();
|
$orderdetail = new Orderdetail();
|
||||||
$orderdetail->setSupplierpartnr('BC 547');
|
$orderdetail->setSupplierpartnr('BC 547');
|
||||||
$orderdetail->setObsolete(true);
|
$orderdetail->setObsolete(true);
|
||||||
$orderdetail->setSupplier($manager->find(Supplier::class, 1));
|
$orderdetail->setSupplier($manager->find(Supplier::class, 1));
|
||||||
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(1.0)->setPrice("10.0"));
|
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(1.0)->setPrice('10.0'));
|
||||||
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(10.0)->setPrice("15.1"));
|
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(10.0)->setPrice('15.1'));
|
||||||
$part->addOrderdetail($orderdetail);
|
$part->addOrderdetail($orderdetail);
|
||||||
|
|
||||||
$attachment = new PartAttachment();
|
$attachment = new PartAttachment();
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace App\DataFixtures;
|
||||||
|
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||||
use Doctrine\Common\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ class FetchJoinORMAdapter extends ORMAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCount(QueryBuilder $queryBuilder, $identifier)
|
public function getCount(QueryBuilder $queryBuilder, string $identifier)
|
||||||
{
|
{
|
||||||
$paginator = new Paginator($queryBuilder);
|
$paginator = new Paginator($queryBuilder);
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ class ORMAdapter extends AbstractAdapter
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
protected function getCount(QueryBuilder $queryBuilder, $identifier)
|
protected function getCount(QueryBuilder $queryBuilder, string $identifier)
|
||||||
{
|
{
|
||||||
$qb = clone $queryBuilder;
|
$qb = clone $queryBuilder;
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ namespace App\DataTables\Column;
|
||||||
|
|
||||||
use App\Entity\Attachments\Attachment;
|
use App\Entity\Attachments\Attachment;
|
||||||
use App\Entity\Base\AbstractDBElement;
|
use App\Entity\Base\AbstractDBElement;
|
||||||
use App\Entity\Base\AbstractNamedDBElement;
|
|
||||||
use App\Entity\Contracts\NamedElementInterface;
|
use App\Entity\Contracts\NamedElementInterface;
|
||||||
use App\Entity\LogSystem\AbstractLogEntry;
|
use App\Entity\LogSystem\AbstractLogEntry;
|
||||||
use App\Entity\Parameters\AbstractParameter;
|
use App\Entity\Parameters\AbstractParameter;
|
||||||
|
@ -99,7 +98,7 @@ class LogEntryTargetColumn extends AbstractColumn
|
||||||
$tmp = '';
|
$tmp = '';
|
||||||
|
|
||||||
//The element is existing
|
//The element is existing
|
||||||
if ($target instanceof NamedElementInterface && !empty($target->getName())) {
|
if ($target instanceof NamedElementInterface && ! empty($target->getName())) {
|
||||||
try {
|
try {
|
||||||
$tmp = sprintf(
|
$tmp = sprintf(
|
||||||
'<a href="%s">%s</a>',
|
'<a href="%s">%s</a>',
|
||||||
|
@ -126,15 +125,15 @@ class LogEntryTargetColumn extends AbstractColumn
|
||||||
|
|
||||||
//Add a hint to the associated element if possible
|
//Add a hint to the associated element if possible
|
||||||
if (null !== $target && $this->options['show_associated']) {
|
if (null !== $target && $this->options['show_associated']) {
|
||||||
if ($target instanceof Attachment && $target->getElement() !== null) {
|
if ($target instanceof Attachment && null !== $target->getElement()) {
|
||||||
$on = $target->getElement();
|
$on = $target->getElement();
|
||||||
} elseif ($target instanceof AbstractParameter && $target->getElement() !== null) {
|
} elseif ($target instanceof AbstractParameter && null !== $target->getElement()) {
|
||||||
$on = $target->getElement();
|
$on = $target->getElement();
|
||||||
} elseif ($target instanceof PartLot && $target->getPart() !== null) {
|
} elseif ($target instanceof PartLot && null !== $target->getPart()) {
|
||||||
$on = $target->getPart();
|
$on = $target->getPart();
|
||||||
} elseif ($target instanceof Orderdetail && $target->getPart() !== null) {
|
} elseif ($target instanceof Orderdetail && null !== $target->getPart()) {
|
||||||
$on = $target->getPart();
|
$on = $target->getPart();
|
||||||
} elseif ($target instanceof Pricedetail && $target->getOrderdetail() !== null && $target->getOrderdetail()->getPart() !== null) {
|
} elseif ($target instanceof Pricedetail && null !== $target->getOrderdetail() && null !== $target->getOrderdetail()->getPart()) {
|
||||||
$on = $target->getOrderdetail()->getPart();
|
$on = $target->getOrderdetail()->getPart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +145,7 @@ class LogEntryTargetColumn extends AbstractColumn
|
||||||
$this->elementTypeNameGenerator->getTypeNameCombination($on, true)
|
$this->elementTypeNameGenerator->getTypeNameCombination($on, true)
|
||||||
);
|
);
|
||||||
} catch (EntityNotSupportedException $exception) {
|
} catch (EntityNotSupportedException $exception) {
|
||||||
$tmp .= ' (' . $this->elementTypeNameGenerator->getTypeNameCombination($target, true) .')';
|
$tmp .= ' ('.$this->elementTypeNameGenerator->getTypeNameCombination($target, true).')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ class RevertLogColumn extends AbstractColumn
|
||||||
|
|
||||||
public function render($value, $context)
|
public function render($value, $context)
|
||||||
{
|
{
|
||||||
$revertable = true;
|
|
||||||
if (
|
if (
|
||||||
$context instanceof CollectionElementDeleted
|
$context instanceof CollectionElementDeleted
|
||||||
|| ($context instanceof ElementDeletedLogEntry && $context->hasOldDataInformations())
|
|| ($context instanceof ElementDeletedLogEntry && $context->hasOldDataInformations())
|
||||||
|
|
|
@ -212,7 +212,7 @@ class LogDataTable implements DataTableTypeInterface
|
||||||
|
|
||||||
$dataTable->add('target', LogEntryTargetColumn::class, [
|
$dataTable->add('target', LogEntryTargetColumn::class, [
|
||||||
'label' => $this->translator->trans('log.target'),
|
'label' => $this->translator->trans('log.target'),
|
||||||
'show_associated' => $options['mode'] !== 'element_history',
|
'show_associated' => 'element_history' !== $options['mode'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$dataTable->add('extra', LogEntryExtraColumn::class, [
|
$dataTable->add('extra', LogEntryExtraColumn::class, [
|
||||||
|
|
|
@ -329,8 +329,6 @@ final class PartsDataTable implements DataTableTypeInterface
|
||||||
|
|
||||||
private function buildCriteria(QueryBuilder $builder, array $options): void
|
private function buildCriteria(QueryBuilder $builder, array $options): void
|
||||||
{
|
{
|
||||||
$em = $builder->getEntityManager();
|
|
||||||
|
|
||||||
if (isset($options['category'])) {
|
if (isset($options['category'])) {
|
||||||
$category = $options['category'];
|
$category = $options['category'];
|
||||||
$list = $this->treeBuilder->typeToNodesList(Category::class, $category);
|
$list = $this->treeBuilder->typeToNodesList(Category::class, $category);
|
||||||
|
|
|
@ -40,6 +40,7 @@ class AttachmentType extends AbstractStructuralDBElement
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="AttachmentType", mappedBy="parent", cascade={"persist"})
|
* @ORM\OneToMany(targetEntity="AttachmentType", mappedBy="parent", cascade={"persist"})
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $children;
|
protected $children;
|
||||||
|
|
||||||
|
@ -56,13 +57,14 @@ class AttachmentType extends AbstractStructuralDBElement
|
||||||
*/
|
*/
|
||||||
protected $filetype_filter = '';
|
protected $filetype_filter = '';
|
||||||
/**
|
/**
|
||||||
* @var Collection|AttachmentTypeAttachment[]
|
* @var Collection<int, AttachmentTypeAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\AttachmentTypeAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\AttachmentTypeAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
|
||||||
/** @var AttachmentTypeParameter[]
|
/** @var Collection<int, AttachmentTypeParameter>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\AttachmentTypeParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\AttachmentTypeParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
|
@ -70,7 +72,7 @@ class AttachmentType extends AbstractStructuralDBElement
|
||||||
protected $parameters;
|
protected $parameters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection|Attachment[]
|
* @var Collection<int, Attachment>
|
||||||
* @ORM\OneToMany(targetEntity="Attachment", mappedBy="attachment_type")
|
* @ORM\OneToMany(targetEntity="Attachment", mappedBy="attachment_type")
|
||||||
*/
|
*/
|
||||||
protected $attachments_with_type;
|
protected $attachments_with_type;
|
||||||
|
|
|
@ -43,11 +43,13 @@ declare(strict_types=1);
|
||||||
namespace App\Entity\Attachments;
|
namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to an attachmentType element.
|
* A attachment attached to an attachmentType element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class AttachmentTypeAttachment extends Attachment
|
class AttachmentTypeAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,11 +44,13 @@ namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use App\Entity\Parts\Category;
|
use App\Entity\Parts\Category;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a category element.
|
* A attachment attached to a category element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class CategoryAttachment extends Attachment
|
class CategoryAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,11 +44,13 @@ namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a currency element.
|
* A attachment attached to a currency element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class CurrencyAttachment extends Attachment
|
class CurrencyAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,11 +44,13 @@ namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use App\Entity\Devices\Device;
|
use App\Entity\Devices\Device;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a device element.
|
* A attachment attached to a device element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class DeviceAttachment extends Attachment
|
class DeviceAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,11 +44,13 @@ namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use App\Entity\Parts\Footprint;
|
use App\Entity\Parts\Footprint;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a footprint element.
|
* A attachment attached to a footprint element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class FootprintAttachment extends Attachment
|
class FootprintAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,11 +44,13 @@ namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use App\Entity\UserSystem\Group;
|
use App\Entity\UserSystem\Group;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a Group element.
|
* A attachment attached to a Group element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class GroupAttachment extends Attachment
|
class GroupAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,11 +44,13 @@ namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use App\Entity\Parts\Manufacturer;
|
use App\Entity\Parts\Manufacturer;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a manufacturer element.
|
* A attachment attached to a manufacturer element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class ManufacturerAttachment extends Attachment
|
class ManufacturerAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,11 +45,13 @@ namespace App\Entity\Attachments;
|
||||||
use App\Entity\Parts\Manufacturer;
|
use App\Entity\Parts\Manufacturer;
|
||||||
use App\Entity\Parts\MeasurementUnit;
|
use App\Entity\Parts\MeasurementUnit;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a measurement unit element.
|
* A attachment attached to a measurement unit element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class MeasurementUnitAttachment extends Attachment
|
class MeasurementUnitAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,11 +44,13 @@ namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use App\Entity\Parts\Part;
|
use App\Entity\Parts\Part;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a part element.
|
* A attachment attached to a part element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class PartAttachment extends Attachment
|
class PartAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,11 +44,13 @@ namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use App\Entity\Parts\Storelocation;
|
use App\Entity\Parts\Storelocation;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a measurement unit element.
|
* A attachment attached to a measurement unit element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class StorelocationAttachment extends Attachment
|
class StorelocationAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,11 +44,13 @@ namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use App\Entity\Parts\Supplier;
|
use App\Entity\Parts\Supplier;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a supplier element.
|
* A attachment attached to a supplier element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class SupplierAttachment extends Attachment
|
class SupplierAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,11 +44,13 @@ namespace App\Entity\Attachments;
|
||||||
|
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A attachment attached to a user element.
|
* A attachment attached to a user element.
|
||||||
*
|
*
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
|
* @UniqueEntity({"name", "attachment_type", "element"})
|
||||||
*/
|
*/
|
||||||
class UserAttachment extends Attachment
|
class UserAttachment extends Attachment
|
||||||
{
|
{
|
||||||
|
|
|
@ -254,6 +254,7 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
|
||||||
* Get all sub elements of this element.
|
* Get all sub elements of this element.
|
||||||
*
|
*
|
||||||
* @return Collection<static>|iterable all subelements as an array of objects (sorted by their full path)
|
* @return Collection<static>|iterable all subelements as an array of objects (sorted by their full path)
|
||||||
|
* @psalm-return Collection<int, static>
|
||||||
*/
|
*/
|
||||||
public function getSubelements(): iterable
|
public function getSubelements(): iterable
|
||||||
{
|
{
|
||||||
|
@ -262,6 +263,7 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection<static>|iterable
|
* @return Collection<static>|iterable
|
||||||
|
* @psalm-return Collection<int, static>
|
||||||
*/
|
*/
|
||||||
public function getChildren(): iterable
|
public function getChildren(): iterable
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,6 +67,7 @@ class Device extends AbstractPartsContainingDBElement
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Device", mappedBy="parent")
|
* @ORM\OneToMany(targetEntity="Device", mappedBy="parent")
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $children;
|
protected $children;
|
||||||
|
|
||||||
|
@ -93,12 +94,13 @@ class Device extends AbstractPartsContainingDBElement
|
||||||
*/
|
*/
|
||||||
protected $order_only_missing_parts = false;
|
protected $order_only_missing_parts = false;
|
||||||
/**
|
/**
|
||||||
* @var Collection|DeviceAttachment[]
|
* @var Collection<int, DeviceAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\DeviceAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\DeviceAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
|
||||||
/** @var DeviceParameter[]
|
/** @var Collection<int, DeviceParameter>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\DeviceParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\DeviceParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -84,11 +84,7 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
|
||||||
return array_keys($this->getOldData());
|
return array_keys($this->getOldData());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->extra['f'])) {
|
return $this->extra['f'] ?? [];
|
||||||
return $this->extra['f'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,7 +28,6 @@ use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,16 +120,6 @@ abstract class AbstractParameter extends AbstractNamedDBElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the specification (e.g. "Collector-Base Voltage").
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getName(): string
|
|
||||||
{
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the element this parameter belongs to.
|
* Returns the element this parameter belongs to.
|
||||||
*
|
*
|
||||||
|
@ -213,7 +202,8 @@ abstract class AbstractParameter extends AbstractNamedDBElement
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the group this parameter is associated to (e.g. Technical Parameters)
|
* Returns the name of the group this parameter is associated to (e.g. Technical Parameters).
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getGroup(): string
|
public function getGroup(): string
|
||||||
|
@ -223,12 +213,13 @@ abstract class AbstractParameter extends AbstractNamedDBElement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name of the group this parameter is associated to.
|
* Sets the name of the group this parameter is associated to.
|
||||||
* @param string $group
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setGroup(string $group): self
|
public function setGroup(string $group): self
|
||||||
{
|
{
|
||||||
$this->group = $group;
|
$this->group = $group;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,17 +31,19 @@ trait ParametersTrait
|
||||||
/**
|
/**
|
||||||
* Mapping done in subclasses.
|
* Mapping done in subclasses.
|
||||||
*
|
*
|
||||||
* @var AbstractParameter[]|Collection
|
* @var Collection<int, AbstractParameter>
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $parameters;
|
protected $parameters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all associated specifications.
|
* Return all associated specifications.
|
||||||
*
|
*
|
||||||
* @return AbstractParameter[]|Collection
|
* @return Collection
|
||||||
|
*
|
||||||
|
* @psalm-return Collection<int, PartParameter>
|
||||||
*/
|
*/
|
||||||
public function getParameters(): Collection
|
public function getParameters(): \Doctrine\Common\Collections\Collection
|
||||||
{
|
{
|
||||||
return $this->parameters;
|
return $this->parameters;
|
||||||
}
|
}
|
||||||
|
@ -73,6 +75,7 @@ trait ParametersTrait
|
||||||
foreach ($this->parameters as $parameter) {
|
foreach ($this->parameters as $parameter) {
|
||||||
$tmp[$parameter->getGroup()][] = $parameter;
|
$tmp[$parameter->getGroup()][] = $parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tmp;
|
return $tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ class Category extends AbstractPartsContainingDBElement
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
|
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $children;
|
protected $children;
|
||||||
|
|
||||||
|
@ -101,13 +102,14 @@ class Category extends AbstractPartsContainingDBElement
|
||||||
*/
|
*/
|
||||||
protected $default_comment = '';
|
protected $default_comment = '';
|
||||||
/**
|
/**
|
||||||
* @var Collection|CategoryAttachment[]
|
* @var Collection<int, CategoryAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CategoryAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CategoryAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
|
||||||
/** @var CategoryParameter[]
|
/** @var Collection<int, CategoryParameter>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\CategoryParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\CategoryParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
|
|
|
@ -73,6 +73,7 @@ class Footprint extends AbstractPartsContainingDBElement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Footprint", mappedBy="parent")
|
* @ORM\OneToMany(targetEntity="Footprint", mappedBy="parent")
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $children;
|
protected $children;
|
||||||
|
|
||||||
|
@ -81,8 +82,9 @@ class Footprint extends AbstractPartsContainingDBElement
|
||||||
*/
|
*/
|
||||||
protected $parts;
|
protected $parts;
|
||||||
/**
|
/**
|
||||||
* @var Collection|FootprintAttachment[]
|
* @var Collection<int, FootprintAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\FootprintAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\FootprintAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
@ -94,9 +96,9 @@ class Footprint extends AbstractPartsContainingDBElement
|
||||||
*/
|
*/
|
||||||
protected $footprint_3d;
|
protected $footprint_3d;
|
||||||
|
|
||||||
/** @var FootprintParameter[]
|
/** @var Collection<int, FootprintParameter>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\FootprintParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\FootprintParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})@ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $parameters;
|
protected $parameters;
|
||||||
|
|
|
@ -73,6 +73,7 @@ class Manufacturer extends AbstractCompany
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Manufacturer", mappedBy="parent")
|
* @ORM\OneToMany(targetEntity="Manufacturer", mappedBy="parent")
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $children;
|
protected $children;
|
||||||
|
|
||||||
|
@ -81,13 +82,14 @@ class Manufacturer extends AbstractCompany
|
||||||
*/
|
*/
|
||||||
protected $parts;
|
protected $parts;
|
||||||
/**
|
/**
|
||||||
* @var Collection|ManufacturerAttachment[]
|
* @var Collection<int, ManufacturerAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
|
||||||
/** @var ManufacturerParameter[]
|
/** @var Collection<int, ManufacturerParameter>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\ManufacturerParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\ManufacturerParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
|
|
|
@ -84,6 +84,7 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="MeasurementUnit", mappedBy="parent", cascade={"persist"})
|
* @ORM\OneToMany(targetEntity="MeasurementUnit", mappedBy="parent", cascade={"persist"})
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $children;
|
protected $children;
|
||||||
|
|
||||||
|
@ -98,13 +99,14 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
|
||||||
*/
|
*/
|
||||||
protected $parts;
|
protected $parts;
|
||||||
/**
|
/**
|
||||||
* @var Collection|MeasurementUnitAttachment[]
|
* @var Collection<int, MeasurementUnitAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\MeasurementUnitAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\MeasurementUnitAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
|
||||||
/** @var MeasurementUnitParameter[]
|
/** @var Collection<int, MeasurementUnitParameter>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\MeasurementUnitParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\MeasurementUnitParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace App\Entity\Parts;
|
||||||
|
|
||||||
use App\Entity\Attachments\Attachment;
|
use App\Entity\Attachments\Attachment;
|
||||||
use App\Entity\Attachments\AttachmentContainingDBElement;
|
use App\Entity\Attachments\AttachmentContainingDBElement;
|
||||||
|
use App\Entity\Attachments\PartAttachment;
|
||||||
use App\Entity\Devices\Device;
|
use App\Entity\Devices\Device;
|
||||||
use App\Entity\Parameters\ParametersTrait;
|
use App\Entity\Parameters\ParametersTrait;
|
||||||
use App\Entity\Parameters\PartParameter;
|
use App\Entity\Parameters\PartParameter;
|
||||||
|
@ -63,6 +64,7 @@ use App\Entity\Parts\PartTraits\OrderTrait;
|
||||||
use App\Security\Annotations\ColumnSecurity;
|
use App\Security\Annotations\ColumnSecurity;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
|
@ -90,11 +92,10 @@ class Part extends AttachmentContainingDBElement
|
||||||
*/
|
*/
|
||||||
protected $devices = [];
|
protected $devices = [];
|
||||||
|
|
||||||
/** @var PartParameter[]
|
/** @var Collection<int, PartParameter>
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\PartParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\PartParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
|
||||||
*/
|
*/
|
||||||
protected $parameters;
|
protected $parameters;
|
||||||
|
|
||||||
|
@ -117,8 +118,10 @@ class Part extends AttachmentContainingDBElement
|
||||||
protected $name = '';
|
protected $name = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @var Collection<int, PartAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\PartAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\PartAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ColumnSecurity(type="collection", prefix="attachments")
|
* @ColumnSecurity(type="collection", prefix="attachments")
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
|
|
@ -303,8 +303,20 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named
|
||||||
return (float) $this->amount;
|
return (float) $this->amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAmount(float $new_amount): self
|
/**
|
||||||
|
* Sets the amount of parts in the part lot.
|
||||||
|
* If null is passed, amount will be set to unknown.
|
||||||
|
* @param float|null $new_amount
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setAmount(?float $new_amount): self
|
||||||
{
|
{
|
||||||
|
//Treat null like unknown amount
|
||||||
|
if ($new_amount === null) {
|
||||||
|
$this->instock_unknown = true;
|
||||||
|
$new_amount = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
$this->amount = $new_amount;
|
$this->amount = $new_amount;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -328,9 +340,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->description;
|
return $this->description;
|
||||||
|
|
|
@ -57,6 +57,7 @@ trait InstockTrait
|
||||||
* @ORM\OneToMany(targetEntity="PartLot", mappedBy="part", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="PartLot", mappedBy="part", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
* @ColumnSecurity(type="collection", prefix="lots")
|
* @ColumnSecurity(type="collection", prefix="lots")
|
||||||
|
* @ORM\OrderBy({"amount" = "DESC"})
|
||||||
*/
|
*/
|
||||||
protected $partLots;
|
protected $partLots;
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace App\Entity\Parts\PartTraits;
|
||||||
|
|
||||||
use App\Entity\PriceInformations\Orderdetail;
|
use App\Entity\PriceInformations\Orderdetail;
|
||||||
use App\Security\Annotations\ColumnSecurity;
|
use App\Security\Annotations\ColumnSecurity;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use function count;
|
use function count;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
|
||||||
|
@ -57,6 +58,7 @@ trait OrderTrait
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\PriceInformations\Orderdetail", mappedBy="part", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\PriceInformations\Orderdetail", mappedBy="part", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
* @ColumnSecurity(prefix="orderdetails", type="collection")
|
* @ColumnSecurity(prefix="orderdetails", type="collection")
|
||||||
|
* @ORM\OrderBy({"supplierpartnr" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $orderdetails;
|
protected $orderdetails;
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ class Storelocation extends AbstractPartsContainingDBElement
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Storelocation", mappedBy="parent")
|
* @ORM\OneToMany(targetEntity="Storelocation", mappedBy="parent")
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $children;
|
protected $children;
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ class Storelocation extends AbstractPartsContainingDBElement
|
||||||
*/
|
*/
|
||||||
protected $parts;
|
protected $parts;
|
||||||
|
|
||||||
/** @var StorelocationParameter[]
|
/** @var Collection<int, StorelocationParameter>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\StorelocationParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\StorelocationParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
|
@ -117,7 +118,7 @@ class Storelocation extends AbstractPartsContainingDBElement
|
||||||
*/
|
*/
|
||||||
protected $limit_to_existing_parts = false;
|
protected $limit_to_existing_parts = false;
|
||||||
/**
|
/**
|
||||||
* @var Collection|StorelocationAttachment[]
|
* @var Collection<int, StorelocationAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\StorelocationAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\StorelocationAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -69,6 +69,7 @@ class Supplier extends AbstractCompany
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Supplier", mappedBy="parent")
|
* @ORM\OneToMany(targetEntity="Supplier", mappedBy="parent")
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $children;
|
protected $children;
|
||||||
|
|
||||||
|
@ -107,14 +108,16 @@ class Supplier extends AbstractCompany
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
protected $parts;
|
protected $parts;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection|SupplierAttachment[]
|
* @var Collection<int, SupplierAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\SupplierAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\SupplierAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
|
||||||
/** @var SupplierParameter[]
|
/** @var Collection<int, SupplierParameter>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\SupplierParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\SupplierParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
|
|
|
@ -78,6 +78,7 @@ class Currency extends AbstractStructuralDBElement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Currency", mappedBy="parent", cascade={"persist"})
|
* @ORM\OneToMany(targetEntity="Currency", mappedBy="parent", cascade={"persist"})
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $children;
|
protected $children;
|
||||||
|
|
||||||
|
@ -88,13 +89,14 @@ class Currency extends AbstractStructuralDBElement
|
||||||
protected $parent;
|
protected $parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection|CurrencyAttachment[]
|
* @var Collection<int, CurrencyAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CurrencyAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CurrencyAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
|
||||||
/** @var CurrencyParameter[]
|
/** @var Collection<int, CurrencyParameter>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\CurrencyParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\CurrencyParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
|
|
|
@ -59,6 +59,7 @@ use App\Entity\Parts\Supplier;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,6 +68,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||||
* @ORM\Table("`orderdetails`")
|
* @ORM\Table("`orderdetails`")
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
* @ORM\HasLifecycleCallbacks()
|
* @ORM\HasLifecycleCallbacks()
|
||||||
|
* @UniqueEntity({"supplierpartnr", "supplier", "part"})
|
||||||
*/
|
*/
|
||||||
class Orderdetail extends AbstractDBElement implements TimeStampableInterface, NamedElementInterface
|
class Orderdetail extends AbstractDBElement implements TimeStampableInterface, NamedElementInterface
|
||||||
{
|
{
|
||||||
|
@ -361,9 +363,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->getSupplierPartNr();
|
return $this->getSupplierPartNr();
|
||||||
|
|
|
@ -64,7 +64,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||||
* @ORM\Entity()
|
* @ORM\Entity()
|
||||||
* @ORM\Table("`pricedetails`")
|
* @ORM\Table("`pricedetails`")
|
||||||
* @ORM\HasLifecycleCallbacks()
|
* @ORM\HasLifecycleCallbacks()
|
||||||
* @UniqueEntity(fields={"orderdetail", "min_discount_quantity"})
|
* @UniqueEntity(fields={"min_discount_quantity", "orderdetail"})
|
||||||
*/
|
*/
|
||||||
class Pricedetail extends AbstractDBElement implements TimeStampableInterface
|
class Pricedetail extends AbstractDBElement implements TimeStampableInterface
|
||||||
{
|
{
|
||||||
|
@ -136,11 +136,11 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the orderdetail to which this pricedetail belongs to this pricedetails.
|
* Get the orderdetail to which this pricedetail belongs to this pricedetails.
|
||||||
*
|
*
|
||||||
* @return Orderdetail the orderdetail this price belongs to
|
* @return Orderdetail|null the orderdetail this price belongs to
|
||||||
*/
|
*/
|
||||||
public function getOrderdetail(): Orderdetail
|
public function getOrderdetail(): ?Orderdetail
|
||||||
{
|
{
|
||||||
return $this->orderdetail;
|
return $this->orderdetail;
|
||||||
}
|
}
|
||||||
|
@ -157,17 +157,20 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the price for a single unit in the currency associated with this price detail.
|
* Get the price for a single unit in the currency associated with this price detail.
|
||||||
|
*
|
||||||
|
* @param float|string $multiplier The returned price (float or string) will be multiplied
|
||||||
|
* with this multiplier.
|
||||||
|
*
|
||||||
|
* You will get the price for $multiplier parts. If you want the price which is stored
|
||||||
|
* in the database, you have to pass the "price_related_quantity" count as $multiplier.
|
||||||
*
|
*
|
||||||
* @param float|string $multiplier The returned price (float or string) will be multiplied
|
* @param float|string $multiplier The returned price (float or string) will be multiplied
|
||||||
* with this multiplier.
|
* with this multiplier.
|
||||||
*
|
*
|
||||||
* You will get the price for $multiplier parts. If you want the price which is stored
|
* @return null|string the price as a bcmath string
|
||||||
* in the database, you have to pass the "price_related_quantity" count as $multiplier.
|
|
||||||
*
|
|
||||||
* @return string the price as a bcmath string
|
|
||||||
*/
|
*/
|
||||||
public function getPricePerUnit($multiplier = 1.0): string
|
public function getPricePerUnit($multiplier = 1.0): ?string
|
||||||
{
|
{
|
||||||
$multiplier = (string) $multiplier;
|
$multiplier = (string) $multiplier;
|
||||||
$tmp = bcmul($this->price, $multiplier, static::PRICE_PRECISION);
|
$tmp = bcmul($this->price, $multiplier, static::PRICE_PRECISION);
|
||||||
|
|
|
@ -61,6 +61,7 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Group", mappedBy="parent")
|
* @ORM\OneToMany(targetEntity="Group", mappedBy="parent")
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $children;
|
protected $children;
|
||||||
|
|
||||||
|
@ -81,8 +82,9 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa
|
||||||
*/
|
*/
|
||||||
protected $enforce2FA = false;
|
protected $enforce2FA = false;
|
||||||
/**
|
/**
|
||||||
* @var Collection|GroupAttachment[]
|
* @var Collection<int, GroupAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
@ -93,7 +95,7 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa
|
||||||
*/
|
*/
|
||||||
protected $permissions;
|
protected $permissions;
|
||||||
|
|
||||||
/** @var GroupParameter[]
|
/** @var Collection<int, GroupParameter>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\GroupParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\GroupParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
|
||||||
* @Assert\Valid()
|
* @Assert\Valid()
|
||||||
|
|
|
@ -53,7 +53,6 @@ namespace App\Entity\UserSystem;
|
||||||
use App\Entity\Attachments\AttachmentContainingDBElement;
|
use App\Entity\Attachments\AttachmentContainingDBElement;
|
||||||
use App\Entity\Attachments\UserAttachment;
|
use App\Entity\Attachments\UserAttachment;
|
||||||
use App\Entity\Base\AbstractNamedDBElement;
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\Base\MasterAttachmentTrait;
|
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
use App\Security\Interfaces\HasPermissionsInterface;
|
use App\Security\Interfaces\HasPermissionsInterface;
|
||||||
use App\Validator\Constraints\Selectable;
|
use App\Validator\Constraints\Selectable;
|
||||||
|
@ -114,7 +113,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
* @var string|null The hash of a token the user must provide when he wants to reset his password.
|
* @var string|null The hash of a token the user must provide when he wants to reset his password.
|
||||||
* @ORM\Column(type="string", nullable=true)
|
* @ORM\Column(type="string", nullable=true)
|
||||||
*/
|
*/
|
||||||
protected $pw_reset_token = null;
|
protected $pw_reset_token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", name="config_instock_comment_a")
|
* @ORM\Column(type="text", name="config_instock_comment_a")
|
||||||
|
@ -228,8 +227,9 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
protected $settings = [];
|
protected $settings = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection|UserAttachment[]
|
* @var Collection<int, UserAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\UserAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\UserAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"name" = "ASC"})
|
||||||
*/
|
*/
|
||||||
protected $attachments;
|
protected $attachments;
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
*/
|
*/
|
||||||
protected $backupCodesGenerationDate;
|
protected $backupCodesGenerationDate;
|
||||||
|
|
||||||
/** @var Collection<TwoFactorKeyInterface>
|
/** @var Collection<int, TwoFactorKeyInterface>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\UserSystem\U2FKey", mappedBy="user", cascade={"REMOVE"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\UserSystem\U2FKey", mappedBy="user", cascade={"REMOVE"}, orphanRemoval=true)
|
||||||
*/
|
*/
|
||||||
protected $u2fKeys;
|
protected $u2fKeys;
|
||||||
|
@ -252,7 +252,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
* @ORM\JoinColumn(name="currency_id", referencedColumnName="id")
|
* @ORM\JoinColumn(name="currency_id", referencedColumnName="id")
|
||||||
* @Selectable()
|
* @Selectable()
|
||||||
*/
|
*/
|
||||||
protected $currency = null;
|
protected $currency;
|
||||||
|
|
||||||
/** @var PermissionsEmbed
|
/** @var PermissionsEmbed
|
||||||
* @ORM\Embedded(class="PermissionsEmbed", columnPrefix="perms_")
|
* @ORM\Embedded(class="PermissionsEmbed", columnPrefix="perms_")
|
||||||
|
@ -264,7 +264,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
* @var DateTime The time until the password reset token is valid.
|
* @var DateTime The time until the password reset token is valid.
|
||||||
* @ORM\Column(type="datetime", nullable=true)
|
* @ORM\Column(type="datetime", nullable=true)
|
||||||
*/
|
*/
|
||||||
protected $pw_reset_expires = null;
|
protected $pw_reset_expires;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
@ -863,9 +863,11 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all U2F Keys that are associated with this user.
|
* Get all U2F Keys that are associated with this user.
|
||||||
*
|
*
|
||||||
* @return Collection<TwoFactorKeyInterface>
|
* @return Collection
|
||||||
|
*
|
||||||
|
* @psalm-return Collection<int, TwoFactorKeyInterface>
|
||||||
*/
|
*/
|
||||||
public function getU2FKeys(): Collection
|
public function getU2FKeys(): Collection
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,12 +77,21 @@ class AttachmentDeleteListener
|
||||||
public function preUpdateHandler(Attachment $attachment, PreUpdateEventArgs $event): void
|
public function preUpdateHandler(Attachment $attachment, PreUpdateEventArgs $event): void
|
||||||
{
|
{
|
||||||
if ($event->hasChangedField('path')) {
|
if ($event->hasChangedField('path')) {
|
||||||
|
$old_path = $event->getOldValue('path');
|
||||||
|
|
||||||
//Dont delete file if the attachment uses a builtin ressource:
|
//Dont delete file if the attachment uses a builtin ressource:
|
||||||
if (Attachment::checkIfBuiltin($event->getOldValue('path'))) {
|
if (Attachment::checkIfBuiltin($old_path)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$file = new SplFileInfo($this->pathResolver->placeholderToRealPath($event->getOldValue('path')));
|
$real_path = $this->pathResolver->placeholderToRealPath($old_path);
|
||||||
|
|
||||||
|
//If the attachment does not point to a valid file, ignore it!
|
||||||
|
if ($real_path === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = new SplFileInfo($real_path);
|
||||||
$this->attachmentReverseSearch->deleteIfNotUsed($file);
|
$this->attachmentReverseSearch->deleteIfNotUsed($file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ class EventLoggerSubscriber implements EventSubscriber
|
||||||
Orderdetail::class => ['part'],
|
Orderdetail::class => ['part'],
|
||||||
Pricedetail::class => ['orderdetail'],
|
Pricedetail::class => ['orderdetail'],
|
||||||
Attachment::class => ['element'],
|
Attachment::class => ['element'],
|
||||||
AbstractParameter::class => ['element']
|
AbstractParameter::class => ['element'],
|
||||||
];
|
];
|
||||||
|
|
||||||
protected const MAX_STRING_LENGTH = 2000;
|
protected const MAX_STRING_LENGTH = 2000;
|
||||||
|
@ -163,7 +163,7 @@ class EventLoggerSubscriber implements EventSubscriber
|
||||||
*/
|
*/
|
||||||
public function hasFieldRestrictions(AbstractDBElement $element): bool
|
public function hasFieldRestrictions(AbstractDBElement $element): bool
|
||||||
{
|
{
|
||||||
foreach (static::FIELD_BLACKLIST as $class => $blacklist) {
|
foreach (array_keys(static::FIELD_BLACKLIST) as $class) {
|
||||||
if (is_a($element, $class)) {
|
if (is_a($element, $class)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -283,7 +283,7 @@ class EventLoggerSubscriber implements EventSubscriber
|
||||||
}, ARRAY_FILTER_USE_BOTH);
|
}, ARRAY_FILTER_USE_BOTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function saveChangeSet(AbstractDBElement $entity, AbstractLogEntry $logEntry, EntityManagerInterface $em, $element_deleted = false): void
|
protected function saveChangeSet(AbstractDBElement $entity, AbstractLogEntry $logEntry, EntityManagerInterface $em, bool $element_deleted = false): void
|
||||||
{
|
{
|
||||||
$uow = $em->getUnitOfWork();
|
$uow = $em->getUnitOfWork();
|
||||||
|
|
||||||
|
|
|
@ -53,8 +53,6 @@ use Symfony\Component\Security\Core\Security;
|
||||||
final class LogoutOnDisabledUserListener implements EventSubscriberInterface
|
final class LogoutOnDisabledUserListener implements EventSubscriberInterface
|
||||||
{
|
{
|
||||||
private $security;
|
private $security;
|
||||||
private $translator;
|
|
||||||
private $flashBag;
|
|
||||||
private $urlGenerator;
|
private $urlGenerator;
|
||||||
|
|
||||||
public function __construct(Security $security, UrlGeneratorInterface $urlGenerator)
|
public function __construct(Security $security, UrlGeneratorInterface $urlGenerator)
|
||||||
|
|
|
@ -45,14 +45,15 @@ namespace App\EventSubscriber;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||||
|
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
||||||
|
|
||||||
final class SymfonyDebugToolbarSubscriber implements EventSubscriberInterface
|
final class SymfonyDebugToolbarSubscriber implements EventSubscriberInterface
|
||||||
{
|
{
|
||||||
private $kernel;
|
private $kernel_debug;
|
||||||
|
|
||||||
public function __construct(ContainerInterface $kernel)
|
public function __construct(bool $kernel_debug)
|
||||||
{
|
{
|
||||||
$this->kernel = $kernel;
|
$this->kernel_debug = $kernel_debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,9 +79,9 @@ final class SymfonyDebugToolbarSubscriber implements EventSubscriberInterface
|
||||||
return ['kernel.response' => 'onKernelResponse'];
|
return ['kernel.response' => 'onKernelResponse'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onKernelResponse(FilterResponseEvent $event): void
|
public function onKernelResponse(ResponseEvent $event): void
|
||||||
{
|
{
|
||||||
if (! $this->kernel->getParameter('kernel.debug')) {
|
if (! $this->kernel_debug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ namespace App\Form\AdminPages;
|
||||||
use App\Entity\Attachments\Attachment;
|
use App\Entity\Attachments\Attachment;
|
||||||
use App\Entity\Base\AbstractNamedDBElement;
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\Base\AbstractStructuralDBElement;
|
use App\Entity\Base\AbstractStructuralDBElement;
|
||||||
use App\Entity\Parameters\PartParameter;
|
|
||||||
use App\Form\AttachmentFormType;
|
use App\Form\AttachmentFormType;
|
||||||
use App\Form\ParameterType;
|
use App\Form\ParameterType;
|
||||||
use App\Form\Type\MasterPictureAttachmentType;
|
use App\Form\Type\MasterPictureAttachmentType;
|
||||||
|
@ -133,6 +132,7 @@ class BaseEntityAdminForm extends AbstractType
|
||||||
'allow_add' => true,
|
'allow_add' => true,
|
||||||
'allow_delete' => true,
|
'allow_delete' => true,
|
||||||
'label' => false,
|
'label' => false,
|
||||||
|
'reindex_enable' => true,
|
||||||
'disabled' => ! $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
'disabled' => ! $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||||
'entry_options' => [
|
'entry_options' => [
|
||||||
'data_class' => $options['attachment_class'],
|
'data_class' => $options['attachment_class'],
|
||||||
|
@ -159,6 +159,7 @@ class BaseEntityAdminForm extends AbstractType
|
||||||
'allow_add' => $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
'allow_add' => $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||||
'allow_delete' => $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
'allow_delete' => $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||||
'disabled' => ! $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
'disabled' => ! $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||||
|
'reindex_enable' => true,
|
||||||
'label' => false,
|
'label' => false,
|
||||||
'by_reference' => false,
|
'by_reference' => false,
|
||||||
'prototype_data' => new $options['parameter_class'](),
|
'prototype_data' => new $options['parameter_class'](),
|
||||||
|
|
|
@ -57,6 +57,7 @@ use Symfony\Component\Form\FormEvent;
|
||||||
use Symfony\Component\Form\FormEvents;
|
use Symfony\Component\Form\FormEvents;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Component\Validator\Constraints\File;
|
use Symfony\Component\Validator\Constraints\File;
|
||||||
use Symfony\Component\Validator\Constraints\Url;
|
use Symfony\Component\Validator\Constraints\Url;
|
||||||
|
|
||||||
|
@ -65,13 +66,15 @@ class AttachmentFormType extends AbstractType
|
||||||
protected $attachment_helper;
|
protected $attachment_helper;
|
||||||
protected $urlGenerator;
|
protected $urlGenerator;
|
||||||
protected $allow_attachments_download;
|
protected $allow_attachments_download;
|
||||||
|
protected $security;
|
||||||
|
|
||||||
public function __construct(AttachmentManager $attachmentHelper,
|
public function __construct(AttachmentManager $attachmentHelper,
|
||||||
UrlGeneratorInterface $urlGenerator, bool $allow_attachments_downloads)
|
UrlGeneratorInterface $urlGenerator, Security $security, bool $allow_attachments_downloads)
|
||||||
{
|
{
|
||||||
$this->attachment_helper = $attachmentHelper;
|
$this->attachment_helper = $attachmentHelper;
|
||||||
$this->urlGenerator = $urlGenerator;
|
$this->urlGenerator = $urlGenerator;
|
||||||
$this->allow_attachments_download = $allow_attachments_downloads;
|
$this->allow_attachments_download = $allow_attachments_downloads;
|
||||||
|
$this->security = $security;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
|
@ -103,6 +106,7 @@ class AttachmentFormType extends AbstractType
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'label' => 'attachment.edit.secure_file',
|
'label' => 'attachment.edit.secure_file',
|
||||||
'mapped' => false,
|
'mapped' => false,
|
||||||
|
'disabled' => !$this->security->isGranted('@parts_attachments.show_private'),
|
||||||
'attr' => [
|
'attr' => [
|
||||||
'class' => 'form-control-sm',
|
'class' => 'form-control-sm',
|
||||||
],
|
],
|
||||||
|
|
120
src/Form/CollectionTypeExtension.php
Normal file
120
src/Form/CollectionTypeExtension.php
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Symfony\Component\Form\AbstractTypeExtension;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||||
|
use Symfony\Component\Form\FormBuilder;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\Form\FormConfigBuilder;
|
||||||
|
use Symfony\Component\Form\FormEvent;
|
||||||
|
use Symfony\Component\Form\FormEvents;
|
||||||
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a reindexing on CollectionType elements, by assigning the database id as index.
|
||||||
|
* This prevents issues when the collection that is edited uses a OrderBy annotation and therefore the direction of the
|
||||||
|
* elements can change during requests.
|
||||||
|
* Must me enabled by setting reindex_enable to true in Type options.
|
||||||
|
* @package App\Form
|
||||||
|
*/
|
||||||
|
class CollectionTypeExtension extends AbstractTypeExtension
|
||||||
|
{
|
||||||
|
protected $propertyAccess;
|
||||||
|
|
||||||
|
public function __construct(PropertyAccessorInterface $propertyAccess)
|
||||||
|
{
|
||||||
|
$this->propertyAccess = $propertyAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getExtendedTypes(): iterable
|
||||||
|
{
|
||||||
|
return [CollectionType::class];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
/*$resolver->setDefault('error_mapping', function (Options $options) {
|
||||||
|
$options->
|
||||||
|
});*/
|
||||||
|
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'reindex_enable' => false,
|
||||||
|
'reindex_prefix' => 'db_',
|
||||||
|
'reindex_path' => 'id',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$resolver->setAllowedTypes('reindex_enable', 'bool');
|
||||||
|
$resolver->setAllowedTypes('reindex_prefix', 'string');
|
||||||
|
$resolver->setAllowedTypes('reindex_path', 'string');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
|
||||||
|
$data = $event->getData();
|
||||||
|
$config = $event->getForm()->getConfig();
|
||||||
|
//If enabled do a reindexing of the collection
|
||||||
|
if ($options['reindex_enable'] && $data instanceof Collection) {
|
||||||
|
$reindexed_data = new ArrayCollection();
|
||||||
|
|
||||||
|
$error_mapping = [];
|
||||||
|
|
||||||
|
foreach ($data->toArray() as $key => $item) {
|
||||||
|
$index = $options['reindex_prefix'] . $this->propertyAccess->getValue($item, $options['reindex_path']);
|
||||||
|
$error_mapping['[' . $key . ']'] = $index;
|
||||||
|
$reindexed_data->set($index, $item);
|
||||||
|
}
|
||||||
|
$event->setData($reindexed_data);
|
||||||
|
|
||||||
|
//Add error mapping, so that validator error are mapped correctly to the new index fields
|
||||||
|
if ($config instanceof FormBuilder && empty($config->getOption('error_mapping'))) {
|
||||||
|
$this->setOption($config, 'error_mapping', $error_mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 100); //We need to have a higher priority then the PRE_SET_DATA listener on CollectionType
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the option of the form.
|
||||||
|
* This a bit hacky cause we access private properties....
|
||||||
|
* @param $builder
|
||||||
|
* @param string $option
|
||||||
|
* @param $value
|
||||||
|
* @throws \ReflectionException
|
||||||
|
*/
|
||||||
|
public function setOption(FormBuilder $builder, string $option, $value): void
|
||||||
|
{
|
||||||
|
//We have to use FormConfigBuilder::class here, because options is private and not available in sub classes
|
||||||
|
$reflection = new \ReflectionClass(FormConfigBuilder::class);
|
||||||
|
$property = $reflection->getProperty('options');
|
||||||
|
$property->setAccessible(true);
|
||||||
|
$tmp = $property->getValue($builder);
|
||||||
|
$tmp[$option] = $value;
|
||||||
|
$property->setValue($builder, $tmp);
|
||||||
|
$property->setAccessible(false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -113,14 +113,14 @@ class ParameterType extends AbstractType
|
||||||
'attr' => [
|
'attr' => [
|
||||||
'placeholder' => 'parameter.group.placeholder',
|
'placeholder' => 'parameter.group.placeholder',
|
||||||
'class' => 'form-control-sm',
|
'class' => 'form-control-sm',
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver): void
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
{
|
{
|
||||||
$resolver->setDefaults([
|
$resolver->setDefaults([
|
||||||
'data_class' => AbstractParameter::class,
|
'data_class' => AbstractParameter::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,6 @@ class OrderdetailType extends AbstractType
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
{
|
{
|
||||||
/** @var Orderdetail $orderdetail */
|
|
||||||
$orderdetail = $builder->getData();
|
|
||||||
|
|
||||||
$builder->add('supplierpartnr', TextType::class, [
|
$builder->add('supplierpartnr', TextType::class, [
|
||||||
'label' => 'orderdetails.edit.supplierpartnr',
|
'label' => 'orderdetails.edit.supplierpartnr',
|
||||||
'attr' => [
|
'attr' => [
|
||||||
|
@ -117,6 +114,7 @@ class OrderdetailType extends AbstractType
|
||||||
'allow_add' => $this->security->isGranted('@parts_prices.create'),
|
'allow_add' => $this->security->isGranted('@parts_prices.create'),
|
||||||
'allow_delete' => $this->security->isGranted('@parts_prices.delete'),
|
'allow_delete' => $this->security->isGranted('@parts_prices.delete'),
|
||||||
'label' => false,
|
'label' => false,
|
||||||
|
'reindex_enable' => true,
|
||||||
'prototype_data' => $dummy_pricedetail,
|
'prototype_data' => $dummy_pricedetail,
|
||||||
'by_reference' => false,
|
'by_reference' => false,
|
||||||
'entry_options' => [
|
'entry_options' => [
|
||||||
|
|
|
@ -52,7 +52,6 @@ use App\Entity\Parts\MeasurementUnit;
|
||||||
use App\Entity\Parts\Part;
|
use App\Entity\Parts\Part;
|
||||||
use App\Entity\PriceInformations\Orderdetail;
|
use App\Entity\PriceInformations\Orderdetail;
|
||||||
use App\Form\AttachmentFormType;
|
use App\Form\AttachmentFormType;
|
||||||
use App\Form\ParameterGroupType;
|
|
||||||
use App\Form\ParameterType;
|
use App\Form\ParameterType;
|
||||||
use App\Form\Type\MasterPictureAttachmentType;
|
use App\Form\Type\MasterPictureAttachmentType;
|
||||||
use App\Form\Type\SIUnitType;
|
use App\Form\Type\SIUnitType;
|
||||||
|
@ -225,6 +224,7 @@ class PartBaseType extends AbstractType
|
||||||
'entry_type' => PartLotType::class,
|
'entry_type' => PartLotType::class,
|
||||||
'allow_add' => $this->security->isGranted('lots.create', $part),
|
'allow_add' => $this->security->isGranted('lots.create', $part),
|
||||||
'allow_delete' => $this->security->isGranted('lots.delete', $part),
|
'allow_delete' => $this->security->isGranted('lots.delete', $part),
|
||||||
|
'reindex_enable' => true,
|
||||||
'label' => false,
|
'label' => false,
|
||||||
'entry_options' => [
|
'entry_options' => [
|
||||||
'measurement_unit' => $part->getPartUnit(),
|
'measurement_unit' => $part->getPartUnit(),
|
||||||
|
@ -238,6 +238,7 @@ class PartBaseType extends AbstractType
|
||||||
'entry_type' => AttachmentFormType::class,
|
'entry_type' => AttachmentFormType::class,
|
||||||
'allow_add' => $this->security->isGranted('attachments.create', $part),
|
'allow_add' => $this->security->isGranted('attachments.create', $part),
|
||||||
'allow_delete' => $this->security->isGranted('attachments.delete', $part),
|
'allow_delete' => $this->security->isGranted('attachments.delete', $part),
|
||||||
|
'reindex_enable' => true,
|
||||||
'label' => false,
|
'label' => false,
|
||||||
'entry_options' => [
|
'entry_options' => [
|
||||||
'data_class' => PartAttachment::class,
|
'data_class' => PartAttachment::class,
|
||||||
|
@ -258,6 +259,7 @@ class PartBaseType extends AbstractType
|
||||||
'entry_type' => OrderdetailType::class,
|
'entry_type' => OrderdetailType::class,
|
||||||
'allow_add' => $this->security->isGranted('orderdetails.create', $part),
|
'allow_add' => $this->security->isGranted('orderdetails.create', $part),
|
||||||
'allow_delete' => $this->security->isGranted('orderdetails.delete', $part),
|
'allow_delete' => $this->security->isGranted('orderdetails.delete', $part),
|
||||||
|
'reindex_enable' => true,
|
||||||
'label' => false,
|
'label' => false,
|
||||||
'by_reference' => false,
|
'by_reference' => false,
|
||||||
'prototype_data' => new Orderdetail(),
|
'prototype_data' => new Orderdetail(),
|
||||||
|
@ -272,6 +274,7 @@ class PartBaseType extends AbstractType
|
||||||
'allow_add' => $this->security->isGranted('parameters.create', $part),
|
'allow_add' => $this->security->isGranted('parameters.create', $part),
|
||||||
'allow_delete' => $this->security->isGranted('parameters.delete', $part),
|
'allow_delete' => $this->security->isGranted('parameters.delete', $part),
|
||||||
'label' => false,
|
'label' => false,
|
||||||
|
'reindex_enable' => true,
|
||||||
'by_reference' => false,
|
'by_reference' => false,
|
||||||
'prototype_data' => new PartParameter(),
|
'prototype_data' => new PartParameter(),
|
||||||
'entry_options' => [
|
'entry_options' => [
|
||||||
|
|
|
@ -49,7 +49,7 @@ use App\Form\Type\SIUnitType;
|
||||||
use App\Form\Type\StructuralEntityType;
|
use App\Form\Type\StructuralEntityType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
|
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
@ -88,6 +88,7 @@ class PartLotType extends AbstractType
|
||||||
|
|
||||||
$builder->add('amount', SIUnitType::class, [
|
$builder->add('amount', SIUnitType::class, [
|
||||||
'measurement_unit' => $options['measurement_unit'],
|
'measurement_unit' => $options['measurement_unit'],
|
||||||
|
'required' => false,
|
||||||
'label' => 'part_lot.edit.amount',
|
'label' => 'part_lot.edit.amount',
|
||||||
'attr' => [
|
'attr' => [
|
||||||
'class' => 'form-control-sm',
|
'class' => 'form-control-sm',
|
||||||
|
@ -116,9 +117,11 @@ class PartLotType extends AbstractType
|
||||||
'required' => false,
|
'required' => false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$builder->add('expirationDate', DateTimeType::class, [
|
$builder->add('expirationDate', DateType::class, [
|
||||||
'label' => 'part_lot.edit.expiration_date',
|
'label' => 'part_lot.edit.expiration_date',
|
||||||
'attr' => [],
|
'attr' => [],
|
||||||
|
'widget' => 'single_text',
|
||||||
|
'model_timezone' => 'UTC',
|
||||||
'required' => false,
|
'required' => false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ class PermissionsType extends AbstractType
|
||||||
{
|
{
|
||||||
$groups = $this->perm_structure['groups'];
|
$groups = $this->perm_structure['groups'];
|
||||||
|
|
||||||
foreach ($groups as $key => $group) {
|
foreach (array_keys($groups) as $key) {
|
||||||
$builder->add($key, PermissionGroupType::class, [
|
$builder->add($key, PermissionGroupType::class, [
|
||||||
'group_name' => $key,
|
'group_name' => $key,
|
||||||
'mapped' => false,
|
'mapped' => false,
|
||||||
|
|
|
@ -102,7 +102,7 @@ class CurrencyEntityType extends StructuralEntityType
|
||||||
$level -= $parent->getLevel() - 1;
|
$level -= $parent->getLevel() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tmp = str_repeat(' ', $choice->getLevel()); //Use 3 spaces for intendation
|
$tmp = str_repeat(' ', $level); //Use 3 spaces for intendation
|
||||||
if (empty($choice->getIsoCode())) {
|
if (empty($choice->getIsoCode())) {
|
||||||
$tmp .= htmlspecialchars($choice->getName());
|
$tmp .= htmlspecialchars($choice->getName());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -153,37 +153,37 @@ class StructuralEntityType extends AbstractType
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms a value from the original representation to a transformed representation.
|
* Transforms a value from the original representation to a transformed representation.
|
||||||
*
|
*
|
||||||
* This method is called when the form field is initialized with its default data, on
|
* This method is called when the form field is initialized with its default data, on
|
||||||
* two occasions for two types of transformers:
|
* two occasions for two types of transformers:
|
||||||
*
|
*
|
||||||
* 1. Model transformers which normalize the model data.
|
* 1. Model transformers which normalize the model data.
|
||||||
* This is mainly useful when the same form type (the same configuration)
|
* This is mainly useful when the same form type (the same configuration)
|
||||||
* has to handle different kind of underlying data, e.g The DateType can
|
* has to handle different kind of underlying data, e.g The DateType can
|
||||||
* deal with strings or \DateTime objects as input.
|
* deal with strings or \DateTime objects as input.
|
||||||
*
|
*
|
||||||
* 2. View transformers which adapt the normalized data to the view format.
|
* 2. View transformers which adapt the normalized data to the view format.
|
||||||
* a/ When the form is simple, the value returned by convention is used
|
* a/ When the form is simple, the value returned by convention is used
|
||||||
* directly in the view and thus can only be a string or an array. In
|
* directly in the view and thus can only be a string or an array. In
|
||||||
* this case the data class should be null.
|
* this case the data class should be null.
|
||||||
*
|
*
|
||||||
* b/ When the form is compound the returned value should be an array or
|
* b/ When the form is compound the returned value should be an array or
|
||||||
* an object to be mapped to the children. Each property of the compound
|
* an object to be mapped to the children. Each property of the compound
|
||||||
* data will be used as model data by each child and will be transformed
|
* data will be used as model data by each child and will be transformed
|
||||||
* too. In this case data class should be the class of the object, or null
|
* too. In this case data class should be the class of the object, or null
|
||||||
* when it is an array.
|
* when it is an array.
|
||||||
*
|
*
|
||||||
* All transformers are called in a configured order from model data to view value.
|
* All transformers are called in a configured order from model data to view value.
|
||||||
* At the end of this chain the view data will be validated against the data class
|
* At the end of this chain the view data will be validated against the data class
|
||||||
* setting.
|
* setting.
|
||||||
*
|
*
|
||||||
* This method must be able to deal with empty values. Usually this will
|
* This method must be able to deal with empty values. Usually this will
|
||||||
* be NULL, but depending on your implementation other empty values are
|
* be NULL, but depending on your implementation other empty values are
|
||||||
* possible as well (such as empty strings). The reasoning behind this is
|
* possible as well (such as empty strings). The reasoning behind this is
|
||||||
* that data transformers must be chainable. If the transform() method
|
* that data transformers must be chainable. If the transform() method
|
||||||
* of the first data transformer outputs NULL, the second must be able to
|
* of the first data transformer outputs NULL, the second must be able to
|
||||||
* process that value.
|
* process that value.
|
||||||
*
|
*
|
||||||
* @param mixed $value The value in the original representation
|
* @param mixed $value The value in the original representation
|
||||||
*
|
*
|
||||||
|
@ -191,31 +191,31 @@ class StructuralEntityType extends AbstractType
|
||||||
*
|
*
|
||||||
* @throws TransformationFailedException when the transformation fails
|
* @throws TransformationFailedException when the transformation fails
|
||||||
*/
|
*/
|
||||||
public function transform($value, $options)
|
public function transform($value, array $options)
|
||||||
{
|
{
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms a value from the transformed representation to its original
|
* Transforms a value from the transformed representation to its original
|
||||||
* representation.
|
* representation.
|
||||||
*
|
*
|
||||||
* This method is called when {@link Form::submit()} is called to transform the requests tainted data
|
* This method is called when {@link Form::submit()} is called to transform the requests tainted data
|
||||||
* into an acceptable format.
|
* into an acceptable format.
|
||||||
*
|
*
|
||||||
* The same transformers are called in the reverse order so the responsibility is to
|
* The same transformers are called in the reverse order so the responsibility is to
|
||||||
* return one of the types that would be expected as input of transform().
|
* return one of the types that would be expected as input of transform().
|
||||||
*
|
*
|
||||||
* This method must be able to deal with empty values. Usually this will
|
* This method must be able to deal with empty values. Usually this will
|
||||||
* be an empty string, but depending on your implementation other empty
|
* be an empty string, but depending on your implementation other empty
|
||||||
* values are possible as well (such as NULL). The reasoning behind
|
* values are possible as well (such as NULL). The reasoning behind
|
||||||
* this is that value transformers must be chainable. If the
|
* this is that value transformers must be chainable. If the
|
||||||
* reverseTransform() method of the first value transformer outputs an
|
* reverseTransform() method of the first value transformer outputs an
|
||||||
* empty string, the second value transformer must be able to process that
|
* empty string, the second value transformer must be able to process that
|
||||||
* value.
|
* value.
|
||||||
*
|
*
|
||||||
* By convention, reverseTransform() should return NULL if an empty string
|
* By convention, reverseTransform() should return NULL if an empty string
|
||||||
* is passed.
|
* is passed.
|
||||||
*
|
*
|
||||||
* @param mixed $value The value in the transformed representation
|
* @param mixed $value The value in the transformed representation
|
||||||
*
|
*
|
||||||
|
@ -223,7 +223,7 @@ class StructuralEntityType extends AbstractType
|
||||||
*
|
*
|
||||||
* @throws TransformationFailedException when the transformation fails
|
* @throws TransformationFailedException when the transformation fails
|
||||||
*/
|
*/
|
||||||
public function reverseTransform($value, $options)
|
public function reverseTransform($value, array $options)
|
||||||
{
|
{
|
||||||
/* This step is important in combination with the caching!
|
/* This step is important in combination with the caching!
|
||||||
The elements deserialized from cache, are not known to Doctrinte ORM any more, so doctrine thinks,
|
The elements deserialized from cache, are not known to Doctrinte ORM any more, so doctrine thinks,
|
||||||
|
@ -272,7 +272,7 @@ class StructuralEntityType extends AbstractType
|
||||||
$level -= $parent->getLevel() - 1;
|
$level -= $parent->getLevel() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tmp = str_repeat(' ', $choice->getLevel()); //Use 3 spaces for intendation
|
$tmp = str_repeat(' ', $level); //Use 3 spaces for intendation
|
||||||
$tmp .= htmlspecialchars($choice->getName());
|
$tmp .= htmlspecialchars($choice->getName());
|
||||||
|
|
||||||
return $tmp;
|
return $tmp;
|
||||||
|
|
|
@ -244,6 +244,7 @@ class UserAdminForm extends AbstractType
|
||||||
'allow_add' => true,
|
'allow_add' => true,
|
||||||
'allow_delete' => true,
|
'allow_delete' => true,
|
||||||
'label' => false,
|
'label' => false,
|
||||||
|
'reindex_enable' => true,
|
||||||
'entry_options' => [
|
'entry_options' => [
|
||||||
'data_class' => $options['attachment_class'],
|
'data_class' => $options['attachment_class'],
|
||||||
],
|
],
|
||||||
|
|
|
@ -46,11 +46,6 @@ use JsonSerializable;
|
||||||
|
|
||||||
final class TreeViewNodeState implements JsonSerializable
|
final class TreeViewNodeState implements JsonSerializable
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var bool|null
|
|
||||||
*/
|
|
||||||
private $checked = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool|null
|
* @var bool|null
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -41,7 +41,7 @@ final class Version1 extends AbstractMigration
|
||||||
try {
|
try {
|
||||||
//Check if we can use this migration method:
|
//Check if we can use this migration method:
|
||||||
$version = (int) $this->connection->fetchColumn("SELECT keyValue AS version FROM `internal` WHERE `keyName` = 'dbVersion'");
|
$version = (int) $this->connection->fetchColumn("SELECT keyValue AS version FROM `internal` WHERE `keyName` = 'dbVersion'");
|
||||||
$this->skipIf(true, 'Old Part-DB Database detected! Continue with upgrade...');
|
$this->skipIf($version > 0, 'Old Part-DB Database detected! Continue with upgrade...');
|
||||||
} catch (DBALException $dBALException) {
|
} catch (DBALException $dBALException) {
|
||||||
//when the table was not found, we can proceed, because we have an empty DB!
|
//when the table was not found, we can proceed, because we have an empty DB!
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,11 @@ final class Version20200311204104 extends AbstractMigration
|
||||||
$this->addSql('ALTER TABLE `users` ADD perms_parts_parameters SMALLINT NOT NULL');
|
$this->addSql('ALTER TABLE `users` ADD perms_parts_parameters SMALLINT NOT NULL');
|
||||||
$this->addSql('ALTER TABLE log CHANGE level level TINYINT');
|
$this->addSql('ALTER TABLE log CHANGE level level TINYINT');
|
||||||
|
|
||||||
$sql = 'UPDATE `groups`' .
|
$sql = 'UPDATE `groups`'.
|
||||||
'SET perms_parts_parameters = 341 WHERE (id = 1 AND name = "admins") OR (id = 3 AND name = "users");';
|
'SET perms_parts_parameters = 341 WHERE (id = 1 AND name = "admins") OR (id = 3 AND name = "users");';
|
||||||
$this->addSql($sql);
|
$this->addSql($sql);
|
||||||
|
|
||||||
$sql = 'UPDATE `groups`' .
|
$sql = 'UPDATE `groups`'.
|
||||||
'SET perms_parts_parameters = 681 WHERE (id = 2 AND name = "readonly");';
|
'SET perms_parts_parameters = 681 WHERE (id = 2 AND name = "readonly");';
|
||||||
$this->addSql($sql);
|
$this->addSql($sql);
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,13 @@ class DBElementRepository extends EntityRepository
|
||||||
->setParameter(1, $element->getID())
|
->setParameter(1, $element->getID())
|
||||||
->getQuery();
|
->getQuery();
|
||||||
|
|
||||||
$p = $q->execute();
|
//Do the renaming
|
||||||
|
$q->execute();
|
||||||
|
|
||||||
$this->setField($element, 'id', $new_id);
|
$this->setField($element, 'id', $new_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function setField(AbstractDBElement $element, string $field, $new_value): void
|
protected function setField(AbstractDBElement $element, string $field, int $new_value): void
|
||||||
{
|
{
|
||||||
$reflection = new \ReflectionClass(get_class($element));
|
$reflection = new \ReflectionClass(get_class($element));
|
||||||
$property = $reflection->getProperty($field);
|
$property = $reflection->getProperty($field);
|
||||||
|
|
|
@ -142,7 +142,6 @@ class ElementPermissionListener
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$em = $eventArgs->getEntityManager();
|
|
||||||
$unitOfWork = $eventArgs->getEntityManager()->getUnitOfWork();
|
$unitOfWork = $eventArgs->getEntityManager()->getUnitOfWork();
|
||||||
|
|
||||||
$reflectionClass = new ReflectionClass($element);
|
$reflectionClass = new ReflectionClass($element);
|
||||||
|
|
|
@ -43,6 +43,7 @@ declare(strict_types=1);
|
||||||
namespace App\Security\Voter;
|
namespace App\Security\Voter;
|
||||||
|
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
|
use App\Repository\UserRepository;
|
||||||
use App\Services\PermissionResolver;
|
use App\Services\PermissionResolver;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
|
@ -76,6 +77,7 @@ abstract class ExtendedVoter extends Voter
|
||||||
|
|
||||||
// if the user is anonymous, we use the anonymous user.
|
// if the user is anonymous, we use the anonymous user.
|
||||||
if (! $user instanceof User) {
|
if (! $user instanceof User) {
|
||||||
|
/** @var UserRepository $repo */
|
||||||
$repo = $this->entityManager->getRepository(User::class);
|
$repo = $this->entityManager->getRepository(User::class);
|
||||||
$user = $repo->getAnonymousUser();
|
$user = $repo->getAnonymousUser();
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
|
|
|
@ -60,10 +60,11 @@ class AmountFormatter
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats the given value using the measurement unit and options.
|
* Formats the given value using the measurement unit and options.
|
||||||
*
|
*
|
||||||
* @param MeasurementUnit|null $unit The measurement unit, whose unit symbol should be used for formatting.
|
* @param float|string|int $value
|
||||||
* If set to null, it is assumed that the part amount is measured in pieces.
|
* @param MeasurementUnit|null $unit The measurement unit, whose unit symbol should be used for formatting.
|
||||||
|
* If set to null, it is assumed that the part amount is measured in pieces.
|
||||||
*
|
*
|
||||||
* @return string The formatted string
|
* @return string The formatted string
|
||||||
*
|
*
|
||||||
|
|
|
@ -130,7 +130,7 @@ class AttachmentURLGenerator
|
||||||
throw new InvalidArgumentException('Thumbnail creation only works for picture attachments!');
|
throw new InvalidArgumentException('Thumbnail creation only works for picture attachments!');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($attachment->isExternal()) {
|
if ($attachment->isExternal() && !empty($attachment->getURL())) {
|
||||||
return $attachment->getURL();
|
return $attachment->getURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,10 @@ declare(strict_types=1);
|
||||||
namespace App\Services\Attachments;
|
namespace App\Services\Attachments;
|
||||||
|
|
||||||
use App\Entity\Attachments\Attachment;
|
use App\Entity\Attachments\Attachment;
|
||||||
use Psr\Cache\InvalidArgumentException;
|
|
||||||
use Symfony\Component\Finder\Finder;
|
use Symfony\Component\Finder\Finder;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Contracts\Cache\CacheInterface;
|
use Symfony\Contracts\Cache\CacheInterface;
|
||||||
|
use Psr\Cache\InvalidArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service is used to find builtin attachment ressources.
|
* This service is used to find builtin attachment ressources.
|
||||||
|
|
|
@ -174,7 +174,7 @@ class FileTypeFilterTools
|
||||||
$extensions = array_merge($extensions, static::IMAGE_EXTS);
|
$extensions = array_merge($extensions, static::IMAGE_EXTS);
|
||||||
} elseif ('audio/*' === $element) {
|
} elseif ('audio/*' === $element) {
|
||||||
$extensions = array_merge($extensions, static::AUDIO_EXTS);
|
$extensions = array_merge($extensions, static::AUDIO_EXTS);
|
||||||
} elseif ('image/*' === $element) {
|
} elseif ('video/*' === $element) {
|
||||||
$extensions = array_merge($extensions, static::VIDEO_EXTS);
|
$extensions = array_merge($extensions, static::VIDEO_EXTS);
|
||||||
} elseif (preg_match('#^[-\w.]+\/[-\w.*]+#', $element)) {
|
} elseif (preg_match('#^[-\w.]+\/[-\w.*]+#', $element)) {
|
||||||
$extensions = array_merge($extensions, $this->mimeTypes->getExtensions($element));
|
$extensions = array_merge($extensions, $this->mimeTypes->getExtensions($element));
|
||||||
|
|
|
@ -55,13 +55,15 @@ class PartPreviewGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of attachments that can be used for previewing the part ordered by priority.
|
* Returns a list of attachments that can be used for previewing the part ordered by priority.
|
||||||
* The priority is: Part MasterAttachment -> Footprint MasterAttachment -> Category MasterAttachment
|
* The priority is: Part MasterAttachment -> Footprint MasterAttachment -> Category MasterAttachment
|
||||||
* -> Storelocation Attachment -> MeasurementUnit Attachment -> ManufacturerAttachment.
|
* -> Storelocation Attachment -> MeasurementUnit Attachment -> ManufacturerAttachment.
|
||||||
*
|
*
|
||||||
* @param Part $part the part for which the attachments should be determined
|
* @param Part $part the part for which the attachments should be determined
|
||||||
*
|
*
|
||||||
* @return Attachment[]
|
* @return (Attachment|null)[]
|
||||||
|
*
|
||||||
|
* @psalm-return list<Attachment|null>
|
||||||
*/
|
*/
|
||||||
public function getPreviewAttachments(Part $part): array
|
public function getPreviewAttachments(Part $part): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -102,7 +102,7 @@ class ElementTypeNameGenerator
|
||||||
* Useful when the type should be shown to user.
|
* Useful when the type should be shown to user.
|
||||||
* Throws an exception if the class is not supported.
|
* Throws an exception if the class is not supported.
|
||||||
*
|
*
|
||||||
* @param AbstractDBElement|string $entity The element or class for which the label should be generated
|
* @param object|string $entity The element or class for which the label should be generated
|
||||||
*
|
*
|
||||||
* @return string the localized label for the entity type
|
* @return string the localized label for the entity type
|
||||||
*
|
*
|
||||||
|
|
|
@ -77,9 +77,10 @@ class EntityExporter
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports an Entity or an array of entities to multiple file formats.
|
* Exports an Entity or an array of entities to multiple file formats.
|
||||||
*
|
*
|
||||||
* @param Request $request the request that should be used for option resolving
|
* @param Request $request the request that should be used for option resolving
|
||||||
|
* @param AbstractNamedDBElement|object[] $entity
|
||||||
*
|
*
|
||||||
* @return Response the generated response containing the exported data
|
* @return Response the generated response containing the exported data
|
||||||
*
|
*
|
||||||
|
|
|
@ -94,12 +94,12 @@ class EntityURLGenerator
|
||||||
* @param mixed $entity The element for which the page should be generated
|
* @param mixed $entity The element for which the page should be generated
|
||||||
* @param string $type The page type. Currently supported: 'info', 'edit', 'create', 'clone', 'list'/'list_parts'
|
* @param string $type The page type. Currently supported: 'info', 'edit', 'create', 'clone', 'list'/'list_parts'
|
||||||
*
|
*
|
||||||
* @return string the link to the desired page
|
* @return null|string the link to the desired page
|
||||||
*
|
*
|
||||||
* @throws EntityNotSupportedException thrown if the entity is not supported for the given type
|
* @throws EntityNotSupportedException thrown if the entity is not supported for the given type
|
||||||
* @throws InvalidArgumentException thrown if the givent type is not existing
|
* @throws InvalidArgumentException thrown if the givent type is not existing
|
||||||
*/
|
*/
|
||||||
public function getURL($entity, string $type)
|
public function getURL($entity, string $type): ?string
|
||||||
{
|
{
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'info':
|
case 'info':
|
||||||
|
@ -187,7 +187,7 @@ class EntityURLGenerator
|
||||||
throw new EntityNotSupportedException('The given entity is not supported yet!');
|
throw new EntityNotSupportedException('The given entity is not supported yet!');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function viewURL($entity): string
|
public function viewURL(Attachment $entity): ?string
|
||||||
{
|
{
|
||||||
if ($entity instanceof Attachment) {
|
if ($entity instanceof Attachment) {
|
||||||
if ($entity->isExternal()) { //For external attachments, return the link to external path
|
if ($entity->isExternal()) { //For external attachments, return the link to external path
|
||||||
|
@ -201,7 +201,7 @@ class EntityURLGenerator
|
||||||
throw new EntityNotSupportedException('The given entity is not supported yet!');
|
throw new EntityNotSupportedException('The given entity is not supported yet!');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function downloadURL($entity): string
|
public function downloadURL($entity): ?string
|
||||||
{
|
{
|
||||||
if ($entity instanceof Attachment) {
|
if ($entity instanceof Attachment) {
|
||||||
if ($entity->isExternal()) { //For external attachments, return the link to external path
|
if ($entity->isExternal()) { //For external attachments, return the link to external path
|
||||||
|
@ -383,7 +383,7 @@ class EntityURLGenerator
|
||||||
//Check if we have an direct mapping for the given class
|
//Check if we have an direct mapping for the given class
|
||||||
if (! array_key_exists($class, $map)) {
|
if (! array_key_exists($class, $map)) {
|
||||||
//Check if we need to check inheritance by looping through our map
|
//Check if we need to check inheritance by looping through our map
|
||||||
foreach ($map as $key => $value) {
|
foreach (array_keys($map) as $key) {
|
||||||
if (is_a($entity, $key)) {
|
if (is_a($entity, $key)) {
|
||||||
return $map[$key];
|
return $map[$key];
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,10 +60,14 @@ class GitVersionInfo
|
||||||
*/
|
*/
|
||||||
public function getGitBranchName()
|
public function getGitBranchName()
|
||||||
{
|
{
|
||||||
if (file_exists($this->project_dir.'/.git/HEAD')) {
|
if (is_file($this->project_dir.'/.git/HEAD')) {
|
||||||
$git = file($this->project_dir.'/.git/HEAD');
|
$git = file($this->project_dir.'/.git/HEAD');
|
||||||
$head = explode('/', $git[0], 3);
|
$head = explode('/', $git[0], 3);
|
||||||
|
|
||||||
|
if (! isset($head[2])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return trim($head[2]);
|
return trim($head[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +86,13 @@ class GitVersionInfo
|
||||||
public function getGitCommitHash(int $length = 7)
|
public function getGitCommitHash(int $length = 7)
|
||||||
{
|
{
|
||||||
$filename = $this->project_dir.'/.git/refs/remotes/origin/'.$this->getGitBranchName();
|
$filename = $this->project_dir.'/.git/refs/remotes/origin/'.$this->getGitBranchName();
|
||||||
if (file_exists($filename)) {
|
if (is_file($filename)) {
|
||||||
$head = file($filename);
|
$head = file($filename);
|
||||||
|
|
||||||
|
if (! isset($head[0])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$hash = $head[0];
|
$hash = $head[0];
|
||||||
|
|
||||||
return substr($hash, 0, $length);
|
return substr($hash, 0, $length);
|
||||||
|
|
|
@ -31,7 +31,7 @@ class EventCommentHelper
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$message = null;
|
$this->message = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -37,7 +37,7 @@ class EventUndoHelper
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$undone_event = null;
|
$this->undone_event = null;
|
||||||
$this->mode = self::MODE_UNDO;
|
$this->mode = self::MODE_UNDO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,12 @@ class HistoryHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array containing all elements that are associated with the argument.
|
* Returns an array containing all elements that are associated with the argument.
|
||||||
* The returned array contains the given element.
|
* The returned array contains the given element.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
*
|
||||||
|
* @psalm-return array<\App\Entity\Parameters\AbstractParameter|array-key, mixed>
|
||||||
*/
|
*/
|
||||||
public function getAssociatedElements(AbstractDBElement $element): array
|
public function getAssociatedElements(AbstractDBElement $element): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -209,6 +209,9 @@ class TimeTravel
|
||||||
return $property->getValue($element);
|
return $property->getValue($element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DateTime|int|null $new_value
|
||||||
|
*/
|
||||||
protected function setField(AbstractDBElement $element, string $field, $new_value): void
|
protected function setField(AbstractDBElement $element, string $field, $new_value): void
|
||||||
{
|
{
|
||||||
$reflection = new \ReflectionClass(get_class($element));
|
$reflection = new \ReflectionClass(get_class($element));
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
*
|
*
|
||||||
|
@ -20,31 +23,29 @@
|
||||||
|
|
||||||
namespace App\Services\Parameters;
|
namespace App\Services\Parameters;
|
||||||
|
|
||||||
|
|
||||||
use App\Entity\Parameters\AbstractParameter;
|
use App\Entity\Parameters\AbstractParameter;
|
||||||
use App\Entity\Parameters\PartParameter;
|
use App\Entity\Parameters\PartParameter;
|
||||||
|
|
||||||
class ParameterExtractor
|
class ParameterExtractor
|
||||||
{
|
{
|
||||||
protected const ALLOWED_PARAM_SEPARATORS = [", ", "\n"];
|
protected const ALLOWED_PARAM_SEPARATORS = [', ', "\n"];
|
||||||
|
|
||||||
protected const CHAR_LIMIT = 1000;
|
protected const CHAR_LIMIT = 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to extract parameters from the given string.
|
* Tries to extract parameters from the given string.
|
||||||
* Useful for extraction from part description and comment.
|
* Useful for extraction from part description and comment.
|
||||||
* @param string $input
|
*
|
||||||
* @param string $class
|
|
||||||
* @return AbstractParameter[]
|
* @return AbstractParameter[]
|
||||||
*/
|
*/
|
||||||
public function extractParameters(string $input, string $class = PartParameter::class): array
|
public function extractParameters(string $input, string $class = PartParameter::class): array
|
||||||
{
|
{
|
||||||
if (!is_a($class, AbstractParameter::class, true)) {
|
if (! is_a($class, AbstractParameter::class, true)) {
|
||||||
throw new \InvalidArgumentException('$class must be a child class of AbstractParameter!');
|
throw new \InvalidArgumentException('$class must be a child class of AbstractParameter!');
|
||||||
}
|
}
|
||||||
|
|
||||||
//Restrict search length
|
//Restrict search length
|
||||||
$input = mb_strimwidth($input,0,self::CHAR_LIMIT);
|
$input = mb_strimwidth($input, 0, self::CHAR_LIMIT);
|
||||||
|
|
||||||
$parameters = [];
|
$parameters = [];
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ class ParameterExtractor
|
||||||
$split = $this->splitString($input);
|
$split = $this->splitString($input);
|
||||||
foreach ($split as $param_string) {
|
foreach ($split as $param_string) {
|
||||||
$tmp = $this->stringToParam($param_string, $class);
|
$tmp = $this->stringToParam($param_string, $class);
|
||||||
if ($tmp !== null) {
|
if (null !== $tmp) {
|
||||||
$parameters[] = $tmp;
|
$parameters[] = $tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,9 +68,8 @@ class ParameterExtractor
|
||||||
|
|
||||||
$matches = [];
|
$matches = [];
|
||||||
\preg_match($regex, $input, $matches);
|
\preg_match($regex, $input, $matches);
|
||||||
dump($matches);
|
if (! empty($matches)) {
|
||||||
if (!empty($matches)) {
|
[, $name, $value] = $matches;
|
||||||
[$raw, $name, $value] = $matches;
|
|
||||||
$value = trim($value);
|
$value = trim($value);
|
||||||
|
|
||||||
//Dont allow empty names or values (these are a sign of an invalid extracted string)
|
//Dont allow empty names or values (these are a sign of an invalid extracted string)
|
||||||
|
@ -91,7 +91,8 @@ class ParameterExtractor
|
||||||
protected function splitString(string $input): array
|
protected function splitString(string $input): array
|
||||||
{
|
{
|
||||||
//Allow comma as limiter (include space, to prevent splitting in german style numbers)
|
//Allow comma as limiter (include space, to prevent splitting in german style numbers)
|
||||||
$input = str_replace(static::ALLOWED_PARAM_SEPARATORS, ";", $input);
|
$input = str_replace(static::ALLOWED_PARAM_SEPARATORS, ';', $input);
|
||||||
return explode(";", $input);
|
|
||||||
|
return explode(';', $input);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -62,12 +62,12 @@ class PermissionResolver
|
||||||
/**
|
/**
|
||||||
* PermissionResolver constructor.
|
* PermissionResolver constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(ContainerInterface $container)
|
public function __construct(bool $kernel_debug, string $kernel_cache_dir)
|
||||||
{
|
{
|
||||||
$cache_dir = $container->getParameter('kernel.cache_dir');
|
$cache_dir = $kernel_cache_dir;
|
||||||
//Here the cached structure will be saved.
|
//Here the cached structure will be saved.
|
||||||
$this->cache_file = $cache_dir.'/permissions.php.cache';
|
$this->cache_file = $cache_dir.'/permissions.php.cache';
|
||||||
$this->is_debug = $container->getParameter('kernel.debug');
|
$this->is_debug = $kernel_debug;
|
||||||
|
|
||||||
$this->permission_structure = $this->generatePermissionStructure();
|
$this->permission_structure = $this->generatePermissionStructure();
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ class PermissionResolver
|
||||||
return $allowed;
|
return $allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var HasPermissionsInterface $parent */
|
/** @var Group $parent */
|
||||||
$parent = $user->getGroup();
|
$parent = $user->getGroup();
|
||||||
while (null !== $parent) { //The top group, has parent == null
|
while (null !== $parent) { //The top group, has parent == null
|
||||||
//Check if our current element gives a info about disallow/allow
|
//Check if our current element gives a info about disallow/allow
|
||||||
|
|
|
@ -30,12 +30,10 @@ use Twig\TwigFunction;
|
||||||
|
|
||||||
class LastUserExtension extends AbstractExtension
|
class LastUserExtension extends AbstractExtension
|
||||||
{
|
{
|
||||||
private $em;
|
|
||||||
private $repo;
|
private $repo;
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
|
||||||
$this->repo = $em->getRepository(AbstractLogEntry::class);
|
$this->repo = $em->getRepository(AbstractLogEntry::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,9 @@
|
||||||
</span>
|
</span>
|
||||||
</h6>
|
</h6>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if attach.picture %}
|
{% if attach.secure and not is_granted('show_private', attach) %}
|
||||||
|
{# Leave blank #}
|
||||||
|
{% elseif attach.picture %}
|
||||||
<a href="{{ attach | entityURL('file_view') }}" target="_blank" rel="noopener" data-no-ajax>
|
<a href="{{ attach | entityURL('file_view') }}" target="_blank" rel="noopener" data-no-ajax>
|
||||||
<img class="img-fluid img-thumbnail thumbnail-sm" src="{{ attachment_thumbnail(attach, 'thumbnail_md') }}" alt="{% trans %}attachment.preview.alt{% endtrans %}" />
|
<img class="img-fluid img-thumbnail thumbnail-sm" src="{{ attachment_thumbnail(attach, 'thumbnail_md') }}" alt="{% trans %}attachment.preview.alt{% endtrans %}" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -60,7 +62,7 @@
|
||||||
|
|
||||||
{% if attach.secure %}
|
{% if attach.secure %}
|
||||||
<h6>
|
<h6>
|
||||||
<span class="badge badge-primary">
|
<span class="badge badge-success">
|
||||||
<i class="fas fa-fw fa-shield-alt"></i> {% trans %}attachment.secure{% endtrans %}
|
<i class="fas fa-fw fa-shield-alt"></i> {% trans %}attachment.secure{% endtrans %}
|
||||||
</span>
|
</span>
|
||||||
</h6>
|
</h6>
|
||||||
|
@ -90,7 +92,7 @@
|
||||||
//Determine the table, so we can determine, how many entries there are already.
|
//Determine the table, so we can determine, how many entries there are already.
|
||||||
$holder = $("#attachments_table");
|
$holder = $("#attachments_table");
|
||||||
|
|
||||||
var index = $holder.find(":input").length;
|
var index = $holder.children("tbody").children("tr").length;
|
||||||
var newForm = $holder.data("prototype");
|
var newForm = $holder.data("prototype");
|
||||||
|
|
||||||
//Increase the index
|
//Increase the index
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
//Determine the table, so we can determine, how many entries there are already.
|
//Determine the table, so we can determine, how many entries there are already.
|
||||||
$holder = $(btn).siblings("table");
|
$holder = $(btn).siblings("table");
|
||||||
|
|
||||||
var index = $holder.find(":input").length;
|
var index = $holder.children("tbody").children("tr").length;
|
||||||
var newForm = $holder.data("prototype");
|
var newForm = $holder.data("prototype");
|
||||||
|
|
||||||
//Increase the index
|
//Increase the index
|
||||||
|
|
|
@ -40,7 +40,9 @@
|
||||||
</h6>
|
</h6>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if attach.picture %}
|
{% if attach.secure and not is_granted('show_private', attach) %}
|
||||||
|
{# Leave blank #}
|
||||||
|
{% elseif attach.picture %}
|
||||||
<a href="{{ attach | entityURL('file_view') }}" rel="noopener" target="_blank" data-no-ajax>
|
<a href="{{ attach | entityURL('file_view') }}" rel="noopener" target="_blank" data-no-ajax>
|
||||||
<img class="img-fluid img-thumbnail thumbnail-sm" src="{{ attachment_thumbnail(attach, 'thumbnail_md') }}" alt="{% trans %}attachment.preview.alt{% endtrans %}" />
|
<img class="img-fluid img-thumbnail thumbnail-sm" src="{{ attachment_thumbnail(attach, 'thumbnail_md') }}" alt="{% trans %}attachment.preview.alt{% endtrans %}" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -58,7 +60,7 @@
|
||||||
|
|
||||||
{% if attach.secure %}
|
{% if attach.secure %}
|
||||||
<h6>
|
<h6>
|
||||||
<span class="badge badge-primary">
|
<span class="badge badge-success">
|
||||||
<i class="fas fa-fw fa-shield-alt"></i> {% trans %}attachment.secure{% endtrans %}
|
<i class="fas fa-fw fa-shield-alt"></i> {% trans %}attachment.secure{% endtrans %}
|
||||||
</span>
|
</span>
|
||||||
</h6>
|
</h6>
|
||||||
|
@ -88,7 +90,7 @@
|
||||||
//Determine the table, so we can determine, how many entries there are already.
|
//Determine the table, so we can determine, how many entries there are already.
|
||||||
$holder = $("#attachments_table");
|
$holder = $("#attachments_table");
|
||||||
|
|
||||||
var index = $holder.find(":input").length;
|
var index = $holder.children("tbody").children("tr").length;
|
||||||
var newForm = $holder.data("prototype");
|
var newForm = $holder.data("prototype");
|
||||||
|
|
||||||
//Increase the index
|
//Increase the index
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue