View source
<?php
namespace Drupal\course\Entity;
use Drupal;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EditorialContentEntityBase;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Link;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\course\Plugin\CourseOutlinePluginManager;
use Drupal\user\EntityOwnerInterface;
use Drupal\user\EntityOwnerTrait;
class Course extends EditorialContentEntityBase implements EntityOwnerInterface {
use EntityOwnerTrait;
private $courseObjects = array();
private $tracker;
private $active = NULL;
private $next;
private $prev;
public function getTracker(AccountInterface $account) {
$entities = \Drupal::entityTypeManager()
->getStorage('course_enrollment')
->loadByProperties([
'cid' => $this
->id(),
'uid' => $account
->id(),
]);
if ($entities) {
return reset($entities);
}
return FALSE;
}
public function getUrl() {
return Url::fromRoute('course.take', [
'course' => $this
->id(),
]);
}
public function setActive($id = NULL) {
if (!$id && isset($_SESSION['course'][$this
->id()]['taking']['active'])) {
$id = $_SESSION['course'][$this
->id()]['taking']['active'];
}
$old = NULL;
$storeNext = FALSE;
foreach ($this
->getObjects() as $courseObject) {
if (!$courseObject
->getOption('enabled')) {
continue;
}
if ($id == $courseObject
->id()) {
if ($old) {
$this->prev = $old;
}
$storeNext = TRUE;
$this->active = $courseObject;
}
elseif ($storeNext) {
$this->next = clone $courseObject;
$storeNext = FALSE;
}
$old = clone $courseObject;
}
}
public function getActive() {
if (!$this->active) {
$this
->setActive();
}
return $this->active;
}
public function getNext() {
if (!$this->active) {
$this
->setActive();
}
return $this->next;
}
public function getPrev() {
if (!$this->active) {
$this
->setActive();
}
return $this->prev;
}
public function getNavigation(AccountInterface $account) {
$this
->setActive();
$prev = $this
->getPrev();
$next = $this
->getNext();
$links = array();
if ($prev && $prev
->access('take')) {
$links['prev'] = Link::fromTextAndUrl(t('Previous'), $prev
->getUrl());
}
$links['back'] = Link::createFromRoute(t('Back to course'), 'entity.course.canonical', [
'course' => $this
->id(),
]);
if ($next && $next
->access('take')) {
$links['next'] = Link::fromTextAndUrl(t('Next'), $next
->getUrl());
}
elseif (!$next && $this
->getEnrollment($account)
->isComplete()) {
$links['next'] = Link::createFromRoute(t('Next'), 'course.complete', [
'course' => $this
->id(),
]);
}
if ($active = $this
->getActive()) {
foreach ($active
->overrideNavigation() as $key => $link) {
$links[$key] = $link;
}
}
return $links;
}
public function getObjects() {
if (empty($this->courseObjects)) {
$efq = \Drupal::entityQuery('course_object');
$result = $efq
->condition('cid', $this
->id())
->sort('weight')
->execute();
if (!empty($result)) {
$this->courseObjects = \Drupal::entityTypeManager()
->getStorage('course_object')
->loadMultiple($result);
}
}
return $this->courseObjects;
}
function resetCache() {
$this->courseObjects = array();
return $this;
}
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);
$fields += static::ownerBaseFieldDefinitions($entity_type);
$fields['title'] = BaseFieldDefinition::create('string')
->setLabel(t('Title'))
->setRequired(TRUE)
->setTranslatable(TRUE)
->setRevisionable(TRUE)
->setSetting('max_length', 255)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => -5,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => -5,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$config = Drupal::config('course.settings.enrollment');
$pluginManager = Drupal::service('plugin.manager.course.outline');
$outlines = array_column($pluginManager
->getDefinitions(), 'label', 'id');
$ebundles = array_column(CourseEnrollmentType::loadMultiple(), 'label', 'id');
$fields['outline'] = BaseFieldDefinition::create('list_string')
->setLabel(t('Outline display'))
->setDescription(t('This controls the presentation of the course objects.'))
->setRequired(TRUE)
->setDisplayOptions('form', [
'type' => 'options_select',
])
->setDisplayConfigurable('form', TRUE)
->setRevisionable(TRUE)
->setSetting('allowed_values', $outlines);
$fields['enrollment_type'] = BaseFieldDefinition::create('list_string')
->setLabel(t('Enrollment type'))
->setDescription(t("The enrollment type's fields, if required for enrollment, will be presented to the user before starting the course."))
->setRequired(TRUE)
->setDisplayOptions('form', [
'type' => 'options_select',
])
->setDefaultValue($config
->get('default_enrollment_type'))
->setDisplayConfigurable('form', TRUE)
->setRevisionable(TRUE)
->setSetting('allowed_values', $ebundles);
$fields['credits'] = BaseFieldDefinition::create('float')
->setRevisionable(TRUE)
->setLabel(t('Credits'))
->setDescription(t('For more advanced crediting, use the <a href=":link">Course credit</a> module.', array(
':link' => Url::fromUri('https://drupal.org/project/course_credit')
->toString(),
)))
->setDisplayOptions('form', [
'type' => 'number',
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
if (!Drupal::moduleHandler()
->moduleExists('course_credit')) {
$fields['credits']
->setDisplayConfigurable('form', FALSE);
}
$fields['duration'] = BaseFieldDefinition::create('integer')
->setRevisionable(TRUE)
->setLabel(t('Duration'))
->setDescription(t('Length of time in seconds that a user can remain in the course. Leave blank for unlimited.<br/>For a better experience, install the <a href=":link">Time period</a> module.', array(
':link' => Url::fromUri('https://drupal.org/project/timeperiod')
->toString(),
)))
->setDisplayOptions('form', [
'type' => 'number',
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
if (Drupal::moduleHandler()
->moduleExists('timeperiod')) {
$form['course']['duration']['#type'] = 'timeperiod_select';
$form['course']['duration']['#units'] = array(
'86400' => array(
'max' => 30,
'step size' => 1,
),
'3600' => array(
'max' => 24,
'step size' => 1,
),
'60' => array(
'max' => 60,
'step size' => 1,
),
);
$form['course']['duration']['#description'] = t('Length of time that a user can remain in the course.');
}
$fields['external_id'] = BaseFieldDefinition::create('string')
->setLabel(t('External learning application course ID'))
->setDescription('If using an external learning application, the ID of the external course.')
->setDisplayOptions('form', [
'type' => 'string_textfield',
])
->setDisplayConfigurable('form', TRUE);
if (FALSE && arg(2) == 'clone') {
$form['course']['clone_type'] = array(
'#title' => t('Course object cloning'),
'#description' => t('"New" will create new instances of all course objects.<br/>"Reference" will link supported content in the old course to the new course.<br/>"Clone" will copy supported course objects, otherwise create new ones.'),
'#type' => 'radios',
'#options' => array(
'clone' => 'Clone',
'reference' => 'Reference',
'new' => 'New',
),
'#default_value' => 'clone',
);
}
$fields['created'] = BaseFieldDefinition::create('created')
->setRevisionable(TRUE)
->setLabel('Created');
$fields['changed'] = BaseFieldDefinition::create('changed')
->setRevisionable(TRUE)
->setLabel('Changed');
$fields['course_date'] = BaseFieldDefinition::create('daterange')
->setDisplayConfigurable('form', TRUE)
->setRevisionable(TRUE)
->setDisplayOptions('form', [
'type' => 'daterange_default',
])
->setDisplayConfigurable('view', TRUE)
->setLabel('Course date');
$fields['uid']
->setLabel(t('Authored by'))
->setDescription(t('The username of the content author.'))
->setRevisionable(TRUE)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'author',
'weight' => 0,
])
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => 5,
'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'placeholder' => '',
],
])
->setDisplayConfigurable('form', TRUE);
$fields['status']
->setRevisionable(TRUE)
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'settings' => [
'display_label' => TRUE,
],
'weight' => 120,
])
->setDisplayConfigurable('form', TRUE);
return $fields;
}
function isEnrolled(AccountInterface $account) {
return (bool) $this
->getEnrollment($account);
}
function enroll(AccountInterface $account, $values = []) {
if (!($enrollment = $this
->getEnrollment($account))) {
$enrollment = CourseEnrollment::create([
'cid' => $this
->id(),
'uid' => $account
->id(),
] + $values);
$enrollment
->save();
}
return $enrollment;
}
function unEnroll(AccountInterface $account) {
return $this
->getEnrollment($account)
->delete();
}
static function preDelete(Drupal\Core\Entity\EntityStorageInterface $storage, array $entities) {
foreach ($entities as $course) {
$enrollment_storage = \Drupal::entityTypeManager()
->getStorage('course_enrollment');
$course_enrollments = $enrollment_storage
->loadByProperties([
'cid' => $course
->id(),
]);
$enrollment_storage
->delete($course_enrollments);
$object_storage = \Drupal::entityTypeManager()
->getStorage('course_object');
$course_objects = $object_storage
->loadByProperties([
'cid' => $course
->id(),
]);
$object_storage
->delete($course_objects);
}
parent::preDelete($storage, $entities);
}
function getEnrollment(AccountInterface $account) {
$entities = Drupal::entityTypeManager()
->getStorage('course_enrollment')
->loadByProperties([
'cid' => $this
->id(),
'uid' => $account
->id(),
]);
if ($entities) {
return reset($entities);
}
}
function getTitle() {
return $this
->get('title')->value;
}
public function accessMultiple($operation, AccountInterface $account = NULL) {
if ($account == NULL) {
$account = \Drupal::currentUser();
}
return \Drupal::moduleHandler()
->invokeAll('course_access', [
$this,
$operation,
$account,
]);
}
}