diff --git a/token.pages.inc b/token.pages.inc index cf4c2d1..53b7928 100644 --- a/token.pages.inc +++ b/token.pages.inc @@ -41,6 +41,12 @@ function theme_token_tree($variables) { elseif ($variables['global_types']) { $token_types = array_merge($token_types, token_get_global_token_types()); } + // Remove the list types to avoid overloading the token tree. + foreach ($token_types as $index => $token_type) { + if (preg_match('/list<([a-z]*)>/', $token_type, $match)) { + unset($token_types[$index]); + } + } $element = array( '#cache' => array( diff --git a/token.tokens.inc b/token.tokens.inc index e382a0b..3bb7235 100644 --- a/token.tokens.inc +++ b/token.tokens.inc @@ -76,6 +76,40 @@ function token_token_info_alter(&$info) { ); } } + + // Add list types. + $list_types = array(); + foreach ($info['tokens'] as $group => $tokens) { + foreach ($tokens as $token) { + if (isset($token['type']) && preg_match('/list<([a-z]*)>/', $token['type'], $match)) { + $list_types[$match[1]] = $match[0]; + } + } + } + foreach ($list_types as $type => $list) { + $info['tokens'][$list] = $info['tokens']['array']; + $info['tokens'][$list]['first']['type'] = $type; + $info['tokens'][$list]['last']['type'] = $type; + $info['tokens'][$list]['reversed']['type'] = $list; + $info['tokens'][$list]['value'] = array( + 'type' => $type, + 'name' => t('Value by key'), + 'description' => t('The specific element of the array, indexed by the keys/IDs in %keys.', array('%keys' => 'keys')), + 'dynamic' => TRUE, + ); + $info['tokens'][$list]['index'] = array( + 'type' => $type, + 'name' => t('Value by index'), + 'description' => t('The specific element of the array, indexed by zero-based numeric index.'), + 'dynamic' => TRUE, + ); + $type = $info['types'][$type]['name']; + $info['types'][$list] = array( + 'name' => t('Array of @type', array('@type' => $type)), + 'description' => t('Tokens related to arrays of %type', array('%type' => $type)), + 'needs-data' => $list, + ); + } } /** @@ -811,6 +845,101 @@ function token_tokens($type, $tokens, array $data = array(), array $options = ar // @todo Handle if the array values are not strings and could be chained. } + // List tokens. + if (preg_match('/list<([a-z]*)>/', $type, $match) && !empty($data[$type]) && is_array($data[$type])) { + $array_type = $type; + $element_type = $match[1]; + $array = $data[$array_type]; + + $sort = isset($options['array sort']) ? $options['array sort'] : TRUE; + $keys = element_children($array, $sort); + + foreach ($tokens as $name => $original) { + switch ($name) { + case 'first': + $value = $array[$keys[0]]; + $value = is_array($value) ? render($value) : (string) $value; + $replacements[$original] = $sanitize ? check_plain($value) : $value; + break; + case 'last': + $value = $array[$keys[count($keys) - 1]]; + $value = is_array($value) ? render($value) : (string) $value; + $replacements[$original] = $sanitize ? check_plain($value) : $value; + break; + case 'count': + $replacements[$original] = count($keys); + break; + case 'keys': + $replacements[$original] = token_render_array($keys, $options); + break; + case 'reversed': + $reversed = array_reverse($array, TRUE); + $replacements[$original] = token_render_array($reversed, $options); + break; + case 'join': + $replacements[$original] = token_render_array($array, array('join' => '') + $options); + break; + } + } + + // [list<>:value:*] dynamic tokens. + if ($value_tokens = token_find_with_prefix($tokens, 'value')) { + $tokss = array(); + foreach ($value_tokens as $key => $original) { + $k = strtok($key, ':'); + $tokss[$k][substr($key, strlen($k) + 1)] = $original; + } + foreach ($tokss as $key => $toks) { + if ($key[0] !== '#' && isset($array[$key])) { + $replacements += token_generate($element_type, $toks, array($element_type => $array[$key]), $options); + } + } + } + + // [list<>:index:*] dynamic tokens. + if ($index_tokens = token_find_with_prefix($tokens, 'index')) { + $tokss = array(); + foreach ($index_tokens as $index => $original) { + $i = strtok($index, ':'); + $tokss[$i][substr($index, strlen($i) + 1)] = $original; + } + $array_keys = array_keys($array); + foreach ($tokss as $index => $toks) { + if ($index[0] !== '#' && isset($array[$array_keys[$index]])) { + $replacements += token_generate($element_type, $toks, array($element_type => $array[$array_keys[$index]]), $options); + } + } + } + + // [list<>:first:*] chained tokens. + if ($first_tokens = token_find_with_prefix($tokens, 'first')) { + $replacements += token_generate($element_type, $first_tokens, array($element_type => $array[$keys[0]]), $options); + } + + // [list<>:last:*] chained tokens. + if ($last_tokens = token_find_with_prefix($tokens, 'last')) { + $replacements += token_generate($element_type, $last_tokens, array($element_type => $array[count($keys) - 1]), $options); + } + + // [list<>:join:?] dynamic tokens. + if ($join_tokens = token_find_with_prefix($tokens, 'join')) { + foreach ($join_tokens as $join => $original) { + $replacements[$original] = token_render_array($array, array('join' => $join) + $options); + } + } + + // [list<>:keys:*] chained tokens. + if ($key_tokens = token_find_with_prefix($tokens, 'keys')) { + $replacements += token_generate('array', $key_tokens, array('array' => $keys), $options); + } + + // [list<>:reversed:*] chained tokens. + if ($reversed_tokens = token_find_with_prefix($tokens, 'reversed')) { + $reversed = array_reverse($array, TRUE); + $replacements += token_generate($array_type, $reversed_tokens, array($array_type => $reversed), $options); + } + } + // Random tokens. if ($type == 'random') { foreach ($tokens as $name => $original) {