Skip to content

Course: Refactor course creation service #5302

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions assets/vue/components/course/Form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@
v-model="fillDemoContent"
name=""
/>
<BaseAutocomplete
<!--BaseAutocomplete
id="template"
v-model="courseTemplate"
:label="t('Select Template')"
:search="searchTemplates"
/>
/-->
</div>
<!-- Form Footer -->
<div class="form-footer">
Expand Down
27 changes: 15 additions & 12 deletions assets/vue/views/course/Create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { useRouter } from "vue-router"
import Message from 'primevue/message'
import courseService from "../../services/courseService"
import { useI18n } from "vue-i18n"
import { useNotification } from "../../composables/notification"

const store = useStore()
const item = ref({})
Expand All @@ -38,24 +39,26 @@ const { t } = useI18n()
const isLoading = computed(() => store.getters['course/getField']('isLoading'))
const violations = computed(() => store.getters['course/getField']('violations'))
const courseData = ref({})
const { showSuccessNotification, showErrorNotification } = useNotification()

const submitCourse = async (formData) => {
isLoading.value = true
try {
let tempResponse = await courseService.createCourse(formData)
if (tempResponse.success) {
const courseId = tempResponse.courseId
const sessionId = 0
await router.push(`/course/${courseId}/home?sid=${sessionId}`)
} else {
console.error(tempResponse.message)
}
const response = await courseService.createCourse(formData)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Este servicio que hace la llamada ajax a createCourse, tiene que ser a través de api-platform

const courseId = response.courseId
const sessionId = 0
showSuccessNotification(t('Course created successfully.'))
await router.push(`/course/${courseId}/home?sid=${sessionId}`)
} catch (error) {
console.error(error)
if (error.response && error.response.data) {
violations.value = error.response.data
} else {
console.error('An unexpected error occurred.')

const errorMessage = error.response && error.response.data && error.response.data.message
? error.response.data.message
: t('An unexpected error occurred.')
showErrorNotification(errorMessage)

if (error.response && error.response.data && error.response.data.violations) {
violations.value = error.response.data.violations
}
} finally {
isLoading.value = false
Expand Down
49 changes: 27 additions & 22 deletions src/CoreBundle/Controller/CourseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Chamilo\CoreBundle\Repository\Node\IllustrationRepository;
use Chamilo\CoreBundle\Repository\TagRepository;
use Chamilo\CoreBundle\Security\Authorization\Voter\CourseVoter;
use Chamilo\CoreBundle\Service\CourseService;
use Chamilo\CoreBundle\ServiceHelper\AccessUrlHelper;
use Chamilo\CoreBundle\Settings\SettingsManager;
use Chamilo\CoreBundle\Tool\ToolChain;
Expand Down Expand Up @@ -721,7 +722,7 @@ public function searchCourseTemplates(
foreach ($courseList as $course) {
$title = $course['title'];
$results['items'][] = [
'id' => $course['code'],
'id' => $course['id'],
'name' => $title.' ('.$course['code'].') ',
];
}
Expand All @@ -730,43 +731,47 @@ public function searchCourseTemplates(
}

#[Route('/create', name: 'chamilo_core_course_create')]
public function createCourse(Request $request, TranslatorInterface $translator): JsonResponse
{
public function createCourse(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debería estar en un StateProcessor de ApiPlatform para tener un solo endpoint de creación de curso

Request $request,
TranslatorInterface $translator,
CourseService $courseService
): JsonResponse {
$courseData = json_decode($request->getContent(), true);

$title = $courseData['name'] ?? null;
$wantedCode = $courseData['code'] ?? null;
$courseLanguage = $courseData['language']['id'] ?? null;
$categoryCode = $courseData['category'] ?? null;
$title = $courseData['name'];
$courseLanguage = isset($courseData['language']) ? $courseData['language']['id'] : '';
$exemplaryContent = $courseData['fillDemoContent'] ?? false;
$template = $courseData['template'] ?? '';

if (empty($wantedCode)) {
$wantedCode = CourseManager::generate_course_code(substr($title, 0, CourseManager::MAX_COURSE_LENGTH_CODE));
}

$courseCodeOk = !CourseManager::course_code_exists($wantedCode);
if ($courseCodeOk) {
$params = [
'title' => $title,
'exemplary_content' => $exemplaryContent,
'wanted_code' => $wantedCode,
'course_language' => $courseLanguage,
'course_template' => $template,
];
$params = [
'title' => $title,
'wanted_code' => $wantedCode,
'course_language' => $courseLanguage,
'exemplary_content' => $exemplaryContent,
'course_template' => $template,
];

if ($categoryCode) {
$params['course_categories'] = $categoryCode;
}
if ($categoryCode) {
$params['course_categories'] = $categoryCode;
}

$course = CourseManager::create_course($params);
try {
$course = $courseService->createCourse($params);
if ($course) {
return new JsonResponse([
'success' => true,
'message' => $translator->trans('Course created successfully.'),
'courseId' => $course->getId(),
]);
}
} catch (\Exception $e) {

return new JsonResponse([
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aquí se debería lanzar una exception en lugar de devolver una respuesta con json

'success' => false,
'message' => $translator->trans($e->getMessage())
], Response::HTTP_BAD_REQUEST);
}

return new JsonResponse(['success' => false, 'message' => $translator->trans('An error occurred while creating the course.')]);
Expand Down
25 changes: 24 additions & 1 deletion src/CoreBundle/Repository/Node/CourseRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
use Chamilo\CoreBundle\Entity\AccessUrl;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\CourseRelUser;
use Chamilo\CoreBundle\Entity\ResourceNode;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Repository\ResourceRepository;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
Expand Down Expand Up @@ -207,4 +207,27 @@ public function getSubscribedUsersByStatus(Course $course, int $status)

return $queryBuilder;
}

public function courseCodeExists(string $code): bool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing function doc comment

{
$qb = $this->createQueryBuilder('c')
->select('count(c.id)')
->where('c.code = :code OR c.visualCode = :code')
->setParameter('code', $code)
->getQuery();

return (int) $qb->getSingleScalarResult() > 0;
}

public function findCourseAsArray($id)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing function doc comment

{
$qb = $this->createQueryBuilder('c')
->select('c.id, c.code, c.title, c.visualCode, c.courseLanguage, c.departmentUrl, c.departmentName')
->where('c.id = :id')
->setParameter('id', $id);

$query = $qb->getQuery();

return $query->getOneOrNullResult(AbstractQuery::HYDRATE_ARRAY);
}
}
Loading