checklistapi.pages.inc 8.4 KB
Newer Older
TravisCarden's avatar
TravisCarden committed
1 2 3 4 5 6 7
<?php

/**
 * @file
 * Page callbacks for the Checklist API module.
 */

8 9 10
/**
 * Page callback: Form constructor for "Clear saved progress" confirmation form.
 *
11 12
 * @param string $id
 *   The checklist ID.
13 14 15 16 17
 *
 * @see checklistapi_menu()
 *
 * @ingroup forms
 */
18 19
function checklistapi_checklist_clear_confirm($form, &$form_state, $id) {
  $checklist = checklistapi_checklist_load($id);
20
  $form['#checklist'] = $checklist;
21 22 23 24 25 26 27
  $question = t('Are you sure you want to clear %title saved progress?', array(
    '%title' => $checklist->title,
  ));
  $description = t('All progress details will be erased. This action cannot be undone.');
  $yes = t('Clear');
  $no = t('Cancel');
  return confirm_form($form, $question, $checklist->path, $description, $yes, $no);
28 29 30 31 32 33
}

/**
 * Form submission handler for checklistapi_checklist_clear_confirm().
 */
function checklistapi_checklist_clear_confirm_submit($form, &$form_state) {
34
  // If user confirmed, clear saved progress.
35
  if ($form_state['values']['confirm']) {
36
    $form['#checklist']->clearSavedProgress();
37
  }
38 39

  // Redirect back to checklist.
40
  $form_state['redirect'] = $form['#checklist']->path;
41 42
}

TravisCarden's avatar
TravisCarden committed
43
/**
44
 * Page callback: Form constructor for the checklist form.
TravisCarden's avatar
TravisCarden committed
45
 *
46 47
 * @param string $id
 *   The checklist ID.
TravisCarden's avatar
TravisCarden committed
48
 *
49 50
 * @see checklistapi_checklist_form_submit()
 * @see checklistapi_menu()
51
 *
TravisCarden's avatar
TravisCarden committed
52 53
 * @ingroup forms
 */
54
function checklistapi_checklist_form($form, &$form_state, $id) {
55
  $form['#checklist'] = $checklist = checklistapi_checklist_load($id);
56

57 58 59 60 61 62 63 64 65 66 67 68
  $form['progress_bar'] = array(
    '#type' => 'markup',
    '#markup' => theme('checklistapi_progress_bar', array(
      'message' => ($checklist->hasSavedProgress()) ? t('Last updated @date by !user', array(
        '@date' => $checklist->getLastUpdatedDate(),
        '!user' => $checklist->getLastUpdatedUser(),
      )) : '&nbsp;',
      'number_complete' => $checklist->getNumberCompleted(),
      'number_of_items' => $checklist->getNumberOfItems(),
      'percent_complete' => round($checklist->getPercentComplete()),
    )),
  );
69 70 71
  if (checklistapi_compact_mode()) {
    $form['#attributes']['class'] = array('compact-mode');
  }
72 73 74
  $form['compact_mode_link'] = array(
    '#markup' => theme('checklistapi_compact_link'),
  );
75

TravisCarden's avatar
TravisCarden committed
76 77 78 79 80
  $form['checklistapi'] = array(
    '#attached' => array(
      'css' => array(drupal_get_path('module', 'checklistapi') . '/checklistapi.css'),
      'js' => array(drupal_get_path('module', 'checklistapi') . '/checklistapi.js'),
    ),
81 82
    '#tree' => TRUE,
    '#type' => 'vertical_tabs',
TravisCarden's avatar
TravisCarden committed
83
  );
84

TravisCarden's avatar
TravisCarden committed
85
  // Loop through groups.
86
  $num_autochecked_items = 0;
87 88
  $groups = $checklist->items;
  foreach (element_children($groups) as $group_key) {
89
    $group = &$groups[$group_key];
TravisCarden's avatar
TravisCarden committed
90
    $form['checklistapi'][$group_key] = array(
91
      '#title' => filter_xss($group['#title']),
92
      '#type' => 'fieldset',
TravisCarden's avatar
TravisCarden committed
93
    );
94 95
    if (!empty($group['#description'])) {
      $form['checklistapi'][$group_key]['#description'] = filter_xss_admin($group['#description']);
TravisCarden's avatar
TravisCarden committed
96
    }
97

TravisCarden's avatar
TravisCarden committed
98
    // Loop through items.
99
    foreach (element_children($group) as $item_key) {
100
      $item = &$group[$item_key];
101
      $saved_item = !empty($checklist->savedProgress[$item_key]) ? $checklist->savedProgress[$item_key] : 0;
102 103 104
      // Build title.
      $title = filter_xss($item['#title']);
      if ($saved_item) {
105
        // Append completion details.
106 107
        $user = user_load($saved_item['#uid']);
        $title .= t(
108
          '<span class="completion-details"> - Completed @time by !user</a>',
109 110 111 112 113 114 115
          array(
            '@time' => format_date($saved_item['#completed'], 'short'),
            '!user' => theme('username', array('account' => $user)),
          )
        );
      }
      // Set default value.
TravisCarden's avatar
TravisCarden committed
116 117 118 119
      $default_value = FALSE;
      if ($saved_item) {
        $default_value = TRUE;
      }
120
      elseif (!empty($item['#default_value'])) {
121 122 123
        if ($default_value = $item['#default_value']) {
          $num_autochecked_items++;
        }
TravisCarden's avatar
TravisCarden committed
124 125
      }
      // Get description.
126
      $description = (isset($item['#description'])) ? '<p>' . filter_xss_admin($item['#description']) . '</p>' : '';
127
      // Append links.
TravisCarden's avatar
TravisCarden committed
128
      $links = array();
129
      foreach (element_children($item) as $link_key) {
130
        $link = &$item[$link_key];
131 132
        $options = (!empty($link['#options']) && is_array($link['#options'])) ? $link['#options'] : array();
        $links[] = l($link['#text'], $link['#path'], $options);
133
      }
134 135 136
      if (count($links)) {
        $description .= '<div class="links">' . implode(' | ', $links) . '</div>';
      }
137
      // Compile the list item.
TravisCarden's avatar
TravisCarden committed
138
      $form['checklistapi'][$group_key][$item_key] = array(
139
        '#attributes' => array('class' => array('checklistapi-item')),
TravisCarden's avatar
TravisCarden committed
140
        '#default_value' => $default_value,
141
        '#description' => filter_xss_admin($description),
142
        '#disabled' => !($user_has_edit_access = $checklist->userHasAccess('edit')),
143
        '#title' => filter_xss_admin($title),
144
        '#type' => 'checkbox',
TravisCarden's avatar
TravisCarden committed
145 146 147
      );
    }
  }
148

149 150
  $form['actions'] = array(
    '#access' => $user_has_edit_access,
151
    '#type' => 'actions',
152 153
    '#weight' => 100,
    'save' => array(
154
      '#submit' => array('checklistapi_checklist_form_submit'),
155 156 157 158 159
      '#type' => 'submit',
      '#value' => t('Save'),
    ),
    'clear' => array(
      '#access' => $checklist->hasSavedProgress(),
160
      '#attributes' => array('class' => array('clear-saved-progress')),
161 162 163
      '#href' => $checklist->path . '/clear',
      '#title' => t('Clear saved progress'),
      '#type' => 'link',
164 165
    ),
  );
166 167 168 169 170

  // Alert the user of autochecked items. Only set the message on GET requests
  // to prevent it from reappearing after saving the form. (Testing the request
  // method may not be the "correct" way to accomplish this.)
  if ($num_autochecked_items && $_SERVER['REQUEST_METHOD'] == 'GET') {
171 172 173 174 175 176 177 178 179 180
    $args = array(
      '%checklist' => $checklist->title,
      '@num' => $num_autochecked_items,
    );
    $message = format_plural(
      $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)
    );
    drupal_set_message($message, 'status');
181 182
  }

TravisCarden's avatar
TravisCarden committed
183 184 185 186
  return $form;
}

/**
187
 * Form submission handler for checklistapi_checklist_form().
TravisCarden's avatar
TravisCarden committed
188
 */
189
function checklistapi_checklist_form_submit($form, &$form_state) {
190
  $form['#checklist']->saveProgress($form_state['values']['checklistapi']);
TravisCarden's avatar
TravisCarden committed
191
}
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206

/**
 * Determines whether the current user is in compact mode.
 *
 * Compact mode shows checklist forms with less description text.
 *
 * Whether the user is in compact mode is determined by a cookie, which is set
 * for the user by checklistapi_compact_page().
 *
 * If the user does not have the cookie, the default value is given by the
 * system variable 'checklistapi_compact_mode', which itself defaults to FALSE.
 * This does not have a user interface to set it: it is a hidden variable which
 * can be set in the settings.php file.
 *
 * @return bool
207
 *   TRUE when in compact mode, or FALSE when in expanded mode.
208 209 210 211 212 213 214 215 216
 */
function checklistapi_compact_mode() {
  return isset($_COOKIE['Drupal_visitor_checklistapi_compact_mode']) ? $_COOKIE['Drupal_visitor_checklistapi_compact_mode'] : variable_get('checklistapi_compact_mode', FALSE);
}

/**
 * Menu callback: Sets whether the admin menu is in compact mode or not.
 *
 * @param string $mode
217 218
 *   (optional) The mode to set compact mode to. Accepted values are "on" and
 *   "off". Defaults to "off".
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
 */
function checklistapi_compact_page($mode = 'off') {
  user_cookie_save(array('checklistapi_compact_mode' => ($mode == 'on')));
  drupal_goto();
}

/**
 * Returns HTML for a link to show or hide inline item descriptions.
 *
 * @ingroup themeable
 */
function theme_checklistapi_compact_link() {
  $output = '<div class="compact-link">';
  if (checklistapi_compact_mode()) {
    $output .= l(
234
      t('Show item descriptions'),
235
      current_path() . '/compact/off',
236 237
      array(
        'attributes' => array(
238
          'title' => t('Expand layout to include item descriptions.'),
239 240 241 242 243 244 245
        ),
        'query' => drupal_get_destination(),
      )
    );
  }
  else {
    $output .= l(
246
      t('Hide item descriptions'),
247
      current_path() . '/compact/on',
248 249
      array(
        'attributes' => array(
250
          'title' => t('Compress layout by hiding item descriptions.'),
251 252 253 254 255 256 257 258
        ),
        'query' => drupal_get_destination(),
      )
    );
  }
  $output .= '</div>';
  return $output;
}