You are here

hansel_ui.module in Hansel breadcrumbs 7

Same filename and directory in other branches
  1. 8 hansel_ui/hansel_ui.module

Hansel UI module

File

hansel_ui/hansel_ui.module
View source
<?php

/**
 * @file
 * Hansel UI module
 */

/**
 * Implements hook_menu().
 */
function hansel_ui_menu() {
  module_load_include('inc', 'hansel_ui', 'hansel_ui.registry');
  return _hansel_ui_menu();
}

/**
 * Page callback
 *
 * Generates the admin page
 */
function hansel_ui_page() {
  $output = '';
  drupal_add_css(drupal_get_path('module', 'hansel_ui') . '/css/hansel_ui.css');
  drupal_add_js(drupal_get_path('module', 'hansel_ui') . '/js/hansel_ui.js');
  if ($rules = _hansel_ui_list_rules()) {
    $output .= '<div id="hansel-rules">';
    $output .= $rules;
    $output .= '</div>';
  }
  else {

    // No rules are defined yet.
    $output .= '<p>' . t('You do not have any rules defined yet. You can create a new rule with the form below.') . '</p>';
    $output .= '<p>' . t('All configurations must have a rule with the name "start", which is the first rule to be executed.') . '</p>';
  }
  $hansel_ui_rule_form = drupal_get_form('hansel_ui_rule_form');
  $output .= '<h2 class="title">' . t('Add rule') . '</h2><div>' . drupal_render($hansel_ui_rule_form) . '</div>';
  return $output;
}
function _hansel_ui_list_rules($pid = 0) {
  $output = '';
  foreach (_hansel_get_rules($pid) as $rule) {
    $delete_path = str_replace('%', $rule->rid, 'admin/config/search/hansel/rule/%/delete');
    $config_path = str_replace('%', $rule->rid, 'admin/config/search/hansel/rule/%');
    $delete_link = '<a href="' . url($delete_path) . '" class="hansel-delete-link"><span>delete</span></a>';
    $config_link = '<a href="' . url($config_path) . '" class="hansel-config-rule-link"><span>configure rule</span></a>';
    $output .= '<div class="hansel-rule">';

    // Add rule name, configure and delete link
    $output .= '<div class="hansel-name">';
    $output .= '<span class="hansel-rule-name">' . check_plain($rule->name) . '</span>';
    $output .= '<div class="hansel-buttons">' . $config_link . ' ' . $delete_link . '</div>';
    $output .= '</div>';
    $output .= '<div class="hansel-info">';

    // Add crumb info (if any)
    if (!empty($rule->crumb_action)) {
      $output .= '<div class="hansel-crumb-info">';
      $output .= _hansel_get_crumb_action_info($rule);
      $output .= '</div>';
    }

    // Add action info
    $output .= '<div class="hansel-type">';
    switch ($rule->action) {
      case 'goto':
        $res = db_query("SELECT r.name FROM {hansel_rule} r WHERE r.rid = :rid", array(
          ':rid' => $rule->destination,
        ));
        if (!($name = $res
          ->fetchField())) {
          $name = t('(broken link)');
        }
        $output .= 'goto ' . check_plain($name);
        break;
      case 'leave':
        if ($rule->restore) {
          $output .= 'leave (restore original breadcrumbs)';
        }
        else {
          $output .= 'leave';
        }
        break;
      case 'switch':
        if (_hansel_is_configurable_switch($rule->handler)) {
          $config_path = str_replace('%', $rule->rid, 'admin/config/search/hansel/switch/%');
          $output .= 'switch on ' . l($rule->handler, $config_path);
        }
        else {
          $output .= 'switch on ' . check_plain($rule->handler);
        }
        $output .= ' ' . _hansel_get_switch_info($rule);
        break;
    }
    $output .= '</div>';

    // Add child rules (if any)
    $children = _hansel_ui_list_rules($rule->rid);
    if ($children) {
      $output .= '<div class="hansel-children">' . $children . '</div>';
    }
    $output .= '</div>';

    // Close .hansel-info
    $output .= '</div>';

    // Close .hansel-rule
  }
  return $output;
}

/**
 * Page callback.
 *
 * Generates the settings page for Hansel.
 */
function hansel_ui_settings($form_state) {
  $form = array();
  $form['hansel_breadcrumb_last_item_link'] = array(
    '#type' => 'checkbox',
    '#title' => t('Render last item as a link'),
    '#default_value' => variable_get('hansel_breadcrumb_last_item_link', TRUE),
    '#description' => t('When turned on, the last item in the breadcrumb will be a link.'),
  );
  $form['hansel_breadcrumb_last_item_hide'] = array(
    '#type' => 'checkbox',
    '#title' => t('Hide last item'),
    '#default_value' => variable_get('hansel_breadcrumb_last_item_hide', FALSE),
    '#description' => t('Remove the last item of the breadcrumb.'),
  );
  $form['hansel_max_item_length'] = array(
    '#type' => 'textfield',
    '#title' => t('Maximum length for individual items'),
    '#default_value' => variable_get('hansel_max_item_length', 0),
    '#description' => t('Maximum length in characters. Use 0 to disable trimming.'),
    '#size' => 5,
  );
  $form['hansel_trim_on_word_boundary'] = array(
    '#type' => 'checkbox',
    '#title' => t('Trim on word boundary'),
    '#default_value' => variable_get('hansel_trim_on_word_boundary', TRUE),
  );
  $form['hansel_trim_ellipsis'] = array(
    '#type' => 'textfield',
    '#title' => t('Ellipsis'),
    '#default_value' => variable_get('hansel_trim_ellipsis', '...'),
    '#description' => t('Text to add after trimmed texts.'),
  );
  $form['hansel_max_item_count'] = array(
    '#type' => 'textfield',
    '#title' => t('Maximum number of items'),
    '#default_value' => variable_get('hansel_max_item_count', 0),
    '#description' => t('Maximum number of breadcrumb items. Items will be removed from the middle. Use 0 to disable.'),
    '#size' => 5,
  );
  $form['hansel_removed_items_replacement'] = array(
    '#type' => 'textfield',
    '#title' => t('Removed items replacement'),
    '#default_value' => variable_get('hansel_removed_items_replacement', '(...)'),
    '#description' => t('Removed breadcrumb items will be replaced by this text.'),
  );
  $form['hansel_remove_first_token_item'] = array(
    '#type' => 'checkbox',
    '#title' => t('Remove first item from Hansel path token'),
    '#default_value' => variable_get('hansel_remove_first_token_item', TRUE),
    '#description' => t('Hansel provides a path token for use in Pathauto. This option removes the first breadcrumb item from this token, which is usually "Home".'),
  );
  $options = array(
    60,
    120,
    300,
    600,
    900,
    1800,
    3600,
    10800,
    21600,
    43200,
    86400,
  );
  $options = array(
    0 => t('Disable'),
  ) + drupal_map_assoc($options, 'format_interval');
  $form['hansel_cache'] = array(
    '#type' => 'select',
    '#title' => t('Cache'),
    '#options' => $options,
    '#default_value' => variable_get('hansel_cache', 0),
    '#description' => t('Only parts which require interaction with the database are cached. Enabling this cache is only recommended when you use an efficient caching system (such as memcache).'),
  );
  $options = array(
    60,
    120,
    300,
    600,
    900,
    1800,
    3600,
    10800,
    21600,
    43200,
    86400,
  );
  $options = array(
    0 => t('Disable'),
  ) + drupal_map_assoc($options, 'format_interval');
  $form['hansel_cache_whole'] = array(
    '#type' => 'select',
    '#title' => t('Cache whole breadcrumbs'),
    '#options' => $options,
    '#default_value' => variable_get('hansel_cache_whole', 0),
    '#description' => t('Only for anonymous visitors.'),
  );
  $form['hansel_set_menu_item'] = array(
    '#type' => 'checkbox',
    '#title' => t('Set active menu item'),
    '#default_value' => variable_get('hansel_set_menu_item', FALSE),
    '#description' => t('Look for a menu item which corresponds the breadcrumbs and set that as the active menu item.'),
  );
  $form['hansel_set_menu_item_skip_first'] = array(
    '#type' => 'checkbox',
    '#title' => t('Skip first crumb'),
    '#default_value' => variable_get('hansel_set_menu_item_skip_first', TRUE),
    '#description' => t('Ignore the first breadcrumb item when searching for a menu item.'),
  );
  $form['hansel_set_menu_name'] = array(
    '#type' => 'checkbox',
    '#title' => t('Set active menu name for current path'),
    '#default_value' => variable_get('hansel_set_menu_name', TRUE),
    '#description' => t('This is required for the \'leave original breadcrumbs\' option to work for pages which are not in the default menu. Turn this option off if you experience side effects.'),
  );
  $form['hansel_parent_lookup_paths'] = array(
    '#type' => 'checkbox',
    '#title' => t('Lookup url aliases when looking for parents'),
    '#default_value' => variable_get('hansel_parent_lookup_paths', TRUE),
    '#description' => t('Hansel is able to lookup parents based on url aliases. But this may cost extra database queries. You should disable this feature when not required.'),
  );
  return system_settings_form($form);
}

/**
 * Validate callback for the Hansel settings form.
 */
function hansel_ui_settings_validate($form, &$form_state) {
  if (!preg_match('/^[0-9]+$/', $form_state['values']['hansel_max_item_length'])) {
    form_set_error('hansel_max_item_length', t('The maximum length of individual breadcrumb items must be a number.'));
  }
  if (!preg_match('/^[0-9]+$/', $form_state['values']['hansel_max_item_count'])) {
    form_set_error('hansel_max_item_count', t('The maximum number of items must be a number.'));
  }
}

/**
 * Generates the form for adding and editing rules.
 *
 * @param array $form
 * @param array $form_state
 * @param int $rid
 * @return array
 */
function hansel_ui_rule_form($form, &$form_state, $rid = NULL) {
  $form = array();
  if ($form_state['submitted']) {
    !empty($form_state['storage']) or $form_state['storage'] = array();
    $form_state['storage'] += $form_state['values'];
  }
  if ($rid) {
    $form['#rid'] = $rid;
    $sql = "SELECT r.rid, r.pid, r.name, r.crumb_action, r.crumb_action_arguments,\n      rag.destination as goto_destination, ral.restore_original as leave_restore,\n      ras.handler as switch_handler, ras.arguments as switch_arguments\n      FROM {hansel_rule} r\n      LEFT JOIN {hansel_rule_action_goto} rag ON rag.rid = r.rid\n      LEFT JOIN {hansel_rule_action_leave} ral ON ral.rid = r.rid\n      LEFT JOIN {hansel_rule_action_switch} ras ON ras.rid = r.rid\n      WHERE r.rid = :rid";
    $res = db_query($sql, array(
      ':rid' => $rid,
    ));
    if (!($rule = $res
      ->fetchObject())) {
      drupal_set_message(t('Rule not found'), 'error');
      drupal_goto('admin/config/search/hansel');
    }
    $rule->crumb_action_arguments = unserialize($rule->crumb_action_arguments);
    $rule_action = 'leave';
    empty($rule->goto_destination) or $rule_action = 'goto';
    empty($rule->switch_handler) or $rule_action = 'switch';
  }
  else {
    $rule = new stdClass();
  }
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
    '#required' => TRUE,
    '#default_value' => isset($form_state['storage']['name']) ? $form_state['storage']['name'] : isset($rule->name) ? $rule->name : '',
  );
  $form['pid'] = array(
    '#type' => 'select',
    '#title' => t('Parent'),
    '#options' => _hansel_get_rules_tree(-1),
    '#default_value' => isset($form_state['storage']['pid']) ? $form_state['storage']['pid'] : isset($rule->pid) ? $rule->pid : 0,
  );
  $form['config'] = array(
    '#prefix' => '<div id="hansel-config">',
    '#suffix' => '</div>',
  );
  if (empty($form_state['values']['action'])) {
    $options = array(
      '' => 'none',
    );
    foreach (_hansel_get_action_types() as $types => $details) {
      $options[$types] = $types;
    }
    $form['config']['crumb_action'] = array(
      '#type' => 'select',
      '#title' => t('Action with breadcrumbs'),
      '#options' => $options,
      '#default_value' => isset($rule->crumb_action) ? $rule->crumb_action : 'add single link',
    );
    $form['config']['action'] = array(
      '#type' => 'radios',
      '#title' => t('Action'),
      '#required' => TRUE,
      '#options' => array(
        'goto' => t('Goto rule'),
        'leave' => t('Leave'),
        'switch' => t('Switch'),
      ),
      '#default_value' => isset($rule_action) ? $rule_action : '',
    );
    $form['config']['next'] = array(
      '#type' => 'submit',
      '#value' => t('Next'),
      '#submit' => array(
        'hansel_ui_rule_form_submit',
      ),
      '#ajax' => array(
        'callback' => 'hansel_ui_rule_form_ajax',
        'wrapper' => 'hansel-config',
        'effect' => 'fade',
      ),
    );

    // Add a cancel link only if we are editting an existing rule
    if (isset($rule->name)) {
      $form['config']['buttons']['cancel'] = array(
        '#value' => l(t('Cancel'), 'admin/config/search/hansel'),
      );
    }
  }
  else {
    if (!empty($form_state['values']['crumb_action'])) {
      $action_types = _hansel_get_action_types();
      if (!empty($action_types[$form_state['values']['crumb_action']]['config form'])) {
        $arguments = !empty($rule->crumb_action_arguments) ? $rule->crumb_action_arguments : array();
        $config_form = call_user_func($action_types[$form_state['values']['crumb_action']]['config form'], $arguments);
        if (!empty($config_form)) {
          $form['config']['crumb'] = array(
            '#type' => 'fieldset',
            '#title' => t('Actions with breadcrumbs'),
          );
        }
        foreach ($config_form as $name => $element) {
          $form['config']['crumb']['crumb_action_' . $name] = $element;
        }

        // Add the list of available tokens.
        if (!empty($action_types[$form_state['values']['crumb_action']]['show token list'])) {
          $form['config']['tokens'] = _hansel_ui_rule_form_generate_token_list();
        }
      }
    }
    if ($form_state['values']['action'] == 'goto') {
      $options = _hansel_get_rules_tree();
      $form['config']['goto'] = array(
        '#type' => 'fieldset',
        '#title' => t('Goto'),
      );
      $form['config']['goto']['destination_rid'] = array(
        '#type' => 'select',
        '#title' => t('Destination'),
        '#options' => $options,
        '#required' => TRUE,
        '#default_value' => isset($rule->goto_destination) ? $rule->goto_destination : 0,
      );
    }
    if ($form_state['values']['action'] == 'switch') {
      $options = array();
      foreach (_hansel_get_switch_types() as $types => $details) {
        $options[$types] = $types;
      }
      $form['config']['switch'] = array(
        '#type' => 'fieldset',
        '#title' => t('Switch'),
      );
      $form['config']['switch']['handler'] = array(
        '#type' => 'select',
        '#title' => t('Switch on'),
        '#options' => $options,
        '#required' => TRUE,
        '#default_value' => isset($rule->switch_handler) ? $rule->switch_handler : '',
      );
    }
    if ($form_state['values']['action'] == 'leave') {
      $form['config']['leave'] = array(
        '#type' => 'fieldset',
        '#title' => t('Leave'),
      );
      $form['config']['leave']['restore'] = array(
        '#type' => 'checkbox',
        '#title' => t('Restore original breadcrumbs'),
        '#default_value' => !empty($rule->leave_restore) ? TRUE : FALSE,
      );
    }
    $form['config']['buttons']['save'] = array(
      '#type' => 'submit',
      '#value' => t('Save'),
      '#submit' => array(
        'hansel_ui_rule_form_submit',
      ),
    );
    $form['config']['buttons']['save'] = array(
      '#type' => 'submit',
      '#value' => t('Save'),
      '#submit' => array(
        'hansel_ui_rule_form_submit',
      ),
    );
    $form['config']['buttons']['cancel'] = array(
      '#markup' => l(t('Cancel'), 'admin/config/search/hansel'),
    );
  }
  return $form;
}

/**
 * Form submit handler.
 *
 * Saves the rule to the database.
 */
function hansel_ui_rule_form_submit($form, &$form_state) {
  switch ($form_state['clicked_button']['#id']) {
    case 'edit-save':
      $name = $form_state['values']['name'];
      $pid = $form_state['values']['pid'];
      $action = $form_state['storage']['action'];
      $crumb_action = $form_state['storage']['crumb_action'];
      $rule = new stdClass();

      // Build the update argument for drupal_write_record()
      $update = array();
      if (!empty($form['#rid'])) {
        $update[] = 'rid';
        $rule->rid = $form['#rid'];
      }
      $rule->name = $name;
      $rule->pid = $pid;
      if ($crumb_action) {
        $crumb_action_arguments = array();
        foreach ($form_state['values'] as $name => $value) {
          if (preg_match('/^crumb_action_(.+)$/', $name, $match)) {
            $crumb_action_arguments[$match[1]] = $value;
          }
        }
        $rule->crumb_action = $crumb_action;
        $rule->crumb_action_arguments = serialize($crumb_action_arguments);
      }
      else {
        $rule->crumb_action = '';
        $rule->crumb_action_arguments = serialize(array());
      }
      if (!drupal_write_record('hansel_rule', $rule, $update)) {
        drupal_set_message(t('Error writing rule to database'), 'error');
        return;
      }
      if ($update) {
        foreach (array(
          'goto',
          'leave',
          'switch',
        ) as $table_suffix) {
          $result = db_query("DELETE FROM {hansel_rule_action_" . $table_suffix . "} WHERE rid = :rid", array(
            ':rid' => $rule->rid,
          ));
          $result
            ->rowCount();

          // Make sure the query ran before inserting the new row
        }
      }
      $rule_action = new stdClass();
      $rule_action->rid = $rule->rid;
      switch ($action) {
        case 'goto':
          $rule_action->destination = $form_state['values']['destination_rid'];
          break;
        case 'leave':
          $rule_action->restore_original = $form_state['values']['restore'] ? 1 : 0;
          break;
        case 'switch':
          $rule_action->handler = $form_state['values']['handler'];
          $rule_action->arguments = serialize(array());
          break;
      }
      if (!drupal_write_record('hansel_rule_action_' . $action, $rule_action)) {
        drupal_set_message(t('Error writing rule to database'), 'error');
        return;
      }
      cache_clear_all('hansel_config', 'cache');
      drupal_set_message(t('Succesfully saved rule %name', array(
        '%name' => $rule->name,
      )));
      $form_state['redirect'] = 'admin/config/search/hansel';
      drupal_goto('admin/config/search/hansel');

      // $form_state['redirect'] does not redirect for some reason
      break;
  }
  $form_state['rebuild'] = TRUE;
}

/**
 * Ajax form handler
 */
function hansel_ui_rule_form_ajax($form, $form_state) {
  return $form['config'];
}

/**
 * Generate a fieldset with a list of available tokens.
 *
 * @param array $types
 * @return array
 */
function _hansel_ui_rule_form_generate_token_list() {
  $placeholders = array(
    array(
      '[arg-?]',
      t('URL argument. Replace the question mark by a number, 1 is the first argument.'),
    ),
  );
  $tokens = token_info();
  foreach ($tokens['tokens'] as $type => $token) {
    if ($type == 'node' || $type == 'user') {
      foreach ($token as $placeholder => $name) {
        $placeholders[] = array(
          check_plain("[{$type}:{$placeholder}]"),
          check_plain($name['description']),
        );
      }
    }
  }
  $form_element = array(
    '#type' => 'fieldset',
    '#title' => t('Available tokens'),
    '#description' => t('You can use these tokens in the link title and path. Not all tokens might be available, depending on the path. You should use the "-raw" alternative if available.'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form_element['items'] = array(
    '#markup' => theme('table', array(
      'header' => array(
        t('Token'),
        t('Description'),
      ),
      'rows' => $placeholders,
    )),
  );
  return $form_element;
}

/**
 * Alter a switch configuration form before passing it to the rendering engine.
 *
 * @param array $form
 * @return array
 */
function hansel_ui_switch_configure_form($form) {
  global $_hansel_rid;
  $form['#rid'] = $_hansel_rid;
  $form['#submit'][] = 'hansel_ui_switch_configure_form_submit';
  $form['buttons']['save'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );
  $form['buttons']['cancel'] = array(
    '#value' => l(t('Cancel'), 'admin/config/search/hansel'),
  );
  return $form;
}

/**
 * Form submit handler for switch configuration forms.
 *
 * Saves the switch configuration to the database.
 */
function hansel_ui_switch_configure_form_submit($form, &$form_state) {
  $arguments = $form_state['values'];
  unset($arguments['op']);
  unset($arguments['save']);
  unset($arguments['form_build_id']);
  unset($arguments['form_token']);
  unset($arguments['form_id']);
  db_query("UPDATE {hansel_rule_action_switch} SET arguments = :args WHERE rid = :rid", array(
    ':args' => serialize($arguments),
    ':rid' => $form['#rid'],
  ));
  cache_clear_all('hansel_config', 'cache');
  $form_state['redirect'] = 'admin/config/search/hansel';
}

/**
 * Generate the switch configuration form.
 */
function hansel_ui_config_switch_form($form, &$form_state, $rid) {

  // Store the rule id in a global var, will be used in hansel_ui_switch_configure_form().
  global $_hansel_rid;
  $_hansel_rid = $rid;
  $sql = "SELECT r.rid, r.name, ras.handler as handler, ras.arguments as arguments\n    FROM {hansel_rule} r\n    JOIN {hansel_rule_action_switch} ras ON ras.rid = r.rid\n    WHERE r.rid = :rid";
  $res = db_query($sql, array(
    ':rid' => $rid,
  ));
  if (!($rule = $res
    ->fetchObject())) {
    drupal_set_message(t('No switch found for rule'), 'error');
    drupal_goto('admin/config/search/hansel');
  }
  if (!_hansel_is_configurable_switch($rule->handler)) {
    drupal_set_message(t('Invalid or non configurable switch handler'), 'error');
    drupal_goto('admin/config/search/hansel');
  }
  $rule->arguments = empty($rule->arguments) ? array() : unserialize($rule->arguments);
  $types = _hansel_get_switch_types();
  return call_user_func($types[$rule->handler]['config form'], $rule->arguments);
}

/**
 * Menu callback for the delete rule form.
 */
function hansel_ui_delete_rule_form($form, &$form_state, $rid) {
  $form = array();
  $form['#rid'] = $rid;
  $sql = "SELECT r.name, (SELECT COUNT(*) FROM {hansel_rule} r2 WHERE r2.pid = r.rid) as children\n    FROM {hansel_rule} r WHERE r.rid = :rid";
  $res = db_query($sql, array(
    ':rid' => $rid,
  ))
    ->fetchObject();
  if (!($rule = $res)) {
    drupal_set_message(t('Rule not found'), 'error');
    drupal_goto('admin/config/search/hansel');
  }
  if ($rule->children) {
    $form['info'] = array(
      '#markup' => '<p>' . t('Are you sure you want to delete rule %rule with all its child rules?', array(
        '%rule' => $rule->name,
      )) . '</p>',
    );
  }
  else {
    $form['info'] = array(
      '#markup' => '<p>' . t('Are you sure you want to delete rule %rule?', array(
        '%rule' => $rule->name,
      )) . '</p>',
    );
  }
  $form['buttons']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Delete'),
  );
  $form['buttons']['cancel'] = array(
    '#markup' => l(t('Cancel'), 'admin/config/search/hansel'),
  );
  return $form;
}

/**
 * Form submit handler for the delete rule form.
 */
function hansel_ui_delete_rule_form_submit($form, &$form_state) {
  $deleted = _hansel_ui_delete_rule($form['#rid']);
  cache_clear_all('hansel_config', 'cache');
  drupal_set_message(format_plural($deleted, '1 rule deleted', '@count rules deleted'));
  $form_state['redirect'] = 'admin/config/search/hansel';
}

/**
 * Delete a rule with all of its subrules.
 *
 * @access private
 * @param int $rid
 * @return int
 */
function _hansel_ui_delete_rule($rid) {
  $deleted = 0;
  $res = db_query("SELECT rid FROM {hansel_rule} WHERE pid = :pid", array(
    ':pid' => $rid,
  ));
  while ($rule = $res
    ->fetchObject()) {
    $deleted += _hansel_ui_delete_rule($rule->rid);
  }
  $result = db_query("DELETE FROM {hansel_rule} WHERE rid = :rid", array(
    ':rid' => $rid,
  ));
  $deleted += $result
    ->rowCount();
  return $deleted;
}

/**
 * Callback for "url argument" switch to generate the configuration form.
 *
 * @param array $arguments
 * @return array
 */
function hansel_ui_switch_url_argument_config_form($arguments) {
  $form = array();
  $form['argument'] = array(
    '#type' => 'textfield',
    '#title' => t('Argument number'),
    '#default_value' => empty($arguments['argument']) ? '1' : $arguments['argument'],
    '#size' => 5,
    '#description' => t('Must be numeric. Use 1 for the first argument.'),
    '#required' => TRUE,
  );
  $form['cs'] = array(
    '#type' => 'checkbox',
    '#title' => t('Use case sensitive matching'),
    '#default_value' => !empty($arguments['cs']),
    '#description' => t('Do not match on rule "node" when on path "Node".'),
  );
  $form['regex'] = array(
    '#type' => 'checkbox',
    '#title' => t('Use regular expressions'),
    '#default_value' => !empty($arguments['regex']),
    '#description' => t('If enabled, all subrules are parsed as Perl compatible regular expressions.'),
  );
  $form['#validate'] = array(
    'hansel_ui_switch_url_arguments_config_form_validate',
  );
  return hansel_ui_switch_configure_form($form);
}

/**
 * Validate callback for the "url argument" switch configuration form.
 */
function hansel_ui_switch_url_arguments_config_form_validate($form, &$form_state) {
  if (!preg_match('/^[1-9][0-9]?$/', $form_state['values']['argument'])) {
    form_set_error('argument', t('Argument must be a number between 1 and 99'));
  }
}

/**
 * Callback for "PHP code" switch to generate the configuration form.
 *
 * @param array $arguments
 * @return array
 */
function hansel_ui_switch_php_argument_config_form($arguments) {
  $form = array();
  if (user_access('use PHP for hansel configuration')) {
    $form['php_argument'] = array(
      '#type' => 'textarea',
      '#title' => t('PHP evaluation'),
      '#default_value' => isset($arguments['php_argument']) ? $arguments['php_argument'] : '',
      '#description' => t('PHP code to return the argument. Include %php tags.', array(
        '%php' => '<?php ?>',
      )),
      '#required' => TRUE,
    );
    return hansel_ui_switch_configure_form($form);
  }
  else {
    $form['php_argument'] = array(
      '#type' => 'value',
      '#value' => isset($arguments['php_argument']) ? $arguments['php_argument'] : '',
    );
    $form['php_argument_info'] = array(
      '#type' => 'markup',
      '#value' => t('You don\'t have sufficient permissions to use PHP in Hansel.'),
    );
    return $form;
  }
}

/**
 * Callback for "node age" switch to generate the configuration form.
 *
 * @param array $arguments
 * @return array
 */
function hansel_ui_switch_node_age_config_form($arguments) {
  $form = array();
  $options = drupal_map_assoc(array(
    1,
    60,
    3600,
    86400,
    86400 * 30,
    86400 * 365,
  ), 'format_interval');
  $form['unit'] = array(
    '#type' => 'radios',
    '#title' => t('Unit definition'),
    '#options' => $options,
    '#default_value' => empty($arguments['unit']) ? 86400 : $arguments['unit'],
    '#required' => TRUE,
    '#description' => t('When this is set to 1 day, a subrule with the name <em>&lt; 2</em> means less than two days old.'),
  );
  return hansel_ui_switch_configure_form($form);
}

/**
 * Callback for "path alias" switch to generate the configuration form.
 *
 * @param array $arguments
 * @return array
 */
function hansel_ui_switch_path_alias_config_form($arguments) {
  $form = array();
  $options = array(
    0 => t('starts with'),
    1 => t('ends with'),
    2 => t('contains'),
    3 => t('matches regular expression'),
  );
  $form['mode'] = array(
    '#type' => 'radios',
    '#title' => t('Mode'),
    '#options' => $options,
    '#default_value' => empty($arguments['mode']) ? 0 : $arguments['mode'],
    '#required' => TRUE,
  );
  $form['cs'] = array(
    '#type' => 'checkbox',
    '#title' => t('Use case sensitive matching'),
    '#default_value' => !empty($arguments['cs']),
    '#description' => t('Do not match on rule "node" when on path "Node".'),
  );
  return hansel_ui_switch_configure_form($form);
}

/**
 * Callback for "request uri" switch to generate the configuration form.
 *
 * @param array $arguments
 * @return array
 */
function hansel_ui_switch_request_uri_config_form($arguments) {
  return hansel_ui_switch_path_alias_config_form($arguments);
}

/**
 * Callback for the "add single link" breadcrumb action to generate the config form.
 *
 * @param array $arguments
 * @return array
 */
function hansel_ui_action_add_single_link_config_form($arguments) {
  $form = array();
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Link title'),
    '#required' => TRUE,
    '#default_value' => isset($arguments['title']) ? $arguments['title'] : '',
  );
  $form['translate'] = array(
    '#type' => 'checkbox',
    '#title' => t('Translate title'),
    '#default_value' => isset($arguments['translate']) ? $arguments['translate'] : FALSE,
  );
  $form['remove_tokens'] = array(
    '#type' => 'checkbox',
    '#title' => t('Remove non-existent tokens in output'),
    '#default_value' => isset($arguments['remove_tokens']) ? $arguments['remove_tokens'] : FALSE,
  );
  $form['path'] = array(
    '#type' => 'textfield',
    '#title' => t('Link path'),
    '#required' => TRUE,
    '#default_value' => isset($arguments['path']) ? $arguments['path'] : '',
  );
  $form['skipalias'] = array(
    '#type' => 'checkbox',
    '#title' => t('Skip link in alias token'),
    '#default_value' => isset($arguments['skipalias']) ? $arguments['skipalias'] : FALSE,
  );
  return $form;
}

/**
 * Callback for the "add link to nodetype" breadcrumb action to generate the config form.
 *
 * @param array $arguments
 * @return array
 */
function hansel_ui_action_add_link_to_nodetype_config_form($arguments) {
  $form = array();
  $form['path'] = array(
    '#type' => 'textfield',
    '#title' => t('Link path'),
    '#required' => TRUE,
    '#default_value' => isset($arguments['path']) ? $arguments['path'] : 'node/add/[type]',
    '#description' => t('[type] will be replaced by the nodetype, with underscores replaced by dashes. [type-raw] can be used for the original typename.'),
  );
  return $form;
}

/**
 * Callback for the "add link to user" breadcrumb action to generate the config form.
 *
 * @param array $arguments
 * @return array
 */
function hansel_ui_action_add_link_to_user_config_form($arguments) {
  $form = array();
  $form['you'] = array(
    '#type' => 'textfield',
    '#title' => t('Title for your account'),
    '#default_value' => isset($arguments['you']) ? $arguments['you'] : '',
    '#description' => t('Text to use if the user is the same as the visitor. Leave empty to use username.'),
  );
  $form['translate'] = array(
    '#type' => 'checkbox',
    '#title' => t('Translate title'),
    '#default_value' => isset($arguments['translate']) ? $arguments['translate'] : FALSE,
  );
  if (module_exists('realname')) {
    $form['realname'] = array(
      '#type' => 'checkbox',
      '#title' => t('Use realname'),
      '#default_value' => isset($arguments['realname']) ? $arguments['realname'] : FALSE,
      '#description' => t('Use the name configured in the realname module instead of the username.'),
    );
  }
  return $form;
}

/**
 * Nodetypes form.
 */
function hansel_ui_nodetypes_form($form, &$form_state) {
  $configuration = variable_get('hansel_nodetypes', array());
  $form['info'] = array(
    '#markup' => '<p>' . t('On this page you can define the parents for nodes of a given type. This parent is used for the <em>add parents</em> action. I.e.: you can define a news page on <em>/news</em> as the parent page for all nodes of type <em>news</em>.') . '</p>',
  );
  $info = entity_get_info('node');
  foreach ($info['bundles'] as $name => $type) {
    $path = isset($configuration[$name]) ? $configuration[$name]['path'] : '';
    $title = isset($configuration[$name]) ? $configuration[$name]['title'] : '';
    $form["fieldset-{$name}"] = array(
      '#title' => $type['label'],
      '#type' => 'fieldset',
      '#collapsible' => TRUE,
      '#collapsed' => $path ? FALSE : TRUE,
    );
    $form["fieldset-{$name}"]["path-{$name}"] = array(
      '#type' => 'textfield',
      '#title' => t('Path'),
      '#default_value' => $path,
      '#description' => t('Path of parent page. Do not use leading or trailing slashes.'),
    );
    $form["fieldset-{$name}"]["title-{$name}"] = array(
      '#type' => 'textfield',
      '#title' => t('Title'),
      '#default_value' => $title,
      '#description' => t('Title of parent page. This text is used in the breadcrumbs. Hansel will try to get the title from menu or node if leaved empty.'),
    );
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save configuration'),
  );
  return $form;
}

/**
 * Form validate callback.
 */
function hansel_ui_nodetypes_form_validate($form, &$form_state) {
  $info = entity_get_info('node');
  foreach ($info['bundles'] as $name => $type) {
    $path = empty($form_state['values']["path-{$name}"]) ? '' : $form_state['values']["path-{$name}"];
    $title = empty($form_state['values']["title-{$name}"]) ? '' : $form_state['values']["title-{$name}"];
    $path = _hansel_get_original_path($path);
    if (empty($path) && !empty($title)) {
      form_set_error("path-{$name}", t('Path for %type is required when title is given.', array(
        '%type' => $type['label'],
      )));
    }
    if (!empty($path) && empty($title)) {

      // Try to get the title automatically.
      if (!($title = _hansel_ui_get_title_for_path($path))) {
        form_set_error("title-{$name}", t('Title for %type could not be set automatically.', array(
          '%type' => $type['label'],
        )));
      }
    }
  }
}

/**
 * Form submit callback.
 */
function hansel_ui_nodetypes_form_submit($form, &$form_state) {
  $configuration = array();
  $info = entity_get_info('node');
  foreach ($info['bundles'] as $name => $type) {
    $path = empty($form_state['values']["path-{$name}"]) ? '' : $form_state['values']["path-{$name}"];
    $title = empty($form_state['values']["title-{$name}"]) ? '' : $form_state['values']["title-{$name}"];
    $path = _hansel_get_original_path($path);
    if (!empty($path)) {
      $title = empty($title) ? $title = _hansel_ui_get_title_for_path($path) : $title;
      $configuration[$name] = array(
        'path' => $path,
        'title' => $title,
      );
    }
  }
  variable_set('hansel_nodetypes', $configuration);
  cache_clear_all('hansel_config', 'cache');
  drupal_set_message(t('The configuration options have been saved.'));
}

/**
 * Try to reveal the title by path via menu or node.
 * 
 * @param string $path
 * @return string 
 */
function _hansel_ui_get_title_for_path($path) {
  if (module_exists('menu')) {
    $link_title = db_select('menu_links', 'ml')
      ->fields('ml', array(
      'link_title',
    ))
      ->condition('ml.link_path', $path)
      ->range(0, 1)
      ->execute()
      ->fetchField();
    if ($link_title) {
      return $link_title;
    }
  }
  if (preg_match('/^node\\/([0-9]+)$/si', $path, $match)) {
    $title = db_select('node', 'n')
      ->fields('n', array(
      'title',
    ))
      ->condition('n.nid', $match[1])
      ->range(0, 1)
      ->execute()
      ->fetchField();
    if ($title) {
      return $title;
    }
  }
  return FALSE;
}

Functions

Namesort descending Description
hansel_ui_action_add_link_to_nodetype_config_form Callback for the "add link to nodetype" breadcrumb action to generate the config form.
hansel_ui_action_add_link_to_user_config_form Callback for the "add link to user" breadcrumb action to generate the config form.
hansel_ui_action_add_single_link_config_form Callback for the "add single link" breadcrumb action to generate the config form.
hansel_ui_config_switch_form Generate the switch configuration form.
hansel_ui_delete_rule_form Menu callback for the delete rule form.
hansel_ui_delete_rule_form_submit Form submit handler for the delete rule form.
hansel_ui_menu Implements hook_menu().
hansel_ui_nodetypes_form Nodetypes form.
hansel_ui_nodetypes_form_submit Form submit callback.
hansel_ui_nodetypes_form_validate Form validate callback.
hansel_ui_page Page callback
hansel_ui_rule_form Generates the form for adding and editing rules.
hansel_ui_rule_form_ajax Ajax form handler
hansel_ui_rule_form_submit Form submit handler.
hansel_ui_settings Page callback.
hansel_ui_settings_validate Validate callback for the Hansel settings form.
hansel_ui_switch_configure_form Alter a switch configuration form before passing it to the rendering engine.
hansel_ui_switch_configure_form_submit Form submit handler for switch configuration forms.
hansel_ui_switch_node_age_config_form Callback for "node age" switch to generate the configuration form.
hansel_ui_switch_path_alias_config_form Callback for "path alias" switch to generate the configuration form.
hansel_ui_switch_php_argument_config_form Callback for "PHP code" switch to generate the configuration form.
hansel_ui_switch_request_uri_config_form Callback for "request uri" switch to generate the configuration form.
hansel_ui_switch_url_arguments_config_form_validate Validate callback for the "url argument" switch configuration form.
hansel_ui_switch_url_argument_config_form Callback for "url argument" switch to generate the configuration form.
_hansel_ui_delete_rule Delete a rule with all of its subrules.
_hansel_ui_get_title_for_path Try to reveal the title by path via menu or node.
_hansel_ui_list_rules
_hansel_ui_rule_form_generate_token_list Generate a fieldset with a list of available tokens.