diff --git a/src/BeSimple/SoapCommon/Util/MessageBinder.php b/src/BeSimple/SoapCommon/Util/MessageBinder.php new file mode 100644 index 0000000..d018355 --- /dev/null +++ b/src/BeSimple/SoapCommon/Util/MessageBinder.php @@ -0,0 +1,103 @@ + + * (c) Francis Besset + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace BeSimple\SoapCommon\Util; + +/** + * @author Francis Besset + */ +class MessageBinder +{ + /** + * @var Object + */ + protected $message; + + /** + * @var \ReflectionClass + */ + protected $reflectionClass; + + public function __construct($message) + { + if (!is_object($message)) { + throw new \InvalidArgumentException(sprintf('The message must be an object, %s given', gettype($message))); + } + + $this->message = $message; + $this->reflectionClass = new \ReflectionClass($this->message); + } + + public function readProperty($property) + { + if ($this->reflectionClass->hasMethod($getter = 'get'.$property)) { + if (!$this->reflectionClass->getMethod($getter)->isPublic()) { + throw new \RuntimeException(sprintf('Method "%s()" is not public in class "%s"', $getter, $this->reflectionClass->name)); + } + + $value = $this->message->{$getter}(); + } elseif ($this->reflectionClass->hasMethod($isser = 'is'.$property)) { + if (!$this->reflectionClass->getMethod($isser)->isPublic()) { + throw new \RuntimeException(sprintf('Method "%s()" is not public in class "%s"', $isser, $this->reflectionClass->name)); + } + + $value = $this->message->{$isser}(); + } elseif ($this->reflectionClass->hasMethod($hasser = 'has'.$property)) { + if (!$this->reflectionClass->getMethod($hasser)->isPublic()) { + throw new \RuntimeException(sprintf('Method "%s()" is not public in class "%s"', $hasser, $this->reflectionClass->name)); + } + + $value = $this->message->{$hasser}(); + } elseif ($this->reflectionClass->hasMethod('__get')) { + // needed to support magic method __get + $value = $this->message->{$property}; + } elseif ($this->reflectionClass->hasProperty($property)) { + if (!$this->reflectionClass->getProperty($property)->isPublic()) { + throw new \RuntimeException(sprintf('Property "%s" is not public in class "%s". Maybe you should create the method "%s()" or "%s()" or "%s()"?', $property, $this->reflectionClass->name, $getter, $isser, $hasser)); + } + + $value = $this->message->{$property}; + } elseif (property_exists($this->message, $property)) { + // needed to support \stdClass instances + $value = $this->message->{$property}; + } else { + throw new \RuntimeException(sprintf('Neither property "%s" nor method "%s()" nor method "%s()" exists in class "%s"', $property, $getter, $isser, $this->reflectionClass->name)); + } + + return $value; + } + + public function writeProperty($property, $value) + { + if ($this->reflectionClass->hasMethod($setter = 'set'.$property)) { + if (!$this->reflectionClass->getMethod($setter)->isPublic()) { + throw new \RuntimeException(sprintf('Method "%s()" is not public in class "%s"', $setter, $this->reflectionClass->name)); + } + + $this->message->{$setter}($value); + } elseif ($this->reflectionClass->hasMethod('__set')) { + // needed to support magic method __set + $this->message->{$property} = $value; + } elseif ($this->reflectionClass->hasProperty($property)) { + if (!$this->reflectionClass->getProperty($property)->isPublic()) { + throw new \RuntimeException(sprintf('Property "%s" is not public in class "%s". Maybe you should create the method "%s()"?', $property, $this->reflectionClass->name, $setter)); + } + + $this->message->{$property} = $value; + } elseif (property_exists($this->message, $property)) { + // needed to support \stdClass instances + $this->message->{$property} = $value; + } else { + throw new \RuntimeException(sprintf('Neither element "%s" nor method "%s()" exists in class "%s"', $property, $setter, $this->reflectionClass->name)); + } + } +}