Skip to content

Commit 29db370

Browse files
committed
local conflict resolution
2 parents 5db1af3 + 1001b4a commit 29db370

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+843
-301
lines changed

bin/dev/reset-db-fixtures.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,11 @@ docker compose run --rm databox-api-php /bin/ash -c 'bin/console doctrine:databa
1717
&& bin/console doctrine:migrations:version --add --all --no-interaction \
1818
&& bin/console hautelook:fixtures:load --no-interaction \
1919
&& bin/console fos:elastica:populate'
20+
21+
docker compose run --rm -e DATABOX_UPLOADER_TARGET_SLUG uploader-api-php /bin/ash -c 'bin/console doctrine:database:drop --force \
22+
&& bin/console doctrine:database:create \
23+
&& bin/console doctrine:schema:create \
24+
&& bin/console doctrine:migrations:sync-metadata-storage \
25+
&& bin/console doctrine:migrations:version --delete --all --no-interaction \
26+
&& bin/console doctrine:migrations:version --add --all --no-interaction \
27+
&& bin/console app:create-target ${DATABOX_UPLOADER_TARGET_SLUG} Databox\ Uploader http://databox-api/incoming-uploads'

databox/api/config/workflows/incoming-uploader-file.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
outputs:
2525
fileId: ${{ steps.accept_file.outputs.fileId }}
2626
assetId: ${{ steps.accept_file.outputs.assetId }}
27+
renditionId: ${{ steps.accept_file.outputs.renditionId }}
2728

2829
uploader_ack:
2930
needs: [ border ]
@@ -37,3 +38,4 @@ jobs:
3738
with:
3839
assetId: ${{ jobs.border.outputs.assetId }}
3940
fileId: ${{ jobs.border.outputs.fileId }}
41+
renditionId: ${{ jobs.border.outputs.renditionId }}

databox/api/src/Api/Processor/PostMessageProcessor.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
namespace App\Api\Processor;
66

77
use Alchemy\AuthBundle\Security\Traits\SecurityAwareTrait;
8-
use Alchemy\CoreBundle\Pusher\PusherManager;
98
use Alchemy\CoreBundle\Util\DoctrineUtil;
109
use ApiPlatform\Metadata\Operation;
1110
use ApiPlatform\State\ProcessorInterface;
@@ -27,7 +26,6 @@ public function __construct(
2726
private readonly EntityManagerInterface $em,
2827
private readonly MessageBusInterface $bus,
2928
private readonly ThreadRepository $threadRepository,
30-
private readonly PusherManager $pusherManager,
3129
private readonly DiscussionPusher $discussionPusher,
3230
) {
3331
}

databox/api/src/Security/Voter/ThreadMessageVoter.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public function supportsType(string $subjectType): bool
2626
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
2727
{
2828
switch ($attribute) {
29+
case self::READ:
30+
return $this->security->isGranted(self::READ, $subject->getThread());
2931
case self::EDIT:
3032
case self::DELETE:
3133
$user = $token->getUser();

databox/api/src/Security/Voter/ThreadVoter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $
3838
return $this->security->isGranted(self::READ, $object);
3939
case self::EDIT:
4040
return $this->security->isGranted(JwtUser::IS_AUTHENTICATED_FULLY)
41-
&& $this->security->isGranted(self::EDIT, $object);
41+
&& $this->security->isGranted(self::READ, $object);
4242
}
4343

4444
return false;

databox/api/src/Service/DiscussionPusher.php

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@
55
use Alchemy\CoreBundle\Pusher\PusherManager;
66
use App\Entity\Discussion\Message;
77
use Symfony\Component\Messenger\MessageBusInterface;
8-
use Symfony\Component\Serializer\SerializerInterface;
98

109
final readonly class DiscussionPusher
1110
{
1211
public function __construct(
1312
private PusherManager $pusherManager,
14-
private SerializerInterface $serializer,
1513
private MessageBusInterface $bus,
1614
) {
1715
}
@@ -23,14 +21,9 @@ public function dispatchMessageToThread(Message $message, bool $removed = false)
2321
$this->bus->dispatch($this->pusherManager->createBusMessage(
2422
'thread-'.$message->getThread()->getKey(),
2523
$event,
26-
$removed ? [
24+
[
2725
'id' => $message->getId(),
28-
] : json_decode($this->serializer->serialize($message, 'json', [
29-
'groups' => [
30-
'_',
31-
Message::GROUP_READ,
32-
],
33-
]), true, 512, JSON_THROW_ON_ERROR),
26+
],
3427
));
3528
}
3629
}

databox/api/src/Workflow/Action/AcceptFileAction.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use App\Border\UploaderClient;
1313
use App\Entity\Core\Asset;
1414
use App\Entity\Core\Collection;
15+
use App\Entity\Core\RenditionDefinition;
1516
use App\Entity\Core\Workspace;
1617
use Doctrine\ORM\EntityManagerInterface;
1718

@@ -28,16 +29,22 @@ public function handle(RunContext $context): void
2829
{
2930
$inputs = $context->getInputs();
3031
$userId = $inputs['userId'];
31-
$assetData = $this->uploaderClient->getAsset($inputs['baseUrl'], $inputs['assetId'], $inputs['token']);
3232
$data = $assetData['data'];
33-
$assetId = $data['targetAsset'] ?? null;
33+
$assetId = $assetData['data']['targetAsset'] ?? null;
34+
$assetData = $this->uploaderClient->getAsset($inputs['baseUrl'], $inputs['assetId'], $inputs['token']);
35+
$renditionDefId = $assetData['data']['targetRendition'] ?? null;
3436

3537
if (null !== $assetId) {
3638
$asset = DoctrineUtil::findStrict($this->em, Asset::class, $assetId);
37-
$uploadToken = $data['uploadToken'];
39+
if ($renditionDefId) {
40+
DoctrineUtil::findStrict($this->em, RenditionDefinition::class, $renditionDefId);
41+
} else {
42+
$uploadToken = $assetData['data']['uploadToken'];
3843

39-
if ($uploadToken !== $asset->getPendingUploadToken()) {
40-
throw new \InvalidArgumentException('Unexpected upload token');
44+
45+
if ($uploadToken !== $asset->getPendingUploadToken()) {
46+
throw new \InvalidArgumentException('Unexpected upload token');
47+
}
4148
}
4249
} else {
4350
$collection = null;
@@ -76,5 +83,6 @@ public function handle(RunContext $context): void
7683
$file = $this->borderManager->acceptFile($inputFile, $asset->getWorkspace());
7784
$context->setOutput('fileId', $file->getId());
7885
$context->setOutput('assetId', $asset->getId());
86+
$context->setOutput('renditionId', $renditionDefId);
7987
}
8088
}

databox/api/src/Workflow/Action/AssignSourceFileToAssetAction.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@
1010
use App\Asset\AssetManager;
1111
use App\Entity\Core\Asset;
1212
use App\Entity\Core\File;
13+
use App\Entity\Core\RenditionDefinition;
14+
use App\Storage\RenditionManager;
1315
use Doctrine\ORM\EntityManagerInterface;
1416

1517
readonly class AssignSourceFileToAssetAction implements ActionInterface
1618
{
1719
public function __construct(
1820
private AssetManager $assetManager,
1921
private EntityManagerInterface $em,
22+
private RenditionManager $renditionManager,
2023
) {
2124
}
2225

@@ -25,11 +28,31 @@ public function handle(RunContext $context): void
2528
$inputs = $context->getInputs();
2629
$fileId = $inputs['fileId'];
2730
$assetId = $inputs['assetId'];
31+
$renditionId = $inputs['renditionId'];
2832

2933
$file = DoctrineUtil::findStrict($this->em, File::class, $fileId);
3034
$asset = DoctrineUtil::findStrict($this->em, Asset::class, $assetId);
3135

32-
$this->assetManager->assignNewAssetSourceFile($asset, $file);
33-
$this->em->flush();
36+
if (null !== $renditionId) {
37+
$renditionDefinition = DoctrineUtil::findStrict($this->em, RenditionDefinition::class, $renditionId);
38+
if ($renditionDefinition->getWorkspaceId() !== $asset->getWorkspaceId()) {
39+
throw new \InvalidArgumentException(sprintf('Rendition "%s" does not belong to the same workspace as the asset "%s"', $renditionDefinition->getId(), $asset->getId()));
40+
}
41+
42+
$this->renditionManager->createOrReplaceRenditionFile(
43+
$asset,
44+
$renditionDefinition,
45+
$file,
46+
buildHash: null,
47+
moduleHashes: [],
48+
substituted: true,
49+
force: true,
50+
projection: false,
51+
);
52+
$this->em->flush();
53+
} else {
54+
$this->assetManager->assignNewAssetSourceFile($asset, $file);
55+
$this->em->flush();
56+
}
3457
}
3558
}

databox/client/src/api/discussion.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ export async function getThreadMessages(
1111
return getHydraCollection(res.data);
1212
}
1313

14+
export async function getMessage(id: string): Promise<ThreadMessage> {
15+
return (await apiClient.get(`/messages/${id}`)).data;
16+
}
17+
1418
export async function postThreadMessage(data: {
1519
threadKey: string;
1620
threadId?: string;

databox/client/src/api/uploader/file.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,51 @@ type FormData = Record<string, any> | undefined;
2525

2626
type UploadedFile = {
2727
data?: Record<string, any>;
28-
file: File;
29-
};
28+
} & FileOrUrl;
29+
30+
export type FileOrUrl =
31+
| {
32+
file: File;
33+
url?: never;
34+
}
35+
| {
36+
file?: never;
37+
url: string;
38+
};
39+
3040
export async function UploadFiles(
3141
files: UploadedFile[],
3242
formData?: FormData
3343
): Promise<void> {
3444
const targetSlug = config.uploaderTargetSlug;
35-
const assets = await promiseConcurrency(
36-
files.map(f => () => UploadFile(targetSlug, f)),
37-
2
38-
);
45+
const assets = (
46+
await promiseConcurrency(
47+
files.map(f => () => UploadFile(targetSlug, f)),
48+
2
49+
)
50+
).filter(a => a) as string[];
3951

40-
await CommitUpload(targetSlug, assets, formData);
52+
if (assets.length > 0) {
53+
await CommitUpload(targetSlug, assets, formData);
54+
}
4155
}
4256

4357
export async function UploadFile(
4458
targetSlug: string,
4559
uploadedFile: UploadedFile
46-
): Promise<string> {
60+
): Promise<string | undefined> {
61+
if (uploadedFile.url) {
62+
await uploaderClient.post(`/downloads`, {
63+
targetSlug,
64+
url: uploadedFile.url,
65+
data: uploadedFile.data,
66+
});
67+
return;
68+
}
69+
4770
const multipart = await multipartUpload(
4871
uploaderClient,
49-
uploadedFile.file,
72+
uploadedFile.file!,
5073
{}
5174
);
5275

0 commit comments

Comments
 (0)