Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\HttpKernel\Debug; Chris@0: Chris@0: use Symfony\Component\HttpFoundation\Request; Chris@0: use Symfony\Component\HttpFoundation\RequestStack; Chris@14: use Symfony\Component\Routing\Exception\ExceptionInterface; Chris@14: use Symfony\Component\Routing\Generator\UrlGeneratorInterface; Chris@0: Chris@0: /** Chris@0: * Formats debug file links. Chris@0: * Chris@0: * @author Jérémy Romey Chris@0: */ Chris@0: class FileLinkFormatter implements \Serializable Chris@0: { Chris@0: private $fileLinkFormat; Chris@0: private $requestStack; Chris@0: private $baseDir; Chris@0: private $urlFormat; Chris@0: Chris@14: /** Chris@14: * @param string|\Closure $urlFormat the URL format, or a closure that returns it on-demand Chris@14: */ Chris@0: public function __construct($fileLinkFormat = null, RequestStack $requestStack = null, $baseDir = null, $urlFormat = null) Chris@0: { Chris@0: $fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); Chris@17: if ($fileLinkFormat && !\is_array($fileLinkFormat)) { Chris@17: $i = strpos($f = $fileLinkFormat, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: \strlen($f); Chris@17: $fileLinkFormat = [substr($f, 0, $i)] + preg_split('/&([^>]++)>/', substr($f, $i), -1, PREG_SPLIT_DELIM_CAPTURE); Chris@0: } Chris@0: Chris@0: $this->fileLinkFormat = $fileLinkFormat; Chris@0: $this->requestStack = $requestStack; Chris@0: $this->baseDir = $baseDir; Chris@0: $this->urlFormat = $urlFormat; Chris@0: } Chris@0: Chris@0: public function format($file, $line) Chris@0: { Chris@0: if ($fmt = $this->getFileLinkFormat()) { Chris@0: for ($i = 1; isset($fmt[$i]); ++$i) { Chris@0: if (0 === strpos($file, $k = $fmt[$i++])) { Chris@17: $file = substr_replace($file, $fmt[$i], 0, \strlen($k)); Chris@0: break; Chris@0: } Chris@0: } Chris@0: Chris@17: return strtr($fmt[0], ['%f' => $file, '%l' => $line]); Chris@0: } Chris@0: Chris@0: return false; Chris@0: } Chris@0: Chris@17: /** Chris@17: * @internal Chris@17: */ Chris@0: public function serialize() Chris@0: { Chris@0: return serialize($this->getFileLinkFormat()); Chris@0: } Chris@0: Chris@17: /** Chris@17: * @internal Chris@17: */ Chris@0: public function unserialize($serialized) Chris@0: { Chris@14: if (\PHP_VERSION_ID >= 70000) { Chris@17: $this->fileLinkFormat = unserialize($serialized, ['allowed_classes' => false]); Chris@14: } else { Chris@14: $this->fileLinkFormat = unserialize($serialized); Chris@14: } Chris@14: } Chris@14: Chris@14: /** Chris@14: * @internal Chris@14: */ Chris@14: public static function generateUrlFormat(UrlGeneratorInterface $router, $routeName, $queryString) Chris@14: { Chris@14: try { Chris@14: return $router->generate($routeName).$queryString; Chris@14: } catch (ExceptionInterface $e) { Chris@14: return null; Chris@14: } Chris@0: } Chris@0: Chris@0: private function getFileLinkFormat() Chris@0: { Chris@0: if ($this->fileLinkFormat) { Chris@0: return $this->fileLinkFormat; Chris@0: } Chris@0: if ($this->requestStack && $this->baseDir && $this->urlFormat) { Chris@0: $request = $this->requestStack->getMasterRequest(); Chris@0: if ($request instanceof Request) { Chris@14: if ($this->urlFormat instanceof \Closure && !$this->urlFormat = \call_user_func($this->urlFormat)) { Chris@14: return; Chris@14: } Chris@14: Chris@17: return [ Chris@17: $request->getSchemeAndHttpHost().$request->getBasePath().$this->urlFormat, Chris@17: $this->baseDir.\DIRECTORY_SEPARATOR, '', Chris@17: ]; Chris@0: } Chris@0: } Chris@0: } Chris@0: }