Chamilo is a learning management system focused on ease of use and accessibility
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
chamilo-lms/src/ApiBundle/GraphQL/Resolver/CourseResolver.php

598 lines
18 KiB

<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\ApiBundle\GraphQL\Resolver;
use Chamilo\ApiBundle\GraphQL\ApiGraphQLTrait;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
use Chamilo\CourseBundle\Entity\CAnnouncement;
use Chamilo\CourseBundle\Entity\CForumCategory;
use Chamilo\CourseBundle\Entity\CForumForum;
use Chamilo\CourseBundle\Entity\CForumThread;
use Chamilo\CourseBundle\Entity\CItemProperty;
use Chamilo\CourseBundle\Entity\CLpCategory;
use Chamilo\CourseBundle\Entity\CTool;
use Chamilo\CourseBundle\Repository\CNotebookRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
use Firebase\JWT\JWT;
use Overblog\GraphQLBundle\Definition\Argument;
use Overblog\GraphQLBundle\Error\UserError;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
/**
* Class CourseResolver.
*
* @package Chamilo\ApiBundle\GraphQL\Resolver
*/
class CourseResolver implements ContainerAwareInterface
{
use ApiGraphQLTrait;
/**
* @param Course $course
* @param Argument $args
*
* @return string|null
*/
public function getPicture(Course $course, Argument $args)
{
return \CourseManager::getPicturePath($course, $args['fullSize']);
}
/**
* @param Course $course
* @param Argument $args
* @param \ArrayObject $context
*
* @return array
*/
public function getTeachers(Course $course, Argument $args, \ArrayObject $context): array
{
if ($context->offsetExists('session')) {
/** @var Session $session */
$session = $context->offsetGet('session');
if ($session) {
$coaches = [];
$coachSubscriptions = $session->getUserCourseSubscriptionsByStatus($course, Session::COACH);
/** @var SessionRelCourseRelUser $coachSubscription */
foreach ($coachSubscriptions as $coachSubscription) {
$coaches[] = $coachSubscription->getUser();
}
return $coaches;
}
}
$courseRepo = $this->em->getRepository('ChamiloCoreBundle:Course');
$teachers = $courseRepo
->getSubscribedTeachers($course)
->getQuery()
->getResult();
return $teachers;
}
/**
* @param Course $course
* @param Argument $args
* @param \ArrayObject $context
*
* @return ArrayCollection
*/
public function getTools(Course $course, Argument $args, \ArrayObject $context): ArrayCollection
{
$session = null;
if ($context->offsetExists('session')) {
/** @var Session $session */
$session = $context->offsetGet('session');
}
if (empty($args['type'])) {
return $course->getTools($session);
}
$criteria = Criteria::create()
->where(
Criteria::expr()->eq('name', $args['type'])
);
return $course->getTools($session)->matching($criteria);
}
/**
* @param CTool $tool
* @param \ArrayObject $context
*
* @return array
*/
public function getDescriptions(Ctool $tool, \ArrayObject $context)
{
/** @var Session $session */
$session = $context->offsetGet('session');
$cd = new \CourseDescription();
$cd->set_course_id($tool->getCourse()->getId());
if ($session) {
$cd->set_session_id($session->getId());
}
$descriptions = $cd->get_description_data();
if (empty($descriptions)) {
return [];
}
$qb = $this->em->createQueryBuilder();
$qb
->select('d')
->from('ChamiloCourseBundle:CCourseDescription', 'd')
->where(
$qb->expr()->in('d.id', array_keys($descriptions['descriptions']))
);
return $qb->getQuery()->getResult();
}
/**
* @param CTool $tool
* @param \ArrayObject $context
*
* @return array
*/
public function getAnnouncements(CTool $tool, \ArrayObject $context): array
{
$announcementManager = $this->container->get('chamilo_course.entity.manager.announcement_manager');
$announcementsInfo = $announcementManager->getAnnouncements(
$this->getCurrentUser(),
$tool->getCourse(),
null,
$context->offsetGet('session'),
api_get_course_setting('allow_user_edit_announcement') === 'true',
api_get_configuration_value('hide_base_course_announcements_in_group') === true
);
$announcements = [];
for ($z = 0; $z < count($announcementsInfo); $z += 2) {
$announcements[] = self::getAnnouncementObject($announcementsInfo[$z], $announcementsInfo[$z + 1]);
}
return $announcements;
}
/**
* @param int $id
* @param \ArrayObject $context
*
* @return \stdClass
*/
public function getAnnouncement($id, \ArrayObject $context)
{
$announcementInfo = \AnnouncementManager::getAnnouncementInfoById(
$id,
$context->offsetGet('course')->getId(),
$this->getCurrentUser()->getId()
);
if (empty($announcementInfo)) {
throw new UserError($this->translator->trans('Announcement not found.'));
}
return self::getAnnouncementObject($announcementInfo['announcement'], $announcementInfo['item_property']);
}
/**
* @param \ArrayObject $context
*
* @return array
*/
public function getNotes(\ArrayObject $context): array
{
/** @var CNotebookRepository $notebooksRepo */
$notebooksRepo = $this->em->getRepository('ChamiloCourseBundle:CNotebook');
$notebooks = $notebooksRepo->findByUser(
$this->getCurrentUser(),
$context->offsetGet('course'),
$context->offsetGet('session')
);
return $notebooks;
}
/**
* @param \ArrayObject $context
*
* @return array
*/
public function getForumCategories(\ArrayObject $context): array
{
/** @var Course $course */
$course = $context->offsetGet('course');
/** @var Session $session */
$session = $context->offsetGet('session');
$catRepo = $this->em->getRepository('ChamiloCourseBundle:CForumCategory');
$cats = $catRepo->findAllInCourse(false, $course, $session);
return $cats;
}
/**
* @param CForumCategory $category
* @param \ArrayObject $context
*
* @return array
*/
public function getForums(CForumCategory $category, \ArrayObject $context): array
{
/** @var Course $course */
$course = $context->offsetGet('course');
/** @var Session $session */
$session = $context->offsetGet('session');
$forumRepo = $this->em->getRepository('ChamiloCourseBundle:CForumForum');
$forums = $forumRepo->findAllInCourseByCategory(false, $category, $course, $session);
return $forums;
}
/**
* @param int $id
* @param \ArrayObject $context
*
* @return CForumForum
*/
public function getForum($id, \ArrayObject $context)
{
/** @var Course $course */
$course = $context->offsetGet('course');
$forumRepo = $this->em->getRepository('ChamiloCourseBundle:CForumForum');
$forum = $forumRepo->findOneInCourse($id, $course);
if (empty($forum)) {
throw new UserError($this->translator->trans('Forum not found in this course.'));
}
return $forum;
}
/**
* @param CForumForum $forum
* @param \ArrayObject $context
*
* @return array
*/
public function getThreads(CForumForum $forum, \ArrayObject $context): array
{
/** @var Course $course */
$course = $context->offsetGet('course');
/** @var Session $session */
$session = $context->offsetGet('session');
$threadRepo = $this->em->getRepository('ChamiloCourseBundle:CForumThread');
$threads = $threadRepo->findAllInCourseByForum(false, $forum, $course, $session);
return $threads;
}
/**
* @param int $id
* @param \ArrayObject $context
*
* @return CForumThread
*/
public function getThread($id, \ArrayObject $context)
{
/** @var Course $course */
$course = $context->offsetGet('course');
/** @var Session $session */
$session = $context->offsetGet('session');
$threadRepo = $this->em->getRepository('ChamiloCourseBundle:CForumThread');
$thread = $threadRepo->findOneInCourse($id, $course, $session);
if (empty($thread)) {
throw new UserError($this->translator->trans('Forum thread not found in this course.'));
}
return $thread;
}
/**
* @param CForumThread $thread
* @param \ArrayObject $context
*
* @return array
*/
public function getPosts(CForumThread $thread, \ArrayObject $context)
{
/** @var Course $course */
$course = $context->offsetGet('course');
$postRepo = $this->em->getRepository('ChamiloCourseBundle:CForumPost');
$posts = $postRepo->findAllInCourseByThread(
api_is_allowed_to_edit(false, true),
api_is_allowed_to_edit(),
$thread,
$course,
$this->getCurrentUser()
);
return $posts;
}
/**
* @param \ArrayObject $context
*
* @return array
*/
public function getAgenda(\ArrayObject $context): array
{
/** @var Session|null $session */
$session = $context->offsetGet('session');
/** @var Course $course */
$course = $context->offsetGet('course');
$agenda = new \Agenda(
'course',
$this->getCurrentUser()->getId(),
$course->getId(),
$session ? $session->getId() : 0
);
$result = $agenda->parseAgendaFilter(null);
$firstDay = new \DateTime('now', new \DateTimeZone('UTC'));
$firstDay->modify('first day of this month');
$firstDay->setTime(0, 0);
$lastDay = new \DateTime('now', new \DateTimeZone('UTC'));
$lastDay->modify('last day of this month');
$lastDay->setTime(0, 0);
$groupId = current($result['groups']);
$userId = current($result['users']);
$events = $agenda->getEvents(
$firstDay->getTimestamp(),
$lastDay->getTimestamp(),
$course->getId(),
$groupId,
$userId,
'array'
);
return $events;
}
/**
* @param int $dirId
* @param \ArrayObject $context
*
* @return array
*/
public function getDocuments($dirId, \ArrayObject $context): array
{
$path = '/';
/** @var Course $course */
$course = $context->offsetGet('course');
/** @var Session $session */
$session = $context->offsetGet('session');
if (!empty($dirId)) {
$directory = $this->em->getRepository('ChamiloCourseBundle:CDocument')->find($dirId);
if (empty($directory)) {
throw new UserError($this->translator->trans('Directory not found.'));
}
if (empty($directory->getCourse())) {
throw new UserError('The directory has not been assigned to a course.');
}
if ($directory->getCourse()->getId() !== $course->getId()) {
throw new UserError('The directory has not been assgined to this course.');
}
$path = $directory->getPath();
}
$documents = \DocumentManager::getAllDocumentData(
['code' => $course->getCode(), 'real_id' => $course->getId()],
$path,
0,
null,
false,
false,
$session ? $session->getId() : 0,
$this->getCurrentUser()
);
if (empty($documents)) {
return [];
}
$webPath = api_get_path(WEB_CODE_PATH).'document/document.php?';
$results = array_map(
function ($documentInfo) use ($webPath, $course, $session) {
$icon = $documentInfo['filetype'] == 'file'
? choose_image($documentInfo['path'])
: chooseFolderIcon($documentInfo['path']);
return [
'id' => $documentInfo['id'],
'fileType' => $documentInfo['filetype'],
'title' => $documentInfo['title'],
'comment' => $documentInfo['comment'],
'path' => $documentInfo['path'],
'icon' => $icon,
'size' => format_file_size($documentInfo['size']),
'url' => $webPath.http_build_query(
[
'username' => $this->getCurrentUser()->getUsername(),
'api_key' => '', //$this->apiKey,
'cidReq' => $course->getCode(),
'id_session' => $session ? $session->getId() : 0,
'gidReq' => 0,
'gradebook' => 0,
'origin' => '',
'action' => 'download',
'id' => $documentInfo['id'],
]
),
];
},
$documents
);
return $results;
}
/**
* @param \ArrayObject $context
*
* @return array
*/
public function getLearnpathCategories(\ArrayObject $context): array
{
/** @var Course $course */
$course = $context->offsetGet('course');
$none = new CLpCategory();
$none
->setId(0)
->setCId($course->getId())
->setName($this->translator->trans('Without category.'))
->setPosition(0);
$categories = \learnpath::getCategories($course->getId());
array_unshift($categories, $none);
return $categories;
}
/**
* @param CLpCategory $category
* @param \ArrayObject $context
*
* @return array
*/
public function getLearnpathsByCategory(CLpCategory $category, \ArrayObject $context): array
{
$user = $this->getCurrentUser();
/** @var Course $course */
$course = $context->offsetGet('course');
/** @var Session $session */
$session = $context->offsetGet('session');
$sessionId = $session ? $session->getId() : 0;
$lpList = new \LearnpathList(
$user->getId(),
$course->getCode(),
$sessionId,
null,
false,
$category->getId()
);
$flatList = $lpList->get_flat_list();
$lps = [];
foreach ($flatList as $lpId => $lpInfo) {
if (empty($lpInfo['lp_visibility'])) {
continue;
}
if (
!\learnpath::is_lp_visible_for_student($lpId, $user->getId(), $course->getCode(), $sessionId)
) {
continue;
}
$timeLimits = !empty($lpInfo['expired_on']);
if ($timeLimits) {
if (!empty($lpInfo['publicated_on']) && !empty($lpInfo['expired_on'])) {
$utc = new \DateTimeZone('UTC');
$starTime = new \DateTime($lpInfo['publicated_on'], $utc);
$endTime = new \DateTime($lpInfo['expired_on'], $utc);
$now = new \DateTime('now', $utc);
$isActived = $now > $starTime && $endTime > $now;
if (!$isActived) {
continue;
}
}
}
$progress = \learnpath::getProgress($lpId, $user->getId(), $course->getId(), $sessionId);
$lps[] = [
'id' => $lpId,
'title' => \Security::remove_XSS($lpInfo['lp_name']),
'progress' => (int) $progress,
'url' => $this->generateLpUrl($lpId, $course, $session),
];
}
return $lps;
}
/**
* @param CAnnouncement $a
* @param CItemProperty $ip
*
* @return \stdClass
*/
private static function getAnnouncementObject(CAnnouncement $a, CItemProperty $ip)
{
$announcement = new \stdClass();
$announcement->id = $a->getIid();
$announcement->title = $a->getTitle();
$announcement->content = $a->getContent();
$announcement->author = $ip->getInsertUser();
$announcement->lastUpdateDate = $ip->getLasteditDate();
return $announcement;
}
/**
* @param int $lpId
* @param Course $course
* @param Session|null $session
*
* @return string
*/
private function generateLpUrl($lpId, Course $course, Session $session = null)
{
$user = $this->getCurrentUser();
$secret = $this->container->getParameter('secret');
$time = time();
$payload = [
'iat' => $time,
'exp' => $time + (60 * 30 * 1),
'data' => [
'user' => $user->getId(),
'lp' => (int) $lpId,
'course' => [
'id' => $course->getId(),
'code' => $course->getCode(),
],
'session' => $session ? $session->getId() : null,
],
];
$token = JWT::encode($payload, $secret, 'HS384');
return $this->container->get('router')->generate('chamilo_graphql_learnpath', ['token' => $token]);
}
}