Whoops, looks like something went wrong.

1/1 RuntimeException in Kernel.php line 589: Unable to write in the cache directory (/var/www/html/vibia-front/app/cache/dev)

  1. in Kernel.php line 589
  2. at Kernel->buildContainer() in Kernel.php line 510
  3. at Kernel->initializeContainer() in Kernel.php line 133
  4. at Kernel->boot() in Kernel.php line 182
  5. at Kernel->handle(object(Request)) in app_dev.php line 43
Realer Raum trifft digitalen Raum: Isern Serra und Ezequiel Pini im Gespräch

Realer Raum trifft digitalen Raum: Isern Serra und Ezequiel Pini im Gespräch

Der Architekt Isern Serra hat einen innovativen Arbeitsbereich für das multidisziplinäre Kreativstudio Six N. Five, unter Leitung von Ezequiel Pini, konzipiert.

Vibia The Edit - Isern Serra
Vibia The Edit - Ezequiel Pini

Dieser weitläufige Innenraum befindet sich im barcelonischen Viertel Poblenou und ist teils privat teils öffentlich zugänglich.

Vibia The Edit - Isern Serra & Ezequiel Pini in conversation

Neben den Vorhängen tragen eine Reihe architektonischer Elemente wie die Zwischengeschosse oder die Einbaumöbel dazu bei, das variable Arbeitsprogramm, eine Ausstellung und einen Coffee Shop umzusetzen. Die erdigen Farbtöne und die meisterhafte Lenkung des natürlichen und künstlichen Lichts lassen einen organischen und einhüllenden Raum entstehen.

Vibia The Edit - Isern Serra & Ezequiel Pini in conversation
Vibia The Edit - Isern Serra & Ezequiel Pini in conversation

Tempo von Vibia thront über dem Küchentisch gleich neben dem bepflanzten Hof, dem wohl privatesten Bereich des Projekts. Wir baten sowohl Isern als auch Ezequiel, uns die Wahl der Materialien, Farben und Leuchten dieses innovativen Innenraums zu begründen.

Vibia The Edit - Isern Serra & Ezequiel Pini in conversation - Tempo
Vibia The Edit - Isern Serra & Ezequiel Pini in conversation - Tempo

Erzählt doch mal, wie begann eure Zusammenarbeit? Kanntet ihr euch bereits?

E: Ich kannte Iserns Arbeit und wir hatten uns um das Jahr 2018 bei einem Vortrag, den ich bei Flowers by Bornay hielt, persönlich kennengelernt. Mir war nach einem Raum, der mir an meinem Arbeitsplatz ein Gefühl von Zuhause vermittelte. Die Renovierungsarbeiten, die er an seinem Heimatelier mit Valeria Vasi vorgenommen hatte, gefielen mir sehr und auch Aufträge für andere Büros. Demnach schien er mir der ideale Designer für mein Studio zu sein.

I: Für mich war es eine Ehre, mit der Gestaltung seines Arbeitsbereichs beauftragt zu werden! Ich folgte seinen Projekten schon seit Langem.

Ezequiel, welche waren beim Projektstart die Voraussetzungen bzw. Anweisungen seitens deines Studios? Was suchtest du für diesen neuen Raum?

E: Vom ersten Moment an war mir klar, dass ich einen multidisziplinären Raum wollte, in dem es diverse Zonen gibt, die zwar abgegrenzt, aber doch miteinander verknüpft sind. Wärme und Menschlichkeit scheinen mir Schlüsselaspekte, etwas Einladendes also.
Weitere spezifischere Voraussetzungen waren die Einbindung eines Showrooms, eine kleine Werkstatt, ein klimatisierter Extraraum für die Computer, eine Küche sowie ein abgesonderter Meetingbereich abgesehen von der Hauptarbeitszone.

Vibia The Edit - Isern Serra & Ezequiel Pini in conversation - Tempo

Isern, welche war die größte Herausforderung des Projekts?

I: Ehrlich gesagt gab es keine Herausforderungen. Das Projekt war sehr angenehm, immer im Fluss, da Ezequiel mir von Anfang an vertraut hat und wir uns durchgehend sehr einig waren. Das Schwierigste war wohl, das Programm im gegebenen Raum durchzuführen und die richtige Textur der Wand zu treffen – materisch, aber nicht dekorativ; warm, aber gleichzeitig roh – dafür musste ich viel mit den verschiedensten Materialien experimentieren.
Auch musste ich viel und lange nachforschen, um den diversen Materialien des Projekts den exakten Farbton zu geben.

Vibia The Edit - Isern Serra & Ezequiel Pini in conversation
Vibia The Edit - Isern Serra & Ezequiel Pini in conversation

Six N. Five ist ein Kreativstudio. Wie habt ihr es geschafft, die Kreativität im neuen Raum zu spiegeln und welche Eindrücke oder Emotionen erhofftet ihr vermitteln zu können?

E: Was das angeht, hat Isern eine große Rolle gespielt. In der Anfangsphase gingen wir verschiedene Vorschläge, Formtypen und Anordnungen durch. Mir gefiel das eher Minimale und Neutrale. Und wir waren beide der Meinung, dass der Raum Wärme und Wohlbefinden ausstrahlen sollte. Auch ein Gefühl von Zuhause schien mir fundamental an diesem Ort, an dem wir so viele Stunden verbringen. Zuhause empfange ich gerne Besuch, organisiere gemeinsame Essen und gemütliches Beisammensein. Ich meine, dass der Raum all dies vermittelt und noch mehr als erhofft.

Vibia The Edit - Isern Serra & Ezequiel Pini in conversation - Tempo

Wie kam es zur Wahl der neutralen und hellen Farbtöne sowohl beim Mobiliar als auch bei den Wänden und dem Boden? War das eine Vorgabe?

I: Wir beide suchten etwas sehr Warmes, Natürliches, Ruhiges und das erreichten wir, indem wir mit dieser Farbpalette experimentierten.

Das Endergebnis zeigt auch ein großes Augenmerk auf Materialien und Kunsthandwerk …

I: Ja, absolut. Uns gefiel dieses Zusammenspiel aus dem Materischen des Raums und dem Ätherischen, das in Ezequiels Studio kreiert wird. Alles sollte einen kunsthandwerklichen Charakter haben, die Sensibilität des Handgemachten sollte allgegenwärtig sein. Deswegen war auch der Mikrozement als Finish aller Bauelemente, die manuell vor Ort angefertigt wurden, essenziell. Der verschalte Tisch, die diversen Ebenen, die Stufen, die zur Küche führen – alle sind klar architektonische Elemente, drücken aber eine Menschlichkeit aus, was eine greifbare Friedlichkeit ausstrahlt, wenn man sich im Raum befindet.

Vibia The Edit - Isern Serra & Ezequiel Pini in conversation
Vibia The Edit - Isern Serra & Ezequiel Pini in conversation

Welche Rolle spielt das Licht, ob natürlich oder künstlich, in einer solchen Umgebung?

E: Für mich persönlich ist Tageslicht unabdinglich für alle meine Aktivitäten. Ich erzähle immer, dass ich scheinbar ein Solarpanel im Körper trage, durch das Tages- und Sonnenlicht mich mit Energie laden, um zur Tat zu schreiten oder weiterzuarbeiten. Auf der Suche nach den Räumlichkeiten waren große Fenster und viel Lichteinfall ausschlaggebend bei der Wahl. Nachts ist das Licht sehr warm und sanft. Wenn es früher dunkel wird, lädt dies dazu ein, etwas länger zu bleiben.

I: Das Licht ist ein weiteres Element, das uns in die Karten spielt, denn das Sonnenlicht am Nachmittag hebt unsere Idee der Zufluchtsstätte, der Ruhe und Gelassenheit noch mehr hervor.
Und durch die Bestückung der äußeren Blumenkästen mit einer großen Vielfalt an Pflanzen sind die Schatten, die nach innen geworfen werden, umwerfend schön.
Bei Dunkelheit sollte ein warmes, häusliches Ambiente entstehen, um dem Konzept der traditionellen Bürobeleuchtung zu entfliehen. Punktuelle, angenehme Lichtakzente, die die verschiedenen Zonen des offenen Bereichs betonen und gemütliche Ecken schaffen.

Vibia The Edit - Isern Serra & Ezequiel Pini in conversation - Tempo
Vibia The Edit - Isern Serra & Ezequiel Pini in conversation

I + E: Was hat euch zur Wahl der Kollektion Tempo von Vibia verleitet? Aufgrund welcher ihrer Charakteristiken meintet ihr, dass sie gut mit der Umgebung harmonieren könnte?

E: Der Vorschlag kam von Isern und überzeugte mich sofort.

I: Die Wahl der Leuchte war eines der wenigen Dinge, die mir von Anfang an klar waren. Ich bin ein großer Fan der Produkte von Lievore Altherr. Mir gefiel sehr der Kontrast, der zwischen diesem so prächtigen materischen Raum und den zwei subtilen, feinen Leuchten über dem Tisch entstand. Dieses punktuelle Licht und die perfekte Integration von Tempo in die Umgebung sagten mir sehr zu.

Vibia The Edit - Isern Serra & Ezequiel Pini in conversation - Tempo

An welcher Stelle wurde sie platziert und warum?

I: Mir war klar, dass sie sich in der Küche über dem Tisch im Hintergrund des Arbeitsbereichs befinden müsste. Mich fasziniert die Schlichtheit und Eleganz, die sie ausstrahlt und natürlich das Licht, das sie wirft. Ehrlich gesagt finde ich, dass es eine sehr ästhetische und zeitlose Leuchte ist, was sehr zum Stil meiner Projekte passt.

Vibia The Edit - Isern Serra & Ezequiel Pini in conversation - Tempo
Vibia The Edit - Isern Serra & Ezequiel Pini in conversation - Tempo

Credits:
– Photography: Salva Lopez

Entdecke Tempo

Whoops, looks like something went wrong.

1/1 RuntimeException in ClassCollectionLoader.php line 285: Failed to write cache file "/var/www/html/vibia-front/app/cache/dev/classes.php".

  1. in ClassCollectionLoader.php line 285
  2. at ClassCollectionLoader::writeCacheFile('/var/www/html/vibia-front/app/cache/dev/classes.php', '<?php namespace Symfony\Component\EventDispatcher { interface EventSubscriberInterface { public static function getSubscribedEvents(); } } namespace Symfony\Component\HttpKernel\EventListener { use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; abstract class SessionListener implements EventSubscriberInterface { public function onKernelRequest(GetResponseEvent $event) { if (!$event->isMasterRequest()) { return; } $request = $event->getRequest(); $session = $this->getSession(); if (null === $session || $request->hasSession()) { return; } $request->setSession($session); } public static function getSubscribedEvents() { return array( KernelEvents::REQUEST => array('onKernelRequest', 128), ); } abstract protected function getSession(); } } namespace Symfony\Bundle\FrameworkBundle\EventListener { use Symfony\Component\HttpKernel\EventListener\SessionListener as BaseSessionListener; use Symfony\Component\DependencyInjection\ContainerInterface; class SessionListener extends BaseSessionListener { private $container; public function __construct(ContainerInterface $container) { $this->container = $container; } protected function getSession() { if (!$this->container->has('session')) { return; } return $this->container->get('session'); } } } namespace Symfony\Component\HttpFoundation\Session\Storage { use Symfony\Component\HttpFoundation\Session\SessionBagInterface; interface SessionStorageInterface { public function start(); public function isStarted(); public function getId(); public function setId($id); public function getName(); public function setName($name); public function regenerate($destroy = false, $lifetime = null); public function save(); public function clear(); public function getBag($name); public function registerBag(SessionBagInterface $bag); public function getMetadataBag(); } } namespace Symfony\Component\HttpFoundation\Session\Storage { use Symfony\Component\HttpFoundation\Session\SessionBagInterface; use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; class NativeSessionStorage implements SessionStorageInterface { protected $bags; protected $started = false; protected $closed = false; protected $saveHandler; protected $metadataBag; public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) { session_cache_limiter(''); ini_set('session.use_cookies', 1); session_register_shutdown(); $this->setMetadataBag($metaBag); $this->setOptions($options); $this->setSaveHandler($handler); } public function getSaveHandler() { return $this->saveHandler; } public function start() { if ($this->started) { return true; } if (PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE === session_status()) { throw new \RuntimeException('Failed to start the session: already started by PHP.'); } if (PHP_VERSION_ID < 50400 && !$this->closed && isset($_SESSION) && session_id()) { throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).'); } if (ini_get('session.use_cookies') && headers_sent($file, $line)) { throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line)); } if (!session_start()) { throw new \RuntimeException('Failed to start the session'); } $this->loadSession(); if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { $this->saveHandler->setActive(true); } return true; } public function getId() { return $this->saveHandler->getId(); } public function setId($id) { $this->saveHandler->setId($id); } public function getName() { return $this->saveHandler->getName(); } public function setName($name) { $this->saveHandler->setName($name); } public function regenerate($destroy = false, $lifetime = null) { if (PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE !== session_status()) { return false; } if (PHP_VERSION_ID < 50400 &&''=== session_id()) { return false; } if (null !== $lifetime) { ini_set('session.cookie_lifetime', $lifetime); } if ($destroy) { $this->metadataBag->stampNew(); } $isRegenerated = session_regenerate_id($destroy); $this->loadSession(); return $isRegenerated; } public function save() { session_write_close(); if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { $this->saveHandler->setActive(false); } $this->closed = true; $this->started = false; } public function clear() { foreach ($this->bags as $bag) { $bag->clear(); } $_SESSION = array(); $this->loadSession(); } public function registerBag(SessionBagInterface $bag) { if ($this->started) { throw new \LogicException('Cannot register a bag when the session is already started.'); } $this->bags[$bag->getName()] = $bag; } public function getBag($name) { if (!isset($this->bags[$name])) { throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name)); } if ($this->saveHandler->isActive() && !$this->started) { $this->loadSession(); } elseif (!$this->started) { $this->start(); } return $this->bags[$name]; } public function setMetadataBag(MetadataBag $metaBag = null) { if (null === $metaBag) { $metaBag = new MetadataBag(); } $this->metadataBag = $metaBag; } public function getMetadataBag() { return $this->metadataBag; } public function isStarted() { return $this->started; } public function setOptions(array $options) { $validOptions = array_flip(array('cache_limiter','cookie_domain','cookie_httponly','cookie_lifetime','cookie_path','cookie_secure','entropy_file','entropy_length','gc_divisor','gc_maxlifetime','gc_probability','hash_bits_per_character','hash_function','name','referer_check','serialize_handler','use_cookies','use_only_cookies','use_trans_sid','upload_progress.enabled','upload_progress.cleanup','upload_progress.prefix','upload_progress.name','upload_progress.freq','upload_progress.min-freq','url_rewriter.tags', )); foreach ($options as $key => $value) { if (isset($validOptions[$key])) { ini_set('session.'.$key, $value); } } } public function setSaveHandler($saveHandler = null) { if (!$saveHandler instanceof AbstractProxy && !$saveHandler instanceof NativeSessionHandler && !$saveHandler instanceof \SessionHandlerInterface && null !== $saveHandler) { throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.'); } if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { $saveHandler = new SessionHandlerProxy($saveHandler); } elseif (!$saveHandler instanceof AbstractProxy) { $saveHandler = PHP_VERSION_ID >= 50400 ? new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy(); } $this->saveHandler = $saveHandler; if ($this->saveHandler instanceof \SessionHandlerInterface) { if (PHP_VERSION_ID >= 50400) { session_set_save_handler($this->saveHandler, false); } else { session_set_save_handler( array($this->saveHandler,'open'), array($this->saveHandler,'close'), array($this->saveHandler,'read'), array($this->saveHandler,'write'), array($this->saveHandler,'destroy'), array($this->saveHandler,'gc') ); } } } protected function loadSession(array &$session = null) { if (null === $session) { $session = &$_SESSION; } $bags = array_merge($this->bags, array($this->metadataBag)); foreach ($bags as $bag) { $key = $bag->getStorageKey(); $session[$key] = isset($session[$key]) ? $session[$key] : array(); $bag->initialize($session[$key]); } $this->started = true; $this->closed = false; } } } namespace Symfony\Component\HttpFoundation\Session\Storage { use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler; class PhpBridgeSessionStorage extends NativeSessionStorage { public function __construct($handler = null, MetadataBag $metaBag = null) { $this->setMetadataBag($metaBag); $this->setSaveHandler($handler); } public function start() { if ($this->started) { return true; } $this->loadSession(); if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { $this->saveHandler->setActive(true); } return true; } public function clear() { foreach ($this->bags as $bag) { $bag->clear(); } $this->loadSession(); } } } namespace Symfony\Component\HttpFoundation\Session\Storage\Handler { if (PHP_VERSION_ID >= 50400) { class NativeSessionHandler extends \SessionHandler { } } else { class NativeSessionHandler { } } } namespace Symfony\Component\HttpFoundation\Session\Storage\Handler { class NativeFileSessionHandler extends NativeSessionHandler { public function __construct($savePath = null) { if (null === $savePath) { $savePath = ini_get('session.save_path'); } $baseDir = $savePath; if ($count = substr_count($savePath,';')) { if ($count > 2) { throw new \InvalidArgumentException(sprintf('Invalid argument $savePath \'%s\'', $savePath)); } $baseDir = ltrim(strrchr($savePath,';'),';'); } if ($baseDir && !is_dir($baseDir) && !@mkdir($baseDir, 0777, true) && !is_dir($baseDir)) { throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s"', $baseDir)); } ini_set('session.save_path', $savePath); ini_set('session.save_handler','files'); } } } namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy { abstract class AbstractProxy { protected $wrapper = false; protected $active = false; protected $saveHandlerName; public function getSaveHandlerName() { return $this->saveHandlerName; } public function isSessionHandlerInterface() { return $this instanceof \SessionHandlerInterface; } public function isWrapper() { return $this->wrapper; } public function isActive() { if (PHP_VERSION_ID >= 50400) { return $this->active = \PHP_SESSION_ACTIVE === session_status(); } return $this->active; } public function setActive($flag) { if (PHP_VERSION_ID >= 50400) { throw new \LogicException('This method is disabled in PHP 5.4.0+'); } $this->active = (bool) $flag; } public function getId() { return session_id(); } public function setId($id) { if ($this->isActive()) { throw new \LogicException('Cannot change the ID of an active session'); } session_id($id); } public function getName() { return session_name(); } public function setName($name) { if ($this->isActive()) { throw new \LogicException('Cannot change the name of an active session'); } session_name($name); } } } namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy { class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface { protected $handler; public function __construct(\SessionHandlerInterface $handler) { $this->handler = $handler; $this->wrapper = ($handler instanceof \SessionHandler); $this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') :'user'; } public function open($savePath, $sessionName) { $return = (bool) $this->handler->open($savePath, $sessionName); if (true === $return) { $this->active = true; } return $return; } public function close() { $this->active = false; return (bool) $this->handler->close(); } public function read($sessionId) { return (string) $this->handler->read($sessionId); } public function write($sessionId, $data) { return (bool) $this->handler->write($sessionId, $data); } public function destroy($sessionId) { return (bool) $this->handler->destroy($sessionId); } public function gc($maxlifetime) { return (bool) $this->handler->gc($maxlifetime); } } } namespace Symfony\Component\HttpFoundation\Session { use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag; interface SessionInterface { public function start(); public function getId(); public function setId($id); public function getName(); public function setName($name); public function invalidate($lifetime = null); public function migrate($destroy = false, $lifetime = null); public function save(); public function has($name); public function get($name, $default = null); public function set($name, $value); public function all(); public function replace(array $attributes); public function remove($name); public function clear(); public function isStarted(); public function registerBag(SessionBagInterface $bag); public function getBag($name); public function getMetadataBag(); } } namespace Symfony\Component\HttpFoundation\Session { use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface; use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; class Session implements SessionInterface, \IteratorAggregate, \Countable { protected $storage; private $flashName; private $attributeName; public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null) { $this->storage = $storage ?: new NativeSessionStorage(); $attributes = $attributes ?: new AttributeBag(); $this->attributeName = $attributes->getName(); $this->registerBag($attributes); $flashes = $flashes ?: new FlashBag(); $this->flashName = $flashes->getName(); $this->registerBag($flashes); } public function start() { return $this->storage->start(); } public function has($name) { return $this->storage->getBag($this->attributeName)->has($name); } public function get($name, $default = null) { return $this->storage->getBag($this->attributeName)->get($name, $default); } public function set($name, $value) { $this->storage->getBag($this->attributeName)->set($name, $value); } public function all() { return $this->storage->getBag($this->attributeName)->all(); } public function replace(array $attributes) { $this->storage->getBag($this->attributeName)->replace($attributes); } public function remove($name) { return $this->storage->getBag($this->attributeName)->remove($name); } public function clear() { $this->storage->getBag($this->attributeName)->clear(); } public function isStarted() { return $this->storage->isStarted(); } public function getIterator() { return new \ArrayIterator($this->storage->getBag($this->attributeName)->all()); } public function count() { return count($this->storage->getBag($this->attributeName)->all()); } public function invalidate($lifetime = null) { $this->storage->clear(); return $this->migrate(true, $lifetime); } public function migrate($destroy = false, $lifetime = null) { return $this->storage->regenerate($destroy, $lifetime); } public function save() { $this->storage->save(); } public function getId() { return $this->storage->getId(); } public function setId($id) { $this->storage->setId($id); } public function getName() { return $this->storage->getName(); } public function setName($name) { $this->storage->setName($name); } public function getMetadataBag() { return $this->storage->getMetadataBag(); } public function registerBag(SessionBagInterface $bag) { $this->storage->registerBag($bag); } public function getBag($name) { return $this->storage->getBag($name); } public function getFlashBag() { return $this->getBag($this->flashName); } } } namespace Symfony\Bundle\FrameworkBundle\Templating { use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Security\Core\SecurityContext; class GlobalVariables { protected $container; public function __construct(ContainerInterface $container) { $this->container = $container; } public function getSecurity() { @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED); if ($this->container->has('security.context')) { return $this->container->get('security.context'); } } public function getUser() { if (!$this->container->has('security.token_storage')) { return; } $tokenStorage = $this->container->get('security.token_storage'); if (!$token = $tokenStorage->getToken()) { return; } $user = $token->getUser(); if (!is_object($user)) { return; } return $user; } public function getRequest() { if ($this->container->has('request_stack')) { return $this->container->get('request_stack')->getCurrentRequest(); } } public function getSession() { if ($request = $this->getRequest()) { return $request->getSession(); } } public function getEnvironment() { return $this->container->getParameter('kernel.environment'); } public function getDebug() { return (bool) $this->container->getParameter('kernel.debug'); } } } namespace Symfony\Component\Templating { interface TemplateReferenceInterface { public function all(); public function set($name, $value); public function get($name); public function getPath(); public function getLogicalName(); public function __toString(); } } namespace Symfony\Component\Templating { class TemplateReference implements TemplateReferenceInterface { protected $parameters; public function __construct($name = null, $engine = null) { $this->parameters = array('name'=> $name,'engine'=> $engine, ); } public function __toString() { return $this->getLogicalName(); } public function set($name, $value) { if (array_key_exists($name, $this->parameters)) { $this->parameters[$name] = $value; } else { throw new \InvalidArgumentException(sprintf('The template does not support the "%s" parameter.', $name)); } return $this; } public function get($name) { if (array_key_exists($name, $this->parameters)) { return $this->parameters[$name]; } throw new \InvalidArgumentException(sprintf('The template does not support the "%s" parameter.', $name)); } public function all() { return $this->parameters; } public function getPath() { return $this->parameters['name']; } public function getLogicalName() { return $this->parameters['name']; } } } namespace Symfony\Bundle\FrameworkBundle\Templating { use Symfony\Component\Templating\TemplateReference as BaseTemplateReference; class TemplateReference extends BaseTemplateReference { public function __construct($bundle = null, $controller = null, $name = null, $format = null, $engine = null) { $this->parameters = array('bundle'=> $bundle,'controller'=> $controller,'name'=> $name,'format'=> $format,'engine'=> $engine, ); } public function getPath() { $controller = str_replace('\\','/', $this->get('controller')); $path = (empty($controller) ?'': $controller.'/').$this->get('name').'.'.$this->get('format').'.'.$this->get('engine'); return empty($this->parameters['bundle']) ?'views/'.$path :'@'.$this->get('bundle').'/Resources/views/'.$path; } public function getLogicalName() { return sprintf('%s:%s:%s.%s.%s', $this->parameters['bundle'], $this->parameters['controller'], $this->parameters['name'], $this->parameters['format'], $this->parameters['engine']); } } } namespace Symfony\Component\Templating { interface TemplateNameParserInterface { public function parse($name); } } namespace Symfony\Component\Templating { class TemplateNameParser implements TemplateNameParserInterface { public function parse($name) { if ($name instanceof TemplateReferenceInterface) { return $name; } $engine = null; if (false !== $pos = strrpos($name,'.')) { $engine = substr($name, $pos + 1); } return new TemplateReference($name, $engine); } } } namespace Symfony\Bundle\FrameworkBundle\Templating { use Symfony\Component\Templating\TemplateReferenceInterface; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Templating\TemplateNameParser as BaseTemplateNameParser; class TemplateNameParser extends BaseTemplateNameParser { protected $kernel; protected $cache = array(); public function __construct(KernelInterface $kernel) { $this->kernel = $kernel; } public function parse($name) { if ($name instanceof TemplateReferenceInterface) { return $name; } elseif (isset($this->cache[$name])) { return $this->cache[$name]; } $name = str_replace(':/',':', preg_replace('#/{2,}#','/', str_replace('\\','/', $name))); if (false !== strpos($name,'..')) { throw new \RuntimeException(sprintf('Template name "%s" contains invalid characters.', $name)); } if (!preg_match('/^(?:([^:]*):([^:]*):)?(.+)\.([^\.]+)\.([^\.]+)$/', $name, $matches) || $this->isAbsolutePath($name) || 0 === strpos($name,'@')) { return parent::parse($name); } $template = new TemplateReference($matches[1], $matches[2], $matches[3], $matches[4], $matches[5]); if ($template->get('bundle')) { try { $this->kernel->getBundle($template->get('bundle')); } catch (\Exception $e) { throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid.', $name), 0, $e); } } return $this->cache[$name] = $template; } private function isAbsolutePath($file) { return (bool) preg_match('#^(?:/|[a-zA-Z]:)#', $file); } } } namespace Symfony\Component\Config { interface FileLocatorInterface { public function locate($name, $currentPath = null, $first = true); } } namespace Symfony\Bundle\FrameworkBundle\Templating\Loader { use Symfony\Component\Config\FileLocatorInterface; use Symfony\Component\Templating\TemplateReferenceInterface; class TemplateLocator implements FileLocatorInterface { protected $locator; protected $cache; public function __construct(FileLocatorInterface $locator, $cacheDir = null) { if (null !== $cacheDir && is_file($cache = $cacheDir.'/templates.php')) { $this->cache = require $cache; } $this->locator = $locator; } protected function getCacheKey($template) { return $template->getLogicalName(); } public function locate($template, $currentPath = null, $first = true) { if (!$template instanceof TemplateReferenceInterface) { throw new \InvalidArgumentException('The template must be an instance of TemplateReferenceInterface.'); } $key = $this->getCacheKey($template); if (isset($this->cache[$key])) { return $this->cache[$key]; } try { return $this->cache[$key] = $this->locator->locate($template->getPath(), $currentPath); } catch (\InvalidArgumentException $e) { throw new \InvalidArgumentException(sprintf('Unable to find template "%s" : "%s".', $template, $e->getMessage()), 0, $e); } } } } namespace Symfony\Component\Routing { interface RequestContextAwareInterface { public function setContext(RequestContext $context); public function getContext(); } } namespace Symfony\Component\Routing\Generator { use Symfony\Component\Routing\Exception\InvalidParameterException; use Symfony\Component\Routing\Exception\MissingMandatoryParametersException; use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\RequestContextAwareInterface; interface UrlGeneratorInterface extends RequestContextAwareInterface { const ABSOLUTE_URL = 0; const ABSOLUTE_PATH = 1; const RELATIVE_PATH = 2; const NETWORK_PATH = 3; public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH); } } namespace Symfony\Component\Routing\Generator { interface ConfigurableRequirementsInterface { public function setStrictRequirements($enabled); public function isStrictRequirements(); } } namespace Symfony\Component\Routing\Generator { use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Exception\InvalidParameterException; use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\Exception\MissingMandatoryParametersException; use Psr\Log\LoggerInterface; class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInterface { protected $routes; protected $context; protected $strictRequirements = true; protected $logger; protected $decodedChars = array('%2F'=>'/','%40'=>'@','%3A'=>':','%3B'=>';','%2C'=>',','%3D'=>'=','%2B'=>'+','%21'=>'!','%2A'=>'*','%7C'=>'|', ); public function __construct(RouteCollection $routes, RequestContext $context, LoggerInterface $logger = null) { $this->routes = $routes; $this->context = $context; $this->logger = $logger; } public function setContext(RequestContext $context) { $this->context = $context; } public function getContext() { return $this->context; } public function setStrictRequirements($enabled) { $this->strictRequirements = null === $enabled ? null : (bool) $enabled; } public function isStrictRequirements() { return $this->strictRequirements; } public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) { if (null === $route = $this->routes->get($name)) { throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name)); } $compiledRoute = $route->compile(); return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens(), $route->getSchemes()); } protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, array $requiredSchemes = array()) { if (is_bool($referenceType) || is_string($referenceType)) { @trigger_error('The hardcoded value you are using for the $referenceType argument of the '.__CLASS__.'::generate method is deprecated since version 2.8 and will not be supported anymore in 3.0. Use the constants defined in the UrlGeneratorInterface instead.', E_USER_DEPRECATED); if (true === $referenceType) { $referenceType = self::ABSOLUTE_URL; } elseif (false === $referenceType) { $referenceType = self::ABSOLUTE_PATH; } elseif ('relative'=== $referenceType) { $referenceType = self::RELATIVE_PATH; } elseif ('network'=== $referenceType) { $referenceType = self::NETWORK_PATH; } } $variables = array_flip($variables); $mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters); if ($diff = array_diff_key($variables, $mergedParams)) { throw new MissingMandatoryParametersException(sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', array_keys($diff)), $name)); } $url =''; $optional = true; foreach ($tokens as $token) { if ('variable'=== $token[0]) { if (!$optional || !array_key_exists($token[3], $defaults) || null !== $mergedParams[$token[3]] && (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) { if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#', $mergedParams[$token[3]])) { $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]); if ($this->strictRequirements) { throw new InvalidParameterException($message); } if ($this->logger) { $this->logger->error($message); } return; } $url = $token[1].$mergedParams[$token[3]].$url; $optional = false; } } else { $url = $token[1].$url; $optional = false; } } if (''=== $url) { $url ='/'; } $url = strtr(rawurlencode($url), $this->decodedChars); $url = strtr($url, array('/../'=>'/%2E%2E/','/./'=>'/%2E/')); if ('/..'=== substr($url, -3)) { $url = substr($url, 0, -2).'%2E%2E'; } elseif ('/.'=== substr($url, -2)) { $url = substr($url, 0, -1).'%2E'; } $schemeAuthority =''; if ($host = $this->context->getHost()) { $scheme = $this->context->getScheme(); if ($requiredSchemes) { if (!in_array($scheme, $requiredSchemes, true)) { $referenceType = self::ABSOLUTE_URL; $scheme = current($requiredSchemes); } } elseif (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme !== $req) { $referenceType = self::ABSOLUTE_URL; $scheme = $req; } if ($hostTokens) { $routeHost =''; foreach ($hostTokens as $token) { if ('variable'=== $token[0]) { if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#i', $mergedParams[$token[3]])) { $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]); if ($this->strictRequirements) { throw new InvalidParameterException($message); } if ($this->logger) { $this->logger->error($message); } return; } $routeHost = $token[1].$mergedParams[$token[3]].$routeHost; } else { $routeHost = $token[1].$routeHost; } } if ($routeHost !== $host) { $host = $routeHost; if (self::ABSOLUTE_URL !== $referenceType) { $referenceType = self::NETWORK_PATH; } } } if (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) { $port =''; if ('http'=== $scheme && 80 != $this->context->getHttpPort()) { $port =':'.$this->context->getHttpPort(); } elseif ('https'=== $scheme && 443 != $this->context->getHttpsPort()) { $port =':'.$this->context->getHttpsPort(); } $schemeAuthority = self::NETWORK_PATH === $referenceType ?'//': "$scheme://"; $schemeAuthority .= $host.$port; } } if (self::RELATIVE_PATH === $referenceType) { $url = self::getRelativePath($this->context->getPathInfo(), $url); } else { $url = $schemeAuthority.$this->context->getBaseUrl().$url; } $extra = array_udiff_assoc(array_diff_key($parameters, $variables), $defaults, function ($a, $b) { return $a == $b ? 0 : 1; }); if ($extra && $query = http_build_query($extra,'','&')) { $url .='?'.strtr($query, array('%2F'=>'/')); } return $url; } public static function getRelativePath($basePath, $targetPath) { if ($basePath === $targetPath) { return''; } $sourceDirs = explode('/', isset($basePath[0]) &&'/'=== $basePath[0] ? substr($basePath, 1) : $basePath); $targetDirs = explode('/', isset($targetPath[0]) &&'/'=== $targetPath[0] ? substr($targetPath, 1) : $targetPath); array_pop($sourceDirs); $targetFile = array_pop($targetDirs); foreach ($sourceDirs as $i => $dir) { if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) { unset($sourceDirs[$i], $targetDirs[$i]); } else { break; } } $targetDirs[] = $targetFile; $path = str_repeat('../', count($sourceDirs)).implode('/', $targetDirs); return''=== $path ||'/'=== $path[0] || false !== ($colonPos = strpos($path,':')) && ($colonPos < ($slashPos = strpos($path,'/')) || false === $slashPos) ? "./$path" : $path; } } } namespace Symfony\Component\Routing { use Symfony\Component\HttpFoundation\Request; class RequestContext { private $baseUrl; private $pathInfo; private $method; private $host; private $scheme; private $httpPort; private $httpsPort; private $queryString; private $parameters = array(); public function __construct($baseUrl ='', $method ='GET', $host ='localhost', $scheme ='http', $httpPort = 80, $httpsPort = 443, $path ='/', $queryString ='') { $this->setBaseUrl($baseUrl); $this->setMethod($method); $this->setHost($host); $this->setScheme($scheme); $this->setHttpPort($httpPort); $this->setHttpsPort($httpsPort); $this->setPathInfo($path); $this->setQueryString($queryString); } public function fromRequest(Request $request) { $this->setBaseUrl($request->getBaseUrl()); $this->setPathInfo($request->getPathInfo()); $this->setMethod($request->getMethod()); $this->setHost($request->getHost()); $this->setScheme($request->getScheme()); $this->setHttpPort($request->isSecure() ? $this->httpPort : $request->getPort()); $this->setHttpsPort($request->isSecure() ? $request->getPort() : $this->httpsPort); $this->setQueryString($request->server->get('QUERY_STRING','')); return $this; } public function getBaseUrl() { return $this->baseUrl; } public function setBaseUrl($baseUrl) { $this->baseUrl = $baseUrl; return $this; } public function getPathInfo() { return $this->pathInfo; } public function setPathInfo($pathInfo) { $this->pathInfo = $pathInfo; return $this; } public function getMethod() { return $this->method; } public function setMethod($method) { $this->method = strtoupper($method); return $this; } public function getHost() { return $this->host; } public function setHost($host) { $this->host = strtolower($host); return $this; } public function getScheme() { return $this->scheme; } public function setScheme($scheme) { $this->scheme = strtolower($scheme); return $this; } public function getHttpPort() { return $this->httpPort; } public function setHttpPort($httpPort) { $this->httpPort = (int) $httpPort; return $this; } public function getHttpsPort() { return $this->httpsPort; } public function setHttpsPort($httpsPort) { $this->httpsPort = (int) $httpsPort; return $this; } public function getQueryString() { return $this->queryString; } public function setQueryString($queryString) { $this->queryString = (string) $queryString; return $this; } public function getParameters() { return $this->parameters; } public function setParameters(array $parameters) { $this->parameters = $parameters; return $this; } public function getParameter($name) { return isset($this->parameters[$name]) ? $this->parameters[$name] : null; } public function hasParameter($name) { return array_key_exists($name, $this->parameters); } public function setParameter($name, $parameter) { $this->parameters[$name] = $parameter; return $this; } } } namespace Symfony\Component\Routing\Matcher { use Symfony\Component\Routing\RequestContextAwareInterface; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Exception\MethodNotAllowedException; interface UrlMatcherInterface extends RequestContextAwareInterface { public function match($pathinfo); } } namespace Symfony\Component\Routing { use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface { public function getRouteCollection(); } } namespace Symfony\Component\Routing\Matcher { use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Exception\MethodNotAllowedException; interface RequestMatcherInterface { public function matchRequest(Request $request); } } namespace Symfony\Component\Routing { use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\ConfigCacheInterface; use Symfony\Component\Config\ConfigCacheFactoryInterface; use Symfony\Component\Config\ConfigCacheFactory; use Psr\Log\LoggerInterface; use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface; use Symfony\Component\Routing\Matcher\RequestMatcherInterface; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; class Router implements RouterInterface, RequestMatcherInterface { protected $matcher; protected $generator; protected $context; protected $loader; protected $collection; protected $resource; protected $options = array(); protected $logger; private $configCacheFactory; private $expressionLanguageProviders = array(); public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, LoggerInterface $logger = null) { $this->loader = $loader; $this->resource = $resource; $this->logger = $logger; $this->context = $context ?: new RequestContext(); $this->setOptions($options); } public function setOptions(array $options) { $this->options = array('cache_dir'=> null,'debug'=> false,'generator_class'=>'Symfony\\Component\\Routing\\Generator\\UrlGenerator','generator_base_class'=>'Symfony\\Component\\Routing\\Generator\\UrlGenerator','generator_dumper_class'=>'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper','generator_cache_class'=>'ProjectUrlGenerator','matcher_class'=>'Symfony\\Component\\Routing\\Matcher\\UrlMatcher','matcher_base_class'=>'Symfony\\Component\\Routing\\Matcher\\UrlMatcher','matcher_dumper_class'=>'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper','matcher_cache_class'=>'ProjectUrlMatcher','resource_type'=> null,'strict_requirements'=> true, ); $invalid = array(); foreach ($options as $key => $value) { if (array_key_exists($key, $this->options)) { $this->options[$key] = $value; } else { $invalid[] = $key; } } if ($invalid) { throw new \InvalidArgumentException(sprintf('The Router does not support the following options: "%s".', implode('", "', $invalid))); } } public function setOption($key, $value) { if (!array_key_exists($key, $this->options)) { throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key)); } $this->options[$key] = $value; } public function getOption($key) { if (!array_key_exists($key, $this->options)) { throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key)); } return $this->options[$key]; } public function getRouteCollection() { if (null === $this->collection) { $this->collection = $this->loader->load($this->resource, $this->options['resource_type']); } return $this->collection; } public function setContext(RequestContext $context) { $this->context = $context; if (null !== $this->matcher) { $this->getMatcher()->setContext($context); } if (null !== $this->generator) { $this->getGenerator()->setContext($context); } } public function getContext() { return $this->context; } public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory) { $this->configCacheFactory = $configCacheFactory; } public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) { return $this->getGenerator()->generate($name, $parameters, $referenceType); } public function match($pathinfo) { return $this->getMatcher()->match($pathinfo); } public function matchRequest(Request $request) { $matcher = $this->getMatcher(); if (!$matcher instanceof RequestMatcherInterface) { return $matcher->match($request->getPathInfo()); } return $matcher->matchRequest($request); } public function getMatcher() { if (null !== $this->matcher) { return $this->matcher; } if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) { $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context); if (method_exists($this->matcher,'addExpressionLanguageProvider')) { foreach ($this->expressionLanguageProviders as $provider) { $this->matcher->addExpressionLanguageProvider($provider); } } return $this->matcher; } $class = $this->options['matcher_cache_class']; $baseClass = $this->options['matcher_base_class']; $expressionLanguageProviders = $this->expressionLanguageProviders; $that = $this; $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php', function (ConfigCacheInterface $cache) use ($that, $class, $baseClass, $expressionLanguageProviders) { $dumper = $that->getMatcherDumperInstance(); if (method_exists($dumper,'addExpressionLanguageProvider')) { foreach ($expressionLanguageProviders as $provider) { $dumper->addExpressionLanguageProvider($provider); } } $options = array('class'=> $class,'base_class'=> $baseClass, ); $cache->write($dumper->dump($options), $that->getRouteCollection()->getResources()); } ); require_once $cache->getPath(); return $this->matcher = new $class($this->context); } public function getGenerator() { if (null !== $this->generator) { return $this->generator; } if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) { $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger); } else { $class = $this->options['generator_cache_class']; $baseClass = $this->options['generator_base_class']; $that = $this; $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php', function (ConfigCacheInterface $cache) use ($that, $class, $baseClass) { $dumper = $that->getGeneratorDumperInstance(); $options = array('class'=> $class,'base_class'=> $baseClass, ); $cache->write($dumper->dump($options), $that->getRouteCollection()->getResources()); } ); require_once $cache->getPath(); $this->generator = new $class($this->context, $this->logger); } if ($this->generator instanceof ConfigurableRequirementsInterface) { $this->generator->setStrictRequirements($this->options['strict_requirements']); } return $this->generator; } public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider) { $this->expressionLanguageProviders[] = $provider; } public function getGeneratorDumperInstance() { return new $this->options['generator_dumper_class']($this->getRouteCollection()); } public function getMatcherDumperInstance() { return new $this->options['matcher_dumper_class']($this->getRouteCollection()); } private function getConfigCacheFactory() { if (null === $this->configCacheFactory) { $this->configCacheFactory = new ConfigCacheFactory($this->options['debug']); } return $this->configCacheFactory; } } } namespace Symfony\Component\Routing\Matcher { interface RedirectableUrlMatcherInterface { public function redirect($path, $route, $scheme = null); } } namespace Symfony\Component\Routing\Matcher { use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Route; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface { const REQUIREMENT_MATCH = 0; const REQUIREMENT_MISMATCH = 1; const ROUTE_MATCH = 2; protected $context; protected $allow = array(); protected $routes; protected $request; protected $expressionLanguage; protected $expressionLanguageProviders = array(); public function __construct(RouteCollection $routes, RequestContext $context) { $this->routes = $routes; $this->context = $context; } public function setContext(RequestContext $context) { $this->context = $context; } public function getContext() { return $this->context; } public function match($pathinfo) { $this->allow = array(); if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) { return $ret; } throw 0 < count($this->allow) ? new MethodNotAllowedException(array_unique($this->allow)) : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo)); } public function matchRequest(Request $request) { $this->request = $request; $ret = $this->match($request->getPathInfo()); $this->request = null; return $ret; } public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider) { $this->expressionLanguageProviders[] = $provider; } protected function matchCollection($pathinfo, RouteCollection $routes) { foreach ($routes as $name => $route) { $compiledRoute = $route->compile(); if (''!== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { continue; } if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { continue; } $hostMatches = array(); if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { continue; } if ($requiredMethods = $route->getMethods()) { if ('HEAD'=== $method = $this->context->getMethod()) { $method ='GET'; } if (!in_array($method, $requiredMethods)) { $this->allow = array_merge($this->allow, $requiredMethods); continue; } } $status = $this->handleRouteRequirements($pathinfo, $name, $route); if (self::ROUTE_MATCH === $status[0]) { return $status[1]; } if (self::REQUIREMENT_MISMATCH === $status[0]) { continue; } return $this->getAttributes($route, $name, array_replace($matches, $hostMatches)); } } protected function getAttributes(Route $route, $name, array $attributes) { $attributes['_route'] = $name; return $this->mergeDefaults($attributes, $route->getDefaults()); } protected function handleRouteRequirements($pathinfo, $name, Route $route) { if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context'=> $this->context,'request'=> $this->request))) { return array(self::REQUIREMENT_MISMATCH, null); } $scheme = $this->context->getScheme(); $status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH; return array($status, null); } protected function mergeDefaults($params, $defaults) { foreach ($params as $key => $value) { if (!is_int($key)) { $defaults[$key] = $value; } } return $defaults; } protected function getExpressionLanguage() { if (null === $this->expressionLanguage) { if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) { throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); } $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders); } return $this->expressionLanguage; } } } namespace Symfony\Component\Routing\Matcher { use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Route; abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface { public function match($pathinfo) { try { $parameters = parent::match($pathinfo); } catch (ResourceNotFoundException $e) { if ('/'=== substr($pathinfo, -1) || !in_array($this->context->getMethod(), array('HEAD','GET'))) { throw $e; } try { parent::match($pathinfo.'/'); return $this->redirect($pathinfo.'/', null); } catch (ResourceNotFoundException $e2) { throw $e; } } return $parameters; } protected function handleRouteRequirements($pathinfo, $name, Route $route) { if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context'=> $this->context,'request'=> $this->request))) { return array(self::REQUIREMENT_MISMATCH, null); } $scheme = $this->context->getScheme(); $schemes = $route->getSchemes(); if ($schemes && !$route->hasScheme($scheme)) { return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, current($schemes))); } return array(self::REQUIREMENT_MATCH, null); } } } namespace Symfony\Bundle\FrameworkBundle\Routing { use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseMatcher; class RedirectableUrlMatcher extends BaseMatcher { public function redirect($path, $route, $scheme = null) { return array('_controller'=>'Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController::urlRedirectAction','path'=> $path,'permanent'=> true,'scheme'=> $scheme,'httpPort'=> $this->context->getHttpPort(),'httpsPort'=> $this->context->getHttpsPort(),'_route'=> $route, ); } } } namespace Symfony\Component\HttpKernel\CacheWarmer { interface WarmableInterface { public function warmUp($cacheDir); } } namespace Symfony\Bundle\FrameworkBundle\Routing { use Symfony\Component\Routing\Router as BaseRouter; use Symfony\Component\Routing\RequestContext; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface; use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; use Symfony\Component\DependencyInjection\Exception\RuntimeException; class Router extends BaseRouter implements WarmableInterface { private $container; public function __construct(ContainerInterface $container, $resource, array $options = array(), RequestContext $context = null) { $this->container = $container; $this->resource = $resource; $this->context = $context ?: new RequestContext(); $this->setOptions($options); } public function getRouteCollection() { if (null === $this->collection) { $this->collection = $this->container->get('routing.loader')->load($this->resource, $this->options['resource_type']); $this->resolveParameters($this->collection); } return $this->collection; } public function warmUp($cacheDir) { $currentDir = $this->getOption('cache_dir'); $this->setOption('cache_dir', $cacheDir); $this->getMatcher(); $this->getGenerator(); $this->setOption('cache_dir', $currentDir); } private function resolveParameters(RouteCollection $collection) { foreach ($collection as $route) { foreach ($route->getDefaults() as $name => $value) { $route->setDefault($name, $this->resolve($value)); } foreach ($route->getRequirements() as $name => $value) { if ('_scheme'=== $name ||'_method'=== $name) { continue; } $route->setRequirement($name, $this->resolve($value)); } $route->setPath($this->resolve($route->getPath())); $route->setHost($this->resolve($route->getHost())); $schemes = array(); foreach ($route->getSchemes() as $scheme) { $schemes = array_merge($schemes, explode('|', $this->resolve($scheme))); } $route->setSchemes($schemes); $methods = array(); foreach ($route->getMethods() as $method) { $methods = array_merge($methods, explode('|', $this->resolve($method))); } $route->setMethods($methods); $route->setCondition($this->resolve($route->getCondition())); } } private function resolve($value) { if (is_array($value)) { foreach ($value as $key => $val) { $value[$key] = $this->resolve($val); } return $value; } if (!is_string($value)) { return $value; } $container = $this->container; $escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($container, $value) { if (!isset($match[1])) { return'%%'; } $resolved = $container->getParameter($match[1]); if (is_string($resolved) || is_numeric($resolved)) { return (string) $resolved; } throw new RuntimeException(sprintf('The container parameter "%s", used in the route configuration value "%s", '.'must be a string or numeric, but it is of type %s.', $match[1], $value, gettype($resolved) ) ); }, $value); return str_replace('%%','%', $escapedValue); } } } namespace Symfony\Component\Config { class FileLocator implements FileLocatorInterface { protected $paths; public function __construct($paths = array()) { $this->paths = (array) $paths; } public function locate($name, $currentPath = null, $first = true) { if (''== $name) { throw new \InvalidArgumentException('An empty file name is not valid to be located.'); } if ($this->isAbsolutePath($name)) { if (!file_exists($name)) { throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $name)); } return $name; } $paths = $this->paths; if (null !== $currentPath) { array_unshift($paths, $currentPath); } $paths = array_unique($paths); $filepaths = array(); foreach ($paths as $path) { if (@file_exists($file = $path.DIRECTORY_SEPARATOR.$name)) { if (true === $first) { return $file; } $filepaths[] = $file; } } if (!$filepaths) { throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s).', $name, implode(', ', $paths))); } return $filepaths; } private function isAbsolutePath($file) { if ($file[0] ==='/'|| $file[0] ==='\\'|| (strlen($file) > 3 && ctype_alpha($file[0]) && $file[1] ===':'&& ($file[2] ==='\\'|| $file[2] ==='/') ) || null !== parse_url($file, PHP_URL_SCHEME) ) { return true; } return false; } } } namespace Symfony\Component\EventDispatcher { class Event { private $propagationStopped = false; private $dispatcher; private $name; public function isPropagationStopped() { return $this->propagationStopped; } public function stopPropagation() { $this->propagationStopped = true; } public function setDispatcher(EventDispatcherInterface $dispatcher) { $this->dispatcher = $dispatcher; } public function getDispatcher() { @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0. The event dispatcher instance can be received in the listener call instead.', E_USER_DEPRECATED); return $this->dispatcher; } public function getName() { @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0. The event name can be received in the listener call instead.', E_USER_DEPRECATED); return $this->name; } public function setName($name) { $this->name = $name; } } } namespace Symfony\Component\EventDispatcher { interface EventDispatcherInterface { public function dispatch($eventName, Event $event = null); public function addListener($eventName, $listener, $priority = 0); public function addSubscriber(EventSubscriberInterface $subscriber); public function removeListener($eventName, $listener); public function removeSubscriber(EventSubscriberInterface $subscriber); public function getListeners($eventName = null); public function hasListeners($eventName = null); } } namespace Symfony\Component\EventDispatcher { class EventDispatcher implements EventDispatcherInterface { private $listeners = array(); private $sorted = array(); public function dispatch($eventName, Event $event = null) { if (null === $event) { $event = new Event(); } $event->setDispatcher($this); $event->setName($eventName); if ($listeners = $this->getListeners($eventName)) { $this->doDispatch($listeners, $eventName, $event); } return $event; } public function getListeners($eventName = null) { if (null !== $eventName) { if (!isset($this->listeners[$eventName])) { return array(); } if (!isset($this->sorted[$eventName])) { $this->sortListeners($eventName); } return $this->sorted[$eventName]; } foreach ($this->listeners as $eventName => $eventListeners) { if (!isset($this->sorted[$eventName])) { $this->sortListeners($eventName); } } return array_filter($this->sorted); } public function getListenerPriority($eventName, $listener) { if (!isset($this->listeners[$eventName])) { return; } foreach ($this->listeners[$eventName] as $priority => $listeners) { if (false !== in_array($listener, $listeners, true)) { return $priority; } } } public function hasListeners($eventName = null) { return (bool) count($this->getListeners($eventName)); } public function addListener($eventName, $listener, $priority = 0) { $this->listeners[$eventName][$priority][] = $listener; unset($this->sorted[$eventName]); } public function removeListener($eventName, $listener) { if (!isset($this->listeners[$eventName])) { return; } foreach ($this->listeners[$eventName] as $priority => $listeners) { if (false !== ($key = array_search($listener, $listeners, true))) { unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]); } } } public function addSubscriber(EventSubscriberInterface $subscriber) { foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { if (is_string($params)) { $this->addListener($eventName, array($subscriber, $params)); } elseif (is_string($params[0])) { $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0); } else { foreach ($params as $listener) { $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0); } } } } public function removeSubscriber(EventSubscriberInterface $subscriber) { foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { if (is_array($params) && is_array($params[0])) { foreach ($params as $listener) { $this->removeListener($eventName, array($subscriber, $listener[0])); } } else { $this->removeListener($eventName, array($subscriber, is_string($params) ? $params : $params[0])); } } } protected function doDispatch($listeners, $eventName, Event $event) { foreach ($listeners as $listener) { if ($event->isPropagationStopped()) { break; } call_user_func($listener, $event, $eventName, $this); } } private function sortListeners($eventName) { krsort($this->listeners[$eventName]); $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]); } } } namespace Symfony\Component\EventDispatcher { use Symfony\Component\DependencyInjection\ContainerInterface; class ContainerAwareEventDispatcher extends EventDispatcher { private $container; private $listenerIds = array(); private $listeners = array(); public function __construct(ContainerInterface $container) { $this->container = $container; } public function addListenerService($eventName, $callback, $priority = 0) { if (!is_array($callback) || 2 !== count($callback)) { throw new \InvalidArgumentException('Expected an array("service", "method") argument'); } $this->listenerIds[$eventName][] = array($callback[0], $callback[1], $priority); } public function removeListener($eventName, $listener) { $this->lazyLoad($eventName); if (isset($this->listenerIds[$eventName])) { foreach ($this->listenerIds[$eventName] as $i => $args) { list($serviceId, $method, $priority) = $args; $key = $serviceId.'.'.$method; if (isset($this->listeners[$eventName][$key]) && $listener === array($this->listeners[$eventName][$key], $method)) { unset($this->listeners[$eventName][$key]); if (empty($this->listeners[$eventName])) { unset($this->listeners[$eventName]); } unset($this->listenerIds[$eventName][$i]); if (empty($this->listenerIds[$eventName])) { unset($this->listenerIds[$eventName]); } } } } parent::removeListener($eventName, $listener); } public function hasListeners($eventName = null) { if (null === $eventName) { return (bool) count($this->listenerIds) || (bool) count($this->listeners); } if (isset($this->listenerIds[$eventName])) { return true; } return parent::hasListeners($eventName); } public function getListeners($eventName = null) { if (null === $eventName) { foreach ($this->listenerIds as $serviceEventName => $args) { $this->lazyLoad($serviceEventName); } } else { $this->lazyLoad($eventName); } return parent::getListeners($eventName); } public function getListenerPriority($eventName, $listener) { $this->lazyLoad($eventName); return parent::getListenerPriority($eventName, $listener); } public function addSubscriberService($serviceId, $class) { foreach ($class::getSubscribedEvents() as $eventName => $params) { if (is_string($params)) { $this->listenerIds[$eventName][] = array($serviceId, $params, 0); } elseif (is_string($params[0])) { $this->listenerIds[$eventName][] = array($serviceId, $params[0], isset($params[1]) ? $params[1] : 0); } else { foreach ($params as $listener) { $this->listenerIds[$eventName][] = array($serviceId, $listener[0], isset($listener[1]) ? $listener[1] : 0); } } } } public function getContainer() { return $this->container; } protected function lazyLoad($eventName) { if (isset($this->listenerIds[$eventName])) { foreach ($this->listenerIds[$eventName] as $args) { list($serviceId, $method, $priority) = $args; $listener = $this->container->get($serviceId); $key = $serviceId.'.'.$method; if (!isset($this->listeners[$eventName][$key])) { $this->addListener($eventName, array($listener, $method), $priority); } elseif ($listener !== $this->listeners[$eventName][$key]) { parent::removeListener($eventName, array($this->listeners[$eventName][$key], $method)); $this->addListener($eventName, array($listener, $method), $priority); } $this->listeners[$eventName][$key] = $listener; } } } } } namespace Symfony\Component\HttpKernel\EventListener { use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ResponseListener implements EventSubscriberInterface { private $charset; public function __construct($charset) { $this->charset = $charset; } public function onKernelResponse(FilterResponseEvent $event) { if (!$event->isMasterRequest()) { return; } $response = $event->getResponse(); if (null === $response->getCharset()) { $response->setCharset($this->charset); } $response->prepare($event->getRequest()); } public static function getSubscribedEvents() { return array( KernelEvents::RESPONSE =>'onKernelResponse', ); } } } namespace Symfony\Component\HttpKernel\EventListener { use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; use Symfony\Component\Routing\Matcher\RequestMatcherInterface; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\RequestContextAwareInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; class RouterListener implements EventSubscriberInterface { private $matcher; private $context; private $logger; private $request; private $requestStack; public function __construct($matcher, $requestStack = null, $context = null, $logger = null) { if ($requestStack instanceof RequestContext || $context instanceof LoggerInterface || $logger instanceof RequestStack) { $tmp = $requestStack; $requestStack = $logger; $logger = $context; $context = $tmp; @trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as second argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); } elseif (!$requestStack instanceof RequestStack) { @trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); } if (null !== $requestStack && !$requestStack instanceof RequestStack) { throw new \InvalidArgumentException('RequestStack instance expected.'); } if (null !== $context && !$context instanceof RequestContext) { throw new \InvalidArgumentException('RequestContext instance expected.'); } if (null !== $logger && !$logger instanceof LoggerInterface) { throw new \InvalidArgumentException('Logger must implement LoggerInterface.'); } if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) { throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.'); } if (null === $context && !$matcher instanceof RequestContextAwareInterface) { throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.'); } $this->matcher = $matcher; $this->context = $context ?: $matcher->getContext(); $this->requestStack = $requestStack; $this->logger = $logger; } public function setRequest(Request $request = null) { @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be made private in 3.0.', E_USER_DEPRECATED); $this->setCurrentRequest($request); } private function setCurrentRequest(Request $request = null) { if (null !== $request && $this->request !== $request) { $this->context->fromRequest($request); } $this->request = $request; } public function onKernelFinishRequest(FinishRequestEvent $event) { if (null === $this->requestStack) { return; } $this->setCurrentRequest($this->requestStack->getParentRequest()); } public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); if (null !== $this->requestStack) { $this->setCurrentRequest($request); } if ($request->attributes->has('_controller')) { return; } try { if ($this->matcher instanceof RequestMatcherInterface) { $parameters = $this->matcher->matchRequest($request); } else { $parameters = $this->matcher->match($request->getPathInfo()); } if (null !== $this->logger) { $this->logger->info(sprintf('Matched route "%s".', isset($parameters['_route']) ? $parameters['_route'] :'n/a'), array('route_parameters'=> $parameters,'request_uri'=> $request->getUri(), )); } $request->attributes->add($parameters); unset($parameters['_route'], $parameters['_controller']); $request->attributes->set('_route_params', $parameters); } catch (ResourceNotFoundException $e) { $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo()); if ($referer = $request->headers->get('referer')) { $message .= sprintf(' (from "%s")', $referer); } throw new NotFoundHttpException($message, $e); } catch (MethodNotAllowedException $e) { $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), implode(', ', $e->getAllowedMethods())); throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e); } } public static function getSubscribedEvents() { return array( KernelEvents::REQUEST => array(array('onKernelRequest', 32)), KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)), ); } } } namespace Symfony\Component\HttpKernel\Controller { use Symfony\Component\HttpFoundation\Request; interface ControllerResolverInterface { public function getController(Request $request); public function getArguments(Request $request, $controller); } } namespace Symfony\Component\HttpKernel\Controller { use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; class ControllerResolver implements ControllerResolverInterface { private $logger; private $supportsVariadic; public function __construct(LoggerInterface $logger = null) { $this->logger = $logger; $this->supportsVariadic = method_exists('ReflectionParameter','isVariadic'); } public function getController(Request $request) { if (!$controller = $request->attributes->get('_controller')) { if (null !== $this->logger) { $this->logger->warning('Unable to look for the controller as the "_controller" parameter is missing.'); } return false; } if (is_array($controller)) { return $controller; } if (is_object($controller)) { if (method_exists($controller,'__invoke')) { return $controller; } throw new \InvalidArgumentException(sprintf('Controller "%s" for URI "%s" is not callable.', get_class($controller), $request->getPathInfo())); } if (false === strpos($controller,':')) { if (method_exists($controller,'__invoke')) { return $this->instantiateController($controller); } elseif (function_exists($controller)) { return $controller; } } $callable = $this->createController($controller); if (!is_callable($callable)) { throw new \InvalidArgumentException(sprintf('Controller "%s" for URI "%s" is not callable.', $controller, $request->getPathInfo())); } return $callable; } public function getArguments(Request $request, $controller) { if (is_array($controller)) { $r = new \ReflectionMethod($controller[0], $controller[1]); } elseif (is_object($controller) && !$controller instanceof \Closure) { $r = new \ReflectionObject($controller); $r = $r->getMethod('__invoke'); } else { $r = new \ReflectionFunction($controller); } return $this->doGetArguments($request, $controller, $r->getParameters()); } protected function doGetArguments(Request $request, $controller, array $parameters) { $attributes = $request->attributes->all(); $arguments = array(); foreach ($parameters as $param) { if (array_key_exists($param->name, $attributes)) { if ($this->supportsVariadic && $param->isVariadic() && is_array($attributes[$param->name])) { $arguments = array_merge($arguments, array_values($attributes[$param->name])); } else { $arguments[] = $attributes[$param->name]; } } elseif ($param->getClass() && $param->getClass()->isInstance($request)) { $arguments[] = $request; } elseif ($param->isDefaultValueAvailable()) { $arguments[] = $param->getDefaultValue(); } elseif ($param->allowsNull()) { $arguments[] = null; } else { if (is_array($controller)) { $repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]); } elseif (is_object($controller)) { $repr = get_class($controller); } else { $repr = $controller; } throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name)); } } return $arguments; } protected function createController($controller) { if (false === strpos($controller,'::')) { throw new \InvalidArgumentException(sprintf('Unable to find controller "%s".', $controller)); } list($class, $method) = explode('::', $controller, 2); if (!class_exists($class)) { throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); } return array($this->instantiateController($class), $method); } protected function instantiateController($class) { return new $class(); } } } namespace Symfony\Component\HttpKernel\Event { use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\EventDispatcher\Event; class KernelEvent extends Event { private $kernel; private $request; private $requestType; public function __construct(HttpKernelInterface $kernel, Request $request, $requestType) { $this->kernel = $kernel; $this->request = $request; $this->requestType = $requestType; } public function getKernel() { return $this->kernel; } public function getRequest() { return $this->request; } public function getRequestType() { return $this->requestType; } public function isMasterRequest() { return HttpKernelInterface::MASTER_REQUEST === $this->requestType; } } } namespace Symfony\Component\HttpKernel\Event { use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; class FilterControllerEvent extends KernelEvent { private $controller; public function __construct(HttpKernelInterface $kernel, $controller, Request $request, $requestType) { parent::__construct($kernel, $request, $requestType); $this->setController($controller); } public function getController() { return $this->controller; } public function setController($controller) { if (!is_callable($controller)) { throw new \LogicException(sprintf('The controller must be a callable (%s given).', $this->varToString($controller))); } $this->controller = $controller; } private function varToString($var) { if (is_object($var)) { return sprintf('Object(%s)', get_class($var)); } if (is_array($var)) { $a = array(); foreach ($var as $k => $v) { $a[] = sprintf('%s => %s', $k, $this->varToString($v)); } return sprintf('Array(%s)', implode(', ', $a)); } if (is_resource($var)) { return sprintf('Resource(%s)', get_resource_type($var)); } if (null === $var) { return'null'; } if (false === $var) { return'false'; } if (true === $var) { return'true'; } return (string) $var; } } } namespace Symfony\Component\HttpKernel\Event { use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class FilterResponseEvent extends KernelEvent { private $response; public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, Response $response) { parent::__construct($kernel, $request, $requestType); $this->setResponse($response); } public function getResponse() { return $this->response; } public function setResponse(Response $response) { $this->response = $response; } } } namespace Symfony\Component\HttpKernel\Event { use Symfony\Component\HttpFoundation\Response; class GetResponseEvent extends KernelEvent { private $response; public function getResponse() { return $this->response; } public function setResponse(Response $response) { $this->response = $response; $this->stopPropagation(); } public function hasResponse() { return null !== $this->response; } } } namespace Symfony\Component\HttpKernel\Event { use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; class GetResponseForControllerResultEvent extends GetResponseEvent { private $controllerResult; public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, $controllerResult) { parent::__construct($kernel, $request, $requestType); $this->controllerResult = $controllerResult; } public function getControllerResult() { return $this->controllerResult; } public function setControllerResult($controllerResult) { $this->controllerResult = $controllerResult; } } } namespace Symfony\Component\HttpKernel\Event { use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; class GetResponseForExceptionEvent extends GetResponseEvent { private $exception; public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, \Exception $e) { parent::__construct($kernel, $request, $requestType); $this->setException($e); } public function getException() { return $this->exception; } public function setException(\Exception $exception) { $this->exception = $exception; } } } namespace Symfony\Component\HttpKernel { final class KernelEvents { const REQUEST ='kernel.request'; const EXCEPTION ='kernel.exception'; const VIEW ='kernel.view'; const CONTROLLER ='kernel.controller'; const RESPONSE ='kernel.response'; const TERMINATE ='kernel.terminate'; const FINISH_REQUEST ='kernel.finish_request'; } } namespace Symfony\Component\HttpKernel\Config { use Symfony\Component\Config\FileLocator as BaseFileLocator; use Symfony\Component\HttpKernel\KernelInterface; class FileLocator extends BaseFileLocator { private $kernel; private $path; public function __construct(KernelInterface $kernel, $path = null, array $paths = array()) { $this->kernel = $kernel; if (null !== $path) { $this->path = $path; $paths[] = $path; } parent::__construct($paths); } public function locate($file, $currentPath = null, $first = true) { if (isset($file[0]) &&'@'=== $file[0]) { return $this->kernel->locateResource($file, $this->path, $first); } return parent::locate($file, $currentPath, $first); } } } namespace Symfony\Bundle\FrameworkBundle\Controller { use Symfony\Component\HttpKernel\KernelInterface; class ControllerNameParser { protected $kernel; public function __construct(KernelInterface $kernel) { $this->kernel = $kernel; } public function parse($controller) { $originalController = $controller; if (3 !== count($parts = explode(':', $controller))) { throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid "a:b:c" controller string.', $controller)); } list($bundle, $controller, $action) = $parts; $controller = str_replace('/','\\', $controller); $bundles = array(); try { $allBundles = $this->kernel->getBundle($bundle, false); } catch (\InvalidArgumentException $e) { $message = sprintf('The "%s" (from the _controller value "%s") does not exist or is not enabled in your kernel!', $bundle, $originalController ); if ($alternative = $this->findAlternative($bundle)) { $message .= sprintf(' Did you mean "%s:%s:%s"?', $alternative, $controller, $action); } throw new \InvalidArgumentException($message, 0, $e); } foreach ($allBundles as $b) { $try = $b->getNamespace().'\\Controller\\'.$controller.'Controller'; if (class_exists($try)) { return $try.'::'.$action.'Action'; } $bundles[] = $b->getName(); $msg = sprintf('The _controller value "%s:%s:%s" maps to a "%s" class, but this class was not found. Create this class or check the spelling of the class and its namespace.', $bundle, $controller, $action, $try); } if (count($bundles) > 1) { $msg = sprintf('Unable to find controller "%s:%s" in bundles %s.', $bundle, $controller, implode(', ', $bundles)); } throw new \InvalidArgumentException($msg); } public function build($controller) { if (0 === preg_match('#^(.*?\\\\Controller\\\\(.+)Controller)::(.+)Action$#', $controller, $match)) { throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid "class::method" string.', $controller)); } $className = $match[1]; $controllerName = $match[2]; $actionName = $match[3]; foreach ($this->kernel->getBundles() as $name => $bundle) { if (0 !== strpos($className, $bundle->getNamespace())) { continue; } return sprintf('%s:%s:%s', $name, $controllerName, $actionName); } throw new \InvalidArgumentException(sprintf('Unable to find a bundle that defines controller "%s".', $controller)); } private function findAlternative($nonExistentBundleName) { $bundleNames = array_map(function ($b) { return $b->getName(); }, $this->kernel->getBundles()); $alternative = null; $shortest = null; foreach ($bundleNames as $bundleName) { if (false !== strpos($bundleName, $nonExistentBundleName)) { return $bundleName; } $lev = levenshtein($nonExistentBundleName, $bundleName); if ($lev <= strlen($nonExistentBundleName) / 3 && ($alternative === null || $lev < $shortest)) { $alternative = $bundleName; $shortest = $lev; } } return $alternative; } } } namespace Symfony\Bundle\FrameworkBundle\Controller { use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface; class ControllerResolver extends BaseControllerResolver { protected $container; protected $parser; public function __construct(ContainerInterface $container, ControllerNameParser $parser, LoggerInterface $logger = null) { $this->container = $container; $this->parser = $parser; parent::__construct($logger); } protected function createController($controller) { if (false === strpos($controller,'::')) { $count = substr_count($controller,':'); if (2 == $count) { $controller = $this->parser->parse($controller); } elseif (1 == $count) { list($service, $method) = explode(':', $controller, 2); return array($this->container->get($service), $method); } elseif ($this->container->has($controller) && method_exists($service = $this->container->get($controller),'__invoke')) { return $service; } else { throw new \LogicException(sprintf('Unable to parse the controller name "%s".', $controller)); } } return parent::createController($controller); } protected function instantiateController($class) { if ($this->container->has($class)) { return $this->container->get($class); } $controller = parent::instantiateController($class); if ($controller instanceof ContainerAwareInterface) { $controller->setContainer($this->container); } return $controller; } } } namespace Symfony\Component\Security\Http { use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class Firewall implements EventSubscriberInterface { private $map; private $dispatcher; private $exceptionListeners; public function __construct(FirewallMapInterface $map, EventDispatcherInterface $dispatcher) { $this->map = $map; $this->dispatcher = $dispatcher; $this->exceptionListeners = new \SplObjectStorage(); } public function onKernelRequest(GetResponseEvent $event) { if (!$event->isMasterRequest()) { return; } list($listeners, $exceptionListener) = $this->map->getListeners($event->getRequest()); if (null !== $exceptionListener) { $this->exceptionListeners[$event->getRequest()] = $exceptionListener; $exceptionListener->register($this->dispatcher); } foreach ($listeners as $listener) { $listener->handle($event); if ($event->hasResponse()) { break; } } } public function onKernelFinishRequest(FinishRequestEvent $event) { $request = $event->getRequest(); if (isset($this->exceptionListeners[$request])) { $this->exceptionListeners[$request]->unregister($this->dispatcher); unset($this->exceptionListeners[$request]); } } public static function getSubscribedEvents() { return array( KernelEvents::REQUEST => array('onKernelRequest', 8), KernelEvents::FINISH_REQUEST =>'onKernelFinishRequest', ); } } } namespace Symfony\Component\Security\Core\User { use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Core\Exception\UnsupportedUserException; interface UserProviderInterface { public function loadUserByUsername($username); public function refreshUser(UserInterface $user); public function supportsClass($class); } } namespace Symfony\Component\Security\Core\Authentication { use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; interface AuthenticationManagerInterface { public function authenticate(TokenInterface $token); } } namespace Symfony\Component\Security\Core\Authentication { use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent; use Symfony\Component\Security\Core\Event\AuthenticationEvent; use Symfony\Component\Security\Core\AuthenticationEvents; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Security\Core\Exception\AccountStatusException; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\ProviderNotFoundException; use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; class AuthenticationProviderManager implements AuthenticationManagerInterface { private $providers; private $eraseCredentials; private $eventDispatcher; public function __construct(array $providers, $eraseCredentials = true) { if (!$providers) { throw new \InvalidArgumentException('You must at least add one authentication provider.'); } foreach ($providers as $provider) { if (!$provider instanceof AuthenticationProviderInterface) { throw new \InvalidArgumentException(sprintf('Provider "%s" must implement the AuthenticationProviderInterface.', get_class($provider))); } } $this->providers = $providers; $this->eraseCredentials = (bool) $eraseCredentials; } public function setEventDispatcher(EventDispatcherInterface $dispatcher) { $this->eventDispatcher = $dispatcher; } public function authenticate(TokenInterface $token) { $lastException = null; $result = null; foreach ($this->providers as $provider) { if (!$provider->supports($token)) { continue; } try { $result = $provider->authenticate($token); if (null !== $result) { break; } } catch (AccountStatusException $e) { $e->setToken($token); throw $e; } catch (AuthenticationException $e) { $lastException = $e; } } if (null !== $result) { if (true === $this->eraseCredentials) { $result->eraseCredentials(); } if (null !== $this->eventDispatcher) { $this->eventDispatcher->dispatch(AuthenticationEvents::AUTHENTICATION_SUCCESS, new AuthenticationEvent($result)); } return $result; } if (null === $lastException) { $lastException = new ProviderNotFoundException(sprintf('No Authentication Provider found for token of class "%s".', get_class($token))); } if (null !== $this->eventDispatcher) { $this->eventDispatcher->dispatch(AuthenticationEvents::AUTHENTICATION_FAILURE, new AuthenticationFailureEvent($token, $lastException)); } $lastException->setToken($token); throw $lastException; } } } namespace Symfony\Component\Security\Core\Authentication\Token\Storage { use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; interface TokenStorageInterface { public function getToken(); public function setToken(TokenInterface $token = null); } } namespace Symfony\Component\Security\Core\Authentication\Token\Storage { use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; class TokenStorage implements TokenStorageInterface { private $token; public function getToken() { return $this->token; } public function setToken(TokenInterface $token = null) { $this->token = $token; } } } namespace Symfony\Component\Security\Core\Authorization { use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; interface AccessDecisionManagerInterface { public function decide(TokenInterface $token, array $attributes, $object = null); public function supportsAttribute($attribute); public function supportsClass($class); } } namespace Symfony\Component\Security\Core\Authorization { use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; class AccessDecisionManager implements AccessDecisionManagerInterface { const STRATEGY_AFFIRMATIVE ='affirmative'; const STRATEGY_CONSENSUS ='consensus'; const STRATEGY_UNANIMOUS ='unanimous'; private $voters; private $strategy; private $allowIfAllAbstainDecisions; private $allowIfEqualGrantedDeniedDecisions; public function __construct(array $voters = array(), $strategy = self::STRATEGY_AFFIRMATIVE, $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true) { $strategyMethod ='decide'.ucfirst($strategy); if (!is_callable(array($this, $strategyMethod))) { throw new \InvalidArgumentException(sprintf('The strategy "%s" is not supported.', $strategy)); } $this->voters = $voters; $this->strategy = $strategyMethod; $this->allowIfAllAbstainDecisions = (bool) $allowIfAllAbstainDecisions; $this->allowIfEqualGrantedDeniedDecisions = (bool) $allowIfEqualGrantedDeniedDecisions; } public function setVoters(array $voters) { $this->voters = $voters; } public function decide(TokenInterface $token, array $attributes, $object = null) { return $this->{$this->strategy}($token, $attributes, $object); } public function supportsAttribute($attribute) { @trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED); foreach ($this->voters as $voter) { if ($voter->supportsAttribute($attribute)) { return true; } } return false; } public function supportsClass($class) { @trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED); foreach ($this->voters as $voter) { if ($voter->supportsClass($class)) { return true; } } return false; } private function decideAffirmative(TokenInterface $token, array $attributes, $object = null) { $deny = 0; foreach ($this->voters as $voter) { $result = $voter->vote($token, $object, $attributes); switch ($result) { case VoterInterface::ACCESS_GRANTED: return true; case VoterInterface::ACCESS_DENIED: ++$deny; break; default: break; } } if ($deny > 0) { return false; } return $this->allowIfAllAbstainDecisions; } private function decideConsensus(TokenInterface $token, array $attributes, $object = null) { $grant = 0; $deny = 0; foreach ($this->voters as $voter) { $result = $voter->vote($token, $object, $attributes); switch ($result) { case VoterInterface::ACCESS_GRANTED: ++$grant; break; case VoterInterface::ACCESS_DENIED: ++$deny; break; } } if ($grant > $deny) { return true; } if ($deny > $grant) { return false; } if ($grant > 0) { return $this->allowIfEqualGrantedDeniedDecisions; } return $this->allowIfAllAbstainDecisions; } private function decideUnanimous(TokenInterface $token, array $attributes, $object = null) { $grant = 0; foreach ($attributes as $attribute) { foreach ($this->voters as $voter) { $result = $voter->vote($token, $object, array($attribute)); switch ($result) { case VoterInterface::ACCESS_GRANTED: ++$grant; break; case VoterInterface::ACCESS_DENIED: return false; default: break; } } } if ($grant > 0) { return true; } return $this->allowIfAllAbstainDecisions; } } } namespace Symfony\Component\Security\Core\Authorization { interface AuthorizationCheckerInterface { public function isGranted($attributes, $object = null); } } namespace Symfony\Component\Security\Core\Authorization { use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException; class AuthorizationChecker implements AuthorizationCheckerInterface { private $tokenStorage; private $accessDecisionManager; private $authenticationManager; private $alwaysAuthenticate; public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager, $alwaysAuthenticate = false) { $this->tokenStorage = $tokenStorage; $this->authenticationManager = $authenticationManager; $this->accessDecisionManager = $accessDecisionManager; $this->alwaysAuthenticate = $alwaysAuthenticate; } final public function isGranted($attributes, $object = null) { if (null === ($token = $this->tokenStorage->getToken())) { throw new AuthenticationCredentialsNotFoundException('The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL.'); } if ($this->alwaysAuthenticate || !$token->isAuthenticated()) { $this->tokenStorage->setToken($token = $this->authenticationManager->authenticate($token)); } if (!is_array($attributes)) { $attributes = array($attributes); } return $this->accessDecisionManager->decide($token, $attributes, $object); } } } namespace Symfony\Component\Security\Core\Authorization\Voter { use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; interface VoterInterface { const ACCESS_GRANTED = 1; const ACCESS_ABSTAIN = 0; const ACCESS_DENIED = -1; public function supportsAttribute($attribute); public function supportsClass($class); public function vote(TokenInterface $token, $object, array $attributes); } } namespace Symfony\Component\Security\Http { use Symfony\Component\HttpFoundation\Request; interface FirewallMapInterface { public function getListeners(Request $request); } } namespace Symfony\Bundle\SecurityBundle\Security { use Symfony\Component\Security\Http\FirewallMapInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\DependencyInjection\ContainerInterface; class FirewallMap implements FirewallMapInterface { protected $container; protected $map; public function __construct(ContainerInterface $container, array $map) { $this->container = $container; $this->map = $map; } public function getListeners(Request $request) { foreach ($this->map as $contextId => $requestMatcher) { if (null === $requestMatcher || $requestMatcher->matches($request)) { return $this->container->get($contextId)->getContext(); } } return array(array(), null); } } } namespace Symfony\Bundle\SecurityBundle\Security { use Symfony\Component\Security\Http\Firewall\ExceptionListener; class FirewallContext { private $listeners; private $exceptionListener; public function __construct(array $listeners, ExceptionListener $exceptionListener = null) { $this->listeners = $listeners; $this->exceptionListener = $exceptionListener; } public function getContext() { return array($this->listeners, $this->exceptionListener); } } } namespace Symfony\Component\HttpFoundation { interface RequestMatcherInterface { public function matches(Request $request); } } namespace Symfony\Component\HttpFoundation { class RequestMatcher implements RequestMatcherInterface { private $path; private $host; private $methods = array(); private $ips = array(); private $attributes = array(); private $schemes = array(); public function __construct($path = null, $host = null, $methods = null, $ips = null, array $attributes = array(), $schemes = null) { $this->matchPath($path); $this->matchHost($host); $this->matchMethod($methods); $this->matchIps($ips); $this->matchScheme($schemes); foreach ($attributes as $k => $v) { $this->matchAttribute($k, $v); } } public function matchScheme($scheme) { $this->schemes = null !== $scheme ? array_map('strtolower', (array) $scheme) : array(); } public function matchHost($regexp) { $this->host = $regexp; } public function matchPath($regexp) { $this->path = $regexp; } public function matchIp($ip) { $this->matchIps($ip); } public function matchIps($ips) { $this->ips = null !== $ips ? (array) $ips : array(); } public function matchMethod($method) { $this->methods = null !== $method ? array_map('strtoupper', (array) $method) : array(); } public function matchAttribute($key, $regexp) { $this->attributes[$key] = $regexp; } public function matches(Request $request) { if ($this->schemes && !in_array($request->getScheme(), $this->schemes, true)) { return false; } if ($this->methods && !in_array($request->getMethod(), $this->methods, true)) { return false; } foreach ($this->attributes as $key => $pattern) { if (!preg_match('{'.$pattern.'}', $request->attributes->get($key))) { return false; } } if (null !== $this->path && !preg_match('{'.$this->path.'}', rawurldecode($request->getPathInfo()))) { return false; } if (null !== $this->host && !preg_match('{'.$this->host.'}i', $request->getHost())) { return false; } if (IpUtils::checkIp($request->getClientIp(), $this->ips)) { return true; } return count($this->ips) === 0; } } } namespace { class Twig_Environment { const VERSION ='1.28.1'; const VERSION_ID = 12801; const MAJOR_VERSION = 1; const MINOR_VERSION = 28; const RELEASE_VERSION = 1; const EXTRA_VERSION =''; protected $charset; protected $loader; protected $debug; protected $autoReload; protected $cache; protected $lexer; protected $parser; protected $compiler; protected $baseTemplateClass; protected $extensions; protected $parsers; protected $visitors; protected $filters; protected $tests; protected $functions; protected $globals; protected $runtimeInitialized = false; protected $extensionInitialized = false; protected $loadedTemplates; protected $strictVariables; protected $unaryOperators; protected $binaryOperators; protected $templateClassPrefix ='__TwigTemplate_'; protected $functionCallbacks = array(); protected $filterCallbacks = array(); protected $staging; private $originalCache; private $bcWriteCacheFile = false; private $bcGetCacheFilename = false; private $lastModifiedExtension = 0; private $extensionsByClass = array(); private $runtimeLoaders = array(); private $runtimes = array(); private $optionsHash; public function __construct(Twig_LoaderInterface $loader = null, $options = array()) { if (null !== $loader) { $this->setLoader($loader); } else { @trigger_error('Not passing a Twig_LoaderInterface as the first constructor argument of Twig_Environment is deprecated since version 1.21.', E_USER_DEPRECATED); } $options = array_merge(array('debug'=> false,'charset'=>'UTF-8','base_template_class'=>'Twig_Template','strict_variables'=> false,'autoescape'=>'html','cache'=> false,'auto_reload'=> null,'optimizations'=> -1, ), $options); $this->debug = (bool) $options['debug']; $this->charset = strtoupper($options['charset']); $this->baseTemplateClass = $options['base_template_class']; $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload']; $this->strictVariables = (bool) $options['strict_variables']; $this->setCache($options['cache']); $this->addExtension(new Twig_Extension_Core()); $this->addExtension(new Twig_Extension_Escaper($options['autoescape'])); $this->addExtension(new Twig_Extension_Optimizer($options['optimizations'])); $this->staging = new Twig_Extension_Staging(); if (is_string($this->originalCache)) { $r = new ReflectionMethod($this,'writeCacheFile'); if ($r->getDeclaringClass()->getName() !== __CLASS__) { @trigger_error('The Twig_Environment::writeCacheFile method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED); $this->bcWriteCacheFile = true; } $r = new ReflectionMethod($this,'getCacheFilename'); if ($r->getDeclaringClass()->getName() !== __CLASS__) { @trigger_error('The Twig_Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED); $this->bcGetCacheFilename = true; } } } public function getBaseTemplateClass() { return $this->baseTemplateClass; } public function setBaseTemplateClass($class) { $this->baseTemplateClass = $class; $this->updateOptionsHash(); } public function enableDebug() { $this->debug = true; $this->updateOptionsHash(); } public function disableDebug() { $this->debug = false; $this->updateOptionsHash(); } public function isDebug() { return $this->debug; } public function enableAutoReload() { $this->autoReload = true; } public function disableAutoReload() { $this->autoReload = false; } public function isAutoReload() { return $this->autoReload; } public function enableStrictVariables() { $this->strictVariables = true; $this->updateOptionsHash(); } public function disableStrictVariables() { $this->strictVariables = false; $this->updateOptionsHash(); } public function isStrictVariables() { return $this->strictVariables; } public function getCache($original = true) { return $original ? $this->originalCache : $this->cache; } public function setCache($cache) { if (is_string($cache)) { $this->originalCache = $cache; $this->cache = new Twig_Cache_Filesystem($cache); } elseif (false === $cache) { $this->originalCache = $cache; $this->cache = new Twig_Cache_Null(); } elseif (null === $cache) { @trigger_error('Using "null" as the cache strategy is deprecated since version 1.23 and will be removed in Twig 2.0.', E_USER_DEPRECATED); $this->originalCache = false; $this->cache = new Twig_Cache_Null(); } elseif ($cache instanceof Twig_CacheInterface) { $this->originalCache = $this->cache = $cache; } else { throw new LogicException(sprintf('Cache can only be a string, false, or a Twig_CacheInterface implementation.')); } } public function getCacheFilename($name) { @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED); $key = $this->cache->generateKey($name, $this->getTemplateClass($name)); return !$key ? false : $key; } public function getTemplateClass($name, $index = null) { $key = $this->getLoader()->getCacheKey($name).$this->optionsHash; return $this->templateClassPrefix.hash('sha256', $key).(null === $index ?'':'_'.$index); } public function getTemplateClassPrefix() { @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED); return $this->templateClassPrefix; } public function render($name, array $context = array()) { return $this->loadTemplate($name)->render($context); } public function display($name, array $context = array()) { $this->loadTemplate($name)->display($context); } public function load($name) { if ($name instanceof Twig_TemplateWrapper) { return $name; } if ($name instanceof Twig_Template) { return new Twig_TemplateWrapper($this, $name); } return new Twig_TemplateWrapper($this, $this->loadTemplate($name)); } public function loadTemplate($name, $index = null) { $cls = $this->getTemplateClass($name, $index); if (isset($this->loadedTemplates[$cls])) { return $this->loadedTemplates[$cls]; } if (!class_exists($cls, false)) { if ($this->bcGetCacheFilename) { $key = $this->getCacheFilename($name); } else { $key = $this->cache->generateKey($name, $cls); } if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) { $this->cache->load($key); } if (!class_exists($cls, false)) { $loader = $this->getLoader(); if (!$loader instanceof Twig_SourceContextLoaderInterface) { $source = new Twig_Source($loader->getSource($name), $name); } else { $source = $loader->getSourceContext($name); } $content = $this->compileSource($source); if ($this->bcWriteCacheFile) { $this->writeCacheFile($key, $content); } else { $this->cache->write($key, $content); $this->cache->load($key); } if (!class_exists($cls, false)) { eval('?>'.$content); } } } if (!$this->runtimeInitialized) { $this->initRuntime(); } return $this->loadedTemplates[$cls] = new $cls($this); } public function createTemplate($template) { $name = sprintf('__string_template__%s', hash('sha256', uniqid(mt_rand(), true), false)); $loader = new Twig_Loader_Chain(array( new Twig_Loader_Array(array($name => $template)), $current = $this->getLoader(), )); $this->setLoader($loader); try { $template = $this->loadTemplate($name); } catch (Exception $e) { $this->setLoader($current); throw $e; } catch (Throwable $e) { $this->setLoader($current); throw $e; } $this->setLoader($current); return $template; } public function isTemplateFresh($name, $time) { if (0 === $this->lastModifiedExtension) { foreach ($this->extensions as $extension) { $r = new ReflectionObject($extension); if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModifiedExtension) { $this->lastModifiedExtension = $extensionTime; } } } return $this->lastModifiedExtension <= $time && $this->getLoader()->isFresh($name, $time); } public function resolveTemplate($names) { if (!is_array($names)) { $names = array($names); } foreach ($names as $name) { if ($name instanceof Twig_Template) { return $name; } try { return $this->loadTemplate($name); } catch (Twig_Error_Loader $e) { } } if (1 === count($names)) { throw $e; } throw new Twig_Error_Loader(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names))); } public function clearTemplateCache() { @trigger_error(sprintf('The %s method is deprecated since version 1.18.3 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED); $this->loadedTemplates = array(); } public function clearCacheFiles() { @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED); if (is_string($this->originalCache)) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->originalCache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) { if ($file->isFile()) { @unlink($file->getPathname()); } } } } public function getLexer() { @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED); if (null === $this->lexer) { $this->lexer = new Twig_Lexer($this); } return $this->lexer; } public function setLexer(Twig_LexerInterface $lexer) { $this->lexer = $lexer; } public function tokenize($source, $name = null) { if (!$source instanceof Twig_Source) { @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED); $source = new Twig_Source($source, $name); } if (null === $this->lexer) { $this->lexer = new Twig_Lexer($this); } return $this->lexer->tokenize($source); } public function getParser() { @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED); if (null === $this->parser) { $this->parser = new Twig_Parser($this); } return $this->parser; } public function setParser(Twig_ParserInterface $parser) { $this->parser = $parser; } public function parse(Twig_TokenStream $stream) { if (null === $this->parser) { $this->parser = new Twig_Parser($this); } return $this->parser->parse($stream); } public function getCompiler() { @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED); if (null === $this->compiler) { $this->compiler = new Twig_Compiler($this); } return $this->compiler; } public function setCompiler(Twig_CompilerInterface $compiler) { $this->compiler = $compiler; } public function compile(Twig_NodeInterface $node) { if (null === $this->compiler) { $this->compiler = new Twig_Compiler($this); } return $this->compiler->compile($node)->getSource(); } public function compileSource($source, $name = null) { if (!$source instanceof Twig_Source) { @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED); $source = new Twig_Source($source, $name); } try { return $this->compile($this->parse($this->tokenize($source))); } catch (Twig_Error $e) { $e->setTemplateName($source->getName()); throw $e; } catch (Exception $e) { throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source->getName(), $e); } } public function setLoader(Twig_LoaderInterface $loader) { if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader),'Mock_Twig_LoaderInterface')) { @trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', get_class($loader)), E_USER_DEPRECATED); } $this->loader = $loader; } public function getLoader() { if (null === $this->loader) { throw new LogicException('You must set a loader first.'); } return $this->loader; } public function setCharset($charset) { $this->charset = strtoupper($charset); } public function getCharset() { return $this->charset; } public function initRuntime() { $this->runtimeInitialized = true; foreach ($this->getExtensions() as $name => $extension) { if (!$extension instanceof Twig_Extension_InitRuntimeInterface) { $m = new ReflectionMethod($extension,'initRuntime'); if ('Twig_Extension'!== $m->getDeclaringClass()->getName()) { @trigger_error(sprintf('Defining the initRuntime() method in the "%s" extension is deprecated since version 1.23. Use the `needs_environment` option to get the Twig_Environment instance in filters, functions, or tests; or explicitly implement Twig_Extension_InitRuntimeInterface if needed (not recommended).', $name), E_USER_DEPRECATED); } } $extension->initRuntime($this); } } public function hasExtension($class) { $class = ltrim($class,'\\'); if (isset($this->extensions[$class])) { if ($class !== get_class($this->extensions[$class])) { @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED); } return true; } return isset($this->extensionsByClass[ltrim($class,'\\')]); } public function addRuntimeLoader(Twig_RuntimeLoaderInterface $loader) { $this->runtimeLoaders[] = $loader; } public function getExtension($class) { $class = ltrim($class,'\\'); if (isset($this->extensions[$class])) { if ($class !== get_class($this->extensions[$class])) { @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED); } return $this->extensions[$class]; } if (!isset($this->extensionsByClass[$class])) { throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $class)); } return $this->extensionsByClass[$class]; } public function getRuntime($class) { if (isset($this->runtimes[$class])) { return $this->runtimes[$class]; } foreach ($this->runtimeLoaders as $loader) { if (null !== $runtime = $loader->load($class)) { return $this->runtimes[$class] = $runtime; } } throw new Twig_Error_Runtime(sprintf('Unable to load the "%s" runtime.', $class)); } public function addExtension(Twig_ExtensionInterface $extension) { if ($this->extensionInitialized) { throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName())); } $class = get_class($extension); if ($class !== $extension->getName()) { if (isset($this->extensions[$extension->getName()])) { unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]); @trigger_error(sprintf('The possibility to register the same extension twice ("%s") is deprecated since version 1.23 and will be removed in Twig 2.0. Use proper PHP inheritance instead.', $extension->getName()), E_USER_DEPRECATED); } } $this->lastModifiedExtension = 0; $this->extensionsByClass[$class] = $extension; $this->extensions[$extension->getName()] = $extension; $this->updateOptionsHash(); } public function removeExtension($name) { @trigger_error(sprintf('The %s method is deprecated since version 1.12 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED); if ($this->extensionInitialized) { throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name)); } $class = ltrim($name,'\\'); if (isset($this->extensions[$class])) { if ($class !== get_class($this->extensions[$class])) { @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED); } unset($this->extensions[$class]); } unset($this->extensions[$class]); $this->updateOptionsHash(); } public function setExtensions(array $extensions) { foreach ($extensions as $extension) { $this->addExtension($extension); } } public function getExtensions() { return $this->extensions; } public function addTokenParser(Twig_TokenParserInterface $parser) { if ($this->extensionInitialized) { throw new LogicException('Unable to add a token parser as extensions have already been initialized.'); } $this->staging->addTokenParser($parser); } public function getTokenParsers() { if (!$this->extensionInitialized) { $this->initExtensions(); } return $this->parsers; } public function getTags() { $tags = array(); foreach ($this->getTokenParsers()->getParsers() as $parser) { if ($parser instanceof Twig_TokenParserInterface) { $tags[$parser->getTag()] = $parser; } } return $tags; } public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) { if ($this->extensionInitialized) { throw new LogicException('Unable to add a node visitor as extensions have already been initialized.'); } $this->staging->addNodeVisitor($visitor); } public function getNodeVisitors() { if (!$this->extensionInitialized) { $this->initExtensions(); } return $this->visitors; } public function addFilter($name, $filter = null) { if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) { throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter.'); } if ($name instanceof Twig_SimpleFilter) { $filter = $name; $name = $filter->getName(); } else { @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFilter" instead when defining filter "%s".', __METHOD__, $name), E_USER_DEPRECATED); } if ($this->extensionInitialized) { throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name)); } $this->staging->addFilter($name, $filter); } public function getFilter($name) { if (!$this->extensionInitialized) { $this->initExtensions(); } if (isset($this->filters[$name])) { return $this->filters[$name]; } foreach ($this->filters as $pattern => $filter) { $pattern = str_replace('\\*','(.*?)', preg_quote($pattern,'#'), $count); if ($count) { if (preg_match('#^'.$pattern.'$#', $name, $matches)) { array_shift($matches); $filter->setArguments($matches); return $filter; } } } foreach ($this->filterCallbacks as $callback) { if (false !== $filter = call_user_func($callback, $name)) { return $filter; } } return false; } public function registerUndefinedFilterCallback($callable) { $this->filterCallbacks[] = $callable; } public function getFilters() { if (!$this->extensionInitialized) { $this->initExtensions(); } return $this->filters; } public function addTest($name, $test = null) { if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) { throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest.'); } if ($name instanceof Twig_SimpleTest) { $test = $name; $name = $test->getName(); } else { @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleTest" instead when defining test "%s".', __METHOD__, $name), E_USER_DEPRECATED); } if ($this->extensionInitialized) { throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name)); } $this->staging->addTest($name, $test); } public function getTests() { if (!$this->extensionInitialized) { $this->initExtensions(); } return $this->tests; } public function getTest($name) { if (!$this->extensionInitialized) { $this->initExtensions(); } if (isset($this->tests[$name])) { return $this->tests[$name]; } return false; } public function addFunction($name, $function = null) { if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) { throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction.'); } if ($name instanceof Twig_SimpleFunction) { $function = $name; $name = $function->getName(); } else { @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFunction" instead when defining function "%s".', __METHOD__, $name), E_USER_DEPRECATED); } if ($this->extensionInitialized) { throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name)); } $this->staging->addFunction($name, $function); } public function getFunction($name) { if (!$this->extensionInitialized) { $this->initExtensions(); } if (isset($this->functions[$name])) { return $this->functions[$name]; } foreach ($this->functions as $pattern => $function) { $pattern = str_replace('\\*','(.*?)', preg_quote($pattern,'#'), $count); if ($count) { if (preg_match('#^'.$pattern.'$#', $name, $matches)) { array_shift($matches); $function->setArguments($matches); return $function; } } } foreach ($this->functionCallbacks as $callback) { if (false !== $function = call_user_func($callback, $name)) { return $function; } } return false; } public function registerUndefinedFunctionCallback($callable) { $this->functionCallbacks[] = $callable; } public function getFunctions() { if (!$this->extensionInitialized) { $this->initExtensions(); } return $this->functions; } public function addGlobal($name, $value) { if ($this->extensionInitialized || $this->runtimeInitialized) { if (null === $this->globals) { $this->globals = $this->initGlobals(); } if (!array_key_exists($name, $this->globals)) { @trigger_error(sprintf('Registering global variable "%s" at runtime or when the extensions have already been initialized is deprecated since version 1.21.', $name), E_USER_DEPRECATED); } } if ($this->extensionInitialized || $this->runtimeInitialized) { $this->globals[$name] = $value; } else { $this->staging->addGlobal($name, $value); } } public function getGlobals() { if (!$this->runtimeInitialized && !$this->extensionInitialized) { return $this->initGlobals(); } if (null === $this->globals) { $this->globals = $this->initGlobals(); } return $this->globals; } public function mergeGlobals(array $context) { foreach ($this->getGlobals() as $key => $value) { if (!array_key_exists($key, $context)) { $context[$key] = $value; } } return $context; } public function getUnaryOperators() { if (!$this->extensionInitialized) { $this->initExtensions(); } return $this->unaryOperators; } public function getBinaryOperators() { if (!$this->extensionInitialized) { $this->initExtensions(); } return $this->binaryOperators; } public function computeAlternatives($name, $items) { @trigger_error(sprintf('The %s method is deprecated since version 1.23 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED); return Twig_Error_Syntax::computeAlternatives($name, $items); } protected function initGlobals() { $globals = array(); foreach ($this->extensions as $name => $extension) { if (!$extension instanceof Twig_Extension_GlobalsInterface) { $m = new ReflectionMethod($extension,'getGlobals'); if ('Twig_Extension'!== $m->getDeclaringClass()->getName()) { @trigger_error(sprintf('Defining the getGlobals() method in the "%s" extension without explicitly implementing Twig_Extension_GlobalsInterface is deprecated since version 1.23.', $name), E_USER_DEPRECATED); } } $extGlob = $extension->getGlobals(); if (!is_array($extGlob)) { throw new UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', get_class($extension))); } $globals[] = $extGlob; } $globals[] = $this->staging->getGlobals(); return call_user_func_array('array_merge', $globals); } protected function initExtensions() { if ($this->extensionInitialized) { return; } $this->extensionInitialized = true; $this->parsers = new Twig_TokenParserBroker(array(), array(), false); $this->filters = array(); $this->functions = array(); $this->tests = array(); $this->visitors = array(); $this->unaryOperators = array(); $this->binaryOperators = array(); foreach ($this->extensions as $extension) { $this->initExtension($extension); } $this->initExtension($this->staging); } protected function initExtension(Twig_ExtensionInterface $extension) { foreach ($extension->getFilters() as $name => $filter) { if ($filter instanceof Twig_SimpleFilter) { $name = $filter->getName(); } else { @trigger_error(sprintf('Using an instance of "%s" for filter "%s" is deprecated since version 1.21. Use Twig_SimpleFilter instead.', get_class($filter), $name), E_USER_DEPRECATED); } $this->filters[$name] = $filter; } foreach ($extension->getFunctions() as $name => $function) { if ($function instanceof Twig_SimpleFunction) { $name = $function->getName(); } else { @trigger_error(sprintf('Using an instance of "%s" for function "%s" is deprecated since version 1.21. Use Twig_SimpleFunction instead.', get_class($function), $name), E_USER_DEPRECATED); } $this->functions[$name] = $function; } foreach ($extension->getTests() as $name => $test) { if ($test instanceof Twig_SimpleTest) { $name = $test->getName(); } else { @trigger_error(sprintf('Using an instance of "%s" for test "%s" is deprecated since version 1.21. Use Twig_SimpleTest instead.', get_class($test), $name), E_USER_DEPRECATED); } $this->tests[$name] = $test; } foreach ($extension->getTokenParsers() as $parser) { if ($parser instanceof Twig_TokenParserInterface) { $this->parsers->addTokenParser($parser); } elseif ($parser instanceof Twig_TokenParserBrokerInterface) { @trigger_error('Registering a Twig_TokenParserBrokerInterface instance is deprecated since version 1.21.', E_USER_DEPRECATED); $this->parsers->addTokenParserBroker($parser); } else { throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances.'); } } foreach ($extension->getNodeVisitors() as $visitor) { $this->visitors[] = $visitor; } if ($operators = $extension->getOperators()) { if (2 !== count($operators)) { throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension))); } $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]); $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]); } } protected function writeCacheFile($file, $content) { $this->cache->write($file, $content); } private function updateOptionsHash() { $hashParts = array_merge( array_keys($this->extensions), array( (int) function_exists('twig_template_get_attributes'), PHP_MAJOR_VERSION, PHP_MINOR_VERSION, self::VERSION, (int) $this->debug, $this->baseTemplateClass, (int) $this->strictVariables, ) ); $this->optionsHash = implode(':', $hashParts); } } } namespace { interface Twig_ExtensionInterface { public function initRuntime(Twig_Environment $environment); public function getTokenParsers(); public function getNodeVisitors(); public function getFilters(); public function getTests(); public function getFunctions(); public function getOperators(); public function getGlobals(); public function getName(); } } namespace { abstract class Twig_Extension implements Twig_ExtensionInterface { public function initRuntime(Twig_Environment $environment) { } public function getTokenParsers() { return array(); } public function getNodeVisitors() { return array(); } public function getFilters() { return array(); } public function getTests() { return array(); } public function getFunctions() { return array(); } public function getOperators() { return array(); } public function getGlobals() { return array(); } public function getName() { return get_class($this); } } } namespace { if (!defined('ENT_SUBSTITUTE')) { define('ENT_SUBSTITUTE', 0); } class Twig_Extension_Core extends Twig_Extension { protected $dateFormats = array('F j, Y H:i','%d days'); protected $numberFormat = array(0,'.',','); protected $timezone = null; protected $escapers = array(); public function setEscaper($strategy, $callable) { $this->escapers[$strategy] = $callable; } public function getEscapers() { return $this->escapers; } public function setDateFormat($format = null, $dateIntervalFormat = null) { if (null !== $format) { $this->dateFormats[0] = $format; } if (null !== $dateIntervalFormat) { $this->dateFormats[1] = $dateIntervalFormat; } } public function getDateFormat() { return $this->dateFormats; } public function setTimezone($timezone) { $this->timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone); } public function getTimezone() { if (null === $this->timezone) { $this->timezone = new DateTimeZone(date_default_timezone_get()); } return $this->timezone; } public function setNumberFormat($decimal, $decimalPoint, $thousandSep) { $this->numberFormat = array($decimal, $decimalPoint, $thousandSep); } public function getNumberFormat() { return $this->numberFormat; } public function getTokenParsers() { return array( new Twig_TokenParser_For(), new Twig_TokenParser_If(), new Twig_TokenParser_Extends(), new Twig_TokenParser_Include(), new Twig_TokenParser_Block(), new Twig_TokenParser_Use(), new Twig_TokenParser_Filter(), new Twig_TokenParser_Macro(), new Twig_TokenParser_Import(), new Twig_TokenParser_From(), new Twig_TokenParser_Set(), new Twig_TokenParser_Spaceless(), new Twig_TokenParser_Flush(), new Twig_TokenParser_Do(), new Twig_TokenParser_Embed(), new Twig_TokenParser_With(), ); } public function getFilters() { $filters = array( new Twig_SimpleFilter('date','twig_date_format_filter', array('needs_environment'=> true)), new Twig_SimpleFilter('date_modify','twig_date_modify_filter', array('needs_environment'=> true)), new Twig_SimpleFilter('format','sprintf'), new Twig_SimpleFilter('replace','twig_replace_filter'), new Twig_SimpleFilter('number_format','twig_number_format_filter', array('needs_environment'=> true)), new Twig_SimpleFilter('abs','abs'), new Twig_SimpleFilter('round','twig_round'), new Twig_SimpleFilter('url_encode','twig_urlencode_filter'), new Twig_SimpleFilter('json_encode','twig_jsonencode_filter'), new Twig_SimpleFilter('convert_encoding','twig_convert_encoding'), new Twig_SimpleFilter('title','twig_title_string_filter', array('needs_environment'=> true)), new Twig_SimpleFilter('capitalize','twig_capitalize_string_filter', array('needs_environment'=> true)), new Twig_SimpleFilter('upper','strtoupper'), new Twig_SimpleFilter('lower','strtolower'), new Twig_SimpleFilter('striptags','strip_tags'), new Twig_SimpleFilter('trim','trim'), new Twig_SimpleFilter('nl2br','nl2br', array('pre_escape'=>'html','is_safe'=> array('html'))), new Twig_SimpleFilter('join','twig_join_filter'), new Twig_SimpleFilter('split','twig_split_filter', array('needs_environment'=> true)), new Twig_SimpleFilter('sort','twig_sort_filter'), new Twig_SimpleFilter('merge','twig_array_merge'), new Twig_SimpleFilter('batch','twig_array_batch'), new Twig_SimpleFilter('reverse','twig_reverse_filter', array('needs_environment'=> true)), new Twig_SimpleFilter('length','twig_length_filter', array('needs_environment'=> true)), new Twig_SimpleFilter('slice','twig_slice', array('needs_environment'=> true)), new Twig_SimpleFilter('first','twig_first', array('needs_environment'=> true)), new Twig_SimpleFilter('last','twig_last', array('needs_environment'=> true)), new Twig_SimpleFilter('default','_twig_default_filter', array('node_class'=>'Twig_Node_Expression_Filter_Default')), new Twig_SimpleFilter('keys','twig_get_array_keys_filter'), new Twig_SimpleFilter('escape','twig_escape_filter', array('needs_environment'=> true,'is_safe_callback'=>'twig_escape_filter_is_safe')), new Twig_SimpleFilter('e','twig_escape_filter', array('needs_environment'=> true,'is_safe_callback'=>'twig_escape_filter_is_safe')), ); if (function_exists('mb_get_info')) { $filters[] = new Twig_SimpleFilter('upper','twig_upper_filter', array('needs_environment'=> true)); $filters[] = new Twig_SimpleFilter('lower','twig_lower_filter', array('needs_environment'=> true)); } return $filters; } public function getFunctions() { return array( new Twig_SimpleFunction('max','max'), new Twig_SimpleFunction('min','min'), new Twig_SimpleFunction('range','range'), new Twig_SimpleFunction('constant','twig_constant'), new Twig_SimpleFunction('cycle','twig_cycle'), new Twig_SimpleFunction('random','twig_random', array('needs_environment'=> true)), new Twig_SimpleFunction('date','twig_date_converter', array('needs_environment'=> true)), new Twig_SimpleFunction('include','twig_include', array('needs_environment'=> true,'needs_context'=> true,'is_safe'=> array('all'))), new Twig_SimpleFunction('source','twig_source', array('needs_environment'=> true,'is_safe'=> array('all'))), ); } public function getTests() { return array( new Twig_SimpleTest('even', null, array('node_class'=>'Twig_Node_Expression_Test_Even')), new Twig_SimpleTest('odd', null, array('node_class'=>'Twig_Node_Expression_Test_Odd')), new Twig_SimpleTest('defined', null, array('node_class'=>'Twig_Node_Expression_Test_Defined')), new Twig_SimpleTest('sameas', null, array('node_class'=>'Twig_Node_Expression_Test_Sameas','deprecated'=>'1.21','alternative'=>'same as')), new Twig_SimpleTest('same as', null, array('node_class'=>'Twig_Node_Expression_Test_Sameas')), new Twig_SimpleTest('none', null, array('node_class'=>'Twig_Node_Expression_Test_Null')), new Twig_SimpleTest('null', null, array('node_class'=>'Twig_Node_Expression_Test_Null')), new Twig_SimpleTest('divisibleby', null, array('node_class'=>'Twig_Node_Expression_Test_Divisibleby','deprecated'=>'1.21','alternative'=>'divisible by')), new Twig_SimpleTest('divisible by', null, array('node_class'=>'Twig_Node_Expression_Test_Divisibleby')), new Twig_SimpleTest('constant', null, array('node_class'=>'Twig_Node_Expression_Test_Constant')), new Twig_SimpleTest('empty','twig_test_empty'), new Twig_SimpleTest('iterable','twig_test_iterable'), ); } public function getOperators() { return array( array('not'=> array('precedence'=> 50,'class'=>'Twig_Node_Expression_Unary_Not'),'-'=> array('precedence'=> 500,'class'=>'Twig_Node_Expression_Unary_Neg'),'+'=> array('precedence'=> 500,'class'=>'Twig_Node_Expression_Unary_Pos'), ), array('or'=> array('precedence'=> 10,'class'=>'Twig_Node_Expression_Binary_Or','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'and'=> array('precedence'=> 15,'class'=>'Twig_Node_Expression_Binary_And','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'b-or'=> array('precedence'=> 16,'class'=>'Twig_Node_Expression_Binary_BitwiseOr','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'b-xor'=> array('precedence'=> 17,'class'=>'Twig_Node_Expression_Binary_BitwiseXor','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'b-and'=> array('precedence'=> 18,'class'=>'Twig_Node_Expression_Binary_BitwiseAnd','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'=='=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_Equal','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'!='=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_NotEqual','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'<'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_Less','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'>'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_Greater','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'>='=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_GreaterEqual','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'<='=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_LessEqual','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'not in'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_NotIn','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'in'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_In','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'matches'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_Matches','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'starts with'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_StartsWith','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'ends with'=> array('precedence'=> 20,'class'=>'Twig_Node_Expression_Binary_EndsWith','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'..'=> array('precedence'=> 25,'class'=>'Twig_Node_Expression_Binary_Range','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'+'=> array('precedence'=> 30,'class'=>'Twig_Node_Expression_Binary_Add','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'-'=> array('precedence'=> 30,'class'=>'Twig_Node_Expression_Binary_Sub','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'~'=> array('precedence'=> 40,'class'=>'Twig_Node_Expression_Binary_Concat','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'*'=> array('precedence'=> 60,'class'=>'Twig_Node_Expression_Binary_Mul','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'/'=> array('precedence'=> 60,'class'=>'Twig_Node_Expression_Binary_Div','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'//'=> array('precedence'=> 60,'class'=>'Twig_Node_Expression_Binary_FloorDiv','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'%'=> array('precedence'=> 60,'class'=>'Twig_Node_Expression_Binary_Mod','associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'is'=> array('precedence'=> 100,'associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'is not'=> array('precedence'=> 100,'associativity'=> Twig_ExpressionParser::OPERATOR_LEFT),'**'=> array('precedence'=> 200,'class'=>'Twig_Node_Expression_Binary_Power','associativity'=> Twig_ExpressionParser::OPERATOR_RIGHT),'??'=> array('precedence'=> 300,'class'=>'Twig_Node_Expression_NullCoalesce','associativity'=> Twig_ExpressionParser::OPERATOR_RIGHT), ), ); } public function getName() { return'core'; } } function twig_cycle($values, $position) { if (!is_array($values) && !$values instanceof ArrayAccess) { return $values; } return $values[$position % count($values)]; } function twig_random(Twig_Environment $env, $values = null) { if (null === $values) { return mt_rand(); } if (is_int($values) || is_float($values)) { return $values < 0 ? mt_rand($values, 0) : mt_rand(0, $values); } if ($values instanceof Traversable) { $values = iterator_to_array($values); } elseif (is_string($values)) { if (''=== $values) { return''; } if (null !== $charset = $env->getCharset()) { if ('UTF-8'!== $charset) { $values = twig_convert_encoding($values,'UTF-8', $charset); } $values = preg_split('/(?<!^)(?!$)/u', $values); if ('UTF-8'!== $charset) { foreach ($values as $i => $value) { $values[$i] = twig_convert_encoding($value, $charset,'UTF-8'); } } } else { return $values[mt_rand(0, strlen($values) - 1)]; } } if (!is_array($values)) { return $values; } if (0 === count($values)) { throw new Twig_Error_Runtime('The random function cannot pick from an empty array.'); } return $values[array_rand($values, 1)]; } function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null) { if (null === $format) { $formats = $env->getExtension('Twig_Extension_Core')->getDateFormat(); $format = $date instanceof DateInterval ? $formats[1] : $formats[0]; } if ($date instanceof DateInterval) { return $date->format($format); } return twig_date_converter($env, $date, $timezone)->format($format); } function twig_date_modify_filter(Twig_Environment $env, $date, $modifier) { $date = twig_date_converter($env, $date, false); $resultDate = $date->modify($modifier); return null === $resultDate ? $date : $resultDate; } function twig_date_converter(Twig_Environment $env, $date = null, $timezone = null) { if (false !== $timezone) { if (null === $timezone) { $timezone = $env->getExtension('Twig_Extension_Core')->getTimezone(); } elseif (!$timezone instanceof DateTimeZone) { $timezone = new DateTimeZone($timezone); } } if ($date instanceof DateTimeImmutable) { return false !== $timezone ? $date->setTimezone($timezone) : $date; } if ($date instanceof DateTime || $date instanceof DateTimeInterface) { $date = clone $date; if (false !== $timezone) { $date->setTimezone($timezone); } return $date; } if (null === $date ||'now'=== $date) { return new DateTime($date, false !== $timezone ? $timezone : $env->getExtension('Twig_Extension_Core')->getTimezone()); } $asString = (string) $date; if (ctype_digit($asString) || (!empty($asString) &&'-'=== $asString[0] && ctype_digit(substr($asString, 1)))) { $date = new DateTime('@'.$date); } else { $date = new DateTime($date, $env->getExtension('Twig_Extension_Core')->getTimezone()); } if (false !== $timezone) { $date->setTimezone($timezone); } return $date; } function twig_replace_filter($str, $from, $to = null) { if ($from instanceof Traversable) { $from = iterator_to_array($from); } elseif (is_string($from) && is_string($to)) { @trigger_error('Using "replace" with character by character replacement is deprecated since version 1.22 and will be removed in Twig 2.0', E_USER_DEPRECATED); return strtr($str, $from, $to); } elseif (!is_array($from)) { throw new Twig_Error_Runtime(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', is_object($from) ? get_class($from) : gettype($from))); } return strtr($str, $from); } function twig_round($value, $precision = 0, $method ='common') { if ('common'== $method) { return round($value, $precision); } if ('ceil'!= $method &&'floor'!= $method) { throw new Twig_Error_Runtime('The round filter only supports the "common", "ceil", and "floor" methods.'); } return $method($value * pow(10, $precision)) / pow(10, $precision); } function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null) { $defaults = $env->getExtension('Twig_Extension_Core')->getNumberFormat(); if (null === $decimal) { $decimal = $defaults[0]; } if (null === $decimalPoint) { $decimalPoint = $defaults[1]; } if (null === $thousandSep) { $thousandSep = $defaults[2]; } return number_format((float) $number, $decimal, $decimalPoint, $thousandSep); } function twig_urlencode_filter($url) { if (is_array($url)) { if (defined('PHP_QUERY_RFC3986')) { return http_build_query($url,'','&', PHP_QUERY_RFC3986); } return http_build_query($url,'','&'); } return rawurlencode($url); } if (PHP_VERSION_ID < 50300) { function twig_jsonencode_filter($value, $options = 0) { if ($value instanceof Twig_Markup) { $value = (string) $value; } elseif (is_array($value)) { array_walk_recursive($value,'_twig_markup2string'); } return json_encode($value); } } else { function twig_jsonencode_filter($value, $options = 0) { if ($value instanceof Twig_Markup) { $value = (string) $value; } elseif (is_array($value)) { array_walk_recursive($value,'_twig_markup2string'); } return json_encode($value, $options); } } function _twig_markup2string(&$value) { if ($value instanceof Twig_Markup) { $value = (string) $value; } } function twig_array_merge($arr1, $arr2) { if ($arr1 instanceof Traversable) { $arr1 = iterator_to_array($arr1); } elseif (!is_array($arr1)) { throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as first argument.', gettype($arr1))); } if ($arr2 instanceof Traversable) { $arr2 = iterator_to_array($arr2); } elseif (!is_array($arr2)) { throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as second argument.', gettype($arr2))); } return array_merge($arr1, $arr2); } function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false) { if ($item instanceof Traversable) { if ($item instanceof IteratorAggregate) { $item = $item->getIterator(); } if ($start >= 0 && $length >= 0 && $item instanceof Iterator) { try { return iterator_to_array(new LimitIterator($item, $start, $length === null ? -1 : $length), $preserveKeys); } catch (OutOfBoundsException $exception) { return array(); } } $item = iterator_to_array($item, $preserveKeys); } if (is_array($item)) { return array_slice($item, $start, $length, $preserveKeys); } $item = (string) $item; if (function_exists('mb_get_info') && null !== $charset = $env->getCharset()) { return (string) mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset); } return (string) (null === $length ? substr($item, $start) : substr($item, $start, $length)); } function twig_first(Twig_Environment $env, $item) { $elements = twig_slice($env, $item, 0, 1, false); return is_string($elements) ? $elements : current($elements); } function twig_last(Twig_Environment $env, $item) { $elements = twig_slice($env, $item, -1, 1, false); return is_string($elements) ? $elements : current($elements); } function twig_join_filter($value, $glue ='') { if ($value instanceof Traversable) { $value = iterator_to_array($value, false); } return implode($glue, (array) $value); } function twig_split_filter(Twig_Environment $env, $value, $delimiter, $limit = null) { if (!empty($delimiter)) { return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit); } if (!function_exists('mb_get_info') || null === $charset = $env->getCharset()) { return str_split($value, null === $limit ? 1 : $limit); } if ($limit <= 1) { return preg_split('/(?<!^)(?!$)/u', $value); } $length = mb_strlen($value, $charset); if ($length < $limit) { return array($value); } $r = array(); for ($i = 0; $i < $length; $i += $limit) { $r[] = mb_substr($value, $i, $limit, $charset); } return $r; } function _twig_default_filter($value, $default ='') { if (twig_test_empty($value)) { return $default; } return $value; } function twig_get_array_keys_filter($array) { if ($array instanceof Traversable) { return array_keys(iterator_to_array($array)); } if (!is_array($array)) { return array(); } return array_keys($array); } function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false) { if ($item instanceof Traversable) { return array_reverse(iterator_to_array($item), $preserveKeys); } if (is_array($item)) { return array_reverse($item, $preserveKeys); } if (null !== $charset = $env->getCharset()) { $string = (string) $item; if ('UTF-8'!== $charset) { $item = twig_convert_encoding($string,'UTF-8', $charset); } preg_match_all('/./us', $item, $matches); $string = implode('', array_reverse($matches[0])); if ('UTF-8'!== $charset) { $string = twig_convert_encoding($string, $charset,'UTF-8'); } return $string; } return strrev((string) $item); } function twig_sort_filter($array) { if ($array instanceof Traversable) { $array = iterator_to_array($array); } elseif (!is_array($array)) { throw new Twig_Error_Runtime(sprintf('The sort filter only works with arrays or "Traversable", got "%s".', gettype($array))); } asort($array); return $array; } function twig_in_filter($value, $compare) { if (is_array($compare)) { return in_array($value, $compare, is_object($value) || is_resource($value)); } elseif (is_string($compare) && (is_string($value) || is_int($value) || is_float($value))) { return''=== $value || false !== strpos($compare, (string) $value); } elseif ($compare instanceof Traversable) { return in_array($value, iterator_to_array($compare, false), is_object($value) || is_resource($value)); } return false; } function twig_escape_filter(Twig_Environment $env, $string, $strategy ='html', $charset = null, $autoescape = false) { if ($autoescape && $string instanceof Twig_Markup) { return $string; } if (!is_string($string)) { if (is_object($string) && method_exists($string,'__toString')) { $string = (string) $string; } elseif (in_array($strategy, array('html','js','css','html_attr','url'))) { return $string; } } if (null === $charset) { $charset = $env->getCharset(); } switch ($strategy) { case'html': static $htmlspecialcharsCharsets; if (null === $htmlspecialcharsCharsets) { if (defined('HHVM_VERSION')) { $htmlspecialcharsCharsets = array('utf-8'=> true,'UTF-8'=> true); } else { $htmlspecialcharsCharsets = array('ISO-8859-1'=> true,'ISO8859-1'=> true,'ISO-8859-15'=> true,'ISO8859-15'=> true,'utf-8'=> true,'UTF-8'=> true,'CP866'=> true,'IBM866'=> true,'866'=> true,'CP1251'=> true,'WINDOWS-1251'=> true,'WIN-1251'=> true,'1251'=> true,'CP1252'=> true,'WINDOWS-1252'=> true,'1252'=> true,'KOI8-R'=> true,'KOI8-RU'=> true,'KOI8R'=> true,'BIG5'=> true,'950'=> true,'GB2312'=> true,'936'=> true,'BIG5-HKSCS'=> true,'SHIFT_JIS'=> true,'SJIS'=> true,'932'=> true,'EUC-JP'=> true,'EUCJP'=> true,'ISO8859-5'=> true,'ISO-8859-5'=> true,'MACROMAN'=> true, ); } } if (isset($htmlspecialcharsCharsets[$charset])) { return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset); } if (isset($htmlspecialcharsCharsets[strtoupper($charset)])) { $htmlspecialcharsCharsets[$charset] = true; return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset); } $string = twig_convert_encoding($string,'UTF-8', $charset); $string = htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE,'UTF-8'); return twig_convert_encoding($string, $charset,'UTF-8'); case'js': if ('UTF-8'!== $charset) { $string = twig_convert_encoding($string,'UTF-8', $charset); } if (0 == strlen($string) ? false : 1 !== preg_match('/^./su', $string)) { throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); } $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su','_twig_escape_js_callback', $string); if ('UTF-8'!== $charset) { $string = twig_convert_encoding($string, $charset,'UTF-8'); } return $string; case'css': if ('UTF-8'!== $charset) { $string = twig_convert_encoding($string,'UTF-8', $charset); } if (0 == strlen($string) ? false : 1 !== preg_match('/^./su', $string)) { throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); } $string = preg_replace_callback('#[^a-zA-Z0-9]#Su','_twig_escape_css_callback', $string); if ('UTF-8'!== $charset) { $string = twig_convert_encoding($string, $charset,'UTF-8'); } return $string; case'html_attr': if ('UTF-8'!== $charset) { $string = twig_convert_encoding($string,'UTF-8', $charset); } if (0 == strlen($string) ? false : 1 !== preg_match('/^./su', $string)) { throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); } $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su','_twig_escape_html_attr_callback', $string); if ('UTF-8'!== $charset) { $string = twig_convert_encoding($string, $charset,'UTF-8'); } return $string; case'url': if (PHP_VERSION_ID < 50300) { return str_replace('%7E','~', rawurlencode($string)); } return rawurlencode($string); default: static $escapers; if (null === $escapers) { $escapers = $env->getExtension('Twig_Extension_Core')->getEscapers(); } if (isset($escapers[$strategy])) { return call_user_func($escapers[$strategy], $env, $string, $charset); } $validStrategies = implode(', ', array_merge(array('html','js','url','css','html_attr'), array_keys($escapers))); throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies)); } } function twig_escape_filter_is_safe(Twig_Node $filterArgs) { foreach ($filterArgs as $arg) { if ($arg instanceof Twig_Node_Expression_Constant) { return array($arg->getAttribute('value')); } return array(); } return array('html'); } if (function_exists('mb_convert_encoding')) { function twig_convert_encoding($string, $to, $from) { return mb_convert_encoding($string, $to, $from); } } elseif (function_exists('iconv')) { function twig_convert_encoding($string, $to, $from) { return iconv($from, $to, $string); } } else { function twig_convert_encoding($string, $to, $from) { throw new Twig_Error_Runtime('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).'); } } function _twig_escape_js_callback($matches) { $char = $matches[0]; if (!isset($char[1])) { return'\\x'.strtoupper(substr('00'.bin2hex($char), -2)); } $char = twig_convert_encoding($char,'UTF-16BE','UTF-8'); return'\\u'.strtoupper(substr('0000'.bin2hex($char), -4)); } function _twig_escape_css_callback($matches) { $char = $matches[0]; if (!isset($char[1])) { $hex = ltrim(strtoupper(bin2hex($char)),'0'); if (0 === strlen($hex)) { $hex ='0'; } return'\\'.$hex.' '; } $char = twig_convert_encoding($char,'UTF-16BE','UTF-8'); return'\\'.ltrim(strtoupper(bin2hex($char)),'0').' '; } function _twig_escape_html_attr_callback($matches) { static $entityMap = array( 34 =>'quot', 38 =>'amp', 60 =>'lt', 62 =>'gt', ); $chr = $matches[0]; $ord = ord($chr); if (($ord <= 0x1f && $chr !="\t"&& $chr !="\n"&& $chr !="\r") || ($ord >= 0x7f && $ord <= 0x9f)) { return'&#xFFFD;'; } if (strlen($chr) == 1) { $hex = strtoupper(substr('00'.bin2hex($chr), -2)); } else { $chr = twig_convert_encoding($chr,'UTF-16BE','UTF-8'); $hex = strtoupper(substr('0000'.bin2hex($chr), -4)); } $int = hexdec($hex); if (array_key_exists($int, $entityMap)) { return sprintf('&%s;', $entityMap[$int]); } return sprintf('&#x%s;', $hex); } if (function_exists('mb_get_info')) { function twig_length_filter(Twig_Environment $env, $thing) { return is_scalar($thing) ? mb_strlen($thing, $env->getCharset()) : count($thing); } function twig_upper_filter(Twig_Environment $env, $string) { if (null !== $charset = $env->getCharset()) { return mb_strtoupper($string, $charset); } return strtoupper($string); } function twig_lower_filter(Twig_Environment $env, $string) { if (null !== $charset = $env->getCharset()) { return mb_strtolower($string, $charset); } return strtolower($string); } function twig_title_string_filter(Twig_Environment $env, $string) { if (null !== $charset = $env->getCharset()) { return mb_convert_case($string, MB_CASE_TITLE, $charset); } return ucwords(strtolower($string)); } function twig_capitalize_string_filter(Twig_Environment $env, $string) { if (null !== $charset = $env->getCharset()) { return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset); } return ucfirst(strtolower($string)); } } else { function twig_length_filter(Twig_Environment $env, $thing) { return is_scalar($thing) ? strlen($thing) : count($thing); } function twig_title_string_filter(Twig_Environment $env, $string) { return ucwords(strtolower($string)); } function twig_capitalize_string_filter(Twig_Environment $env, $string) { return ucfirst(strtolower($string)); } } function twig_ensure_traversable($seq) { if ($seq instanceof Traversable || is_array($seq)) { return $seq; } return array(); } function twig_test_empty($value) { if ($value instanceof Countable) { return 0 == count($value); } return''=== $value || false === $value || null === $value || array() === $value; } function twig_test_iterable($value) { return $value instanceof Traversable || is_array($value); } function twig_include(Twig_Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false) { $alreadySandboxed = false; $sandbox = null; if ($withContext) { $variables = array_merge($context, $variables); } if ($isSandboxed = $sandboxed && $env->hasExtension('Twig_Extension_Sandbox')) { $sandbox = $env->getExtension('Twig_Extension_Sandbox'); if (!$alreadySandboxed = $sandbox->isSandboxed()) { $sandbox->enableSandbox(); } } $result = null; try { $result = $env->resolveTemplate($template)->render($variables); } catch (Twig_Error_Loader $e) { if (!$ignoreMissing) { if ($isSandboxed && !$alreadySandboxed) { $sandbox->disableSandbox(); } throw $e; } } if ($isSandboxed && !$alreadySandboxed) { $sandbox->disableSandbox(); } return $result; } function twig_source(Twig_Environment $env, $name, $ignoreMissing = false) { $loader = $env->getLoader(); try { if (!$loader instanceof Twig_SourceContextLoaderInterface) { return $loader->getSource($name); } else { return $loader->getSourceContext($name)->getCode(); } } catch (Twig_Error_Loader $e) { if (!$ignoreMissing) { throw $e; } } } function twig_constant($constant, $object = null) { if (null !== $object) { $constant = get_class($object).'::'.$constant; } return constant($constant); } function twig_constant_is_defined($constant, $object = null) { if (null !== $object) { $constant = get_class($object).'::'.$constant; } return defined($constant); } function twig_array_batch($items, $size, $fill = null) { if ($items instanceof Traversable) { $items = iterator_to_array($items, false); } $size = ceil($size); $result = array_chunk($items, $size, true); if (null !== $fill && !empty($result)) { $last = count($result) - 1; if ($fillCount = $size - count($result[$last])) { $result[$last] = array_merge( $result[$last], array_fill(0, $fillCount, $fill) ); } } return $result; } } namespace { class Twig_Extension_Escaper extends Twig_Extension { protected $defaultStrategy; public function __construct($defaultStrategy ='html') { $this->setDefaultStrategy($defaultStrategy); } public function getTokenParsers() { return array(new Twig_TokenParser_AutoEscape()); } public function getNodeVisitors() { return array(new Twig_NodeVisitor_Escaper()); } public function getFilters() { return array( new Twig_SimpleFilter('raw','twig_raw_filter', array('is_safe'=> array('all'))), ); } public function setDefaultStrategy($defaultStrategy) { if (true === $defaultStrategy) { @trigger_error('Using "true" as the default strategy is deprecated since version 1.21. Use "html" instead.', E_USER_DEPRECATED); $defaultStrategy ='html'; } if ('filename'=== $defaultStrategy) { @trigger_error('Using "filename" as the default strategy is deprecated since version 1.27. Use "name" instead.', E_USER_DEPRECATED); $defaultStrategy ='name'; } if ('name'=== $defaultStrategy) { $defaultStrategy = array('Twig_FileExtensionEscapingStrategy','guess'); } $this->defaultStrategy = $defaultStrategy; } public function getDefaultStrategy($name) { if (!is_string($this->defaultStrategy) && false !== $this->defaultStrategy) { return call_user_func($this->defaultStrategy, $name); } return $this->defaultStrategy; } public function getName() { return'escaper'; } } function twig_raw_filter($string) { return $string; } } namespace { class Twig_Extension_Optimizer extends Twig_Extension { protected $optimizers; public function __construct($optimizers = -1) { $this->optimizers = $optimizers; } public function getNodeVisitors() { return array(new Twig_NodeVisitor_Optimizer($this->optimizers)); } public function getName() { return'optimizer'; } } } namespace { interface Twig_LoaderInterface { public function getSource($name); public function getCacheKey($name); public function isFresh($name, $time); } } namespace { class Twig_Markup implements Countable { protected $content; protected $charset; public function __construct($content, $charset) { $this->content = (string) $content; $this->charset = $charset; } public function __toString() { return $this->content; } public function count() { return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content); } } } namespace { interface Twig_TemplateInterface { const ANY_CALL ='any'; const ARRAY_CALL ='array'; const METHOD_CALL ='method'; public function render(array $context); public function display(array $context, array $blocks = array()); public function getEnvironment(); } } namespace { abstract class Twig_Template implements Twig_TemplateInterface { protected static $cache = array(); protected $parent; protected $parents = array(); protected $env; protected $blocks = array(); protected $traits = array(); public function __construct(Twig_Environment $env) { $this->env = $env; } abstract public function getTemplateName(); public function getDebugInfo() { return array(); } public function getSource() { @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED); return''; } public function getSourceContext() { return new Twig_Source('', $this->getTemplateName()); } public function getEnvironment() { @trigger_error('The '.__METHOD__.' method is deprecated since version 1.20 and will be removed in 2.0.', E_USER_DEPRECATED); return $this->env; } public function getParent(array $context) { if (null !== $this->parent) { return $this->parent; } try { $parent = $this->doGetParent($context); if (false === $parent) { return false; } if ($parent instanceof self) { return $this->parents[$parent->getTemplateName()] = $parent; } if (!isset($this->parents[$parent])) { $this->parents[$parent] = $this->loadTemplate($parent); } } catch (Twig_Error_Loader $e) { $e->setTemplateName(null); $e->guess(); throw $e; } return $this->parents[$parent]; } protected function doGetParent(array $context) { return false; } public function isTraitable() { return true; } public function displayParentBlock($name, array $context, array $blocks = array()) { $name = (string) $name; if (isset($this->traits[$name])) { $this->traits[$name][0]->displayBlock($name, $context, $blocks, false); } elseif (false !== $parent = $this->getParent($context)) { $parent->displayBlock($name, $context, $blocks, false); } else { throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getTemplateName()); } } public function displayBlock($name, array $context, array $blocks = array(), $useBlocks = true) { $name = (string) $name; if ($useBlocks && isset($blocks[$name])) { $template = $blocks[$name][0]; $block = $blocks[$name][1]; } elseif (isset($this->blocks[$name])) { $template = $this->blocks[$name][0]; $block = $this->blocks[$name][1]; } else { $template = null; $block = null; } if (null !== $template) { if (!$template instanceof self) { throw new LogicException('A block must be a method on a Twig_Template instance.'); } try { $template->$block($context, $blocks); } catch (Twig_Error $e) { if (!$e->getTemplateName()) { $e->setTemplateName($template->getTemplateName()); } if (false === $e->getTemplateLine()) { $e->setTemplateLine(-1); $e->guess(); } throw $e; } catch (Exception $e) { throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getTemplateName(), $e); } } elseif (false !== $parent = $this->getParent($context)) { $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false); } } public function renderParentBlock($name, array $context, array $blocks = array()) { ob_start(); $this->displayParentBlock($name, $context, $blocks); return ob_get_clean(); } public function renderBlock($name, array $context, array $blocks = array(), $useBlocks = true) { ob_start(); $this->displayBlock($name, $context, $blocks, $useBlocks); return ob_get_clean(); } public function hasBlock($name, array $context = null, array $blocks = array()) { if (null === $context) { @trigger_error('The '.__METHOD__.' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', E_USER_DEPRECATED); return isset($this->blocks[(string) $name]); } if (isset($blocks[$name])) { return $blocks[$name][0] instanceof self; } if (isset($this->blocks[$name])) { return true; } if (false !== $parent = $this->getParent($context)) { return $parent->hasBlock($name, $context); } return false; } public function getBlockNames(array $context = null, array $blocks = array()) { if (null === $context) { @trigger_error('The '.__METHOD__.' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', E_USER_DEPRECATED); return array_keys($this->blocks); } $names = array_merge(array_keys($blocks), array_keys($this->blocks)); if (false !== $parent = $this->getParent($context)) { $names = array_merge($names, $parent->getBlockNames($context)); } return array_unique($names); } protected function loadTemplate($template, $templateName = null, $line = null, $index = null) { try { if (is_array($template)) { return $this->env->resolveTemplate($template); } if ($template instanceof self) { return $template; } if ($template instanceof Twig_TemplateWrapper) { return $template; } return $this->env->loadTemplate($template, $index); } catch (Twig_Error $e) { if (!$e->getTemplateName()) { $e->setTemplateName($templateName ? $templateName : $this->getTemplateName()); } if ($e->getTemplateLine()) { throw $e; } if (!$line) { $e->guess(); } else { $e->setTemplateLine($line); } throw $e; } } public function getBlocks() { return $this->blocks; } public function display(array $context, array $blocks = array()) { $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks)); } public function render(array $context) { $level = ob_get_level(); ob_start(); try { $this->display($context); } catch (Exception $e) { while (ob_get_level() > $level) { ob_end_clean(); } throw $e; } catch (Throwable $e) { while (ob_get_level() > $level) { ob_end_clean(); } throw $e; } return ob_get_clean(); } protected function displayWithErrorHandling(array $context, array $blocks = array()) { try { $this->doDisplay($context, $blocks); } catch (Twig_Error $e) { if (!$e->getTemplateName()) { $e->setTemplateName($this->getTemplateName()); } if (false === $e->getTemplateLine()) { $e->setTemplateLine(-1); $e->guess(); } throw $e; } catch (Exception $e) { throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getTemplateName(), $e); } } abstract protected function doDisplay(array $context, array $blocks = array()); final protected function getContext($context, $item, $ignoreStrictCheck = false) { if (!array_key_exists($item, $context)) { if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { return; } throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist.', $item), -1, $this->getTemplateName()); } return $context[$item]; } protected function getAttribute($object, $item, array $arguments = array(), $type = self::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false) { if (self::METHOD_CALL !== $type) { $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item; if ((is_array($object) && (isset($object[$arrayItem]) || array_key_exists($arrayItem, $object))) || ($object instanceof ArrayAccess && isset($object[$arrayItem])) ) { if ($isDefinedTest) { return true; } return $object[$arrayItem]; } if (self::ARRAY_CALL === $type || !is_object($object)) { if ($isDefinedTest) { return false; } if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { return; } if ($object instanceof ArrayAccess) { $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist.', $arrayItem, get_class($object)); } elseif (is_object($object)) { $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, get_class($object)); } elseif (is_array($object)) { if (empty($object)) { $message = sprintf('Key "%s" does not exist as the array is empty.', $arrayItem); } else { $message = sprintf('Key "%s" for array with keys "%s" does not exist.', $arrayItem, implode(', ', array_keys($object))); } } elseif (self::ARRAY_CALL === $type) { if (null === $object) { $message = sprintf('Impossible to access a key ("%s") on a null variable.', $item); } else { $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, gettype($object), $object); } } elseif (null === $object) { $message = sprintf('Impossible to access an attribute ("%s") on a null variable.', $item); } else { $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, gettype($object), $object); } throw new Twig_Error_Runtime($message, -1, $this->getTemplateName()); } } if (!is_object($object)) { if ($isDefinedTest) { return false; } if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { return; } if (null === $object) { $message = sprintf('Impossible to invoke a method ("%s") on a null variable.', $item); } else { $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, gettype($object), $object); } throw new Twig_Error_Runtime($message, -1, $this->getTemplateName()); } if (self::METHOD_CALL !== $type && !$object instanceof self) { if (isset($object->$item) || array_key_exists((string) $item, $object)) { if ($isDefinedTest) { return true; } if ($this->env->hasExtension('Twig_Extension_Sandbox')) { $this->env->getExtension('Twig_Extension_Sandbox')->checkPropertyAllowed($object, $item); } return $object->$item; } } $class = get_class($object); if (!isset(self::$cache[$class])) { if ($object instanceof self) { $ref = new ReflectionClass($class); $methods = array(); foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $refMethod) { if ('getenvironment'!== strtolower($refMethod->name)) { $methods[] = $refMethod->name; } } } else { $methods = get_class_methods($object); } $cache = array(); foreach ($methods as $method) { $cache[$method] = $method; $cache[$lcName = strtolower($method)] = $method; if ('g'=== $lcName[0] && 0 === strpos($lcName,'get')) { $name = substr($method, 3); $lcName = substr($lcName, 3); } elseif ('i'=== $lcName[0] && 0 === strpos($lcName,'is')) { $name = substr($method, 2); $lcName = substr($lcName, 2); } else { continue; } if (!isset($cache[$name])) { $cache[$name] = $method; } if (!isset($cache[$lcName])) { $cache[$lcName] = $method; } } self::$cache[$class] = $cache; } $call = false; if (isset(self::$cache[$class][$item])) { $method = self::$cache[$class][$item]; } elseif (isset(self::$cache[$class][$lcItem = strtolower($item)])) { $method = self::$cache[$class][$lcItem]; } elseif (isset(self::$cache[$class]['__call'])) { $method = $item; $call = true; } else { if ($isDefinedTest) { return false; } if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { return; } throw new Twig_Error_Runtime(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s".', $item, $class), -1, $this->getTemplateName()); } if ($isDefinedTest) { return true; } if ($this->env->hasExtension('Twig_Extension_Sandbox')) { $this->env->getExtension('Twig_Extension_Sandbox')->checkMethodAllowed($object, $method); } try { if (!$arguments) { $ret = $object->$method(); } else { $ret = call_user_func_array(array($object, $method), $arguments); } } catch (BadMethodCallException $e) { if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) { return; } throw $e; } if ($object instanceof Twig_TemplateInterface) { @trigger_error('Using the dot notation on an instance of '.__CLASS__.' is deprecated since version 1.28 and won\'t be supported anymore in 2.0.', E_USER_DEPRECATED); return $ret ===''?'': new Twig_Markup($ret, $this->env->getCharset()); } return $ret; } } } namespace Monolog\Formatter { interface FormatterInterface { public function format(array $record); public function formatBatch(array $records); } } namespace Monolog\Formatter { use Exception; use Monolog\Utils; class NormalizerFormatter implements FormatterInterface { const SIMPLE_DATE ="Y-m-d H:i:s"; protected $dateFormat; protected $maxDepth; public function __construct($dateFormat = null, $maxDepth = 9) { $this->dateFormat = $dateFormat ?: static::SIMPLE_DATE; $this->maxDepth = $maxDepth; if (!function_exists('json_encode')) { throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s NormalizerFormatter'); } } public function format(array $record) { return $this->normalize($record); } public function formatBatch(array $records) { foreach ($records as $key => $record) { $records[$key] = $this->format($record); } return $records; } public function getMaxDepth() { return $this->maxDepth; } public function setMaxDepth($maxDepth) { $this->maxDepth = $maxDepth; } protected function normalize($data, $depth = 0) { if ($depth > $this->maxDepth) { return'Over '.$this->maxDepth.' levels deep, aborting normalization'; } if (null === $data || is_scalar($data)) { if (is_float($data)) { if (is_infinite($data)) { return ($data > 0 ?'':'-') .'INF'; } if (is_nan($data)) { return'NaN'; } } return $data; } if (is_array($data)) { $normalized = array(); $count = 1; foreach ($data as $key => $value) { if ($count++ > 1000) { $normalized['...'] ='Over 1000 items ('.count($data).' total), aborting normalization'; break; } $normalized[$key] = $this->normalize($value, $depth+1); } return $normalized; } if ($data instanceof \DateTime) { return $data->format($this->dateFormat); } if (is_object($data)) { if ($data instanceof Exception || (PHP_VERSION_ID > 70000 && $data instanceof \Throwable)) { return $this->normalizeException($data); } if (method_exists($data,'__toString') && !$data instanceof \JsonSerializable) { $value = $data->__toString(); } else { $value = $this->toJson($data, true); } return sprintf("[object] (%s: %s)", Utils::getClass($data), $value); } if (is_resource($data)) { return sprintf('[resource] (%s)', get_resource_type($data)); } return'[unknown('.gettype($data).')]'; } protected function normalizeException($e) { if (!$e instanceof Exception && !$e instanceof \Throwable) { throw new \InvalidArgumentException('Exception/Throwable expected, got '.gettype($e).' / '.Utils::getClass($e)); } $data = array('class'=> Utils::getClass($e),'message'=> $e->getMessage(),'code'=> (int) $e->getCode(),'file'=> $e->getFile().':'.$e->getLine(), ); if ($e instanceof \SoapFault) { if (isset($e->faultcode)) { $data['faultcode'] = $e->faultcode; } if (isset($e->faultactor)) { $data['faultactor'] = $e->faultactor; } if (isset($e->detail)) { if (is_string($e->detail)) { $data['detail'] = $e->detail; } elseif (is_object($e->detail) || is_array($e->detail)) { $data['detail'] = $this->toJson($e->detail, true); } } } $trace = $e->getTrace(); foreach ($trace as $frame) { if (isset($frame['file'])) { $data['trace'][] = $frame['file'].':'.$frame['line']; } } if ($previous = $e->getPrevious()) { $data['previous'] = $this->normalizeException($previous); } return $data; } protected function toJson($data, $ignoreErrors = false) { return Utils::jsonEncode($data, null, $ignoreErrors); } }} namespace Monolog\Formatter { use Monolog\Utils; class LineFormatter extends NormalizerFormatter { const SIMPLE_FORMAT ="[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"; protected $format; protected $allowInlineLineBreaks; protected $ignoreEmptyContextAndExtra; protected $includeStacktraces; public function __construct($format = null, $dateFormat = null, $allowInlineLineBreaks = false, $ignoreEmptyContextAndExtra = false) { $this->format = $format ?: static::SIMPLE_FORMAT; $this->allowInlineLineBreaks = $allowInlineLineBreaks; $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra; parent::__construct($dateFormat); } public function includeStacktraces($include = true) { $this->includeStacktraces = $include; if ($this->includeStacktraces) { $this->allowInlineLineBreaks = true; } } public function allowInlineLineBreaks($allow = true) { $this->allowInlineLineBreaks = $allow; } public function ignoreEmptyContextAndExtra($ignore = true) { $this->ignoreEmptyContextAndExtra = $ignore; } public function format(array $record) { $vars = parent::format($record); $output = $this->format; foreach ($vars['extra'] as $var => $val) { if (false !== strpos($output,'%extra.'.$var.'%')) { $output = str_replace('%extra.'.$var.'%', $this->stringify($val), $output); unset($vars['extra'][$var]); } } foreach ($vars['context'] as $var => $val) { if (false !== strpos($output,'%context.'.$var.'%')) { $output = str_replace('%context.'.$var.'%', $this->stringify($val), $output); unset($vars['context'][$var]); } } if ($this->ignoreEmptyContextAndExtra) { if (empty($vars['context'])) { unset($vars['context']); $output = str_replace('%context%','', $output); } if (empty($vars['extra'])) { unset($vars['extra']); $output = str_replace('%extra%','', $output); } } foreach ($vars as $var => $val) { if (false !== strpos($output,'%'.$var.'%')) { $output = str_replace('%'.$var.'%', $this->stringify($val), $output); } } if (false !== strpos($output,'%')) { $output = preg_replace('/%(?:extra|context)\..+?%/','', $output); } return $output; } public function formatBatch(array $records) { $message =''; foreach ($records as $record) { $message .= $this->format($record); } return $message; } public function stringify($value) { return $this->replaceNewlines($this->convertToString($value)); } protected function normalizeException($e) { if (!$e instanceof \Exception && !$e instanceof \Throwable) { throw new \InvalidArgumentException('Exception/Throwable expected, got '.gettype($e).' / '.Utils::getClass($e)); } $previousText =''; if ($previous = $e->getPrevious()) { do { $previousText .=', '.Utils::getClass($previous).'(code: '.$previous->getCode().'): '.$previous->getMessage().' at '.$previous->getFile().':'.$previous->getLine(); } while ($previous = $previous->getPrevious()); } $str ='[object] ('.Utils::getClass($e).'(code: '.$e->getCode().'): '.$e->getMessage().' at '.$e->getFile().':'.$e->getLine().$previousText.')'; if ($this->includeStacktraces) { $str .="\n[stacktrace]\n".$e->getTraceAsString()."\n"; } return $str; } protected function convertToString($data) { if (null === $data || is_bool($data)) { return var_export($data, true); } if (is_scalar($data)) { return (string) $data; } if (version_compare(PHP_VERSION,'5.4.0','>=')) { return $this->toJson($data, true); } return str_replace('\\/','/', $this->toJson($data, true)); } protected function replaceNewlines($str) { if ($this->allowInlineLineBreaks) { if (0 === strpos($str,'{')) { return str_replace(array('\r','\n'), array("\r","\n"), $str); } return $str; } return str_replace(array("\r\n","\r","\n"),' ', $str); } } } namespace Monolog\Handler { use Monolog\Formatter\FormatterInterface; interface HandlerInterface { public function isHandling(array $record); public function handle(array $record); public function handleBatch(array $records); public function pushProcessor($callback); public function popProcessor(); public function setFormatter(FormatterInterface $formatter); public function getFormatter(); } } namespace Monolog { interface ResettableInterface { public function reset(); } } namespace Monolog\Handler { use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; use Monolog\Logger; use Monolog\ResettableInterface; abstract class AbstractHandler implements HandlerInterface, ResettableInterface { protected $level = Logger::DEBUG; protected $bubble = true; protected $formatter; protected $processors = array(); public function __construct($level = Logger::DEBUG, $bubble = true) { $this->setLevel($level); $this->bubble = $bubble; } public function isHandling(array $record) { return $record['level'] >= $this->level; } public function handleBatch(array $records) { foreach ($records as $record) { $this->handle($record); } } public function close() { } public function pushProcessor($callback) { if (!is_callable($callback)) { throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); } array_unshift($this->processors, $callback); return $this; } public function popProcessor() { if (!$this->processors) { throw new \LogicException('You tried to pop from an empty processor stack.'); } return array_shift($this->processors); } public function setFormatter(FormatterInterface $formatter) { $this->formatter = $formatter; return $this; } public function getFormatter() { if (!$this->formatter) { $this->formatter = $this->getDefaultFormatter(); } return $this->formatter; } public function setLevel($level) { $this->level = Logger::toMonologLevel($level); return $this; } public function getLevel() { return $this->level; } public function setBubble($bubble) { $this->bubble = $bubble; return $this; } public function getBubble() { return $this->bubble; } public function __destruct() { try { $this->close(); } catch (\Exception $e) { } catch (\Throwable $e) { } } public function reset() { foreach ($this->processors as $processor) { if ($processor instanceof ResettableInterface) { $processor->reset(); } } } protected function getDefaultFormatter() { return new LineFormatter(); } } } namespace Monolog\Handler { use Monolog\ResettableInterface; abstract class AbstractProcessingHandler extends AbstractHandler { public function handle(array $record) { if (!$this->isHandling($record)) { return false; } $record = $this->processRecord($record); $record['formatted'] = $this->getFormatter()->format($record); $this->write($record); return false === $this->bubble; } abstract protected function write(array $record); protected function processRecord(array $record) { if ($this->processors) { foreach ($this->processors as $processor) { $record = call_user_func($processor, $record); } } return $record; } } } namespace Monolog\Handler { use Monolog\Logger; use Monolog\Utils; class StreamHandler extends AbstractProcessingHandler { const CHUNK_SIZE = 524288; protected $stream; protected $url; private $errorMessage; protected $filePermission; protected $useLocking; private $dirCreated; public function __construct($stream, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false) { parent::__construct($level, $bubble); if (is_resource($stream)) { $this->stream = $stream; $this->streamSetChunkSize(); } elseif (is_string($stream)) { $this->url = Utils::canonicalizePath($stream); } else { throw new \InvalidArgumentException('A stream must either be a resource or a string.'); } $this->filePermission = $filePermission; $this->useLocking = $useLocking; } public function close() { if ($this->url && is_resource($this->stream)) { fclose($this->stream); } $this->stream = null; $this->dirCreated = null; } public function getStream() { return $this->stream; } public function getUrl() { return $this->url; } protected function write(array $record) { if (!is_resource($this->stream)) { if (null === $this->url ||''=== $this->url) { throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().'); } $this->createDir(); $this->errorMessage = null; set_error_handler(array($this,'customErrorHandler')); $this->stream = fopen($this->url,'a'); if ($this->filePermission !== null) { @chmod($this->url, $this->filePermission); } restore_error_handler(); if (!is_resource($this->stream)) { $this->stream = null; throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened in append mode: '.$this->errorMessage, $this->url)); } $this->streamSetChunkSize(); } if ($this->useLocking) { flock($this->stream, LOCK_EX); } $this->streamWrite($this->stream, $record); if ($this->useLocking) { flock($this->stream, LOCK_UN); } } protected function streamWrite($stream, array $record) { fwrite($stream, (string) $record['formatted']); } protected function streamSetChunkSize() { if (version_compare(PHP_VERSION,'5.4.0','>=')) { return stream_set_chunk_size($this->stream, self::CHUNK_SIZE); } return false; } private function customErrorHandler($code, $msg) { $this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }','', $msg); } private function getDirFromStream($stream) { $pos = strpos($stream,'://'); if ($pos === false) { return dirname($stream); } if ('file://'=== substr($stream, 0, 7)) { return dirname(substr($stream, 7)); } return null; } private function createDir() { if ($this->dirCreated) { return; } $dir = $this->getDirFromStream($this->url); if (null !== $dir && !is_dir($dir)) { $this->errorMessage = null; set_error_handler(array($this,'customErrorHandler')); $status = mkdir($dir, 0777, true); restore_error_handler(); if (false === $status && !is_dir($dir)) { throw new \UnexpectedValueException(sprintf('There is no existing directory at "%s" and its not buildable: '.$this->errorMessage, $dir)); } } $this->dirCreated = true; } } } namespace Monolog\Handler { use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; use Monolog\Logger; use Monolog\ResettableInterface; use Monolog\Formatter\FormatterInterface; class FingersCrossedHandler extends AbstractHandler { protected $handler; protected $activationStrategy; protected $buffering = true; protected $bufferSize; protected $buffer = array(); protected $stopBuffering; protected $passthruLevel; public function __construct($handler, $activationStrategy = null, $bufferSize = 0, $bubble = true, $stopBuffering = true, $passthruLevel = null) { if (null === $activationStrategy) { $activationStrategy = new ErrorLevelActivationStrategy(Logger::WARNING); } if (!$activationStrategy instanceof ActivationStrategyInterface) { $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy); } $this->handler = $handler; $this->activationStrategy = $activationStrategy; $this->bufferSize = $bufferSize; $this->bubble = $bubble; $this->stopBuffering = $stopBuffering; if ($passthruLevel !== null) { $this->passthruLevel = Logger::toMonologLevel($passthruLevel); } if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); } } public function isHandling(array $record) { return true; } public function activate() { if ($this->stopBuffering) { $this->buffering = false; } $this->getHandler(end($this->buffer) ?: null)->handleBatch($this->buffer); $this->buffer = array(); } public function handle(array $record) { if ($this->processors) { foreach ($this->processors as $processor) { $record = call_user_func($processor, $record); } } if ($this->buffering) { $this->buffer[] = $record; if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) { array_shift($this->buffer); } if ($this->activationStrategy->isHandlerActivated($record)) { $this->activate(); } } else { $this->getHandler($record)->handle($record); } return false === $this->bubble; } public function close() { $this->flushBuffer(); } public function reset() { $this->flushBuffer(); parent::reset(); if ($this->getHandler() instanceof ResettableInterface) { $this->getHandler()->reset(); } } public function clear() { $this->buffer = array(); $this->reset(); } private function flushBuffer() { if (null !== $this->passthruLevel) { $level = $this->passthruLevel; $this->buffer = array_filter($this->buffer, function ($record) use ($level) { return $record['level'] >= $level; }); if (count($this->buffer) > 0) { $this->getHandler(end($this->buffer) ?: null)->handleBatch($this->buffer); } } $this->buffer = array(); $this->buffering = true; } public function getHandler(array $record = null) { if (!$this->handler instanceof HandlerInterface) { $this->handler = call_user_func($this->handler, $record, $this); if (!$this->handler instanceof HandlerInterface) { throw new \RuntimeException("The factory callable should return a HandlerInterface"); } } return $this->handler; } public function setFormatter(FormatterInterface $formatter) { $this->getHandler()->setFormatter($formatter); return $this; } public function getFormatter() { return $this->getHandler()->getFormatter(); } } } namespace Monolog\Handler { use Monolog\Logger; use Monolog\Formatter\FormatterInterface; class FilterHandler extends AbstractHandler { protected $handler; protected $acceptedLevels; protected $bubble; public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, $bubble = true) { $this->handler = $handler; $this->bubble = $bubble; $this->setAcceptedLevels($minLevelOrList, $maxLevel); if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); } } public function getAcceptedLevels() { return array_flip($this->acceptedLevels); } public function setAcceptedLevels($minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY) { if (is_array($minLevelOrList)) { $acceptedLevels = array_map('Monolog\Logger::toMonologLevel', $minLevelOrList); } else { $minLevelOrList = Logger::toMonologLevel($minLevelOrList); $maxLevel = Logger::toMonologLevel($maxLevel); $acceptedLevels = array_values(array_filter(Logger::getLevels(), function ($level) use ($minLevelOrList, $maxLevel) { return $level >= $minLevelOrList && $level <= $maxLevel; })); } $this->acceptedLevels = array_flip($acceptedLevels); } public function isHandling(array $record) { return isset($this->acceptedLevels[$record['level']]); } public function handle(array $record) { if (!$this->isHandling($record)) { return false; } if ($this->processors) { foreach ($this->processors as $processor) { $record = call_user_func($processor, $record); } } $this->getHandler($record)->handle($record); return false === $this->bubble; } public function handleBatch(array $records) { $filtered = array(); foreach ($records as $record) { if ($this->isHandling($record)) { $filtered[] = $record; } } if (count($filtered) > 0) { $this->getHandler($filtered[count($filtered) - 1])->handleBatch($filtered); } } public function getHandler(array $record = null) { if (!$this->handler instanceof HandlerInterface) { $this->handler = call_user_func($this->handler, $record, $this); if (!$this->handler instanceof HandlerInterface) { throw new \RuntimeException("The factory callable should return a HandlerInterface"); } } return $this->handler; } public function setFormatter(FormatterInterface $formatter) { $this->getHandler()->setFormatter($formatter); return $this; } public function getFormatter() { return $this->getHandler()->getFormatter(); } } } namespace Monolog\Handler { class TestHandler extends AbstractProcessingHandler { protected $records = array(); protected $recordsByLevel = array(); private $skipReset = false; public function getRecords() { return $this->records; } public function clear() { $this->records = array(); $this->recordsByLevel = array(); } public function reset() { if (!$this->skipReset) { $this->clear(); } } public function setSkipReset($skipReset) { $this->skipReset = $skipReset; } public function hasRecords($level) { return isset($this->recordsByLevel[$level]); } public function hasRecord($record, $level) { if (is_string($record)) { $record = array('message'=> $record); } return $this->hasRecordThatPasses(function ($rec) use ($record) { if ($rec['message'] !== $record['message']) { return false; } if (isset($record['context']) && $rec['context'] !== $record['context']) { return false; } return true; }, $level); } public function hasRecordThatContains($message, $level) { return $this->hasRecordThatPasses(function ($rec) use ($message) { return strpos($rec['message'], $message) !== false; }, $level); } public function hasRecordThatMatches($regex, $level) { return $this->hasRecordThatPasses(function ($rec) use ($regex) { return preg_match($regex, $rec['message']) > 0; }, $level); } public function hasRecordThatPasses($predicate, $level) { if (!is_callable($predicate)) { throw new \InvalidArgumentException("Expected a callable for hasRecordThatSucceeds"); } if (!isset($this->recordsByLevel[$level])) { return false; } foreach ($this->recordsByLevel[$level] as $i => $rec) { if (call_user_func($predicate, $rec, $i)) { return true; } } return false; } protected function write(array $record) { $this->recordsByLevel[$record['level']][] = $record; $this->records[] = $record; } public function __call($method, $args) { if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { $genericMethod = $matches[1] . ('Records'!== $matches[3] ?'Record':'') . $matches[3]; $level = constant('Monolog\Logger::'. strtoupper($matches[2])); if (method_exists($this, $genericMethod)) { $args[] = $level; return call_user_func_array(array($this, $genericMethod), $args); } } throw new \BadMethodCallException('Call to undefined method '. get_class($this) .'::'. $method .'()'); } } } namespace Monolog { use Monolog\Handler\HandlerInterface; use Monolog\Handler\StreamHandler; use Psr\Log\LoggerInterface; use Psr\Log\InvalidArgumentException; use Exception; class Logger implements LoggerInterface, ResettableInterface { const DEBUG = 100; const INFO = 200; const NOTICE = 250; const WARNING = 300; const ERROR = 400; const CRITICAL = 500; const ALERT = 550; const EMERGENCY = 600; const API = 1; protected static $levels = array( self::DEBUG =>'DEBUG', self::INFO =>'INFO', self::NOTICE =>'NOTICE', self::WARNING =>'WARNING', self::ERROR =>'ERROR', self::CRITICAL =>'CRITICAL', self::ALERT =>'ALERT', self::EMERGENCY =>'EMERGENCY', ); protected static $timezone; protected $name; protected $handlers; protected $processors; protected $microsecondTimestamps = true; protected $exceptionHandler; public function __construct($name, array $handlers = array(), array $processors = array()) { $this->name = $name; $this->setHandlers($handlers); $this->processors = $processors; } public function getName() { return $this->name; } public function withName($name) { $new = clone $this; $new->name = $name; return $new; } public function pushHandler(HandlerInterface $handler) { array_unshift($this->handlers, $handler); return $this; } public function popHandler() { if (!$this->handlers) { throw new \LogicException('You tried to pop from an empty handler stack.'); } return array_shift($this->handlers); } public function setHandlers(array $handlers) { $this->handlers = array(); foreach (array_reverse($handlers) as $handler) { $this->pushHandler($handler); } return $this; } public function getHandlers() { return $this->handlers; } public function pushProcessor($callback) { if (!is_callable($callback)) { throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); } array_unshift($this->processors, $callback); return $this; } public function popProcessor() { if (!$this->processors) { throw new \LogicException('You tried to pop from an empty processor stack.'); } return array_shift($this->processors); } public function getProcessors() { return $this->processors; } public function useMicrosecondTimestamps($micro) { $this->microsecondTimestamps = (bool) $micro; } public function addRecord($level, $message, array $context = array()) { if (!$this->handlers) { $this->pushHandler(new StreamHandler('php://stderr', static::DEBUG)); } $levelName = static::getLevelName($level); $handlerKey = null; reset($this->handlers); while ($handler = current($this->handlers)) { if ($handler->isHandling(array('level'=> $level))) { $handlerKey = key($this->handlers); break; } next($this->handlers); } if (null === $handlerKey) { return false; } if (!static::$timezone) { static::$timezone = new \DateTimeZone(date_default_timezone_get() ?:'UTC'); } if ($this->microsecondTimestamps && PHP_VERSION_ID < 70100) { $ts = \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), static::$timezone); } else { $ts = new \DateTime('now', static::$timezone); } $ts->setTimezone(static::$timezone); $record = array('message'=> (string) $message,'context'=> $context,'level'=> $level,'level_name'=> $levelName,'channel'=> $this->name,'datetime'=> $ts,'extra'=> array(), ); try { foreach ($this->processors as $processor) { $record = call_user_func($processor, $record); } while ($handler = current($this->handlers)) { if (true === $handler->handle($record)) { break; } next($this->handlers); } } catch (Exception $e) { $this->handleException($e, $record); } return true; } public function close() { foreach ($this->handlers as $handler) { if (method_exists($handler,'close')) { $handler->close(); } } } public function reset() { foreach ($this->handlers as $handler) { if ($handler instanceof ResettableInterface) { $handler->reset(); } } foreach ($this->processors as $processor) { if ($processor instanceof ResettableInterface) { $processor->reset(); } } } public function addDebug($message, array $context = array()) { return $this->addRecord(static::DEBUG, $message, $context); } public function addInfo($message, array $context = array()) { return $this->addRecord(static::INFO, $message, $context); } public function addNotice($message, array $context = array()) { return $this->addRecord(static::NOTICE, $message, $context); } public function addWarning($message, array $context = array()) { return $this->addRecord(static::WARNING, $message, $context); } public function addError($message, array $context = array()) { return $this->addRecord(static::ERROR, $message, $context); } public function addCritical($message, array $context = array()) { return $this->addRecord(static::CRITICAL, $message, $context); } public function addAlert($message, array $context = array()) { return $this->addRecord(static::ALERT, $message, $context); } public function addEmergency($message, array $context = array()) { return $this->addRecord(static::EMERGENCY, $message, $context); } public static function getLevels() { return array_flip(static::$levels); } public static function getLevelName($level) { if (!isset(static::$levels[$level])) { throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels))); } return static::$levels[$level]; } public static function toMonologLevel($level) { if (is_string($level)) { $upper = strtr($level,'abcdefgilmnortuwy','ABCDEFGILMNORTUWY'); if (defined(__CLASS__.'::'.$upper)) { return constant(__CLASS__ .'::'. $upper); } } return $level; } public function isHandling($level) { $record = array('level'=> $level, ); foreach ($this->handlers as $handler) { if ($handler->isHandling($record)) { return true; } } return false; } public function setExceptionHandler($callback) { if (!is_callable($callback)) { throw new \InvalidArgumentException('Exception handler must be valid callable (callback or object with an __invoke method), '.var_export($callback, true).' given'); } $this->exceptionHandler = $callback; return $this; } public function getExceptionHandler() { return $this->exceptionHandler; } protected function handleException(Exception $e, array $record) { if (!$this->exceptionHandler) { throw $e; } call_user_func($this->exceptionHandler, $e, $record); } public function log($level, $message, array $context = array()) { $level = static::toMonologLevel($level); return $this->addRecord($level, $message, $context); } public function debug($message, array $context = array()) { return $this->addRecord(static::DEBUG, $message, $context); } public function info($message, array $context = array()) { return $this->addRecord(static::INFO, $message, $context); } public function notice($message, array $context = array()) { return $this->addRecord(static::NOTICE, $message, $context); } public function warn($message, array $context = array()) { return $this->addRecord(static::WARNING, $message, $context); } public function warning($message, array $context = array()) { return $this->addRecord(static::WARNING, $message, $context); } public function err($message, array $context = array()) { return $this->addRecord(static::ERROR, $message, $context); } public function error($message, array $context = array()) { return $this->addRecord(static::ERROR, $message, $context); } public function crit($message, array $context = array()) { return $this->addRecord(static::CRITICAL, $message, $context); } public function critical($message, array $context = array()) { return $this->addRecord(static::CRITICAL, $message, $context); } public function alert($message, array $context = array()) { return $this->addRecord(static::ALERT, $message, $context); } public function emerg($message, array $context = array()) { return $this->addRecord(static::EMERGENCY, $message, $context); } public function emergency($message, array $context = array()) { return $this->addRecord(static::EMERGENCY, $message, $context); } public static function setTimezone(\DateTimeZone $tz) { self::$timezone = $tz; } } } namespace Symfony\Component\HttpKernel\Log { use Psr\Log\LoggerInterface as PsrLogger; interface LoggerInterface extends PsrLogger { public function emerg($message, array $context = array()); public function crit($message, array $context = array()); public function err($message, array $context = array()); public function warn($message, array $context = array()); } } namespace Symfony\Component\HttpKernel\Log { interface DebugLoggerInterface { public function getLogs(); public function countErrors(); } } namespace Symfony\Bridge\Monolog { use Monolog\Logger as BaseLogger; use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; class Logger extends BaseLogger implements LoggerInterface, DebugLoggerInterface { public function emerg($message, array $context = array()) { @trigger_error('The '.__METHOD__.' method inherited from the Symfony\Component\HttpKernel\Log\LoggerInterface interface is deprecated since version 2.2 and will be removed in 3.0. Use the emergency() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); return parent::addRecord(BaseLogger::EMERGENCY, $message, $context); } public function crit($message, array $context = array()) { @trigger_error('The '.__METHOD__.' method inherited from the Symfony\Component\HttpKernel\Log\LoggerInterface interface is deprecated since version 2.2 and will be removed in 3.0. Use the method critical() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); return parent::addRecord(BaseLogger::CRITICAL, $message, $context); } public function err($message, array $context = array()) { @trigger_error('The '.__METHOD__.' method inherited from the Symfony\Component\HttpKernel\Log\LoggerInterface interface is deprecated since version 2.2 and will be removed in 3.0. Use the error() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); return parent::addRecord(BaseLogger::ERROR, $message, $context); } public function warn($message, array $context = array()) { @trigger_error('The '.__METHOD__.' method inherited from the Symfony\Component\HttpKernel\Log\LoggerInterface interface is deprecated since version 2.2 and will be removed in 3.0. Use the warning() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); return parent::addRecord(BaseLogger::WARNING, $message, $context); } public function getLogs() { if ($logger = $this->getDebugLogger()) { return $logger->getLogs(); } return array(); } public function countErrors() { if ($logger = $this->getDebugLogger()) { return $logger->countErrors(); } return 0; } private function getDebugLogger() { foreach ($this->handlers as $handler) { if ($handler instanceof DebugLoggerInterface) { return $handler; } } } } } namespace Symfony\Bridge\Monolog\Handler { use Monolog\Logger; use Monolog\Handler\TestHandler; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; class DebugHandler extends TestHandler implements DebugLoggerInterface { public function getLogs() { $records = array(); foreach ($this->records as $record) { $records[] = array('timestamp'=> $record['datetime']->getTimestamp(),'message'=> $record['message'],'priority'=> $record['level'],'priorityName'=> $record['level_name'],'context'=> $record['context'],'channel'=> isset($record['channel']) ? $record['channel'] :'', ); } return $records; } public function countErrors() { $cnt = 0; $levels = array(Logger::ERROR, Logger::CRITICAL, Logger::ALERT, Logger::EMERGENCY); foreach ($levels as $level) { if (isset($this->recordsByLevel[$level])) { $cnt += count($this->recordsByLevel[$level]); } } return $cnt; } } } namespace Monolog\Handler\FingersCrossed { interface ActivationStrategyInterface { public function isHandlerActivated(array $record); } } namespace Monolog\Handler\FingersCrossed { use Monolog\Logger; class ErrorLevelActivationStrategy implements ActivationStrategyInterface { private $actionLevel; public function __construct($actionLevel) { $this->actionLevel = Logger::toMonologLevel($actionLevel); } public function isHandlerActivated(array $record) { return $record['level'] >= $this->actionLevel; } } } namespace Doctrine\Common\Lexer { abstract class AbstractLexer { private $input; private $tokens = array(); private $position = 0; private $peek = 0; public $lookahead; public $token; public function setInput($input) { $this->input = $input; $this->tokens = array(); $this->reset(); $this->scan($input); } public function reset() { $this->lookahead = null; $this->token = null; $this->peek = 0; $this->position = 0; } public function resetPeek() { $this->peek = 0; } public function resetPosition($position = 0) { $this->position = $position; } public function getInputUntilPosition($position) { return substr($this->input, 0, $position); } public function isNextToken($token) { return null !== $this->lookahead && $this->lookahead['type'] === $token; } public function isNextTokenAny(array $tokens) { return null !== $this->lookahead && in_array($this->lookahead['type'], $tokens, true); } public function moveNext() { $this->peek = 0; $this->token = $this->lookahead; $this->lookahead = (isset($this->tokens[$this->position])) ? $this->tokens[$this->position++] : null; return $this->lookahead !== null; } public function skipUntil($type) { while ($this->lookahead !== null && $this->lookahead['type'] !== $type) { $this->moveNext(); } } public function isA($value, $token) { return $this->getType($value) === $token; } public function peek() { if (isset($this->tokens[$this->position + $this->peek])) { return $this->tokens[$this->position + $this->peek++]; } else { return null; } } public function glimpse() { $peek = $this->peek(); $this->peek = 0; return $peek; } protected function scan($input) { static $regex; if ( ! isset($regex)) { $regex = sprintf('/(%s)|%s/%s', implode(')|(', $this->getCatchablePatterns()), implode('|', $this->getNonCatchablePatterns()), $this->getModifiers() ); } $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE; $matches = preg_split($regex, $input, -1, $flags); foreach ($matches as $match) { $type = $this->getType($match[0]); $this->tokens[] = array('value'=> $match[0],'type'=> $type,'position'=> $match[1], ); } } public function getLiteral($token) { $className = get_class($this); $reflClass = new \ReflectionClass($className); $constants = $reflClass->getConstants(); foreach ($constants as $name => $value) { if ($value === $token) { return $className .'::'. $name; } } return $token; } protected function getModifiers() { return'i'; } abstract protected function getCatchablePatterns(); abstract protected function getNonCatchablePatterns(); abstract protected function getType(&$value); } } namespace Doctrine\Common\Annotations { use Doctrine\Common\Lexer\AbstractLexer; final class DocLexer extends AbstractLexer { const T_NONE = 1; const T_INTEGER = 2; const T_STRING = 3; const T_FLOAT = 4; const T_IDENTIFIER = 100; const T_AT = 101; const T_CLOSE_CURLY_BRACES = 102; const T_CLOSE_PARENTHESIS = 103; const T_COMMA = 104; const T_EQUALS = 105; const T_FALSE = 106; const T_NAMESPACE_SEPARATOR = 107; const T_OPEN_CURLY_BRACES = 108; const T_OPEN_PARENTHESIS = 109; const T_TRUE = 110; const T_NULL = 111; const T_COLON = 112; protected $noCase = array('@'=> self::T_AT,','=> self::T_COMMA,'('=> self::T_OPEN_PARENTHESIS,')'=> self::T_CLOSE_PARENTHESIS,'{'=> self::T_OPEN_CURLY_BRACES,'}'=> self::T_CLOSE_CURLY_BRACES,'='=> self::T_EQUALS,':'=> self::T_COLON,'\\'=> self::T_NAMESPACE_SEPARATOR ); protected $withCase = array('true'=> self::T_TRUE,'false'=> self::T_FALSE,'null'=> self::T_NULL ); protected function getCatchablePatterns() { return array('[a-z_\\\][a-z0-9_\:\\\]*[a-z_][a-z0-9_]*','(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?','"(?:""|[^"])*+"', ); } protected function getNonCatchablePatterns() { return array('\s+','\*+','(.)'); } protected function getType(&$value) { $type = self::T_NONE; if ($value[0] ==='"') { $value = str_replace('""','"', substr($value, 1, strlen($value) - 2)); return self::T_STRING; } if (isset($this->noCase[$value])) { return $this->noCase[$value]; } if ($value[0] ==='_'|| $value[0] ==='\\'|| ctype_alpha($value[0])) { return self::T_IDENTIFIER; } $lowerValue = strtolower($value); if (isset($this->withCase[$lowerValue])) { return $this->withCase[$lowerValue]; } if (is_numeric($value)) { return (strpos($value,'.') !== false || stripos($value,'e') !== false) ? self::T_FLOAT : self::T_INTEGER; } return $type; } } } namespace Doctrine\Common\Annotations { interface Reader { function getClassAnnotations(\ReflectionClass $class); function getClassAnnotation(\ReflectionClass $class, $annotationName); function getMethodAnnotations(\ReflectionMethod $method); function getMethodAnnotation(\ReflectionMethod $method, $annotationName); function getPropertyAnnotations(\ReflectionProperty $property); function getPropertyAnnotation(\ReflectionProperty $property, $annotationName); } } namespace Doctrine\Common\Annotations { class FileCacheReader implements Reader { private $reader; private $dir; private $debug; private $loadedAnnotations = array(); private $classNameHashes = array(); private $umask; public function __construct(Reader $reader, $cacheDir, $debug = false, $umask = 0002) { if ( ! is_int($umask)) { throw new \InvalidArgumentException(sprintf('The parameter umask must be an integer, was: %s', gettype($umask) )); } $this->reader = $reader; $this->umask = $umask; if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777 & (~$this->umask), true)) { throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $cacheDir)); } $this->dir = rtrim($cacheDir,'\\/'); $this->debug = $debug; } public function getClassAnnotations(\ReflectionClass $class) { if ( ! isset($this->classNameHashes[$class->name])) { $this->classNameHashes[$class->name] = sha1($class->name); } $key = $this->classNameHashes[$class->name]; if (isset($this->loadedAnnotations[$key])) { return $this->loadedAnnotations[$key]; } $path = $this->dir.'/'.strtr($key,'\\','-').'.cache.php'; if (!is_file($path)) { $annot = $this->reader->getClassAnnotations($class); $this->saveCacheFile($path, $annot); return $this->loadedAnnotations[$key] = $annot; } if ($this->debug && (false !== $filename = $class->getFilename()) && filemtime($path) < filemtime($filename)) { @unlink($path); $annot = $this->reader->getClassAnnotations($class); $this->saveCacheFile($path, $annot); return $this->loadedAnnotations[$key] = $annot; } return $this->loadedAnnotations[$key] = include $path; } public function getPropertyAnnotations(\ReflectionProperty $property) { $class = $property->getDeclaringClass(); if ( ! isset($this->classNameHashes[$class->name])) { $this->classNameHashes[$class->name] = sha1($class->name); } $key = $this->classNameHashes[$class->name].'$'.$property->getName(); if (isset($this->loadedAnnotations[$key])) { return $this->loadedAnnotations[$key]; } $path = $this->dir.'/'.strtr($key,'\\','-').'.cache.php'; if (!is_file($path)) { $annot = $this->reader->getPropertyAnnotations($property); $this->saveCacheFile($path, $annot); return $this->loadedAnnotations[$key] = $annot; } if ($this->debug && (false !== $filename = $class->getFilename()) && filemtime($path) < filemtime($filename)) { @unlink($path); $annot = $this->reader->getPropertyAnnotations($property); $this->saveCacheFile($path, $annot); return $this->loadedAnnotations[$key] = $annot; } return $this->loadedAnnotations[$key] = include $path; } public function getMethodAnnotations(\ReflectionMethod $method) { $class = $method->getDeclaringClass(); if ( ! isset($this->classNameHashes[$class->name])) { $this->classNameHashes[$class->name] = sha1($class->name); } $key = $this->classNameHashes[$class->name].'#'.$method->getName(); if (isset($this->loadedAnnotations[$key])) { return $this->loadedAnnotations[$key]; } $path = $this->dir.'/'.strtr($key,'\\','-').'.cache.php'; if (!is_file($path)) { $annot = $this->reader->getMethodAnnotations($method); $this->saveCacheFile($path, $annot); return $this->loadedAnnotations[$key] = $annot; } if ($this->debug && (false !== $filename = $class->getFilename()) && filemtime($path) < filemtime($filename)) { @unlink($path); $annot = $this->reader->getMethodAnnotations($method); $this->saveCacheFile($path, $annot); return $this->loadedAnnotations[$key] = $annot; } return $this->loadedAnnotations[$key] = include $path; } private function saveCacheFile($path, $data) { if (!is_writable($this->dir)) { throw new \InvalidArgumentException(sprintf('The directory "%s" is not writable. Both, the webserver and the console user need access. You can manage access rights for multiple users with "chmod +a". If your system does not support this, check out the acl package.', $this->dir)); } $tempfile = tempnam($this->dir, uniqid('', true)); if (false === $tempfile) { throw new \RuntimeException(sprintf('Unable to create tempfile in directory: %s', $this->dir)); } $written = file_put_contents($tempfile,'<?php return unserialize('.var_export(serialize($data), true).');'); if (false === $written) { throw new \RuntimeException(sprintf('Unable to write cached file to: %s', $tempfile)); } @chmod($tempfile, 0666 & (~$this->umask)); if (false === rename($tempfile, $path)) { @unlink($tempfile); throw new \RuntimeException(sprintf('Unable to rename %s to %s', $tempfile, $path)); } } public function getClassAnnotation(\ReflectionClass $class, $annotationName) { $annotations = $this->getClassAnnotations($class); foreach ($annotations as $annotation) { if ($annotation instanceof $annotationName) { return $annotation; } } return null; } public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) { $annotations = $this->getMethodAnnotations($method); foreach ($annotations as $annotation) { if ($annotation instanceof $annotationName) { return $annotation; } } return null; } public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) { $annotations = $this->getPropertyAnnotations($property); foreach ($annotations as $annotation) { if ($annotation instanceof $annotationName) { return $annotation; } } return null; } public function clearLoadedAnnotations() { $this->loadedAnnotations = array(); } } } namespace Doctrine\Common\Annotations { use SplFileObject; final class PhpParser { public function parseClass(\ReflectionClass $class) { if (method_exists($class,'getUseStatements')) { return $class->getUseStatements(); } if (false === $filename = $class->getFilename()) { return array(); } $content = $this->getFileContent($filename, $class->getStartLine()); if (null === $content) { return array(); } $namespace = preg_quote($class->getNamespaceName()); $content = preg_replace('/^.*?(\bnamespace\s+'. $namespace .'\s*[;{].*)$/s','\\1', $content); $tokenizer = new TokenParser('<?php '. $content); $statements = $tokenizer->parseUseStatements($class->getNamespaceName()); return $statements; } private function getFileContent($filename, $lineNumber) { if ( ! is_file($filename)) { return null; } $content =''; $lineCnt = 0; $file = new SplFileObject($filename); while (!$file->eof()) { if ($lineCnt++ == $lineNumber) { break; } $content .= $file->fgets(); } return $content; } } } namespace Doctrine\Common { use Doctrine\Common\Lexer\AbstractLexer; abstract class Lexer extends AbstractLexer { } } namespace Doctrine\Common\Persistence { interface ConnectionRegistry { public function getDefaultConnectionName(); public function getConnection($name = null); public function getConnections(); public function getConnectionNames(); } } namespace Doctrine\Common\Persistence { interface Proxy { const MARKER ='__CG__'; const MARKER_LENGTH = 6; public function __load(); public function __isInitialized(); } } namespace Doctrine\Common\Util { use Doctrine\Common\Persistence\Proxy; class ClassUtils { public static function getRealClass($class) { if (false === $pos = strrpos($class,'\\'.Proxy::MARKER.'\\')) { return $class; } return substr($class, $pos + Proxy::MARKER_LENGTH + 2); } public static function getClass($object) { return self::getRealClass(get_class($object)); } public static function getParentClass($className) { return get_parent_class( self::getRealClass( $className ) ); } public static function newReflectionClass($class) { return new \ReflectionClass( self::getRealClass( $class ) ); } public static function newReflectionObject($object) { return self::newReflectionClass( self::getClass( $object ) ); } public static function generateProxyClassName($className, $proxyNamespace) { return rtrim($proxyNamespace,'\\') .'\\'.Proxy::MARKER.'\\'. ltrim($className,'\\'); } } } namespace Symfony\Component\DependencyInjection { interface ContainerAwareInterface { public function setContainer(ContainerInterface $container = null); } } namespace Doctrine\Common\Persistence { interface ManagerRegistry extends ConnectionRegistry { public function getDefaultManagerName(); public function getManager($name = null); public function getManagers(); public function resetManager($name = null); public function getAliasNamespace($alias); public function getManagerNames(); public function getRepository($persistentObject, $persistentManagerName = null); public function getManagerForClass($class); } } namespace Symfony\Bridge\Doctrine { use Doctrine\Common\Persistence\ManagerRegistry as ManagerRegistryInterface; use Doctrine\ORM\EntityManager; interface RegistryInterface extends ManagerRegistryInterface { public function getDefaultEntityManagerName(); public function getEntityManager($name = null); public function getEntityManagers(); public function resetEntityManager($name = null); public function getEntityNamespace($alias); public function getEntityManagerNames(); public function getEntityManagerForClass($class); } } namespace Doctrine\Common\Persistence { abstract class AbstractManagerRegistry implements ManagerRegistry { private $name; private $connections; private $managers; private $defaultConnection; private $defaultManager; private $proxyInterfaceName; public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName) { $this->name = $name; $this->connections = $connections; $this->managers = $managers; $this->defaultConnection = $defaultConnection; $this->defaultManager = $defaultManager; $this->proxyInterfaceName = $proxyInterfaceName; } abstract protected function getService($name); abstract protected function resetService($name); public function getName() { return $this->name; } public function getConnection($name = null) { if (null === $name) { $name = $this->defaultConnection; } if (!isset($this->connections[$name])) { throw new \InvalidArgumentException(sprintf('Doctrine %s Connection named "%s" does not exist.', $this->name, $name)); } return $this->getService($this->connections[$name]); } public function getConnectionNames() { return $this->connections; } public function getConnections() { $connections = array(); foreach ($this->connections as $name => $id) { $connections[$name] = $this->getService($id); } return $connections; } public function getDefaultConnectionName() { return $this->defaultConnection; } public function getDefaultManagerName() { return $this->defaultManager; } public function getManager($name = null) { if (null === $name) { $name = $this->defaultManager; } if (!isset($this->managers[$name])) { throw new \InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name)); } return $this->getService($this->managers[$name]); } public function getManagerForClass($class) { if (strpos($class,':') !== false) { list($namespaceAlias, $simpleClassName) = explode(':', $class, 2); $class = $this->getAliasNamespace($namespaceAlias) .'\\'. $simpleClassName; } $proxyClass = new \ReflectionClass($class); if ($proxyClass->implementsInterface($this->proxyInterfaceName)) { if (! $parentClass = $proxyClass->getParentClass()) { return null; } $class = $parentClass->getName(); } foreach ($this->managers as $id) { $manager = $this->getService($id); if (!$manager->getMetadataFactory()->isTransient($class)) { return $manager; } } } public function getManagerNames() { return $this->managers; } public function getManagers() { $dms = array(); foreach ($this->managers as $name => $id) { $dms[$name] = $this->getService($id); } return $dms; } public function getRepository($persistentObjectName, $persistentManagerName = null) { return $this->getManager($persistentManagerName)->getRepository($persistentObjectName); } public function resetManager($name = null) { if (null === $name) { $name = $this->defaultManager; } if (!isset($this->managers[$name])) { throw new \InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name)); } $this->resetService($this->managers[$name]); } } } namespace Symfony\Bridge\Doctrine { use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Doctrine\Common\Persistence\AbstractManagerRegistry; abstract class ManagerRegistry extends AbstractManagerRegistry implements ContainerAwareInterface { protected $container; protected function getService($name) { return $this->container->get($name); } protected function resetService($name) { $this->container->set($name, null); } public function setContainer(ContainerInterface $container = null) { $this->container = $container; } } } namespace Doctrine\Bundle\DoctrineBundle { use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Bridge\Doctrine\RegistryInterface; use Symfony\Bridge\Doctrine\ManagerRegistry; use Doctrine\ORM\ORMException; use Doctrine\ORM\EntityManager; class Registry extends ManagerRegistry implements RegistryInterface { public function __construct(ContainerInterface $container, array $connections, array $entityManagers, $defaultConnection, $defaultEntityManager) { $this->setContainer($container); parent::__construct('ORM', $connections, $entityManagers, $defaultConnection, $defaultEntityManager,'Doctrine\ORM\Proxy\Proxy'); } public function getDefaultEntityManagerName() { trigger_error('getDefaultEntityManagerName is deprecated since Symfony 2.1. Use getDefaultManagerName instead', E_USER_DEPRECATED); return $this->getDefaultManagerName(); } public function getEntityManager($name = null) { trigger_error('getEntityManager is deprecated since Symfony 2.1. Use getManager instead', E_USER_DEPRECATED); return $this->getManager($name); } public function getEntityManagers() { trigger_error('getEntityManagers is deprecated since Symfony 2.1. Use getManagers instead', E_USER_DEPRECATED); return $this->getManagers(); } public function resetEntityManager($name = null) { trigger_error('resetEntityManager is deprecated since Symfony 2.1. Use resetManager instead', E_USER_DEPRECATED); $this->resetManager($name); } public function getEntityNamespace($alias) { trigger_error('getEntityNamespace is deprecated since Symfony 2.1. Use getAliasNamespace instead', E_USER_DEPRECATED); return $this->getAliasNamespace($alias); } public function getAliasNamespace($alias) { foreach (array_keys($this->getManagers()) as $name) { try { return $this->getManager($name)->getConfiguration()->getEntityNamespace($alias); } catch (ORMException $e) { } } throw ORMException::unknownEntityNamespace($alias); } public function getEntityManagerNames() { trigger_error('getEntityManagerNames is deprecated since Symfony 2.1. Use getManagerNames instead', E_USER_DEPRECATED); return $this->getManagerNames(); } public function getEntityManagerForClass($class) { trigger_error('getEntityManagerForClass is deprecated since Symfony 2.1. Use getManagerForClass instead', E_USER_DEPRECATED); return $this->getManagerForClass($class); } } } namespace Sensio\Bundle\FrameworkExtraBundle\EventListener { use Doctrine\Common\Annotations\Reader; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface; use Doctrine\Common\Util\ClassUtils; class ControllerListener implements EventSubscriberInterface { protected $reader; public function __construct(Reader $reader) { $this->reader = $reader; } public function onKernelController(FilterControllerEvent $event) { if (!is_array($controller = $event->getController())) { return; } $className = class_exists('Doctrine\Common\Util\ClassUtils') ? ClassUtils::getClass($controller[0]) : get_class($controller[0]); $object = new \ReflectionClass($className); $method = $object->getMethod($controller[1]); $classConfigurations = $this->getConfigurations($this->reader->getClassAnnotations($object)); $methodConfigurations = $this->getConfigurations($this->reader->getMethodAnnotations($method)); $configurations = array(); foreach (array_merge(array_keys($classConfigurations), array_keys($methodConfigurations)) as $key) { if (!array_key_exists($key, $classConfigurations)) { $configurations[$key] = $methodConfigurations[$key]; } elseif (!array_key_exists($key, $methodConfigurations)) { $configurations[$key] = $classConfigurations[$key]; } else { if (is_array($classConfigurations[$key])) { if (!is_array($methodConfigurations[$key])) { throw new \UnexpectedValueException('Configurations should both be an array or both not be an array'); } $configurations[$key] = array_merge($classConfigurations[$key], $methodConfigurations[$key]); } else { $configurations[$key] = $methodConfigurations[$key]; } } } $request = $event->getRequest(); foreach ($configurations as $key => $attributes) { $request->attributes->set($key, $attributes); } } protected function getConfigurations(array $annotations) { $configurations = array(); foreach ($annotations as $configuration) { if ($configuration instanceof ConfigurationInterface) { if ($configuration->allowArray()) { $configurations['_'.$configuration->getAliasName()][] = $configuration; } elseif (!isset($configurations['_'.$configuration->getAliasName()])) { $configurations['_'.$configuration->getAliasName()] = $configuration; } else { throw new \LogicException(sprintf('Multiple "%s" annotations are not allowed.', $configuration->getAliasName())); } } } return $configurations; } public static function getSubscribedEvents() { return array( KernelEvents::CONTROLLER =>'onKernelController', ); } } } namespace Sensio\Bundle\FrameworkExtraBundle\EventListener { use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterManager; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ParamConverterListener implements EventSubscriberInterface { protected $manager; protected $autoConvert; public function __construct(ParamConverterManager $manager, $autoConvert = true) { $this->manager = $manager; $this->autoConvert = $autoConvert; } public function onKernelController(FilterControllerEvent $event) { $controller = $event->getController(); $request = $event->getRequest(); $configurations = array(); if ($configuration = $request->attributes->get('_converters')) { foreach (is_array($configuration) ? $configuration : array($configuration) as $configuration) { $configurations[$configuration->getName()] = $configuration; } } if (is_array($controller)) { $r = new \ReflectionMethod($controller[0], $controller[1]); } elseif (is_object($controller) && is_callable($controller,'__invoke')) { $r = new \ReflectionMethod($controller,'__invoke'); } else { $r = new \ReflectionFunction($controller); } if ($this->autoConvert) { $configurations = $this->autoConfigure($r, $request, $configurations); } $this->manager->apply($request, $configurations); } private function autoConfigure(\ReflectionFunctionAbstract $r, Request $request, $configurations) { foreach ($r->getParameters() as $param) { if (!$param->getClass() || $param->getClass()->isInstance($request)) { continue; } $name = $param->getName(); if (!isset($configurations[$name])) { $configuration = new ParamConverter(array()); $configuration->setName($name); $configuration->setClass($param->getClass()->getName()); $configurations[$name] = $configuration; } elseif (null === $configurations[$name]->getClass()) { $configurations[$name]->setClass($param->getClass()->getName()); } $configurations[$name]->setIsOptional($param->isOptional()); } return $configurations; } public static function getSubscribedEvents() { return array( KernelEvents::CONTROLLER =>'onKernelController', ); } } } namespace Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter { use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Component\HttpFoundation\Request; interface ParamConverterInterface { public function apply(Request $request, ParamConverter $configuration); public function supports(ParamConverter $configuration); } } namespace Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter { use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use DateTime; class DateTimeParamConverter implements ParamConverterInterface { public function apply(Request $request, ParamConverter $configuration) { $param = $configuration->getName(); if (!$request->attributes->has($param)) { return false; } $options = $configuration->getOptions(); $value = $request->attributes->get($param); if (!$value && $configuration->isOptional()) { return false; } if (isset($options['format'])) { $date = DateTime::createFromFormat($options['format'], $value); if (!$date) { throw new NotFoundHttpException('Invalid date given.'); } } else { if (false === strtotime($value)) { throw new NotFoundHttpException('Invalid date given.'); } $date = new DateTime($value); } $request->attributes->set($param, $date); return true; } public function supports(ParamConverter $configuration) { if (null === $configuration->getClass()) { return false; } return'DateTime'=== $configuration->getClass(); } } } namespace Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter { use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpFoundation\Request; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ORM\NoResultException; class DoctrineParamConverter implements ParamConverterInterface { protected $registry; public function __construct(ManagerRegistry $registry = null) { $this->registry = $registry; } public function apply(Request $request, ParamConverter $configuration) { $name = $configuration->getName(); $class = $configuration->getClass(); $options = $this->getOptions($configuration); if (null === $request->attributes->get($name, false)) { $configuration->setIsOptional(true); } if (false === $object = $this->find($class, $request, $options, $name)) { if (false === $object = $this->findOneBy($class, $request, $options)) { if ($configuration->isOptional()) { $object = null; } else { throw new \LogicException('Unable to guess how to get a Doctrine instance from the request information.'); } } } if (null === $object && false === $configuration->isOptional()) { throw new NotFoundHttpException(sprintf('%s object not found.', $class)); } $request->attributes->set($name, $object); return true; } protected function find($class, Request $request, $options, $name) { if ($options['mapping'] || $options['exclude']) { return false; } $id = $this->getIdentifier($request, $options, $name); if (false === $id || null === $id) { return false; } if (isset($options['repository_method'])) { $method = $options['repository_method']; } else { $method ='find'; } try { return $this->getManager($options['entity_manager'], $class)->getRepository($class)->$method($id); } catch (NoResultException $e) { return; } } protected function getIdentifier(Request $request, $options, $name) { if (isset($options['id'])) { if (!is_array($options['id'])) { $name = $options['id']; } elseif (is_array($options['id'])) { $id = array(); foreach ($options['id'] as $field) { $id[$field] = $request->attributes->get($field); } return $id; } } if ($request->attributes->has($name)) { return $request->attributes->get($name); } if ($request->attributes->has('id') && !isset($options['id'])) { return $request->attributes->get('id'); } return false; } protected function findOneBy($class, Request $request, $options) { if (!$options['mapping']) { $keys = $request->attributes->keys(); $options['mapping'] = $keys ? array_combine($keys, $keys) : array(); } foreach ($options['exclude'] as $exclude) { unset($options['mapping'][$exclude]); } if (!$options['mapping']) { return false; } if (isset($options['id']) && null === $request->attributes->get($options['id'])) { return false; } $criteria = array(); $em = $this->getManager($options['entity_manager'], $class); $metadata = $em->getClassMetadata($class); $mapMethodSignature = isset($options['repository_method']) && isset($options['map_method_signature']) && $options['map_method_signature'] === true; foreach ($options['mapping'] as $attribute => $field) { if ($metadata->hasField($field) || ($metadata->hasAssociation($field) && $metadata->isSingleValuedAssociation($field)) || $mapMethodSignature) { $criteria[$field] = $request->attributes->get($attribute); } } if ($options['strip_null']) { $criteria = array_filter($criteria, function ($value) { return !is_null($value); }); } if (!$criteria) { return false; } if (isset($options['repository_method'])) { $repositoryMethod = $options['repository_method']; } else { $repositoryMethod ='findOneBy'; } try { if ($mapMethodSignature) { return $this->findDataByMapMethodSignature($em, $class, $repositoryMethod, $criteria); } return $em->getRepository($class)->$repositoryMethod($criteria); } catch (NoResultException $e) { return; } } private function findDataByMapMethodSignature($em, $class, $repositoryMethod, $criteria) { $arguments = array(); $repository = $em->getRepository($class); $ref = new \ReflectionMethod($repository, $repositoryMethod); foreach ($ref->getParameters() as $parameter) { if (array_key_exists($parameter->name, $criteria)) { $arguments[] = $criteria[$parameter->name]; } elseif ($parameter->isDefaultValueAvailable()) { $arguments[] = $parameter->getDefaultValue(); } else { throw new \InvalidArgumentException(sprintf('Repository method "%s::%s" requires that you provide a value for the "$%s" argument.', get_class($repository), $repositoryMethod, $parameter->name)); } } return $ref->invokeArgs($repository, $arguments); } public function supports(ParamConverter $configuration) { if (null === $this->registry || !count($this->registry->getManagers())) { return false; } if (null === $configuration->getClass()) { return false; } $options = $this->getOptions($configuration); $em = $this->getManager($options['entity_manager'], $configuration->getClass()); if (null === $em) { return false; } return !$em->getMetadataFactory()->isTransient($configuration->getClass()); } protected function getOptions(ParamConverter $configuration) { return array_replace(array('entity_manager'=> null,'exclude'=> array(),'mapping'=> array(),'strip_null'=> false, ), $configuration->getOptions()); } private function getManager($name, $class) { if (null === $name) { return $this->registry->getManagerForClass($class); } return $this->registry->getManager($name); } } } namespace Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter { use Symfony\Component\HttpFoundation\Request; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface; class ParamConverterManager { protected $converters = array(); protected $namedConverters = array(); public function apply(Request $request, $configurations) { if (is_object($configurations)) { $configurations = array($configurations); } foreach ($configurations as $configuration) { $this->applyConverter($request, $configuration); } } protected function applyConverter(Request $request, ConfigurationInterface $configuration) { $value = $request->attributes->get($configuration->getName()); $className = $configuration->getClass(); if (is_object($value) && $value instanceof $className) { return; } if ($converterName = $configuration->getConverter()) { if (!isset($this->namedConverters[$converterName])) { throw new \RuntimeException(sprintf("No converter named '%s' found for conversion of parameter '%s'.", $converterName, $configuration->getName() )); } $converter = $this->namedConverters[$converterName]; if (!$converter->supports($configuration)) { throw new \RuntimeException(sprintf("Converter '%s' does not support conversion of parameter '%s'.", $converterName, $configuration->getName() )); } $converter->apply($request, $configuration); return; } foreach ($this->all() as $converter) { if ($converter->supports($configuration)) { if ($converter->apply($request, $configuration)) { return; } } } } public function add(ParamConverterInterface $converter, $priority = 0, $name = null) { if ($priority !== null) { if (!isset($this->converters[$priority])) { $this->converters[$priority] = array(); } $this->converters[$priority][] = $converter; } if (null !== $name) { $this->namedConverters[$name] = $converter; } } public function all() { krsort($this->converters); $converters = array(); foreach ($this->converters as $all) { $converters = array_merge($converters, $all); } return $converters; } } } namespace Sensio\Bundle\FrameworkExtraBundle\EventListener { use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\StreamedResponse; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; class TemplateListener implements EventSubscriberInterface { protected $container; public function __construct(ContainerInterface $container) { $this->container = $container; } public function onKernelController(FilterControllerEvent $event) { $request = $event->getRequest(); $template = $request->attributes->get('_template'); if (null === $template) { return; } if (!$template instanceof Template) { throw new \InvalidArgumentException('Request attribute "_template" is reserved for @Template annotations.'); } $template->setOwner($controller = $event->getController()); if (null === $template->getTemplate()) { $guesser = $this->container->get('sensio_framework_extra.view.guesser'); $template->setTemplate($guesser->guessTemplateName($controller, $request, $template->getEngine())); } } public function onKernelView(GetResponseForControllerResultEvent $event) { $request = $event->getRequest(); $template = $request->attributes->get('_template'); if (null === $template) { return; } $parameters = $event->getControllerResult(); $owner = $template->getOwner(); list($controller, $action) = $owner; if (null === $parameters) { $parameters = $this->resolveDefaultParameters($request, $template, $controller, $action); } $templating = $this->container->get('templating'); if ($template->isStreamable()) { $callback = function () use ($templating, $template, $parameters) { return $templating->stream($template->getTemplate(), $parameters); }; $event->setResponse(new StreamedResponse($callback)); } $template->setOwner(array()); $event->setResponse($templating->renderResponse($template->getTemplate(), $parameters)); } public static function getSubscribedEvents() { return array( KernelEvents::CONTROLLER => array('onKernelController', -128), KernelEvents::VIEW =>'onKernelView', ); } private function resolveDefaultParameters(Request $request, Template $template, $controller, $action) { $parameters = array(); $arguments = $template->getVars(); if (0 === count($arguments)) { $r = new \ReflectionObject($controller); $arguments = array(); foreach ($r->getMethod($action)->getParameters() as $param) { $arguments[] = $param->getName(); } } foreach ($arguments as $argument) { $parameters[$argument] = $request->attributes->get($argument); } return $parameters; } } } namespace Sensio\Bundle\FrameworkExtraBundle\EventListener { use Symfony\Component\HttpKernel\Event\FilterControllerEvent; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; class HttpCacheListener implements EventSubscriberInterface { private $lastModifiedDates; private $etags; private $expressionLanguage; public function __construct() { $this->lastModifiedDates = new \SplObjectStorage(); $this->etags = new \SplObjectStorage(); } public function onKernelController(FilterControllerEvent $event) { $request = $event->getRequest(); if (!$configuration = $request->attributes->get('_cache')) { return; } $response = new Response(); $lastModifiedDate =''; if ($configuration->getLastModified()) { $lastModifiedDate = $this->getExpressionLanguage()->evaluate($configuration->getLastModified(), $request->attributes->all()); $response->setLastModified($lastModifiedDate); } $etag =''; if ($configuration->getETag()) { $etag = hash('sha256', $this->getExpressionLanguage()->evaluate($configuration->getETag(), $request->attributes->all())); $response->setETag($etag); } if ($response->isNotModified($request)) { $event->setController(function () use ($response) { return $response; }); } else { if ($etag) { $this->etags[$request] = $etag; } if ($lastModifiedDate) { $this->lastModifiedDates[$request] = $lastModifiedDate; } } } public function onKernelResponse(FilterResponseEvent $event) { $request = $event->getRequest(); if (!$configuration = $request->attributes->get('_cache')) { return; } $response = $event->getResponse(); if (!in_array($response->getStatusCode(), array(200, 203, 300, 301, 302, 304, 404, 410))) { return; } if (null !== $age = $configuration->getSMaxAge()) { if (!is_numeric($age)) { $now = microtime(true); $age = ceil(strtotime($configuration->getSMaxAge(), $now) - $now); } $response->setSharedMaxAge($age); } if (null !== $age = $configuration->getMaxAge()) { if (!is_numeric($age)) { $now = microtime(true); $age = ceil(strtotime($configuration->getMaxAge(), $now) - $now); } $response->setMaxAge($age); } if (null !== $configuration->getExpires()) { $date = \DateTime::createFromFormat('U', strtotime($configuration->getExpires()), new \DateTimeZone('UTC')); $response->setExpires($date); } if (null !== $configuration->getVary()) { $response->setVary($configuration->getVary()); } if ($configuration->isPublic()) { $response->setPublic(); } if ($configuration->isPrivate()) { $response->setPrivate(); } if (isset($this->lastModifiedDates[$request])) { $response->setLastModified($this->lastModifiedDates[$request]); unset($this->lastModifiedDates[$request]); } if (isset($this->etags[$request])) { $response->setETag($this->etags[$request]); unset($this->etags[$request]); } $event->setResponse($response); } public static function getSubscribedEvents() { return array( KernelEvents::CONTROLLER =>'onKernelController', KernelEvents::RESPONSE =>'onKernelResponse', ); } private function getExpressionLanguage() { if (null === $this->expressionLanguage) { if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) { throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); } $this->expressionLanguage = new ExpressionLanguage(); } return $this->expressionLanguage; } } } namespace Sensio\Bundle\FrameworkExtraBundle\EventListener { use Sensio\Bundle\FrameworkExtraBundle\Security\ExpressionLanguage; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; class SecurityListener implements EventSubscriberInterface { private $tokenStorage; private $authChecker; private $language; private $trustResolver; private $roleHierarchy; public function __construct(SecurityContextInterface $securityContext = null, ExpressionLanguage $language = null, AuthenticationTrustResolverInterface $trustResolver = null, RoleHierarchyInterface $roleHierarchy = null, TokenStorageInterface $tokenStorage = null, AuthorizationCheckerInterface $authChecker = null) { $this->tokenStorage = $tokenStorage ?: $securityContext; $this->authChecker = $authChecker ?: $securityContext; $this->language = $language; $this->trustResolver = $trustResolver; $this->roleHierarchy = $roleHierarchy; } public function onKernelController(FilterControllerEvent $event) { $request = $event->getRequest(); if (!$configuration = $request->attributes->get('_security')) { return; } if (null === $this->tokenStorage || null === $this->trustResolver) { throw new \LogicException('To use the @Security tag, you need to install the Symfony Security bundle.'); } if (null === $this->tokenStorage->getToken()) { throw new \LogicException('To use the @Security tag, your controller needs to be behind a firewall.'); } if (null === $this->language) { throw new \LogicException('To use the @Security tag, you need to use the Security component 2.4 or newer and to install the ExpressionLanguage component.'); } if (!$this->language->evaluate($configuration->getExpression(), $this->getVariables($request))) { throw new AccessDeniedException(sprintf('Expression "%s" denied access.', $configuration->getExpression())); } } private function getVariables(Request $request) { $token = $this->tokenStorage->getToken(); if (null !== $this->roleHierarchy) { $roles = $this->roleHierarchy->getReachableRoles($token->getRoles()); } else { $roles = $token->getRoles(); } $variables = array('token'=> $token,'user'=> $token->getUser(),'object'=> $request,'request'=> $request,'roles'=> array_map(function ($role) { return $role->getRole(); }, $roles),'trust_resolver'=> $this->trustResolver,'auth_checker'=> $this->authChecker, ); return array_merge($request->attributes->all(), $variables); } public static function getSubscribedEvents() { return array(KernelEvents::CONTROLLER =>'onKernelController'); } } } namespace Sensio\Bundle\FrameworkExtraBundle\Configuration { interface ConfigurationInterface { public function getAliasName(); public function allowArray(); } } namespace Sensio\Bundle\FrameworkExtraBundle\Configuration { abstract class ConfigurationAnnotation implements ConfigurationInterface { public function __construct(array $values) { foreach ($values as $k => $v) { if (!method_exists($this, $name ='set'.$k)) { throw new \RuntimeException(sprintf('Unknown key "%s" for annotation "@%s".', $k, get_class($this))); } $this->$name($v); } } } }') in ClassCollectionLoader.php line 159
  3. at ClassCollectionLoader::load(array('Symfony\Bundle\FrameworkBundle\EventListener\SessionListener', 'Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage', 'Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage', 'Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler', 'Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy', 'Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', 'Symfony\Component\HttpFoundation\Session\Session', 'Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables', 'Symfony\Bundle\FrameworkBundle\Templating\TemplateReference', 'Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser', 'Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator', 'Symfony\Component\Routing\Generator\UrlGenerator', 'Symfony\Component\Routing\RequestContext', 'Symfony\Component\Routing\Router', 'Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher', 'Symfony\Bundle\FrameworkBundle\Routing\Router', 'Symfony\Component\Config\FileLocator', 'Symfony\Component\Debug\ErrorHandler', 'Symfony\Component\EventDispatcher\Event', 'Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher', 'Symfony\Component\HttpKernel\EventListener\ResponseListener', 'Symfony\Component\HttpKernel\EventListener\RouterListener', 'Symfony\Component\HttpKernel\Controller\ControllerResolver', 'Symfony\Component\HttpKernel\Event\KernelEvent', 'Symfony\Component\HttpKernel\Event\FilterControllerEvent', 'Symfony\Component\HttpKernel\Event\FilterResponseEvent', 'Symfony\Component\HttpKernel\Event\GetResponseEvent', 'Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent', 'Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent', 'Symfony\Component\HttpKernel\KernelEvents', 'Symfony\Component\HttpKernel\Config\FileLocator', 'Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser', 'Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver', 'Symfony\Component\Security\Http\Firewall', 'Symfony\Component\Security\Core\User\UserProviderInterface', 'Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager', 'Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage', 'Symfony\Component\Security\Core\Authorization\AccessDecisionManager', 'Symfony\Component\Security\Core\Authorization\AuthorizationChecker', 'Symfony\Component\Security\Core\Authorization\Voter\VoterInterface', 'Symfony\Bundle\SecurityBundle\Security\FirewallMap', 'Symfony\Bundle\SecurityBundle\Security\FirewallContext', 'Symfony\Component\HttpFoundation\RequestMatcher', 'Twig_Environment', 'Twig_Extension', 'Twig_Extension_Core', 'Twig_Extension_Escaper', 'Twig_Extension_Optimizer', 'Twig_LoaderInterface', 'Twig_Markup', 'Twig_Template', 'Monolog\Formatter\FormatterInterface', 'Monolog\Formatter\LineFormatter', 'Monolog\Handler\HandlerInterface', 'Monolog\Handler\AbstractHandler', 'Monolog\Handler\AbstractProcessingHandler', 'Monolog\Handler\StreamHandler', 'Monolog\Handler\FingersCrossedHandler', 'Monolog\Handler\FilterHandler', 'Monolog\Handler\TestHandler', 'Monolog\Logger', 'Symfony\Bridge\Monolog\Logger', 'Symfony\Bridge\Monolog\Handler\DebugHandler', 'Monolog\Handler\FingersCrossed\ActivationStrategyInterface', 'Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy', 'Doctrine\Common\Annotations\DocLexer', 'Doctrine\Common\Annotations\FileCacheReader', 'Doctrine\Common\Annotations\PhpParser', 'Doctrine\Common\Annotations\Reader', 'Doctrine\Common\Lexer', 'Doctrine\Common\Persistence\ConnectionRegistry', 'Doctrine\Common\Persistence\Proxy', 'Doctrine\Common\Util\ClassUtils', 'Doctrine\Bundle\DoctrineBundle\Registry', 'Sensio\Bundle\FrameworkExtraBundle\EventListener\ControllerListener', 'Sensio\Bundle\FrameworkExtraBundle\EventListener\ParamConverterListener', 'Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DateTimeParamConverter', 'Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter', 'Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface', 'Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterManager', 'Sensio\Bundle\FrameworkExtraBundle\EventListener\TemplateListener', 'Sensio\Bundle\FrameworkExtraBundle\EventListener\HttpCacheListener', 'Sensio\Bundle\FrameworkExtraBundle\EventListener\SecurityListener', 'Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation'), '/var/www/html/vibia-front/app/cache/dev', 'classes', true, false, '.php') in Kernel.php line 408
  4. at Kernel->doLoadClassCache('classes', '.php') in Kernel.php line 126
  5. at Kernel->boot() in Kernel.php line 182
  6. at Kernel->handle(object(Request)) in app_dev.php line 43