commit
90cb87c68b
@ -0,0 +1,74 @@ |
||||
import { usePlatformConfig } from "../../store/platformConfig" |
||||
import { useRoute, useRouter } from "vue-router" |
||||
import { useStore } from "vuex" |
||||
import { useSecurityStore } from "../../store/securityStore" |
||||
|
||||
function isValidHttpUrl(string) { |
||||
let url |
||||
|
||||
try { |
||||
url = new URL(string) |
||||
} catch (_) { |
||||
return false |
||||
} |
||||
|
||||
return url.protocol === "http:" || url.protocol === "https:" |
||||
} |
||||
|
||||
export function useLogin() { |
||||
const route = useRoute() |
||||
const router = useRouter() |
||||
const store = useStore() |
||||
const securityStore = useSecurityStore() |
||||
|
||||
async function performLogin(payload) { |
||||
const responseData = await store.dispatch("security/login", payload) |
||||
|
||||
if (store.getters["security/hasError"]) { |
||||
return |
||||
} |
||||
|
||||
if (route.query.redirect) { |
||||
// Check if 'redirect' is an absolute URL
|
||||
if (isValidHttpUrl(route.query.redirect.toString())) { |
||||
// If it's an absolute URL, redirect directly
|
||||
window.location.href = route.query.redirect.toString() |
||||
|
||||
return |
||||
} |
||||
|
||||
securityStore.user = responseData |
||||
|
||||
const platformConfigurationStore = usePlatformConfig() |
||||
await platformConfigurationStore.initialize() |
||||
|
||||
// If 'redirect' is a relative path, use 'router.push' to navigate
|
||||
await router.push({ path: route.query.redirect.toString() }) |
||||
|
||||
return |
||||
} |
||||
|
||||
if (responseData.load_terms) { |
||||
window.location.href = responseData.redirect |
||||
} else { |
||||
window.location.href = "/home" |
||||
} |
||||
} |
||||
|
||||
async function redirectNotAuthenticated() { |
||||
if (!securityStore.isAuthenticated) { |
||||
return |
||||
} |
||||
|
||||
if (route.query.redirect) { |
||||
await router.push({ path: route.query.redirect.toString() }) |
||||
} else { |
||||
await router.replace({ name: "Home" }) |
||||
} |
||||
} |
||||
|
||||
return { |
||||
performLogin, |
||||
redirectNotAuthenticated, |
||||
} |
||||
} |
@ -1,166 +0,0 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Entity; |
||||
|
||||
use DateTime; |
||||
use Doctrine\ORM\Mapping as ORM; |
||||
|
||||
/** |
||||
* SysCalendar. |
||||
*/ |
||||
#[ORM\Table(name: 'sys_calendar')] |
||||
#[ORM\Entity] |
||||
class SysCalendar |
||||
{ |
||||
public const COLOR_SYSTEM_EVENT = '#FF0000'; |
||||
|
||||
#[ORM\Column(name: 'id', type: 'integer')] |
||||
#[ORM\Id] |
||||
#[ORM\GeneratedValue(strategy: 'IDENTITY')] |
||||
protected ?int $id = null; |
||||
|
||||
#[ORM\Column(name: 'title', type: 'string', length: 255, nullable: false)] |
||||
protected string $title; |
||||
|
||||
#[ORM\Column(name: 'content', type: 'text', nullable: true)] |
||||
protected ?string $content = null; |
||||
|
||||
#[ORM\Column(name: 'start_date', type: 'datetime', nullable: true)] |
||||
protected ?DateTime $startDate = null; |
||||
|
||||
#[ORM\Column(name: 'end_date', type: 'datetime', nullable: true)] |
||||
protected ?DateTime $endDate = null; |
||||
|
||||
#[ORM\ManyToOne(targetEntity: AccessUrl::class)] |
||||
#[ORM\JoinColumn(name: 'access_url_id', referencedColumnName: 'id', onDelete: 'CASCADE')] |
||||
protected AccessUrl $url; |
||||
|
||||
#[ORM\Column(name: 'all_day', type: 'integer', nullable: false)] |
||||
protected int $allDay; |
||||
|
||||
#[ORM\Column(name: 'color', type: 'string', length: 20, nullable: true)] |
||||
protected ?string $color = null; |
||||
|
||||
public function setTitle(string $title): self |
||||
{ |
||||
$this->title = $title; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
/** |
||||
* Get title. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getTitle() |
||||
{ |
||||
return $this->title; |
||||
} |
||||
|
||||
public function setContent(string $content): self |
||||
{ |
||||
$this->content = $content; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
/** |
||||
* Get content. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getContent() |
||||
{ |
||||
return $this->content; |
||||
} |
||||
|
||||
public function setStartDate(DateTime $startDate): self |
||||
{ |
||||
$this->startDate = $startDate; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
/** |
||||
* Get startDate. |
||||
* |
||||
* @return DateTime |
||||
*/ |
||||
public function getStartDate() |
||||
{ |
||||
return $this->startDate; |
||||
} |
||||
|
||||
public function setEndDate(DateTime $endDate): self |
||||
{ |
||||
$this->endDate = $endDate; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
/** |
||||
* Get endDate. |
||||
* |
||||
* @return DateTime |
||||
*/ |
||||
public function getEndDate() |
||||
{ |
||||
return $this->endDate; |
||||
} |
||||
|
||||
public function setAllDay(int $allDay): self |
||||
{ |
||||
$this->allDay = $allDay; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
/** |
||||
* Get allDay. |
||||
* |
||||
* @return int |
||||
*/ |
||||
public function getAllDay() |
||||
{ |
||||
return $this->allDay; |
||||
} |
||||
|
||||
/** |
||||
* Get id. |
||||
* |
||||
* @return int |
||||
*/ |
||||
public function getId() |
||||
{ |
||||
return $this->id; |
||||
} |
||||
|
||||
public function getColor(): ?string |
||||
{ |
||||
return $this->color; |
||||
} |
||||
|
||||
public function setColor(string $color): self |
||||
{ |
||||
$this->color = $color; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getUrl(): AccessUrl |
||||
{ |
||||
return $this->url; |
||||
} |
||||
|
||||
public function setUrl(AccessUrl $url): self |
||||
{ |
||||
$this->url = $url; |
||||
|
||||
return $this; |
||||
} |
||||
} |
@ -0,0 +1,65 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Chamilo\CoreBundle\Filter; |
||||
|
||||
use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter; |
||||
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface; |
||||
use ApiPlatform\Metadata\Operation; |
||||
use Chamilo\CoreBundle\Entity\ResourceNode; |
||||
use Doctrine\ORM\QueryBuilder; |
||||
use Doctrine\Persistence\ManagerRegistry; |
||||
use Psr\Log\LoggerInterface; |
||||
use Symfony\Component\Serializer\NameConverter\NameConverterInterface; |
||||
|
||||
class GlobalEventFilter extends AbstractFilter |
||||
{ |
||||
public function __construct( |
||||
ManagerRegistry $managerRegistry, |
||||
?LoggerInterface $logger = null, |
||||
?array $properties = null, |
||||
?NameConverterInterface $nameConverter = null |
||||
) { |
||||
parent::__construct($managerRegistry, $logger, $properties, $nameConverter); |
||||
} |
||||
|
||||
protected function filterProperty( |
||||
string $property, |
||||
$value, |
||||
QueryBuilder $queryBuilder, |
||||
QueryNameGeneratorInterface $queryNameGenerator, |
||||
string $resourceClass, |
||||
?Operation $operation = null, |
||||
array $context = [] |
||||
): void { |
||||
$isGlobalType = isset($context['filters']['type']) && $context['filters']['type'] === 'global'; |
||||
if (!$isGlobalType) { |
||||
return; |
||||
} |
||||
|
||||
$rootAlias = $queryBuilder->getRootAliases()[0]; |
||||
$resourceNodeAlias = $queryNameGenerator->generateJoinAlias('resourceNode'); |
||||
$resourceLinkAlias = $queryNameGenerator->generateJoinAlias('resourceLink'); |
||||
$queryBuilder |
||||
->innerJoin("$rootAlias.resourceNode", $resourceNodeAlias) |
||||
->innerJoin("$resourceNodeAlias.resourceLinks", $resourceLinkAlias) |
||||
->andWhere("$resourceLinkAlias.course IS NULL") |
||||
->andWhere("$resourceLinkAlias.session IS NULL") |
||||
->andWhere("$resourceLinkAlias.group IS NULL") |
||||
->andWhere("$resourceLinkAlias.user IS NULL"); |
||||
} |
||||
|
||||
public function getDescription(string $resourceClass): array |
||||
{ |
||||
return [ |
||||
'type' => [ |
||||
'property' => 'type', |
||||
'type' => 'string', |
||||
'required' => false, |
||||
'description' => 'Filter events by type. Use "global" to get global events.', |
||||
], |
||||
]; |
||||
} |
||||
} |
@ -0,0 +1,102 @@ |
||||
<?php |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Chamilo\CoreBundle\Migrations\Schema\V200; |
||||
|
||||
use Chamilo\CoreBundle\Entity\ResourceLink; |
||||
use Chamilo\CoreBundle\Entity\User; |
||||
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo; |
||||
use Chamilo\CourseBundle\Entity\CCalendarEvent; |
||||
use DateTime; |
||||
use DateTimeZone; |
||||
use Doctrine\DBAL\Schema\Schema; |
||||
|
||||
class Version20240323181500 extends AbstractMigrationChamilo |
||||
{ |
||||
public function getDescription(): string |
||||
{ |
||||
return 'Migrate sys_calendar to c_calendar_event'; |
||||
} |
||||
|
||||
public function up(Schema $schema): void |
||||
{ |
||||
$em = $this->getEntityManager(); |
||||
$sysCalendars = $this->connection->fetchAllAssociative('SELECT * FROM sys_calendar'); |
||||
|
||||
$utc = new DateTimeZone('UTC'); |
||||
$admin = $this->getAdmin(); |
||||
foreach ($sysCalendars as $sysCalendar) { |
||||
|
||||
$calendarEvent = $this->createCCalendarEvent( |
||||
$sysCalendar['title'] ?: '-', |
||||
$sysCalendar['content'], |
||||
$sysCalendar['start_date'] ? new DateTime($sysCalendar['start_date'], $utc) : null, |
||||
$sysCalendar['end_date'] ? new DateTime($sysCalendar['end_date'], $utc) : null, |
||||
(bool) $sysCalendar['all_day'], |
||||
$sysCalendar['color'] ?? '', |
||||
$admin |
||||
); |
||||
|
||||
$em->persist($calendarEvent); |
||||
$this->addGlobalResourceLinkToNode($em, $calendarEvent->getResourceNode()); |
||||
} |
||||
|
||||
$em->flush(); |
||||
} |
||||
|
||||
private function createCCalendarEvent( |
||||
string $title, |
||||
string $content, |
||||
?DateTime $startDate, |
||||
?DateTime $endDate, |
||||
bool $allDay, |
||||
string $color, |
||||
User $creator |
||||
): CCalendarEvent { |
||||
$calendarEvent = new CCalendarEvent(); |
||||
$calendarEvent |
||||
->setTitle($title) |
||||
->setContent($content) |
||||
->setStartDate($startDate) |
||||
->setEndDate($endDate) |
||||
->setAllDay($allDay) |
||||
->setColor($color) |
||||
->setCreator($creator) |
||||
->setResourceName($title) |
||||
->setParentResourceNode($creator->getResourceNode()->getId()) |
||||
; |
||||
|
||||
return $calendarEvent; |
||||
} |
||||
|
||||
private function addGlobalResourceLinkToNode($em, $resourceNode): void |
||||
{ |
||||
$globalLink = new ResourceLink(); |
||||
$globalLink->setCourse(null) |
||||
->setSession(null) |
||||
->setGroup(null) |
||||
->setUser(null); |
||||
|
||||
$alreadyHasGlobalLink = false; |
||||
foreach ($resourceNode->getResourceLinks() as $existingLink) { |
||||
if (null === $existingLink->getCourse() && null === $existingLink->getSession() && |
||||
null === $existingLink->getGroup() && null === $existingLink->getUser()) { |
||||
$alreadyHasGlobalLink = true; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (!$alreadyHasGlobalLink) { |
||||
$resourceNode->addResourceLink($globalLink); |
||||
$em->persist($globalLink); |
||||
} |
||||
} |
||||
|
||||
public function down(Schema $schema): void |
||||
{ |
||||
// Down migration is not defined, as data migration cannot be easily reverted |
||||
} |
||||
} |
@ -0,0 +1,29 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Chamilo\CoreBundle\Migrations\Schema\V200; |
||||
|
||||
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo; |
||||
use Doctrine\DBAL\Schema\Schema; |
||||
|
||||
final class Version20240323222700 extends AbstractMigrationChamilo |
||||
{ |
||||
public function getDescription(): string |
||||
{ |
||||
return 'Remove the sys_calendar table'; |
||||
} |
||||
|
||||
public function up(Schema $schema): void |
||||
{ |
||||
$this->addSql('DROP TABLE IF EXISTS sys_calendar'); |
||||
} |
||||
|
||||
public function down(Schema $schema): void |
||||
{ |
||||
if (!$schema->hasTable('sys_calendar')) { |
||||
$this->addSql('CREATE TABLE sys_calendar (id INT AUTO_INCREMENT NOT NULL, title VARCHAR(255) NOT NULL, content LONGTEXT DEFAULT NULL, start_date DATETIME DEFAULT NULL, end_date DATETIME DEFAULT NULL, access_url_id INT DEFAULT NULL, all_day INT NOT NULL, color VARCHAR(20) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); |
||||
} |
||||
} |
||||
} |
@ -1,19 +0,0 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Repository; |
||||
|
||||
use Chamilo\CoreBundle\Entity\SysCalendar; |
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; |
||||
use Doctrine\Persistence\ManagerRegistry; |
||||
|
||||
class SysCalendarRepository extends ServiceEntityRepository |
||||
{ |
||||
public function __construct(ManagerRegistry $registry) |
||||
{ |
||||
parent::__construct($registry, SysCalendar::class); |
||||
} |
||||
} |
@ -0,0 +1,15 @@ |
||||
<?php |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Chamilo\CoreBundle\Tool; |
||||
|
||||
abstract class AbstractPlugin extends AbstractCourseTool implements ToolInterface |
||||
{ |
||||
public function getCategory(): string |
||||
{ |
||||
return 'plugin'; |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
<?php |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Chamilo\CoreBundle\Tool; |
||||
|
||||
class CustomCertificate extends AbstractPlugin |
||||
{ |
||||
public function getTitle(): string |
||||
{ |
||||
return 'customcertificate'; |
||||
} |
||||
|
||||
public function getLink(): string |
||||
{ |
||||
return '/plugin/customcertificate/start.php'; |
||||
} |
||||
|
||||
public function getIcon(): string |
||||
{ |
||||
return 'mdi-certificate-outline'; |
||||
} |
||||
|
||||
public function getTitleToShow(): string |
||||
{ |
||||
return 'Custom certificate'; |
||||
} |
||||
} |
@ -0,0 +1,29 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Chamilo\CoreBundle\Tool; |
||||
|
||||
class NotebookTeacher extends AbstractPlugin |
||||
{ |
||||
public function getTitle(): string |
||||
{ |
||||
return 'notebookteacher'; |
||||
} |
||||
|
||||
public function getLink(): string |
||||
{ |
||||
return '/plugin/notebookteacher/start.php'; |
||||
} |
||||
|
||||
public function getIcon(): string |
||||
{ |
||||
return 'mdi-note-edit'; |
||||
} |
||||
|
||||
public function getTitleToShow(): string |
||||
{ |
||||
return 'Teacher notes'; |
||||
} |
||||
} |
@ -0,0 +1,25 @@ |
||||
<?php |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Chamilo\CoreBundle\Tool; |
||||
|
||||
class Positioning extends AbstractPlugin |
||||
{ |
||||
public function getTitle(): string |
||||
{ |
||||
return 'positioning'; |
||||
} |
||||
|
||||
public function getLink(): string |
||||
{ |
||||
return '/plugin/positioning/start.php'; |
||||
} |
||||
|
||||
public function getIcon(): string |
||||
{ |
||||
return 'mdi-radar'; |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
<?php |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Chamilo\CoreBundle\Tool; |
||||
|
||||
class Test2Pdf extends AbstractPlugin |
||||
{ |
||||
public function getTitle(): string |
||||
{ |
||||
return 'test2pdf'; |
||||
} |
||||
|
||||
public function getLink(): string |
||||
{ |
||||
return '/plugin/test2pdf/start.php'; |
||||
} |
||||
|
||||
public function getIcon(): string |
||||
{ |
||||
return 'mdi-file-pdf-box'; |
||||
} |
||||
|
||||
public function getTitleToShow(): string |
||||
{ |
||||
return 'Test to Pdf (Test2Pdf)'; |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
<?php |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Chamilo\CoreBundle\Tool; |
||||
|
||||
class Zoom extends AbstractPlugin |
||||
{ |
||||
public function getTitle(): string |
||||
{ |
||||
return 'zoom'; |
||||
} |
||||
|
||||
public function getLink(): string |
||||
{ |
||||
return 'plugin/zoom/start.php'; |
||||
} |
||||
|
||||
public function getIcon(): string |
||||
{ |
||||
return 'mdi-video-box'; |
||||
} |
||||
|
||||
public function getTitleToShow(): string |
||||
{ |
||||
return 'Zoom Videoconference'; |
||||
} |
||||
} |
Loading…
Reference in new issue