diff --git a/databox/api/config/bundles.php b/databox/api/config/bundles.php index 50835713d..fe0b86f76 100644 --- a/databox/api/config/bundles.php +++ b/databox/api/config/bundles.php @@ -30,7 +30,7 @@ Alchemy\WorkflowBundle\AlchemyWorkflowBundle::class => ['all' => true], Alchemy\ESBundle\AlchemyESBundle::class => ['all' => true], Alchemy\MessengerBundle\AlchemyMessengerBundle::class => ['all' => true], - Sentry\SentryBundle\SentryBundle::class => ['prod' => true], + Sentry\SentryBundle\SentryBundle::class => ['all' => true], Arthem\ObjectReferenceBundle\ArthemObjectReferenceBundle::class => ['all' => true], Alchemy\RenditionFactoryBundle\AlchemyRenditionFactoryBundle::class => ['all' => true], ]; diff --git a/databox/api/config/packages/messenger.yaml b/databox/api/config/packages/messenger.yaml index 16672517f..10d6e30b2 100644 --- a/databox/api/config/packages/messenger.yaml +++ b/databox/api/config/packages/messenger.yaml @@ -14,6 +14,7 @@ framework: Alchemy\Workflow\Message\JobConsumer: p1 Alchemy\WebhookBundle\Consumer\WebhookTriggerMessage: p2 Alchemy\WebhookBundle\Consumer\WebhookEvent: p2 + Alchemy\CoreBundle\Message\Debug\SentryDebug: p1 when@dev: framework: diff --git a/databox/api/src/Controller/Admin/AssetRenditionCrudController.php b/databox/api/src/Controller/Admin/AssetRenditionCrudController.php index cc5bd9881..a5b8685ac 100644 --- a/databox/api/src/Controller/Admin/AssetRenditionCrudController.php +++ b/databox/api/src/Controller/Admin/AssetRenditionCrudController.php @@ -6,8 +6,10 @@ use Alchemy\AdminBundle\Field\CodeField; use Alchemy\AdminBundle\Field\IdField; use Alchemy\AdminBundle\Field\JsonField; +use Alchemy\AdminBundle\Filter\AssociationIdentifierFilter; use Alchemy\AdminBundle\Filter\ChildPropertyEntityFilter; use App\Entity\Core\AssetRendition; +use App\Entity\Core\Workspace; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; @@ -15,7 +17,9 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField; use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; +use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter; use EasyCorp\Bundle\EasyAdminBundle\Filter\DateTimeFilter; +use EasyCorp\Bundle\EasyAdminBundle\Filter\EntityFilter; use EasyCorp\Bundle\EasyAdminBundle\Filter\NullFilter; class AssetRenditionCrudController extends AbstractAdminCrudController @@ -45,9 +49,18 @@ public function configureCrud(Crud $crud): Crud public function configureFilters(Filters $filters): Filters { return $filters - ->add(ChildPropertyEntityFilter::new('definition', 'workspace', 'Workspace')) + ->add(ChildPropertyEntityFilter::new( + 'definition', + 'workspace', + Workspace::class, + 'Workspace' + )) + ->add(EntityFilter::new('definition')) + ->add(AssociationIdentifierFilter::new('asset')) ->add(NullFilter::new('file', 'Is Ready')->setChoiceLabels('Not ready', 'Ready')) ->add(DateTimeFilter::new('createdAt')) + ->add(BooleanFilter::new('locked')) + ->add(BooleanFilter::new('substituted')) ; } diff --git a/databox/api/src/Controller/Admin/AttributeCrudController.php b/databox/api/src/Controller/Admin/AttributeCrudController.php index 614e8cbd3..130ae71c5 100644 --- a/databox/api/src/Controller/Admin/AttributeCrudController.php +++ b/databox/api/src/Controller/Admin/AttributeCrudController.php @@ -5,8 +5,10 @@ use Alchemy\AdminBundle\Controller\AbstractAdminCrudController; use Alchemy\AdminBundle\Field\IdField; use Alchemy\AdminBundle\Field\JsonField; +use Alchemy\AdminBundle\Filter\AssociationIdentifierFilter; use Alchemy\AdminBundle\Filter\ChildPropertyEntityFilter; use App\Entity\Core\Attribute; +use App\Entity\Core\Workspace; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; @@ -19,6 +21,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter; +use EasyCorp\Bundle\EasyAdminBundle\Filter\EntityFilter; use EasyCorp\Bundle\EasyAdminBundle\Filter\TextFilter; class AttributeCrudController extends AbstractAdminCrudController @@ -38,7 +41,14 @@ public function configureActions(Actions $actions): Actions public function configureFilters(Filters $filters): Filters { return $filters - ->add(ChildPropertyEntityFilter::new('definition', 'workspace', 'Workspace')) + ->add(ChildPropertyEntityFilter::new( + 'definition', + 'workspace', + Workspace::class, + 'Workspace' + )) + ->add(EntityFilter::new('definition')) + ->add(AssociationIdentifierFilter::new('asset')) ->add(TextFilter::new('value')) ->add(TextFilter::new('locale')) ->add(BooleanFilter::new('locked')) @@ -50,7 +60,7 @@ public function configureCrud(Crud $crud): Crud return parent::configureCrud($crud) ->setEntityLabelInSingular('Attribute') ->setEntityLabelInPlural('Attribute') - ->setSearchFields(['id', 'locale', 'position', 'translationId', 'translationOriginHash', 'value', 'origin', 'originVendor', 'originUserId', 'originVendorContext', 'coordinates', 'status', 'confidence']) + ->setSearchFields(['id', 'locale', 'position', 'translationOriginHash', 'value', 'origin', 'originVendor', 'originUserId', 'originVendorContext', 'coordinates', 'status', 'confidence']) ->setPaginatorPageSize(20); } diff --git a/databox/api/src/Doctrine/Delete/CollectionDelete.php b/databox/api/src/Doctrine/Delete/CollectionDelete.php index 703a1933b..d5c1863d6 100644 --- a/databox/api/src/Doctrine/Delete/CollectionDelete.php +++ b/databox/api/src/Doctrine/Delete/CollectionDelete.php @@ -10,12 +10,16 @@ use App\Entity\Core\Asset; use App\Entity\Core\Collection; use App\Entity\Core\CollectionAsset; +use App\Entity\Template\AssetDataTemplate; use Doctrine\ORM\EntityManagerInterface; final readonly class CollectionDelete { - public function __construct(private EntityManagerInterface $em, private IndexCleaner $indexCleaner, private SoftDeleteToggler $softDeleteToggler) - { + public function __construct( + private EntityManagerInterface $em, + private IndexCleaner $indexCleaner, + private SoftDeleteToggler $softDeleteToggler, + ) { } public function deleteCollection(string $collectionId, bool $isChildProcess = false): void @@ -79,13 +83,6 @@ private function doDelete(string $collectionId): void ->getQuery() ->toIterable(); - foreach ($assets as $a) { - $asset = $this->em->find(Asset::class, $a['id']); - $this->em->remove($asset); - $this->em->flush(); - $this->em->clear(); - } - $this->em->getRepository(CollectionAsset::class) ->createQueryBuilder('t') ->delete() @@ -94,10 +91,31 @@ private function doDelete(string $collectionId): void ->getQuery() ->execute(); + foreach ($assets as $a) { + $asset = $this->em->find(Asset::class, $a['id']); + $this->em->remove($asset); + $this->em->flush(); + $this->em->clear(); + } + + $this->deleteDependencies(AssetDataTemplate::class, $collectionId); + $collection = $this->em->find(Collection::class, $collectionId); if ($collection instanceof Collection) { $this->em->remove($collection); $this->em->flush(); } } + + private function deleteDependencies(string $entityClass, string $collectionId): void + { + $items = $this->em->getRepository($entityClass)->findBy([ + 'collection' => $collectionId, + ]); + foreach ($items as $item) { + $this->em->remove($item); + } + $this->em->flush(); + $this->em->clear(); + } } diff --git a/databox/api/src/Doctrine/Delete/WorkspaceDelete.php b/databox/api/src/Doctrine/Delete/WorkspaceDelete.php index b640c2522..8611ab0c9 100644 --- a/databox/api/src/Doctrine/Delete/WorkspaceDelete.php +++ b/databox/api/src/Doctrine/Delete/WorkspaceDelete.php @@ -15,12 +15,17 @@ use App\Entity\Core\RenditionDefinition; use App\Entity\Core\Tag; use App\Entity\Core\Workspace; +use App\Entity\Template\AssetDataTemplate; use Doctrine\ORM\EntityManagerInterface; -class WorkspaceDelete +final readonly class WorkspaceDelete { - public function __construct(private readonly EntityManagerInterface $em, private readonly CollectionDelete $collectionDelete, private readonly IndexCleaner $indexCleaner, private readonly SoftDeleteToggler $softDeleteToggler) - { + public function __construct( + private EntityManagerInterface $em, + private CollectionDelete $collectionDelete, + private IndexCleaner $indexCleaner, + private SoftDeleteToggler $softDeleteToggler, + ) { } public function deleteWorkspace(string $workspaceId): void @@ -62,6 +67,7 @@ public function deleteWorkspace(string $workspaceId): void $this->deleteDependencies(RenditionClass::class, $workspaceId); $this->deleteDependencies(AttributeDefinition::class, $workspaceId); $this->deleteDependencies(AttributeClass::class, $workspaceId); + $this->deleteDependencies(AssetDataTemplate::class, $workspaceId); $files = $this->em->getRepository(File::class) ->createQueryBuilder('t') diff --git a/expose/api/config/bundles.php b/expose/api/config/bundles.php index 6882f3890..aaa4655d0 100644 --- a/expose/api/config/bundles.php +++ b/expose/api/config/bundles.php @@ -24,6 +24,6 @@ Exercise\HTMLPurifierBundle\ExerciseHTMLPurifierBundle::class => ['all' => true], Alchemy\NotifyBundle\AlchemyNotifyBundle::class => ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], - Sentry\SentryBundle\SentryBundle::class => ['prod' => true], + Sentry\SentryBundle\SentryBundle::class => ['all' => true], Alchemy\MessengerBundle\AlchemyMessengerBundle::class => ['all' => true], ]; diff --git a/expose/api/config/packages/messenger.yaml b/expose/api/config/packages/messenger.yaml index cc60768e3..228be678a 100644 --- a/expose/api/config/packages/messenger.yaml +++ b/expose/api/config/packages/messenger.yaml @@ -5,6 +5,9 @@ framework: dsn: '%alchemy_messenger.amqp_transport_dsn%/p1' options: '%alchemy_messenger.amqp_transport_options%' + routing: + Alchemy\CoreBundle\Message\Debug\SentryDebug: p1 + when@dev: framework: messenger: diff --git a/lib/php/admin-bundle/Filter/ChildPropertyEntityFilter.php b/lib/php/admin-bundle/Filter/ChildPropertyEntityFilter.php index dff8b7963..4fb056feb 100644 --- a/lib/php/admin-bundle/Filter/ChildPropertyEntityFilter.php +++ b/lib/php/admin-bundle/Filter/ChildPropertyEntityFilter.php @@ -14,6 +14,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; use EasyCorp\Bundle\EasyAdminBundle\Dto\FilterDataDto; +use EasyCorp\Bundle\EasyAdminBundle\Dto\FilterDto; use EasyCorp\Bundle\EasyAdminBundle\Filter\FilterTrait; use EasyCorp\Bundle\EasyAdminBundle\Form\Filter\Type\EntityFilterType; use EasyCorp\Bundle\EasyAdminBundle\Form\Type\ComparisonType; @@ -24,17 +25,25 @@ final class ChildPropertyEntityFilter implements FilterInterface { use FilterTrait; - public static function new(string $propertyName, string $childPropertyName, $label = null): self + private string $realPropertyName; + private string $subPropertyName; + + + public static function new(string $propertyName, string $childPropertyName, string $entityClass, $label = null): self { $label = null == $label ? $childPropertyName : $label; return (new self()) ->setFilterFqcn(__CLASS__) - ->setProperty($propertyName) + ->setRealPropertyName($propertyName) + ->setSubPropertyName($childPropertyName) + ->setProperty(sprintf('%s__%s', $propertyName, $childPropertyName)) ->setLabel($label) ->setFormType(EntityFilterType::class) ->setFormTypeOption('translation_domain', 'EasyAdminBundle') - ->setFormTypeOption('value_type_options.attr.data-child-property', $childPropertyName); + ->setFormTypeOption('value_type_options.attr.data-child-property', $childPropertyName) + ->setFormTypeOption('value_type_options.class', $entityClass) + ; } /** @@ -48,13 +57,13 @@ public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto, $assocAlias = 'ea_'.$filterDataDto->getParameterName(); $childAssocAlias = 'ea_'.$filterDataDto->getParameter2Name(); - $property = $filterDataDto->getProperty(); + $property = $this->realPropertyName; $comparison = $filterDataDto->getComparison(); $parameterName = $filterDataDto->getParameterName(); $value = $filterDataDto->getValue(); $isMultiple = $filterDataDto->getFormTypeOption('value_type_options.multiple'); - $childPropertyName = $filterDataDto->getFormTypeOption('value_type_options.attr.data-child-property'); + $childPropertyName = $this->subPropertyName; $doctrineMetadata = $entityDto->getPropertyMetadata($property); $entityManager = $queryBuilder->getEntityManager(); $propertyEntityFqcn = $doctrineMetadata->get('targetEntity'); @@ -155,4 +164,18 @@ private function processSingleParameterValue(QueryBuilder $queryBuilder, mixed $ return $parameterValue; } + + public function setRealPropertyName(string $realPropertyName): self + { + $this->realPropertyName = $realPropertyName; + + return $this; + } + + public function setSubPropertyName(string $subPropertyName): self + { + $this->subPropertyName = $subPropertyName; + + return $this; + } } diff --git a/lib/php/core-bundle/Controller/SentryTestController.php b/lib/php/core-bundle/Controller/SentryTestController.php index 6ed5fbb39..00d078cc3 100644 --- a/lib/php/core-bundle/Controller/SentryTestController.php +++ b/lib/php/core-bundle/Controller/SentryTestController.php @@ -4,10 +4,12 @@ namespace Alchemy\CoreBundle\Controller; +use Alchemy\CoreBundle\Message\Debug\SentryDebug; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\Attribute\Autoconfigure; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; +use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Annotation\Route; #[Route(path: '/_health/sentry-test')] @@ -40,4 +42,22 @@ public function testBoth(): never throw new \RuntimeException('[BOTH] Exception'); } + + #[Route(path: '/log-stack')] + public function logStack(): never + { + $this->logger->debug('This is a DEBUG log'); + $this->logger->info('This is a INFO log'); + $this->logger->error('This is a ERROR log'); + + throw new \RuntimeException('Stack'); + } + + #[Route(path: '/messenger')] + public function messenger(MessageBusInterface $bus): Response + { + $bus->dispatch(new SentryDebug(date(\DateTimeInterface::ATOM), ['extra' => 'data'])); + + return new Response(''); + } } diff --git a/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php b/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php index d947697d6..df5d22ba9 100644 --- a/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php +++ b/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php @@ -150,8 +150,9 @@ public function prepend(ContainerBuilder $container): void ], ]); } + if (isset($bundles['SentryBundle'])) { - $container->prependExtensionConfig('sentry', [ + $sentryConfig = [ 'tracing' => [ 'dbal' => [ 'enabled' => false, @@ -181,7 +182,12 @@ public function prepend(ContainerBuilder $container): void NotAcceptableHttpException::class, ], ], - ]); + ]; + + if ($env !== 'prod') { + $sentryConfig['dsn'] = null; + } + $container->prependExtensionConfig('sentry', $sentryConfig); if (isset($bundles['MonologBundle'])) { $container->prependExtensionConfig('sentry', [ diff --git a/lib/php/core-bundle/Message/Debug/SentryDebug.php b/lib/php/core-bundle/Message/Debug/SentryDebug.php new file mode 100644 index 000000000..41f926b02 --- /dev/null +++ b/lib/php/core-bundle/Message/Debug/SentryDebug.php @@ -0,0 +1,22 @@ +id; + } + + public function getExtra(): array + { + return $this->extra; + } +} diff --git a/lib/php/core-bundle/Message/Debug/SentryDebugHandler.php b/lib/php/core-bundle/Message/Debug/SentryDebugHandler.php new file mode 100644 index 000000000..745993ff1 --- /dev/null +++ b/lib/php/core-bundle/Message/Debug/SentryDebugHandler.php @@ -0,0 +1,14 @@ +getId())); + } +} diff --git a/lib/php/core-bundle/Resources/config/sentry.yaml b/lib/php/core-bundle/Resources/config/sentry.yaml index 758b9c41f..063de3ca7 100644 --- a/lib/php/core-bundle/Resources/config/sentry.yaml +++ b/lib/php/core-bundle/Resources/config/sentry.yaml @@ -9,6 +9,7 @@ services: autoconfigure: true Alchemy\CoreBundle\Controller\SentryTestController: ~ + Alchemy\CoreBundle\Message\Debug\SentryDebugHandler: ~ Sentry\Monolog\Handler: arguments: diff --git a/lib/php/core-bundle/Util/UrlUtil.php b/lib/php/core-bundle/Util/UrlUtil.php index 194bf5c85..18f92e5d3 100644 --- a/lib/php/core-bundle/Util/UrlUtil.php +++ b/lib/php/core-bundle/Util/UrlUtil.php @@ -24,6 +24,11 @@ public static function removeQueryParamFromUrl(string $url, string $key): string return $baseUrl.'?'.$query; } + public static function getUriWithoutQuery(string $url): string + { + return strtok($url, '?'); + } + public static function extractUrlParameters(string $url): ?array { $parts = parse_url($url); diff --git a/lib/php/messenger-bundle/Controller/MessengerMessageCrudController.php b/lib/php/messenger-bundle/Controller/MessengerMessageCrudController.php index e10b796eb..57806e712 100644 --- a/lib/php/messenger-bundle/Controller/MessengerMessageCrudController.php +++ b/lib/php/messenger-bundle/Controller/MessengerMessageCrudController.php @@ -16,6 +16,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; +use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\Messenger\MessageBusInterface; @@ -70,7 +71,8 @@ public function retry(AdminContext $context): RedirectResponse $this->em->persist($message); $this->em->flush(); - return new RedirectResponse($context->getReferrer()); + return $this->redirect($context->getReferrer() + ?? $this->container->get(AdminUrlGenerator::class)->setAction(Action::INDEX)->generateUrl()); } public function configureCrud(Crud $crud): Crud diff --git a/lib/php/messenger-bundle/Listener/SentryMessengerListener.php b/lib/php/messenger-bundle/Listener/SentryMessengerListener.php index 991eacd73..9d24bac73 100644 --- a/lib/php/messenger-bundle/Listener/SentryMessengerListener.php +++ b/lib/php/messenger-bundle/Listener/SentryMessengerListener.php @@ -40,9 +40,6 @@ public function handleWorkerMessageFailedEvent(WorkerMessageFailedEvent $event): $envelope = $event->getEnvelope(); $exception = $event->getThrowable(); - $scope->setTag('messenger.receiver_name', $event->getReceiverName()); - $scope->setTag('messenger.message_class', \get_class($envelope->getMessage())); - /** @var BusNameStamp|null $messageBusStamp */ $messageBusStamp = $envelope->last(BusNameStamp::class); @@ -50,14 +47,15 @@ public function handleWorkerMessageFailedEvent(WorkerMessageFailedEvent $event): $scope->setTag('messenger.message_bus', $messageBusStamp->getBusName()); } - $scope->setExtras([ - 'Messenger Message' => get_debug_type($envelope->getMessage()), - 'Messenger Payload' => $this->serializer->serialize( + $scope->setContext('messenger', [ + 'Message' => get_debug_type($envelope->getMessage()), + 'Payload' => $this->serializer->serialize( $envelope->getMessage(), JsonEncoder::FORMAT, [ - JsonEncode::OPTIONS => JSON_PRETTY_PRINT + JsonEncode::OPTIONS => JSON_PRETTY_PRINT, ] ), + 'ReceiverName' => $event->getReceiverName(), ]); $this->captureException($exception, $event->willRetry()); diff --git a/lib/php/rendition-factory/src/Command/CreateCommand.php b/lib/php/rendition-factory/src/Command/CreateCommand.php index 6dd533b96..3fc870e70 100644 --- a/lib/php/rendition-factory/src/Command/CreateCommand.php +++ b/lib/php/rendition-factory/src/Command/CreateCommand.php @@ -56,7 +56,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int if (null === $mimeType) { $mimeType = $this->mimeTypeGuesser->guessMimeTypeFromPath($src); - $output->writeln(sprintf('MIME type guessed: %s', $mimeType)); + $output->writeln(sprintf('MIME type guessed: %s', $mimeType ?? 'unknown')); } $buildConfig = $this->yamlLoader->load($input->getArgument('build-config')); diff --git a/lib/php/rendition-factory/src/Context/ReadOnlyTransformationContext.php b/lib/php/rendition-factory/src/Context/ReadOnlyTransformationContext.php index f2efc96bc..73cb6bf74 100644 --- a/lib/php/rendition-factory/src/Context/ReadOnlyTransformationContext.php +++ b/lib/php/rendition-factory/src/Context/ReadOnlyTransformationContext.php @@ -25,7 +25,7 @@ public function getCacheDir(string $folder): string throw new \InvalidArgumentException('Cannot get cache directory in read-only context'); } - public function guessMimeTypeFromPath(string $path): string + public function guessMimeTypeFromPath(string $path): ?string { return $this->mimeTypeGuesser->guessMimeTypeFromPath($path); } diff --git a/lib/php/rendition-factory/src/Context/TransformationContext.php b/lib/php/rendition-factory/src/Context/TransformationContext.php index c56039842..97af1eb42 100644 --- a/lib/php/rendition-factory/src/Context/TransformationContext.php +++ b/lib/php/rendition-factory/src/Context/TransformationContext.php @@ -2,6 +2,7 @@ namespace Alchemy\RenditionFactory\Context; +use Alchemy\CoreBundle\Util\UrlUtil; use Alchemy\RenditionFactory\DTO\Metadata\MetadataContainerInterface; use Alchemy\RenditionFactory\MimeType\MimeTypeGuesser; use Psr\Log\LoggerInterface; @@ -46,7 +47,7 @@ public function getCacheDir(string $folder): string return $cacheDir; } - public function guessMimeTypeFromPath(string $path): string + public function guessMimeTypeFromPath(string $path): ?string { return $this->mimeTypeGuesser->guessMimeTypeFromPath($path); } @@ -59,18 +60,23 @@ public function getExtension(string $mimeType): ?string public function getRemoteFile(string $uri): string { $cacheDir = $this->getCacheDir('remote'); - $mimeType = $this->guessMimeTypeFromPath($uri); - $extension = $this->getExtension($mimeType); + $mimeType = $this->guessMimeTypeFromPath(UrlUtil::getUriWithoutQuery($uri)); + $extension = null !== $mimeType ? $this->getExtension($mimeType) : null; $path = $cacheDir.'/'.md5($uri).($extension ? '.'.$extension : ''); if (!file_exists($path)) { - $this->download($uri, $path); + $contentType = $this->download($uri, $path); + if (null === $mimeType && null !== $contentType) { + $newPath = $path.'.'.$this->getExtension($contentType); + rename($path, $newPath); + $path = $newPath; + } } return $path; } - private function download(string $uri, string $dest): void + private function download(string $uri, string $dest): ?string { $response = $this->client->request('GET', $uri); @@ -79,6 +85,13 @@ private function download(string $uri, string $dest): void fwrite($fileHandler, $chunk->getContent()); } fclose($fileHandler); + + $contentType = $response->getHeaders()['content-type'] ?? null; + if (empty($contentType)) { + return null; + } + + return is_array($contentType) ? $contentType[0] : $contentType; } public function getMetadata(string $name): ?string diff --git a/lib/php/rendition-factory/src/Context/TransformationContextInterface.php b/lib/php/rendition-factory/src/Context/TransformationContextInterface.php index e568b00e1..88278d409 100644 --- a/lib/php/rendition-factory/src/Context/TransformationContextInterface.php +++ b/lib/php/rendition-factory/src/Context/TransformationContextInterface.php @@ -8,7 +8,7 @@ public function createTmpFilePath(?string $extension): string; public function getCacheDir(string $folder): string; - public function guessMimeTypeFromPath(string $path): string; + public function guessMimeTypeFromPath(string $path): ?string; public function getExtension(string $mimeType): ?string; diff --git a/lib/php/workflow/src/Executor/JobExecutor.php b/lib/php/workflow/src/Executor/JobExecutor.php index 40337f492..a2366f4e4 100644 --- a/lib/php/workflow/src/Executor/JobExecutor.php +++ b/lib/php/workflow/src/Executor/JobExecutor.php @@ -177,11 +177,11 @@ private function dispatchEvent(JobUpdateEvent $event): void } } - private function persistJobState(JobState $jobState): void + private function persistJobState(JobState $jobState, bool $releaseLock = true): void { $this->stateRepository->persistJobState($jobState); - if ($this->stateRepository instanceof LockAwareStateRepositoryInterface) { + if ($releaseLock && $this->stateRepository instanceof LockAwareStateRepositoryInterface) { $this->stateRepository->releaseJobLock($jobState->getWorkflowId(), $jobState->getId()); } @@ -241,7 +241,7 @@ private function runJob(JobExecutionContext $context, Job $job): void if ($runContext->isRetainJob()) { $this->extractOutputs($job, $context); - $this->stateRepository->persistJobState($jobState); + $this->persistJobState($jobState, releaseLock: false); return; } @@ -252,7 +252,7 @@ private function runJob(JobExecutionContext $context, Job $job): void $jobState->setEndedAt(new MicroDateTime()); $jobState->setStatus($endStatus); - $this->stateRepository->persistJobState($jobState); + $this->persistJobState($jobState, releaseLock: false); } private function getJobCallable(Step $step, JobExecutionContext $context, RunContext $runContext): callable diff --git a/notify/api/config/bundles.php b/notify/api/config/bundles.php index a62c2bdb9..390f616e7 100644 --- a/notify/api/config/bundles.php +++ b/notify/api/config/bundles.php @@ -12,6 +12,6 @@ Alchemy\AdminBundle\AlchemyAdminBundle::class => ['all' => true], EasyCorp\Bundle\EasyAdminBundle\EasyAdminBundle::class => ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], - Sentry\SentryBundle\SentryBundle::class => ['prod' => true], + Sentry\SentryBundle\SentryBundle::class => ['all' => true], Alchemy\MessengerBundle\AlchemyMessengerBundle::class => ['all' => true], ]; diff --git a/notify/api/config/packages/messenger.yaml b/notify/api/config/packages/messenger.yaml index cc60768e3..228be678a 100644 --- a/notify/api/config/packages/messenger.yaml +++ b/notify/api/config/packages/messenger.yaml @@ -5,6 +5,9 @@ framework: dsn: '%alchemy_messenger.amqp_transport_dsn%/p1' options: '%alchemy_messenger.amqp_transport_options%' + routing: + Alchemy\CoreBundle\Message\Debug\SentryDebug: p1 + when@dev: framework: messenger: diff --git a/uploader/api/config/bundles.php b/uploader/api/config/bundles.php index e332b2900..33480728a 100644 --- a/uploader/api/config/bundles.php +++ b/uploader/api/config/bundles.php @@ -27,6 +27,6 @@ Alchemy\StorageBundle\AlchemyStorageBundle::class => ['all' => true], Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], Oneup\FlysystemBundle\OneupFlysystemBundle::class => ['all' => true], - Sentry\SentryBundle\SentryBundle::class => ['prod' => true], + Sentry\SentryBundle\SentryBundle::class => ['all' => true], Alchemy\MessengerBundle\AlchemyMessengerBundle::class => ['all' => true], ]; diff --git a/uploader/api/config/packages/messenger.yaml b/uploader/api/config/packages/messenger.yaml index 76191dc2d..ef018a2b1 100644 --- a/uploader/api/config/packages/messenger.yaml +++ b/uploader/api/config/packages/messenger.yaml @@ -11,6 +11,9 @@ framework: dsn: '%alchemy_messenger.amqp_transport_dsn%/p3' options: '%alchemy_messenger.amqp_transport_options%' + routing: + Alchemy\CoreBundle\Message\Debug\SentryDebug: p1 + when@dev: framework: messenger: