Merge branch 'master' into settings-bundle

This commit is contained in:
Jan Böhmer 2025-06-15 18:39:49 +02:00
commit 442457f11b
131 changed files with 12759 additions and 6750 deletions

View file

@ -54,7 +54,7 @@ class TwoStepORMAdapter extends ORMAdapter
private \Closure|null $query_modifier = null;
public function __construct(ManagerRegistry $registry = null)
public function __construct(?ManagerRegistry $registry = null)
{
parent::__construct($registry);
$this->detailQueryCallable = static function (QueryBuilder $qb, array $ids): never {

View file

@ -50,8 +50,8 @@ final class AttachmentDataTable implements DataTableTypeInterface
{
$dataTable->add('dont_matter', RowClassColumn::class, [
'render' => function ($value, Attachment $context): string {
//Mark attachments with missing files yellow
if(!$this->attachmentHelper->isFileExisting($context)){
//Mark attachments yellow which have an internal file linked that doesn't exist
if($context->hasInternal() && !$this->attachmentHelper->isInternalFileExisting($context)){
return 'table-warning';
}
@ -64,8 +64,8 @@ final class AttachmentDataTable implements DataTableTypeInterface
'className' => 'no-colvis',
'render' => function ($value, Attachment $context): string {
if ($context->isPicture()
&& !$context->isExternal()
&& $this->attachmentHelper->isFileExisting($context)) {
&& $this->attachmentHelper->isInternalFileExisting($context)) {
$title = htmlspecialchars($context->getName());
if ($context->getFilename()) {
$title .= ' ('.htmlspecialchars($context->getFilename()).')';
@ -93,26 +93,6 @@ final class AttachmentDataTable implements DataTableTypeInterface
$dataTable->add('name', TextColumn::class, [
'label' => 'attachment.edit.name',
'orderField' => 'NATSORT(attachment.name)',
'render' => function ($value, Attachment $context) {
//Link to external source
if ($context->isExternal()) {
return sprintf(
'<a href="%s" class="link-external">%s</a>',
htmlspecialchars((string) $context->getURL()),
htmlspecialchars($value)
);
}
if ($this->attachmentHelper->isFileExisting($context)) {
return sprintf(
'<a href="%s" target="_blank" data-no-ajax>%s</a>',
$this->entityURLGenerator->viewURL($context),
htmlspecialchars($value)
);
}
return $value;
},
]);
$dataTable->add('attachment_type', TextColumn::class, [
@ -136,25 +116,60 @@ final class AttachmentDataTable implements DataTableTypeInterface
),
]);
$dataTable->add('filename', TextColumn::class, [
'label' => $this->translator->trans('attachment.table.filename'),
$dataTable->add('internal_link', TextColumn::class, [
'label' => 'attachment.table.internal_file',
'propertyPath' => 'filename',
'orderField' => 'NATSORT(attachment.original_filename)',
'render' => function ($value, Attachment $context) {
if ($this->attachmentHelper->isInternalFileExisting($context)) {
return sprintf(
'<a href="%s" target="_blank" data-no-ajax>%s</a>',
$this->entityURLGenerator->viewURL($context),
htmlspecialchars($value)
);
}
return $value;
}
]);
$dataTable->add('external_link', TextColumn::class, [
'label' => 'attachment.table.external_link',
'propertyPath' => 'host',
'orderField' => 'attachment.external_path',
'render' => function ($value, Attachment $context) {
if ($context->hasExternal()) {
return sprintf(
'<a href="%s" class="link-external" title="%s" target="_blank" rel="noopener">%s</a>',
htmlspecialchars((string) $context->getExternalPath()),
htmlspecialchars((string) $context->getExternalPath()),
htmlspecialchars($value),
);
}
return $value;
}
]);
$dataTable->add('filesize', TextColumn::class, [
'label' => $this->translator->trans('attachment.table.filesize'),
'render' => function ($value, Attachment $context) {
if ($context->isExternal()) {
if (!$context->hasInternal()) {
return sprintf(
'<span class="badge bg-primary">
<i class="fas fa-globe fa-fw"></i>%s
</span>',
$this->translator->trans('attachment.external')
$this->translator->trans('attachment.external_only')
);
}
if ($this->attachmentHelper->isFileExisting($context)) {
return $this->attachmentHelper->getHumanFileSize($context);
if ($this->attachmentHelper->isInternalFileExisting($context)) {
return sprintf(
'<span class="badge bg-secondary">
<i class="fas fa-hdd fa-fw"></i> %s
</span>',
$this->attachmentHelper->getHumanFileSize($context)
);
}
return sprintf(

View file

@ -45,6 +45,9 @@ class AttachmentFilter implements FilterInterface
public readonly DateTimeConstraint $lastModified;
public readonly DateTimeConstraint $addedDate;
public readonly TextConstraint $originalFileName;
public readonly TextConstraint $externalLink;
public function __construct(NodesListBuilder $nodesListBuilder)
{
@ -55,6 +58,9 @@ class AttachmentFilter implements FilterInterface
$this->lastModified = new DateTimeConstraint('attachment.lastModified');
$this->addedDate = new DateTimeConstraint('attachment.addedDate');
$this->showInTable = new BooleanConstraint('attachment.show_in_table');
$this->originalFileName = new TextConstraint('attachment.original_filename');
$this->externalLink = new TextConstraint('attachment.external_path');
}
public function apply(QueryBuilder $queryBuilder): void

View file

@ -45,7 +45,7 @@ abstract class AbstractConstraint implements FilterInterface
* @var string The property where this BooleanConstraint should apply to
*/
protected string $property,
string $identifier = null)
?string $identifier = null)
{
$this->identifier = $identifier ?? $this->generateParameterIdentifier($property);
}

View file

@ -28,7 +28,7 @@ class BooleanConstraint extends AbstractConstraint
{
public function __construct(
string $property,
string $identifier = null,
?string $identifier = null,
/** @var bool|null The value of our constraint */
protected ?bool $value = null
)

View file

@ -34,7 +34,7 @@ class DateTimeConstraint extends AbstractConstraint
public function __construct(
string $property,
string $identifier = null,
?string $identifier = null,
/**
* The value1 used for comparison (this is the main one used for all mono-value comparisons)
*/

View file

@ -46,7 +46,7 @@ class EntityConstraint extends AbstractConstraint
public function __construct(protected ?NodesListBuilder $nodesListBuilder,
protected string $class,
string $property,
string $identifier = null,
?string $identifier = null,
protected ?AbstractDBElement $value = null,
protected ?string $operator = null)
{

View file

@ -31,7 +31,7 @@ class NumberConstraint extends AbstractConstraint
public function __construct(
string $property,
string $identifier = null,
?string $identifier = null,
/**
* The value1 used for comparison (this is the main one used for all mono-value comparisons)
*/

View file

@ -28,7 +28,7 @@ use Doctrine\ORM\QueryBuilder;
class LessThanDesiredConstraint extends BooleanConstraint
{
public function __construct(string $property = null, string $identifier = null, ?bool $default_value = null)
public function __construct(?string $property = null, ?string $identifier = null, ?bool $default_value = null)
{
parent::__construct($property ?? '(
SELECT COALESCE(SUM(ld_partLot.amount), 0.0)

View file

@ -30,7 +30,7 @@ class TagsConstraint extends AbstractConstraint
{
final public const ALLOWED_OPERATOR_VALUES = ['ANY', 'ALL', 'NONE'];
public function __construct(string $property, string $identifier = null,
public function __construct(string $property, ?string $identifier = null,
protected ?string $value = null,
protected ?string $operator = '')
{

View file

@ -32,7 +32,7 @@ class TextConstraint extends AbstractConstraint
/**
* @param string $value
*/
public function __construct(string $property, string $identifier = null, /**
public function __construct(string $property, ?string $identifier = null, /**
* @var string|null The value to compare to
*/
protected ?string $value = null, /**

View file

@ -58,6 +58,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
final class PartsDataTable implements DataTableTypeInterface
{
const LENGTH_MENU = [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]];
public function __construct(
private readonly EntityURLGenerator $urlGenerator,
private readonly TranslatorInterface $translator,