SoapService.php 5.87 KB
Newer Older
1
<?php
2 3
namespace T3o\TerFe2\Service;

4 5
/*
 * This file is part of the TYPO3 CMS project.
6
 *
7 8 9
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
10
 *
11 12
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
13
 *
14 15
 * The TYPO3 project - inspiring people to share!
 */
16 17 18 19

/**
 * Service to handle soap requests
 */
20
class SoapService implements \TYPO3\CMS\Core\SingletonInterface
21 22 23
{

    /**
Jens Jacobsen's avatar
Jens Jacobsen committed
24
     * @var \SoapClient
25 26 27 28
     */
    protected $soapConnection;

    /**
Jens Jacobsen's avatar
Jens Jacobsen committed
29
     * @var \SoapHeader
30 31 32
     */
    protected $authenticationHeader;

33 34 35 36
    /**
     * @var array
     */
    protected $httpAuth = [];
37

38 39 40 41
    protected $wsdlUrl;
    protected $username;
    protected $password;
    protected $returnExceptions;
42 43 44 45 46 47 48

    /**
     * Setup connection
     *
     * @param string $wsdlUrl URL of the wsdl
     * @param string $username Login with this username
     * @param string $password Login with this password
49
     * @param bool $returnExceptions Return exception in case of errors
50
     * @param array $httpAuth HTTP Authentication if needed
Jens Jacobsen's avatar
Jens Jacobsen committed
51 52
     * @return \SoapClient
     * @throws \Exception
53
     */
Markus Sommer's avatar
Markus Sommer committed
54
    public function connect($wsdlUrl, $username = '', $password = '', $returnExceptions = false, array $httpAuth = [])
55 56
    {
        if (empty($wsdlUrl)) {
57
            throw new \Exception('No valid wsdl URL given');
58 59 60
        }

        if (!class_exists('SoapClient')) {
61
            throw new \Exception('PHP SOAP extension not available');
62 63 64 65 66 67
        }

        $this->wsdlUrl = $wsdlUrl;
        $this->username = $username;
        $this->password = $password;
        $this->returnExceptions = $returnExceptions;
68
        $this->httpAuth = $httpAuth;
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

        return $this->resetConnection();
    }

    /**
     * creates a new connection
     *
     * A new SoapClient has to be used to prevent unexpected behavior.
     * The bug occured when registering an extension key. The response to the second request to the server (createExtensionKey)
     * just returned pure jibberish and caused an exception.
     * This seems to be a bug in PHP (@see https://bugs.php.net/bug.php?id=42191) and the easiest way to fix it, is
     * to reset the connection.
     * Maybe this bug was fixed in a newer version of PHP (don't know), but it is a real issue on my local PHP
     * installation (5.2.10). So this *might* be reverted later on.
     *
     * @author Christian Zenker <christian.zenker@599media.de>
     */
    public function resetConnection()
    {
        // Create connection
89
        $this->soapConnection = new \SoapClient($this->wsdlUrl, [
90 91 92 93 94
            'trace' => 1,
            'exceptions' => (bool)$this->returnExceptions,
            'encoding' => 'UTF-8',
            'soap_version' => SOAP_1_2,
            'cache_wsdl' => WSDL_CACHE_NONE,
95 96
            'login' => $this->httpAuth['login'] ?: '',
            'password' => $this->httpAuth['password'] ?: ''
97
        ]);
98

99 100
        $this->soapConnection->__setCookie('fe_typo_user', $_COOKIE['fe_typo_user']);

101 102
        // Get authentication header
        if (!empty($this->username) && !empty($this->password)) {
103
            $headerData = ['username' => $this->username, 'password' => $this->password];
Markus Sommer's avatar
Markus Sommer committed
104
            $this->authenticationHeader = new \SoapHeader('', 'HeaderLogin', (object)$headerData, true);
105 106 107 108 109 110
        }
    }

    /**
     * Set connection object
     *
Jens Jacobsen's avatar
Jens Jacobsen committed
111
     * @param \SoapClient $soapConnection SOAP connection object
112 113
     * @deprecated Christian Zenker: Seems not to be used anywhere on typo3.org and the method is useless if the connection is reset for each call
     */
Jens Jacobsen's avatar
Jens Jacobsen committed
114
    public function setConnection(\SoapClient $soapConnection)
115 116 117 118 119 120 121
    {
        $this->soapConnection = $soapConnection;
    }

    /**
     * Returns current connection object
     *
Jens Jacobsen's avatar
Jens Jacobsen committed
122
     * @return \SoapClient
123 124 125 126 127 128 129 130 131
     */
    public function getConnection()
    {
        return $this->soapConnection;
    }

    /**
     * Set authentication header
     *
132
     * @param \SoapHeader $authenticationHeader SOAP header
133
     */
Jens Jacobsen's avatar
Jens Jacobsen committed
134
    public function setAuthenticationHeader(\SoapHeader $authenticationHeader)
135 136 137 138 139 140 141
    {
        $this->authenticationHeader;
    }

    /**
     * Returns current authentication header
     *
Jens Jacobsen's avatar
Jens Jacobsen committed
142
     * @return \SoapHeader
143 144 145 146 147 148 149 150 151 152 153 154
     */
    public function getAuthenticationHeader()
    {
        return $this->authenticationHeader;
    }

    /**
     * Wrapper method for SOAP calls
     *
     * @param string $methodName Method name
     * @param array $params Parameters
     * @return array Result of the SOAP call
Jens Jacobsen's avatar
Jens Jacobsen committed
155
     * @throws \Exception
156
     */
157
    public function __call($methodName, array $params = [])
158
    {
159 160
        // To prevent invalid xml errors in the second request, reset the connection before every request
        $this->resetConnection();
161 162

        // Call given method
163 164 165 166
        try {
            $response = $this->soapConnection->__soapCall(
                $methodName,
                $params,
Markus Sommer's avatar
Markus Sommer committed
167
                null,
168 169 170 171
                $this->authenticationHeader
            );
        } catch (\SoapFault $soapFault) {
            throw new \Exception('Could not call function "' . $methodName . '" on soap server. SoapFault: ' . $soapFault->getMessage());
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
        }

        return $this->convertObjectToArray($response);
    }

    /**
     * Convert an object to array
     *
     * @param object $object Object to convert
     * @return array Converted object
     */
    protected function convertObjectToArray($object)
    {
        if (is_object($object) || is_array($object)) {
            $object = (array)$object;
            foreach ($object as $key => $value) {
                $object[$key] = $this->convertObjectToArray($value);
            }
        }

        return $object;
    }

    /**
     * Close connection
     */
    public function disconnect()
    {
        unset($this->soapConnection, $this->authenticationHeader);
    }
}