View source
<?php
namespace Drupal\checklistapi\Form;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\Element;
use Drupal\user\Entity\User;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ChecklistapiChecklistForm implements FormInterface, ContainerInjectionInterface {
protected $dateFormatter;
protected $messenger;
public function __construct(DateFormatterInterface $date_formatter, MessengerInterface $messenger) {
$this->dateFormatter = $date_formatter;
$this->messenger = $messenger;
}
public static function create(ContainerInterface $container) {
$date_formatter = $container
->get('date.formatter');
$messenger = $container
->get('messenger');
return new static($date_formatter, $messenger);
}
public function getFormId() {
return 'checklistapi_checklist_form';
}
public function buildForm(array $form, FormStateInterface $form_state, $checklist_id = NULL) {
$form['#checklist'] = $checklist = checklistapi_checklist_load($checklist_id);
$user_has_edit_access = $checklist
->userHasAccess('edit');
$form['progress_bar'] = [
'#theme' => 'checklistapi_progress_bar',
'#message' => $checklist
->hasSavedProgress() ? t('Last updated @date by @user', [
'@date' => $checklist
->getLastUpdatedDate(),
'@user' => $checklist
->getLastUpdatedUser(),
]) : '',
'#number_complete' => $checklist
->getNumberCompleted(),
'#number_of_items' => $checklist
->getNumberOfItems(),
'#percent_complete' => (int) round($checklist
->getPercentComplete()),
'#attached' => [
'library' => [
'classy/progress',
],
],
];
if (checklistapi_compact_mode_is_on()) {
$form['#attributes']['class'] = [
'compact-mode',
];
}
$form['compact_mode_link'] = [
'#markup' => '<div class="compact-link"></div>',
];
$form['checklistapi'] = [
'#attached' => [
'library' => [
'checklistapi/checklistapi',
],
],
'#tree' => TRUE,
'#type' => 'vertical_tabs',
];
$num_autochecked_items = 0;
$groups = $checklist->items;
foreach (Element::children($groups) as $group_key) {
$group =& $groups[$group_key];
$form[$group_key] = [
'#title' => Xss::filter($group['#title']),
'#type' => 'details',
'#group' => 'checklistapi',
];
if (!empty($group['#description'])) {
$form[$group_key]['#description'] = Xss::filterAdmin($group['#description']);
}
foreach (Element::children($group) as $item_key) {
$item =& $group[$item_key];
$saved_item = !empty($checklist->savedProgress['#items'][$item_key]) ? $checklist->savedProgress['#items'][$item_key] : 0;
$title = Xss::filter($item['#title']);
if ($saved_item) {
$user = User::load($saved_item['#uid']);
$title .= '<span class="completion-details"> - ' . t('Completed @time by @user', [
'@time' => $this->dateFormatter
->format($saved_item['#completed'], 'short'),
'@user' => $user ? $user
->getAccountName() : t('[missing user]'),
]) . '</span>';
}
$default_value = FALSE;
if ($saved_item) {
$default_value = TRUE;
}
elseif (!empty($item['#default_value'])) {
if ($default_value = $item['#default_value']) {
$num_autochecked_items++;
}
}
$description = isset($item['#description']) ? '<p>' . Xss::filterAdmin($item['#description']) . '</p>' : '';
$links = [];
foreach (Element::children($item) as $link_key) {
$link =& $item[$link_key];
$links[] = Link::fromTextAndUrl($link['#text'], $link['#url'])
->toString();
}
if (count($links)) {
$description .= '<div class="links">' . implode(' | ', $links) . '</div>';
}
$form[$group_key][$item_key] = [
'#attributes' => [
'class' => [
'checklistapi-item',
],
],
'#default_value' => $default_value,
'#description' => Xss::filterAdmin($description),
'#disabled' => !$user_has_edit_access,
'#title' => Xss::filterAdmin($title),
'#type' => 'checkbox',
'#group' => $group_key,
'#parents' => [
'checklistapi',
$group_key,
$item_key,
],
];
}
}
$form['actions'] = [
'#access' => $user_has_edit_access,
'#type' => 'actions',
'#weight' => 100,
'save' => [
'#button_type' => 'primary',
'#type' => 'submit',
'#value' => t('Save'),
],
'clear' => [
'#access' => $checklist
->hasSavedProgress(),
'#button_type' => 'danger',
'#attributes' => [
'class' => [
'clear-saved-progress',
],
],
'#submit' => [
[
$this,
'clear',
],
],
'#type' => 'submit',
'#value' => t('Clear saved progress'),
],
];
if ($num_autochecked_items && $_SERVER['REQUEST_METHOD'] == 'GET') {
$args = [
'%checklist' => $checklist->title,
'@num' => $num_autochecked_items,
];
$message = \Drupal::translation()
->formatPlural($num_autochecked_items, t('%checklist found 1 unchecked item that was already completed and checked it for you. Save the form to record the change.', $args), t('%checklist found @num unchecked items that were already completed and checked them for you. Save the form to record the changes.', $args));
$this->messenger
->addStatus($message);
}
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$checklist = $form['#checklist'];
$values = $form_state
->getValue('checklistapi');
$checklist
->saveProgress($values);
$form_state
->setRedirect($checklist
->getRouteName(), [], [
'fragment' => $values['checklistapi__active_tab'],
]);
}
public function clear(array &$form, FormStateInterface $form_state) {
$form_state
->setRedirect($form['#checklist']
->getRouteName() . '.clear');
}
}