WIP - Add new resources CRUD see #2326

- Improve UI grid
- Allow create resource inside a resource.
- create file, edit resource, and show actions implemented:
When a new CDocument is created the 3 tables are filled:
ResourceNode, ResourceLink, ResourceRights.
- Not yet added to the "classic" document list
- Database migrations from v1 to v2 (requires testing)
pull/2650/head
Julio Montoya 7 years ago
parent 6e36d64abd
commit ac354cd3d5
  1. 8
      app/Migrations/Schema/V200/Version20.php
  2. 51
      config/routes.yaml
  3. 159
      src/CoreBundle/Controller/ResourceController.php
  4. 18
      src/CoreBundle/Form/Type/DocumentType.php
  5. 40
      src/CoreBundle/Repository/ResourceRepository.php
  6. 21
      src/CoreBundle/Resources/views/Document/create.html.twig
  7. 25
      src/CoreBundle/Resources/views/Document/grid.html.twig
  8. 12
      src/CoreBundle/Resources/views/Document/index.html.twig
  9. 35
      src/CoreBundle/Resources/views/Document/show.html.twig
  10. 32
      src/CoreBundle/Resources/views/Document/show_metadata.html.twig
  11. 4
      src/CoreBundle/Resources/views/Document/update.html.twig
  12. 85
      src/CoreBundle/Resources/views/grid.html.twig
  13. 112
      src/CourseBundle/Entity/CDocument.php

@ -625,9 +625,17 @@ class Version20 extends AbstractMigrationChamilo
$this->addSql('ALTER TABLE course_category CHANGE auth_course_child auth_course_child VARCHAR(40) DEFAULT NULL');
// WIP: Document - resource
$this->addSql('ALTER TABLE c_document CHANGE c_id c_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE c_document ADD CONSTRAINT FK_C9FA0CBD91D79BD3 FOREIGN KEY (c_id) REFERENCES course (id)');
$this->addSql('ALTER TABLE c_document ADD resource_node_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE c_document ADD CONSTRAINT FK_C9FA0CBD1BAD783F FOREIGN KEY (resource_node_id) REFERENCES resource_node (id);');
$this->addSql('CREATE UNIQUE INDEX UNIQ_C9FA0CBD1BAD783F ON c_document (resource_node_id)');
$this->addSql('ALTER TABLE c_document CHANGE session_id session_id INT DEFAULT NULL;');
$this->addSql('ALTER TABLE c_document ADD CONSTRAINT FK_C9FA0CBD613FECDF FOREIGN KEY (session_id) REFERENCES session (id)');
$this->addSql('CREATE INDEX IDX_C9FA0CBD613FECDF ON c_document (session_id)');
}
/**

@ -26,18 +26,57 @@ app_document:
type: sylius.resource
app_document_index:
path: /resource/documents/
path: /courses/{course}/resource/documents/
methods: [GET,POST]
defaults:
_controller: app.controller.document:indexAction
_sylius:
template: ChamiloCoreBundle:Document:show.html.twig # Use a custom template.
# repository:
# method: findForStore # Use a custom repository method.
# arguments: [$slug] # Pass the slug from the url to the repository.
template: ChamiloCoreBundle:Document:show.html.twig
app_document_create:
path: /courses/{course}/resource/documents/new
methods: [GET,POST]
defaults:
_controller: app.controller.document:createAction
_sylius:
template: ChamiloCoreBundle:Document:create.html.twig
form: Chamilo\CoreBundle\Form\Type\DocumentType
app_document_create_document:
path: /courses/{course}/resource/documents/new_document
methods: [GET,POST]
defaults:
_controller: app.controller.document:createDocumentAction
_sylius:
template: ChamiloCoreBundle:Document:create.html.twig
form: Chamilo\CoreBundle\Form\Type\DocumentType
app_document_show:
path: /courses/{course}/resource/documents/{id}
methods: [GET]
defaults:
_controller: app.controller.document:showAction
_sylius:
template: ChamiloCoreBundle:Document:show.html.twig
app_document_update:
path: /courses/{course}/resource/documents/{id}/edit
methods: [GET,PUT,PATCH]
defaults:
_controller: app.controller.document:updateAction
_sylius:
template: ChamiloCoreBundle:Document:update.html.twig
form: Chamilo\CoreBundle\Form\Type\DocumentType
app_document_delete:
path: /courses/{course}/resource/documents/{id}
methods: [DELETE]
defaults:
_controller: app.controller.document:deleteAction
# type: sylius.resource_api
#admin_dashboard:
# pattern: /administration/

@ -5,13 +5,16 @@ namespace Chamilo\CoreBundle\Controller;
use APY\DataGridBundle\Grid\Export\CSVExport;
use APY\DataGridBundle\Grid\Export\ExcelExport;
use APY\DataGridBundle\Grid\Grid;
use Chamilo\CoreBundle\Repository\ResourceRepository;
use Chamilo\CoreBundle\Entity\Resource\ResourceRights;
use Chamilo\CourseBundle\Controller\CourseControllerTrait;
use Chamilo\CourseBundle\Controller\CourseControllerInterface;
use Chamilo\CourseBundle\Entity\CDocument;
use Chamilo\CourseBundle\Repository\CDocumentRepository;
use APY\DataGridBundle\Grid\Action\MassAction;
use APY\DataGridBundle\Grid\Action\RowAction;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController as BaseResourceController;
@ -19,6 +22,8 @@ use APY\DataGridBundle\Grid\Source\Entity;
use FOS\RestBundle\View\View;
use Sylius\Component\Resource\ResourceActions;
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Sylius\Component\Resource\Exception\UpdateHandlingException;
/**
* Class ResourceController.
@ -40,7 +45,7 @@ class ResourceController extends BaseResourceController implements CourseControl
{
$source = new Entity('ChamiloCourseBundle:CDocument');
/* @var $grid \APY\DataGridBundle\Grid\Grid */
/* @var Grid $grid */
$grid = $this->get('grid');
/*$tableAlias = $source->getTableAlias();
@ -54,15 +59,20 @@ class ResourceController extends BaseResourceController implements CourseControl
$repository = $this->repository;
$course = $this->getCourse();
$tool = $repository->getTool('document');
$resources = $repository->getResourceByCourse($course, $tool);
$parentId = $request->get('parent');
$parent = null;
if (!empty($parentId)) {
$parent = $this->repository->find($parentId);
}
$resources = $repository->getResourceByCourse($course, $tool, $parent);
$source->setData($resources);
$grid->setSource($source);
//$grid->hideFilters();
$grid->setLimits(5);
$grid->setLimits(20);
//$grid->isReadyForRedirect();
//$grid->setMaxResults(1);
//$grid->setLimits(2);
/*$grid->getColumn('id')->manipulateRenderCell(
@ -75,12 +85,14 @@ class ResourceController extends BaseResourceController implements CourseControl
}
);*/
$courseIdentifier = $course->getCode();
if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
$deleteMassAction = new MassAction(
'Delete',
'chamilo.controller.notebook:deleteMassAction',
true,
array('course' => $request->get('course'))
['course' => $courseIdentifier]
);
$grid->addMassAction($deleteMassAction);
}
@ -92,9 +104,9 @@ class ResourceController extends BaseResourceController implements CourseControl
'app_document_show',
false,
'_self',
['class' => 'btn btn-default']
['class' => 'btn btn-secondary']
);
$myRowAction->setRouteParameters(array('course' => $course, 'id'));
$myRowAction->setRouteParameters(['course' => $courseIdentifier, 'id']);
$grid->addRowAction($myRowAction);
if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
@ -103,9 +115,9 @@ class ResourceController extends BaseResourceController implements CourseControl
'app_document_update',
false,
'_self',
['class' => 'btn btn-info']
['class' => 'btn btn-secondary']
);
$myRowAction->setRouteParameters(array('course' => $course, 'id'));
$myRowAction->setRouteParameters(['course' => $courseIdentifier, 'id']);
$grid->addRowAction($myRowAction);
$myRowAction = new RowAction(
@ -115,47 +127,54 @@ class ResourceController extends BaseResourceController implements CourseControl
'_self',
['class' => 'btn btn-danger', 'form_delete' => true]
);
$myRowAction->setRouteParameters(['course' => $course, 'id']);
$myRowAction->setRouteParameters(['course' => $courseIdentifier, 'id']);
$grid->addRowAction($myRowAction);
}
$grid->addExport(
new CSVExport(
$translation->trans('CSV Export'), 'export', ['course' => $course]
)
);
$grid->addExport(new CSVExport($translation->trans('CSV Export'), 'export', ['course' => $courseIdentifier]));
$grid->addExport(
new ExcelExport(
$translation->trans('Excel Export'),
'export',
['course' => $course]
['course' => $courseIdentifier]
)
);
return $grid->getGridResponse('ChamiloCoreBundle:Document:index.html.twig');
return $grid->getGridResponse('ChamiloCoreBundle:Document:index.html.twig', ['parent_id' => $parentId]);
}
/**
* @param Request $request
* @param string $fileType
*
* @return RedirectResponse|Response
* @return null|\Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function createAction(Request $request): Response
public function createResource(Request $request, $fileType = 'file')
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::CREATE);
/** @var CDocument $newResource */
$newResource = $this->newResourceFactory->create($configuration, $this->factory);
$form = $this->resourceFormFactory->create($configuration, $newResource);
$course = $this->getCourse();
$session = $this->getSession();
$newResource->setCId($course->getId());
$newResource->setCourse($course);
$newResource->c_id = $course->getId();
$newResource->setFiletype($fileType);
$form->setData($newResource);
$parentId = $request->get('parent');
$parent = null;
if (!empty($parentId)) {
/** @var CDocument $parent */
$parent = $this->repository->find($parentId);
}
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
/** @var \Chamilo\CourseBundle\Entity\CDocument $newResource */
/** @var CDocument $newResource */
$newResource = $form->getData();
$event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::CREATE, $configuration, $newResource);
@ -176,9 +195,9 @@ class ResourceController extends BaseResourceController implements CourseControl
$this->stateMachine->apply($configuration, $newResource);
}
//$newResource->setCId($request->get('c_id'));
$sharedType = $form->get('shared')->getData();
$shareList = array();
//$sharedType = $form->get('shared')->getData();
$shareList = [];
$sharedType = 'this_course';
switch ($sharedType) {
case 'this_course':
@ -187,41 +206,37 @@ class ResourceController extends BaseResourceController implements CourseControl
}
// Default Chamilo behaviour:
// Teachers can edit and students can see
$shareList = array(
array(
$shareList = [
[
'sharing' => 'course',
'mask' => ResourceNodeVoter::getReaderMask(),
'role' => ResourceNodeVoter::ROLE_CURRENT_COURSE_STUDENT,
'search' => $course->getId(),
),
array(
],
[
'sharing' => 'course',
'mask' => ResourceNodeVoter::getEditorMask(),
'role' => ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER,
'search' => $course->getId(),
),
);
],
];
break;
case 'shared':
$shareList = $form->get('rights')->getData();
break;
case 'only_me':
$shareList = array(
array(
$shareList = [
[
'sharing' => 'user',
'only_me' => true,
),
);
],
];
break;
}
error_log(print_r($shareList, 1));
/** @var ResourceRepository $repository */
$repository = $this->repository;
$resourceNode = $repository->addResourceNode($newResource, $this->getUser());
$resourceNode = $repository->addResourceNode($newResource, $this->getUser(), $parent);
// Loops all sharing options
foreach ($shareList as $share) {
@ -280,21 +295,39 @@ class ResourceController extends BaseResourceController implements CourseControl
}
$newResource
->setCId($course->getId())
->setPath('/a')
->setFiletype('file')
->setSize('12')
->setCourse($course)
->setFiletype($fileType)
->setSession($session)
//->setTitle($title)
//->setComment($comment)
->setReadonly(false)
->setSessionId(0)
->setResourceNode($resourceNode)
;
$this->repository->add($newResource);
$path = \URLify::filter($newResource->getTitle());
switch ($fileType) {
case 'folder':
$newResource
->setPath($path)
->setSize(0)
;
break;
case 'file':
$newResource
->setPath($path)
->setSize(0)
;
break;
}
$this->repository->add($newResource);
$postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::CREATE, $configuration, $newResource);
$newResource->setId($newResource->getIid());
$this->getDoctrine()->getManager()->persist($newResource);
$this->getDoctrine()->getManager()->flush();
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create($newResource, Response::HTTP_CREATED));
}
@ -302,12 +335,19 @@ class ResourceController extends BaseResourceController implements CourseControl
$this->addFlash('success', 'saved');
//$this->flashHelper->addSuccessFlash($configuration, ResourceActions::CREATE, $newResource);
if ($postEvent->hasResponse()) {
return $postEvent->getResponse();
}
return $this->redirectHandler->redirectToResource($configuration, $newResource);
return $this->redirectToRoute(
'app_document_show',
[
'id' => $newResource->getIid(),
'course' => $course->getCode(),
'parent_id' => $parentId,
]
);
//return $this->redirectHandler->redirectToResource($configuration, $newResource);
}
if (!$configuration->isHtmlRequest()) {
@ -326,6 +366,8 @@ class ResourceController extends BaseResourceController implements CourseControl
'resource' => $newResource,
$this->metadata->getName() => $newResource,
'form' => $form->createView(),
'parent_id' => $parentId,
'file_type' => $fileType
])
->setTemplate($configuration->getTemplate(ResourceActions::CREATE . '.html'))
;
@ -333,6 +375,26 @@ class ResourceController extends BaseResourceController implements CourseControl
return $this->viewHandler->handle($configuration, $view);
}
/**
* @param Request $request
*
* @return Response
*/
public function createAction(Request $request): Response
{
return $this->createResource($request, 'folder');
}
/**
* @param Request $request
*
* @return Response
*/
public function createDocumentAction(Request $request): Response
{
return $this->createResource($request, 'file');
}
/**
* @param Request $request
*
@ -343,7 +405,7 @@ class ResourceController extends BaseResourceController implements CourseControl
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::SHOW);
/** @var AbstractResource $resource */
/** @var CDocument $resource */
$resource = $this->findOr404($configuration);
$resourceNode = $resource->getResourceNode();
@ -383,6 +445,7 @@ class ResourceController extends BaseResourceController implements CourseControl
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::UPDATE);
/** @var CDocument $resource */
$resource = $this->findOr404($configuration);
$resourceNode = $resource->getResourceNode();

@ -3,10 +3,14 @@
namespace Chamilo\CoreBundle\Form\Type;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CourseBundle\Entity\CDocument;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@ -24,7 +28,7 @@ class DocumentType extends AbstractType
$builder
->add('title')
->add('comment', 'ckeditor')
->add(
/*->add(
'shared',
ChoiceType::class,
array(
@ -41,7 +45,7 @@ class DocumentType extends AbstractType
)
->add(
'rights',
'collection',
CollectionType::class,
array(
'entry_type' => ResourceLinkType::class,
'mapped' => false,
@ -49,8 +53,10 @@ class DocumentType extends AbstractType
'by_reference' => false,
'allow_delete' => true,
)
)
)*/
->add('c_id', HiddenType::class)
->add('filetype', HiddenType::class)
/*->add(
'rights',
'collection',
@ -61,7 +67,7 @@ class DocumentType extends AbstractType
)
)*/
//->add('resourceNode', new ResourceNodeType())
->add('save', 'submit');
->add('save', SubmitType::class);
}
/**
@ -70,9 +76,9 @@ class DocumentType extends AbstractType
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
[
'data_class' => CDocument::class,
)
]
);
}

@ -16,6 +16,7 @@ use Chamilo\UserBundle\Entity\User;
use Chamilo\CoreBundle\Entity\Resource\AbstractResource;
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Query\Expr\Join;
use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository;
/**
@ -30,10 +31,15 @@ class ResourceRepository extends EntityRepository
*
* @param AbstractResource $resource
* @param User $creator
* @param AbstractResource $parent
*
* @return ResourceNode
*/
public function addResourceNode(AbstractResource $resource, User $creator): ResourceNode
public function addResourceNode(
AbstractResource $resource,
User $creator,
AbstractResource $parent = null
): ResourceNode
{
$resourceNode = new ResourceNode();
@ -44,6 +50,10 @@ class ResourceRepository extends EntityRepository
->setCreator($creator)
->setTool($tool);
if ($parent !== null) {
$resourceNode->setParent($parent->getResourceNode());
}
$this->getEntityManager()->persist($resourceNode);
$this->getEntityManager()->flush();
@ -126,7 +136,7 @@ class ResourceRepository extends EntityRepository
* @param ResourceNode $resourceNode
* @param array $userList User id list
*/
public function addResourceToUserList(ResourceNode $resourceNode, $userList)
public function addResourceToUserList(ResourceNode $resourceNode, array $userList)
{
$em = $this->getEntityManager();
@ -227,16 +237,24 @@ class ResourceRepository extends EntityRepository
}
/**
* @param Course $course
* @param Course $course
* @param Tool $tool
* @param AbstractResource $parent
*
* @return ResourceLink
*/
public function getResourceByCourse(Course $course, Tool $tool)
public function getResourceByCourse(Course $course, Tool $tool, AbstractResource $parent = null)
{
$query = $this->getEntityManager()->createQueryBuilder()
->select('resource')
->from('Chamilo\CoreBundle\Entity\Resource\ResourceNode', 'node')
->innerJoin('node.links', 'links')
->innerJoin($this->getClassName(), 'resource')
->innerJoin(
$this->getClassName(),
'resource',
Join::WITH,
'resource.course = links.course AND resource.resourceNode = node.id'
)
->where('node.tool = :tool')
->andWhere('links.course = :course')
//->where('link.cId = ?', $course->getId())
@ -247,8 +265,16 @@ class ResourceRepository extends EntityRepository
'tool' => $tool,
'course' => $course,
)
)
->getQuery();
);
if ($parent !== null) {
$query->andWhere('node.parent = :parentId');
$query->setParameter('parentId', $parent->getResourceNode()->getId());
} else {
$query->andWhere('node.parent IS NULL');
}
$query = $query->getQuery();
/*$query = $this->getEntityManager()->createQueryBuilder()
->select('notebook')

@ -174,21 +174,26 @@
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">Create</h3>
<h3 class="box-title">{{'Create'|trans}}</h3>
</div>
{% set create_url = path('app_document_create_document', {'course': course.code, 'parent': parent_id }) %}
{% if file_type == 'folder' %}
{% set create_url = path('app_document_create', {'course': course.code, 'parent': parent_id }) %}
{% endif %}
<form method="post"
action="{{ path('app_document_create', {'c_id': course.id }) }}">
action="{{ create_url }}"
>
<div class="box-body">
{{ form_start(form) }}
{{ form_row(form.title) }}
{{ form_row(form.comment) }}
{{ form_row(form.c_id) }}
{{ form_row(form.shared) }}
<ul id="rights" class="tags"
data-prototype="{{ form_widget(form.rights.vars.prototype)|e }}">
</ul>
{{ form_row(form.filetype) }}
{#{{ form_row(form.shared) }}#}
{#<ul id="rights" class="tags"#}
{#data-prototype="{{ form_widget(form.rights.vars.prototype)|e }}">#}
{#</ul>#}
{{ form_end(form) }}
</div>
</form>

@ -1,15 +1,24 @@
{% extends 'ChamiloCoreBundle::grid.html.twig' %}
{% block grid_column_id_cell %}
<a href="{{ url('app_document_show', {'id': row.getField('id'), 'course': course }) }}">
{{ row.getField('id') }}
</a>
{% endblock %}
{#{% block grid_column_id_cell %}#}
{#<a class="btn btn-secondary" href="{{ url('app_document_show', {'id': row.getField('iid'), 'course': course.code }) }}">#}
{#{{ row.getField('id') }}#}
{#</a>#}
{#{% endblock %}#}
{% block grid_column_title_cell %}
{#<a class="" href="{{ url('app_document_show', {'id': row.getField('iid'), 'course': course.code }) }}">#}
{% block grid_column_name_cell %}
<a href="{{ url('app_document_show', {'id': row.getField('id'), 'course': course }) }}">
{% if row.getField('filetype') == 'folder' %}
<a class="" href="{{ url('app_document_index', {'course': course.code, 'parent' : row.getField('iid') }) }}">
{{ value }}
</a>
{% else %}
{{ value }}
</a>
{#<a class="" href="{{ url('app_document_show', {'id': row.getField('iid'), 'course': course.code, 'parent' => parent }) }}">#}
{#{{ value }}#}
{#</a>#}
{% endif %}
{% endblock %}
{#{% block grid_column_actions_cell %}#}

@ -109,7 +109,6 @@
}
/* Grid Search */
.grid-search {
border: 1px solid #D4E0EE;
padding: 10px;
@ -127,10 +126,15 @@
</style>
{% if is_granted('ROLE_CURRENT_COURSE_TEACHER') %}
<div class="actions">
<a class="btn btn-default"
href="{{ url('app_document_create', { 'c_id': course.id }) }}">
<a class="btn btn-secondary"
href="{{ url('app_document_create', { 'course': course.code, 'parent': parent_id}) }}">
{{ 'Add' | trans }}
</a>
<a class="btn btn-secondary"
href="{{ url('app_document_create_document', { 'course': course.code, 'parent': parent_id }) }}">
{{ 'AddDocument' | trans }}
</a>
</div>
{% endif %}
@ -141,7 +145,5 @@
{# ajax #}
{#{{ grid_search(grid, 'APYDataGridBundle::blocks.html.twig') }}#}
{#{{ grid(grid, 'APYDataGridBundle::blocks_js.jquery.html.twig') }}#}
{% endblock %}

@ -9,39 +9,6 @@
<i class="fa fa-info-circle"></i>
<h3 class="box-title">{{ 'Description' | trans }}</h3>
</div><!-- /.box-header -->
<div class="box-body">
<dl class="dl-horizontal">
<dt>{{ 'Creator' | trans }}</dt>
<dd>{{ resource.resourceNode.creator.username }}</dd>
<dt>{{ 'CreatedAt' | trans }}</dt>
<dd>{{ resource.resourceNode.createdAt | format_datetime }}</dd>
<dt>{{ 'UpdatedAt' | trans }}</dt>
<dd>{{ resource.resourceNode.updatedAt | format_datetime }}</dd>
<dt>{{ 'Shared' | trans }}</dt>
{% for link in resource.resourceNode.links %}
{% if link.private %}
<dd>Only with me</dd>
{% else %}
{% if link.course %}
<dd> {{ 'Course' | trans }} : {{ link.course.title }}
({{ link.course.code }})
</dd>
{% endif %}
{% if link.session %}
<dd> {{ 'Session' | trans }} : {{ link.session.title }}
({{ link.session.title }})
</dd>
{% endif %}
{% endif %}
{% for right in link.rights %}
{{ right.role }} - {{ right.mask }}
{% endfor %}
{% endfor %}
</dl>
</div><!-- /.box-body -->
{% include '@ChamiloCore/Document/show_metadata.html.twig' %}
</div>
{% endblock %}

@ -0,0 +1,32 @@
<div class="box-body">
<dl class="dl-horizontal">
<dt>{{ 'Creator' | trans }}</dt>
<dd>{{ resource.resourceNode.creator.username }}</dd>
<dt>{{ 'CreatedAt' | trans }}</dt>
<dd>{{ resource.resourceNode.createdAt | format_datetime }}</dd>
<dt>{{ 'UpdatedAt' | trans }}</dt>
<dd>{{ resource.resourceNode.updatedAt | format_datetime }}</dd>
<dt>{{ 'Shared' | trans }}</dt>
{% for link in resource.resourceNode.links %}
{% if link.private %}
<dd>Only with me</dd>
{% else %}
{% if link.course %}
<dd> {{ 'Course' | trans }} : {{ link.course.title }}
({{ link.course.code }})
</dd>
{% endif %}
{% if link.session %}
<dd> {{ 'Session' | trans }} : {{ link.session.title }}
({{ link.session.title }})
</dd>
{% endif %}
{% endif %}
{% for right in link.rights %}
{{ right.role }} - {{ right.mask }}
{% endfor %}
{% endfor %}
</dl>
</div>

@ -2,9 +2,9 @@
{% block content %}
<form method="post"
action="{{ path('app_document_update', {'c_id': course.id, 'id' : resource.iid } ) }}">
action="{{ path('app_document_update', {'course': course.code, 'id' : resource.iid } ) }}">
<input type="hidden" name="_method" value="PUT"/>
{{ form_widget(form) }}
</form>
{% include '@ChamiloCore/Document/show_metadata.html.twig' %}
{% endblock %}

@ -1,34 +1,37 @@
{% import "ChamiloThemeBundle:Macros:box.html.twig" as macro %}
{% extends 'APYDataGridBundle::blocks.html.twig' %}
{% block grid_actions %}
<div class="mass-actions">
<div class="btn-group" role="group">
<span class="grid_massactions_helper">
<a class="btn btn-default" href="#"
onclick="return {{ grid.hash }}_markVisible(true);">{{ 'Select visible'|trans }}</a>
<a class="btn btn-default" href="#"
onclick="return {{ grid.hash }}_markVisible(false);">{{ 'Deselect visible'|trans }}</a>
<a class="btn btn-default" href="#"
onclick="return {{ grid.hash }}_markAll(true);">{{ 'Select all'|trans }}</a>
<a class="btn btn-default" href="#"
onclick="return {{ grid.hash }}_markAll(false);">{{ 'Deselect all'|trans }}</a>
<span class="mass-actions-selected"
id="{{ grid.hash }}_mass_action_selected"></span>
</span>
{#<a class="btn btn-secondary" href="#" onclick="return {{ grid.hash }}_markVisible(true);">#}
{#{{ 'Select visible'|trans }}#}
{#</a>#}
{#<a class="btn btn-secondary" href="#" onclick="return {{ grid.hash }}_markVisible(false);">#}
{#{{ 'Deselect visible'|trans }}#}
{#</a>#}
<a class="btn btn-secondary" href="#" onclick="return {{ grid.hash }}_markAll(true);">
{{ 'Select all'|trans }}
</a>
<a class="btn btn-secondary" href="#" onclick="return {{ grid.hash }}_markAll(false);">
{{ 'Deselect all'|trans }}
</a>
<span class="mass-actions-selected" id="{{ grid.hash }}_mass_action_selected"></span>
</div>
{% spaceless %}
<div style="float:right;" class="grid_massactions">
{{ 'Action'|trans }}
<input type="hidden" id="{{ grid.hash }}_mass_action_all"
name="{{ grid.hash }}[{{ constant('APY\\DataGridBundle\\Grid\\Grid::REQUEST_QUERY_MASS_ACTION_ALL_KEYS_SELECTED') }}]"
value="0"/>
name="{{ grid.hash }}[{{ constant('APY\\DataGridBundle\\Grid\\Grid::REQUEST_QUERY_MASS_ACTION_ALL_KEYS_SELECTED') }}]"
value="0"/>
<select name="{{ grid.hash }}[{{ constant('APY\\DataGridBundle\\Grid\\Grid::REQUEST_QUERY_MASS_ACTION') }}]">
<option value="-1"></option>
{% for key, massAction in grid.massActions %}
<option value="{{ key }}">{{ massAction.title|trans }}</option>
{% endfor %}
</select>
<input type="submit" value="{{ 'Submit Action'|trans }}"/>
<input class="btn btn-secondary" type="submit" value="{{ 'Submit Action'|trans }}"/>
</div>
{% endspaceless %}
</div>
@ -39,7 +42,7 @@
{% set actions = column.getActionsToRender(row) %}
<div class="btn-group">
{% for action in actions %}
{% if action.attributes.form_delete is defined and action.attributes.form_delete %}
{% if action.attributes.form_delete is defined and action.attributes.form_delete %}
<div class="btn-group">
<form method="post" action="{{ url(action.route, column.routeParameters(row, action), false) }}">
<input type="hidden" name="_method" value="DELETE" />
@ -49,8 +52,9 @@
</form>
</div>
{% else %}
<a class="btn btn-default"
href="{{ url(action.route, column.routeParameters(row, action), false) }}" target="{{ action.target }}"{% if action.confirm %} onclick="return confirm('{{ action.confirmMessage }}')"{% endif %}{% for name, value in action.attributes %} {{ name }}="{{ value }}" {% endfor %}>
<a class="btn btn-secondary"
href="{{ url(action.route, column.routeParameters(row, action), false) }}"
target="{{ action.target }}"{% if action.confirm %} onclick="return confirm('{{ action.confirmMessage }}')"{% endif %}{% for name, value in action.attributes %} {{ name }}="{{ value }}" {% endfor %}>
{{ action.title|trans }}
</a>
{% endif %}
@ -106,34 +110,25 @@
{% block grid_search %}
{% if grid.isFilterSectionVisible %}
<div class="col-md-2">
<div class="box box-primary">
<div class="box-header">
<h4 class="box-title filter_legend inactive">Filters</h4>
</div>
<div class="box-body">
<form id="{{ grid.hash }}_search"
action="{{ grid.routeUrl }}" method="post">
{% for column in grid.columns %}
{% if column.isFilterable and column.type not in ['actions', 'massaction'] %}
{% set columnTitle = grid.prefixTitle ~ column.title %}
<div class="{{ cycle(['odd', 'even'], loop.index) }}">
<label>{{ columnTitle|trans }}</label>{{ grid_filter(column, grid, false)|raw }}
</div>
{% endif %}
{% endfor %}
<div class="grid-search-action"><input type="submit"
class="grid-search-submit"
value="{{ 'Search'|trans }}"/><input
type="button" class="grid-search-reset"
value="{{ 'Reset'|trans }}"
onclick="return {{ grid.hash }}_reset();"/>
<div class="col-md-2">
{% set searchContent %}
<form id="{{ grid.hash }}_search" action="{{ grid.routeUrl }}" method="post">
{% for column in grid.columns %}
{% if column.isFilterable and column.type not in ['actions', 'massaction'] %}
{% set columnTitle = grid.prefixTitle ~ column.title %}
<div class="{{ cycle(['odd', 'even'], loop.index) }}">
<label>{{ columnTitle|trans }}</label>
{{ grid_filter(column, grid, false)|raw }}
</div>
</form>
{% endif %}
{% endfor %}
<div class="grid-search-action">
<input type="submit" class="grid-search-submit" value="{{ 'Search'|trans }}"/>
<input type="button" class="grid-search-reset" value="{{ 'Reset'|trans }}" onclick="return {{ grid.hash }}_reset();"/>
</div>
</div>
</div>
</form>
{% endset %}
{{ macro.panel('Filters' | trans, searchContent) }}
</div>
{% endif %}
{% endblock grid_search %}

@ -3,9 +3,13 @@
namespace Chamilo\CourseBundle\Entity;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Resource\AbstractResource;
use Chamilo\CoreBundle\Entity\Resource\ResourceInterface;
use Chamilo\CoreBundle\Entity\Session;
use Doctrine\ORM\Mapping as ORM;
use APY\DataGridBundle\Grid\Mapping as GRID;
use Doctrine\ORM\Event\LifecycleEventArgs;
/**
* CDocument.
@ -16,6 +20,8 @@ use Doctrine\ORM\Mapping as ORM;
* @ORM\Index(name="course", columns={"c_id"})
* }
* )
* @GRID\Source(columns="iid, id, title, filetype", filterable=false)
*
* @ORM\Entity(repositoryClass="Chamilo\CourseBundle\Repository\CDocumentRepository")
*/
class CDocument extends AbstractResource implements ResourceInterface
@ -36,13 +42,6 @@ class CDocument extends AbstractResource implements ResourceInterface
*/
protected $id;
/**
* @var int
*
* @ORM\Column(name="c_id", type="integer")
*/
protected $cId;
/**
* @var string
*
@ -86,11 +85,16 @@ class CDocument extends AbstractResource implements ResourceInterface
protected $readonly;
/**
* @var int
*
* @ORM\Column(name="session_id", type="integer", nullable=false)
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", cascade={"persist"})
* @ORM\JoinColumn(name="c_id", referencedColumnName="id")
*/
protected $sessionId;
protected $course;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Session", cascade={"persist"})
* @ORM\JoinColumn(name="session_id", referencedColumnName="id")
*/
protected $session;
/**
* CDocument constructor.
@ -244,83 +248,90 @@ class CDocument extends AbstractResource implements ResourceInterface
}
/**
* Set sessionId.
* Set id.
*
* @param int $sessionId
* @param int $id
*
* @return CDocument
*/
public function setSessionId($sessionId)
public function setId($id)
{
$this->sessionId = $sessionId;
$this->id = $id;
return $this;
}
/**
* Get sessionId.
* Get id.
*
* @return int
*/
public function getSessionId()
public function getId()
{
return $this->sessionId;
return $this->id;
}
/**
* Set id.
*
* @param int $id
* @return Course
*/
public function getCourse(): Course
{
return $this->course;
}
/**
* @param Course $course
*
* @return CDocument
*/
public function setId($id)
public function setCourse($course)
{
$this->id = $id;
$this->course = $course;
return $this;
}
/**
* Get id.
*
* @return int
*/
public function getId()
public function getIid()
{
return $this->id;
return $this->iid;
}
/**
* Set cId.
*
* @param int $cId
*
* @return CDocument
* @return Session
*/
public function setCId($cId)
public function getSession()
{
$this->cId = $cId;
return $this;
return $this->session;
}
/**
* Get cId.
* @param Session $session
*
* @return int
* @return CDocument
*/
public function getCId()
public function setSession($session)
{
return $this->cId;
$this->session = $session;
return $this;
}
/**
* @return int
* @ORM\PostPersist()
*
* @param LifecycleEventArgs $args
*
*/
public function getIid()
public function postPersist(LifecycleEventArgs $args)
{
return $this->iid;
// Update id with iid value
$em = $args->getEntityManager();
$this->setId($this->iid);
$em->persist($this);
$em->flush($this);
}
// Resource classes
@ -340,22 +351,7 @@ class CDocument extends AbstractResource implements ResourceInterface
return 'document';
}
public function getName()
{
}
public function name()
{
}
public function isName()
{
}
public function hasName() {
}
public function __get($a) {
}
}

Loading…
Cancel
Save