Merge remote-tracking branch 'origin/master'

pull/4750/head
Angel Fernando Quiroz Campos 1 year ago
commit a8850e7de5
  1. 9
      public/main/inc/lib/course.lib.php
  2. 116
      public/main/lp/learnpath.class.php
  3. 39
      public/main/lp/lp_report.php
  4. 86
      public/main/lp/lp_subscribe_users.php
  5. 5
      public/main/lp/lp_subscribe_users_to_category.php
  6. 10
      src/CoreBundle/Controller/Admin/IndexBlocksController.php
  7. 35
      src/CoreBundle/DataFixtures/ResourceFormatFixtures.php
  8. 23
      src/CoreBundle/Entity/Listener/ResourceListener.php
  9. 80
      src/CoreBundle/Entity/ResourceFormat.php
  10. 37
      src/CoreBundle/Entity/ResourceNode.php
  11. 3
      src/CoreBundle/Migrations/Schema/V200/Version20170525122900.php
  12. 36
      src/CoreBundle/Migrations/Schema/V200/Version20230215062918.php
  13. 94
      src/CoreBundle/Migrations/Schema/V200/Version20230215072918.php
  14. 52
      src/CoreBundle/Migrations/Schema/V200/Version20230306145019.php
  15. 50
      src/CoreBundle/Migrations/Schema/V200/Version20230306150219.php
  16. 25
      src/CoreBundle/Tool/ToolChain.php
  17. 60
      src/CourseBundle/Entity/CLpCategoryRelUserGroup.php
  18. 102
      src/CourseBundle/Entity/CLpRelUser.php
  19. 162
      src/CourseBundle/Repository/CLpRelUserRepository.php
  20. 0
      var/cache/.gitkeep

@ -2227,7 +2227,8 @@ class CourseManager
public static function get_group_list_of_course(
$course_code,
$session_id = 0,
$getEmptyGroups = 0
$getEmptyGroups = 0,
$asArray = false
) {
$course_info = api_get_course_info($course_code);
@ -2254,7 +2255,11 @@ class CourseManager
continue;
}
}
$groupList[$group->getIid()] = $group;
if ($asArray) {
$groupList[$group->getIid()] = ['id' => $group->getIid(), 'name' => $group->getName()];
} else {
$groupList[$group->getIid()] = $group;
}
}
/* 0 != $session_id ? $session_condition = ' WHERE g.session_id IN(1,'.intval($session_id).')' : $session_condition = ' WHERE g.session_id = 0';

@ -5,8 +5,10 @@
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Entity\Session as SessionEntity;
use Chamilo\CourseBundle\Entity\CLpRelUser;
use Chamilo\CoreBundle\Framework\Container;
use Chamilo\CoreBundle\Repository\Node\CourseRepository;
use Chamilo\CourseBundle\Repository\CLpRelUserRepository;
use Chamilo\CourseBundle\Component\CourseCopy\CourseArchiver;
use Chamilo\CourseBundle\Component\CourseCopy\CourseBuilder;
use Chamilo\CourseBundle\Component\CourseCopy\CourseRestorer;
@ -1818,33 +1820,113 @@ class learnpath
// Try group
$is_visible = false;
// Checking only the user visibility
// @todo fix visibility
$userVisibility = 1;
if (1 == $userVisibility) {
$is_visible = true;
} else {
$userGroups = GroupManager::getAllGroupPerUserSubscription($student_id, $courseId);
if (!empty($userGroups)) {
foreach ($userGroups as $groupInfo) {
$groupId = $groupInfo['iid'];
// @todo fix visibility.
$userVisibility = 1;
if (1 == $userVisibility) {
$is_visible = true;
break;
}
}
}
$userVisibility = self::isUserSubscribedToLp($lp, $student_id, $course, $session);
if (true === $userVisibility) {
return true;
}
// Try with groups
$groupVisibility = self::isGroupSubscribedToLp($lp, $student_id, $course, $session);
if (true === $groupVisibility) {
return true;
}
}
}
return $is_visible;
} else {
$is_visible = true;
$subscriptionSettings = self::getSubscriptionSettings();
// Check if the subscription users/group to a LP is ON
if (1 == $lp->getSubscribeUsers() &&
true === $subscriptionSettings['allow_add_users_to_lp']
) {
$is_visible = false;
$userVisibility = self::isUserSubscribedToLp($lp, $student_id, $course, $session);
if (true === $userVisibility) {
return true;
}
// Try with groups
$groupVisibility = self::isGroupSubscribedToLp($lp, $student_id, $course, $session);
if (true === $groupVisibility) {
return true;
}
}
return $is_visible;
}
return true;
}
public static function isGroupSubscribedToLp(
CLp $lp,
int $studentId,
Course $course,
SessionEntity $session = null
): bool {
// Subscribed groups to a LP
$links = $lp->getResourceNode()->getResourceLinks();
$selectedChoices = [];
foreach ($links as $link) {
if (null !== $link->getGroup()) {
$selectedChoices[] = $link->getGroup()->getIid();
}
}
$isVisible = false;
$userGroups = GroupManager::getAllGroupPerUserSubscription($studentId, $course->getId());
if (!empty($userGroups)) {
foreach ($userGroups as $groupInfo) {
$groupId = $groupInfo['iid'];
if (in_array($groupId, $selectedChoices)) {
$isVisible = true;
break;
}
}
}
return $isVisible;
}
public static function isUserSubscribedToLp(
CLp $lp,
int $studentId,
Course $course,
SessionEntity $session = null
): bool {
$isVisible = true;
$em = Database::getManager();
/** @var CLpRelUserRepository $cLpRelUserRepo */
$cLpRelUserRepo = $em->getRepository(CLpRelUser::class);
// Getting subscribed users to a LP.
$subscribedUsersInLp = $cLpRelUserRepo->getUsersSubscribedToItem(
$lp,
$course,
$session
);
$selectedChoices = [];
foreach ($subscribedUsersInLp as $users) {
/** @var \Chamilo\CourseBundle\Entity\CLpRelUser $users */
$selectedChoices[] = $users->getUser()->getId();
}
if (!api_is_allowed_to_edit() && !in_array($studentId, $selectedChoices)) {
$isVisible = false;
}
return $isVisible;
}
/**
* @param int $lpId
* @param int $userId

@ -6,6 +6,8 @@ use Chamilo\CoreBundle\Entity\Usergroup;
use Chamilo\CoreBundle\Framework\Container;
use Chamilo\CourseBundle\Entity\CLp;
use Chamilo\CourseBundle\Entity\CLpCategory;
use Chamilo\CourseBundle\Entity\CLpRelUser;
use Chamilo\CourseBundle\Repository\CLpRelUserRepository;
/**
* Report from students for learning path.
@ -59,33 +61,21 @@ $session = api_get_session_entity($sessionId);
$em = Database::getManager();
// Check LP subscribers
if ('1' === $lp->getSubscribeUsers()) {
/** @var ItemPropertyRepository $itemRepo */
$itemRepo = $em->getRepository('ChamiloCourseBundle:CItemProperty');
$subscribedUsersInLp = $itemRepo->getUsersSubscribedToItem(
'learnpath',
$lpId,
$course,
$session
);
// Subscribed groups to a LP
$subscribedGroupsInLp = $itemRepo->getGroupsSubscribedToItem(
'learnpath',
$lpId,
/** @var CLpRelUserRepository $cLpRelUserRepo */
$cLpRelUserRepo = $em->getRepository('ChamiloCourseBundle:CLpRelUser');
$subscribedUsersInLp = $cLpRelUserRepo->getUsersSubscribedToItem(
$entity,
$course,
$session
);
// Subscribed groups to a LP
$links = $entity->getResourceNode()->getResourceLinks();
$groups = [];
/** @var CItemProperty $itemProperty */
if (!empty($subscribedGroupsInLp)) {
foreach ($subscribedGroupsInLp as $itemProperty) {
if (!empty($itemProperty)) {
$getGroup = $itemProperty->getGroup();
if (!empty($getGroup)) {
$groups[] = $itemProperty->getGroup()->getId();
}
}
foreach ($links as $link) {
if (null !== $link->getGroup()) {
$groups[] = $link->getGroup()->getIid();
}
}
@ -102,10 +92,11 @@ if ('1' === $lp->getSubscribeUsers()) {
}
if (!empty($subscribedUsersInLp)) {
foreach ($subscribedUsersInLp as $itemProperty) {
$user = $itemProperty->getToUser();
foreach ($subscribedUsersInLp as $users) {
/** @var CLpRelUser $users */
$user = $users->getUser();
if ($user) {
$users[]['user_id'] = $itemProperty->getToUser()->getId();
$users[]['user_id'] = $user->getId();
}
}
}

@ -2,9 +2,11 @@
/* For licensing terms, see /license.txt */
use Chamilo\CourseBundle\Repository\CLpRelUserRepository;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CourseBundle\Entity\CLpRelUser;
use Chamilo\CoreBundle\Framework\Container;
use Chamilo\CourseBundle\Entity\CLp;
@ -53,6 +55,9 @@ $url = api_get_self().'?'.api_get_cidreq().'&lp_id='.$lpId;
$em = Database::getManager();
$courseRepo = Container::getCourseRepository();
/** @var CLpRelUserRepository $cLpRelUserRepo */
$cLpRelUserRepo = $em->getRepository(CLpRelUser::class);
/** @var Session $session */
$session = null;
if (!empty($sessionId)) {
@ -85,16 +90,16 @@ foreach ($subscribedUsers as $user) {
}
// Getting subscribed users to a LP.
$subscribedUsersInLp = $itemRepo->getUsersSubscribedToItem(
'learnpath',
$lpId,
$subscribedUsersInLp = $cLpRelUserRepo->getUsersSubscribedToItem(
$entity,
$course,
$session
);
$selectedChoices = [];
foreach ($subscribedUsersInLp as $itemProperty) {
$selectedChoices[] = $itemProperty->getToUser()->getId();
foreach ($subscribedUsersInLp as $users) {
/** @var CLpRelUser $users */
$selectedChoices[] = $users->getUser()->getId();
}
//Building the form for Users
@ -116,6 +121,9 @@ if (!empty($selectedChoices)) {
$formUsers->setDefaults($defaults);
// Subscribed groups to a LP
$links = $entity->getResourceNode()->getResourceLinks();
// Building the form for Groups
$form = new FormValidator('lp_edit', 'post', $url);
$form->addElement('hidden', 'group_form', 1);
@ -124,22 +132,16 @@ $form->addElement('hidden', 'group_form', 1);
$groupList = \CourseManager::get_group_list_of_course(
api_get_course_id(),
api_get_session_id(),
1
1,
true
);
$groupChoices = array_column($groupList, 'name', 'id');
// Subscribed groups to a LP
$subscribedGroupsInLp = $itemRepo->getGroupsSubscribedToItem(
'learnpath',
$lpId,
$course,
$session
);
$selectedGroupChoices = [];
/** @var CItemProperty $itemProperty */
foreach ($subscribedGroupsInLp as $itemProperty) {
$selectedGroupChoices[] = $itemProperty->getGroup()->getId();
foreach ($links as $link) {
if (null !== $link->getGroup()) {
$selectedGroupChoices[] = $link->getGroup()->getIid();
}
}
$groupMultiSelect = $form->addMultiSelect(
@ -197,11 +199,10 @@ if ($allowUserGroups) {
Database::query($sql);
$userList = $userGroup->get_users_by_usergroup($userGroupId);
$itemRepo->unsubcribeUsersToItem(
'learnpath',
$cLpRelUserRepo->unsubcribeUsersToItem(
$course,
$session,
$lpId,
$entity,
$userList
);
}
@ -236,12 +237,11 @@ if ($allowUserGroups) {
$userList = [];
foreach ($groups as $groupId) {
$userList = $userGroup->get_users_by_usergroup($groupId);
$itemRepo->subscribeUsersToItem(
$cLpRelUserRepo->subscribeUsersToItem(
$currentUser,
'learnpath',
$course,
$session,
$lpId,
$entity,
$userList,
false
);
@ -251,11 +251,10 @@ if ($allowUserGroups) {
} else {
foreach ($groups as $group) {
$userList = $userGroup->get_users_by_usergroup($group['id']);
$itemRepo->unsubcribeUsersToItem(
'learnpath',
$cLpRelUserRepo->unsubcribeUsersToItem(
$course,
$session,
$lpId,
$entity,
$userList
);
}
@ -294,12 +293,11 @@ if ($form->validate()) {
$userForm = isset($values['user_form']) ? $values['user_form'] : [];
if (!empty($userForm)) {
$itemRepo->subscribeUsersToItem(
$cLpRelUserRepo->subscribeUsersToItem(
$currentUser,
'learnpath',
$course,
$session,
$lpId,
$entity,
$users
);
Display::addFlash(Display::return_message(get_lang('Update successful')));
@ -310,14 +308,28 @@ if ($form->validate()) {
$groupForm = isset($values['group_form']) ? $values['group_form'] : [];
if (!empty($groupForm)) {
$itemRepo->subscribeGroupsToItem(
$currentUser,
'learnpath',
$course,
$session,
$lpId,
$groups
);
if (!empty($selectedGroupChoices)) {
$diff = array_diff($selectedGroupChoices, $groups);
if (!empty($diff)) {
foreach ($diff as $groupIdToDelete) {
foreach ($links as $link) {
if ($link->getGroup() && $link->getGroup()->getIid()) {
$em->remove($link);
}
}
}
$em->flush();
}
}
foreach ($groups as $groupId) {
$group = api_get_group_entity($groupId);
$entity->addGroupLink($course, $group);
}
$em->persist($entity);
$em->flush();
Display::addFlash(Display::return_message(get_lang('Update successful')));
}

@ -64,7 +64,8 @@ $form->addLabel('', $message);
$groupList = \CourseManager::get_group_list_of_course(
api_get_course_id(),
api_get_session_id(),
1
1,
true
);
$groupChoices = array_column($groupList, 'name', 'id');
$session = api_get_session_entity($sessionId);
@ -267,7 +268,7 @@ $formUsers->setDefaults($defaults);
// Building the form for Groups
$tpl = new Template();
if ($formUsers->validate()) {
if ($form->validate()) {
$values = $formUsers->getSubmitValues();
// Subscribing users

@ -594,22 +594,22 @@ class IndexBlocksController extends BaseController
$items = [];
$items[] = [
'class' => 'item-skill-wheel',
'url' => $this->generateUrl('legacy_main', ['name' => 'admin/skills_wheel.php']),
'url' => $this->generateUrl('legacy_main', ['name' => 'skills/skills_wheel.php']),
'label' => $this->translator->trans('Skills wheel'),
];
$items[] = [
'class' => 'item-skill-import',
'url' => $this->generateUrl('legacy_main', ['name' => 'admin/skills_import.php']),
'url' => $this->generateUrl('legacy_main', ['name' => 'skills/skills_import.php']),
'label' => $this->translator->trans('Skills import'),
];
$items[] = [
'class' => 'item-skill-list',
'url' => $this->generateUrl('legacy_main', ['name' => 'admin/skill_list.php']),
'url' => $this->generateUrl('legacy_main', ['name' => 'skills/skill_list.php']),
'label' => $this->translator->trans('Manage skills'),
];
$items[] = [
'class' => 'item-skill-level',
'url' => $this->generateUrl('legacy_main', ['name' => 'admin/skill.php']),
'url' => $this->generateUrl('legacy_main', ['name' => 'skills/skill.php']),
'label' => $this->translator->trans('Manage skills levels'),
];
@ -620,7 +620,7 @@ class IndexBlocksController extends BaseController
];
$items[] = [
'class' => 'item-skill-gradebook',
'url' => $this->generateUrl('legacy_main', ['name' => 'admin/skills_gradebook.php']),
'url' => $this->generateUrl('legacy_main', ['name' => 'skills/skills_gradebook.php']),
'label' => $this->translator->trans('Skills and assessments'),
];
/*$items[] = [

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\DataFixtures;
use Chamilo\CoreBundle\Entity\ResourceFormat;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
class ResourceFormatFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
$list = [
[
'name' => 'html',
],
[
'name' => 'txt',
],
];
foreach ($list as $key => $data) {
$resourceFormat = (new ResourceFormat())
->setName($data['name'])
;
$manager->persist($resourceFormat);
}
$manager->flush();
}
}

@ -13,6 +13,7 @@ use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\EntityAccessUrlInterface;
use Chamilo\CoreBundle\Entity\PersonalFile;
use Chamilo\CoreBundle\Entity\ResourceFile;
use Chamilo\CoreBundle\Entity\ResourceFormat;
use Chamilo\CoreBundle\Entity\ResourceNode;
use Chamilo\CoreBundle\Entity\ResourceToRootInterface;
use Chamilo\CoreBundle\Entity\ResourceType;
@ -198,6 +199,28 @@ class ResourceListener
->setResourceType($resourceType)
->setParent($parentNode)
;
// Set ResourceFormat.
$txtTypes = [
'events',
'event_attachments',
'illustrations',
'links',
'files',
'courses',
'users',
'external_tools',
'usergroups',
];
$resourceFormatRepo = $em->getRepository(ResourceFormat::class);
$formatName = (in_array($name, $txtTypes) ? 'txt' : 'html');
$resourceFormat = $resourceFormatRepo->findOneBy([
'name' => $formatName,
]);
if ($resourceFormat) {
$resourceNode->setResourceFormat($resourceFormat);
}
$resource->setResourceNode($resourceNode);
// Update resourceNode title from Resource.

@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity]
#[ORM\Table(name: "resource_format")]
class ResourceFormat
{
use TimestampableEntity;
#[ORM\Id]
#[ORM\Column(type: "integer")]
#[ORM\GeneratedValue]
protected ?int $id = null;
#[ORM\Column]
#[Assert\NotBlank]
protected string $name;
/**
* @var Collection<int, ResourceNode>
*/
#[ORM\OneToMany(targetEntity: ResourceNode::class, mappedBy: "resourceFormat", cascade: ["persist", "remove"])]
protected Collection $resourceNodes;
public function __construct()
{
$this->resourceNodes = new ArrayCollection();
}
public function __toString(): string
{
return $this->name;
}
public function getId(): int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection<int, ResourceNode>
*/
public function getResourceNodes(): Collection
{
return $this->resourceNodes;
}
/**
* @param Rollection<int, ResourceNode>
*/
public function setResourceNodes(Collection $resourceNodes): self
{
$this->resourceNodes = $resourceNodes;
return $this;
}
}

@ -91,7 +91,13 @@ class ResourceNode implements Stringable
#[Assert\NotNull]
#[ORM\ManyToOne(targetEntity: ResourceType::class, inversedBy: 'resourceNodes')]
#[ORM\JoinColumn(name: 'resource_type_id', referencedColumnName: 'id', nullable: false)]
#[Gedmo\SortableGroup]
protected ResourceType $resourceType;
#[ORM\ManyToOne(targetEntity: ResourceFormat::class, cascade: ["persist", "remove"], inversedBy: "resourceNodes")]
#[ORM\JoinColumn(name: "resource_format_id", referencedColumnName: "id")]
protected ResourceFormat $resourceFormat;
/**
* @var Collection<int, ResourceLink>
*/
@ -115,6 +121,7 @@ class ResourceNode implements Stringable
#[ORM\JoinColumn(name: 'parent_id', onDelete: 'CASCADE')]
#[Gedmo\TreeParent]
#[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')]
#[Gedmo\SortableGroup]
protected ?ResourceNode $parent = null;
/**
* @var Collection|ResourceNode[]
@ -160,6 +167,10 @@ class ResourceNode implements Stringable
#[Groups(['resource_node:read', 'document:read'])]
#[ORM\Column(type: 'uuid', unique: true)]
protected ?UuidV4 $uuid = null;
#[ORM\Column(name: 'display_order', type: 'integer', nullable: false)]
#[Gedmo\SortablePosition]
protected int $displayOrder;
public function __construct()
{
$this->public = false;
@ -169,6 +180,7 @@ class ResourceNode implements Stringable
$this->comments = new ArrayCollection();
$this->createdAt = new DateTime();
$this->fileEditableText = false;
$this->displayOrder = 0;
}
public function __toString(): string
{
@ -349,6 +361,19 @@ class ResourceNode implements Stringable
return $this;
}
public function getResourceFormat(): ?ResourceFormat
{
return $this->resourceFormat;
}
public function setResourceFormat(ResourceFormat $resourceFormat): self
{
$this->resourceFormat = $resourceFormat;
return $this;
}
public function getResourceLinks(): Collection
{
return $this->resourceLinks;
@ -486,4 +511,16 @@ class ResourceNode implements Stringable
return $this;
}
public function getDisplayOrder(): int
{
return $this->displayOrder;
}
public function setDisplayOrder(int $displayOrder): self
{
$this->displayOrder = $displayOrder;
return $this;
}
}

@ -33,6 +33,9 @@ class Version20170525122900 extends AbstractMigrationChamilo
);
$this->addSql('CREATE UNIQUE INDEX UNIQ_8A5F48FFD17F50A6 ON resource_node (uuid)');
$this->addSql('ALTER TABLE resource_node ADD public TINYINT(1) NOT NULL');
$this->addSql(
'ALTER TABLE resource_node ADD display_order INT NOT NULL'
);
}
if (!$schema->hasTable('resource_link')) {

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
use Doctrine\DBAL\Schema\Schema;
final class Version20230215062918 extends AbstractMigrationChamilo
{
public function getDescription(): string
{
return 'Learnpath subscription changes';
}
public function up(Schema $schema): void
{
if (false === $schema->hasTable('c_lp_rel_user')) {
$this->addSql(
"CREATE TABLE c_lp_rel_user (iid INT AUTO_INCREMENT NOT NULL, lp_id INT DEFAULT NULL, c_id INT NOT NULL, session_id INT DEFAULT NULL, user_id INT NOT NULL, creator_id INT DEFAULT NULL, created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime)', INDEX IDX_AD97516E68DFD1EF (lp_id), INDEX IDX_AD97516E91D79BD3 (c_id), INDEX IDX_AD97516E613FECDF (session_id), INDEX IDX_AD97516EA76ED395 (user_id), INDEX IDX_AD97516E61220EA6 (creator_id), PRIMARY KEY(iid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB ROW_FORMAT = DYNAMIC;"
);
$this->addSql("ALTER TABLE c_lp_rel_user ADD CONSTRAINT FK_AD97516E68DFD1EF FOREIGN KEY (lp_id) REFERENCES c_lp (iid);");
$this->addSql("ALTER TABLE c_lp_rel_user ADD CONSTRAINT FK_AD97516E91D79BD3 FOREIGN KEY (c_id) REFERENCES course (id);");
$this->addSql("ALTER TABLE c_lp_rel_user ADD CONSTRAINT FK_AD97516E613FECDF FOREIGN KEY (session_id) REFERENCES session (id);");
$this->addSql("ALTER TABLE c_lp_rel_user ADD CONSTRAINT FK_AD97516EA76ED395 FOREIGN KEY (user_id) REFERENCES user (id);");
$this->addSql("ALTER TABLE c_lp_rel_user ADD CONSTRAINT FK_AD97516E61220EA6 FOREIGN KEY (creator_id) REFERENCES user (id);");
}
}
public function down(Schema $schema): void
{
}
}

@ -0,0 +1,94 @@
<?php
declare(strict_types=1);
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
use Chamilo\CoreBundle\Repository\Node\CourseRepository;
use Chamilo\CourseBundle\Entity\CLp;
use Chamilo\CourseBundle\Entity\CLpRelUser;
use Chamilo\CourseBundle\Repository\CLpRelUserRepository;
use Chamilo\Kernel;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\Schema;
final class Version20230215072918 extends AbstractMigrationChamilo
{
public function getDescription(): string
{
return 'Migrate learnpath subscription';
}
public function up(Schema $schema): void
{
$container = $this->getContainer();
$doctrine = $container->get('doctrine');
$em = $doctrine->getManager();
/** @var Connection $connection */
$connection = $em->getConnection();
$lpRepo = $container->get(CLp::class);
/** @var CLpRelUserRepository $cLpRelUserRepo */
$cLpRelUserRepo = $container->get(CLpRelUser::class);
$courseRepo = $container->get(CourseRepository::class);
$sessionRepo = $container->get(Session::class);
$userRepo = $container->get(User::class);
/** @var Kernel $kernel */
$kernel = $container->get('kernel');
$rootPath = $kernel->getProjectDir();
$admin = $this->getAdmin();
$q = $em->createQuery('SELECT c FROM Chamilo\CoreBundle\Entity\Course c');
/** @var Course $course */
foreach ($q->toIterable() as $course) {
$courseId = $course->getId();
$course = $courseRepo->find($courseId);
$sql = "SELECT * FROM c_lp WHERE c_id = {$courseId}
ORDER BY iid";
$result = $connection->executeQuery($sql);
$lps = $result->fetchAllAssociative();
foreach ($lps as $lpData) {
$id = $lpData['iid'];
$lp = $lpRepo->find($id);
$sql = "SELECT * FROM c_item_property
WHERE tool = 'learnpath' AND c_id = {$courseId} AND ref = {$id} AND lastedit_type = 'LearnpathSubscription'";
$result = $connection->executeQuery($sql);
$items = $result->fetchAllAssociative();
if (!empty($items)) {
foreach ($items as $item) {
$sessionId = $item['session_id'] ?? 0;
$userId = $item['to_user_id'] ?? 0;
$session = $sessionRepo->find($sessionId);
$user = $userRepo->find($userId);
$item = new CLpRelUser();
$item
->setUser($user)
->setCourse($course)
->setLp($lp);
if (!empty($session)) {
$item->setSession($session);
}
$em->persist($item);
$em->flush();
}
}
}
}
}
public function down(Schema $schema): void
{
}
}

@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
use Doctrine\DBAL\Schema\Schema;
final class Version20230306145019 extends AbstractMigrationChamilo
{
public function getDescription(): string
{
return 'Create table resource_format';
}
public function up(Schema $schema): void
{
if (!$schema->hasTable('resource_format')) {
$this->addSql(
"CREATE TABLE resource_format (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime)', updated_at DATETIME NOT NULL COMMENT '(DC2Type:datetime)', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB ROW_FORMAT = DYNAMIC;"
);
$this->addSql(
'ALTER TABLE resource_node ADD resource_format_id INT DEFAULT NULL;'
);
$this->addSql(
'ALTER TABLE resource_node ADD CONSTRAINT FK_8A5F48FF7EE0A59A FOREIGN KEY (resource_format_id) REFERENCES resource_format (id) ON DELETE SET NULL;'
);
$this->addSql(
'CREATE INDEX IDX_8A5F48FF7EE0A59A ON resource_node (resource_format_id);'
);
}
}
public function down(Schema $schema): void
{
if ($schema->hasTable('resource_format')) {
$this->addSql(
'ALTER TABLE resource_node DROP FOREIGN KEY FK_8A5F48FF7EE0A59A;'
);
$this->addSql(
'ALTER TABLE resource_node DROP INDEX IDX_8A5F48FF7EE0A59A;'
);
$this->addSql(
'ALTER TABLE resource_node DROP resource_format_id;'
);
$this->addSql(
'DROP TABLE resource_format;'
);
}
}
}

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
use Doctrine\DBAL\Schema\Schema;
final class Version20230306150219 extends AbstractMigrationChamilo
{
public function getDescription(): string
{
return 'Insert default values to table resource_format';
}
public function up(Schema $schema): void
{
$connection = $this->getEntityManager()->getConnection();
if ($schema->hasTable('resource_format')) {
$result = $connection->executeQuery(" SELECT * FROM resource_format WHERE name = 'html'");
$exists = $result->fetchAllAssociative();
if (empty($exists)) {
$this->addSql("INSERT INTO resource_format SET name = 'html', created_at = NOW(), updated_at = NOW();");
}
$result = $connection->executeQuery(" SELECT * FROM resource_format WHERE name = 'txt'");
$exists = $result->fetchAllAssociative();
if (empty($exists)) {
$this->addSql("INSERT INTO resource_format SET name = 'txt', created_at = NOW(), updated_at = NOW();");
}
}
}
public function down(Schema $schema): void
{
$connection = $this->getEntityManager()->getConnection();
if ($schema->hasTable('resource_format')) {
$result = $connection->executeQuery(" SELECT * FROM resource_format WHERE name = 'txt'");
$exists = $result->fetchAllAssociative();
if (!empty($exists)) {
$this->addSql("DELETE FROM resource_format WHERE name = 'txt';");
}
$result = $connection->executeQuery(" SELECT * FROM resource_format WHERE name = 'html'");
$exists = $result->fetchAllAssociative();
if (!empty($exists)) {
$this->addSql("DELETE FROM resource_format WHERE name = 'html';");
}
}
}
}

@ -181,18 +181,19 @@ class ToolChain
/** @var Tool $toolEntity */
$toolEntity = $toolRepo->findOneBy($criteria);
$position = $toolList[$tool->getName()] + 1;
$courseTool = (new CTool())
->setTool($toolEntity)
->setName($tool->getName())
->setPosition($position)
->setVisibility($visibility)
->setParent($course)
->setCreator($course->getCreator())
->addCourseLink($course)
;
$course->addTool($courseTool);
if ($toolEntity) {
$position = $toolList[$tool->getName()] + 1;
$courseTool = (new CTool())
->setTool($toolEntity)
->setName($tool->getName())
->setPosition($position)
->setVisibility($visibility)
->setParent($course)
->setCreator($course->getCreator())
->addCourseLink($course);
$course->addTool($courseTool);
}
}
return $course;

@ -27,8 +27,8 @@ class CLpCategoryRelUserGroup
protected ?int $id = null;
#[ORM\ManyToOne(targetEntity: CLpCategory::class)]
#[ORM\JoinColumn(name: 'category_id', referencedColumnName: 'iid')]
protected CLpCategory $category;
#[ORM\JoinColumn(name: "lp_category_id", referencedColumnName: "iid")]
protected CLpCategory $lpCategory;
#[ORM\ManyToOne(targetEntity: Session::class)]
#[ORM\JoinColumn(name: 'session_id', referencedColumnName: 'id', nullable: true)]
@ -49,4 +49,60 @@ class CLpCategoryRelUserGroup
public function __construct()
{
}
/**
* @return CLpCategory
*/
public function getLpCategory(): CLpCategory
{
return $this->lpCategory;
}
/**
* @param CLpCategory $lpCategory
*/
public function setLpCategory(CLpCategory $lpCategory): self
{
$this->lpCategory = $lpCategory;
return $this;
}
/**
* @return Usergroup|null
*/
public function getUserGroup(): ?Usergroup
{
return $this->userGroup;
}
/**
* @param Usergroup|null $userGroup
*/
public function setUserGroup(?Usergroup $userGroup): self
{
$this->userGroup = $userGroup;
return $this;
}
/**
* @return DateTime
*/
public function getCreatedAt(): DateTime
{
return $this->createdAt;
}
/**
* @param DateTime $createdAt
*/
public function setCreatedAt(DateTime $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
}

@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace Chamilo\CourseBundle\Entity;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Traits\CourseTrait;
use Chamilo\CoreBundle\Traits\SessionTrait;
use Chamilo\CoreBundle\Traits\UserTrait;
use Chamilo\CourseBundle\Repository\CLpRelUserRepository;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
#[ORM\Table(name: "c_lp_rel_user")]
#[ORM\Entity(repositoryClass: CLpRelUserRepository::class)]
class CLpRelUser
{
use CourseTrait;
use SessionTrait;
use UserTrait;
#[ORM\Column(name: "iid", type: "integer")]
#[ORM\Id]
#[ORM\GeneratedValue]
protected int $iid;
#[ORM\ManyToOne(targetEntity: CLp::class)]
#[ORM\JoinColumn(name: "lp_id", referencedColumnName: "iid")]
protected CLp $lp;
#[ORM\ManyToOne(targetEntity: Course::class)]
#[ORM\JoinColumn(name: "c_id", referencedColumnName: "id", nullable: false)]
protected Course $course;
#[ORM\ManyToOne(targetEntity: Session::class)]
#[ORM\JoinColumn(name: "session_id", referencedColumnName: "id", nullable: true)]
protected ?Session $session = null;
#[ORM\ManyToOne(targetEntity: User::class)]
#[ORM\JoinColumn(name: "user_id", referencedColumnName: "id", nullable: false)]
protected User $user;
#[Gedmo\Timestampable(on: "create")]
#[ORM\Column(name: "created_at", type: "datetime", nullable: false)]
protected DateTime $createdAt;
#[ORM\ManyToOne(targetEntity: User::class, cascade: ["persist"])]
#[ORM\JoinColumn(name: "creator_id", referencedColumnName: "id")]
protected $creatorUser;
public function getIid(): int
{
return $this->iid;
}
public function setIid(int $iid): self
{
$this->iid = $iid;
return $this;
}
public function getLp(): CLp
{
return $this->lp;
}
public function setLp(CLp $lp): self
{
$this->lp = $lp;
return $this;
}
public function getCreatedAt(): DateTime
{
return $this->createdAt;
}
public function setCreatedAt(DateTime $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getCreatorUser()
{
return $this->creatorUser;
}
public function setCreatorUser(User $creatorUser): self
{
$this->creatorUser = $creatorUser;
return $this;
}
}

@ -0,0 +1,162 @@
<?php
declare(strict_types=1);
/* For licensing terms, see /license.txt */
namespace Chamilo\CourseBundle\Repository;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Repository\ResourceRepository;
use Chamilo\CourseBundle\Entity\CLp;
use Chamilo\CourseBundle\Entity\CLpRelUser;
use Doctrine\Persistence\ManagerRegistry;
/**
* Class CLpRelUserRepository.
*/
final class CLpRelUserRepository extends ResourceRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, CLpRelUser::class);
}
/**
* Get users subscribed to a item LP.
*
* @param CLp $lp
* @param Course $course
* @param Session $session
*
* @return array
*/
public function getUsersSubscribedToItem(
CLp $lp,
Course $course,
Session $session = null
) {
$criteria = [
'lp' => $lp,
'course' => $course,
'session' => $session,
];
return $this->findBy($criteria);
}
/**
* Subscribe users to a LP.
*
* @param User $currentUser
* @param Course $course
* @param Session $session
* @param CLp $lp
* @param array $newUserList
* @param bool $deleteUsers
*/
public function subscribeUsersToItem(
$currentUser,
Course $course,
Session $session = null,
CLp $lp,
$newUserList = [],
$deleteUsers = true
) {
$em = $this->getEntityManager();
$user = $em->getRepository(User::class);
$usersSubscribedToItem = $this->getUsersSubscribedToItem(
$lp,
$course,
$session
);
$alreadyAddedUsers = [];
if ($usersSubscribedToItem) {
/** @var CLpRelUser $lpUser */
foreach ($usersSubscribedToItem as $lpUser) {
$getToUser = $lpUser->getUser();
if (!empty($getToUser)) {
$alreadyAddedUsers[] = $lpUser->getUser()->getId();
}
}
}
if ($deleteUsers) {
$usersToDelete = $alreadyAddedUsers;
if (!empty($newUserList)) {
$usersToDelete = array_diff($alreadyAddedUsers, $newUserList);
}
if ($usersToDelete) {
$this->unsubcribeUsersToItem(
$course,
$session,
$lp,
$usersToDelete
);
}
}
foreach ($newUserList as $userId) {
if (!in_array($userId, $alreadyAddedUsers)) {
$userObj = $user->find($userId);
if ($userObj) {
$item = new CLpRelUser();
$item
->setUser($userObj)
->setCourse($course)
->setLp($lp)
->setCreatedAt(api_get_utc_datetime(null, false, true))
->setCreatorUser(api_get_user_entity());
if (!empty($session)) {
$item->setSession($session);
}
$em->persist($item); //$em is an instance of EntityManager
}
}
}
$em->flush();
}
/**
* Unsubscribe users to Lp.
*
* @param Course $course
* @param Session $session
* @param CLp $lp
* @param array $usersToDelete
*/
public function unsubcribeUsersToItem(
Course $course,
Session $session = null,
CLp $lp,
$usersToDelete
) {
$em = $this->getEntityManager();
if (!empty($usersToDelete)) {
foreach ($usersToDelete as $userId) {
$userId = (int) $userId;
$item = $this->findOneBy(
[
'course' => $course,
'session' => $session,
'lp' => $lp,
'user' => api_get_user_entity($userId),
]
);
if ($item) {
$em->remove($item);
}
}
$em->flush();
}
}
}
Loading…
Cancel
Save