<?php

/**
 * Vlastní SOAP klient pro práci s reality.sk
 */
class Realitysk_Soap extends SoapClient
{
	const XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
	const XSD_NS = "http://www.w3.org/2001/XMLSchema";

	public function __doRequest($request, $location, $action, $version, $one_way = null)
	{
		$request = preg_replace('/(<SOAP-ENV:Envelope )/',
                    '\\1 xmlns:xsi="' . self::XSI_NS . '" xmlns:xsd="' . self::XSD_NS . '" ',
                    $request);

		return parent::__doRequest($request, $location, $action, $version, $one_way);
	}

	/**
	 * Vola danou metody s danymi parametry.
	 *
	 * @param string $method
	 * @param array $params
	 */
	public function call($method, array $params = array())
	{
		$doc = new DOMDocument();
		$root = $doc->createElement('ns1:' . $method);

		$this->_toXml($params, $root, $doc);

		$xml = $doc->saveXML($root);

		$var = new SoapVar($xml, XSD_ANYXML);
		$param = new SoapParam($var, 'tojeuplnejedno');

		$response = $this->__soapCall($method, array($param));

		if (isset($response->return)) {
			return $response->return;
		}
	}

	/**
	 * Pomocna specialni rekursivka pro zpracovani pole do xml
	 *
	 * @param array $data
	 * @param DOMElement $el
	 * @param DOMDocument $doc
	 * @return DOMElement
	 */
	private function _toXml(array $data, DOMElement &$el, DOMDocument &$doc)
	{
		foreach ($data as $k => $v) {

			if (is_array($v)) {

				// descriptions maji malou vyjimku
				if ($k === 'descriptions') {

					$child = $doc->createElement($k);
					$el->appendChild($child);
					self::_toXML($v[0], $child, $doc);

					continue;
				}

				if ($k === 'characteristics') {

					$characs = $doc->createElement('characteristics');
					foreach ($v as $key => $value) {
						$characNode = $doc->createElement('entry');
						$keyNode = $doc->createElement('key', $key);
						$valueNode = $doc->createElement('value', $value);
						$valueNode->setAttribute('xsi:type', 'xsd:' . Params::getType($key));

						$characNode->appendChild($keyNode);
						$characNode->appendChild($valueNode);
						$characs->appendChild($characNode);
					}

					$el->appendChild($characs);
					continue;
				}

				// pokud jsou data cislovane pole, pak se vytvari elementy podle klice
				if (isset($v[0])) {
					foreach($v as $key => $value) {
						$node = $doc->createElement($k);
						$el->appendChild($node);
						self::_toXML($value, $node, $doc);
					}
					continue;
				}

				$child = $doc->createElement($k);
				$el->appendChild($child);
				self::_toXML($v, $child, $doc);

			} else {

				$newEl = $doc->createElement($k, $v);
				$el->appendChild($newEl);
			}
		}
		return $el;
	}
}
