Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/CoreBundle/Controller/Admin/AdminController.php
pull/5677/head
Angel Fernando Quiroz Campos 2 years ago
commit cc379ffd20
No known key found for this signature in database
GPG Key ID: B284841AE3E562CD
  1. 55
      src/CoreBundle/Controller/Admin/AdminController.php
  2. 3
      src/CoreBundle/Entity/ResourceFile.php
  3. 81
      src/CoreBundle/Repository/ResourceFileRepository.php
  4. 134
      src/CoreBundle/Resources/views/Admin/files_info.html.twig

@ -7,7 +7,7 @@ declare(strict_types=1);
namespace Chamilo\CoreBundle\Controller\Admin;
use Chamilo\CoreBundle\Controller\BaseController;
use Chamilo\CoreBundle\Entity\ResourceFile;
use Chamilo\CoreBundle\Repository\ResourceFileRepository;
use Chamilo\CoreBundle\Repository\ResourceNodeRepository;
use Chamilo\CoreBundle\ServiceHelper\AccessUrlHelper;
use Chamilo\CoreBundle\Settings\SettingsManager;
@ -50,58 +50,15 @@ class AdminController extends BaseController
#[IsGranted('ROLE_ADMIN')]
#[Route('/files_info', name: 'admin_files_info', methods: ['GET'])]
public function listFilesInfo(Request $request): Response
public function listFilesInfo(Request $request, ResourceFileRepository $resourceFileRepository): Response
{
$page = $request->query->getInt('page', 1);
$search = $request->query->get('search', '');
$offset = ($page - 1) * self::ITEMS_PER_PAGE;
$queryBuilder = $this->entityManager->getRepository(ResourceFile::class)->createQueryBuilder('rf')
->leftJoin('rf.resourceNode', 'rn')
->leftJoin('rn.resourceLinks', 'rl')
->leftJoin('rl.course', 'c')
->leftJoin('rl.user', 'u')
->addSelect('rn', 'rl', 'c', 'u')
;
if ($search) {
$queryBuilder->where('rf.title LIKE :search')
->orWhere('rf.originalName LIKE :search')
->orWhere('c.title LIKE :search')
->orWhere('u.username LIKE :search')
->orWhere('rn.uuid LIKE :search')
->setParameter('search', '%'.$search.'%')
;
}
$queryBuilder->orderBy('rf.id', 'DESC')
->setFirstResult($offset)
->setMaxResults(self::ITEMS_PER_PAGE)
;
$files = $queryBuilder->getQuery()->getResult();
$totalItemsQuery = $this->entityManager->getRepository(ResourceFile::class)
->createQueryBuilder('rf')
->leftJoin('rf.resourceNode', 'rn')
->leftJoin('rn.resourceLinks', 'rl')
->leftJoin('rl.course', 'c')
->leftJoin('rl.user', 'u')
->select('COUNT(rf.id)')
;
if ($search) {
$totalItemsQuery->where('rf.title LIKE :search')
->orWhere('rf.originalName LIKE :search')
->orWhere('c.title LIKE :search')
->orWhere('u.username LIKE :search')
->orWhere('rn.uuid LIKE :search')
->setParameter('search', '%'.$search.'%')
;
}
$totalItems = $totalItemsQuery->getQuery()->getSingleScalarResult();
$totalPages = ceil($totalItems / self::ITEMS_PER_PAGE);
$files = $resourceFileRepository->searchFiles($search, $offset, self::ITEMS_PER_PAGE);
$totalItems = $resourceFileRepository->countFiles($search);
$totalPages = $totalItems > 0 ? ceil($totalItems / self::ITEMS_PER_PAGE) : 1;
$fileUrls = [];
$filePaths = [];
@ -114,7 +71,7 @@ class AdminController extends BaseController
$fileUrls[$file->getId()] = null;
$creator = null;
}
$filePaths[$file->getId()] = $this->resourceNodeRepository->getFilename($file);
$filePaths[$file->getId()] = '/upload/resources'.$this->resourceNodeRepository->getFilename($file);
}
return $this->render('@ChamiloCore/Admin/files_info.html.twig', [

@ -15,6 +15,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Serializer\Filter\PropertyFilter;
use Chamilo\CoreBundle\Controller\CreateResourceFileAction;
use Chamilo\CoreBundle\Repository\ResourceFileRepository;
use DateTime;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
@ -74,7 +75,7 @@ use Vich\UploaderBundle\Mapping\Annotation as Vich;
]
)]
#[ORM\Table(name: 'resource_file')]
#[ORM\Entity]
#[ORM\Entity(repositoryClass: ResourceFileRepository::class)]
#[ApiFilter(filterClass: PropertyFilter::class)]
#[ApiFilter(filterClass: SearchFilter::class, properties: ['name' => 'partial'])]
#[ApiFilter(filterClass: OrderFilter::class, properties: ['id', 'name', 'size', 'updatedAt'])]

@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Repository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Chamilo\CoreBundle\Entity\ResourceFile;
class ResourceFileRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, ResourceFile::class);
}
public function searchFiles(string $search, int $offset, int $limit): array
{
$uuid = '';
if (preg_match('/[a-f0-9]{32}|[a-f0-9\-]{36}/i', $search, $matches)) {
$uuid = strtoupper(str_replace('-', '', $matches[0]));
}
$uuidBinary = pack('H*', $uuid);
$queryBuilder = $this->createQueryBuilder('rf')
->leftJoin('rf.resourceNode', 'rn')
->leftJoin('rn.resourceLinks', 'rl')
->leftJoin('rl.course', 'c')
->leftJoin('rl.user', 'u')
->addSelect('rn', 'rl', 'c', 'u');
if ($search) {
$queryBuilder->where('rf.title LIKE :search')
->orWhere('rf.originalName LIKE :search')
->orWhere('c.title LIKE :search')
->orWhere('u.username LIKE :search')
->orWhere('rn.uuid = :uuid')
->setParameter('search', '%' . $search . '%')
->setParameter('uuid', $uuidBinary);
}
$queryBuilder->orderBy('rf.id', 'DESC')
->setFirstResult($offset)
->setMaxResults($limit);
return $queryBuilder->getQuery()->getResult();
}
public function countFiles(string $search): int
{
$uuid = '';
if (preg_match('/[a-f0-9]{32}|[a-f0-9\-]{36}/i', $search, $matches)) {
$uuid = strtoupper(str_replace('-', '', $matches[0]));
}
$uuidBinary = pack('H*', $uuid);
$queryBuilder = $this->createQueryBuilder('rf')
->leftJoin('rf.resourceNode', 'rn')
->leftJoin('rn.resourceLinks', 'rl')
->leftJoin('rl.course', 'c')
->leftJoin('rl.user', 'u')
->select('COUNT(rf.id)');
if ($search) {
$queryBuilder->where('rf.title LIKE :search')
->orWhere('rf.originalName LIKE :search')
->orWhere('c.title LIKE :search')
->orWhere('u.username LIKE :search')
->orWhere('rn.uuid = :uuid')
->setParameter('search', '%' . $search . '%')
->setParameter('uuid', $uuidBinary);
}
return $queryBuilder->getQuery()->getSingleScalarResult();
}
}

@ -9,72 +9,78 @@
<button type="submit" class="btn btn--primary">{{ 'Search'|trans }}</button>
</form>
<table class="data_table">
<thead>
<tr>
<th>{{ 'Title'|trans }}</th>
<th>{{ 'Original Name'|trans }}</th>
<th>{{ 'Course'|trans }}</th>
<th>{{ 'User'|trans }}</th>
<th>{{ 'Actions'|trans }}</th>
</tr>
</thead>
<tbody>
{% for file in files %}
{% if files is empty %}
<p>{{ 'No results found.'|trans }}</p>
{% else %}
<table class="data_table">
<thead>
<tr>
<td>{{ file.title }}</td>
<td>{{ file.originalName }}</td>
<td>
{% if file.resourceNode and file.resourceNode.resourceLinks|length > 0 %}
{{ file.resourceNode.resourceLinks|first.course.title ?? 'N/A' }}
{% else %}
{{ 'N/A'|trans }}
{% endif %}
</td>
<td>
{% if file.resourceNode and file.resourceNode.resourceLinks|length > 0 %}
{{ file.resourceNode.resourceLinks|first.user.username ?? 'N/A' }}
{% elseif file.resourceNode and file.resourceNode.creator %}
{{ file.resourceNode.creator.username ?? 'N/A' }}
{% else %}
{{ 'N/A'|trans }}
{% endif %}
</td>
<td>
<a href="#" class="open-modal"
data-title="{{ file.title }}"
data-mime-type="{{ file.mimeType }}"
data-original-name="{{ file.originalName }}"
data-size="{{ file.size }}"
data-course="{% if file.resourceNode and file.resourceNode.resourceLinks|length > 0 %}{{ file.resourceNode.resourceLinks|first.course.title ?? 'N/A' }}{% else %}{{ 'N/A'|trans }}{% endif %}"
data-user="{% if file.resourceNode and file.resourceNode.resourceLinks|length > 0 %}{{ file.resourceNode.resourceLinks|first.user.username ?? 'N/A' }}{% elseif file.resourceNode and file.resourceNode.creator %}{{ file.resourceNode.creator.username ?? 'N/A' }}{% else %}{{ 'N/A'|trans }}{% endif %}"
data-file-url="{{ fileUrls[file.id] }}"
data-file-path="{{ filePaths[file.id] }}">
{{ 'View'|trans }}
</a>
</td>
<th>{{ 'Title'|trans }}</th>
<th>{{ 'Original Name'|trans }}</th>
<th>{{ 'Course'|trans }}</th>
<th>{{ 'User'|trans }}</th>
<th>{{ 'Actions'|trans }}</th>
</tr>
{% endfor %}
</tbody>
</table>
</thead>
<tbody>
{% for file in files %}
<tr>
<td>{{ file.title }}</td>
<td>{{ file.originalName }}</td>
<td>
{% if file.resourceNode and file.resourceNode.resourceLinks|length > 0 %}
{{ file.resourceNode.resourceLinks|first.course.title ?? 'N/A' }}
{% else %}
{{ 'N/A'|trans }}
{% endif %}
</td>
<td>
{% if file.resourceNode and file.resourceNode.resourceLinks|length > 0 %}
{{ file.resourceNode.resourceLinks|first.user.username ?? 'N/A' }}
{% elseif file.resourceNode and file.resourceNode.creator %}
{{ file.resourceNode.creator.username ?? 'N/A' }}
{% else %}
{{ 'N/A'|trans }}
{% endif %}
</td>
<td>
<a href="#" class="open-modal"
data-title="{{ file.title }}"
data-mime-type="{{ file.mimeType }}"
data-original-name="{{ file.originalName }}"
data-size="{{ file.size }}"
data-course="{% if file.resourceNode and file.resourceNode.resourceLinks|length > 0 %}{{ file.resourceNode.resourceLinks|first.course.title ?? 'N/A' }}{% else %}{{ 'N/A'|trans }}{% endif %}"
data-user="{% if file.resourceNode and file.resourceNode.resourceLinks|length > 0 %}{{ file.resourceNode.resourceLinks|first.user.username ?? 'N/A' }}{% elseif file.resourceNode and file.resourceNode.creator %}{{ file.resourceNode.creator.username ?? 'N/A' }}{% else %}{{ 'N/A'|trans }}{% endif %}"
data-file-url="{{ fileUrls[file.id] }}"
data-file-path="{{ filePaths[file.id] }}"
data-resource-node-id="{{ file.resourceNode ? file.resourceNode.id : 'N/A' }}"
data-resource-file-id="{{ file.id }}">
{{ 'View'|trans }}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="pagination">
{% if currentPage > 1 %}
<a href="{{ path('admin_files_info', {'page': currentPage - 1, 'search': search}) }}">&laquo; {{ 'Previous'|trans }}</a>
{% endif %}
{% for i in max(1, currentPage - 2)..min(totalPages, currentPage + 2) %}
{% if i == currentPage %}
<span>{{ i }}</span>
{% else %}
<a href="{{ path('admin_files_info', {'page': i, 'search': search}) }}">{{ i }}</a>
<div class="pagination">
{% if currentPage > 1 %}
<a href="{{ path('admin_files_info', {'page': currentPage - 1, 'search': search}) }}">&laquo; {{ 'Previous'|trans }}</a>
{% endif %}
{% endfor %}
{% if currentPage < totalPages %}
<a href="{{ path('admin_files_info', {'page': currentPage + 1, 'search': search}) }}">{{ 'Next'|trans }} &raquo;</a>
{% endif %}
</div>
{% for i in max(1, currentPage - 2)..min(totalPages, currentPage + 2) %}
{% if i == currentPage %}
<span>{{ i }}</span>
{% else %}
<a href="{{ path('admin_files_info', {'page': i, 'search': search}) }}">{{ i }}</a>
{% endif %}
{% endfor %}
{% if currentPage < totalPages %}
<a href="{{ path('admin_files_info', {'page': currentPage + 1, 'search': search}) }}">{{ 'Next'|trans }} &raquo;</a>
{% endif %}
</div>
{% endif %}
<!-- Modal -->
<div id="fileInfoModal" class="modal">
@ -87,6 +93,8 @@
<p class="mb-3"><strong>{{ 'Size:'|trans }}</strong> <span id="file-size"></span></p>
<p class="mb-3"><strong>{{ 'Course:'|trans }}</strong> <span id="file-course"></span></p>
<p class="mb-3"><strong>{{ 'User:'|trans }}</strong> <span id="file-user"></span></p>
<p class="mb-3"><strong>{{ 'Resource Node ID:'|trans }}</strong> <span id="resource-node-id"></span></p>
<p class="mb-3"><strong>{{ 'Resource File ID:'|trans }}</strong> <span id="resource-file-id"></span></p>
<p class="mb-3"><strong>{{ 'File Path:'|trans }}</strong> <span id="file-path"></span>&nbsp;&nbsp;&nbsp;<button id="copy-path" class="mdi mdi-content-copy"></button></p>
<p class="mb-3"><strong>{{ 'File Link:'|trans }}</strong> <a href="#" id="file-url" target="_blank">{{ 'Open File'|trans }}</a></p>
</div>
@ -110,6 +118,8 @@
var user = button.getAttribute('data-user');
var filePath = button.getAttribute('data-file-path');
var fileUrl = button.getAttribute('data-file-url');
var resourceNodeId = button.getAttribute('data-resource-node-id');
var resourceFileId = button.getAttribute('data-resource-file-id');
document.getElementById('file-title').textContent = title;
document.getElementById('file-mime-type').textContent = mimeType;
@ -119,6 +129,8 @@
document.getElementById('file-user').textContent = user;
document.getElementById('file-path').textContent = filePath;
document.getElementById('file-url').href = fileUrl;
document.getElementById('resource-node-id').textContent = resourceNodeId;
document.getElementById('resource-file-id').textContent = resourceFileId;
modal.style.display = "block";
};

Loading…
Cancel
Save