View source
<?php
namespace Drupal\course_attendance\Plugin\course\CourseObject;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResultForbidden;
use Drupal;
use Drupal\Core\Form\FormStateInterface;
use Drupal\course\Entity\CourseObject;
class CourseObjectAttendance extends CourseObject {
public function optionsDefinition() {
$config = \Drupal::config('course_attendance.settings');
$defaults = parent::optionsDefinition();
$defaults['open'] = $config
->get('open');
$defaults['close'] = $config
->get('closed');
return $defaults;
}
public function take() {
$account = Drupal::currentUser();
if ($this
->getFulfillment($account)
->isComplete()) {
return [
'#markup' => t("You have been marked attended by an administrator."),
];
}
else {
return [
'#markup' => t("You must be marked attended by an administrator."),
];
}
}
function optionsForm(&$form, FormStateInterface $form_state) {
parent::optionsForm($form, $form_state);
$config = $this
->getOptions();
$duration = \Drupal::service('duration_field.service');
$form['instance'] = [
'#type' => 'textfield',
'#title' => t('Attendance code'),
'#description' => t('Randomly generated when this signup is created, but you can change it here.'),
'#default_value' => $config['instance'],
];
$form['open']['#type'] = 'container';
$form['open']['#prefix'] = '<div class="container-inline">';
$form['open']['#suffix'] = ' start date</div>';
$form['open']['open'] = array(
'#title' => t('Open attendance'),
'#type' => 'duration',
'#granularity' => 'd:h:i',
'#default_value' => $duration
->getDurationStringFromDateInterval($this
->secondsToInterval(abs($config['open']))),
);
$form['open']['open_direction'] = array(
'#title' => t(''),
'#title_display' => 'invisible',
'#type' => 'select',
'#options' => array(
1 => 'after',
-1 => 'before',
),
'#default_value' => $config['open'] > 1 ? 1 : -1,
);
$form['close']['#type'] = 'container';
$form['close']['#prefix'] = '<div class="container-inline">';
$form['close']['#suffix'] = ' start date</div>';
$form['close']['close'] = array(
'#title' => t('Close attendance'),
'#type' => 'duration',
'#granularity' => 'd:h:i',
'#default_value' => $duration
->getDurationStringFromDateInterval($this
->secondsToInterval(abs($config['close']))),
);
$form['close']['close_direction'] = array(
'#title' => t(''),
'#title_display' => 'invisible',
'#type' => 'select',
'#options' => array(
1 => 'after',
-1 => 'before',
),
'#default_value' => $config['close'] > 1 ? 1 : -1,
);
$form['reset'] = array(
'#title' => 'Reset code',
'#description' => t('Check this to randomly generate a new code.'),
'#type' => 'checkbox',
);
}
function optionsValidate(&$form, FormStateInterface $form_state) {
parent::optionsValidate($form, $form_state);
if ($courseObject = $this
->findObjectByCode($form_state
->getValue('instance'))) {
if ($courseObject
->id() != $this
->id()) {
$form_state
->setError($form['attendance']['instance'], t('Code is already in use.'));
}
}
$duration = \Drupal::service('duration_field.service');
$form_state
->setValue('open', $form_state
->getValue('open_direction') * $duration
->getSecondsFromDateInterval($form_state
->getValue('open')));
$form_state
->setValue('close', $form_state
->getValue('close_direction') * $duration
->getSecondsFromDateInterval($form_state
->getValue('close')));
}
function preSave(EntityStorageInterface $storage) {
if ($this
->get('instance')
->isEmpty()) {
$this
->set('instance', self::generateWord());
}
}
public static function findObjectByCode(string $code) {
$entities = Drupal::entityTypeManager()
->getStorage('course_object')
->loadByProperties([
'object_type' => 'attendance',
'instance' => $code,
]);
return $entities ? reset($entities) : NULL;
}
static function generateWord() {
$accepted_cons_start = "BCDFGHJKLMNPQRSTVWYZ";
$accepted_cons_end = "BCDFGHKLMNPQRSTVWXYZ";
$accepted_vowels = "AEUO";
do {
$word = '';
for ($i = 1; $i <= 6; $i++) {
switch ($i) {
case 1:
case 4:
$word .= $accepted_cons_start[rand(0, strlen($accepted_cons_start) - 1)];
break;
case 3:
case 6:
$word .= $accepted_cons_end[rand(0, strlen($accepted_cons_end) - 1)];
break;
case 2:
case 5:
$word .= $accepted_vowels[rand(0, strlen($accepted_vowels) - 1)];
break;
}
}
\Drupal::moduleHandler()
->alter('course_attendance_word', $word);
} while (self::findObjectByCode($word));
return $word;
}
function secondsToInterval($seconds) {
$date1 = new \DateTime('1904-01-01');
$date2 = new \DateTime('1904-01-01');
$date2
->add(new \DateInterval("PT{$seconds}S"));
return $date2
->diff($date1);
}
function getOptionsSummary() {
$summary = parent::getOptionsSummary();
$summary['instance'] = t('Code: @code', [
'@code' => $this
->getOption('instance'),
]);
return $summary;
}
function access($operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
if ($operation == 'attendance') {
$start_date = strtotime($this
->getCourse()
->get('field_course_event_date')->value . ' UTC');
$open = $start_date + $this
->getOption('open');
$close = $start_date + $this
->getOption('close');
if (\Drupal::time()
->getRequestTime() < $open) {
return $return_as_object ? AccessResultForbidden::forbidden('not_open') : FALSE;
}
if (\Drupal::time()
->getRequestTime() > $close) {
return $return_as_object ? AccessResultForbidden::forbidden('closed') : FALSE;
}
}
return parent::access($operation, $account, $return_as_object);
}
}