PluginProbe
Depicter — Popup & Slider Builder / 1.3.2
Depicter — Popup & Slider Builder v1.3.2
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / vendor / netresearch / jsonmapper / src / JsonMapper.php

JsonMapper.php in Depicter — Popup & Slider Builder 1.3.2, at vendor/netresearch/jsonmapper/src/JsonMapper.php

851 lines 27.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Part of JsonMapper
4 *
5 * PHP version 5
6 *
7 * @category Netresearch
8 * @package JsonMapper
9 * @author Christian Weiske <cweiske@cweiske.de>
10 * @license OSL-3.0 http://opensource.org/licenses/osl-3.0
11 * @link http://cweiske.de/
12 */
13
14 /**
15 * Automatically map JSON structures into objects.
16 *
17 * @category Netresearch
18 * @package JsonMapper
19 * @author Christian Weiske <cweiske@cweiske.de>
20 * @license OSL-3.0 http://opensource.org/licenses/osl-3.0
21 * @link http://cweiske.de/
22 */
23 class JsonMapper
24 {
25 /**
26 * PSR-3 compatible logger object
27 *
28 * @link http://www.php-fig.org/psr/psr-3/
29 * @var object
30 * @see setLogger()
31 */
32 protected $logger;
33
34 /**
35 * Throw an exception when JSON data contain a property
36 * that is not defined in the PHP class
37 *
38 * @var boolean
39 */
40 public $bExceptionOnUndefinedProperty = false;
41
42 /**
43 * Throw an exception if the JSON data miss a property
44 * that is marked with @required in the PHP class
45 *
46 * @var boolean
47 */
48 public $bExceptionOnMissingData = false;
49
50 /**
51 * If the types of map() parameters shall be checked.
52 *
53 * You have to disable it if you're using the json_decode "assoc" parameter.
54 *
55 * json_decode($str, false)
56 *
57 * @var boolean
58 */
59 public $bEnforceMapType = true;
60
61 /**
62 * Throw an exception when an object is expected but the JSON contains
63 * a non-object type.
64 *
65 * @var boolean
66 */
67 public $bStrictObjectTypeChecking = false;
68
69 /**
70 * Throw an exception, if null value is found
71 * but the type of attribute does not allow nulls.
72 *
73 * @var bool
74 */
75 public $bStrictNullTypes = true;
76
77 /**
78 * Allow mapping of private and proteted properties.
79 *
80 * @var boolean
81 */
82 public $bIgnoreVisibility = false;
83
84 /**
85 * Remove attributes that were not passed in JSON,
86 * to avoid confusion between them and NULL values.
87 *
88 * @var boolean
89 */
90 public $bRemoveUndefinedAttributes = false;
91
92 /**
93 * Override class names that JsonMapper uses to create objects.
94 * Useful when your setter methods accept abstract classes or interfaces.
95 *
96 * @var array
97 */
98 public $classMap = array();
99
100 /**
101 * Callback used when an undefined property is found.
102 *
103 * Works only when $bExceptionOnUndefinedProperty is disabled.
104 *
105 * Parameters to this function are:
106 * 1. Object that is being filled
107 * 2. Name of the unknown JSON property
108 * 3. JSON value of the property
109 *
110 * @var callable
111 */
112 public $undefinedPropertyHandler = null;
113
114 /**
115 * Runtime cache for inspected classes. This is particularly effective if
116 * mapArray() is called with a large number of objects
117 *
118 * @var array property inspection result cache
119 */
120 protected $arInspectedClasses = array();
121
122 /**
123 * Method to call on each object after deserialization is done.
124 *
125 * Is only called if it exists on the object.
126 *
127 * @var string|null
128 */
129 public $postMappingMethod = null;
130
131 /**
132 * Map data all data in $json into the given $object instance.
133 *
134 * @param object|array $json JSON object structure from json_decode()
135 * @param object $object Object to map $json data into
136 *
137 * @return mixed Mapped object is returned.
138 * @see mapArray()
139 */
140 public function map($json, $object)
141 {
142 if ($this->bEnforceMapType && !is_object($json)) {
143 throw new InvalidArgumentException(
144 'JsonMapper::map() requires first argument to be an object'
145 . ', ' . gettype($json) . ' given.'
146 );
147 }
148 if (!is_object($object)) {
149 throw new InvalidArgumentException(
150 'JsonMapper::map() requires second argument to be an object'
151 . ', ' . gettype($object) . ' given.'
152 );
153 }
154
155 $strClassName = get_class($object);
156 $rc = new ReflectionClass($object);
157 $strNs = $rc->getNamespaceName();
158 $providedProperties = array();
159 foreach ($json as $key => $jvalue) {
160 $key = $this->getSafeName($key);
161 $providedProperties[$key] = true;
162
163 // Store the property inspection results so we don't have to do it
164 // again for subsequent objects of the same type
165 if (!isset($this->arInspectedClasses[$strClassName][$key])) {
166 $this->arInspectedClasses[$strClassName][$key]
167 = $this->inspectProperty($rc, $key);
168 }
169
170 list($hasProperty, $accessor, $type, $isNullable)
171 = $this->arInspectedClasses[$strClassName][$key];
172
173 if (!$hasProperty) {
174 if ($this->bExceptionOnUndefinedProperty) {
175 throw new JsonMapper_Exception(
176 'JSON property "' . $key . '" does not exist'
177 . ' in object of type ' . $strClassName
178 );
179 } else if ($this->undefinedPropertyHandler !== null) {
180 call_user_func(
181 $this->undefinedPropertyHandler,
182 $object, $key, $jvalue
183 );
184 } else {
185 $this->log(
186 'info',
187 'Property {property} does not exist in {class}',
188 array('property' => $key, 'class' => $strClassName)
189 );
190 }
191 continue;
192 }
193
194 if ($accessor === null) {
195 if ($this->bExceptionOnUndefinedProperty) {
196 throw new JsonMapper_Exception(
197 'JSON property "' . $key . '" has no public setter method'
198 . ' in object of type ' . $strClassName
199 );
200 }
201 $this->log(
202 'info',
203 'Property {property} has no public setter method in {class}',
204 array('property' => $key, 'class' => $strClassName)
205 );
206 continue;
207 }
208
209 if ($isNullable || !$this->bStrictNullTypes) {
210 if ($jvalue === null) {
211 $this->setProperty($object, $accessor, null);
212 continue;
213 }
214 $type = $this->removeNullable($type);
215 } else if ($jvalue === null) {
216 throw new JsonMapper_Exception(
217 'JSON property "' . $key . '" in class "'
218 . $strClassName . '" must not be NULL'
219 );
220 }
221
222 $type = $this->getFullNamespace($type, $strNs);
223 $type = $this->getMappedType($type, $jvalue);
224
225 if ($type === null || $type === 'mixed') {
226 //no given type - simply set the json data
227 $this->setProperty($object, $accessor, $jvalue);
228 continue;
229 } else if ($this->isObjectOfSameType($type, $jvalue)) {
230 $this->setProperty($object, $accessor, $jvalue);
231 continue;
232 } else if ($this->isSimpleType($type)) {
233 if ($type === 'string' && is_object($jvalue)) {
234 throw new JsonMapper_Exception(
235 'JSON property "' . $key . '" in class "'
236 . $strClassName . '" is an object and'
237 . ' cannot be converted to a string'
238 );
239 }
240 settype($jvalue, $type);
241 $this->setProperty($object, $accessor, $jvalue);
242 continue;
243 }
244
245 //FIXME: check if type exists, give detailed error message if not
246 if ($type === '') {
247 throw new JsonMapper_Exception(
248 'Empty type at property "'
249 . $strClassName . '::$' . $key . '"'
250 );
251 }
252
253 $array = null;
254 $subtype = null;
255 if ($this->isArrayOfType($type)) {
256 //array
257 $array = array();
258 $subtype = substr($type, 0, -2);
259 } else if (substr($type, -1) == ']') {
260 list($proptype, $subtype) = explode('[', substr($type, 0, -1));
261 if ($proptype == 'array') {
262 $array = array();
263 } else {
264 $array = $this->createInstance($proptype, false, $jvalue);
265 }
266 } else {
267 if (is_a($type, 'ArrayObject', true)) {
268 $array = $this->createInstance($type, false, $jvalue);
269 }
270 }
271
272 if ($array !== null) {
273 if (!is_array($jvalue) && $this->isFlatType(gettype($jvalue))) {
274 throw new JsonMapper_Exception(
275 'JSON property "' . $key . '" must be an array, '
276 . gettype($jvalue) . ' given'
277 );
278 }
279
280 $cleanSubtype = $this->removeNullable($subtype);
281 $subtype = $this->getFullNamespace($cleanSubtype, $strNs);
282 $child = $this->mapArray($jvalue, $array, $subtype, $key);
283 } else if ($this->isFlatType(gettype($jvalue))) {
284 //use constructor parameter if we have a class
285 // but only a flat type (i.e. string, int)
286 if ($this->bStrictObjectTypeChecking) {
287 throw new JsonMapper_Exception(
288 'JSON property "' . $key . '" must be an object, '
289 . gettype($jvalue) . ' given'
290 );
291 }
292 $child = $this->createInstance($type, true, $jvalue);
293 } else {
294 $child = $this->createInstance($type, false, $jvalue);
295 $this->map($jvalue, $child);
296 }
297 $this->setProperty($object, $accessor, $child);
298 }
299
300 if ($this->bExceptionOnMissingData) {
301 $this->checkMissingData($providedProperties, $rc);
302 }
303
304 if ($this->bRemoveUndefinedAttributes) {
305 $this->removeUndefinedAttributes($object, $providedProperties);
306 }
307
308 if ($this->postMappingMethod !== null
309 && $rc->hasMethod($this->postMappingMethod)
310 ) {
311 $refDeserializePostMethod = $rc->getMethod(
312 $this->postMappingMethod
313 );
314 $refDeserializePostMethod->setAccessible(true);
315 $refDeserializePostMethod->invoke($object);
316 }
317
318 return $object;
319 }
320
321 /**
322 * Convert a type name to a fully namespaced type name.
323 *
324 * @param string $type Type name (simple type or class name)
325 * @param string $strNs Base namespace that gets prepended to the type name
326 *
327 * @return string Fully-qualified type name with namespace
328 */
329 protected function getFullNamespace($type, $strNs)
330 {
331 if ($type === null || $type === '' || $type[0] === '\\' || $strNs === '') {
332 return $type;
333 }
334 list($first) = explode('[', $type, 2);
335 if ($first === 'mixed' || $this->isSimpleType($first)) {
336 return $type;
337 }
338
339 //create a full qualified namespace
340 return '\\' . $strNs . '\\' . $type;
341 }
342
343 /**
344 * Check required properties exist in json
345 *
346 * @param array $providedProperties array with json properties
347 * @param object $rc Reflection class to check
348 *
349 * @throws JsonMapper_Exception
350 *
351 * @return void
352 */
353 protected function checkMissingData($providedProperties, ReflectionClass $rc)
354 {
355 foreach ($rc->getProperties() as $property) {
356 $rprop = $rc->getProperty($property->name);
357 $docblock = $rprop->getDocComment();
358 $annotations = static::parseAnnotations($docblock);
359 if (isset($annotations['required'])
360 && !isset($providedProperties[$property->name])
361 ) {
362 throw new JsonMapper_Exception(
363 'Required property "' . $property->name . '" of class '
364 . $rc->getName()
365 . ' is missing in JSON data'
366 );
367 }
368 }
369 }
370
371 /**
372 * Remove attributes from object that were not passed in JSON data.
373 *
374 * This is to avoid confusion between those that were actually passed
375 * as NULL, and those that weren't provided at all.
376 *
377 * @param object $object Object to remove properties from
378 * @param array $providedProperties Array with JSON properties
379 *
380 * @return void
381 */
382 protected function removeUndefinedAttributes($object, $providedProperties)
383 {
384 foreach (get_object_vars($object) as $propertyName => $dummy) {
385 if (!isset($providedProperties[$propertyName])) {
386 unset($object->{$propertyName});
387 }
388 }
389 }
390
391 /**
392 * Map an array
393 *
394 * @param array $json JSON array structure from json_decode()
395 * @param mixed $array Array or ArrayObject that gets filled with
396 * data from $json
397 * @param string $class Class name for children objects.
398 * All children will get mapped onto this type.
399 * Supports class names and simple types
400 * like "string" and nullability "string|null".
401 * Pass "null" to not convert any values
402 * @param string $parent_key Defines the key this array belongs to
403 * in order to aid debugging.
404 *
405 * @return mixed Mapped $array is returned
406 */
407 public function mapArray($json, $array, $class = null, $parent_key = '')
408 {
409 $originalClass = $class;
410 foreach ($json as $key => $jvalue) {
411 $class = $this->getMappedType($originalClass, $jvalue);
412 if ($class === null) {
413 $array[$key] = $jvalue;
414 } else if ($this->isArrayOfType($class)) {
415 $array[$key] = $this->mapArray(
416 $jvalue,
417 array(),
418 substr($class, 0, -2)
419 );
420 } else if ($this->isFlatType(gettype($jvalue))) {
421 //use constructor parameter if we have a class
422 // but only a flat type (i.e. string, int)
423 if ($jvalue === null) {
424 $array[$key] = null;
425 } else {
426 if ($this->isSimpleType($class)) {
427 settype($jvalue, $class);
428 $array[$key] = $jvalue;
429 } else {
430 $array[$key] = $this->createInstance(
431 $class, true, $jvalue
432 );
433 }
434 }
435 } else if ($this->isFlatType($class)) {
436 throw new JsonMapper_Exception(
437 'JSON property "' . ($parent_key ? $parent_key : '?') . '"'
438 . ' is an array of type "' . $class . '"'
439 . ' but contained a value of type'
440 . ' "' . gettype($jvalue) . '"'
441 );
442 } else if (is_a($class, 'ArrayObject', true)) {
443 $array[$key] = $this->mapArray(
444 $jvalue,
445 $this->createInstance($class)
446 );
447 } else {
448 $array[$key] = $this->map(
449 $jvalue, $this->createInstance($class, false, $jvalue)
450 );
451 }
452 }
453 return $array;
454 }
455
456 /**
457 * Try to find out if a property exists in a given class.
458 * Checks property first, falls back to setter method.
459 *
460 * @param ReflectionClass $rc Reflection class to check
461 * @param string $name Property name
462 *
463 * @return array First value: if the property exists
464 * Second value: the accessor to use (
465 * ReflectionMethod or ReflectionProperty, or null)
466 * Third value: type of the property
467 * Fourth value: if the property is nullable
468 */
469 protected function inspectProperty(ReflectionClass $rc, $name)
470 {
471 //try setter method first
472 $setter = 'set' . $this->getCamelCaseName($name);
473
474 if ($rc->hasMethod($setter)) {
475 $rmeth = $rc->getMethod($setter);
476 if ($rmeth->isPublic() || $this->bIgnoreVisibility) {
477 $isNullable = false;
478 $rparams = $rmeth->getParameters();
479 if (count($rparams) > 0) {
480 $isNullable = $rparams[0]->allowsNull();
481 $ptype = $rparams[0]->getType();
482 if ($ptype !== null) {
483 if ($ptype instanceof ReflectionNamedType) {
484 $typeName = $ptype->getName();
485 }
486 if ($ptype instanceof ReflectionUnionType
487 || !$ptype->isBuiltin()
488 ) {
489 $typeName = '\\' . $typeName;
490 }
491 //allow overriding an "array" type hint
492 // with a more specific class in the docblock
493 if ($typeName !== 'array') {
494 return array(
495 true, $rmeth,
496 $typeName,
497 $isNullable,
498 );
499 }
500 }
501 }
502
503 $docblock = $rmeth->getDocComment();
504 $annotations = static::parseAnnotations($docblock);
505
506 if (!isset($annotations['param'][0])) {
507 return array(true, $rmeth, null, $isNullable);
508 }
509 list($type) = explode(' ', trim($annotations['param'][0]));
510 return array(true, $rmeth, $type, $this->isNullable($type));
511 }
512 }
513
514 //now try to set the property directly
515 //we have to look it up in the class hierarchy
516 $class = $rc;
517 $rprop = null;
518 do {
519 if ($class->hasProperty($name)) {
520 $rprop = $class->getProperty($name);
521 }
522 } while ($rprop === null && $class = $class->getParentClass());
523
524 if ($rprop === null) {
525 //case-insensitive property matching
526 foreach ($rc->getProperties() as $p) {
527 if ((strcasecmp($p->name, $name) === 0)) {
528 $rprop = $p;
529 break;
530 }
531 }
532 }
533 if ($rprop !== null) {
534 if ($rprop->isPublic() || $this->bIgnoreVisibility) {
535 $docblock = $rprop->getDocComment();
536 $annotations = static::parseAnnotations($docblock);
537
538 if (!isset($annotations['var'][0])) {
539 // If there is no annotations (higher priority) inspect
540 // if there's a scalar type being defined
541 if (PHP_VERSION_ID >= 70400 && $rprop->hasType()) {
542 $rPropType = $rprop->getType();
543 $propTypeName = $rPropType->getName();
544
545 if ($this->isSimpleType($propTypeName)) {
546 return array(
547 true,
548 $rprop,
549 $propTypeName,
550 $rPropType->allowsNull()
551 );
552 }
553
554 return array(
555 true,
556 $rprop,
557 '\\'.$propTypeName,
558 $rPropType->allowsNull()
559 );
560 }
561
562 return array(true, $rprop, null, false);
563 }
564
565 //support "@var type description"
566 list($type) = explode(' ', $annotations['var'][0]);
567
568 return array(true, $rprop, $type, $this->isNullable($type));
569 } else {
570 //no setter, private property
571 return array(true, null, null, false);
572 }
573 }
574
575 //no setter, no property
576 return array(false, null, null, false);
577 }
578
579 /**
580 * Removes - and _ and makes the next letter uppercase
581 *
582 * @param string $name Property name
583 *
584 * @return string CamelCasedVariableName
585 */
586 protected function getCamelCaseName($name)
587 {
588 return str_replace(
589 ' ', '', ucwords(str_replace(array('_', '-'), ' ', $name))
590 );
591 }
592
593 /**
594 * Since hyphens cannot be used in variables we have to uppercase them.
595 *
596 * Technically you may use them, but they are awkward to access.
597 *
598 * @param string $name Property name
599 *
600 * @return string Name without hyphen
601 */
602 protected function getSafeName($name)
603 {
604 if (strpos($name, '-') !== false) {
605 $name = $this->getCamelCaseName($name);
606 }
607
608 return $name;
609 }
610
611 /**
612 * Set a property on a given object to a given value.
613 *
614 * Checks if the setter or the property are public are made before
615 * calling this method.
616 *
617 * @param object $object Object to set property on
618 * @param object $accessor ReflectionMethod or ReflectionProperty
619 * @param mixed $value Value of property
620 *
621 * @return void
622 */
623 protected function setProperty(
624 $object, $accessor, $value
625 ) {
626 if (!$accessor->isPublic() && $this->bIgnoreVisibility) {
627 $accessor->setAccessible(true);
628 }
629 if ($accessor instanceof ReflectionProperty) {
630 $accessor->setValue($object, $value);
631 } else {
632 //setter method
633 $accessor->invoke($object, $value);
634 }
635 }
636
637 /**
638 * Create a new object of the given type.
639 *
640 * This method exists to be overwritten in child classes,
641 * so you can do dependency injection or so.
642 *
643 * @param string $class Class name to instantiate
644 * @param boolean $useParameter Pass $parameter to the constructor or not
645 * @param mixed $jvalue Constructor parameter (the json value)
646 *
647 * @return object Freshly created object
648 */
649 protected function createInstance(
650 $class, $useParameter = false, $jvalue = null
651 ) {
652 if ($useParameter) {
653 return new $class($jvalue);
654 } else {
655 $reflectClass = new ReflectionClass($class);
656 $constructor = $reflectClass->getConstructor();
657 if (null === $constructor
658 || $constructor->getNumberOfRequiredParameters() > 0
659 ) {
660 return $reflectClass->newInstanceWithoutConstructor();
661 }
662 return $reflectClass->newInstance();
663 }
664 }
665
666 /**
667 * Get the mapped class/type name for this class.
668 * Returns the incoming classname if not mapped.
669 *
670 * @param string $type Type name to map
671 * @param mixed $jvalue Constructor parameter (the json value)
672 *
673 * @return string The mapped type/class name
674 */
675 protected function getMappedType($type, $jvalue = null)
676 {
677 if (isset($this->classMap[$type])) {
678 $target = $this->classMap[$type];
679 } else if (is_string($type) && $type !== '' && $type[0] == '\\'
680 && isset($this->classMap[substr($type, 1)])
681 ) {
682 $target = $this->classMap[substr($type, 1)];
683 } else {
684 $target = null;
685 }
686
687 if ($target) {
688 if (is_callable($target)) {
689 $type = $target($type, $jvalue);
690 } else {
691 $type = $target;
692 }
693 }
694 return $type;
695 }
696
697 /**
698 * Checks if the given type is a "simple type"
699 *
700 * @param string $type type name from gettype()
701 *
702 * @return boolean True if it is a simple PHP type
703 *
704 * @see isFlatType()
705 */
706 protected function isSimpleType($type)
707 {
708 return $type == 'string'
709 || $type == 'boolean' || $type == 'bool'
710 || $type == 'integer' || $type == 'int'
711 || $type == 'double' || $type == 'float'
712 || $type == 'array' || $type == 'object';
713 }
714
715 /**
716 * Checks if the object is of this type or has this type as one of its parents
717 *
718 * @param string $type class name of type being required
719 * @param mixed $value Some PHP value to be tested
720 *
721 * @return boolean True if $object has type of $type
722 */
723 protected function isObjectOfSameType($type, $value)
724 {
725 if (false === is_object($value)) {
726 return false;
727 }
728
729 return is_a($value, $type);
730 }
731
732 /**
733 * Checks if the given type is a type that is not nested
734 * (simple type except array and object)
735 *
736 * @param string $type type name from gettype()
737 *
738 * @return boolean True if it is a non-nested PHP type
739 *
740 * @see isSimpleType()
741 */
742 protected function isFlatType($type)
743 {
744 return $type == 'NULL'
745 || $type == 'string'
746 || $type == 'boolean' || $type == 'bool'
747 || $type == 'integer' || $type == 'int'
748 || $type == 'double' || $type == 'float';
749 }
750
751 /**
752 * Returns true if type is an array of elements
753 * (bracket notation)
754 *
755 * @param string $strType type to be matched
756 *
757 * @return bool
758 */
759 protected function isArrayOfType($strType)
760 {
761 return substr($strType, -2) === '[]';
762 }
763
764 /**
765 * Checks if the given type is nullable
766 *
767 * @param string $type type name from the phpdoc param
768 *
769 * @return boolean True if it is nullable
770 */
771 protected function isNullable($type)
772 {
773 return stripos('|' . $type . '|', '|null|') !== false;
774 }
775
776 /**
777 * Remove the 'null' section of a type
778 *
779 * @param string $type type name from the phpdoc param
780 *
781 * @return string The new type value
782 */
783 protected function removeNullable($type)
784 {
785 if ($type === null) {
786 return null;
787 }
788 return substr(
789 str_ireplace('|null|', '|', '|' . $type . '|'),
790 1, -1
791 );
792 }
793
794 /**
795 * Copied from PHPUnit 3.7.29, Util/Test.php
796 *
797 * @param string $docblock Full method docblock
798 *
799 * @return array Array of arrays.
800 * Key is the "@"-name like "param",
801 * each value is an array of the rest of the @-lines
802 */
803 protected static function parseAnnotations($docblock)
804 {
805 $annotations = array();
806 // Strip away the docblock header and footer
807 // to ease parsing of one line annotations
808 $docblock = substr($docblock, 3, -2);
809
810 $re = '/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m';
811 if (preg_match_all($re, $docblock, $matches)) {
812 $numMatches = count($matches[0]);
813
814 for ($i = 0; $i < $numMatches; ++$i) {
815 $annotations[$matches['name'][$i]][] = $matches['value'][$i];
816 }
817 }
818
819 return $annotations;
820 }
821
822 /**
823 * Log a message to the $logger object
824 *
825 * @param string $level Logging level
826 * @param string $message Text to log
827 * @param array $context Additional information
828 *
829 * @return null
830 */
831 protected function log($level, $message, array $context = array())
832 {
833 if ($this->logger) {
834 $this->logger->log($level, $message, $context);
835 }
836 }
837
838 /**
839 * Sets a logger instance on the object
840 *
841 * @param LoggerInterface $logger PSR-3 compatible logger object
842 *
843 * @return null
844 */
845 public function setLogger($logger)
846 {
847 $this->logger = $logger;
848 }
849 }
850 ?>
851