Add create html file in documents

pull/3346/head
Julio Montoya 4 years ago
parent 0747f23abc
commit 95d679d00b
  1. 17
      assets/vue/components/Toolbar.vue
  2. 100
      assets/vue/components/documents/FormNewDocument.vue
  3. 5
      assets/vue/mixins/ListMixin.js
  4. 5
      assets/vue/router/documents.js
  5. 2
      assets/vue/views/documents/CreateFile.vue
  6. 1
      assets/vue/views/documents/List.vue
  7. 23
      assets/vue/views/documents/Show.vue
  8. 56
      assets/vue/views/documents/Upload.vue
  9. 37
      src/CoreBundle/Controller/CreateResourceNodeFileAction.php
  10. 1
      src/CoreBundle/Entity/AbstractResource.php
  11. 17
      src/CoreBundle/Entity/Listener/ResourceListener.php
  12. 1
      src/CoreBundle/Entity/ResourceFile.php
  13. 4
      src/CourseBundle/Entity/CDocument.php

@ -53,10 +53,14 @@
</v-btn>
<v-btn v-if="handleAddDocument" color="primary" rounded @click="addDocument">
<v-icon left>mdi-cloud-upload</v-icon>File upload
<v-icon left>mdi-cloud-upload</v-icon>New document
</v-btn>
<v-btn v-if="handleUploadDocument" color="primary" rounded @click="uploadDocument">
<v-icon left>mdi-cloud-upload</v-icon>File upload
</v-btn>
</div>
<ConfirmDelete
v-if="handleDelete"
:visible="confirmDelete"
@ -108,7 +112,10 @@ export default {
type: Function,
required: false
},
handleUploadDocument: {
type: Function,
required: false
},
title: {
type: String,
required: false
@ -135,7 +142,11 @@ export default {
this.handleAddDocument();
}
},
uploadDocument() {
if (this.uploadDocument) {
this.handleUploadDocument();
}
},
editItem() {
if (this.handleEdit) {
this.handleEdit();

@ -0,0 +1,100 @@
<template>
<v-form>
<v-container fluid>
<v-row>
<v-col cols="12" sm="6" md="6">
<v-text-field
v-model="item.title"
:error-messages="titleErrors"
:label="$t('Title')"
required
@input="$v.item.title.$touch()"
@blur="$v.item.title.$touch()"
/>
<v-textarea
v-model="item.content"
:label="$t('Text')"
value=""
></v-textarea>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
import has from 'lodash/has';
import { validationMixin } from 'vuelidate';
import { required } from 'vuelidate/lib/validators';
import { mapActions } from 'vuex';
import { mapFields } from 'vuex-map-fields';
export default {
name: 'DocumentsForm',
mixins: [validationMixin],
props: {
values: {
type: Object,
required: true
},
errors: {
type: Object,
default: () => {}
},
initialValues: {
type: Object,
default: () => {}
},
},
created () {
},
data() {
return {
title: null,
content: null,
parentResourceNodeId: null,
};
},
computed: {
// eslint-disable-next-line
item() {
return this.initialValues || this.values;
},
titleErrors() {
const errors = [];
if (!this.$v.item.title.$dirty) return errors;
has(this.violations, 'title') && errors.push(this.violations.title);
!this.$v.item.title.required && errors.push(this.$t('Field is required'));
return errors;
},
contentErrors() {
const errors = [];
if (!this.$v.item.content.$dirty) return errors;
has(this.violations, 'content') && errors.push(this.violations.content);
!this.$v.item.content.required && errors.push(this.$t('Field is required'));
return errors;
},
violations() {
return this.errors || {};
}
},
methods: {
},
validations: {
item: {
title: {
required,
},
content: {
required,
},
parentResourceNodeId: {
},
}
}
};
</script>

@ -82,6 +82,11 @@ export default {
this.$router.push({ name: `${this.$options.servicePrefix}CreateFile` , query: folderParams});
},
uploadDocumentHandler() {
let folderParams = this.$route.query;
this.$router.push({ name: `${this.$options.servicePrefix}UploadFile` , query: folderParams});
},
showHandler(item) {
let folderParams = this.$route.query;
folderParams['id'] = item['@id'];

@ -20,6 +20,11 @@ export default {
path: 'new_file',
component: () => import('../views/documents/CreateFile')
},
{
name: 'DocumentsUploadFile',
path: 'upload',
component: () => import('../views/documents/Upload')
},
{
name: 'DocumentsUpdate',
path: ':id/edit',

@ -9,7 +9,7 @@
<script>
import { mapActions } from 'vuex';
import { createHelpers } from 'vuex-map-fields';
import DocumentsForm from '../../components/documents/FormUpload';
import DocumentsForm from '../../components/documents/FormNewDocument';
import Loading from '../../components/Loading';
import Toolbar from '../../components/Toolbar';
import CreateMixin from '../../mixins/CreateMixin';

@ -3,6 +3,7 @@
<Toolbar
:handle-add="addHandler"
:handle-add-document="addDocumentHandler"
:handle-upload-document="uploadDocumentHandler"
/>
<v-container grid-list-xl fluid>
<v-layout row wrap>

@ -13,18 +13,17 @@
<div v-if="item" class="table-documents-show">
<div v-if="item['resourceLinkList']">
<ul>
<li
v-for="link in item['resourceLinkList']"
>
Status: {{ link.visibilityName }}
<div v-if="link['course']">
Course: {{ link.course.resourceNode.title }}
</div>
<div v-if="link['session']">
Session: {{ link.session.resourceNode.title }}
</div>
</li>
<li
v-for="link in item['resourceLinkList']"
>
Status: {{ link.visibilityName }}
<div v-if="link['course']">
Course: {{ link.course.resourceNode.title }}
</div>
<div v-if="link['session']">
Session: {{ link.session.resourceNode.title }}
</div>
</li>
</ul>
</div>
<v-simple-table>

@ -0,0 +1,56 @@
<template>
<div>
<Toolbar :handle-submit="onSendForm" :handle-reset="resetForm"></Toolbar>
<DocumentsForm ref="createForm" :values="item" :errors="violations" />
<Loading :visible="isLoading" />
</div>
</template>
<script>
import { mapActions } from 'vuex';
import { createHelpers } from 'vuex-map-fields';
import DocumentsForm from '../../components/documents/FormUpload';
import Loading from '../../components/Loading';
import Toolbar from '../../components/Toolbar';
import CreateMixin from '../../mixins/CreateMixin';
const servicePrefix = 'Documents';
const { mapFields } = createHelpers({
getterType: 'documents/getField',
mutationType: 'documents/updateField'
});
export default {
name: 'DocumentsCreate',
servicePrefix,
mixins: [CreateMixin],
components: {
Loading,
Toolbar,
DocumentsForm
},
data() {
return {
item: {
filetype: 'file',
parentResourceNodeId: null,
resourceLinkList: null
},
};
},
computed: {
...mapFields(['error', 'isLoading', 'created', 'violations'])
},
created() {
this.item.parentResourceNodeId = this.$route.params.node;
this.item.resourceLinkList = JSON.stringify([{
c_id: this.$route.query.cid,
visibility: 2,
}]);
},
methods: {
...mapActions('documents', ['create', 'reset'])
}
};
</script>

@ -16,14 +16,37 @@ class CreateResourceNodeFileAction
$document = new CDocument();
$title = $request->get('title');
if ('file' === $request->get('filetype') && $request->files->count() > 0) {
/** @var UploadedFile $uploadedFile */
$uploadedFile = $request->files->get('uploadFile');
if (!$uploadedFile) {
throw new BadRequestHttpException('"uploadFile" is required');
if ('file' === $request->get('filetype')) {
$fileParsed = false;
// File upload
if ($request->files->count() > 0) {
/** @var UploadedFile $uploadedFile */
$uploadedFile = $request->files->get('uploadFile');
if (!$uploadedFile) {
throw new BadRequestHttpException('"uploadFile" is required');
}
$title = $uploadedFile->getClientOriginalName();
$document->setUploadFile($uploadedFile);
$fileParsed = true;
}
// Get data in content and create a HTML file
if (false === $fileParsed && $request->request->has('content')) {
$content = $request->request->get('content');
$title .= '.html';
$handle = tmpfile();
fwrite($handle, $content);
$meta = stream_get_meta_data($handle);
$file = new UploadedFile($meta['uri'], $title, 'text/html', null, true);
$document->setUploadFile($file);
$fileParsed = true;
}
if (false === $fileParsed) {
throw new \InvalidArgumentException(
'filetype was set to "file" but not upload found'
);
}
$title = $uploadedFile->getClientOriginalName();
$document->setUploadFile($uploadedFile);
}
if ($request->request->has('resourceLinkList')) {

@ -47,7 +47,6 @@ abstract class AbstractResource
/**
* @ApiProperty(iri="http://schema.org/image")
* @Groups({"resource_node:read", "resource_node:write", "document:read", "document:write"})
*/
public $uploadFile;

@ -146,8 +146,21 @@ class ResourceListener
}
if ($resource->hasUploadFile()) {
// @todo check CreateResourceNodeFileAction
/** @var File $uploadedFile */
$uploadedFile = $request->getCurrentRequest()->files->get('uploadFile');
if (empty($uploadedFile)) {
$content = $request->getCurrentRequest()->get('content');
$title = $resourceName.'.html';
$handle = tmpfile();
fwrite($handle, $content);
$meta = stream_get_meta_data($handle);
$uploadedFile = new UploadedFile($meta['uri'], $title, 'text/html', null, true);
}
// File upload
if ($uploadedFile instanceof UploadedFile) {
$resourceFile = new ResourceFile();
$resourceFile->setName($uploadedFile->getFilename());
@ -170,7 +183,7 @@ class ResourceListener
if ($course) {
$resourceLink->setCourse($course);
} else {
throw new \InvalidArgumentException('Course #'.$link['c_id'].' does not exists');
throw new \InvalidArgumentException(sprintf('Course #%s does not exists', $link['c_id']));
}
}
@ -179,7 +192,7 @@ class ResourceListener
if ($session) {
$resourceLink->setSession($session);
} else {
throw new \InvalidArgumentException('Session #'.$link['session_id'].' does not exists');
throw new \InvalidArgumentException(sprintf('Session #%s does not exists', $link['session_id']));
}
}

@ -167,6 +167,7 @@ class ResourceFile
public function __construct()
{
$this->metadata = [];
$this->dimensions = [];
}
public function __toString(): string

@ -8,7 +8,6 @@ use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use APY\DataGridBundle\Grid\Mapping as GRID;
use Chamilo\CoreBundle\Controller\CreateResourceNodeFileAction;
use Chamilo\CoreBundle\Entity\AbstractResource;
use Chamilo\CoreBundle\Entity\Course;
@ -48,6 +47,9 @@ use Symfony\Component\Serializer\Annotation\Groups;
* "comment"={
* "type"="string",
* },
* "content"={
* "type"="string",
* },
* "uploadFile"={
* "type"="string",
* "format"="binary"

Loading…
Cancel
Save