Merge branch 'master' into l10n_master

This commit is contained in:
Jan Böhmer 2020-03-29 15:29:24 +02:00
commit b0e216cbb8
166 changed files with 5312 additions and 3361 deletions

View file

@ -811,7 +811,7 @@ div.dataTables_wrapper div.dataTables_info {
padding: 10px 10px;
margin: 0 0 10px;
font-size: 17.5px;
border-left: 5px solid #eee;
border-left: 5px solid #aaa;
}
.darkmode-layer {

View file

@ -91,6 +91,11 @@ require('./jquery.tristate.js');
require('darkmode-js');
//Equation rendering
require('katex');
window.renderMathInElement = require('katex/contrib/auto-render/auto-render').default;
import 'katex/dist/katex.css';
window.ClipboardJS = require('clipboard');
window.QRCode = require('qrcode');

View file

@ -465,6 +465,19 @@ $(document).on("ajaxUI:start", function () {
//Bootstrapify objects
$('table', this).addClass('table table-hover table-striped table-bordered');
});
//Latex rendering have to be done after markdown parsing
$('.latex').each(function(index, element) {
//@ts-ignore
window.renderMathInElement(element, {
delimiters: [
{left: "$$", right: "$$", display: true},
{left: "$", right: "$", display: false},
{left: "\\(", right: "\\)", display: false},
{left: "\\[", right: "\\]", display: true}
]
});
});
}
//Configure markdown
@ -552,6 +565,7 @@ $(document).on("ajaxUI:reload", function() {
})
});
//Need for proper body padding, with every navbar height
$(window).resize(function () {
let height : number = $('#navbar').height() + 10;

View file

@ -69,7 +69,7 @@
"symfony/maker-bundle": "^1.13",
"symfony/profiler-pack": "*",
"symfony/test-pack": "^1.0",
"symplify/easy-coding-standard": "^7.1",
"symplify/easy-coding-standard": "7.2.3",
"vimeo/psalm": "^3.5"
},
"config": {
@ -91,14 +91,6 @@
"App\\Tests\\": "tests/"
}
},
"replace": {
"paragonie/random_compat": "2.*",
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php71": "*",
"symfony/polyfill-php70": "*",
"symfony/polyfill-php56": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",

843
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,14 @@
Welcome to Part-DB.
<small>If you want to change this banner, edit `config/banner.md` file or set the `BANNER` environment variable.</small>
<small>If you want to change this banner, edit `config/banner.md` file or set the `BANNER` environment variable.</small>
<blockquote class="pb-0">
<p style="font-size: 12px">
And God said <br>
$\nabla \cdot \vec{D} = \rho$,
$\nabla \cdot \vec{B} = 0$,
$\nabla \times \vec{E} = -\frac{\partial \vec{B}}{\partial t}$,
$\nabla \times \vec{H} = \vec{j} + \frac{\partial \vec{D}}{\partial t}$, <br>
and then there was light.
</p>
</blockquote>

View file

@ -1,4 +1,7 @@
#webpack_encore:
webpack_encore:
# Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes)
# Available in version 1.2
#cache: true
cache: true
# Preload in production
preload: false

View file

@ -8,7 +8,7 @@ webpack_encore:
# crossorigin: 'anonymous'
# preload all rendered script and link tags automatically via the http2 Link header
preload: true
#preload: false
# Throw an exception if the entrypoints.json file is missing or an entry is missing from the data
# strict_mode: false

View file

@ -153,6 +153,10 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
<<: *PART_MULTI_ATTRIBUTE
label: "perm.part.prices"
parts_parameters:
<<: *PART_MULTI_ATTRIBUTE
label: "perm.part.parameters"
parts_lots:
<<: *PART_MULTI_ATTRIBUTE
label: "perm.part.lots"

View file

@ -9,6 +9,10 @@ parameters:
# - "symplify"
- "symfony"
paths:
- 'src'
- 'tests'
skip:
Symplify\CodingStandard\Fixer\Naming\PropertyNameMatchingTypeFixer: ~
Symplify\CodingStandard\Fixer\LineLength\LineLengthFixer: ~

View file

@ -43,6 +43,7 @@
"exports-loader": "^0.7.0",
"jquery-form": "^4.2.2",
"jszip": "^3.2.0",
"katex": "^0.11.1",
"marked": "^0.8.0",
"patternfly-bootstrap-treeview": "^2.1.8",
"pdfmake": "^0.1.53",

View file

@ -125,6 +125,7 @@ class SetPasswordCommand extends Command
$this->entityManager->flush();
$io->success('Password was set successful! You can now log in using the new password.');
return 0;
}
}

View file

@ -139,6 +139,7 @@ class UpdateExchangeRatesCommand extends Command
$this->em->flush();
$io->success(sprintf('%d (of %d) currency exchange rates were updated.', $success_counter, count($candidates)));
return 0;
}
}

View file

@ -44,6 +44,7 @@ namespace App\Controller\AdminPages;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Attachments\AttachmentTypeAttachment;
use App\Entity\Parameters\AttachmentTypeParameter;
use App\Form\AdminPages\AttachmentTypeAdminForm;
use App\Services\EntityExporter;
use App\Services\EntityImporter;
@ -64,13 +65,11 @@ class AttachmentTypeController extends BaseAdminController
protected $form_class = AttachmentTypeAdminForm::class;
protected $route_base = 'attachment_type';
protected $attachment_class = AttachmentTypeAttachment::class;
protected $parameter_class = AttachmentTypeParameter::class;
/**
* @Route("/{id}", name="attachment_type_delete", methods={"DELETE"})
*
* @param Request $request
* @param AttachmentType $entity
* @param StructuralElementRecursionHelper $recursionHelper
* @return RedirectResponse
*/
public function delete(Request $request, AttachmentType $entity, StructuralElementRecursionHelper $recursionHelper): RedirectResponse
@ -82,9 +81,6 @@ class AttachmentTypeController extends BaseAdminController
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="attachment_type_edit")
* @Route("/{id}", requirements={"id"="\d+"})
*
* @param AttachmentType $entity
* @param Request $request
* @param EntityManagerInterface $em
* @return Response
*/
public function edit(AttachmentType $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
@ -96,9 +92,6 @@ class AttachmentTypeController extends BaseAdminController
* @Route("/new", name="attachment_type_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -109,9 +102,6 @@ class AttachmentTypeController extends BaseAdminController
/**
* @Route("/export", name="attachment_type_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -122,9 +112,6 @@ class AttachmentTypeController extends BaseAdminController
/**
* @Route("/{id}/export", name="attachment_type_export")
*
* @param AttachmentType $entity
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(AttachmentType $entity, EntityExporter $exporter, Request $request): Response

View file

@ -77,6 +77,7 @@ abstract class BaseAdminController extends AbstractController
protected $twig_template = '';
protected $route_base = '';
protected $attachment_class = '';
protected $parameter_class = '';
protected $passwordEncoder;
protected $translator;
@ -101,6 +102,10 @@ abstract class BaseAdminController extends AbstractController
throw new InvalidArgumentException('You have to override the $attachment_class value in your subclass!');
}
if ('' === $this->parameter_class) {
throw new InvalidArgumentException('You have to override the $parameter_class value in your subclass!');
}
$this->translator = $translator;
$this->passwordEncoder = $passwordEncoder;
$this->attachmentHelper = $attachmentHelper;
@ -111,14 +116,12 @@ abstract class BaseAdminController extends AbstractController
$this->dataTableFactory = $dataTableFactory;
}
protected function _edit(AbstractNamedDBElement $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null) : Response
protected function _edit(AbstractNamedDBElement $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
{
$this->denyAccessUnlessGranted('read', $entity);
$timeTravel_timestamp = null;
if ($timestamp !== null) {
if (null !== $timestamp) {
$this->denyAccessUnlessGranted('@tools.timetravel');
$this->denyAccessUnlessGranted('show_history', $entity);
//If the timestamp only contains numbers interpret it as unix timestamp
@ -131,12 +134,12 @@ abstract class BaseAdminController extends AbstractController
$this->timeTravel->revertEntityToTimestamp($entity, $timeTravel_timestamp);
}
if ($this->isGranted('show_history', $entity) ) {
if ($this->isGranted('show_history', $entity)) {
$table = $this->dataTableFactory->createFromType(
LogDataTable::class,
[
'filter_elements' => $this->historyHelper->getAssociatedElements($entity),
'mode' => 'element_history'
'mode' => 'element_history',
],
['pageLength' => 10]
)
@ -151,7 +154,8 @@ abstract class BaseAdminController extends AbstractController
$form = $this->createForm($this->form_class, $entity, [
'attachment_class' => $this->attachment_class,
'disabled' => $timeTravel_timestamp !== null ? true : null
'parameter_class' => $this->parameter_class,
'disabled' => null !== $timeTravel_timestamp ? true : null,
]);
$form->handleRequest($request);
@ -191,7 +195,10 @@ abstract class BaseAdminController extends AbstractController
//Rebuild form, so it is based on the updated data. Important for the parent field!
//We can not use dynamic form events here, because the parent entity list is build from database!
$form = $this->createForm($this->form_class, $entity, ['attachment_class' => $this->attachment_class]);
$form = $this->createForm($this->form_class, $entity, [
'attachment_class' => $this->attachment_class,
'parameter_class' => $this->parameter_class
]);
} elseif ($form->isSubmitted() && ! $form->isValid()) {
$this->addFlash('error', 'entity.edit_flash.invalid');
}
@ -202,7 +209,7 @@ abstract class BaseAdminController extends AbstractController
'attachment_helper' => $this->attachmentHelper,
'route_base' => $this->route_base,
'datatable' => $table,
'timeTravel' => $timeTravel_timestamp
'timeTravel' => $timeTravel_timestamp,
]);
}
@ -214,7 +221,10 @@ abstract class BaseAdminController extends AbstractController
$this->denyAccessUnlessGranted('read', $new_entity);
//Basic edit form
$form = $this->createForm($this->form_class, $new_entity, ['attachment_class' => $this->attachment_class]);
$form = $this->createForm($this->form_class, $new_entity, [
'attachment_class' => $this->attachment_class,
'parameter_class' => $this->parameter_class,
]);
$form->handleRequest($request);
@ -274,9 +284,7 @@ abstract class BaseAdminController extends AbstractController
'csv_separator' => $data['csv_separator'],
];
$this->commentHelper->setMessage('Import ' . $file->getClientOriginalName());
$this->commentHelper->setMessage('Import '.$file->getClientOriginalName());
$errors = $importer->fileToDBEntities($file, $this->entity_class, $options);
@ -319,7 +327,7 @@ abstract class BaseAdminController extends AbstractController
]);
}
protected function _delete(Request $request, AbstractNamedDBElement $entity, StructuralElementRecursionHelper $recursionHelper) : RedirectResponse
protected function _delete(Request $request, AbstractNamedDBElement $entity, StructuralElementRecursionHelper $recursionHelper): RedirectResponse
{
$this->denyAccessUnlessGranted('delete', $entity);

View file

@ -43,6 +43,7 @@ declare(strict_types=1);
namespace App\Controller\AdminPages;
use App\Entity\Attachments\CategoryAttachment;
use App\Entity\Parameters\CategoryParameter;
use App\Entity\Parts\Category;
use App\Form\AdminPages\CategoryAdminForm;
use App\Services\EntityExporter;
@ -64,13 +65,11 @@ class CategoryController extends BaseAdminController
protected $form_class = CategoryAdminForm::class;
protected $route_base = 'category';
protected $attachment_class = CategoryAttachment::class;
protected $parameter_class = CategoryParameter::class;
/**
* @Route("/{id}", name="category_delete", methods={"DELETE"})
*
* @param Request $request
* @param Category $entity
* @param StructuralElementRecursionHelper $recursionHelper
* @return RedirectResponse
*/
public function delete(Request $request, Category $entity, StructuralElementRecursionHelper $recursionHelper): RedirectResponse
@ -82,9 +81,6 @@ class CategoryController extends BaseAdminController
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="category_edit")
* @Route("/{id}", requirements={"id"="\d+"})
*
* @param Category $entity
* @param Request $request
* @param EntityManagerInterface $em
* @return Response
*/
public function edit(Category $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
@ -96,9 +92,6 @@ class CategoryController extends BaseAdminController
* @Route("/new", name="category_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -109,9 +102,6 @@ class CategoryController extends BaseAdminController
/**
* @Route("/export", name="category_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -122,9 +112,6 @@ class CategoryController extends BaseAdminController
/**
* @Route("/{id}/export", name="category_export")
*
* @param Category $entity
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(Category $entity, EntityExporter $exporter, Request $request): Response

View file

@ -43,6 +43,7 @@ declare(strict_types=1);
namespace App\Controller\AdminPages;
use App\Entity\Attachments\CurrencyAttachment;
use App\Entity\Parameters\CurrencyParameter;
use App\Entity\PriceInformations\Currency;
use App\Form\AdminPages\CurrencyAdminForm;
use App\Services\EntityExporter;
@ -66,13 +67,11 @@ class CurrencyController extends BaseAdminController
protected $form_class = CurrencyAdminForm::class;
protected $route_base = 'currency';
protected $attachment_class = CurrencyAttachment::class;
protected $parameter_class = CurrencyParameter::class;
/**
* @Route("/{id}", name="currency_delete", methods={"DELETE"})
*
* @param Request $request
* @param Currency $entity
* @param StructuralElementRecursionHelper $recursionHelper
* @return RedirectResponse
*/
public function delete(Request $request, Currency $entity, StructuralElementRecursionHelper $recursionHelper): RedirectResponse
@ -84,9 +83,6 @@ class CurrencyController extends BaseAdminController
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="currency_edit")
* @Route("/{id}", requirements={"id"="\d+"})
*
* @param Currency $entity
* @param Request $request
* @param EntityManagerInterface $em
* @return Response
*/
public function edit(Currency $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
@ -98,9 +94,6 @@ class CurrencyController extends BaseAdminController
* @Route("/new", name="currency_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -111,9 +104,6 @@ class CurrencyController extends BaseAdminController
/**
* @Route("/export", name="currency_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -124,9 +114,6 @@ class CurrencyController extends BaseAdminController
/**
* @Route("/{id}/export", name="currency_export")
*
* @param Currency $entity
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(Currency $entity, EntityExporter $exporter, Request $request): Response

View file

@ -44,6 +44,7 @@ namespace App\Controller\AdminPages;
use App\Entity\Attachments\DeviceAttachment;
use App\Entity\Devices\Device;
use App\Entity\Parameters\DeviceParameter;
use App\Form\AdminPages\BaseEntityAdminForm;
use App\Services\EntityExporter;
use App\Services\EntityImporter;
@ -64,13 +65,11 @@ class DeviceController extends BaseAdminController
protected $form_class = BaseEntityAdminForm::class;
protected $route_base = 'device';
protected $attachment_class = DeviceAttachment::class;
protected $parameter_class = DeviceParameter::class;
/**
* @Route("/{id}", name="device_delete", methods={"DELETE"})
*
* @param Request $request
* @param Device $entity
* @param StructuralElementRecursionHelper $recursionHelper
* @return RedirectResponse
*/
public function delete(Request $request, Device $entity, StructuralElementRecursionHelper $recursionHelper): RedirectResponse
@ -82,9 +81,6 @@ class DeviceController extends BaseAdminController
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="device_edit")
* @Route("/{id}", requirements={"id"="\d+"})
*
* @param Device $entity
* @param Request $request
* @param EntityManagerInterface $em
* @return Response
*/
public function edit(Device $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
@ -96,9 +92,6 @@ class DeviceController extends BaseAdminController
* @Route("/new", name="device_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -109,9 +102,6 @@ class DeviceController extends BaseAdminController
/**
* @Route("/export", name="device_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -122,9 +112,6 @@ class DeviceController extends BaseAdminController
/**
* @Route("/{id}/export", name="device_export")
*
* @param Device $entity
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(Device $entity, EntityExporter $exporter, Request $request): Response

View file

@ -44,6 +44,7 @@ namespace App\Controller\AdminPages;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Attachments\FootprintAttachment;
use App\Entity\Parameters\FootprintParameter;
use App\Entity\Parts\Footprint;
use App\Form\AdminPages\FootprintAdminForm;
use App\Services\EntityExporter;
@ -64,12 +65,11 @@ class FootprintController extends BaseAdminController
protected $form_class = FootprintAdminForm::class;
protected $route_base = 'footprint';
protected $attachment_class = FootprintAttachment::class;
protected $parameter_class = FootprintParameter::class;
/**
* @Route("/{id}", name="footprint_delete", methods={"DELETE"})
* @param Request $request
* @param Footprint $entity
* @param StructuralElementRecursionHelper $recursionHelper
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function delete(Request $request, Footprint $entity, StructuralElementRecursionHelper $recursionHelper)
@ -80,9 +80,7 @@ class FootprintController extends BaseAdminController
/**
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="footprint_edit")
* @Route("/{id}", requirements={"id"="\d+"})
* @param Footprint $entity
* @param Request $request
* @param EntityManagerInterface $em
*
* @return Response
*/
public function edit(Footprint $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
@ -94,9 +92,6 @@ class FootprintController extends BaseAdminController
* @Route("/new", name="footprint_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -107,9 +102,6 @@ class FootprintController extends BaseAdminController
/**
* @Route("/export", name="footprint_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -120,9 +112,6 @@ class FootprintController extends BaseAdminController
/**
* @Route("/{id}/export", name="footprint_export")
*
* @param AttachmentType $entity
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(AttachmentType $entity, EntityExporter $exporter, Request $request): Response

View file

@ -43,6 +43,7 @@ declare(strict_types=1);
namespace App\Controller\AdminPages;
use App\Entity\Attachments\ManufacturerAttachment;
use App\Entity\Parameters\ManufacturerParameter;
use App\Entity\Parts\Manufacturer;
use App\Form\AdminPages\CompanyForm;
use App\Services\EntityExporter;
@ -63,12 +64,11 @@ class ManufacturerController extends BaseAdminController
protected $form_class = CompanyForm::class;
protected $route_base = 'manufacturer';
protected $attachment_class = ManufacturerAttachment::class;
protected $parameter_class = ManufacturerParameter::class;
/**
* @Route("/{id}", name="manufacturer_delete", methods={"DELETE"})
* @param Request $request
* @param Manufacturer $entity
* @param StructuralElementRecursionHelper $recursionHelper
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function delete(Request $request, Manufacturer $entity, StructuralElementRecursionHelper $recursionHelper)
@ -79,9 +79,7 @@ class ManufacturerController extends BaseAdminController
/**
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="manufacturer_edit")
* @Route("/{id}", requirements={"id"="\d+"})
* @param Manufacturer $entity
* @param Request $request
* @param EntityManagerInterface $em
*
* @return Response
*/
public function edit(Manufacturer $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
@ -93,9 +91,6 @@ class ManufacturerController extends BaseAdminController
* @Route("/new", name="manufacturer_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -106,9 +101,6 @@ class ManufacturerController extends BaseAdminController
/**
* @Route("/export", name="manufacturer_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -119,10 +111,6 @@ class ManufacturerController extends BaseAdminController
/**
* @Route("/{id}/export", name="manufacturer_export")
*
* @param Manufacturer $entity
*
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(Manufacturer $entity, EntityExporter $exporter, Request $request): Response

View file

@ -44,6 +44,7 @@ namespace App\Controller\AdminPages;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Attachments\MeasurementUnitAttachment;
use App\Entity\Parameters\MeasurementUnitParameter;
use App\Entity\Parts\MeasurementUnit;
use App\Form\AdminPages\MeasurementUnitAdminForm;
use App\Services\EntityExporter;
@ -64,12 +65,11 @@ class MeasurementUnitController extends BaseAdminController
protected $form_class = MeasurementUnitAdminForm::class;
protected $route_base = 'measurement_unit';
protected $attachment_class = MeasurementUnitAttachment::class;
protected $parameter_class = MeasurementUnitParameter::class;
/**
* @Route("/{id}", name="measurement_unit_delete", methods={"DELETE"})
* @param Request $request
* @param MeasurementUnit $entity
* @param StructuralElementRecursionHelper $recursionHelper
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function delete(Request $request, MeasurementUnit $entity, StructuralElementRecursionHelper $recursionHelper)
@ -80,9 +80,7 @@ class MeasurementUnitController extends BaseAdminController
/**
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="measurement_unit_edit")
* @Route("/{id}", requirements={"id"="\d+"})
* @param MeasurementUnit $entity
* @param Request $request
* @param EntityManagerInterface $em
*
* @return Response
*/
public function edit(MeasurementUnit $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
@ -94,9 +92,6 @@ class MeasurementUnitController extends BaseAdminController
* @Route("/new", name="measurement_unit_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -107,9 +102,6 @@ class MeasurementUnitController extends BaseAdminController
/**
* @Route("/export", name="measurement_unit_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -120,9 +112,6 @@ class MeasurementUnitController extends BaseAdminController
/**
* @Route("/{id}/export", name="measurement_unit_export")
*
* @param AttachmentType $entity
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(AttachmentType $entity, EntityExporter $exporter, Request $request): Response

View file

@ -42,6 +42,7 @@ declare(strict_types=1);
namespace App\Controller\AdminPages;
use App\Entity\Parameters\StorelocationParameter;
use App\Entity\Parts\Storelocation;
use App\Form\AdminPages\StorelocationAdminForm;
use App\Services\EntityExporter;
@ -62,12 +63,11 @@ class StorelocationController extends BaseAdminController
protected $form_class = StorelocationAdminForm::class;
protected $route_base = 'store_location';
protected $attachment_class = StorelocationAdminForm::class;
protected $parameter_class = StorelocationParameter::class;
/**
* @Route("/{id}", name="store_location_delete", methods={"DELETE"})
* @param Request $request
* @param Storelocation $entity
* @param StructuralElementRecursionHelper $recursionHelper
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function delete(Request $request, Storelocation $entity, StructuralElementRecursionHelper $recursionHelper)
@ -78,9 +78,7 @@ class StorelocationController extends BaseAdminController
/**
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="store_location_edit")
* @Route("/{id}", requirements={"id"="\d+"})
* @param Storelocation $entity
* @param Request $request
* @param EntityManagerInterface $em
*
* @return Response
*/
public function edit(Storelocation $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
@ -92,9 +90,6 @@ class StorelocationController extends BaseAdminController
* @Route("/new", name="store_location_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -105,9 +100,6 @@ class StorelocationController extends BaseAdminController
/**
* @Route("/export", name="store_location_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -118,10 +110,6 @@ class StorelocationController extends BaseAdminController
/**
* @Route("/{id}/export", name="store_location_export")
*
* @param Storelocation $entity
*
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(Storelocation $entity, EntityExporter $exporter, Request $request): Response

View file

@ -43,6 +43,7 @@ declare(strict_types=1);
namespace App\Controller\AdminPages;
use App\Entity\Attachments\SupplierAttachment;
use App\Entity\Parameters\SupplierParameter;
use App\Entity\Parts\Supplier;
use App\Form\AdminPages\SupplierForm;
use App\Services\EntityExporter;
@ -63,12 +64,11 @@ class SupplierController extends BaseAdminController
protected $form_class = SupplierForm::class;
protected $route_base = 'supplier';
protected $attachment_class = SupplierAttachment::class;
protected $parameter_class = SupplierParameter::class;
/**
* @Route("/{id}", name="supplier_delete", methods={"DELETE"})
* @param Request $request
* @param Supplier $entity
* @param StructuralElementRecursionHelper $recursionHelper
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function delete(Request $request, Supplier $entity, StructuralElementRecursionHelper $recursionHelper)
@ -79,9 +79,7 @@ class SupplierController extends BaseAdminController
/**
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="supplier_edit")
* @Route("/{id}", requirements={"id"="\d+"})
* @param Supplier $entity
* @param Request $request
* @param EntityManagerInterface $em
*
* @return Response
*/
public function edit(Supplier $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
@ -93,9 +91,6 @@ class SupplierController extends BaseAdminController
* @Route("/new", name="supplier_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -106,9 +101,6 @@ class SupplierController extends BaseAdminController
/**
* @Route("/export", name="supplier_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -119,9 +111,6 @@ class SupplierController extends BaseAdminController
/**
* @Route("/{id}/export", name="supplier_export")
*
* @param Supplier $entity
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(Supplier $entity, EntityExporter $exporter, Request $request): Response

View file

@ -46,7 +46,6 @@ use App\DataTables\AttachmentDataTable;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\PartAttachment;
use App\Services\Attachments\AttachmentManager;
use Exception;
use Omines\DataTablesBundle\DataTableFactory;
use RuntimeException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -64,8 +63,6 @@ class AttachmentFileController extends AbstractController
*
* @Route("/attachment/{id}/download", name="attachment_download")
*
* @param Attachment $attachment
* @param AttachmentManager $helper
* @return BinaryFileResponse
*/
public function download(Attachment $attachment, AttachmentManager $helper): BinaryFileResponse
@ -94,10 +91,7 @@ class AttachmentFileController extends AbstractController
*
* @Route("/attachment/{id}/view", name="attachment_view")
*
* @param Attachment $attachment
* @param AttachmentManager $helper
* @return BinaryFileResponse
*
*/
public function view(Attachment $attachment, AttachmentManager $helper): BinaryFileResponse
{
@ -123,8 +117,6 @@ class AttachmentFileController extends AbstractController
/**
* @Route("/attachment/list", name="attachment_list")
*
* @param DataTableFactory $dataTable
* @param Request $request
* @return JsonResponse|Response
*/
public function attachmentsTable(DataTableFactory $dataTable, Request $request)

View file

@ -44,6 +44,7 @@ namespace App\Controller;
use App\Controller\AdminPages\BaseAdminController;
use App\Entity\Attachments\GroupAttachment;
use App\Entity\Parameters\GroupParameter;
use App\Entity\UserSystem\Group;
use App\Form\AdminPages\GroupAdminForm;
use App\Services\EntityExporter;
@ -65,14 +66,12 @@ class GroupController extends BaseAdminController
protected $form_class = GroupAdminForm::class;
protected $route_base = 'group';
protected $attachment_class = GroupAttachment::class;
protected $parameter_class = GroupParameter::class;
/**
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="group_edit")
* @Route("/{id}/", requirements={"id"="\d+"})
*
* @param Group $entity
* @param Request $request
* @param EntityManagerInterface $em
* @return Response
*/
public function edit(Group $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
@ -84,9 +83,6 @@ class GroupController extends BaseAdminController
* @Route("/new", name="group_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -97,9 +93,6 @@ class GroupController extends BaseAdminController
/**
* @Route("/{id}", name="group_delete", methods={"DELETE"})
*
* @param Request $request
* @param Group $entity
* @param StructuralElementRecursionHelper $recursionHelper
* @return RedirectResponse
*/
public function delete(Request $request, Group $entity, StructuralElementRecursionHelper $recursionHelper): RedirectResponse
@ -110,9 +103,6 @@ class GroupController extends BaseAdminController
/**
* @Route("/export", name="group_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -123,9 +113,6 @@ class GroupController extends BaseAdminController
/**
* @Route("/{id}/export", name="group_export")
*
* @param Group $entity
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(Group $entity, EntityExporter $exporter, Request $request): Response

View file

@ -44,11 +44,11 @@ namespace App\Controller;
use App\DataTables\LogDataTable;
use App\Services\GitVersionInfo;
use const DIRECTORY_SEPARATOR;
use Omines\DataTablesBundle\DataTableFactory;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use const DIRECTORY_SEPARATOR;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Cache\CacheInterface;
@ -81,16 +81,16 @@ class HomepageController extends AbstractController
/**
* @Route("/", name="homepage")
* @param GitVersionInfo $versionInfo
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function homepage(Request $request, GitVersionInfo $versionInfo): Response
{
if ($this->isGranted("@tools.lastActivity")) {
if ($this->isGranted('@tools.lastActivity')) {
$table = $this->dataTable->createFromType(
LogDataTable::class,
[
'mode' => 'last_activity'
'mode' => 'last_activity',
],
['pageLength' => 10]
)
@ -107,7 +107,7 @@ class HomepageController extends AbstractController
'banner' => $this->getBanner(),
'git_branch' => $versionInfo->getGitBranchName(),
'git_commit' => $versionInfo->getGitCommitHash(),
'datatable' => $table
'datatable' => $table,
]);
}
}

View file

@ -56,7 +56,6 @@ use Omines\DataTablesBundle\DataTableFactory;
use phpDocumentor\Reflection\Element;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
@ -70,7 +69,6 @@ class LogController extends AbstractController
protected $timeTravel;
protected $dbRepository;
public function __construct(EntityManagerInterface $entityManager, TimeTravel $timeTravel)
{
$this->entityManager = $entityManager;
@ -81,8 +79,6 @@ class LogController extends AbstractController
/**
* @Route("/", name="log_view")
*
* @param Request $request
* @param DataTableFactory $dataTable
* @return JsonResponse|Response
*/
public function showLogs(Request $request, DataTableFactory $dataTable)
@ -103,7 +99,6 @@ class LogController extends AbstractController
/**
* @Route("/undo", name="log_undo", methods={"POST"})
* @param Request $request
*/
public function undoRevertLog(Request $request, EventUndoHelper $eventUndoHelper)
{
@ -111,13 +106,13 @@ class LogController extends AbstractController
$id = $request->request->get('undo');
//If no undo value was set check if a revert was set
if ($id === null) {
if (null === $id) {
$id = $request->get('revert');
$mode = EventUndoHelper::MODE_REVERT;
}
$log_element = $this->entityManager->find(AbstractLogEntry::class, $id);
if ($log_element === null) {
if (null === $log_element) {
throw new \InvalidArgumentException('No log entry with the given ID is existing!');
}
@ -126,15 +121,16 @@ class LogController extends AbstractController
$eventUndoHelper->setMode($mode);
$eventUndoHelper->setUndoneEvent($log_element);
if ($mode === EventUndoHelper::MODE_UNDO) {
if (EventUndoHelper::MODE_UNDO === $mode) {
$this->undoLog($log_element);
} elseif ($mode === EventUndoHelper::MODE_REVERT) {
} elseif (EventUndoHelper::MODE_REVERT === $mode) {
$this->revertLog($log_element);
}
$eventUndoHelper->clearUndoneEvent();
$redirect = $request->request->get('redirect_back');
return $this->redirect($redirect);
}
@ -143,15 +139,16 @@ class LogController extends AbstractController
$timestamp = $logEntry->getTimestamp();
$element = $this->entityManager->find($logEntry->getTargetClass(), $logEntry->getTargetID());
//If the element is not available in DB try to undelete it
if ($element === null) {
if (null === $element) {
$element = $this->timeTravel->undeleteEntity($logEntry->getTargetClass(), $logEntry->getTargetID());
$this->entityManager->persist($element);
$this->entityManager->flush();
$this->dbRepository->changeID($element, $logEntry->getTargetID());
}
if (!$element instanceof AbstractDBElement) {
if (! $element instanceof AbstractDBElement) {
$this->addFlash('error', 'log.undo.target_not_found');
return;
}
@ -172,7 +169,7 @@ class LogController extends AbstractController
}
//Check if the element we want to undelete already exits
if ($this->entityManager->find($element_class, $element_id) == null) {
if (null === $this->entityManager->find($element_class, $element_id)) {
$undeleted_element = $this->timeTravel->undeleteEntity($element_class, $element_id);
$this->entityManager->persist($undeleted_element);
$this->entityManager->flush();
@ -183,7 +180,7 @@ class LogController extends AbstractController
}
} elseif ($log_element instanceof ElementCreatedLogEntry) {
$element = $this->entityManager->find($log_element->getTargetClass(), $log_element->getTargetID());
if ($element !== null) {
if (null !== $element) {
$this->entityManager->remove($element);
$this->entityManager->flush();
$this->addFlash('success', 'log.undo.element_delete_success');

View file

@ -53,6 +53,7 @@ use App\Services\Attachments\PartPreviewGenerator;
use App\Services\LogSystem\EventCommentHelper;
use App\Services\LogSystem\HistoryHelper;
use App\Services\LogSystem\TimeTravel;
use App\Services\Parameters\ParameterExtractor;
use App\Services\PricedetailHelper;
use Doctrine\ORM\EntityManagerInterface;
use Omines\DataTablesBundle\DataTableFactory;
@ -87,17 +88,17 @@ class PartController extends AbstractController
* @Route("/{id}/info/{timestamp}", name="part_info")
* @Route("/{id}", requirements={"id"="\d+"})
*
* @param Part $part
* @return Response
*
* @throws \Exception
*/
public function show(Part $part, Request $request, TimeTravel $timeTravel, HistoryHelper $historyHelper,
DataTableFactory $dataTable, ?string $timestamp = null): Response
DataTableFactory $dataTable, ParameterExtractor $parameterExtractor, ?string $timestamp = null): Response
{
$this->denyAccessUnlessGranted('read', $part);
$timeTravel_timestamp = null;
if ($timestamp !== null) {
if (null !== $timestamp) {
$this->denyAccessUnlessGranted('@tools.timetravel');
$this->denyAccessUnlessGranted('show_history', $part);
//If the timestamp only contains numbers interpret it as unix timestamp
@ -110,10 +111,10 @@ class PartController extends AbstractController
$timeTravel->revertEntityToTimestamp($part, $timeTravel_timestamp);
}
if ($this->isGranted('show_history', $part) ) {
if ($this->isGranted('show_history', $part)) {
$table = $dataTable->createFromType(LogDataTable::class, [
'filter_elements' => $historyHelper->getAssociatedElements($part),
'mode' => 'element_history'
'mode' => 'element_history',
], ['pageLength' => 10])
->handleRequest($request);
@ -132,7 +133,9 @@ class PartController extends AbstractController
'attachment_helper' => $this->attachmentManager,
'pricedetail_helper' => $this->pricedetailHelper,
'pictures' => $this->partPreviewGenerator->getPreviewAttachments($part),
'timeTravel' => $timeTravel_timestamp
'timeTravel' => $timeTravel_timestamp,
'description_params' => $parameterExtractor->extractParameters($part->getDescription()),
'comment_params' => $parameterExtractor->extractParameters($part->getComment())
]
);
}
@ -140,11 +143,6 @@ class PartController extends AbstractController
/**
* @Route("/{id}/edit", name="part_edit")
*
* @param Part $part
* @param Request $request
* @param EntityManagerInterface $em
* @param TranslatorInterface $translator
* @param AttachmentSubmitHandler $attachmentSubmitHandler
* @return Response
*/
public function edit(Part $part, Request $request, EntityManagerInterface $em, TranslatorInterface $translator,
@ -197,8 +195,6 @@ class PartController extends AbstractController
/**
* @Route("/{id}/delete", name="part_delete", methods={"DELETE"})
*
* @param Request $request
* @param Part $part
* @return RedirectResponse
*/
public function delete(Request $request, Part $part): RedirectResponse
@ -226,17 +222,12 @@ class PartController extends AbstractController
* @Route("/new", name="part_new")
* @Route("/{id}/clone", name="part_clone")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param TranslatorInterface $translator
* @param AttachmentManager $attachmentHelper
* @param AttachmentSubmitHandler $attachmentSubmitHandler
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, TranslatorInterface $translator,
AttachmentManager $attachmentHelper, AttachmentSubmitHandler $attachmentSubmitHandler, ?Part $part = null): Response
{
if($part === null) {
if (null === $part) {
$new_part = new Part();
} else {
$new_part = clone $part;
@ -247,7 +238,7 @@ class PartController extends AbstractController
$cid = $request->get('cid', 1);
$category = $em->find(Category::class, $cid);
if (null !== $category && $new_part->getCategory() === null) {
if (null !== $category && null === $new_part->getCategory()) {
$new_part->setCategory($category);
}

View file

@ -60,9 +60,6 @@ class PartListsController extends AbstractController
/**
* @Route("/category/{id}/parts", name="part_list_category")
*
* @param Category $category
* @param Request $request
* @param DataTableFactory $dataTable
* @return JsonResponse|Response
*/
public function showCategory(Category $category, Request $request, DataTableFactory $dataTable)
@ -83,9 +80,6 @@ class PartListsController extends AbstractController
/**
* @Route("/footprint/{id}/parts", name="part_list_footprint")
*
* @param Footprint $footprint
* @param Request $request
* @param DataTableFactory $dataTable
* @return JsonResponse|Response
*/
public function showFootprint(Footprint $footprint, Request $request, DataTableFactory $dataTable)
@ -106,9 +100,6 @@ class PartListsController extends AbstractController
/**
* @Route("/manufacturer/{id}/parts", name="part_list_manufacturer")
*
* @param Manufacturer $manufacturer
* @param Request $request
* @param DataTableFactory $dataTable
* @return JsonResponse|Response
*/
public function showManufacturer(Manufacturer $manufacturer, Request $request, DataTableFactory $dataTable)
@ -129,9 +120,6 @@ class PartListsController extends AbstractController
/**
* @Route("/store_location/{id}/parts", name="part_list_store_location")
*
* @param Storelocation $storelocation
* @param Request $request
* @param DataTableFactory $dataTable
* @return JsonResponse|Response
*/
public function showStorelocation(Storelocation $storelocation, Request $request, DataTableFactory $dataTable)
@ -152,9 +140,6 @@ class PartListsController extends AbstractController
/**
* @Route("/supplier/{id}/parts", name="part_list_supplier")
*
* @param Supplier $supplier
* @param Request $request
* @param DataTableFactory $dataTable
* @return JsonResponse|Response
*/
public function showSupplier(Supplier $supplier, Request $request, DataTableFactory $dataTable)
@ -175,9 +160,6 @@ class PartListsController extends AbstractController
/**
* @Route("/parts/by_tag/{tag}", name="part_list_tags")
*
* @param string $tag
* @param Request $request
* @param DataTableFactory $dataTable
* @return JsonResponse|Response
*/
public function showTag(string $tag, Request $request, DataTableFactory $dataTable)
@ -197,8 +179,7 @@ class PartListsController extends AbstractController
/**
* @Route("/parts/search", name="parts_search")
* @param Request $request
* @param DataTableFactory $dataTable
*
* @return JsonResponse|Response
*/
public function showSearch(Request $request, DataTableFactory $dataTable)
@ -218,9 +199,8 @@ class PartListsController extends AbstractController
'regex' => $request->query->getBoolean('regex'),
];
$table = $dataTable->createFromType(PartsDataTable::class, [
'search' => $search, 'search_options' => $search_options
'search' => $search, 'search_options' => $search_options,
])
->handleRequest($request);
@ -237,8 +217,6 @@ class PartListsController extends AbstractController
/**
* @Route("/parts", name="parts_show_all")
*
* @param Request $request
* @param DataTableFactory $dataTable
* @return JsonResponse|Response
*/
public function showAll(Request $request, DataTableFactory $dataTable)

View file

@ -70,7 +70,6 @@ class RedirectController extends AbstractController
* This function is called whenever a route was not matching the localized routes.
* The purpose is to redirect the user to the localized version of the page.
*
* @param Request $request
* @return RedirectResponse
*/
public function addLocalePart(Request $request): RedirectResponse

View file

@ -71,7 +71,7 @@ class SecurityController extends AbstractController
/**
* @Route("/login", name="login", methods={"GET", "POST"})
* @param AuthenticationUtils $authenticationUtils
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function login(AuthenticationUtils $authenticationUtils): \Symfony\Component\HttpFoundation\Response
@ -90,8 +90,7 @@ class SecurityController extends AbstractController
/**
* @Route("/pw_reset/request", name="pw_reset_request")
* @param PasswordResetManager $passwordReset
* @param Request $request
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
*/
public function requestPwReset(PasswordResetManager $passwordReset, Request $request)
@ -135,10 +134,7 @@ class SecurityController extends AbstractController
/**
* @Route("/pw_reset/new_pw/{user}/{token}", name="pw_reset_new_pw")
* @param PasswordResetManager $passwordReset
* @param Request $request
* @param string|null $user
* @param string|null $token
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
*/
public function pwResetNewPw(PasswordResetManager $passwordReset, Request $request, ?string $user = null, ?string $token = null)

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -20,7 +23,6 @@
namespace App\Controller;
use App\Services\StatisticsHelper;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
@ -30,6 +32,7 @@ class StatisticsController extends AbstractController
{
/**
* @Route("/statistics", name="statistics_view")
*
* @return Response
*/
public function showStatistics(StatisticsHelper $helper): Response
@ -40,4 +43,4 @@ class StatisticsController extends AbstractController
'helper' => $helper,
]);
}
}
}

View file

@ -70,7 +70,7 @@ class TreeController extends AbstractController
/**
* @Route("/tools", name="tree_tools")
* @param ToolsTreeBuilder $builder
*
* @return JsonResponse
*/
public function tools(ToolsTreeBuilder $builder): JsonResponse
@ -83,7 +83,7 @@ class TreeController extends AbstractController
/**
* @Route("/category/{id}", name="tree_category")
* @Route("/categories")
* @param Category|null $category
*
* @return JsonResponse
*/
public function categoryTree(?Category $category = null): JsonResponse
@ -96,7 +96,7 @@ class TreeController extends AbstractController
/**
* @Route("/footprint/{id}", name="tree_footprint")
* @Route("/footprints")
* @param Footprint|null $footprint
*
* @return JsonResponse
*/
public function footprintTree(?Footprint $footprint = null): JsonResponse
@ -109,7 +109,7 @@ class TreeController extends AbstractController
/**
* @Route("/location/{id}", name="tree_location")
* @Route("/locations")
* @param Storelocation|null $location
*
* @return JsonResponse
*/
public function locationTree(?Storelocation $location = null): JsonResponse
@ -122,7 +122,7 @@ class TreeController extends AbstractController
/**
* @Route("/manufacturer/{id}", name="tree_manufacturer")
* @Route("/manufacturers")
* @param Manufacturer|null $manufacturer
*
* @return JsonResponse
*/
public function manufacturerTree(?Manufacturer $manufacturer = null): JsonResponse
@ -135,7 +135,7 @@ class TreeController extends AbstractController
/**
* @Route("/supplier/{id}", name="tree_supplier")
* @Route("/suppliers")
* @param Supplier|null $supplier
*
* @return JsonResponse
*/
public function supplierTree(?Supplier $supplier = null): JsonResponse
@ -148,7 +148,7 @@ class TreeController extends AbstractController
/**
* @Route("/device/{id}", name="tree_device")
* @Route("/devices")
* @param Device|null $device
*
* @return JsonResponse
*/
public function deviceTree(?Device $device = null): JsonResponse

View file

@ -61,9 +61,7 @@ class TypeaheadController extends AbstractController
{
/**
* @Route("/builtInResources/search/{query}", name="typeahead_builtInRessources", requirements={"query"= ".+"})
* @param Request $request
* @param string $query
* @param BuiltinAttachmentsFinder $finder
*
* @return JsonResponse
*/
public function builtInResources(Request $request, string $query, BuiltinAttachmentsFinder $finder)
@ -84,8 +82,7 @@ class TypeaheadController extends AbstractController
/**
* @Route("/tags/search/{query}", name="typeahead_tags", requirements={"query"= ".+"})
* @param string $query
* @param TagFinder $finder
*
* @return JsonResponse
*/
public function tags(string $query, TagFinder $finder)

View file

@ -43,6 +43,7 @@ declare(strict_types=1);
namespace App\Controller;
use App\Entity\Attachments\UserAttachment;
use App\Entity\Parameters\PartParameter;
use App\Entity\UserSystem\User;
use App\Form\Permissions\PermissionsType;
use App\Form\UserAdminForm;
@ -67,14 +68,15 @@ class UserController extends AdminPages\BaseAdminController
protected $form_class = UserAdminForm::class;
protected $route_base = 'user';
protected $attachment_class = UserAttachment::class;
//Just define a value here to prevent error. It is not used.
protected $parameter_class = "not used";
/**
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="user_edit")
* @Route("/{id}/", requirements={"id"="\d+"})
* @param User $entity
* @param Request $request
* @param EntityManagerInterface $em
*
* @return Response
*
* @throws \Exception
*/
public function edit(User $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
@ -109,9 +111,6 @@ class UserController extends AdminPages\BaseAdminController
* @Route("/new", name="user_new")
* @Route("/")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param EntityImporter $importer
* @return Response
*/
public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response
@ -121,9 +120,7 @@ class UserController extends AdminPages\BaseAdminController
/**
* @Route("/{id}", name="user_delete", methods={"DELETE"}, requirements={"id"="\d+"})
* @param Request $request
* @param User $entity
* @param StructuralElementRecursionHelper $recursionHelper
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function delete(Request $request, User $entity, StructuralElementRecursionHelper $recursionHelper)
@ -138,9 +135,6 @@ class UserController extends AdminPages\BaseAdminController
/**
* @Route("/export", name="user_export_all")
*
* @param EntityManagerInterface $em
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
@ -151,10 +145,6 @@ class UserController extends AdminPages\BaseAdminController
/**
* @Route("/{id}/export", name="user_export")
*
* @param User $entity
*
* @param EntityExporter $exporter
* @param Request $request
* @return Response
*/
public function exportEntity(User $entity, EntityExporter $exporter, Request $request): Response
@ -165,8 +155,7 @@ class UserController extends AdminPages\BaseAdminController
/**
* @Route("/info", name="user_info_self")
* @Route("/{id}/info", name="user_info")
* @param User|null $user
* @param Packages $packages
*
* @return Response
*/
public function userInfo(?User $user, Packages $packages): Response
@ -174,7 +163,7 @@ class UserController extends AdminPages\BaseAdminController
//If no user id was passed, then we show info about the current user
if (null === $user) {
$tmp = $this->getUser();
if(!$tmp instanceof User) {
if (! $tmp instanceof User) {
throw new InvalidArgumentException('Userinfo only works for database users!');
}
$user = $tmp;

View file

@ -102,9 +102,6 @@ class UserSettingsController extends AbstractController
/**
* @Route("/u2f_delete", name="u2f_delete", methods={"DELETE"})
*
* @param Request $request
* @param EntityManagerInterface $entityManager
* @param BackupCodeManager $backupCodeManager
* @return RedirectResponse
*/
public function removeU2FToken(Request $request, EntityManagerInterface $entityManager, BackupCodeManager $backupCodeManager): RedirectResponse
@ -155,8 +152,7 @@ class UserSettingsController extends AbstractController
/**
* @Route("/invalidate_trustedDevices", name="tfa_trustedDevices_invalidate", methods={"DELETE"})
* @param Request $request
* @param EntityManagerInterface $entityManager
*
* @return RuntimeException|RedirectResponse
*/
public function resetTrustedDevices(Request $request, EntityManagerInterface $entityManager)
@ -187,11 +183,7 @@ class UserSettingsController extends AbstractController
/**
* @Route("/settings", name="user_settings")
* @param Request $request
* @param EntityManagerInterface $em
* @param UserPasswordEncoderInterface $passwordEncoder
* @param GoogleAuthenticator $googleAuthenticator
* @param BackupCodeManager $backupCodeManager
*
* @return RedirectResponse|\Symfony\Component\HttpFoundation\Response
*/
public function userSettings(Request $request, EntityManagerInterface $em, UserPasswordEncoderInterface $passwordEncoder, GoogleAuthenticator $googleAuthenticator, BackupCodeManager $backupCodeManager)
@ -266,9 +258,9 @@ class UserSettingsController extends AbstractController
],
],
'constraints' => [new Length([
'min' => 6,
'max' => 128,
])],
'min' => 6,
'max' => 128,
])],
])
->add('submit', SubmitType::class, ['label' => 'save'])
->getForm();
@ -297,7 +289,7 @@ class UserSettingsController extends AbstractController
}
$google_form->handleRequest($request);
if ( ! $this->demo_mode && $google_form->isSubmitted() && $google_form->isValid()) {
if (! $this->demo_mode && $google_form->isSubmitted() && $google_form->isValid()) {
if (! $google_enabled) {
//Save 2FA settings (save secrets)
$user->setGoogleAuthenticatorSecret($google_form->get('googleAuthenticatorSecret')->getData());

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -20,7 +23,6 @@
namespace App\DataFixtures;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Attachments\PartAttachment;
use App\Entity\Parts\Category;
@ -38,7 +40,6 @@ use Doctrine\Persistence\ObjectManager;
class PartFixtures extends Fixture
{
protected $em;
public function __construct(EntityManagerInterface $entityManager)
@ -46,10 +47,7 @@ class PartFixtures extends Fixture
$this->em = $entityManager;
}
/**
* @inheritDoc
*/
public function load(ObjectManager $manager)
public function load(ObjectManager $manager): void
{
$table_name = $this->em->getClassMetadata(Part::class)->getTableName();
$this->em->getConnection()->exec("ALTER TABLE `${table_name}` AUTO_INCREMENT = 1;");
@ -91,16 +89,16 @@ class PartFixtures extends Fixture
$orderdetail = new Orderdetail();
$orderdetail->setSupplier($manager->find(Supplier::class, 1));
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(1.0)->setPrice(10));
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(10.0)->setPrice(15));
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(1.0)->setPrice("10.0"));
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(10.0)->setPrice("15.0"));
$part->addOrderdetail($orderdetail);
$orderdetail = new Orderdetail();
$orderdetail->setSupplierpartnr('BC 547');
$orderdetail->setObsolete(true);
$orderdetail->setSupplier($manager->find(Supplier::class, 1));
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(1.0)->setPrice(10));
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(10.0)->setPrice(15));
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(1.0)->setPrice("10.0"));
$orderdetail->addPricedetail((new Pricedetail())->setPriceRelatedQuantity(10.0)->setPrice("15.1"));
$part->addOrderdetail($orderdetail);
$attachment = new PartAttachment();
@ -119,4 +117,4 @@ class PartFixtures extends Fixture
$manager->persist($part);
$manager->flush();
}
}
}

View file

@ -47,7 +47,6 @@ use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Omines\DataTablesBundle\Adapter\AdapterQuery;
use Omines\DataTablesBundle\Adapter\Doctrine\Event\ORMAdapterQueryEvent;
use Omines\DataTablesBundle\Adapter\Doctrine\ORMAdapterEvents;
use Omines\DataTablesBundle\Column\AbstractColumn;
use Symfony\Component\OptionsResolver\OptionsResolver;

View file

@ -90,7 +90,7 @@ class EntityColumn extends AbstractColumn
/** @var AbstractDBElement|null $entity */
$entity = $this->accessor->getValue($context, $options['property']);
if ($entity !== null) {
if (null !== $entity) {
if (null !== $entity->getID()) {
return sprintf(
'<a href="%s">%s</a>',
@ -101,6 +101,7 @@ class EntityColumn extends AbstractColumn
return sprintf('<i>%s</i>', $value);
}
return '';
};
});

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -20,16 +23,11 @@
namespace App\DataTables\Column;
use Omines\DataTablesBundle\Column\AbstractColumn;
use Symfony\Component\OptionsResolver\OptionsResolver;
class IconLinkColumn extends AbstractColumn
{
/**
* @inheritDoc
*/
public function normalize($value)
{
return $value;
@ -39,11 +37,11 @@ class IconLinkColumn extends AbstractColumn
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'icon' => 'fas fa-fw fa-edit',
'title' => null,
'href' => null,
'disabled' => false,
]);
'icon' => 'fas fa-fw fa-edit',
'title' => null,
'href' => null,
'disabled' => false,
]);
$resolver->setAllowedTypes('title', ['null', 'string', 'callable']);
$resolver->setAllowedTypes('icon', ['null', 'string', 'callable']);
@ -60,7 +58,7 @@ class IconLinkColumn extends AbstractColumn
$title = $this->getTitle($value, $context);
$disabled = $this->getDisabled($value, $context);
if ($href !== null) {
if (null !== $href) {
return sprintf(
'<a class="btn btn-primary btn-sm %s" href="%s" title="%s"><i class="%s"></i></a>',
$disabled ? 'disabled' : '',
@ -70,7 +68,7 @@ class IconLinkColumn extends AbstractColumn
);
}
return "";
return '';
}
protected function getDisabled($value, $context): bool
@ -82,6 +80,7 @@ class IconLinkColumn extends AbstractColumn
if (is_callable($provider)) {
return call_user_func($provider, $value, $context);
}
return false;
}
@ -123,4 +122,4 @@ class IconLinkColumn extends AbstractColumn
return null;
}
}
}

View file

@ -42,9 +42,15 @@ declare(strict_types=1);
namespace App\DataTables\Column;
use App\Entity\Attachments\Attachment;
use App\Entity\Base\AbstractDBElement;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Contracts\NamedElementInterface;
use App\Entity\LogSystem\AbstractLogEntry;
use App\Entity\Parameters\AbstractParameter;
use App\Entity\Parts\PartLot;
use App\Entity\PriceInformations\Orderdetail;
use App\Entity\PriceInformations\Pricedetail;
use App\Exceptions\EntityNotSupportedException;
use App\Services\ElementTypeNameGenerator;
use App\Services\EntityURLGenerator;
@ -80,6 +86,8 @@ class LogEntryTargetColumn extends AbstractColumn
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefault('show_associated', true);
return $this;
}
@ -88,31 +96,27 @@ class LogEntryTargetColumn extends AbstractColumn
/** @var AbstractLogEntry $context */
$target = $this->entryRepository->getTargetElement($context);
$tmp = '';
//The element is existing
if ($target instanceof AbstractNamedDBElement) {
if ($target instanceof NamedElementInterface && !empty($target->getName())) {
try {
return sprintf(
$tmp = sprintf(
'<a href="%s">%s</a>',
$this->entityURLGenerator->infoURL($target),
$this->elementTypeNameGenerator->getTypeNameCombination($target, true)
);
} catch (EntityNotSupportedException $exception) {
return $this->elementTypeNameGenerator->getTypeNameCombination($target, true);
$tmp = $this->elementTypeNameGenerator->getTypeNameCombination($target, true);
}
}
//Target does not have a name
if ($target instanceof AbstractDBElement) {
return sprintf(
} elseif ($target instanceof AbstractDBElement) { //Target does not have a name
$tmp = sprintf(
'<i>%s</i>: %s',
$this->elementTypeNameGenerator->getLocalizedTypeLabel($target),
$target->getID()
);
}
//Element was deleted
if (null === $target && $context->hasTarget()) {
return sprintf(
} elseif (null === $target && $context->hasTarget()) { //Element was deleted
$tmp = sprintf(
'<i>%s</i>: %s [%s]',
$this->elementTypeNameGenerator->getLocalizedTypeLabel($context->getTargetClass()),
$context->getTargetID(),
@ -120,7 +124,34 @@ class LogEntryTargetColumn extends AbstractColumn
);
}
//Add a hint to the associated element if possible
if (null !== $target && $this->options['show_associated']) {
if ($target instanceof Attachment && $target->getElement() !== null) {
$on = $target->getElement();
} elseif ($target instanceof AbstractParameter && $target->getElement() !== null) {
$on = $target->getElement();
} elseif ($target instanceof PartLot && $target->getPart() !== null) {
$on = $target->getPart();
} elseif ($target instanceof Orderdetail && $target->getPart() !== null) {
$on = $target->getPart();
} elseif ($target instanceof Pricedetail && $target->getOrderdetail() !== null && $target->getOrderdetail()->getPart() !== null) {
$on = $target->getOrderdetail()->getPart();
}
if (isset($on) && is_object($on)) {
try {
$tmp .= sprintf(
' (<a href="%s">%s</a>)',
$this->entityURLGenerator->infoURL($on),
$this->elementTypeNameGenerator->getTypeNameCombination($on, true)
);
} catch (EntityNotSupportedException $exception) {
$tmp .= ' (' . $this->elementTypeNameGenerator->getTypeNameCombination($target, true) .')';
}
}
}
//Log is not associated with an element
return '';
return $tmp;
}
}

View file

@ -112,6 +112,7 @@ class PartAttachmentsColumn extends AbstractColumn
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
return $this;
}
}

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -20,8 +23,6 @@
namespace App\DataTables\Column;
use App\Entity\LogSystem\AbstractLogEntry;
use App\Entity\LogSystem\CollectionElementDeleted;
use App\Entity\LogSystem\ElementCreatedLogEntry;
use App\Entity\LogSystem\ElementDeletedLogEntry;
@ -41,9 +42,6 @@ class RevertLogColumn extends AbstractColumn
$this->security = $security;
}
/**
* @inheritDoc
*/
public function normalize($value)
{
return $value;
@ -68,7 +66,7 @@ class RevertLogColumn extends AbstractColumn
return '';
}
$disabled = !$this->security->isGranted('revert_element', $context->getTargetClass());
$disabled = ! $this->security->isGranted('revert_element', $context->getTargetClass());
$tmp = '<div class="btn-group btn-group-sm">';
$tmp .= sprintf(
@ -90,4 +88,4 @@ class RevertLogColumn extends AbstractColumn
return $tmp;
}
}
}

View file

@ -70,7 +70,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Flex\Options;
class LogDataTable implements DataTableTypeInterface
{
@ -92,12 +91,12 @@ class LogDataTable implements DataTableTypeInterface
$this->security = $security;
}
public function configureOptions(OptionsResolver $optionsResolver)
public function configureOptions(OptionsResolver $optionsResolver): void
{
$optionsResolver->setDefaults([
'mode' => 'system_log',
'filter_elements' => [],
]);
'mode' => 'system_log',
'filter_elements' => [],
]);
$optionsResolver->setAllowedValues('mode', ['system_log', 'element_history', 'last_activity']);
}
@ -108,7 +107,6 @@ class LogDataTable implements DataTableTypeInterface
$this->configureOptions($resolver);
$options = $resolver->resolve($options);
$dataTable->add('symbol', TextColumn::class, [
'label' => '',
'render' => function ($value, AbstractLogEntry $context) {
@ -179,7 +177,7 @@ class LogDataTable implements DataTableTypeInterface
$dataTable->add('level', TextColumn::class, [
'label' => $this->translator->trans('log.level'),
'visible' => $options['mode'] === 'system_log',
'visible' => 'system_log' === $options['mode'],
'propertyPath' => 'levelString',
'render' => function (string $value, AbstractLogEntry $context) {
return $value;
@ -214,13 +212,14 @@ class LogDataTable implements DataTableTypeInterface
$dataTable->add('target', LogEntryTargetColumn::class, [
'label' => $this->translator->trans('log.target'),
'show_associated' => $options['mode'] !== 'element_history',
]);
$dataTable->add('extra', LogEntryExtraColumn::class, [
'label' => $this->translator->trans('log.extra'),
]);
$dataTable->add('timeTravel', IconLinkColumn::class,[
$dataTable->add('timeTravel', IconLinkColumn::class, [
'label' => '',
'icon' => 'fas fa-fw fa-eye',
'href' => function ($value, AbstractLogEntry $context) {
@ -231,26 +230,25 @@ class LogDataTable implements DataTableTypeInterface
) {
try {
$target = $this->logRepo->getTargetElement($context);
if($target !== null) {
$str = $this->entityURLGenerator->timeTravelURL($target, $context->getTimestamp());
return $str;
if (null !== $target) {
return $this->entityURLGenerator->timeTravelURL($target, $context->getTimestamp());
}
} catch (EntityNotSupportedException $exception) {
return null;
}
}
return null;
},
'disabled' => function ($value, AbstractLogEntry $context) {
return
!$this->security->isGranted('@tools.timetravel')
|| !$this->security->isGranted('show_history', $context->getTargetClass());
}
! $this->security->isGranted('@tools.timetravel')
|| ! $this->security->isGranted('show_history', $context->getTargetClass());
},
]);
$dataTable->add('actionRevert', RevertLogColumn::class, [
'label' => ''
'label' => '',
]);
$dataTable->addOrderBy('timestamp', DataTable::SORT_DESCENDING);
@ -270,12 +268,12 @@ class LogDataTable implements DataTableTypeInterface
->from(AbstractLogEntry::class, 'log')
->leftJoin('log.user', 'user');
if ($options['mode'] === 'last_activity') {
$builder->where('log INSTANCE OF ' . ElementCreatedLogEntry::class)
->orWhere('log INSTANCE OF ' . ElementDeletedLogEntry::class)
->orWhere('log INSTANCE OF ' . ElementEditedLogEntry::class)
->orWhere('log INSTANCE OF ' . CollectionElementDeleted::class)
->andWhere('log.target_type NOT IN (:disallowed)');;
if ('last_activity' === $options['mode']) {
$builder->where('log INSTANCE OF '.ElementCreatedLogEntry::class)
->orWhere('log INSTANCE OF '.ElementDeletedLogEntry::class)
->orWhere('log INSTANCE OF '.ElementEditedLogEntry::class)
->orWhere('log INSTANCE OF '.CollectionElementDeleted::class)
->andWhere('log.target_type NOT IN (:disallowed)');
$builder->setParameter('disallowed', [
AbstractLogEntry::targetTypeClassToID(User::class),
@ -283,13 +281,13 @@ class LogDataTable implements DataTableTypeInterface
]);
}
if (!empty($options['filter_elements'])) {
if (! empty($options['filter_elements'])) {
foreach ($options['filter_elements'] as $element) {
/** @var AbstractDBElement $element */
$target_type = AbstractLogEntry::targetTypeClassToID(get_class($element));
$target_id = $element->getID();
$builder->orWhere("log.target_type = $target_type AND log.target_id = $target_id");
$builder->orWhere("log.target_type = ${target_type} AND log.target_id = ${target_id}");
}
}
}

View file

@ -93,17 +93,17 @@ final class PartsDataTable implements DataTableTypeInterface
$this->attachmentURLGenerator = $attachmentURLGenerator;
}
public function configureOptions(OptionsResolver $optionsResolver)
public function configureOptions(OptionsResolver $optionsResolver): void
{
$optionsResolver->setDefaults([
'category' => null,
'footprint' => null,
'manufacturer' => null,
'storelocation' => null,
'supplier' => null,
'tag' => null,
'search' => null,
]);
'category' => null,
'footprint' => null,
'manufacturer' => null,
'storelocation' => null,
'supplier' => null,
'tag' => null,
'search' => null,
]);
$optionsResolver->setAllowedTypes('category', ['null', Category::class]);
$optionsResolver->setAllowedTypes('footprint', ['null', Footprint::class]);
@ -113,20 +113,20 @@ final class PartsDataTable implements DataTableTypeInterface
$optionsResolver->setAllowedTypes('search', ['null', 'string']);
//Configure search options
$optionsResolver->setDefault('search_options', function (OptionsResolver $resolver) {
$optionsResolver->setDefault('search_options', function (OptionsResolver $resolver): void {
$resolver->setDefaults([
'name' => true,
'category' => true,
'description' => true,
'store_location' => true,
'comment' => true,
'ordernr' => true,
'supplier' => false,
'manufacturer' => false,
'footprint' => false,
'tags' => false,
'regex' => false,
]);
'name' => true,
'category' => true,
'description' => true,
'store_location' => true,
'comment' => true,
'ordernr' => true,
'supplier' => false,
'manufacturer' => false,
'footprint' => false,
'tags' => false,
'regex' => false,
]);
$resolver->setAllowedTypes('name', 'bool');
$resolver->setAllowedTypes('category', 'bool');
$resolver->setAllowedTypes('description', 'bool');
@ -375,8 +375,8 @@ final class PartsDataTable implements DataTableTypeInterface
$builder->andWhere('part.tags LIKE :tag')->setParameter('tag', '%'.$options['tag'].'%');
}
if (!empty($options['search'])) {
if (!$options['search_options']['regex']) {
if (! empty($options['search'])) {
if (! $options['search_options']['regex']) {
//Dont show results, if no things are selected
$builder->andWhere('0=1');
$defined = false;
@ -463,7 +463,6 @@ final class PartsDataTable implements DataTableTypeInterface
if ($defined) {
$builder->setParameter('search', $options['search']);
}
}
}
}

View file

@ -365,7 +365,6 @@ abstract class Attachment extends AbstractNamedDBElement
/**
* Sets the element that is associated with this attachment.
*
* @param AttachmentContainingDBElement $element
* @return $this
*/
public function setElement(AttachmentContainingDBElement $element): self
@ -394,7 +393,6 @@ abstract class Attachment extends AbstractNamedDBElement
}
/**
* @param AttachmentType $attachement_type
* @return $this
*/
public function setAttachmentType(AttachmentType $attachement_type): self
@ -408,7 +406,6 @@ abstract class Attachment extends AbstractNamedDBElement
* Sets the url associated with this attachment.
* If the url is empty nothing is changed, to not override the file path.
*
* @param string|null $url
* @return Attachment
*/
public function setURL(?string $url): self

View file

@ -22,8 +22,8 @@ declare(strict_types=1);
namespace App\Entity\Attachments;
use App\Entity\Base\MasterAttachmentTrait;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\MasterAttachmentTrait;
use App\Entity\Contracts\HasAttachmentsInterface;
use App\Entity\Contracts\HasMasterAttachmentInterface;
use Doctrine\Common\Collections\ArrayCollection;
@ -39,8 +39,8 @@ abstract class AttachmentContainingDBElement extends AbstractNamedDBElement impl
/**
* @var Attachment[]|Collection
* //TODO
* //@ORM\OneToMany(targetEntity="Attachment", mappedBy="element")
* //TODO
* //@ORM\OneToMany(targetEntity="Attachment", mappedBy="element")
*
* Mapping is done in sub classes like part
*/
@ -51,6 +51,25 @@ abstract class AttachmentContainingDBElement extends AbstractNamedDBElement impl
$this->attachments = new ArrayCollection();
}
public function __clone()
{
if ($this->id) {
$attachments = $this->attachments;
$this->attachments = new ArrayCollection();
//Set master attachment is needed
foreach ($attachments as $attachment) {
$clone = clone $attachment;
if ($attachment === $this->master_picture_attachment) {
$this->setMasterPictureAttachment($clone);
}
$this->addAttachment($clone);
}
}
//Parent has to be last call, as it resets the ID
parent::__clone();
}
/********************************************************************************
*
* Getters
@ -86,7 +105,6 @@ abstract class AttachmentContainingDBElement extends AbstractNamedDBElement impl
/**
* Removes the given attachment from this element.
*
* @param Attachment $attachment
* @return $this
*/
public function removeAttachment(Attachment $attachment): self
@ -95,23 +113,4 @@ abstract class AttachmentContainingDBElement extends AbstractNamedDBElement impl
return $this;
}
public function __clone()
{
if ($this->id) {
$attachments = $this->attachments;
$this->attachments = new ArrayCollection();
//Set master attachment is needed
foreach ($attachments as $attachment) {
$clone = clone $attachment;
if ($attachment === $this->master_picture_attachment) {
$this->setMasterPictureAttachment($clone);
}
$this->addAttachment($clone);
}
}
//Parent has to be last call, as it resets the ID
parent::__clone();
}
}

View file

@ -23,10 +23,12 @@ declare(strict_types=1);
namespace App\Entity\Attachments;
use App\Entity\Base\AbstractStructuralDBElement;
use App\Entity\Parameters\AttachmentTypeParameter;
use App\Validator\Constraints\ValidFileFilter;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class AttachmentType.
@ -56,9 +58,17 @@ class AttachmentType extends AbstractStructuralDBElement
/**
* @var Collection|AttachmentTypeAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\AttachmentTypeAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid()
*/
protected $attachments;
/** @var AttachmentTypeParameter[]
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\AttachmentTypeParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
* @Assert\Valid()
*/
protected $parameters;
/**
* @var Collection|Attachment[]
* @ORM\OneToMany(targetEntity="Attachment", mappedBy="attachment_type")

View file

@ -173,7 +173,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
/**
* Set the addres.
*
* @param string $new_address the new address (with "\n" as line break)
* @param string $new_address the new address (with "\n" as line break)
*
* @return $this
*/
@ -188,6 +188,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
* Set the phone number.
*
* @param string $new_phone_number the new phone number
*
* @return $this
*/
public function setPhoneNumber(string $new_phone_number): self
@ -201,6 +202,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
* Set the fax number.
*
* @param string $new_fax_number the new fax number
*
* @return $this
*/
public function setFaxNumber(string $new_fax_number): self
@ -214,6 +216,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
* Set the e-mail address.
*
* @param string $new_email_address the new e-mail address
*
* @return $this
*/
public function setEmailAddress(string $new_email_address): self
@ -227,6 +230,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
* Set the website.
*
* @param string $new_website the new website
*
* @return $this
*/
public function setWebsite(string $new_website): self
@ -240,6 +244,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
* Set the link to the website of an article.
*
* @param string $new_url the new URL with the placeholder %PARTNUMBER% for the part number
*
* @return $this
*/
public function setAutoProductUrl(string $new_url): self

View file

@ -57,6 +57,15 @@ abstract class AbstractNamedDBElement extends AbstractDBElement implements Named
return $this->getName();
}
public function __clone()
{
if ($this->id) {
//We create a new object, so give it a new creation date
$this->addedDate = null;
}
parent::__clone(); // TODO: Change the autogenerated stub
}
/********************************************************************************
*
* Getters
@ -89,15 +98,7 @@ abstract class AbstractNamedDBElement extends AbstractDBElement implements Named
public function setName(string $new_name): self
{
$this->name = $new_name;
return $this;
}
public function __clone()
{
if ($this->id) {
//We create a new object, so give it a new creation date
$this->addedDate = null;
}
parent::__clone(); // TODO: Change the autogenerated stub
}
}

View file

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace App\Entity\Base;
use App\Entity\Attachments\AttachmentContainingDBElement;
use App\Entity\Parameters\ParametersTrait;
use App\Validator\Constraints\NoneOfItsChildren;
use function count;
use Doctrine\Common\Collections\ArrayCollection;
@ -50,6 +51,8 @@ use Symfony\Component\Serializer\Annotation\Groups;
*/
abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
{
use ParametersTrait;
public const ID_ROOT_ELEMENT = 0;
/**
@ -101,6 +104,7 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
{
parent::__construct();
$this->children = new ArrayCollection();
$this->parameters = new ArrayCollection();
}
/******************************************************************************
@ -111,7 +115,7 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
* Check if this element is a child of another element (recursive).
*
* @param AbstractStructuralDBElement $another_element the object to compare
* IMPORTANT: both objects to compare must be from the same class (for example two "Device" objects)!
* IMPORTANT: both objects to compare must be from the same class (for example two "Device" objects)!
*
* @return bool True, if this element is child of $another_element.
*
@ -312,13 +316,14 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
}
/**
* @param static[]|Collection $elements
* @param static[]|Collection $elements
*
* @return $this
*/
public function setChildren($elements): self
{
if (!is_array($elements) && !$elements instanceof Collection) {
throw new InvalidArgumentException('$elements must be an array or Collection!');
if (! is_array($elements) && ! $elements instanceof Collection) {
throw new InvalidArgumentException('$elements must be an array or Collection!');
}
$this->children = $elements;
@ -327,7 +332,6 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
}
/**
* @param bool $not_selectable
* @return AbstractStructuralDBElement
*/
public function setNotSelectable(bool $not_selectable): self

View file

@ -72,7 +72,6 @@ trait MasterAttachmentTrait
/**
* Sets the new master picture for this part.
*
* @param Attachment|null $new_master_attachment
* @return $this
*/
public function setMasterPictureAttachment(?Attachment $new_master_attachment): self

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -20,10 +23,9 @@
namespace App\Entity\Contracts;
use Doctrine\Common\Collections\Collection;
interface HasAttachmentsInterface
{
public function getAttachments(): Collection;
}
}

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -20,7 +23,6 @@
namespace App\Entity\Contracts;
use App\Entity\Attachments\Attachment;
interface HasMasterAttachmentInterface
@ -32,4 +34,4 @@ interface HasMasterAttachmentInterface
* @return Attachment|null the master picture Attachment of this part (if there is one)
*/
public function getMasterPictureAttachment(): ?Attachment;
}
}

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -20,11 +23,11 @@
namespace App\Entity\Contracts;
interface LogWithCommentInterface
{
/**
* Checks if this log entry has a user provided comment.
*
* @return bool
*/
public function hasComment(): bool;
@ -32,14 +35,15 @@ interface LogWithCommentInterface
/**
* Gets the user provided comment associated with this log entry.
* Returns null if not comment was set.
*
* @return string|null
*/
public function getComment(): ?string;
/**
* Sets the user provided comment associated with this log entry.
* @param string|null $new_comment
*
* @return $this
*/
public function setComment(?string $new_comment): self;
}
}

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -20,27 +23,27 @@
namespace App\Entity\Contracts;
use App\Entity\LogSystem\AbstractLogEntry;
interface LogWithEventUndoInterface
{
/**
* Checks if this element undoes another event.
*
* @return bool
*/
public function isUndoEvent(): bool;
/**
* Returns the ID of the undone event or null if no event is undone.
*
* @return int|null
*/
public function getUndoEventID(): ?int;
/**
* Sets the event that is undone, and the undo mode.
* @param AbstractLogEntry $event
* @param string $mode
*
* @return $this
*/
public function setUndoneEvent(AbstractLogEntry $event, string $mode = 'undo'): self;
@ -49,7 +52,8 @@ interface LogWithEventUndoInterface
* Returns the mode how the event was undone:
* "undo" = Only a single event was applied to element
* "revert" = Element was reverted to the state it was to the timestamp of the log.
*
* @return string
*/
public function getUndoMode(): string;
}
}

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -20,7 +23,6 @@
namespace App\Entity\Contracts;
interface NamedElementInterface
{
/**
@ -29,4 +31,4 @@ interface NamedElementInterface
* @return string the name of this element
*/
public function getName(): string;
}
}

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -21,7 +24,6 @@
namespace App\Entity\Contracts;
use DateTime;
interface TimeStampableInterface
@ -41,4 +43,4 @@ interface TimeStampableInterface
* @return DateTime|null the creation time of the part
*/
public function getAddedDate(): ?DateTime;
}
}

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -21,11 +24,11 @@
namespace App\Entity\Contracts;
interface TimeTravelInterface
{
/**
* Checks if this entry has informations which data has changed.
*
* @return bool True if this entry has informations about the changed data.
*/
public function hasOldDataInformations(): bool;
@ -35,7 +38,8 @@ interface TimeTravelInterface
/**
* Returns the the timestamp associated with this change.
*
* @return \DateTime
*/
public function getTimestamp(): \DateTime;
}
}

View file

@ -52,6 +52,7 @@ namespace App\Entity\Devices;
use App\Entity\Attachments\DeviceAttachment;
use App\Entity\Base\AbstractPartsContainingDBElement;
use App\Entity\Parameters\DeviceParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use InvalidArgumentException;
@ -97,6 +98,12 @@ class Device extends AbstractPartsContainingDBElement
*/
protected $attachments;
/** @var DeviceParameter[]
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\DeviceParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
*/
protected $parameters;
/********************************************************************************
*
* Getters

View file

@ -47,6 +47,7 @@ use App\Entity\Attachments\AttachmentType;
use App\Entity\Base\AbstractDBElement;
use App\Entity\Devices\Device;
use App\Entity\Devices\DevicePart;
use App\Entity\Parameters\AbstractParameter;
use App\Entity\Parts\Category;
use App\Entity\Parts\Footprint;
use App\Entity\Parts\Manufacturer;
@ -114,6 +115,7 @@ abstract class AbstractLogEntry extends AbstractDBElement
protected const TARGET_TYPE_ORDERDETAIL = 15;
protected const TARGET_TYPE_PRICEDETAIL = 16;
protected const TARGET_TYPE_MEASUREMENTUNIT = 17;
protected const TARGET_TYPE_PARAMETER = 18;
/** @var array This const is used to convert the numeric level to a PSR-3 compatible log level */
protected const LEVEL_ID_TO_STRING = [
@ -145,6 +147,7 @@ abstract class AbstractLogEntry extends AbstractDBElement
self::TARGET_TYPE_ORDERDETAIL => Orderdetail::class,
self::TARGET_TYPE_PRICEDETAIL => Pricedetail::class,
self::TARGET_TYPE_MEASUREMENTUNIT => MeasurementUnit::class,
self::TARGET_TYPE_PARAMETER => AbstractParameter::class,
];
/** @var User The user which has caused this log entry
@ -203,7 +206,6 @@ abstract class AbstractLogEntry extends AbstractDBElement
/**
* Sets the user that caused the event.
*
* @param User $user
* @return $this
*/
public function setUser(User $user): self
@ -226,7 +228,6 @@ abstract class AbstractLogEntry extends AbstractDBElement
/**
* Sets the timestamp when the event happened.
*
* @param DateTime $timestamp
* @return $this
*/
public function setTimestamp(DateTime $timestamp): self
@ -255,7 +256,6 @@ abstract class AbstractLogEntry extends AbstractDBElement
/**
* Sets the new level of this log entry.
*
* @param int $level
* @return $this
*/
public function setLevel(int $level): self
@ -281,7 +281,6 @@ abstract class AbstractLogEntry extends AbstractDBElement
/**
* Sets the priority level of this log entry as PSR3 compatible string.
*
* @param string $level
* @return $this
*/
public function setLevelString(string $level): self
@ -370,12 +369,13 @@ abstract class AbstractLogEntry extends AbstractDBElement
/**
* Sets the target ID of the element associated with this element.
* @param int $target_id
*
* @return $this
*/
public function setTargetElementID(int $target_id): self
{
$this->target_id = $target_id;
return $this;
}

View file

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
@ -20,7 +23,6 @@
namespace App\Entity\LogSystem;
use App\Entity\Base\AbstractDBElement;
use App\Entity\Contracts\LogWithEventUndoInterface;
use App\Entity\Contracts\NamedElementInterface;
@ -52,6 +54,7 @@ class CollectionElementDeleted extends AbstractLogEntry implements LogWithEventU
/**
* Get the name of the collection (on target element) that was changed.
*
* @return string
*/
public function getCollectionName(): string
@ -62,6 +65,7 @@ class CollectionElementDeleted extends AbstractLogEntry implements LogWithEventU
/**
* Gets the name of the element that was deleted.
* Return null, if the element did not have a name.
*
* @return string|null
*/
public function getOldName(): ?string
@ -71,6 +75,7 @@ class CollectionElementDeleted extends AbstractLogEntry implements LogWithEventU
/**
* Returns the class of the deleted element.
*
* @return string
*/
public function getDeletedElementClass(): string
@ -80,6 +85,7 @@ class CollectionElementDeleted extends AbstractLogEntry implements LogWithEventU
/**
* Returns the ID of the deleted element.
*
* @return int
*/
public function getDeletedElementID(): int
@ -87,32 +93,23 @@ class CollectionElementDeleted extends AbstractLogEntry implements LogWithEventU
return $this->extra['i'];
}
/**
* @inheritDoc
*/
public function isUndoEvent(): bool
{
return isset($this->extra['u']);
}
/**
* @inheritDoc
*/
public function getUndoEventID(): ?int
{
return $this->extra['u'] ?? null;
}
/**
* @inheritDoc
*/
public function setUndoneEvent(AbstractLogEntry $event, string $mode = 'undo'): LogWithEventUndoInterface
{
$this->extra['u'] = $event->getID();
if ($mode === 'undo') {
if ('undo' === $mode) {
$this->extra['um'] = 1;
} elseif ($mode === 'revert') {
} elseif ('revert' === $mode) {
$this->extra['um'] = 2;
} else {
throw new \InvalidArgumentException('Passed invalid $mode!');
@ -121,16 +118,13 @@ class CollectionElementDeleted extends AbstractLogEntry implements LogWithEventU
return $this;
}
/**
* @inheritDoc
*/
public function getUndoMode(): string
{
$mode_int = $this->extra['um'] ?? 1;
if ($mode_int === 1) {
if (1 === $mode_int) {
return 'undo';
} else {
return 'revert';
}
return 'revert';
}
}
}

View file

@ -55,6 +55,7 @@ class ConfigChangedLogEntry extends AbstractLogEntry
public function __construct()
{
parent::__construct();
throw new LogEntryObsoleteException();
}
}

View file

@ -88,57 +88,40 @@ class ElementCreatedLogEntry extends AbstractLogEntry implements LogWithCommentI
return null !== $this->getCreationInstockValue();
}
/**
* @inheritDoc
*/
public function hasComment(): bool
{
return isset($this->extra['m']);
}
/**
* @inheritDoc
*/
public function getComment(): ?string
{
return $this->extra['m'] ?? null;
}
/**
* @inheritDoc
*/
public function setComment(?string $new_comment): LogWithCommentInterface
{
$this->extra['m'] = $new_comment;
return $this;
}
/**
* @inheritDoc
*/
public function isUndoEvent(): bool
{
return isset($this->extra['u']);
}
/**
* @inheritDoc
*/
public function getUndoEventID(): ?int
{
return $this->extra['u'] ?? null;
}
/**
* @inheritDoc
*/
public function setUndoneEvent(AbstractLogEntry $event, string $mode = 'undo'): LogWithEventUndoInterface
{
$this->extra['u'] = $event->getID();
if ($mode === 'undo') {
if ('undo' === $mode) {
$this->extra['um'] = 1;
} elseif ($mode === 'revert') {
} elseif ('revert' === $mode) {
$this->extra['um'] = 2;
} else {
throw new \InvalidArgumentException('Passed invalid $mode!');
@ -147,16 +130,13 @@ class ElementCreatedLogEntry extends AbstractLogEntry implements LogWithCommentI
return $this;
}
/**
* @inheritDoc
*/
public function getUndoMode(): string
{
$mode_int = $this->extra['um'] ?? 1;
if ($mode_int === 1) {
if (1 === $mode_int) {
return 'undo';
} else {
return 'revert';
}
return 'revert';
}
}

View file

@ -71,7 +71,6 @@ class ElementDeletedLogEntry extends AbstractLogEntry implements TimeTravelInter
}
/**
* @inheritDoc
* @return $this
*/
public function setTargetElement(?AbstractDBElement $element): AbstractLogEntry
@ -80,12 +79,14 @@ class ElementDeletedLogEntry extends AbstractLogEntry implements TimeTravelInter
if ($element instanceof NamedElementInterface) {
$this->setOldName($element->getName());
}
return $this;
}
public function setOldName(string $old_name): self
{
$this->extra['n'] = $old_name;
return $this;
}
@ -96,82 +97,60 @@ class ElementDeletedLogEntry extends AbstractLogEntry implements TimeTravelInter
/**
* Sets the old data for this entry.
* @param array $old_data
*
* @return $this
*/
public function setOldData(array $old_data): self
{
$this->extra['o'] = $old_data;
return $this;
}
/**
* @inheritDoc
*/
public function hasOldDataInformations(): bool
{
return !empty($this->extra['o']);
return ! empty($this->extra['o']);
}
/**
* @inheritDoc
*/
public function getOldData(): array
{
return $this->extra['o'] ?? [];
}
/**
* @inheritDoc
*/
public function hasComment(): bool
{
return isset($this->extra['m']);
}
/**
* @inheritDoc
*/
public function getComment(): ?string
{
return $this->extra['m'] ?? null;
}
/**
* @inheritDoc
*/
public function setComment(?string $new_comment): LogWithCommentInterface
{
$this->extra['m'] = $new_comment;
return $this;
}
/**
* @inheritDoc
*/
public function isUndoEvent(): bool
{
return isset($this->extra['u']);
}
/**
* @inheritDoc
*/
public function getUndoEventID(): ?int
{
return $this->extra['u'] ?? null;
}
/**
* @inheritDoc
*/
public function setUndoneEvent(AbstractLogEntry $event, string $mode = 'undo'): LogWithEventUndoInterface
{
$this->extra['u'] = $event->getID();
if ($mode === 'undo') {
if ('undo' === $mode) {
$this->extra['um'] = 1;
} elseif ($mode === 'revert') {
} elseif ('revert' === $mode) {
$this->extra['um'] = 2;
} else {
throw new \InvalidArgumentException('Passed invalid $mode!');
@ -180,15 +159,13 @@ class ElementDeletedLogEntry extends AbstractLogEntry implements TimeTravelInter
return $this;
}
/**
* @inheritDoc
*/
public function getUndoMode(): string
{
$mode_int = $this->extra['um'] ?? 1;
if ($mode_int === 1) {
if (1 === $mode_int) {
return 'undo';
}
return 'revert';
}
}

View file

@ -65,6 +65,7 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
/**
* Checks if this log contains infos about which fields has changed.
*
* @return bool
*/
public function hasChangedFieldsInfo(): bool
@ -74,6 +75,7 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
/**
* Return the names of all fields that were changed during the change.
*
* @return string[]
*/
public function getChangedFields(): array
@ -91,93 +93,74 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
/**
* Set the fields that were changed during this element change.
* @param string[] $changed_fields The names of the fields that were changed during the elements
*
* @param string[] $changed_fields The names of the fields that were changed during the elements
*
* @return $this
*/
public function setChangedFields(array $changed_fields): self
{
$this->extra['f'] = $changed_fields;
return $this;
}
/**
* Sets the old data for this entry.
* @param array $old_data
*
* @return $this
*/
public function setOldData(array $old_data): self
{
$this->extra['d'] = $old_data;
return $this;
}
/**
* @inheritDoc
*/
public function hasOldDataInformations(): bool
{
return !empty($this->extra['d']);
return ! empty($this->extra['d']);
}
/**
* @inheritDoc
*/
public function getOldData(): array
{
return $this->extra['d'] ?? [];
}
/**
* @inheritDoc
*/
public function hasComment(): bool
{
return isset($this->extra['m']);
}
/**
* @inheritDoc
*/
public function getComment(): ?string
{
return $this->extra['m'] ?? null;
}
/**
* @inheritDoc
*/
public function setComment(?string $new_comment): LogWithCommentInterface
{
$this->extra['m'] = $new_comment;
return $this;
}
/**
* @inheritDoc
*/
public function isUndoEvent(): bool
{
return isset($this->extra['u']);
}
/**
* @inheritDoc
*/
public function getUndoEventID(): ?int
{
return $this->extra['u'] ?? null;
}
/**
* @inheritDoc
*/
public function setUndoneEvent(AbstractLogEntry $event, string $mode = 'undo'): LogWithEventUndoInterface
{
$this->extra['u'] = $event->getID();
if ($mode === 'undo') {
if ('undo' === $mode) {
$this->extra['um'] = 1;
} elseif ($mode === 'revert') {
} elseif ('revert' === $mode) {
$this->extra['um'] = 2;
} else {
throw new \InvalidArgumentException('Passed invalid $mode!');
@ -186,16 +169,13 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
return $this;
}
/**
* @inheritDoc
*/
public function getUndoMode(): string
{
$mode_int = $this->extra['um'] ?? 1;
if ($mode_int === 1) {
if (1 === $mode_int) {
return 'undo';
} else {
return 'revert';
}
return 'revert';
}
}

View file

@ -55,6 +55,7 @@ class ExceptionLogEntry extends AbstractLogEntry
public function __construct()
{
parent::__construct();
throw new LogEntryObsoleteException();
}

View file

@ -0,0 +1,418 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\Base\AbstractDBElement;
use App\Entity\Base\AbstractNamedDBElement;
use Doctrine\ORM\Mapping as ORM;
use InvalidArgumentException;
use LogicException;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity()
* @ORM\Table("parameters")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="type", type="smallint")
* @ORM\DiscriminatorMap({
* 0 = "CategoryParameter",
* 1 = "CurrencyParameter",
* 2 = "DeviceParameter",
* 3 = "FootprintParameter",
* 4 = "GroupParameter",
* 5 = "ManufacturerParameter",
* 6 = "MeasurementUnitParameter",
* 7 = "PartParameter",
* 8 = "StorelocationParameter",
* 9 = "SupplierParameter",
* 10 = "AttachmentTypeParameter"
* })
*/
abstract class AbstractParameter extends AbstractNamedDBElement
{
/**
* @var string The class of the element that can be passed to this attachment. Must be overridden in subclasses.
*/
public const ALLOWED_ELEMENT_CLASS = '';
/**
* @var string The mathematical symbol for this specification. Can be rendered pretty later. Should be short
* @Assert\Length(max=20)
* @ORM\Column(type="string", nullable=false)
*/
protected $symbol = '';
/**
* @var float|null The guaranteed minimum value of this property.
* @Assert\Type({"float","null"})
* @Assert\LessThanOrEqual(propertyPath="value_typical", message="parameters.validator.min_lesser_typical")
* @Assert\LessThan(propertyPath="value_max", message="parameters.validator.min_lesser_max")
* @ORM\Column(type="float", nullable=true)
*/
protected $value_min;
/**
* @var float|null The typical value of this property.
* @Assert\Type({"null", "float"})
* @ORM\Column(type="float", nullable=true)
*/
protected $value_typical;
/**
* @var float|null The maximum value of this property.
* @Assert\Type({"float", "null"})
* @Assert\GreaterThanOrEqual(propertyPath="value_typical", message="parameters.validator.max_greater_typical")
* @ORM\Column(type="float", nullable=true)
*/
protected $value_max;
/**
* @var string The unit in which the value values are given (e.g. V)
* @Assert\Length(max=5)
* @ORM\Column(type="string", nullable=false)
*/
protected $unit = '';
/**
* @var string A text value for the given property.
* @ORM\Column(type="string", nullable=false)
*/
protected $value_text = '';
/**
* @var string The group this parameter belongs to.
* @ORM\Column(type="string", nullable=false, name="param_group")
*/
protected $group = '';
/**
* Mapping is done in sub classes.
*
* @var AbstractDBElement|null The element to which this parameter belongs to.
*/
protected $element;
public function __construct()
{
if ('' === static::ALLOWED_ELEMENT_CLASS) {
throw new LogicException('An *Attachment class must override the ALLOWED_ELEMENT_CLASS const!');
}
}
/**
* 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.
*
* @return AbstractDBElement|null
*/
public function getElement(): ?AbstractDBElement
{
return $this->element;
}
/**
* Return a formatted string version of the values of the string.
* Based on the set values it can return something like this: 34 V (12 V ... 50 V) [Text].
*
* @return string
*/
public function getFormattedValue(): string
{
//If we just only have text value, return early
if (null === $this->value_typical && null === $this->value_min && null === $this->value_max) {
return $this->value_text;
}
$str = '';
$bracket_opened = false;
if ($this->value_typical) {
$str .= $this->getValueTypicalWithUnit();
if ($this->value_min || $this->value_max) {
$bracket_opened = true;
$str .= ' (';
}
}
if ($this->value_max && $this->value_min) {
$str .= $this->getValueMinWithUnit().' ... '.$this->getValueMaxWithUnit();
} elseif ($this->value_max) {
$str .= 'max. '.$this->getValueMaxWithUnit();
} elseif ($this->value_min) {
$str .= 'min. '.$this->getValueMinWithUnit();
}
//Add closing bracket
if ($bracket_opened) {
$str .= ')';
}
if ($this->value_text) {
$str .= ' ['.$this->value_text.']';
}
return $str;
}
/**
* Sets the element to which this parameter belongs to.
*
* @return $this
*/
public function setElement(AbstractDBElement $element): self
{
if (! is_a($element, static::ALLOWED_ELEMENT_CLASS)) {
throw new InvalidArgumentException(sprintf('The element associated with a %s must be a %s!', static::class, static::ALLOWED_ELEMENT_CLASS));
}
$this->element = $element;
return $this;
}
/**
* Sets the name of the specification. This value is required.
*
* @return $this
*/
public function setName(string $name): AbstractNamedDBElement
{
$this->name = $name;
return $this;
}
/**
* Returns the name of the group this parameter is associated to (e.g. Technical Parameters)
* @return string
*/
public function getGroup(): string
{
return $this->group;
}
/**
* Sets the name of the group this parameter is associated to.
* @param string $group
* @return $this
*/
public function setGroup(string $group): self
{
$this->group = $group;
return $this;
}
/**
* Returns the mathematical symbol for this specification (e.g. "V_CB").
*
* @return string
*/
public function getSymbol(): string
{
return $this->symbol;
}
/**
* Sets the mathematical symbol for this specification (e.g. "V_CB").
*
* @return $this
*/
public function setSymbol(string $symbol): self
{
$this->symbol = $symbol;
return $this;
}
/**
* Returns The guaranteed minimum value of this property.
*
* @return float|null
*/
public function getValueMin(): ?float
{
return $this->value_min;
}
/**
* Sets the minimum value of this property.
*
* @return $this
*/
public function setValueMin(?float $value_min): self
{
$this->value_min = $value_min;
return $this;
}
/**
* Returns the typical value of this property.
*
* @return float|null
*/
public function getValueTypical(): ?float
{
return $this->value_typical;
}
/**
* Return a formatted version with the minimum value with the unit of this parameter.
*
* @return string
*/
public function getValueTypicalWithUnit(): string
{
return $this->formatWithUnit($this->value_typical);
}
/**
* Return a formatted version with the maximum value with the unit of this parameter.
*
* @return string
*/
public function getValueMaxWithUnit(): string
{
return $this->formatWithUnit($this->value_max);
}
/**
* Return a formatted version with the typical value with the unit of this parameter.
*
* @return string
*/
public function getValueMinWithUnit(): string
{
return $this->formatWithUnit($this->value_min);
}
/**
* Sets the typical value of this property.
*
* @param float $value_typical
*
* @return $this
*/
public function setValueTypical(?float $value_typical): self
{
$this->value_typical = $value_typical;
return $this;
}
/**
* Returns the guaranteed maximum value.
*
* @return float|null
*/
public function getValueMax(): ?float
{
return $this->value_max;
}
/**
* Sets the guaranteed maximum value.
*
* @return $this
*/
public function setValueMax(?float $value_max): self
{
$this->value_max = $value_max;
return $this;
}
/**
* Returns the unit used by the value (e.g. "V").
*
* @return string
*/
public function getUnit(): string
{
return $this->unit;
}
/**
* Sets the unit used by the value.
*
* @return $this
*/
public function setUnit(string $unit): self
{
$this->unit = $unit;
return $this;
}
/**
* Returns the text value.
*
* @return string
*/
public function getValueText(): string
{
return $this->value_text;
}
/**
* Sets the text value.
*
* @return $this
*/
public function setValueText(string $value_text): self
{
$this->value_text = $value_text;
return $this;
}
public function getIDString(): string
{
return 'PM'.sprintf('%09d', $this->getID());
}
/**
* Return a string representation and (if possible) with its unit.
*
* @return string
*/
protected function formatWithUnit(float $value, string $format = '%g'): string
{
$str = \sprintf($format, $value);
if (! empty($this->unit)) {
return $str.' '.$this->unit;
}
return $str;
}
}

View file

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\Attachments\AttachmentType;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class AttachmentTypeParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = AttachmentType::class;
/**
* @var AttachmentType the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\Attachments\AttachmentType", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\Parts\Category;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class CategoryParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = Category::class;
/**
* @var Category the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\Parts\Category", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\PriceInformations\Currency;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* A attachment attached to a category element.
*
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class CurrencyParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = Currency::class;
/**
* @var Currency the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\PriceInformations\Currency", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\Devices\Device;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class DeviceParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = Device::class;
/**
* @var Device the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\Devices\Device", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\Parts\Footprint;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class FootprintParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = Footprint::class;
/**
* @var Footprint the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\Parts\Footprint", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\UserSystem\Group;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class GroupParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = Group::class;
/**
* @var Group the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\UserSystem\Group", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\Parts\Manufacturer;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class ManufacturerParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = Manufacturer::class;
/**
* @var Manufacturer the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\Parts\Manufacturer", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\Parts\MeasurementUnit;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class MeasurementUnitParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = MeasurementUnit::class;
/**
* @var MeasurementUnit the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\Parts\MeasurementUnit", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Validator\Constraints as Assert;
trait ParametersTrait
{
/**
* Mapping done in subclasses.
*
* @var AbstractParameter[]|Collection
* @Assert\Valid()
*/
protected $parameters;
/**
* Return all associated specifications.
*
* @return AbstractParameter[]|Collection
*/
public function getParameters(): Collection
{
return $this->parameters;
}
/**
* Add a new parameter information.
*
* @return $this
*/
public function addParameter(AbstractParameter $parameter): self
{
$parameter->setElement($this);
$this->parameters->add($parameter);
return $this;
}
public function removeParameter(AbstractParameter $parameter): self
{
$this->parameters->removeElement($parameter);
return $this;
}
public function getGroupedParameters(): array
{
$tmp = [];
foreach ($this->parameters as $parameter) {
$tmp[$parameter->getGroup()][] = $parameter;
}
return $tmp;
}
}

View file

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\Parts\Part;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class PartParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = Part::class;
/**
* @var Part the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\Parts\Part", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\Parts\Storelocation;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class StorelocationParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = Storelocation::class;
/**
* @var Storelocation the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\Parts\Storelocation", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* 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\Entity\Parameters;
use App\Entity\Parts\Supplier;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @UniqueEntity(fields={"name", "group", "element"})
*/
class SupplierParameter extends AbstractParameter
{
public const ALLOWED_ELEMENT_CLASS = Supplier::class;
/**
* @var Supplier the element this para is associated with
* @ORM\ManyToOne(targetEntity="App\Entity\Parts\Supplier", inversedBy="parameters")
* @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
*/
protected $element;
}

View file

@ -24,8 +24,10 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\CategoryAttachment;
use App\Entity\Base\AbstractPartsContainingDBElement;
use App\Entity\Parameters\CategoryParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class AttachmentType.
@ -101,9 +103,17 @@ class Category extends AbstractPartsContainingDBElement
/**
* @var Collection|CategoryAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CategoryAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid()
*/
protected $attachments;
/** @var CategoryParameter[]
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\CategoryParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
* @Assert\Valid()
*/
protected $parameters;
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.
@ -121,7 +131,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
* @param string $partname_hint
* @return Category
*/
public function setPartnameHint(string $partname_hint): self
@ -137,7 +146,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
* @param string $partname_regex
* @return Category
*/
public function setPartnameRegex(string $partname_regex): self
@ -153,7 +161,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
* @param bool $disable_footprints
* @return Category
*/
public function setDisableFootprints(bool $disable_footprints): self
@ -169,7 +176,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
* @param bool $disable_manufacturers
* @return Category
*/
public function setDisableManufacturers(bool $disable_manufacturers): self
@ -185,7 +191,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
* @param bool $disable_autodatasheets
* @return Category
*/
public function setDisableAutodatasheets(bool $disable_autodatasheets): self
@ -201,7 +206,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
* @param bool $disable_properties
* @return Category
*/
public function setDisableProperties(bool $disable_properties): self
@ -217,7 +221,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
* @param string $default_description
* @return Category
*/
public function setDefaultDescription(string $default_description): self
@ -233,7 +236,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
* @param string $default_comment
* @return Category
*/
public function setDefaultComment(string $default_comment): self

View file

@ -52,8 +52,10 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\FootprintAttachment;
use App\Entity\Base\AbstractPartsContainingDBElement;
use App\Entity\Parameters\FootprintParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Footprint.
@ -81,6 +83,7 @@ class Footprint extends AbstractPartsContainingDBElement
/**
* @var Collection|FootprintAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\FootprintAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid()
*/
protected $attachments;
@ -91,6 +94,13 @@ class Footprint extends AbstractPartsContainingDBElement
*/
protected $footprint_3d;
/** @var FootprintParameter[]
* @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"})
* @Assert\Valid()
*/
protected $parameters;
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.

View file

@ -52,8 +52,10 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\ManufacturerAttachment;
use App\Entity\Base\AbstractCompany;
use App\Entity\Parameters\ManufacturerParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Manufacturer.
@ -81,9 +83,17 @@ class Manufacturer extends AbstractCompany
/**
* @var Collection|ManufacturerAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid()
*/
protected $attachments;
/** @var ManufacturerParameter[]
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\ManufacturerParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
* @Assert\Valid()
*/
protected $parameters;
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.

View file

@ -44,6 +44,7 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\MeasurementUnitAttachment;
use App\Entity\Base\AbstractPartsContainingDBElement;
use App\Entity\Parameters\MeasurementUnitParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
@ -99,9 +100,17 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
/**
* @var Collection|MeasurementUnitAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\MeasurementUnitAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid()
*/
protected $attachments;
/** @var MeasurementUnitParameter[]
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\MeasurementUnitParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
* @Assert\Valid()
*/
protected $parameters;
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.
@ -139,7 +148,6 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
}
/**
* @param bool $isInteger
* @return MeasurementUnit
*/
public function setIsInteger(bool $isInteger): self
@ -155,7 +163,6 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
}
/**
* @param bool $usesSIPrefixes
* @return MeasurementUnit
*/
public function setUseSIPrefix(bool $usesSIPrefixes): self

View file

@ -53,6 +53,8 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\AttachmentContainingDBElement;
use App\Entity\Devices\Device;
use App\Entity\Parameters\ParametersTrait;
use App\Entity\Parameters\PartParameter;
use App\Entity\Parts\PartTraits\AdvancedPropertyTrait;
use App\Entity\Parts\PartTraits\BasicPropertyTrait;
use App\Entity\Parts\PartTraits\InstockTrait;
@ -81,12 +83,21 @@ class Part extends AttachmentContainingDBElement
use InstockTrait;
use ManufacturerTrait;
use OrderTrait;
use ParametersTrait;
/**
* TODO.
*/
protected $devices = [];
/** @var PartParameter[]
* @Assert\Valid()
* @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"})
*/
protected $parameters;
/**
* @ColumnSecurity(type="datetime")
* @ORM\Column(type="datetime", name="datetime_added", options={"default"="CURRENT_TIMESTAMP"})
@ -132,6 +143,27 @@ class Part extends AttachmentContainingDBElement
parent::__construct();
$this->partLots = new ArrayCollection();
$this->orderdetails = new ArrayCollection();
$this->parameters = new ArrayCollection();
}
public function __clone()
{
if ($this->id) {
//Deep clone part lots
$lots = $this->partLots;
$this->partLots = new ArrayCollection();
foreach ($lots as $lot) {
$this->addPartLot(clone $lot);
}
//Deep clone order details
$orderdetails = $this->orderdetails;
$this->orderdetails = new ArrayCollection();
foreach ($orderdetails as $orderdetail) {
$this->addOrderdetail(clone $orderdetail);
}
}
parent::__clone();
}
/**
@ -156,24 +188,4 @@ class Part extends AttachmentContainingDBElement
{
return $this->devices;
}
public function __clone()
{
if ($this->id) {
//Deep clone part lots
$lots = $this->partLots;
$this->partLots = new ArrayCollection();
foreach ($lots as $lot) {
$this->addPartLot(clone $lot);
}
//Deep clone order details
$orderdetails = $this->orderdetails;
$this->orderdetails = new ArrayCollection();
foreach ($orderdetails as $orderdetail) {
$this->addOrderdetail(clone $orderdetail);
}
}
parent::__clone();
}
}

View file

@ -44,6 +44,7 @@ namespace App\Entity\Parts;
use App\Entity\Base\AbstractDBElement;
use App\Entity\Base\TimestampTrait;
use App\Entity\Contracts\NamedElementInterface;
use App\Entity\Contracts\TimeStampableInterface;
use App\Validator\Constraints\Selectable;
use App\Validator\Constraints\ValidPartLot;
@ -61,7 +62,7 @@ use Symfony\Component\Validator\Constraints as Assert;
* @ORM\HasLifecycleCallbacks()
* @ValidPartLot()
*/
class PartLot extends AbstractDBElement implements TimeStampableInterface
class PartLot extends AbstractDBElement implements TimeStampableInterface, NamedElementInterface
{
use TimestampTrait;
@ -119,6 +120,14 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
*/
protected $part;
public function __clone()
{
if ($this->id) {
$this->addedDate = null;
}
parent::__clone();
}
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.
@ -161,7 +170,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the description of the part lot.
*
* @param string $description
* @return PartLot
*/
public function setDescription(string $description): self
@ -184,7 +192,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the comment for this part lot.
*
* @param string $comment
* @return PartLot
*/
public function setComment(string $comment): self
@ -231,7 +238,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the storage location, where this part lot is stored.
*
* @param Storelocation|null $storage_location
* @return PartLot
*/
public function setStorageLocation(?Storelocation $storage_location): self
@ -254,8 +260,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the part that is stored in this part lot.
*
* @param Part $part
*
* @return PartLot
*/
public function setPart(Part $part): self
@ -278,7 +282,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
/**
* Set the unknown instock status of this part lot.
*
* @param bool $instock_unknown
* @return PartLot
*/
public function setInstockUnknown(bool $instock_unknown): self
@ -316,7 +319,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
}
/**
* @param bool $needs_refill
* @return PartLot
*/
public function setNeedsRefill(bool $needs_refill): self
@ -326,11 +328,11 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
return $this;
}
public function __clone()
/**
* @inheritDoc
*/
public function getName(): string
{
if($this->id) {
$this->addedDate = null;
}
parent::__clone();
return $this->description;
}
}

View file

@ -106,6 +106,7 @@ trait AdvancedPropertyTrait
* Sets a comma separated list of tags, that are assigned to this part.
*
* @param string $tags The new tags
*
* @return $this
*/
public function setTags(string $tags): self
@ -129,6 +130,7 @@ trait AdvancedPropertyTrait
* Sett to null, if the mass is unknown.
*
* @param float|null $mass the new mass
*
* @return $this
*/
public function setMass(?float $mass): self

View file

@ -164,6 +164,7 @@ trait BasicPropertyTrait
* Sets the description of this part.
*
* @param string $new_description the new description
*
* @return $this
*/
public function setDescription(?string $new_description): self
@ -177,6 +178,7 @@ trait BasicPropertyTrait
* Sets the comment property of this part.
*
* @param string $new_comment the new comment
*
* @return $this
*/
public function setComment(string $new_comment): self
@ -191,6 +193,7 @@ trait BasicPropertyTrait
* The category property is required for every part, so you can not pass null like the other properties (footprints).
*
* @param Category $category The new category of this part
*
* @return $this
*/
public function setCategory(Category $category): self
@ -205,6 +208,7 @@ trait BasicPropertyTrait
*
* @param Footprint|null $new_footprint The new footprint of this part. Set to null, if this part should not have
* a footprint.
*
* @return $this
*/
public function setFootprint(?Footprint $new_footprint): self
@ -219,6 +223,7 @@ trait BasicPropertyTrait
*
* @param bool $new_favorite_status The new favorite status, that should be applied on this part.
* Set this to true, when the part should be a favorite.
*
* @return $this
*/
public function setFavorite(bool $new_favorite_status): self

View file

@ -90,7 +90,7 @@ trait InstockTrait
/**
* Adds the given part lot, to the list of part lots.
* The part lot is assigned to this part.
* @param PartLot $lot
*
* @return $this
*/
public function addPartLot(PartLot $lot): self
@ -105,6 +105,7 @@ trait InstockTrait
* Removes the given part lot from the list of part lots.
*
* @param PartLot $lot the part lot that should be deleted
*
* @return $this
*/
public function removePartLot(PartLot $lot): self
@ -126,7 +127,7 @@ trait InstockTrait
/**
* Sets the measurement unit in which the part's amount should be measured.
* Set to null, if the part should be measured in quantities.
* @param MeasurementUnit|null $partUnit
*
* @return $this
*/
public function setPartUnit(?MeasurementUnit $partUnit): self
@ -172,7 +173,6 @@ trait InstockTrait
* Part Lots that have unknown value or are expired, are not used for this value.
*
* @return float The amount of parts given in partUnit
*
*/
public function getAmountSum(): float
{
@ -199,6 +199,7 @@ trait InstockTrait
* See getPartUnit() for the associated unit.
*
* @param float $new_minamount the new count of parts which should be in stock at least
*
* @return $this
*/
public function setMinAmount(float $new_minamount): self

View file

@ -136,7 +136,6 @@ trait ManufacturerTrait
* Sets the manufacturing status for this part
* See getManufacturingStatus() for valid values.
*
* @param string $manufacturing_status
* @return Part
*/
public function setManufacturingStatus(string $manufacturing_status): self
@ -167,7 +166,6 @@ trait ManufacturerTrait
/**
* Sets the manufacturer product number (MPN) for this part.
*
* @param string $manufacturer_product_number
* @return Part
*/
public function setManufacturerProductNumber(string $manufacturer_product_number): self
@ -182,6 +180,7 @@ trait ManufacturerTrait
* Set to "" if this part should use the automatically URL based on its manufacturer.
*
* @param string $new_url The new url
*
* @return $this
*/
public function setManufacturerProductURL(string $new_url): self
@ -196,6 +195,7 @@ trait ManufacturerTrait
*
* @param Manufacturer|null $new_manufacturer The new Manufacturer of this part. Set to null, if this part should
* not have a manufacturer.
*
* @return $this
*/
public function setManufacturer(?Manufacturer $new_manufacturer): self

View file

@ -144,6 +144,7 @@ trait OrderTrait
* The orderdetail is assigned to this part.
*
* @param Orderdetail $orderdetail the orderdetail that should be added
*
* @return $this
*/
public function addOrderdetail(Orderdetail $orderdetail): self
@ -156,7 +157,7 @@ trait OrderTrait
/**
* Removes the given orderdetail from the list of orderdetails.
* @param Orderdetail $orderdetail
*
* @return $this
*/
public function removeOrderdetail(Orderdetail $orderdetail): self
@ -177,6 +178,7 @@ trait OrderTrait
* (if the part has exactly one orderdetails,
* set this orderdetails as order orderdetails.
* Otherwise, set "no order orderdetails")
*
* @return $this
*/
public function setManualOrder(bool $new_manual_order, int $new_order_quantity = 1, ?Orderdetail $new_order_orderdetail = null): self

View file

@ -52,8 +52,10 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\StorelocationAttachment;
use App\Entity\Base\AbstractPartsContainingDBElement;
use App\Entity\Parameters\StorelocationParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Store location.
@ -85,11 +87,18 @@ class Storelocation extends AbstractPartsContainingDBElement
* @ORM\ManyToMany(targetEntity="Part", fetch="EXTRA_LAZY")
* @ORM\JoinTable(name="part_lots",
* joinColumns={@ORM\JoinColumn(name="id_store_location", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="id_part", referencedColumnName="id")}
* inverseJoinColumns={@ORM\JoinColumn(name="id_part", referencedColumnName="id")}
* )
*/
protected $parts;
/** @var StorelocationParameter[]
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\StorelocationParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
* @Assert\Valid()
*/
protected $parameters;
/**
* @var bool
* @ORM\Column(type="boolean")
@ -110,6 +119,7 @@ class Storelocation extends AbstractPartsContainingDBElement
/**
* @var Collection|StorelocationAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\StorelocationAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid()
*/
protected $attachments;
@ -143,7 +153,6 @@ class Storelocation extends AbstractPartsContainingDBElement
}
/**
* @param bool $only_single_part
* @return Storelocation
*/
public function setOnlySinglePart(bool $only_single_part): self
@ -164,7 +173,6 @@ class Storelocation extends AbstractPartsContainingDBElement
}
/**
* @param bool $limit_to_existing_parts
* @return Storelocation
*/
public function setLimitToExistingParts(bool $limit_to_existing_parts): self
@ -183,7 +191,6 @@ class Storelocation extends AbstractPartsContainingDBElement
}
/**
* @param MeasurementUnit|null $storage_type
* @return Storelocation
*/
public function setStorageType(?MeasurementUnit $storage_type): self

View file

@ -52,6 +52,7 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\SupplierAttachment;
use App\Entity\Base\AbstractCompany;
use App\Entity\Parameters\SupplierParameter;
use App\Entity\PriceInformations\Currency;
use App\Validator\Constraints\Selectable;
use Doctrine\Common\Collections\Collection;
@ -109,9 +110,17 @@ class Supplier extends AbstractCompany
/**
* @var Collection|SupplierAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\SupplierAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid()
*/
protected $attachments;
/** @var SupplierParameter[]
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\SupplierParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
* @Assert\Valid()
*/
protected $parameters;
/**
* Gets the currency that should be used by default, when creating a orderdetail with this supplier.
*
@ -125,7 +134,6 @@ class Supplier extends AbstractCompany
/**
* Sets the default currency.
*
* @param Currency|null $default_currency
* @return Supplier
*/
public function setDefaultCurrency(?Currency $default_currency): self
@ -154,7 +162,10 @@ class Supplier extends AbstractCompany
*/
public function setShippingCosts(?string $shipping_costs): self
{
$this->shipping_costs = $shipping_costs;
/* Just a little hack to ensure that price has 5 digits after decimal point,
so that DB does not detect changes, when something like 0.4 is passed
Third parameter must have the scale value of decimal column. */
$this->shipping_costs = bcmul($shipping_costs, '1.0', 5);
return $this;
}

View file

@ -44,6 +44,7 @@ namespace App\Entity\PriceInformations;
use App\Entity\Attachments\CurrencyAttachment;
use App\Entity\Base\AbstractStructuralDBElement;
use App\Entity\Parameters\CurrencyParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
@ -89,9 +90,17 @@ class Currency extends AbstractStructuralDBElement
/**
* @var Collection|CurrencyAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CurrencyAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid()
*/
protected $attachments;
/** @var CurrencyParameter[]
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\CurrencyParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
* @Assert\Valid()
*/
protected $parameters;
/**
* Returns the 3 letter ISO code of this currency.
*

View file

@ -52,6 +52,7 @@ namespace App\Entity\PriceInformations;
use App\Entity\Base\AbstractDBElement;
use App\Entity\Base\TimestampTrait;
use App\Entity\Contracts\NamedElementInterface;
use App\Entity\Contracts\TimeStampableInterface;
use App\Entity\Parts\Part;
use App\Entity\Parts\Supplier;
@ -67,7 +68,7 @@ use Symfony\Component\Validator\Constraints as Assert;
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks()
*/
class Orderdetail extends AbstractDBElement implements TimeStampableInterface
class Orderdetail extends AbstractDBElement implements TimeStampableInterface, NamedElementInterface
{
use TimestampTrait;
@ -117,6 +118,20 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface
$this->pricedetails = new ArrayCollection();
}
public function __clone()
{
if ($this->id) {
$this->addedDate = null;
$pricedetails = $this->pricedetails;
$this->pricedetails = new ArrayCollection();
//Set master attachment is needed
foreach ($pricedetails as $pricedetail) {
$this->addPricedetail(clone $pricedetail);
}
}
parent::__clone();
}
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.
@ -228,7 +243,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface
/**
* Removes an pricedetail from this orderdetail.
*
* @param Pricedetail $pricedetail
* @return Orderdetail
*/
public function removePricedetail(Pricedetail $pricedetail): self
@ -276,7 +290,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface
/**
* Sets a new part with which this orderdetail is associated.
*
* @param Part $part
* @return Orderdetail
*/
public function setPart(Part $part): self
@ -289,7 +302,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the new supplier associated with this orderdetail.
*
* @param Supplier $new_supplier
* @return Orderdetail
*/
public function setSupplier(Supplier $new_supplier): self
@ -349,17 +361,11 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface
return $this;
}
public function __clone()
/**
* @inheritDoc
*/
public function getName(): string
{
if ($this->id) {
$this->addedDate = null;
$pricedetails = $this->pricedetails;
$this->pricedetails = new ArrayCollection();
//Set master attachment is needed
foreach ($pricedetails as $pricedetail) {
$this->addPricedetail(clone $pricedetail);
}
}
parent::__clone();
return $this->getSupplierPartNr();
}
}

View file

@ -121,6 +121,14 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
bcscale(static::PRICE_PRECISION);
}
public function __clone()
{
if ($this->id) {
$this->addedDate = null;
}
parent::__clone();
}
/********************************************************************************
*
* Getters
@ -230,7 +238,6 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the orderdetail to which this pricedetail belongs to.
*
* @param Orderdetail $orderdetail
* @return $this
*/
public function setOrderdetail(Orderdetail $orderdetail): self
@ -244,7 +251,6 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
* Sets the currency associated with the price informations.
* Set to null, to use the global base currency.
*
* @param Currency|null $currency
* @return Pricedetail
*/
public function setCurrency(?Currency $currency): self
@ -262,13 +268,17 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
* * This is the price for "price_related_quantity" parts!!
* * Example: if "price_related_quantity" is '10',
* you have to set here the price for 10 parts!
*
* @return $this
*/
public function setPrice(string $new_price): self
{
//Assert::natural($new_price, 'The new price must be positive! Got %s!');
$this->price = $new_price;
/* Just a little hack to ensure that price has 5 digits after decimal point,
so that DB does not detect changes, when something like 0.4 is passed
Third parameter must have the scale value of decimal column. */
$this->price = bcmul($new_price, '1.0', static::PRICE_PRECISION);
return $this;
}
@ -309,6 +319,7 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
* So the orderdetails would have three Pricedetails for one supplier.)
*
* @param float $new_min_discount_quantity the minimum discount quantity
*
* @return $this
*/
public function setMinDiscountQuantity(float $new_min_discount_quantity): self
@ -328,12 +339,4 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
{
return 'PD'.sprintf('%06d', $this->getID());
}
public function __clone()
{
if ($this->id) {
$this->addedDate = null;
}
parent::__clone();
}
}

View file

@ -44,10 +44,12 @@ namespace App\Entity\UserSystem;
use App\Entity\Attachments\GroupAttachment;
use App\Entity\Base\AbstractStructuralDBElement;
use App\Entity\Parameters\GroupParameter;
use App\Security\Interfaces\HasPermissionsInterface;
use App\Validator\Constraints\ValidPermission;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* This entity represents an user group.
@ -81,6 +83,7 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa
/**
* @var Collection|GroupAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid()
*/
protected $attachments;
@ -90,6 +93,13 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa
*/
protected $permissions;
/** @var GroupParameter[]
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\GroupParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
* @Assert\Valid()
*/
protected $parameters;
public function __construct()
{
parent::__construct();

View file

@ -235,6 +235,12 @@ class PermissionsEmbed
*/
protected $parts_prices = 0;
/**
* @var int
* @ORM\Column(type="smallint")
*/
protected $parts_parameters = 0;
/**
* @var int
* @ORM\Column(type="smallint", name="parts_attachements")

View file

@ -123,6 +123,7 @@ class U2FKey implements TwoFactorKeyInterface
public function setKeyHandle($keyHandle): self
{
$this->keyHandle = $keyHandle;
return $this;
}
@ -134,6 +135,7 @@ class U2FKey implements TwoFactorKeyInterface
public function setPublicKey($publicKey): self
{
$this->publicKey = $publicKey;
return $this;
}
@ -145,6 +147,7 @@ class U2FKey implements TwoFactorKeyInterface
public function setCertificate($certificate): self
{
$this->certificate = $certificate;
return $this;
}
@ -156,6 +159,7 @@ class U2FKey implements TwoFactorKeyInterface
public function setCounter($counter): self
{
$this->counter = $counter;
return $this;
}
@ -167,6 +171,7 @@ class U2FKey implements TwoFactorKeyInterface
public function setName($name): self
{
$this->name = $name;
return $this;
}
@ -193,7 +198,6 @@ class U2FKey implements TwoFactorKeyInterface
/**
* Sets the user this U2F key belongs to.
*
* @param User $new_user
* @return $this
*/
public function setUser(User $new_user): self

View file

@ -52,8 +52,8 @@ namespace App\Entity\UserSystem;
use App\Entity\Attachments\AttachmentContainingDBElement;
use App\Entity\Attachments\UserAttachment;
use App\Entity\Base\MasterAttachmentTrait;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\MasterAttachmentTrait;
use App\Entity\PriceInformations\Currency;
use App\Security\Interfaces\HasPermissionsInterface;
use App\Validator\Constraints\Selectable;
@ -338,7 +338,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Sets the password hash for this user.
*
* @param string $password
* @return User
*/
public function setPassword(string $password): self
@ -378,7 +377,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Sets the currency the users prefers to see prices in.
*
* @param Currency|null $currency
* @return User
*/
public function setCurrency(?Currency $currency): self
@ -441,7 +439,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Set the status, if the user needs a password change.
*
* @param bool $need_pw_change
* @return User
*/
public function setNeedPwChange(bool $need_pw_change): self
@ -464,7 +461,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Sets the encrypted password reset token.
*
* @param string|null $pw_reset_token
* @return User
*/
public function setPwResetToken(?string $pw_reset_token): self
@ -487,7 +483,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Sets the datetime when the password reset token expires.
*
* @param DateTime $pw_reset_expires
* @return User
*/
public function setPwResetExpires(DateTime $pw_reset_expires): self
@ -671,7 +666,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Change the timezone of this user.
*
* @param string|null $timezone
* @return $this
*/
public function setTimezone(?string $timezone): self
@ -764,7 +758,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Sets the secret used for Google Authenticator. Set to null to disable Google Authenticator.
*
* @param string|null $googleAuthenticatorSecret
* @return $this
*/
public function setGoogleAuthenticatorSecret(?string $googleAuthenticatorSecret): self
@ -881,7 +874,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Add a U2F key to this user.
* @param TwoFactorKeyInterface $key
*/
public function addU2FKey(TwoFactorKeyInterface $key): void
{
@ -890,7 +882,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Remove a U2F key from this user.
* @param TwoFactorKeyInterface $key
*/
public function removeU2FKey(TwoFactorKeyInterface $key): void
{

Some files were not shown because too many files have changed in this diff Show more