neneaX/multi-routing

View on GitHub
src/Adapters/Soap/Route.php

Summary

Maintainability
A
2 hrs
Test Coverage
<?php
namespace MultiRouting\Adapters\Soap;

use Illuminate\Http\Request;
use Illuminate\Routing\Matching\HostValidator;
use Illuminate\Routing\Matching\MethodValidator;
use Illuminate\Routing\Matching\SchemeValidator;
use Illuminate\Routing\Matching\UriValidator;
use MultiRouting\Adapters\Soap\Request\Interpreters\Interpreter;
use MultiRouting\Adapters\Soap\Response\Response;
use MultiRouting\Request\Interpreters\InterpreterTrait;
use MultiRouting\Request\Proxy\ProxyInterface;
use MultiRouting\Route as BaseRoute;
use MultiRouting\Adapters\Soap\Matching\IntentValidator;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Class Route
 * @package MultiRouting\Adapters\Soap
 */
class Route extends BaseRoute
{

    use InterpreterTrait;

    /**
     * The path to the server WSDL whom the request is matched against
     *
     * @var string
     */
    protected $wsdlPath;

    /**
     * The server WSDL against whom the request is matched
     *
     * @var \SimpleXMLElement
     */
    protected $wsdl;

    /**
     * The intent (called method) that the SOAP route responds to.
     *
     * @var string
     */
    protected $intent;

    /**
     * @param Request $request
     *
     * @return Interpreter
     */
    public function buildInterpreter(Request $request)
    {
        return new Interpreter($request, $this->getWsdlPath());
    }

    /**
     * @param Request $request
     *
     * @return string
     */
    public function computeHash(Request $request)
    {
        return Interpreter::computeHash($request, $this->getWsdlPath());
    }

    /**
     * @return string
     */
    public function getWsdlPath()
    {
        return $this->wsdlPath;
    }

    /**
     * @param string $wsdlPath
     */
    public function setWsdl($wsdlPath)
    {
        $this->wsdlPath = $wsdlPath;
    }

    /**
     * @return string
     */
    public function getIntent()
    {
        return $this->intent;
    }

    /**
     * Set the intent (called method) that the SOAP route responds to.
     *
     * @param string $intent
     * @return $this
     */
    public function setIntent($intent)
    {
        $this->intent = $intent;

        return $this;
    }

    /**
     * Get the route validators for the instance.
     *
     * @return array
     */
    public static function getValidators()
    {
        return [
            new MethodValidator, new SchemeValidator,
            new HostValidator, new UriValidator,
            new IntentValidator
        ];
    }

    /**
     * Extract the parameter list from the request.
     *
     * @param Request $request
     * @return array
     */
    public function bindParameters(Request $request)
    {
        $requestInterpreter = $this->getInterpreter($request);

        $params = $requestInterpreter->getParameters();

        return $this->parameters = $params;
    }

    /**
     * @param Request $request
     */
    public function prepareRun(Request $request)
    {
        // do nothing
    }

    /**
     * Run the route action and return the response.
     *
     * @return mixed
     *
     * @throws NotFoundHttpException
     * @throws \SoapFault
     */
    protected function runController()
    {
        list($class, $method) = explode('@', $this->action['uses']);

        $parameters = $this->resolveClassMethodDependencies(
            $this->parameters(), $class, $method
        );

        $options = [];

        $optionsAlias = 'multirouting.adapters.soap.server.options';
        if ($this->container->bound($optionsAlias)) {
            $options = $this->container->make($optionsAlias);
        }

        try {
            $soapServer = new \SoapServer($this->getWsdlPath(), $options);
        } catch (\SoapFault $e) {
            throw new \SoapFault('500', 'The application encountered an unexpected error.');
        }

        if ( !method_exists($instance = $this->container->make($class), $method)) {
            $soapServer->fault('500', 'The application encountered an unexpected error.');
        }

        ob_start();
        try {
            $proxyAlias = 'multirouting.adapters.soap.request.proxy';
            if ($this->container->bound($proxyAlias)) {
                /** @var ProxyInterface $proxyInstance */
                $proxyInstance = $this->container->make($proxyAlias);

                $proxyInstance->setMatchedInstance($instance);
                $proxyInstance->setMatchedMethod($method);
                $proxyInstance->setMatchedParameters($parameters);

                $instance = $proxyInstance;
            }
            $soapServer->setObject($instance);
            $soapServer->handle();
            $statusCode = 200;
        } catch (\Exception $e) {
            $soapServer->fault(
                $e->getCode(),
                $e->getMessage()
            );
            $statusCode = 500;
        }
        $responseContent = ob_get_contents();
        $headers = headers_list();
        ob_end_clean();

        $responseHeaders = [];
        foreach ($headers as $header) {
            list($key, $value) = explode(':', $header, 2);
            $responseHeaders[trim($key)] = trim($value);
        }

        return new Response($responseContent, $statusCode, $responseHeaders);
    }

    /**
     * @return string
     */
    public function getCollectionIdentifier()
    {
        return $this->glueCollectionIdentifierPieces([
            Adapter::name,
            $this->domain(),
            $this->getUri(),
            $this->getIntent()
        ]);
    }
}