Add 'src/BeSimple/SoapBundle/' from commit 'e99f707b105c0a0472260d8d42a5a14a7fb7a211'

git-subtree-dir: src/BeSimple/SoapBundle
git-subtree-mainline: 9a8d23fa23
git-subtree-split: e99f707b10
This commit is contained in:
Francis Besset
2013-07-19 17:00:11 +02:00
94 changed files with 5786 additions and 0 deletions

View File

@ -0,0 +1,35 @@
<?php
/*
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl <christian-kerl@web.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method;
/**
* @author Christian Kerl <christian-kerl@web.de>
*/
class DocumentLiteralWrappedRequestMessageBinder implements MessageBinderInterface
{
public function processMessage(Method $messageDefinition, $message)
{
if(count($message) > 1) {
throw new \InvalidArgumentException();
}
$result = array();
$message = $message[0];
foreach($messageDefinition->getArguments() as $argument) {
$result[$argument->getName()] = $message->{$argument->getName()};
}
return $result;
}
}

View File

@ -0,0 +1,27 @@
<?php
/*
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl <christian-kerl@web.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method;
/**
* @author Christian Kerl <christian-kerl@web.de>
*/
class DocumentLiteralWrappedResponseMessageBinder implements MessageBinderInterface
{
public function processMessage(Method $messageDefinition, $message)
{
$result = new \stdClass();
$result->{$messageDefinition->getName().'Result'} = $message;
return $result;
}
}

View File

@ -0,0 +1,27 @@
<?php
/*
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl <christian-kerl@web.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method;
/**
* @author Christian Kerl <christian-kerl@web.de>
*/
interface MessageBinderInterface
{
/**
* @param Method $messageDefinition
* @param mixed $message
*
* @return mixed
*/
function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array());
}

View File

@ -0,0 +1,33 @@
<?php
/*
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl <christian-kerl@web.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method;
/**
* @author Francis Besset <francis.besset@gmail.com>
*/
class RpcLiteralRequestHeaderMessageBinder extends RpcLiteralRequestMessageBinder
{
private $header;
public function setHeader($header)
{
$this->header = $header;
}
public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array())
{
$headerDefinition = $messageDefinition->getHeaders()->get($this->header);
return $this->processType($headerDefinition->getType()->getPhpType(), $message, $definitionComplexTypes);
}
}

View File

@ -0,0 +1,118 @@
<?php
/*
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl <christian-kerl@web.de>
* (c) Francis Besset <francis.besset@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method;
use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType;
use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType;
use BeSimple\SoapCommon\Util\MessageBinder;
/**
* @author Christian Kerl <christian-kerl@web.de>
* @author Francis Besset <francis.besset@gmail.com>
*/
class RpcLiteralRequestMessageBinder implements MessageBinderInterface
{
private $messageRefs = array();
private $definitionComplexTypes;
public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array())
{
$this->definitionComplexTypes = $definitionComplexTypes;
$result = array();
$i = 0;
foreach ($messageDefinition->getArguments() as $argument) {
if (isset($message[$i])) {
$result[$argument->getName()] = $this->processType($argument->getType()->getPhpType(), $message[$i]);
}
$i++;
}
return $result;
}
protected function processType($phpType, $message)
{
$isArray = false;
if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) {
$isArray = true;
$array = array();
$phpType = $match[1];
}
// @TODO Fix array reference
if (isset($this->definitionComplexTypes[$phpType])) {
if ($isArray) {
if (isset($message->item)) {
foreach ($message->item as $complexType) {
$array[] = $this->checkComplexType($phpType, $complexType);
}
// See https://github.com/BeSimple/BeSimpleSoapBundle/issues/29
if (in_array('BeSimple\SoapCommon\Type\AbstractKeyValue', class_parents($phpType))) {
$assocArray = array();
foreach ($array as $keyValue) {
$assocArray[$keyValue->getKey()] = $keyValue->getValue();
}
$array = $assocArray;
}
}
$message = $array;
} else {
$message = $this->checkComplexType($phpType, $message);
}
} elseif ($isArray) {
if (isset($message->item)) {
$message = $message->item;
} else {
$message = $array;
}
}
return $message;
}
protected function checkComplexType($phpType, $message)
{
$hash = spl_object_hash($message);
if (isset($this->messageRefs[$hash])) {
return $this->messageRefs[$hash];
}
$this->messageRefs[$hash] = $message;
$messageBinder = new MessageBinder($message);
foreach ($this->definitionComplexTypes[$phpType] as $type) {
$property = $type->getName();
$value = $messageBinder->readProperty($property);
if (null !== $value) {
$value = $this->processType($type->getValue(), $value);
$messageBinder->writeProperty($property, $value);
}
if (!$type->isNillable() && null === $value) {
throw new \SoapFault('SOAP_ERROR_COMPLEX_TYPE', sprintf('"%s:%s" cannot be null.', ucfirst($phpType), $type->getName()));
}
}
return $message;
}
}

View File

@ -0,0 +1,103 @@
<?php
/*
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl <christian-kerl@web.de>
* (c) Francis Besset <francis.besset@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method;
use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType;
use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType;
use BeSimple\SoapCommon\Util\MessageBinder;
/**
* @author Christian Kerl <christian-kerl@web.de>
* @author Francis Besset <francis.besset@gmail.com>
*/
class RpcLiteralResponseMessageBinder implements MessageBinderInterface
{
private $messageRefs = array();
private $definitionComplexTypes;
public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array())
{
$this->definitionComplexTypes = $definitionComplexTypes;
return $this->processType($messageDefinition->getReturn()->getPhpType(), $message);
}
private function processType($phpType, $message)
{
$isArray = false;
if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) {
$isArray = true;
$phpType = $match[1];
}
if (isset($this->definitionComplexTypes[$phpType])) {
if ($isArray) {
$array = array();
// See https://github.com/BeSimple/BeSimpleSoapBundle/issues/29
if (is_array($message) && in_array('BeSimple\SoapCommon\Type\AbstractKeyValue', class_parents($phpType))) {
$keyValue = array();
foreach ($message as $key => $value) {
$keyValue[] = new $phpType($key, $value);
}
$message = $keyValue;
}
foreach ($message as $complexType) {
$array[] = $this->checkComplexType($phpType, $complexType);
}
$message = $array;
} else {
$message = $this->checkComplexType($phpType, $message);
}
}
return $message;
}
private function checkComplexType($phpType, $message)
{
$hash = spl_object_hash($message);
if (isset($this->messageRefs[$hash])) {
return $this->messageRefs[$hash];
}
$this->messageRefs[$hash] = $message;
if (!$message instanceof $phpType) {
throw new \InvalidArgumentException(sprintf('The instance class must be "%s", "%s" given.', get_class($message), $phpType));
}
$messageBinder = new MessageBinder($message);
foreach ($this->definitionComplexTypes[$phpType] as $type) {
$property = $type->getName();
$value = $messageBinder->readProperty($property);
if (null !== $value) {
$value = $this->processType($type->getValue(), $value);
$messageBinder->writeProperty($property, $value);
}
if (!$type->isNillable() && null === $value) {
throw new \InvalidArgumentException(sprintf('"%s::%s" cannot be null.', $phpType, $type->getName()));
}
}
return $message;
}
}

View File

@ -0,0 +1,124 @@
<?php
/*
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl <christian-kerl@web.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Header;
use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition;
use BeSimple\SoapBundle\Soap\SoapHeader;
/**
* @author Christian Kerl <christian-kerl@web.de>
*/
class ServiceBinder
{
/**
* @var \BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition
*/
private $definition;
/**
* @var \BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface
*/
private $requestHeaderMessageBinder;
/**
* @var \BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface
*/
private $requestMessageBinder;
/**
* @var \BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface
*/
private $responseMessageBinder;
/**
* @param ServiceDefinition $definition
* @param MessageBinderInterface $requestHeaderMessageBinder
* @param MessageBinderInterface $requestMessageBinder
* @param MessageBinderInterface $responseMessageBinder
*/
public function __construct(ServiceDefinition $definition, MessageBinderInterface $requestHeaderMessageBinder, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder) {
$this->definition = $definition;
$this->requestHeaderMessageBinder = $requestHeaderMessageBinder;
$this->requestMessageBinder = $requestMessageBinder;
$this->responseMessageBinder = $responseMessageBinder;
}
/**
* @param string $method
* @param string $header
*
* @return boolean
*/
public function isServiceHeader($method, $header)
{
return $this->definition->getMethods()->get($method)->getHeaders()->has($header);
}
/**
* @param $string
*
* @return boolean
*/
public function isServiceMethod($method)
{
return $this->definition->getMethods()->has($method);
}
/**
* @param string $method
* @param string $header
* @param mixed $data
*
* @return SoapHeader
*/
public function processServiceHeader($method, $header, $data)
{
$methodDefinition = $this->definition->getMethods()->get($method);
$headerDefinition = $methodDefinition->getHeaders()->get($header);
$this->requestHeaderMessageBinder->setHeader($header);
$data = $this->requestHeaderMessageBinder->processMessage($methodDefinition, $data, $this->definition->getDefinitionComplexTypes());
return new SoapHeader($this->definition->getNamespace(), $headerDefinition->getName(), $data);
}
/**
* @param string $method
* @param array $arguments
*
* @return array
*/
public function processServiceMethodArguments($method, $arguments)
{
$methodDefinition = $this->definition->getMethods()->get($method);
return array_merge(
array('_controller' => $methodDefinition->getController()),
$this->requestMessageBinder->processMessage($methodDefinition, $arguments, $this->definition->getDefinitionComplexTypes())
);
}
/**
* @param string $name
* @param mixed
*
* @return mixed
*/
public function processServiceMethodReturnValue($name, $return)
{
$methodDefinition = $this->definition->getMethods()->get($name);
return $this->responseMessageBinder->processMessage($methodDefinition, $return, $this->definition->getDefinitionComplexTypes());
}
}