Merge remote-tracking branch 'origin/master'

pull/5674/head
Angel Fernando Quiroz Campos 1 year ago
commit 2f2d8fcb5a
No known key found for this signature in database
GPG Key ID: B284841AE3E562CD
  1. 48
      assets/css/app.scss
  2. 95
      public/documentation/changelog.html
  3. 47
      public/documentation/installation_guide.html
  4. 87
      src/CoreBundle/Controller/Admin/AdminController.php
  5. 6
      src/CoreBundle/Controller/Admin/IndexBlocksController.php
  6. 152
      src/CoreBundle/Resources/views/Admin/files_info.html.twig
  7. 13
      tests/scripts/packaging/gitlog.php

@ -742,6 +742,54 @@ form .field {
} }
} }
.files-info-page {
.form-control {
@apply w-48 p-1 border border-gray-300 rounded;
}
.btn-primary {
@apply bg-primary text-primary-button-text p-1 rounded;
}
.btn-primary:hover {
@apply bg-secondary-hover;
}
.modal {
@apply hidden fixed z-10 left-0 top-0 w-full h-full overflow-auto bg-black bg-opacity-50 pt-16;
}
.modal-content {
@apply bg-white m-auto p-5 border border-gray-300 w-1/3;
}
.close-button {
@apply text-fontdisabled float-right text-2xl font-bold;
}
.close-button:hover,
.close-button:focus {
@apply text-black no-underline cursor-pointer;
}
.pagination {
@apply flex justify-center my-5;
}
.pagination a,
.pagination span {
@apply mx-1 px-4 py-2 text-primary border border-gray-25;
}
.pagination a:hover {
@apply bg-gray-15;
}
.pagination span {
@apply bg-primary text-white border-primary;
}
}
//@import 'primevue-md-light-indigo/theme.css'; //@import 'primevue-md-light-indigo/theme.css';
//@import '~primevue/resources/primevue.min.css'; //@import '~primevue/resources/primevue.min.css';
//@import '~primeflex/primeflex.css'; //@import '~primeflex/primeflex.css';

@ -19,18 +19,33 @@
<div class="version" aria-label="2.0"> <div class="version" aria-label="2.0">
<a id="2.0-alpha.1"></a> <a id="2.0-alpha.1"></a>
<h1>Chamilo 2.0 alpha 1 - [release name not defined], 2024-07-05</h1> <h1>Chamilo 2.0 alpha 1 - Babaorum, 2024-07-18</h1>
<h3>Release notes - summary</h3> <h3>Release notes - summary</h3>
<p>Chamilo 2.0 is a major release that starts a new branch for the Chamilo software. <p>
Chamilo 2.0 will be a major release, a new branch for the Chamilo software.
It is based on Chamilo 1.11.10 and includes tons of backend changes that will make It is based on Chamilo 1.11.10 and includes tons of backend changes that will make
developing Chamilo more "mainstream" in the future, by adopting more widely-known libraries, developing Chamilo more "mainstream" and (hopefully) faster in the future,
with the notable inclusions of Symfony as a main controller and framework (except for by adopting more widely-known libraries, with the notable inclusions of Symfony
some legacy tools not yet converted) and VueJS as our main frontend framework.<br /> as a main controller and framework (except for some legacy tools not yet converted),
For the first time in more than 14 years (since its launch in 2010), VueJS as our main frontend framework and TailwindCSS as our CSS framework.
Chamilo changes appearance, with a new and streamlined (open source) set of </p>
icons, and a design that will allow more flexibility and speed across devices.</p> <p>
For the first time in almost 15 years (since its launch in 2010),
Chamilo considerably changes appearance, with a new, foldable, left menu (meant
to improve space usage on mobile devices) and a streamlined (and open source) set of
icons, and a design that will allow more flexibility and speed across devices.
</p>
<p>
This is an ALPHA release, meaning it is not finished and is meant for testing and development
only. It should *NOT* be used in production unless you have a full-time dedicated IT team behind it.
</p>
<p>
An alpha version, to us, means that (except for unforeseen issues) the database structure is fixed
and the files structure is fixed (although some files could still be added/removed before the beta
release).
</p>
<h3>Release name</h3> <h3>Release name</h3>
<p><a href="https://en.wikipedia.org/wiki/"></a>Not assigned yet</p> <p><a href="https://fr.wikipedia.org/wiki/Liste_des_camps_romains_d%27Ast%C3%A9rix_le_Gaulois#Babaorum"></a>Babaorum (ficticious village name, see French art)</p>
<h3>Security fixes</h3> <h3>Security fixes</h3>
<ul aria-live="off"> <ul aria-live="off">
@ -39,27 +54,71 @@
<h3>Added</h3>. <h3>Added</h3>.
<ul aria-live="off"> <ul aria-live="off">
<li>Web services: Added <a href="https://api-platform.com/">API Platform</a> endpoint "/api". See <a href="https://github.com/chamilo/chamilo-lms/wiki/webservices-api-latest">wiki</a>.</li>
<li>Messages: Messaging can now be made to several people at once from the messages interface (and replies can be made to the same users).</li> <li>Messages: Messaging can now be made to several people at once from the messages interface (and replies can be made to the same users).</li>
<li>Added <a href="https://api-platform.com/">API Platform</a> endpoint "/api". See <a href="https://github.com/chamilo/chamilo-lms/wiki/webservices-api-latest">wiki</a>.</li> <li>Messages: Added tag-based filtering your inbox/outbox.</li>
<li>Admin: Extra fields now have a description field, which allows you to show what you expect from users filling those.</li>
<li>CMS: Added CMS-type management of additional pages, including contact forms. A default install will add empty Home, FAQ, Demo and Contact pages)(<a href="https://github.com/chamilo/chamilo-lms/commit/16429423e18ad27b8f3ae6a816999ad79eca018f">16429423</a> - <a href="https://task.beeznest.com/issues/20918">BT#20918</a>).</li>
<li>Course homepage: Added possibility to re-order tools on course homepage.</li>
<li>Install: Added installation logs for better debug capabilities on install/migrations. Migrations can now be executed step by step if needed (<a href="https://github.com/chamilo/chamilo-lms/commit/f986f77df7f9b53a8d46547edc8dd55636f6d9c9">f986f77d</a>)</li>
<li>Admin: Added the roots of a role-based permissions system. Not functional yet but should be done by stable. Load through <em>/permissions</em> (not the definitive path) to get a sneak peak.</li>
<li>Calendar: Added collective events management in calendar (invite other users as participants to the event) [2021-07-14] (<a href="https://github.com/chamilo/chamilo-lms/commit/026d11634961760eed5e558e4cd39b8157ab0577">026d1163</a> - <a href="https://task.beeznest.com/issues/18894">BT#18894</a>)</li>
<li>Admin: Added pre-deletion of users as safeguard against user mistakes (<a href="https://github.com/chamilo/chamilo-lms/commit/7e917cafadbdafa280c125fd62e64e7543c210fe">7e917caf</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/5097">GH#5097</a>).</li>
<li>Admin: Privacy: Add auto-remove option to delete extra fields when anonymizing users (<a href="https://github.com/chamilo/chamilo-lms/commit/ff4ef19f9a9ca0b995378354428a30ece2cddbdd">ff4ef19f</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/5211">GH#5211</a>).</li>
<li>Messages: Added search feature in message tool (<a href="https://github.com/chamilo/chamilo-lms/commit/2cf10c517237fda95ba667ef7418503d69b5b2ec">2cf10c51</a> - <a href="https://task.beeznest.com/issues/21705">BT#21705</a>)</li>
<li>Announcement: Add event reminders to event created from announcement (<a href="https://github.com/chamilo/chamilo-lms/commit/b5e86d12a1bbe22101a08a158459e06e46cdf6da">b5e86d12</a> - <a href="https://task.beeznest.com/issues/21582">BT#21582</a>).</li>
<li>Admin: Added "News from Chamilo" and "Support" blocks (can be disabled) in the admin section. This will allow us to communicate with admins about updates, security updates and global events, between others, in a non-intrusive way.</li>
<li></li>
</ul> </ul>
<h3>Changed</h3> <h3>Changed</h3>
<ul aria-live="off"> <ul aria-live="off">
<li>Display: Completely changed the design (left menu, reduced top header) and icon set (harder to change but vectorial, color-editable and using one single open library: Material Design Icons).</li>
<li>Display: "My courses" and "My sessions" are now split into 2 different pages. If you only use one, only one appears, highly reducing confusion and increasing speed for portals with many courses/sessions.</li>
<li>Admin: All settings previously found in app/config/configuration.php have been moved to the platform settings interface or (for only a few ones) to .env in your Chamilo's root folder. There are now 720+ settings available to you through the admin interface. Not all settings are implemented yet. Most optional database changes related to those settings have been added to the database by default.</li>
<li>Install: Installation in sub-folders is not possible anymore. Using virtual hosts has become pain-free and cost-free compared to how it was 15 years ago. You will have to use vhosts or another LMS.</li>
<li>Install: When installing, you now need to point your DocumentRoot to the <em>public/</em> directory, otherwise Chamilo will not work. However, .htaccess file support is now optional.</li>
<li>WYSIWYG: We have moved to TinyMCE (from CKEditor) due to CKEditor removing the possibility to edit HTML source (which we consider necessary) (<a href="https://github.com/chamilo/chamilo-lms/commit/53207cf9d7a6a040a2ee3a21b2f1705c0163321c">53207cf9</a>.</li>
<li>Language: Translations now use Gettext. New translation platform at <a href="https://translation.chamilo.org/">translation.chamilo.org</a>.</li>
<li>Internal: cidReq/sessionId/gidReq have been replaced by more sensible cid/sid/gid in URLs.</li>
<li>Internal: Documents are now referenced by id instead of path, which provides for more reliability.</li>
<li>Sessions: Sessions can now have multiple general coaches (including the possibility to have none).</li>
<li>Internal: Files management is now done through a wrapper and in a single writeable directory "var/" (will enable usage with cloud storage services in the future)</li>
<li>Database: All "name" fields have been renamed "title" for consistency across the system.</li> <li>Database: All "name" fields have been renamed "title" for consistency across the system.</li>
<li>Database: As much as possible, tables containing records that had been deleted in Chamilo 1.* are migrated without such records. This means less "ghost" content, but also that the content deleted that way in Chamilo 1.* now has become completely unrecoverable.</li> <li>Install: Updated minimum PHP version required to PHP 8.2</li>
<li>Calendar: Merged all calendar tools (global, course and personal events) for mainstream management.</li>
<li>Messages: Message attachment are no longer replicated the number of times they are received (for example through an announcement). This saves considerable space on large portals.</li> <li>Messages: Message attachment are no longer replicated the number of times they are received (for example through an announcement). This saves considerable space on large portals.</li>
<li>Plugins: Many plugins that seemed either unused or were not maintained by their maintainers. They could be included later on, and their tables have not been removed in the database, but they are not available in the list of plugins.</li> <li>Admin: Remove courses/sessions icons from users list (very seldom used). Cut e-mail address shorter and add icon for full e-mail info on hover.</li>
<li>Wiki: The wiki tool is not available *yet*. It will be included again in future versions, but there were too many changes required to include it in v2.0.</li> <li>Database: As much as possible, tables containing records of objects that had been previously deleted in Chamilo 1.* are migrated without such records. This means less "ghost" content, but also that the content deleted that way in Chamilo 1.* now has become completely unrecoverable.</li>
<li>Blogs: The blogs tool is not available. It might be included again in future versions, but there were too many changes required to include it in v2.0.</li> <li>Internal: Resources (documents, tests, forums, etc) are now global and fully shareable between course contexts, which will allow us (in future versions) to have a central repository of resources to search and share reusable items.</li>
<li>Dropbox: The dropbox tool is not available. It might be included again in future versions, but there were too many changes required to include it in v2.0.</li> <li>Quiz: Add new generated audio file link in exercise notifications (<a href="https://github.com/chamilo/chamilo-lms/commit/dcc441581292dd01464824892801af9de14c35e9">dcc44158</a> - <a href="https://task.beeznest.com/issues/21575">BT#21575</a>).</li>
<li>Global: Sub-folder mode: Chamilo 2 will not support being installed in a sub-folder. Nowadays, defining a subdomain has become very easy and provides higher security and more configuration flexibility, and supporting sub-folders is a complex task.</li> <li>Plugins: xAPI: xAPI plugin and LRS tables integrated into core entities (<a href="https://github.com/chamilo/chamilo-lms/commit/37aede9d72570c5e0818718d658d8c57f1d9d3f6">37aede9d</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2001">GH#2001</a>).</li>
<li>Display: Upon migration, the stylesheets are reset to the default Chamilo stylesheet. You will have to redesign your stylesheets using the stylesheets tool in the admin UI.</li> <li>Global: Added 'duration' field to many item types (course, learning paths, tests, attendances, assignments, ...). This will enable better reporting when activities must be based on "estimated time of completion" rather than tracked time.</li>
<li>Admin: The Multi-URL feature is now enabled by default on the admin page.</li>
</ul>
<h3>Fixed</h3>
<ul aria-live="off">
<li>Forum: Included all coaches in session notifications (<a href="https://github.com/chamilo/chamilo-lms/commit/f1c16adf454dd73cd2bec08e7d431f5b2978a224">f1c16adf</a> - <a href="https://task.beeznest.com/issues/21550">BT#21550</a>).</li>
<li>Survey: Allowed tutors to access doodle past end date (<a href="https://github.com/chamilo/chamilo-lms/commit/e457b0e2971cd30ce0cbd11ad56f18065d9a07fc">e457b0e2</a> - <a href="https://task.beeznest.com/issues/21622">BT#21622</a>)</li>
</ul> </ul>
<h3>Known issues</h3> <h3>Known issues</h3>
<ul aria-live="off"> <ul aria-live="off">
<li>DB title vs name fields: There have been *many* (several hundreds) database changes between v1.* and v2.0. These changes include renaming all "name" fields in all tables to "title", to follow a common standard. This particular change has required dozens of hours of expert work, because the "name" text is very common and the Chamilo 1.* was not *that* well structured. However, we may still have missed a few ones. If you find one, please report it as an issue in our repository.</li>
<li>Customizations of in-course tools (titles, icons, etc) at the course level are lost in migration.</li> <li>Customizations of in-course tools (titles, icons, etc) at the course level are lost in migration.</li>
<li>Multi-URL does not work (fully) yet in this alpha release.</li>
<li>Wiki: The wiki tool is not available *yet*. It will be included again in future versions, but there were too many changes required to include it in v2.0.</li>
<li>Course chat: The course chat tool is not available *yet*. It will be included again in future versions, but there were too many changes required to include it in v2.0.</li>
<li>Plugins: Many plugins that seemed either unused or were not maintained by their maintainers were removed. They could be included again later on, and their tables have not been removed in the database if they had been installed in your 1.11.*, but they are not available in the list of plugins.</li>
<li>Plugins: Installing plugins is disabled in this alpha release. This should be fixed before beta 1.</li>
<li>Display: The Bootstrap (CSS) library has been removed. Some code might still use it. Should be fixed before stable.</li>
<li>Blogs: The blogs tool is not available. It might be included again in future versions, but there were too many changes required to include it in v2.0.</li>
<li>Dropbox: The dropbox tool is not available. It might be included again in future versions, but there were too many changes required to include it in v2.0.</li>
<li>Display: Upon migration, the stylesheets are reset to the default Chamilo stylesheet. You will have to redesign your stylesheets using the stylesheets tool in the admin UI.</li>
<li>Courses list: Removed the ability to sort your own courses in a special list (too complex to support in combination with sessions).</li>
<li>Course catalogue: Not working properly. Will be fixed before stable.</li>
<li>Admin: Document templates have been removed. Previous templates were non-responsive. In this version, there will be no document templates by default, but you can add them easily in Admin > System templates.</li>
<li></li>
</ul> </ul>
</div> </div>
<div class="syntax-description"> <div class="syntax-description">

@ -19,26 +19,39 @@ This version of Chamilo requires the following software stack.
</ul> </ul>
Within PHP, Chamilo requires or benefits from the following extensions: Within PHP, Chamilo requires or benefits from the following extensions:
<ul> <ul>
<li>session (php-session, usually shipped with PHP)</li> <li>curl</li>
<li>mysql</li> <li>exif</li>
<li>zip</li> <li>gd</li>
<li>zlib</li> <li>iconv</li>
<li>pcre</li>
<li>xml</li>
<li>intl</li> <li>intl</li>
<li>json</li> <li>json</li>
<li>gd</li>
<li>curl</li>
<li>mbstring</li> <li>mbstring</li>
<li>exif</li> <li>mysql</li>
<li>opcache</li> <li>opcache</li>
<li>iconv</li> <li>pcre</li>
<li>session (php-session, usually shipped with PHP)</li>
<li>xml</li>
<li>zip</li>
<li>zlib</li>
<li>ldap (optional)</li> <li>ldap (optional)</li>
<li>xapian (optional)</li> <li>xapian (optional)</li>
</ul> </ul>
<h2>Database</h2> <h2>Web-panel installation</h2>
<h3>Database</h3>
Make sure you have a database available with full permissions.
Do not share that database with another application as Chamilo might need to create
a table that has the same name as a table in the other application.
<h3>Virtual host</h3>
Define a new virtual host/subdomain name you will use for Chamilo (Chamilo 2 does *not* work as a sub-folder of an existing website, you need a subdomain like "elearning.yourdomain.com").<br>
Upload and/or unzip your Chamilo files inside your web folder (usually inside a folder called "public_html/").<br>
Configure a virtual host pointing at the "public" directory inside your Chamilo directory. For example, this could be "/home/elearning.yourdomain.com/public_html/chamilo2/public/".<br>
<h3>Installation wizard</h3>
You are ready to go. Open your browser on your subdomain (elearning.yourdomain.com in the example above), keep your database credentials at hand, and let the Chamilo installer guide you.
<h2>Command line installation</h2>
<h3>Database</h3>
You will need a database user with privilege to fully use (and optionally create) a database.<br> You will need a database user with privilege to fully use (and optionally create) a database.<br>
Although progress has been made to support multiple database management systems, Chamilo currently only supports MariaDB and MySQL.<br> Although progress has been made to support multiple database management systems, Chamilo
currently only supports MariaDB and MySQL.<br>
Setup a new user in your database system either through visual tools or directly in the terminal:<br> Setup a new user in your database system either through visual tools or directly in the terminal:<br>
<pre> <pre>
mysql> GRANT ALL PRIVILEGES ON [db-name].* TO [db-user]@[db-host] IDENTIFIED BY '[db-password]'; mysql> GRANT ALL PRIVILEGES ON [db-name].* TO [db-user]@[db-host] IDENTIFIED BY '[db-password]';
@ -53,14 +66,14 @@ where:
<li>[db-host] is the name of the database server (use <em>localhost</em> when using the same machine for web server and database server - if you use a hosted service, your hosting provider will usually give you this name somewhere)</li> <li>[db-host] is the name of the database server (use <em>localhost</em> when using the same machine for web server and database server - if you use a hosted service, your hosting provider will usually give you this name somewhere)</li>
<li>[db-password] is the password this user will use to connect to this database on this host. Use common sense to not make it too easy to guess (use special characters, lowercase and uppercase, numbers, and a length of *at least* 8 characters)</li> <li>[db-password] is the password this user will use to connect to this database on this host. Use common sense to not make it too easy to guess (use special characters, lowercase and uppercase, numbers, and a length of *at least* 8 characters)</li>
</ul> </ul>
<h2>Web server</h2> <h3>Web server</h3>
Chamilo 2+ only requires a working web server setup to work. You can run it on localhost with the default installation of any web server, provided you configure your DocumentRoot as the path pointing to Chamilo's <em>public/</em> subfolder.<br> Chamilo 2+ only requires a working web server setup to work. You can run it on localhost with the default installation of any web server, provided you configure your DocumentRoot as the path pointing to Chamilo's <em>public/</em> subfolder.<br>
Here is a minimal example Apache vhost configuration file for an installation on the http://my.chamilo.local/ URL (replace all values between brackets, including the brackets, to your custom values): Here is a minimal example Apache vhost configuration file for an installation on the http://my.chamilo.local/ URL (replace all values between brackets, including the brackets, to your custom values):
<pre> <pre>
&lt;VirtualHost *:80&gt; &lt;VirtualHost *:80&gt;
ServerAdmin [your-email] ServerAdmin [your-email]
ServerName [my.chamilo.local] ServerName [my.chamilo.local]
DocumentRoot [/var/www/chamilo/public/] DocumentRoot [/var/www/chamilo]/public/
# The following might not even be required # The following might not even be required
ErrorLog /var/log/apache2/[my.chamilo.local]-error.log ErrorLog /var/log/apache2/[my.chamilo.local]-error.log
CustomLog /var/log/apache2/[my.chamilo.local]-access.log combined CustomLog /var/log/apache2/[my.chamilo.local]-access.log combined
@ -73,13 +86,15 @@ After setting up this virtual host, don't forget to enable it (example here on D
a2ensite [my.chamilo.local] a2ensite [my.chamilo.local]
systemctl reload apache2 systemctl reload apache2
</pre> </pre>
Then you should be able to direct your browser to your URL (e.g. <em>[http://my.chamilo.local]</em>).<br> <h3>Installation wizard</h3>
You should now be able to direct your browser to your URL (e.g. <em>[http://my.chamilo.local]</em>).<br>
Chamilo will pick it up from there and offer the installation wizard to help guide you through the rest of the process. Chamilo will pick it up from there and offer the installation wizard to help guide you through the rest of the process.
<h2>Help available</h2> <h2>Help available</h2>
If you are struggling with this guide, don't hesitate to ask for help on <a href="https://github.com/chamilo/chamilo-lms/discussions">our community forum.</a><br> If you are struggling with this guide, don't hesitate to ask for help on <a href="https://github.com/chamilo/chamilo-lms/discussions">our community forum.</a><br>
If you have reasons to seek professional assistance and warranties, please contact <a href="https://chamilo.org/providers">one of our official providers</a>. They contribute heavily to the project and will be able to help you out quickly and efficiently, for configurations from 10 to 1M users.<br> If you have reasons to seek professional assistance and warranties, please contact <a href="https://chamilo.org/providers">one of our official providers</a>. They contribute heavily to the project and will be able to help you out quickly and efficiently, for configurations from 10 to 1M users.<br>
<hr /> <hr />
Last updated: 2024-07-07 Last updated: 2024-07-18
<a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a> <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
<a href="http://jigsaw.w3.org/css-validator/"> <a href="http://jigsaw.w3.org/css-validator/">
<img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" /> <img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />

@ -7,18 +7,27 @@ declare(strict_types=1);
namespace Chamilo\CoreBundle\Controller\Admin; namespace Chamilo\CoreBundle\Controller\Admin;
use Chamilo\CoreBundle\Controller\BaseController; use Chamilo\CoreBundle\Controller\BaseController;
use Chamilo\CoreBundle\Entity\ResourceFile;
use Chamilo\CoreBundle\Repository\ResourceNodeRepository;
use Chamilo\CoreBundle\ServiceHelper\AccessUrlHelper; use Chamilo\CoreBundle\ServiceHelper\AccessUrlHelper;
use Chamilo\CoreBundle\Settings\SettingsManager; use Chamilo\CoreBundle\Settings\SettingsManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Security\Http\Attribute\IsGranted;
use Vich\UploaderBundle\Storage\StorageInterface;
#[Route('/admin')] #[Route('/admin')]
class AdminController extends BaseController class AdminController extends BaseController
{ {
private const ITEMS_PER_PAGE = 50;
public function __construct( public function __construct(
private readonly AccessUrlHelper $accessUrlHelper, private EntityManagerInterface $entityManager,
private ResourceNodeRepository $resourceNodeRepository,
private StorageInterface $storage,
private AccessUrlHelper $accessUrlHelper
) {} ) {}
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
@ -38,4 +47,78 @@ class AdminController extends BaseController
return new Response('', Response::HTTP_NO_CONTENT); return new Response('', Response::HTTP_NO_CONTENT);
} }
#[IsGranted('ROLE_ADMIN')]
#[Route('/files_info', name: 'admin_files_info', methods: ['GET'])]
public function listFilesInfo(Request $request): 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);
$fileUrls = [];
$filePaths = [];
foreach ($files as $file) {
$resourceNode = $file->getResourceNode();
if ($resourceNode) {
$fileUrls[$file->getId()] = $this->resourceNodeRepository->getResourceFileUrl($resourceNode);
$creator = $resourceNode->getCreator();
} else {
$fileUrls[$file->getId()] = null;
$creator = null;
}
$filePaths[$file->getId()] = $this->resourceNodeRepository->getFilename($file);
}
return $this->render('@ChamiloCore/Admin/files_info.html.twig', [
'files' => $files,
'fileUrls' => $fileUrls,
'filePaths' => $filePaths,
'totalPages' => $totalPages,
'currentPage' => $page,
'search' => $search,
]);
}
} }

@ -566,6 +566,12 @@ class IndexBlocksController extends BaseController
'label' => $this->translator->trans('Colors'), 'label' => $this->translator->trans('Colors'),
]; ];
$items[] = [
'class' => 'item-file-info',
'url' => '/admin/files_info',
'label' => $this->translator->trans('File info'),
];
return $items; return $items;
} }

@ -0,0 +1,152 @@
{% extends "@ChamiloCore/Layout/layout_one_col.html.twig" %}
{% block content %}
<div class="files-info-page">
<h1>{{ 'File Information'|trans }}</h1>
<form method="get" action="{{ path('admin_files_info') }}" style="display: flex; justify-content: flex-end; margin-bottom: 20px;">
<input type="text" name="search" value="{{ search }}" placeholder="{{ 'Search...'|trans }}" class="form-control" style="margin-right: 10px;">
<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 %}
<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>
</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>
{% endif %}
{% endfor %}
{% if currentPage < totalPages %}
<a href="{{ path('admin_files_info', {'page': currentPage + 1, 'search': search}) }}">{{ 'Next'|trans }} &raquo;</a>
{% endif %}
</div>
<!-- Modal -->
<div id="fileInfoModal" class="modal">
<div class="modal-content">
<span class="close-button">&times;</span>
<h2>{{ 'File Information'|trans }}</h2>
<p class="mt-3 mb-3"><strong>{{ 'Title:'|trans }}</strong> <span id="file-title"></span></p>
<p class="mb-3"><strong>{{ 'MIME Type:'|trans }}</strong> <span id="file-mime-type"></span></p>
<p class="mb-3"><strong>{{ 'Original Name:'|trans }}</strong> <span id="file-original-name"></span></p>
<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>{{ '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>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
var modal = document.getElementById("fileInfoModal");
var span = document.getElementsByClassName("close-button")[0];
var copyPathButton = document.getElementById('copy-path');
document.querySelectorAll('.open-modal').forEach(function(button) {
button.onclick = function(event) {
event.preventDefault();
var title = button.getAttribute('data-title');
var mimeType = button.getAttribute('data-mime-type');
var originalName = button.getAttribute('data-original-name');
var size = button.getAttribute('data-size');
var course = button.getAttribute('data-course');
var user = button.getAttribute('data-user');
var filePath = button.getAttribute('data-file-path');
var fileUrl = button.getAttribute('data-file-url');
document.getElementById('file-title').textContent = title;
document.getElementById('file-mime-type').textContent = mimeType;
document.getElementById('file-original-name').textContent = originalName;
document.getElementById('file-size').textContent = size + ' bytes';
document.getElementById('file-course').textContent = course;
document.getElementById('file-user').textContent = user;
document.getElementById('file-path').textContent = filePath;
document.getElementById('file-url').href = fileUrl;
modal.style.display = "block";
};
});
span.onclick = function() {
modal.style.display = "none";
};
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
copyPathButton.onclick = function() {
var filePath = document.getElementById('file-path').textContent;
navigator.clipboard.writeText(filePath).then(function() {
copyPathButton.classList.remove('mdi-content-copy');
copyPathButton.classList.add('mdi-check');
setTimeout(function() {
copyPathButton.classList.remove('mdi-check');
copyPathButton.classList.add('mdi-content-copy');
}, 2000);
}, function(err) {
alert('Failed to copy: ', err);
});
};
});
</script>
{% endblock %}

@ -46,6 +46,19 @@ if (!empty($argv[1])) {
echo "An initial commit has been defined as ".$endCommit.PHP_EOL; echo "An initial commit has been defined as ".$endCommit.PHP_EOL;
} }
} }
// List if prefixes that can be skipped when creating a simplified, communication-focused changelog
$skipTechnicalPrefixes = [
'QA',
'Internal',
'Vendor',
'Display',
'Fix',
'Minor',
'Documentation',
'Refactor',
'Migration',
'UI',
];
$git = new \YWarnier\PHPGit\Git($repository); $git = new \YWarnier\PHPGit\Git($repository);
echo "Log from branch: ".$git->getCurrentBranch().PHP_EOL; echo "Log from branch: ".$git->getCurrentBranch().PHP_EOL;

Loading…
Cancel
Save