danielebarchiesi@0: '_blank'); danielebarchiesi@0: danielebarchiesi@0: return l($variables['text'], 'token/tree', $variables['options']); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Page callback to output a token tree as an empty page. danielebarchiesi@0: */ danielebarchiesi@0: function token_page_output_tree() { danielebarchiesi@0: $options = isset($_GET['options']) ? drupal_json_decode($_GET['options']) : array(); danielebarchiesi@0: danielebarchiesi@0: // Check the token against the serialized options to prevent random access to danielebarchiesi@0: // the token browser page. danielebarchiesi@0: if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'token-tree:' . serialize($options))) { danielebarchiesi@0: return MENU_ACCESS_DENIED; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Force the dialog option to be false so we're not creating a dialog within danielebarchiesi@0: // a dialog. danielebarchiesi@0: $options['dialog'] = FALSE; danielebarchiesi@0: danielebarchiesi@0: $output = theme('token_tree', $options); danielebarchiesi@0: print '' . drupal_get_css() . drupal_get_js() . ''; danielebarchiesi@0: print '' . $output . ''; danielebarchiesi@0: drupal_exit(); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Theme a tree table. danielebarchiesi@0: * danielebarchiesi@0: * @ingroup themeable danielebarchiesi@0: */ danielebarchiesi@0: function theme_tree_table($variables) { danielebarchiesi@0: foreach ($variables['rows'] as &$row) { danielebarchiesi@0: $row += array('class' => array()); danielebarchiesi@0: if (!empty($row['parent'])) { danielebarchiesi@0: $row['class'][] = 'child-of-' . $row['parent']; danielebarchiesi@0: unset($row['parent']); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if (!empty($variables['rows'])) { danielebarchiesi@0: drupal_add_library('token', 'treeTable'); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return theme('table', $variables); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Provide a 'tree' display of nested tokens. danielebarchiesi@0: * danielebarchiesi@0: * @ingroup themeable danielebarchiesi@0: */ danielebarchiesi@0: function theme_token_tree($variables) { danielebarchiesi@0: if (!empty($variables['dialog'])) { danielebarchiesi@0: return theme_token_tree_link($variables); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $token_types = $variables['token_types']; danielebarchiesi@0: $info = token_get_info(); danielebarchiesi@0: danielebarchiesi@0: if ($token_types == 'all') { danielebarchiesi@0: $token_types = array_keys($info['types']); danielebarchiesi@0: } danielebarchiesi@0: elseif ($variables['global_types']) { danielebarchiesi@0: $token_types = array_merge($token_types, token_get_global_token_types()); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $element = array( danielebarchiesi@0: '#cache' => array( danielebarchiesi@0: 'cid' => 'tree-rendered:' . hash('sha256', serialize(array('token_types' => $token_types, 'global_types' => NULL) + $variables)), danielebarchiesi@0: 'bin' => 'cache_token', danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: if ($cached_output = token_render_cache_get($element)) { danielebarchiesi@0: return $cached_output; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $options = array( danielebarchiesi@0: 'flat' => TRUE, danielebarchiesi@0: 'restricted' => $variables['show_restricted'], danielebarchiesi@0: 'depth' => $variables['recursion_limit'], danielebarchiesi@0: ); danielebarchiesi@0: $multiple_token_types = (count($token_types) > 1); danielebarchiesi@0: $rows = array(); danielebarchiesi@0: danielebarchiesi@0: foreach ($info['types'] as $type => $type_info) { danielebarchiesi@0: if (!in_array($type, $token_types)) { danielebarchiesi@0: continue; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if ($multiple_token_types) { danielebarchiesi@0: $row = _token_token_tree_format_row($type, $type_info, TRUE); danielebarchiesi@0: unset($row['data']['value']); danielebarchiesi@0: $rows[] = $row; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $tree = token_build_tree($type, $options); danielebarchiesi@0: foreach ($tree as $token => $token_info) { danielebarchiesi@0: if (!empty($token_info['restricted']) && empty($variables['show_restricted'])) { danielebarchiesi@0: continue; danielebarchiesi@0: } danielebarchiesi@0: if ($multiple_token_types && !isset($token_info['parent'])) { danielebarchiesi@0: $token_info['parent'] = $type; danielebarchiesi@0: } danielebarchiesi@0: $row = _token_token_tree_format_row($token, $token_info); danielebarchiesi@0: unset($row['data']['value']); danielebarchiesi@0: $rows[] = $row; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $element += array( danielebarchiesi@0: '#theme' => 'tree_table', danielebarchiesi@0: '#header' => array( danielebarchiesi@0: t('Name'), danielebarchiesi@0: t('Token'), danielebarchiesi@0: t('Description'), danielebarchiesi@0: ), danielebarchiesi@0: '#rows' => $rows, danielebarchiesi@0: '#attributes' => array('class' => array('token-tree')), danielebarchiesi@0: '#empty' => t('No tokens available'), danielebarchiesi@0: '#attached' => array( danielebarchiesi@0: 'js' => array(drupal_get_path('module', 'token') . '/token.js'), danielebarchiesi@0: 'css' => array(drupal_get_path('module', 'token') . '/token.css'), danielebarchiesi@0: 'library' => array(array('token', 'treeTable')), danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: if ($variables['click_insert']) { danielebarchiesi@0: $element['#caption'] = t('Click a token to insert it into the field you\'ve last clicked.'); danielebarchiesi@0: $element['#attributes']['class'][] = 'token-click-insert'; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $output = drupal_render($element); danielebarchiesi@0: token_render_cache_set($output, $element); danielebarchiesi@0: return $output; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Build a row in the token tree. danielebarchiesi@0: */ danielebarchiesi@0: function _token_token_tree_format_row($token, array $token_info, $is_group = FALSE) { danielebarchiesi@0: // Build a statically cached array of default values. This is around four danielebarchiesi@0: // times as efficient as building the base array from scratch each time this danielebarchiesi@0: // function is called. danielebarchiesi@0: static $defaults = array( danielebarchiesi@0: 'id' => '', danielebarchiesi@0: 'class' => array(), danielebarchiesi@0: 'data' => array( danielebarchiesi@0: 'name' => '', danielebarchiesi@0: 'token' => '', danielebarchiesi@0: 'value' => '', danielebarchiesi@0: 'description' => '', danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: $row = $defaults; danielebarchiesi@0: $row['id'] = _token_clean_css_identifier($token); danielebarchiesi@0: $row['data']['name'] = $token_info['name']; danielebarchiesi@0: $row['data']['description'] = $token_info['description']; danielebarchiesi@0: danielebarchiesi@0: if ($is_group) { danielebarchiesi@0: // This is a token type/group. danielebarchiesi@0: $row['class'][] = 'token-group'; danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: // This is a token. danielebarchiesi@0: $row['data']['token']['data'] = $token; danielebarchiesi@0: $row['data']['token']['class'][] = 'token-key'; danielebarchiesi@0: if (isset($token_info['value'])) { danielebarchiesi@0: $row['data']['value'] = $token_info['value']; danielebarchiesi@0: } danielebarchiesi@0: if (!empty($token_info['parent'])) { danielebarchiesi@0: $row['parent'] = _token_clean_css_identifier($token_info['parent']); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return $row; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Wrapper function for drupal_clean_css_identifier() for use with tokens. danielebarchiesi@0: * danielebarchiesi@0: * This trims any brackets from the token and also cleans the colon character danielebarchiesi@0: * to a hyphen. danielebarchiesi@0: * danielebarchiesi@0: * @see drupal_clean_css_identifier() danielebarchiesi@0: */ danielebarchiesi@0: function _token_clean_css_identifier($id) { danielebarchiesi@0: static $replacements = array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '', ':' => '--', '?' => '', '<' => '-', '>' => '-'); danielebarchiesi@0: return 'token-' . rtrim(strtr(trim($id, '[]'), $replacements), '-'); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Menu callback; prints the available tokens and values for an object. danielebarchiesi@0: */ danielebarchiesi@0: function token_devel_token_object($entity_type, $entity, $token_type = NULL) { danielebarchiesi@0: $header = array( danielebarchiesi@0: t('Token'), danielebarchiesi@0: t('Value'), danielebarchiesi@0: ); danielebarchiesi@0: $rows = array(); danielebarchiesi@0: danielebarchiesi@0: $options = array( danielebarchiesi@0: 'flat' => TRUE, danielebarchiesi@0: 'values' => TRUE, danielebarchiesi@0: 'data' => array($entity_type => $entity), danielebarchiesi@0: ); danielebarchiesi@0: if (!isset($token_type)) { danielebarchiesi@0: $token_type = $entity_type; danielebarchiesi@0: } danielebarchiesi@0: $tree = token_build_tree($token_type, $options); danielebarchiesi@0: foreach ($tree as $token => $token_info) { danielebarchiesi@0: if (!empty($token_info['restricted'])) { danielebarchiesi@0: continue; danielebarchiesi@0: } danielebarchiesi@0: if (!isset($token_info['value']) && !empty($token_info['parent']) && !isset($tree[$token_info['parent']]['value'])) { danielebarchiesi@0: continue; danielebarchiesi@0: } danielebarchiesi@0: $row = _token_token_tree_format_row($token, $token_info); danielebarchiesi@0: unset($row['data']['description']); danielebarchiesi@0: unset($row['data']['name']); danielebarchiesi@0: $rows[] = $row; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $build['tokens'] = array( danielebarchiesi@0: '#theme' => 'tree_table', danielebarchiesi@0: '#header' => $header, danielebarchiesi@0: '#rows' => $rows, danielebarchiesi@0: '#attributes' => array('class' => array('token-tree')), danielebarchiesi@0: '#empty' => t('No tokens available.'), danielebarchiesi@0: '#attached' => array( danielebarchiesi@0: 'js' => array(drupal_get_path('module', 'token') . '/token.js'), danielebarchiesi@0: 'css' => array(drupal_get_path('module', 'token') . '/token.css'), danielebarchiesi@0: ), danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: return $build; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Page callback to clear the token registry caches. danielebarchiesi@0: */ danielebarchiesi@0: function token_flush_cache_callback() { danielebarchiesi@0: if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], current_path())) { danielebarchiesi@0: return MENU_NOT_FOUND; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: token_clear_cache(); danielebarchiesi@0: drupal_set_message(t('Token registry caches cleared.')); danielebarchiesi@0: drupal_goto(); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: function token_autocomplete() { danielebarchiesi@0: $args = func_get_args(); danielebarchiesi@0: $string = implode('/', $args); danielebarchiesi@0: danielebarchiesi@0: $token_info = token_info(); danielebarchiesi@0: danielebarchiesi@0: preg_match_all('/\[([^\s\]:]*):?([^\s\]]*)?\]?/', $string, $matches); danielebarchiesi@0: $types = $matches[1]; danielebarchiesi@0: $tokens = $matches[2]; danielebarchiesi@0: danielebarchiesi@0: foreach ($types as $index => $type) { danielebarchiesi@0: if (!empty($tokens[$index]) || isset($token_info['types'][$type])) { danielebarchiesi@0: token_autocomplete_token($type, $tokens[$index]); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: token_autocomplete_type($type); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: function token_autocomplete_type($string = '') { danielebarchiesi@0: $token_info = token_info(); danielebarchiesi@0: $types = $token_info['types']; danielebarchiesi@0: $matches = array(); danielebarchiesi@0: danielebarchiesi@0: foreach ($types as $type => $info) { danielebarchiesi@0: if (!$string || strpos($type, $string) === 0) { danielebarchiesi@0: $type_key = "[{$type}:"; danielebarchiesi@0: $matches[$type_key] = levenshtein($type, $string); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if ($string) { danielebarchiesi@0: asort($matches); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: ksort($matches); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $matches = drupal_map_assoc(array_keys($matches)); danielebarchiesi@0: drupal_json_output($matches); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: function token_autocomplete_token($token_type) { danielebarchiesi@0: $args = func_get_args(); danielebarchiesi@0: array_shift($args); danielebarchiesi@0: $string = trim(implode('/', $args)); danielebarchiesi@0: $string = substr($string, strrpos($string, '[')); danielebarchiesi@0: danielebarchiesi@0: $token_type = $token_type['type']; danielebarchiesi@0: $matches = array(); danielebarchiesi@0: danielebarchiesi@0: if (!drupal_strlen($string)) { danielebarchiesi@0: $matches["[{$token_type}:"] = 0; danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $depth = max(1, substr_count($string, ':')); danielebarchiesi@0: $tree = token_build_tree($token_type, array('flat' => TRUE, 'depth' => $depth)); danielebarchiesi@0: foreach (array_keys($tree) as $token) { danielebarchiesi@0: if (strpos($token, $string) === 0) { danielebarchiesi@0: $matches[$token] = levenshtein($token, $string); danielebarchiesi@0: if (isset($tree[$token]['children'])) { danielebarchiesi@0: $token = rtrim($token, ':]') . ':'; danielebarchiesi@0: $matches[$token] = levenshtein($token, $string); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: asort($matches); danielebarchiesi@0: $matches = drupal_map_assoc(array_keys($matches)); danielebarchiesi@0: drupal_json_output($matches); danielebarchiesi@0: }