3 namespace Drupal\kint\Twig;
6 * Provides the Kint debugging function within Twig templates.
8 class KintExtension extends \Twig_Extension {
13 public function getName() {
20 public function getFunctions() {
22 new \Twig_SimpleFunction('kint', array($this, 'kint'), array(
23 'is_safe' => array('html'),
24 'needs_environment' => TRUE,
25 'needs_context' => TRUE,
26 'is_variadic' => TRUE,
32 * Provides Kint function to Twig templates.
34 * Handles 0, 1, or multiple arguments.
36 * Code derived from https://github.com/barelon/CgKintBundle.
38 * @param \Twig_Environment $env
39 * The twig environment instance.
40 * @param array $context
41 * An array of parameters passed to the template.
43 * An array of parameters passed the function.
46 * String representation of the input variables.
48 public function kint(\Twig_Environment $env, array $context, array $args = []) {
49 // Don't do anything unless twig_debug is enabled. This reads from the Twig
50 // environment, not Drupal Settings, so a container rebuild is necessary
51 // when toggling twig_debug on and off. We can consider injecting Settings.
52 if (!$env->isDebug()) {
56 // Don't display where Kint was called from.
57 // @todo Can we add information about which template Kint was called from?
58 \Kint::$displayCalledFrom = FALSE;
60 // No arguments passed to kint(), display full Twig context.
62 $kint_variable = array();
63 foreach ($context as $key => $value) {
64 if (!$value instanceof \Twig_Template) {
65 $kint_variable[$key] = $value;
69 $result = @\Kint::dump($kint_variable);
70 $output = str_replace('$kint_variable', 'Twig context', $result);
73 // Try to get the names of variables from the Twig template.
74 $parameters = $this->getTwigFunctionParameters();
76 // If there is only one argument, pass to Kint without too much hassle.
77 if (count($args) == 1) {
78 $kint_variable = reset($args);
79 $variable_name = reset($parameters);
80 $result = @\Kint::dump($kint_variable);
81 // Replace $kint_variable with the name of the variable in the Twig
83 $output = str_replace('$kint_variable', $variable_name, $result);
87 // Build an array of variable to pass to Kint.
88 // @todo Can we just call_user_func_array while still retaining the
90 foreach ($args as $index => $arg) {
91 // Prepend a unique index to allow debugging the same variable more
92 // than once in the same Kint dump.
93 $name = !empty($parameters[$index]) ? $parameters[$index] : $index;
94 $kint_args['_index_' . $index . '_' . $name] = $arg;
97 $result = @\Kint::dump($kint_args);
98 // Display a comma separated list of the variables contained in this group.
99 $output = str_replace('$kint_args', implode(', ', $parameters), $result);
100 // Remove unique indexes from output.
101 $output = preg_replace('/_index_([0-9]+)_/', '', $output);
109 * Gets the twig function parameters for the current invocation.
112 * The detected twig function parameters.
114 protected function getTwigFunctionParameters() {
118 $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT);
120 foreach ($backtrace as $index => $trace) {
121 if (isset($trace['object']) && $trace['object'] instanceof \Twig_Template && 'Twig_Template' !== get_class($trace['object'])) {
122 $template = $trace['object'];
123 $callee = $backtrace[$index - 1];
130 /** @var \Twig_Template $template */
131 if (NULL !== $template && NULL !== $callee) {
132 $line_number = $callee['line'];
133 $debug_infos = $template->getDebugInfo();
135 if (isset($debug_infos[$line_number])) {
136 $source_line = $debug_infos[$line_number];
137 $source_file_name = $template->getTemplateName();
139 if (is_readable($source_file_name)) {
140 $source = file($source_file_name, FILE_IGNORE_NEW_LINES);
141 $line = $source[$source_line - 1];
143 preg_match('/kint\((.+)\)/', $line, $matches);
144 if (isset($matches[1])) {
145 $parameters = array_map('trim', explode(',', $matches[1]));