PluginProbe
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor / 4.0.2
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor v4.0.2
4.0.2 4.0.1 4.0.0 3.16.6 3.16.5 3.16.4 3.16.3 3.16.2 3.16.1 3.16.0 3.15.9 3.9.9 3.9.5 3.9.6 3.9.7 3.9.8 1.1.7 1.1.8 1.1.9 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 All 340 releases
profile-builder / assets / lib / Mustache / Engine.php

Engine.php in User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor 4.0.2, at assets/lib/Mustache/Engine.php

830 lines 25.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of Mustache.php.
5 *
6 * (c) 2010-2017 Justin Hileman
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 /**
13 * A Mustache implementation in PHP.
14 *
15 * {@link http://defunkt.github.com/mustache}
16 *
17 * Mustache is a framework-agnostic logic-less templating language. It enforces separation of view
18 * logic from template files. In fact, it is not even possible to embed logic in the template.
19 *
20 * This is very, very rad.
21 *
22 * @author Justin Hileman {@link http://justinhileman.com}
23 */
24 class Mustache_Engine
25 {
26 const VERSION = '2.14.2';
27 const SPEC_VERSION = '1.2.2';
28
29 const PRAGMA_FILTERS = 'FILTERS';
30 const PRAGMA_BLOCKS = 'BLOCKS';
31 const PRAGMA_ANCHORED_DOT = 'ANCHORED-DOT';
32
33 // Known pragmas
34 private static $knownPragmas = array(
35 self::PRAGMA_FILTERS => true,
36 self::PRAGMA_BLOCKS => true,
37 self::PRAGMA_ANCHORED_DOT => true,
38 );
39
40 // Template cache
41 private $templates = array();
42
43 // Environment
44 private $templateClassPrefix = '__Mustache_';
45 private $cache;
46 private $lambdaCache;
47 private $cacheLambdaTemplates = false;
48 private $loader;
49 private $partialsLoader;
50 private $helpers;
51 private $escape;
52 private $entityFlags = ENT_COMPAT;
53 private $charset = 'UTF-8';
54 private $logger;
55 private $strictCallables = false;
56 private $pragmas = array();
57 private $delimiters;
58
59 // Services
60 private $tokenizer;
61 private $parser;
62 private $compiler;
63
64 /**
65 * Mustache class constructor.
66 *
67 * Passing an $options array allows overriding certain Mustache options during instantiation:
68 *
69 * $options = array(
70 * // The class prefix for compiled templates. Defaults to '__Mustache_'.
71 * 'template_class_prefix' => '__MyTemplates_',
72 *
73 * // A Mustache cache instance or a cache directory string for compiled templates.
74 * // Mustache will not cache templates unless this is set.
75 * 'cache' => dirname(__FILE__).'/tmp/cache/mustache',
76 *
77 * // Override default permissions for cache files. Defaults to using the system-defined umask. It is
78 * // *strongly* recommended that you configure your umask properly rather than overriding permissions here.
79 * 'cache_file_mode' => 0666,
80 *
81 * // Optionally, enable caching for lambda section templates. This is generally not recommended, as lambda
82 * // sections are often too dynamic to benefit from caching.
83 * 'cache_lambda_templates' => true,
84 *
85 * // Customize the tag delimiters used by this engine instance. Note that overriding here changes the
86 * // delimiters used to parse all templates and partials loaded by this instance. To override just for a
87 * // single template, use an inline "change delimiters" tag at the start of the template file:
88 * //
89 * // {{=<% %>=}}
90 * //
91 * 'delimiters' => '<% %>',
92 *
93 * // A Mustache template loader instance. Uses a StringLoader if not specified.
94 * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'),
95 *
96 * // A Mustache loader instance for partials.
97 * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'),
98 *
99 * // An array of Mustache partials. Useful for quick-and-dirty string template loading, but not as
100 * // efficient or lazy as a Filesystem (or database) loader.
101 * 'partials' => array('foo' => file_get_contents(dirname(__FILE__).'/views/partials/foo.mustache')),
102 *
103 * // An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order
104 * // sections), or any other valid Mustache context value. They will be prepended to the context stack,
105 * // so they will be available in any template loaded by this Mustache instance.
106 * 'helpers' => array('i18n' => function ($text) {
107 * // do something translatey here...
108 * }),
109 *
110 * // An 'escape' callback, responsible for escaping double-mustache variables.
111 * 'escape' => function ($value) {
112 * return htmlspecialchars($buffer, ENT_COMPAT, 'UTF-8');
113 * },
114 *
115 * // Type argument for `htmlspecialchars`. Defaults to ENT_COMPAT. You may prefer ENT_QUOTES.
116 * 'entity_flags' => ENT_QUOTES,
117 *
118 * // Character set for `htmlspecialchars`. Defaults to 'UTF-8'. Use 'UTF-8'.
119 * 'charset' => 'ISO-8859-1',
120 *
121 * // A Mustache Logger instance. No logging will occur unless this is set. Using a PSR-3 compatible
122 * // logging library -- such as Monolog -- is highly recommended. A simple stream logger implementation is
123 * // available as well:
124 * 'logger' => new Mustache_Logger_StreamLogger('php://stderr'),
125 *
126 * // Only treat Closure instances and invokable classes as callable. If true, values like
127 * // `array('ClassName', 'methodName')` and `array($classInstance, 'methodName')`, which are traditionally
128 * // "callable" in PHP, are not called to resolve variables for interpolation or section contexts. This
129 * // helps protect against arbitrary code execution when user input is passed directly into the template.
130 * // This currently defaults to false, but will default to true in v3.0.
131 * 'strict_callables' => true,
132 *
133 * // Enable pragmas across all templates, regardless of the presence of pragma tags in the individual
134 * // templates.
135 * 'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
136 * );
137 *
138 * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable
139 *
140 * @param array $options (default: array())
141 */
142 public function __construct(array $options = array())
143 {
144 if (isset($options['template_class_prefix'])) {
145 if ((string) $options['template_class_prefix'] === '') {
146 throw new Mustache_Exception_InvalidArgumentException('Mustache Constructor "template_class_prefix" must not be empty');
147 }
148
149 $this->templateClassPrefix = $options['template_class_prefix'];
150 }
151
152 if (isset($options['cache'])) {
153 $cache = $options['cache'];
154
155 if (is_string($cache)) {
156 $mode = isset($options['cache_file_mode']) ? $options['cache_file_mode'] : null;
157 $cache = new Mustache_Cache_FilesystemCache($cache, $mode);
158 }
159
160 $this->setCache($cache);
161 }
162
163 if (isset($options['cache_lambda_templates'])) {
164 $this->cacheLambdaTemplates = (bool) $options['cache_lambda_templates'];
165 }
166
167 if (isset($options['loader'])) {
168 $this->setLoader($options['loader']);
169 }
170
171 if (isset($options['partials_loader'])) {
172 $this->setPartialsLoader($options['partials_loader']);
173 }
174
175 if (isset($options['partials'])) {
176 $this->setPartials($options['partials']);
177 }
178
179 if (isset($options['helpers'])) {
180 $this->setHelpers($options['helpers']);
181 }
182
183 if (isset($options['escape'])) {
184 if (!is_callable($options['escape'])) {
185 throw new Mustache_Exception_InvalidArgumentException('Mustache Constructor "escape" option must be callable');
186 }
187
188 $this->escape = $options['escape'];
189 }
190
191 if (isset($options['entity_flags'])) {
192 $this->entityFlags = $options['entity_flags'];
193 }
194
195 if (isset($options['charset'])) {
196 $this->charset = $options['charset'];
197 }
198
199 if (isset($options['logger'])) {
200 $this->setLogger($options['logger']);
201 }
202
203 if (isset($options['strict_callables'])) {
204 $this->strictCallables = $options['strict_callables'];
205 }
206
207 if (isset($options['delimiters'])) {
208 $this->delimiters = $options['delimiters'];
209 }
210
211 if (isset($options['pragmas'])) {
212 foreach ($options['pragmas'] as $pragma) {
213 if (!isset(self::$knownPragmas[$pragma])) {
214 throw new Mustache_Exception_InvalidArgumentException(sprintf('Unknown pragma: "%s".', $pragma));
215 }
216 $this->pragmas[$pragma] = true;
217 }
218 }
219 }
220
221 /**
222 * Shortcut 'render' invocation.
223 *
224 * Equivalent to calling `$mustache->loadTemplate($template)->render($context);`
225 *
226 * @see Mustache_Engine::loadTemplate
227 * @see Mustache_Template::render
228 *
229 * @param string $template
230 * @param mixed $context (default: array())
231 *
232 * @return string Rendered template
233 */
234 public function render($template, $context = array())
235 {
236 return $this->loadTemplate($template)->render($context);
237 }
238
239 /**
240 * Get the current Mustache escape callback.
241 *
242 * @return callable|null
243 */
244 public function getEscape()
245 {
246 return $this->escape;
247 }
248
249 /**
250 * Get the current Mustache entitity type to escape.
251 *
252 * @return int
253 */
254 public function getEntityFlags()
255 {
256 return $this->entityFlags;
257 }
258
259 /**
260 * Get the current Mustache character set.
261 *
262 * @return string
263 */
264 public function getCharset()
265 {
266 return $this->charset;
267 }
268
269 /**
270 * Get the current globally enabled pragmas.
271 *
272 * @return array
273 */
274 public function getPragmas()
275 {
276 return array_keys($this->pragmas);
277 }
278
279 /**
280 * Set the Mustache template Loader instance.
281 *
282 * @param Mustache_Loader $loader
283 */
284 public function setLoader(Mustache_Loader $loader)
285 {
286 $this->loader = $loader;
287 }
288
289 /**
290 * Get the current Mustache template Loader instance.
291 *
292 * If no Loader instance has been explicitly specified, this method will instantiate and return
293 * a StringLoader instance.
294 *
295 * @return Mustache_Loader
296 */
297 public function getLoader()
298 {
299 if (!isset($this->loader)) {
300 $this->loader = new Mustache_Loader_StringLoader();
301 }
302
303 return $this->loader;
304 }
305
306 /**
307 * Set the Mustache partials Loader instance.
308 *
309 * @param Mustache_Loader $partialsLoader
310 */
311 public function setPartialsLoader(Mustache_Loader $partialsLoader)
312 {
313 $this->partialsLoader = $partialsLoader;
314 }
315
316 /**
317 * Get the current Mustache partials Loader instance.
318 *
319 * If no Loader instance has been explicitly specified, this method will instantiate and return
320 * an ArrayLoader instance.
321 *
322 * @return Mustache_Loader
323 */
324 public function getPartialsLoader()
325 {
326 if (!isset($this->partialsLoader)) {
327 $this->partialsLoader = new Mustache_Loader_ArrayLoader();
328 }
329
330 return $this->partialsLoader;
331 }
332
333 /**
334 * Set partials for the current partials Loader instance.
335 *
336 * @throws Mustache_Exception_RuntimeException If the current Loader instance is immutable
337 *
338 * @param array $partials (default: array())
339 */
340 public function setPartials(array $partials = array())
341 {
342 if (!isset($this->partialsLoader)) {
343 $this->partialsLoader = new Mustache_Loader_ArrayLoader();
344 }
345
346 if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) {
347 throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance');
348 }
349
350 $this->partialsLoader->setTemplates($partials);
351 }
352
353 /**
354 * Set an array of Mustache helpers.
355 *
356 * An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order sections), or
357 * any other valid Mustache context value. They will be prepended to the context stack, so they will be available in
358 * any template loaded by this Mustache instance.
359 *
360 * @throws Mustache_Exception_InvalidArgumentException if $helpers is not an array or Traversable
361 *
362 * @param array|Traversable $helpers
363 */
364 public function setHelpers($helpers)
365 {
366 if (!is_array($helpers) && !$helpers instanceof Traversable) {
367 throw new Mustache_Exception_InvalidArgumentException('setHelpers expects an array of helpers');
368 }
369
370 $this->getHelpers()->clear();
371
372 foreach ($helpers as $name => $helper) {
373 $this->addHelper($name, $helper);
374 }
375 }
376
377 /**
378 * Get the current set of Mustache helpers.
379 *
380 * @see Mustache_Engine::setHelpers
381 *
382 * @return Mustache_HelperCollection
383 */
384 public function getHelpers()
385 {
386 if (!isset($this->helpers)) {
387 $this->helpers = new Mustache_HelperCollection();
388 }
389
390 return $this->helpers;
391 }
392
393 /**
394 * Add a new Mustache helper.
395 *
396 * @see Mustache_Engine::setHelpers
397 *
398 * @param string $name
399 * @param mixed $helper
400 */
401 public function addHelper($name, $helper)
402 {
403 $this->getHelpers()->add($name, $helper);
404 }
405
406 /**
407 * Get a Mustache helper by name.
408 *
409 * @see Mustache_Engine::setHelpers
410 *
411 * @param string $name
412 *
413 * @return mixed Helper
414 */
415 public function getHelper($name)
416 {
417 return $this->getHelpers()->get($name);
418 }
419
420 /**
421 * Check whether this Mustache instance has a helper.
422 *
423 * @see Mustache_Engine::setHelpers
424 *
425 * @param string $name
426 *
427 * @return bool True if the helper is present
428 */
429 public function hasHelper($name)
430 {
431 return $this->getHelpers()->has($name);
432 }
433
434 /**
435 * Remove a helper by name.
436 *
437 * @see Mustache_Engine::setHelpers
438 *
439 * @param string $name
440 */
441 public function removeHelper($name)
442 {
443 $this->getHelpers()->remove($name);
444 }
445
446 /**
447 * Set the Mustache Logger instance.
448 *
449 * @throws Mustache_Exception_InvalidArgumentException If logger is not an instance of Mustache_Logger or Psr\Log\LoggerInterface
450 *
451 * @param Mustache_Logger|Psr\Log\LoggerInterface $logger
452 */
453 public function setLogger($logger = null)
454 {
455 if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
456 throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
457 }
458
459 if ($this->getCache()->getLogger() === null) {
460 $this->getCache()->setLogger($logger);
461 }
462
463 $this->logger = $logger;
464 }
465
466 /**
467 * Get the current Mustache Logger instance.
468 *
469 * @return Mustache_Logger|Psr\Log\LoggerInterface
470 */
471 public function getLogger()
472 {
473 return $this->logger;
474 }
475
476 /**
477 * Set the Mustache Tokenizer instance.
478 *
479 * @param Mustache_Tokenizer $tokenizer
480 */
481 public function setTokenizer(Mustache_Tokenizer $tokenizer)
482 {
483 $this->tokenizer = $tokenizer;
484 }
485
486 /**
487 * Get the current Mustache Tokenizer instance.
488 *
489 * If no Tokenizer instance has been explicitly specified, this method will instantiate and return a new one.
490 *
491 * @return Mustache_Tokenizer
492 */
493 public function getTokenizer()
494 {
495 if (!isset($this->tokenizer)) {
496 $this->tokenizer = new Mustache_Tokenizer();
497 }
498
499 return $this->tokenizer;
500 }
501
502 /**
503 * Set the Mustache Parser instance.
504 *
505 * @param Mustache_Parser $parser
506 */
507 public function setParser(Mustache_Parser $parser)
508 {
509 $this->parser = $parser;
510 }
511
512 /**
513 * Get the current Mustache Parser instance.
514 *
515 * If no Parser instance has been explicitly specified, this method will instantiate and return a new one.
516 *
517 * @return Mustache_Parser
518 */
519 public function getParser()
520 {
521 if (!isset($this->parser)) {
522 $this->parser = new Mustache_Parser();
523 }
524
525 return $this->parser;
526 }
527
528 /**
529 * Set the Mustache Compiler instance.
530 *
531 * @param Mustache_Compiler $compiler
532 */
533 public function setCompiler(Mustache_Compiler $compiler)
534 {
535 $this->compiler = $compiler;
536 }
537
538 /**
539 * Get the current Mustache Compiler instance.
540 *
541 * If no Compiler instance has been explicitly specified, this method will instantiate and return a new one.
542 *
543 * @return Mustache_Compiler
544 */
545 public function getCompiler()
546 {
547 if (!isset($this->compiler)) {
548 $this->compiler = new Mustache_Compiler();
549 }
550
551 return $this->compiler;
552 }
553
554 /**
555 * Set the Mustache Cache instance.
556 *
557 * @param Mustache_Cache $cache
558 */
559 public function setCache(Mustache_Cache $cache)
560 {
561 if (isset($this->logger) && $cache->getLogger() === null) {
562 $cache->setLogger($this->getLogger());
563 }
564
565 $this->cache = $cache;
566 }
567
568 /**
569 * Get the current Mustache Cache instance.
570 *
571 * If no Cache instance has been explicitly specified, this method will instantiate and return a new one.
572 *
573 * @return Mustache_Cache
574 */
575 public function getCache()
576 {
577 if (!isset($this->cache)) {
578 $this->setCache(new Mustache_Cache_NoopCache());
579 }
580
581 return $this->cache;
582 }
583
584 /**
585 * Get the current Lambda Cache instance.
586 *
587 * If 'cache_lambda_templates' is enabled, this is the default cache instance. Otherwise, it is a NoopCache.
588 *
589 * @see Mustache_Engine::getCache
590 *
591 * @return Mustache_Cache
592 */
593 protected function getLambdaCache()
594 {
595 if ($this->cacheLambdaTemplates) {
596 return $this->getCache();
597 }
598
599 if (!isset($this->lambdaCache)) {
600 $this->lambdaCache = new Mustache_Cache_NoopCache();
601 }
602
603 return $this->lambdaCache;
604 }
605
606 /**
607 * Helper method to generate a Mustache template class.
608 *
609 * This method must be updated any time options are added which make it so
610 * the same template could be parsed and compiled multiple different ways.
611 *
612 * @param string|Mustache_Source $source
613 *
614 * @return string Mustache Template class name
615 */
616 public function getTemplateClassName($source)
617 {
618 // For the most part, adding a new option here should do the trick.
619 //
620 // Pick a value here which is unique for each possible way the template
621 // could be compiled... but not necessarily unique per option value. See
622 // escape below, which only needs to differentiate between 'custom' and
623 // 'default' escapes.
624 //
625 // Keep this list in alphabetical order :)
626 $chunks = array(
627 'charset' => $this->charset,
628 'delimiters' => $this->delimiters ? $this->delimiters : '{{ }}',
629 'entityFlags' => $this->entityFlags,
630 'escape' => isset($this->escape) ? 'custom' : 'default',
631 'key' => ($source instanceof Mustache_Source) ? $source->getKey() : 'source',
632 'pragmas' => $this->getPragmas(),
633 'strictCallables' => $this->strictCallables,
634 'version' => self::VERSION,
635 );
636
637 $key = json_encode($chunks);
638
639 // Template Source instances have already provided their own source key. For strings, just include the whole
640 // source string in the md5 hash.
641 if (!$source instanceof Mustache_Source) {
642 $key .= "\n" . $source;
643 }
644
645 return $this->templateClassPrefix . md5($key);
646 }
647
648 /**
649 * Load a Mustache Template by name.
650 *
651 * @param string $name
652 *
653 * @return Mustache_Template
654 */
655 public function loadTemplate($name)
656 {
657 return $this->loadSource($this->getLoader()->load($name));
658 }
659
660 /**
661 * Load a Mustache partial Template by name.
662 *
663 * This is a helper method used internally by Template instances for loading partial templates. You can most likely
664 * ignore it completely.
665 *
666 * @param string $name
667 *
668 * @return Mustache_Template
669 */
670 public function loadPartial($name)
671 {
672 try {
673 if (isset($this->partialsLoader)) {
674 $loader = $this->partialsLoader;
675 } elseif (isset($this->loader) && !$this->loader instanceof Mustache_Loader_StringLoader) {
676 $loader = $this->loader;
677 } else {
678 throw new Mustache_Exception_UnknownTemplateException($name);
679 }
680
681 return $this->loadSource($loader->load($name));
682 } catch (Mustache_Exception_UnknownTemplateException $e) {
683 // If the named partial cannot be found, log then return null.
684 $this->log(
685 Mustache_Logger::WARNING,
686 'Partial not found: "{name}"',
687 array('name' => $e->getTemplateName())
688 );
689 }
690 }
691
692 /**
693 * Load a Mustache lambda Template by source.
694 *
695 * This is a helper method used by Template instances to generate subtemplates for Lambda sections. You can most
696 * likely ignore it completely.
697 *
698 * @param string $source
699 * @param string $delims (default: null)
700 *
701 * @return Mustache_Template
702 */
703 public function loadLambda($source, $delims = null)
704 {
705 if ($delims !== null) {
706 $source = $delims . "\n" . $source;
707 }
708
709 return $this->loadSource($source, $this->getLambdaCache());
710 }
711
712 /**
713 * Instantiate and return a Mustache Template instance by source.
714 *
715 * Optionally provide a Mustache_Cache instance. This is used internally by Mustache_Engine::loadLambda to respect
716 * the 'cache_lambda_templates' configuration option.
717 *
718 * @see Mustache_Engine::loadTemplate
719 * @see Mustache_Engine::loadPartial
720 * @see Mustache_Engine::loadLambda
721 *
722 * @param string|Mustache_Source $source
723 * @param Mustache_Cache $cache (default: null)
724 *
725 * @return Mustache_Template
726 */
727 private function loadSource($source, ?Mustache_Cache $cache = null)
728 {
729 $className = $this->getTemplateClassName($source);
730
731 if (!isset($this->templates[$className])) {
732 if ($cache === null) {
733 $cache = $this->getCache();
734 }
735
736 if (!class_exists($className, false)) {
737 if (!$cache->load($className)) {
738 $compiled = $this->compile($source);
739 $cache->cache($className, $compiled);
740 }
741 }
742
743 $this->log(
744 Mustache_Logger::DEBUG,
745 'Instantiating template: "{className}"',
746 array('className' => $className)
747 );
748
749 $this->templates[$className] = new $className($this);
750 }
751
752 return $this->templates[$className];
753 }
754
755 /**
756 * Helper method to tokenize a Mustache template.
757 *
758 * @see Mustache_Tokenizer::scan
759 *
760 * @param string $source
761 *
762 * @return array Tokens
763 */
764 private function tokenize($source)
765 {
766 return $this->getTokenizer()->scan($source, $this->delimiters);
767 }
768
769 /**
770 * Helper method to parse a Mustache template.
771 *
772 * @see Mustache_Parser::parse
773 *
774 * @param string $source
775 *
776 * @return array Token tree
777 */
778 private function parse($source)
779 {
780 $parser = $this->getParser();
781 $parser->setPragmas($this->getPragmas());
782
783 return $parser->parse($this->tokenize($source));
784 }
785
786 /**
787 * Helper method to compile a Mustache template.
788 *
789 * @see Mustache_Compiler::compile
790 *
791 * @param string|Mustache_Source $source
792 *
793 * @return string generated Mustache template class code
794 */
795 private function compile($source)
796 {
797 $name = $this->getTemplateClassName($source);
798
799 $this->log(
800 Mustache_Logger::INFO,
801 'Compiling template to "{className}" class',
802 array('className' => $name)
803 );
804
805 if ($source instanceof Mustache_Source) {
806 $source = $source->getSource();
807 }
808 $tree = $this->parse($source);
809
810 $compiler = $this->getCompiler();
811 $compiler->setPragmas($this->getPragmas());
812
813 return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
814 }
815
816 /**
817 * Add a log record if logging is enabled.
818 *
819 * @param int $level The logging level
820 * @param string $message The log message
821 * @param array $context The log context
822 */
823 private function log($level, $message, array $context = array())
824 {
825 if (isset($this->logger)) {
826 $this->logger->log($level, $message, $context);
827 }
828 }
829 }
830