-
Notifications
You must be signed in to change notification settings - Fork 486
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Documents: Add support for URL-specific document variations - refs #5956
- Loading branch information
1 parent
c0930e7
commit 130b5cc
Showing
11 changed files
with
544 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
<template> | ||
<div class="p-4 space-y-8"> | ||
<SectionHeader :title="t('Add File Variation')"> | ||
<BaseButton | ||
:label="t('Back to Documents')" | ||
icon="back" | ||
type="gray" | ||
@click="goBack" | ||
/> | ||
</SectionHeader> | ||
|
||
<div v-if="originalFile" class="bg-gray-100 p-4 rounded-md shadow-md"> | ||
<h3 class="text-lg font-semibold">{{ t('Original File') }}</h3> | ||
<p><strong>{{ t('Title:') }}</strong> {{ originalFile.originalName }}</p> | ||
<p><strong>{{ t('Format:') }}</strong> {{ originalFile.mimeType }}</p> | ||
<p><strong>{{ t('Size:') }}</strong> {{ prettyBytes(originalFile.size) }}</p> | ||
</div> | ||
|
||
<div class="space-y-6"> | ||
<h3 class="text-xl font-bold">{{ t('Upload New Variation') }}</h3> | ||
|
||
<form @submit.prevent="uploadVariation" class="flex flex-col space-y-4"> | ||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | ||
<BaseFileUpload | ||
@file-selected="onFileSelected" | ||
:label="t('Choose file')" | ||
accept=".pdf,.html,.docx,.mp4" | ||
required | ||
class="w-full" | ||
/> | ||
|
||
<Dropdown | ||
v-model="selectedAccessUrl" | ||
:options="accessUrls" | ||
optionLabel="url" | ||
optionValue="id" | ||
placeholder="Select a URL" | ||
class="w-full" | ||
/> | ||
</div> | ||
|
||
<div class="flex justify-end"> | ||
<BaseButton | ||
:label="t('Upload')" | ||
icon="file-upload" | ||
type="success" | ||
:disabled="!file" | ||
@click="uploadVariant(file, originalFile?.resourceNode?.id, selectedAccessUrl)" | ||
/> | ||
</div> | ||
</form> | ||
</div> | ||
|
||
<div> | ||
<h3 class="text-xl font-bold mb-4">{{ t('Current Variations') }}</h3> | ||
<DataTable :value="variations" class="w-full"> | ||
<Column field="title" :header="t('Title')" /> | ||
<Column field="mimeType" :header="t('Format')" /> | ||
<Column field="size" :header="t('Size')"> | ||
<template #body="slotProps"> | ||
{{ prettyBytes(slotProps.data.size) }} | ||
</template> | ||
</Column> | ||
<Column field="updatedAt" :header="t('Updated At')" /> | ||
<Column field="url" :header="t('URL')"> | ||
<template #body="slotProps"> | ||
<a | ||
:href="slotProps.data.path" | ||
target="_blank" | ||
class="text-blue-500 hover:underline" | ||
> | ||
{{ t('View') }} | ||
</a> | ||
</template> | ||
</Column> | ||
<Column field="creator" :header="t('Creator')" /> | ||
</DataTable> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import { ref, onMounted, computed } from "vue" | ||
import { useRoute, useRouter } from 'vue-router' | ||
import { useI18n } from 'vue-i18n' | ||
import axios from 'axios' | ||
import DataTable from 'primevue/datatable' | ||
import Column from 'primevue/column' | ||
import SectionHeader from "../../components/layout/SectionHeader.vue" | ||
import BaseButton from "../../components/basecomponents/BaseButton.vue" | ||
import BaseFileUpload from "../../components/basecomponents/BaseFileUpload.vue" | ||
import prettyBytes from 'pretty-bytes' | ||
import { useStore } from "vuex" | ||
import { useCidReq } from "../../composables/cidReq" | ||
const store = useStore() | ||
const route = useRoute() | ||
const router = useRouter() | ||
const { t } = useI18n() | ||
const { cid, sid, gid } = useCidReq() | ||
const file = ref(null) | ||
const variations = ref([]) | ||
const originalFile = ref(null) | ||
const resourceFileId = route.params.resourceFileId; | ||
const selectedAccessUrl = ref(null) | ||
const accessUrls = ref([]) | ||
onMounted(async () => { | ||
await fetchOriginalFile() | ||
await fetchVariations() | ||
await fetchAccessUrls() | ||
}) | ||
async function fetchVariations() { | ||
if (!originalFile.value?.resourceNode?.id) { | ||
console.error('ResourceNodeId is undefined. Cannot fetch variations.') | ||
return | ||
} | ||
try { | ||
const resourceNodeId = originalFile.value.resourceNode.id | ||
const response = await axios.get(`/r/resource_files/${resourceNodeId}/variants`) | ||
variations.value = response.data | ||
} catch (error) { | ||
console.error('Error fetching variations:', error) | ||
} | ||
} | ||
async function fetchAccessUrls() { | ||
try { | ||
const response = await axios.get('/api/access_urls') | ||
if (Array.isArray(response.data['hydra:member'])) { | ||
const currentAccessUrlId = window.access_url_id | ||
accessUrls.value = response.data['hydra:member'].filter( | ||
(url) => url.id !== currentAccessUrlId | ||
) | ||
} else { | ||
accessUrls.value = [] | ||
} | ||
} catch (error) { | ||
console.error('Error fetching access URLs:', error) | ||
accessUrls.value = [] | ||
} | ||
} | ||
async function fetchOriginalFile() { | ||
try { | ||
const response = await axios.get(`/api/resource_files/${resourceFileId}`) | ||
originalFile.value = response.data | ||
} catch (error) { | ||
console.error('Error fetching original file:', error) | ||
} | ||
} | ||
async function uploadVariant(file, resourceNodeId, accessUrlId) { | ||
if (!resourceNodeId) { | ||
console.error('ResourceNodeId is undefined. Check originalFile:', originalFile.value) | ||
return | ||
} | ||
const formData = new FormData() | ||
formData.append('file', file) | ||
formData.append('resourceNodeId', resourceNodeId) | ||
if (accessUrlId) { | ||
formData.append('accessUrlId', accessUrlId) | ||
} | ||
try { | ||
const response = await axios.post('/api/resource_files/add_variant', formData) | ||
console.log('Variant uploaded or updated successfully:', response.data) | ||
await fetchVariations() | ||
file.value = null | ||
selectedAccessUrl.value = null | ||
} catch (error) { | ||
console.error('Error uploading variant:', error) | ||
} | ||
} | ||
function onFileSelected(selectedFile) { | ||
file.value = selectedFile | ||
} | ||
function goBack() { | ||
let queryParams = { cid, sid, gid } | ||
router.push({ name: "DocumentsList", params: { node: parent.id }, query: queryParams }) | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
src/CoreBundle/Controller/AddVariantResourceFileAction.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
namespace Chamilo\CoreBundle\Controller; | ||
|
||
use Chamilo\CoreBundle\Entity\ResourceFile; | ||
use Chamilo\CoreBundle\Entity\ResourceNode; | ||
use Chamilo\CoreBundle\Entity\AccessUrl; | ||
use Doctrine\ORM\EntityManagerInterface; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; | ||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||
|
||
class AddVariantResourceFileAction | ||
{ | ||
public function __invoke(Request $request, EntityManagerInterface $em): ResourceFile | ||
{ | ||
$uploadedFile = $request->files->get('file'); | ||
if (!$uploadedFile) { | ||
throw new BadRequestHttpException('"file" is required'); | ||
} | ||
|
||
$resourceNodeId = $request->get('resourceNodeId'); | ||
if (!$resourceNodeId) { | ||
throw new BadRequestHttpException('"resourceNodeId" is required'); | ||
} | ||
|
||
$resourceNode = $em->getRepository(ResourceNode::class)->find($resourceNodeId); | ||
if (!$resourceNode) { | ||
throw new NotFoundHttpException('ResourceNode not found'); | ||
} | ||
|
||
$accessUrlId = $request->get('accessUrlId'); | ||
$accessUrl = null; | ||
if ($accessUrlId) { | ||
$accessUrl = $em->getRepository(AccessUrl::class)->find($accessUrlId); | ||
if (!$accessUrl) { | ||
throw new NotFoundHttpException('AccessUrl not found'); | ||
} | ||
} | ||
|
||
$existingResourceFile = $em->getRepository(ResourceFile::class)->findOneBy([ | ||
'resourceNode' => $resourceNode, | ||
'accessUrl' => $accessUrl, | ||
]); | ||
|
||
if ($existingResourceFile) { | ||
$existingResourceFile->setTitle($uploadedFile->getClientOriginalName()); | ||
$existingResourceFile->setFile($uploadedFile); | ||
$existingResourceFile->setUpdatedAt(\DateTime::createFromImmutable(new \DateTimeImmutable())); | ||
$resourceFile = $existingResourceFile; | ||
} else { | ||
$resourceFile = new ResourceFile(); | ||
$resourceFile->setTitle($uploadedFile->getClientOriginalName()); | ||
$resourceFile->setFile($uploadedFile); | ||
$resourceFile->setResourceNode($resourceNode); | ||
|
||
if ($accessUrl) { | ||
$resourceFile->setAccessUrl($accessUrl); | ||
} | ||
} | ||
|
||
$em->persist($resourceFile); | ||
$em->flush(); | ||
|
||
return $resourceFile; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.