[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 namespace Symfony\Bridge\Twig\Extension; 13 14 use Twig\Extension\AbstractExtension; 15 use Twig\TwigFilter; 16 17 /** 18 * Twig extension relate to PHP code and used by the profiler and the default exception templates. 19 * 20 * @author Fabien Potencier <fabien@symfony.com> 21 */ 22 class CodeExtension extends AbstractExtension 23 { 24 private $fileLinkFormat; 25 private $rootDir; 26 private $charset; 27 28 /** 29 * @param string $fileLinkFormat The format for links to source files 30 * @param string $rootDir The project root directory 31 * @param string $charset The charset 32 */ 33 public function __construct($fileLinkFormat, $rootDir, $charset) 34 { 35 $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); 36 $this->rootDir = str_replace('/', \DIRECTORY_SEPARATOR, \dirname($rootDir)).\DIRECTORY_SEPARATOR; 37 $this->charset = $charset; 38 } 39 40 /** 41 * {@inheritdoc} 42 */ 43 public function getFilters() 44 { 45 return array( 46 new TwigFilter('abbr_class', array($this, 'abbrClass'), array('is_safe' => array('html'))), 47 new TwigFilter('abbr_method', array($this, 'abbrMethod'), array('is_safe' => array('html'))), 48 new TwigFilter('format_args', array($this, 'formatArgs'), array('is_safe' => array('html'))), 49 new TwigFilter('format_args_as_text', array($this, 'formatArgsAsText')), 50 new TwigFilter('file_excerpt', array($this, 'fileExcerpt'), array('is_safe' => array('html'))), 51 new TwigFilter('format_file', array($this, 'formatFile'), array('is_safe' => array('html'))), 52 new TwigFilter('format_file_from_text', array($this, 'formatFileFromText'), array('is_safe' => array('html'))), 53 new TwigFilter('file_link', array($this, 'getFileLink')), 54 ); 55 } 56 57 public function abbrClass($class) 58 { 59 $parts = explode('\\', $class); 60 $short = array_pop($parts); 61 62 return sprintf('<abbr title="%s">%s</abbr>', $class, $short); 63 } 64 65 public function abbrMethod($method) 66 { 67 if (false !== strpos($method, '::')) { 68 list($class, $method) = explode('::', $method, 2); 69 $result = sprintf('%s::%s()', $this->abbrClass($class), $method); 70 } elseif ('Closure' === $method) { 71 $result = sprintf('<abbr title="%s">%1$s</abbr>', $method); 72 } else { 73 $result = sprintf('<abbr title="%s">%1$s</abbr>()', $method); 74 } 75 76 return $result; 77 } 78 79 /** 80 * Formats an array as a string. 81 * 82 * @param array $args The argument array 83 * 84 * @return string 85 */ 86 public function formatArgs($args) 87 { 88 $result = array(); 89 foreach ($args as $key => $item) { 90 if ('object' === $item[0]) { 91 $parts = explode('\\', $item[1]); 92 $short = array_pop($parts); 93 $formattedValue = sprintf('<em>object</em>(<abbr title="%s">%s</abbr>)', $item[1], $short); 94 } elseif ('array' === $item[0]) { 95 $formattedValue = sprintf('<em>array</em>(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); 96 } elseif ('string' === $item[0]) { 97 $formattedValue = sprintf("'%s'", htmlspecialchars($item[1], ENT_QUOTES, $this->charset)); 98 } elseif ('null' === $item[0]) { 99 $formattedValue = '<em>null</em>'; 100 } elseif ('boolean' === $item[0]) { 101 $formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>'; 102 } elseif ('resource' === $item[0]) { 103 $formattedValue = '<em>resource</em>'; 104 } else { 105 $formattedValue = str_replace("\n", '', var_export(htmlspecialchars((string) $item[1], ENT_QUOTES, $this->charset), true)); 106 } 107 108 $result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); 109 } 110 111 return implode(', ', $result); 112 } 113 114 /** 115 * Formats an array as a string. 116 * 117 * @param array $args The argument array 118 * 119 * @return string 120 */ 121 public function formatArgsAsText($args) 122 { 123 return strip_tags($this->formatArgs($args)); 124 } 125 126 /** 127 * Returns an excerpt of a code file around the given line number. 128 * 129 * @param string $file A file path 130 * @param int $line The selected line number 131 * 132 * @return string An HTML string 133 */ 134 public function fileExcerpt($file, $line) 135 { 136 if (is_readable($file)) { 137 // highlight_file could throw warnings 138 // see https://bugs.php.net/bug.php?id=25725 139 $code = @highlight_file($file, true); 140 // remove main code/span tags 141 $code = preg_replace('#^<code.*?>\s*<span.*?>(.*)</span>\s*</code>#s', '\\1', $code); 142 $content = explode('<br />', $code); 143 144 $lines = array(); 145 for ($i = max($line - 3, 1), $max = min($line + 3, \count($content)); $i <= $max; ++$i) { 146 $lines[] = '<li'.($i == $line ? ' class="selected"' : '').'><code>'.self::fixCodeMarkup($content[$i - 1]).'</code></li>'; 147 } 148 149 return '<ol start="'.max($line - 3, 1).'">'.implode("\n", $lines).'</ol>'; 150 } 151 } 152 153 /** 154 * Formats a file path. 155 * 156 * @param string $file An absolute file path 157 * @param int $line The line number 158 * @param string $text Use this text for the link rather than the file path 159 * 160 * @return string 161 */ 162 public function formatFile($file, $line, $text = null) 163 { 164 $file = trim($file); 165 166 if (null === $text) { 167 $text = str_replace('/', \DIRECTORY_SEPARATOR, $file); 168 if (0 === strpos($text, $this->rootDir)) { 169 $text = substr($text, \strlen($this->rootDir)); 170 $text = explode(\DIRECTORY_SEPARATOR, $text, 2); 171 $text = sprintf('<abbr title="%s%2$s">%s</abbr>%s', $this->rootDir, $text[0], isset($text[1]) ? \DIRECTORY_SEPARATOR.$text[1] : ''); 172 } 173 } 174 175 $text = "$text at line $line"; 176 177 if (false !== $link = $this->getFileLink($file, $line)) { 178 if (\PHP_VERSION_ID >= 50400) { 179 $flags = ENT_QUOTES | ENT_SUBSTITUTE; 180 } else { 181 $flags = ENT_QUOTES; 182 } 183 184 return sprintf('<a href="%s" title="Click to open this file" class="file_link">%s</a>', htmlspecialchars($link, $flags, $this->charset), $text); 185 } 186 187 return $text; 188 } 189 190 /** 191 * Returns the link for a given file/line pair. 192 * 193 * @param string $file An absolute file path 194 * @param int $line The line number 195 * 196 * @return string|false A link or false 197 */ 198 public function getFileLink($file, $line) 199 { 200 if ($this->fileLinkFormat && is_file($file)) { 201 return strtr($this->fileLinkFormat, array('%f' => $file, '%l' => $line)); 202 } 203 204 return false; 205 } 206 207 public function formatFileFromText($text) 208 { 209 $that = $this; 210 211 return preg_replace_callback('/in ("|")?(.+?)\1(?: +(?:on|at))? +line (\d+)/s', function ($match) use ($that) { 212 return 'in '.$that->formatFile($match[2], $match[3]); 213 }, $text); 214 } 215 216 /** 217 * {@inheritdoc} 218 */ 219 public function getName() 220 { 221 return 'code'; 222 } 223 224 protected static function fixCodeMarkup($line) 225 { 226 // </span> ending tag from previous line 227 $opening = strpos($line, '<span'); 228 $closing = strpos($line, '</span>'); 229 if (false !== $closing && (false === $opening || $closing < $opening)) { 230 $line = substr_replace($line, '', $closing, 7); 231 } 232 233 // missing </span> tag at the end of line 234 $opening = strpos($line, '<span'); 235 $closing = strpos($line, '</span>'); 236 if (false !== $opening && (false === $closing || $closing > $opening)) { 237 $line .= '</span>'; 238 } 239 240 return $line; 241 } 242 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |