class CourseController in Course 3.x
Same name and namespace in other branches
- 8.3 src/Controller/CourseController.php \Drupal\course\Controller\CourseController
- 8.2 src/Controller/CourseController.php \Drupal\course\Controller\CourseController
Hierarchy
- class \Drupal\Core\Entity\Controller\EntityController implements ContainerInjectionInterface uses StringTranslationTrait
- class \Drupal\course\Controller\CourseController
Expanded class hierarchy of CourseController
File
- src/
Controller/ CourseController.php, line 17
Namespace
Drupal\course\ControllerView source
class CourseController extends EntityController {
/**
* Access callback for completion page.
*/
function completionAccess(Course $course) {
$account = \Drupal::currentUser();
return AccessResult::allowedIf($course
->isEnrolled($account));
}
/**
* Render a landing page for course completion.
*
* @param Course $course
*
* @return array
* Render array for the completion landing page.
*/
function renderComplete(Course $course) {
$account = \Drupal::currentUser();
// User's course record.
$course_enrollment = $course
->getEnrollment($account);
// Render array.
$page = array();
// Links.
$links = array();
$url = $course
->getUrl();
$url
->setOption('title', t('Return to the course to view course details and material.'));
$links['course'] = Link::fromTextAndUrl(t('Return to course'), $url);
if ($course_enrollment
->isComplete()) {
// Allow modules to add links to the course completion landing page, such as
// post-course actions.
Drupal::moduleHandler()
->alter('course_outline_completion_links', $links, $course, $account);
}
else {
Drupal::moduleHandler()
->alter('course_outline_incomplete_links', $links, $course, $account);
}
$page['#title'] = $course_enrollment
->isComplete() ? t('Course complete') : t('Remaining requirements');
$objects = $course
->getObjects();
$items = array();
foreach ($objects as $courseObject) {
if ($courseObject
->access('see')) {
// Find required course objects the user has not yet completed.
$req = $courseObject
->getFulfillment($account);
$status_css = $req
->isComplete() ? 'complete' : 'incomplete';
$status_img = $req
->isComplete() ? 'core/misc/icons/73b355/check.svg' : ($req
->getCourseObject()
->isRequired() ? 'core/misc/icons/e32700/error.svg' : 'core/misc/icons/e29700/warning.svg');
$status_class = 'course-complete-item-' . $status_img;
$status_optional = ' (' . (!$req
->getCourseObject()
->isRequired() ? t('optional') : t('required')) . ')';
if ($courseObject
->access('take')) {
$link = Link::fromTextAndUrl($req
->getCourseObject()
->getTitle(), $courseObject
->getUrl())
->toString();
}
else {
$link = $req
->getCourseObject()
->getTitle();
}
$items[] = array(
'data' => array(
array(
'data' => [
'#theme' => 'image',
'#uri' => $status_img,
'#alt' => $status_css,
],
'width' => 20,
'class' => array(
'course-complete-item-status',
),
),
array(
'data' => [
'#markup' => $link . $status_optional . '<br/>' . $req
->getCourseObject()
->getStatus(),
],
'class' => array(
'course-complete-item-title',
),
),
),
'class' => array(
$status_class,
),
);
}
}
if ($course_enrollment
->isComplete()) {
$message = t('You have completed the course. Use the links below to review the course content.');
}
else {
$message = t('This course is not complete. Use the links below to access the remaining course content.');
}
$page['course_header'] = array(
'#type' => 'item',
'#title' => t('Thank you for participating in this course.'),
'#description' => $message,
'#description_display' => TRUE,
'#weight' => 1,
);
$page['course_completion_requirements'] = array(
'#theme' => 'table',
'#header' => NULL,
'#rows' => $items,
'#weight' => 3,
'#attributes' => array(
'class' => array(
'course-complete-items',
),
),
);
foreach ($links as $key => $link) {
$element = array(
'#title' => $link
->toString(),
'#description' => $link
->getUrl()
->getOption('title'),
'#type' => 'item',
'#description_display' => TRUE,
);
$page['course_links'][$key] = $element;
}
$page['course_links']['#weight'] = 2;
$page['#cache']['max-age'] = 0;
return $page;
}
/**
* Take a course.
*
* If allowed to enroll:
* - If the user hasn't answered enrollment questions, make them fill it out.
*
* If enrolled:
* - If the user hasn't answered enrollment questions, make them fill it out.
* - Enroll the user.
* - Fire the outline handler.
*
* If not enrolled:
* - Show access blocker.
*/
public function renderTake(Course $course) {
$account = Drupal::currentUser();
$enroll_access = $course
->access('enroll', $account, TRUE);
$enrollment = $course
->getEnrollment($account);
/* @var $enrollment Drupal\course\Entity\CourseEnrollment */
if ($enroll_access
->isAllowed() && (!$enrollment || $enrollment
->get('timestamp')
->isEmpty())) {
// User can enroll in this course and user is not enrolled. Check for
// enrollment fields or enroll the user.
$instances = Drupal::service('entity_field.manager')
->getFieldDefinitions('course_enrollment', $course
->get('enrollment_type')
->getString());
foreach ($instances as $field_name => $field) {
if (is_a($field, FieldConfig::class)) {
/* @var $field Drupal\field\Entity\FieldConfig */
if ($field
->getThirdPartySetting('course', 'show_field')) {
// At least one field must be shown when enrolling. Display the user
// enrollment form.
if (!$enrollment) {
// Create a new enrollment, show them the form.
$enrollment = CourseEnrollment::create([
'cid' => $course
->id(),
'uid' => $account
->id(),
'type' => $course
->get('enrollment_type')
->getString(),
'timestamp' => \Drupal::time()
->getRequestTime(),
'enrollmenttype' => 'self',
]);
}
$redirect_url = Url::fromRoute('course.take', [
'course' => $course
->id(),
]);
$form = \Drupal::service('entity.form_builder')
->getForm($enrollment, 'default', [
'redirect' => $redirect_url,
]);
return $form;
}
}
}
// No fields to show. Check for enrollment. If it does not exist, create it.
if (empty($enrollment)) {
$enrollment = CourseEnrollment::create(array(
'cid' => $course
->id(),
'uid' => $account
->id(),
'type' => $course->enrollment_type
->getString(),
'enrollmenttype' => 'self',
));
$enrollment
->save();
}
}
$take_access = $course
->access('take', $account, TRUE);
if ($take_access
->isAllowed()) {
// User has access to take this course.
if ($enrollment
->get('timestamp')
->isEmpty()) {
// If user hasn't started course, mark start of enrollment.
$enrollment
->set('timestamp', \Drupal::time()
->getRequestTime())
->save();
\Drupal::messenger()
->addStatus(t('Your enrollment in this course has been recorded.'));
}
// Display the configured outline handler output.
/* @var $pluginManager CourseOutlinePluginManager */
$pluginManager = Drupal::service('plugin.manager.course.outline');
/* @var $outlinePlugin CourseOutlinePluginBase */
$outlinePlugin = $pluginManager
->createInstance($course
->get('outline')
->getString());
$outline = $outlinePlugin
->render($course, $account);
if (!$outline) {
$outline['#markup'] = t('No learning objects are available this time.');
}
// Set page title to title of this course.
$outline['#title'] = $course
->get('title')
->getString();
$outline['#cache']['max-age'] = 0;
return $outline;
}
else {
$message = $take_access
->getReason();
if (!$message) {
$message = t('Sorry, you do not have access to take this course.');
}
return [
'#markup' => '<h2>Access denied</h2>' . $take_access
->getReason(),
];
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
CourseController:: |
function | Access callback for completion page. | ||
CourseController:: |
function | Render a landing page for course completion. | ||
CourseController:: |
public | function | Take a course. | |
EntityController:: |
protected | property | The entity repository. | |
EntityController:: |
protected | property | The entity type bundle info. | |
EntityController:: |
protected | property | The entity type manager. | |
EntityController:: |
protected | property | The renderer. | |
EntityController:: |
public | function | Provides a generic add title callback for entities with bundles. | |
EntityController:: |
public | function | Displays add links for the available bundles. | |
EntityController:: |
public | function | Provides a generic add title callback for an entity type. | |
EntityController:: |
public static | function |
Instantiates a new instance of this class. Overrides ContainerInjectionInterface:: |
|
EntityController:: |
public | function | Provides a generic delete title callback. | |
EntityController:: |
protected | function | Determines the entity. | |
EntityController:: |
public | function | Provides a generic edit title callback. | |
EntityController:: |
protected | function | Expands the bundle information with descriptions, if known. | |
EntityController:: |
protected | function | Returns a redirect response object for the specified route. | |
EntityController:: |
public | function | Provides a generic title callback for a single entity. | |
EntityController:: |
public | function | Constructs a new EntityController. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 4 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |