<?php
namespace FintechFab\QiwiSdk;

class Gateway
{

	/**
	 * @var Curl
	 */
	private $curl;

	/**
	 * @var string
	 */
	private $errorMessage;
	private $billStatus;
	private $payReturnStatus;

	const C_ERROR_FORMAT = '5';
	const C_ERROR_SERVER_BUSY = '13';
	const C_AUTH_ERROR = '150';
	const C_BILL_NOT_FOUND = '210';
	const C_BILL_ALREADY_EXIST = '215';
	const C_SMALL_AMOUNT = '241';
	const C_BIG_AMOUNT = '242';
	const C_TECHNICAL_ERROR = '300';

	private static $config;

	private $statusMap = array(
		'waiting'    => 'payable',
		'paid'       => 'paid',
		'rejected'   => 'canceled',
		'expired'    => 'expired',
		'processing' => 'onReturn',
		'success'    => 'returned',
	);
	private $errorMap = array(
		self::C_ERROR_FORMAT       => 'Неверный формат параметров запроса',
		self::C_ERROR_SERVER_BUSY  => 'Сервер занят, повторите запрос позже',
		self::C_AUTH_ERROR         => 'Ошибка авторизации',
		self::C_BILL_NOT_FOUND     => 'Счет не найден',
		self::C_BILL_ALREADY_EXIST => 'Счет с таким bill_id уже существует',
		self::C_SMALL_AMOUNT       => 'Сумма слишком мала',
		self::C_BIG_AMOUNT         => 'Сумма слишком велика',
		self::C_TECHNICAL_ERROR    => 'Техническая ошибка, повторите запрос позже',
	);

	/**
	 * текст ответа для коллбека киви
	 *
	 * @var string
	 */
	private $callbackResponse;

	/**
	 * сумма счета/заказа
	 *
	 * @var string
	 */
	private $callbackAmount;

	/**
	 * номер счета/заказа
	 *
	 * @var string
	 */
	private $callbackOrderId;

	public function __construct(Curl $curl)
	{
		$this->curl = $curl;
	}

	/**
	 * Возвращает значение конфига по ключу
	 *
	 * @param $key
	 *
	 * @return string
	 */
	public static function getConfig($key)
	{
		$keyArray = explode('.', $key);
		$config = self::$config;

		for ($i = 0; $i < count($keyArray); $i++) {
			$config = $config[$keyArray[$i]];
		}

		return $config;

	}

	/**
	 * Установить конфиг перед использованием
	 * $config format array(
	 *      'gateUrl'  => 'url-to-qiwi-gate',
	 *      'shopId'   => 'url-to-qiwi-shopid',
	 *      'provider' => array (
	 *          'id'       => 'your-qiwi-account-id',
	 *          'password' => 'your-qiwi-account-password',
	 *          'name'     => 'your-company-name',
	 *          'key'      => 'your-qiwi-account-key',
	 *       )
	 *  )
	 *
	 *
	 * @param $config array
	 */
	public static function setConfig($config)
	{
		self::$config = $config;
	}

	/**
	 * Если статус получен - возвращает true
	 * Значение полученного статуса счёта - getValueBillStatus()
	 *
	 * @param string $orderId уникальный в магазине id заказа
	 *
	 * @return bool
	 */
	public function doRequestBillStatus($orderId)
	{
		$oResponse = $this->curl->request($orderId);
		$this->parseError($oResponse);

		if ($this->getError()) {
			return false;
		}

		$status = $oResponse->response->bill->status;
		$this->setValueBillStatus($this->statusMap[$status]);

		return true;
	}

	/**
	 * Если счёт создан - возвращает true
	 *
	 * @param string $orderId  - Уникальный в магазине id заказа
	 * @param string $tel      - Номер телефона клиента
	 * @param float  $sum      - Сумма заказа
	 * @param string $comment  - Комментарий к заказу
	 * @param string $lifetime - Срок действия заказа
	 *
	 * @return bool
	 */
	public function createBill(
		$orderId, $tel, $sum, $comment = null, $lifetime = null
	)
	{
		$this->checkSum($sum);
		if ($this->getError()) {
			return false;
		}

		if (null == $lifetime) {
			$dateExpired = new \DateTime();
			$dateExpired->add(new \DateInterval("P1D"));
			$dateExpiredString = $dateExpired->format(\DateTime::ATOM);
		} else {
			$dateExpiredString = date('Y-m-d\TH:i:s', strtotime($lifetime));
		}

		$bill = array(
			'user'     => 'tel:' . $tel,
			'amount'   => $sum,
			'ccy'      => 'RUB',
			'comment'  => $comment,
			'lifetime' => $dateExpiredString,
			'prv_name' => self::getConfig('provider.name'),
		);
		$oResponse = $this->curl->request($orderId, 'PUT', $bill);

		$this->parseError($oResponse);

		return $this->getError()
			? false
			: true;

	}

	/**
	 * Если счёт отменён - возвращает true
	 *
	 * @param string $orderId - Уникальный в магазине id заказа
	 *
	 * @return bool
	 */
	public function cancelBill($orderId)
	{
		$reject = array('status' => 'rejected');
		$oResponse = $this->curl->request($orderId, 'PATCH', $reject);
		$this->parseError($oResponse);

		return $this->getError()
			? false
			: true;

	}

	/**
	 * Если возврат оплаты создан - возвращает true
	 *
	 * @param string $orderId     - Уникальный в магазине id заказа
	 * @param string $payReturnId - Уникальный для заказа id возврата
	 * @param float  $sum         - Сумма возврата
	 *
	 * @return bool
	 */
	public function payReturn($orderId, $payReturnId, $sum)
	{

		$this->checkSum($sum);
		if ($this->getError()) {
			return false;
		}

		$amount = array('amount' => $sum);
		$oResponse = $this->curl->request($orderId, 'PUT', $amount, $payReturnId);
		$this->parseError($oResponse);

		return $this->getError()
			? false
			: true;

	}

	/**
	 * Если статус возврата получен - возвращает true
	 * Значение полученного статуса возврата - getValuePayReturnStatus()
	 *
	 * @param string $orderId     - Уникальный в магазине id заказа
	 * @param string $payReturnId - Уникальный для заказа id возврата
	 *
	 * @return bool
	 */
	public function doRequestReturnStatus($orderId, $payReturnId)
	{
		$oResponse = $this->curl->request($orderId, 'GET', null, $payReturnId);
		$this->parseError($oResponse);

		if ($this->getError()) {
			return false;
		}

		$status = $oResponse->response->refund->status;
		$this->setValuePayReturnStatus($this->statusMap[$status]);

		return true;
	}

	/**
	 * Парсинг ошибок
	 * Получить значение ошибки - getError()
	 *
	 * @param $oResponse
	 */
	private function parseError($oResponse)
	{

		if (!empty($oResponse->curlError)) {
			$this->setError($oResponse->curlError);

			return;
		}

		if (
			$oResponse->response->result_code !== 0 &&
			$oResponse->response->result_code !== '0' &&
			empty($oResponse->response->result_code)
		) {
			$this->setError('Error response format');

			return;
		}

		// код ответа от гейта
		$code = $oResponse->response->result_code;
		if ($code != 0) {
			$this->setError($this->errorMap[$code]);

			return;
		}

	}

	/**
	 * Разбирает коллбэк-запрос от гейта
	 *
	 * После разбора
	 * - получить номер заказа getCallbackOrderId и сумму getCallbackAmount
	 * - получить статус заказа/счета getValueBillStatus
	 *
	 * Если были ошибки - текст ошибки в getError
	 *
	 * Если в коллбэке пришла ошибка error, то
	 * - разбор считается успешным (возвращает true)
	 * - но в getError вернет текст ошибки
	 *
	 * @param array|null $requestParams массив параметров в запросе или будет использован $_POST
	 *
	 * @return bool разбор прошел без ошибок или с ошибками
	 */
	public function doParseCallback($requestParams = null)
	{

		if (null === $requestParams && !empty($_POST)) {
			$requestParams = $_POST;
		}

		$fields = array(
			'bill_id',
			'status',
			'error',
			'amount',
			'user',
			'prv_name',
			'ccy',
			'comment',
			'command',
		);

		// формирование параметров
		$params = array();
		foreach ($fields as $name) {
			if (isset($requestParams[$name])) {
				$params[$name] = urldecode($requestParams[$name]);
			} else {
				// на некоторых полях - не ошибка
				if (!in_array($name, array('comment', 'prv_name'))) {
					$this->setError('Parameter ' . $name . ' is required');
				}
			}
		}

		if ($this->getError()) {
			$this->createCallbackResponse(self::C_ERROR_FORMAT);

			return false;
		}
		if (!$this->checkAuth($requestParams)) {
			$this->setError($this->errorMap[self::C_AUTH_ERROR]);
			$this->createCallbackResponse(self::C_AUTH_ERROR);

			return false;
		}

		// номер телефона
		$params['user'] = str_replace('tel:', '', $params['user']);

		// статус
		$this->setValueBillStatus($this->statusMap[$params['status']]);

		// данные
		$this->setCallbackAmount($params['amount']);
		$this->setCallbackOrderId($params['bill_id']);

		// ответ
		$this->createCallbackResponse();

		// ошибка от гейта
		if ($params['error'] !== '0') {
			$errorMessage = isset($this->errorMap[$params['error']])
				? $this->errorMap[$params['error']]
				: 'Неизвестная ошибка';
			$this->setError($errorMessage);
		}

		return true;

	}

	/**
	 * Отдаёт ошибки
	 *
	 * @return string
	 */

	public function getError()
	{
		return $this->errorMessage;
	}

	/**
	 * Устанавливает ошибки
	 *
	 * @param $message
	 */
	private function setError($message)
	{
		$this->errorMessage = $message;
	}

	/**
	 * Отдаёт значение статуса полученного статуса счёта
	 *
	 * @return string
	 */
	public function getValueBillStatus()
	{
		return $this->billStatus;
	}

	/**
	 * Устанавливает полученное значение статуса счёта
	 *
	 * @param string $status
	 */
	private function setValueBillStatus($status)
	{
		$this->billStatus = $status;
	}

	/**
	 * Отдаёт значение статуса полученного статуса возврата
	 *
	 * @return string
	 */
	public function getValuePayReturnStatus()
	{
		return $this->payReturnStatus;
	}

	/**
	 * Устанавливает полученное значение статуса возврата
	 *
	 * @param string $status
	 */
	private function setValuePayReturnStatus($status)
	{
		$this->payReturnStatus = $status;
	}

	/**
	 * Проверяет что сумма > 0
	 *
	 * @param float $sum
	 */
	private function checkSum($sum)
	{
		if ($sum <= 0) {
			$this->setError($this->errorMap[self::C_SMALL_AMOUNT]);
		}
	}

	/**
	 * Проверка авторизации
	 *
	 * @param $requestParams
	 *
	 * @return bool
	 */
	private function checkAuth($requestParams)
	{
		$sign = $this->getSignForAuth();

		if ($sign != '' && $sign != null) {
			return $this->isCorrectSign($sign, $requestParams);
		}

		$providerData = $this->getProviderForAuth();

		if ($providerData) {

			if (self::getConfig('provider.id') == $providerData['login']
				&& self::getConfig('provider.password') == $providerData['password']
			) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Получить логин:пароль из заголовка callback`а
	 *
	 * @return array|null
	 */
	private function getProviderForAuth()
	{
		$providerData = null;

		if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
			$authBasicHeader = trim($_SERVER['HTTP_AUTHORIZATION']);

			preg_match('/^Basic (.+)$/', $authBasicHeader, $matches);
			@list($login, $password) = explode(':', base64_decode($matches[1]));
			$providerData = array(
				'login'    => $login,
				'password' => $password,
			);
		}

		if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
			$providerData = array(
				'login'    => (int)trim($_SERVER['PHP_AUTH_USER']),
				'password' => trim($_SERVER['PHP_AUTH_PW']),
			);
		}

		return $providerData;
	}

	/**
	 * Получить подпись из заголовка callback`а
	 *
	 * @return string
	 */
	private function getSignForAuth()
	{
		if (isset($_SERVER['HTTP_X_API_SIGNATURE'])) {
			$signHeader = trim($_SERVER['HTTP_X_API_SIGNATURE']);

			return $signHeader;
		}

		return null;
	}

	/**
	 * Проверка подписи из callback`а
	 *
	 * @param string $sign
	 * @param array  $requestParams
	 *
	 * @return bool
	 */
	private function isCorrectSign($sign, $requestParams)
	{
		ksort($requestParams);
		$signData = implode('|', $requestParams);
		$key = self::getConfig('provider.key');
		$localSign = base64_encode(hash_hmac('sha1', $signData, $key));

		return $sign == $localSign;

	}

	/**
	 * Сформировать ответ для коллбэка
	 *
	 * @param int $code код ответа
	 */
	public function createCallbackResponse($code = 0)
	{
		$this->callbackResponse = '<?xml version="1.0"?><result><result_code>' . $code . '</result_code></result>';
	}

	/**
	 * Ответ для коллбэка
	 *
	 * @return string
	 */
	public function getCallbackResponse()
	{
		return $this->callbackResponse;
	}

	/**
	 * ответить на вызов коллбэка
	 *
	 * @return string
	 */
	public function doCallbackResponse()
	{

		@header('Content-type: text/xml');

		return $this->getCallbackResponse();

	}

	/**
	 * Сумма счета/заказа
	 *
	 * @return string
	 */
	public function getCallbackAmount()
	{
		return $this->callbackAmount;
	}

	/**
	 * Сумма счета/заказа
	 *
	 * @param string $amount
	 */
	private function setCallbackAmount($amount)
	{
		$this->callbackAmount = $amount;
	}

	/**
	 * Идентификатор счета/заказа
	 *
	 * @return string
	 */
	public function getCallbackOrderId()
	{
		return $this->callbackOrderId;
	}

	/**
	 * Идентификатор счета/заказа
	 *
	 * @param string $orderId
	 */
	private function setCallbackOrderId($orderId)
	{
		$this->callbackOrderId = $orderId;
	}

}


<?php
	/**
	 * Created by PhpStorm.
	 * User: Abhimanyu
	 * Date: 15-02-2015
	 * Time: 22:24
	 */

	namespace abhimanyu\systemInfo\os;

	use abhimanyu\systemInfo\interfaces\InfoInterface;
	use Exception;
	use PDO;
	use Yii;

	class Windows implements InfoInterface
	{
		/**
		 * Gets the name of the Operating System
		 *
		 * @return string
		 */
		public static function getOS()
		{
			$wmi = Windows::getInstance();

			foreach ($wmi->ExecQuery("SELECT Caption FROM Win32_OperatingSystem") as $os) {
				return $os->Caption;
			}

			return "Windows";
		}

		public static function getInstance()
		{
			$wmi = new \COM('winmgmts:{impersonationLevel=impersonate}//./root/cimv2');

			if (!is_object($wmi)) {
				throw new Exception('This needs access to WMI. Please enable DCOM in php.ini and allow the current
				user to access the WMI DCOM object.');
			}

			return $wmi;
		}

		/**
		 * Gets the Kernel Version of the Operating System
		 *
		 * @return string
		 */
		public static function getKernelVersion()
		{
			$wmi = Windows::getInstance();

			foreach ($wmi->ExecQuery("SELECT WindowsVersion FROM Win32_Process WHERE Handle = 0") as $process) {
				return $process->WindowsVersion;
			}

			return "Unknown";
		}

		/**
		 * Gets the hostname
		 *
		 * @return string
		 */
		public static function getHostname()
		{
			$wmi = Windows::getInstance();

			foreach ($wmi->ExecQuery("SELECT Name FROM Win32_ComputerSystem") as $cs) {
				return $cs->Name;
			}

			return "Unknown";
		}

		/**
		 * Gets Processor's Model
		 *
		 * @return string
		 */
		public static function getCpuModel()
		{
			$wmi = Windows::getInstance();

			$object = $wmi->ExecQuery("SELECT Name FROM Win32_Processor");

			foreach ($object as $cpu) {
				return $cpu->Name;
			}

			return 'Unknown';
		}

		/**
		 * Gets Processor's Vendor
		 *
		 * @return string
		 */
		public static function getCpuVendor()
		{
			$wmi = Windows::getInstance();

			$object = $wmi->ExecQuery("SELECT Manufacturer FROM Win32_Processor");

			foreach ($object as $cpu) {
				return $cpu->Manufacturer;
			}

			return 'Unknown';
		}

		/**
		 * Gets Processor's Frequency
		 *
		 * @return string
		 */
		public static function getCpuFreq()
		{
			$wmi = Windows::getInstance();

			$object = $wmi->ExecQuery("SELECT CurrentClockSpeed FROM Win32_Processor");

			foreach ($object as $cpu) {
				return $cpu->CurrentClockSpeed;
			}

			return 'Unknown';
		}

		/**
		 * Gets current system load
		 *
		 * @return string
		 */
		public static function getLoad()
		{
			$wmi  = Windows::getInstance();
			$load = [];

			foreach ($wmi->ExecQuery("SELECT LoadPercentage FROM Win32_Processor") as $cpu) {
				$load[] = $cpu->LoadPercentage;
			}

			return round(array_sum($load) / count($load), 2) . "%";
		}

		/**
		 * Gets Processor's Architecture
		 *
		 * @return string
		 */
		public static function getCpuArchitecture()
		{
			$wmi = Windows::getInstance();

			foreach ($wmi->ExecQuery("SELECT Architecture FROM Win32_Processor") as $cpu) {
				switch ($cpu->Architecture) {
					case 0:
						return "x86";
					case 1:
						return "MIPS";
					case 2:
						return "Alpha";
					case 3:
						return "PowerPC";
					case 6:
						return "Itanium-based systems";
					case 9:
						return "x64";
				}
			}

			return "Unknown";
		}

		/**
		 * Gets system up-time
		 *
		 * @return string
		 */
		public static function getUpTime()
		{
			$wmi = Windows::getInstance();

			$booted_str = '';
			foreach ($wmi->ExecQuery("SELECT LastBootUpTime FROM Win32_OperatingSystem") as $os) {
				$booted_str = $os->LastBootUpTime;
			}

			$booted    = [
				'year'   => substr($booted_str, 0, 4),
				'month'  => substr($booted_str, 4, 2),
				'day'    => substr($booted_str, 6, 2),
				'hour'   => substr($booted_str, 8, 2),
				'minute' => substr($booted_str, 10, 2),
				'second' => substr($booted_str, 12, 2)
			];
			$booted_ts = mktime($booted['hour'], $booted['minute'], $booted['second'], $booted['month'], $booted['day'], $booted['year']);

			return date('m/d/y h:i A (T)', $booted_ts);
		}

		/**
		 * Gets total number of cores
		 *
		 * @return integer
		 */
		public static function getCpuCores()
		{
			$wmi    = Windows::getInstance();
			$object = $wmi->ExecQuery("SELECT NumberOfLogicalProcessors FROM Win32_Processor");

			$cores = 0;
			foreach ($object as $obj) {
				$cores = $obj->NumberOfLogicalProcessors;
			}

			return $cores;
		}

		/**
		 * Gets Current PHP Version
		 *
		 * @return string
		 */
		public static function getPhpVersion()
		{
			return phpversion();
		}

		/**
		 * Gets Server Name
		 *
		 * @return string
		 */
		public static function getServerName()
		{
			return $_SERVER['SERVER_NAME'];
		}

		/**
		 * Gets Server Protocol
		 *
		 * @return string
		 */
		public static function getServerProtocol()
		{
			return $_SERVER['SERVER_PROTOCOL'];
		}

		/**
		 * Gets the type of server e.g. apache
		 *
		 * @return string
		 */
		public static function getServerSoftware()
		{
			return $_SERVER['SERVER_SOFTWARE'];
		}

		/**
		 * Gets total physical memory
		 *
		 * @return array|null
		 */
		public static function getTotalMemory()
		{
			$wmi = Windows::getInstance();

			foreach ($wmi->ExecQuery("SELECT TotalPhysicalMemory FROM Win32_ComputerSystem") as $mem) {
				return $mem->TotalPhysicalMemory;
			}

			return NULL;
		}

		/**
		 * Gets the current DB Type of Yii2
		 *
		 * @return mixed
		 */
		public static function getDbType()
		{
			return Yii::$app->db->driverName;
		}

		/**
		 * * Gets the current DB Version of Yii2
		 *
		 * @return mixed
		 */
		public static function getDbVersion()
		{
			try {
				// Open Connection if closed
				Yii::$app->db->open();
			} catch (Exception $e) {
				//ignore
			}

			return Yii::$app->db->pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
		}
	}


<?php
namespace FintechFab\QiwiSdk;

use stdClass;

class Curl
{
	private $url;
	public $curlError;

	/**
	 * Определяет URL для curl запроса
	 *
	 * @param $orderId
	 * @param $payReturnId
	 *
	 */
	private function  setUrl($orderId, $payReturnId = null)
	{
		$this->url = Gateway::getConfig('gateUrl') . Gateway::getConfig('shopId')
			. '/bills/' . $orderId;
		if ($payReturnId != null) {
			$this->url .= '/refund/' . $payReturnId;
		}

	}

	/**
	 * Получает параметры для запроса и возвращает объект с ответом от сервера
	 * или с ошибками curl
	 *
	 * @param int    $order_id
	 * @param string $method
	 * @param null   $query
	 * @param null   $payReturnId
	 *
	 * @return stdClass
	 */
	public function request($order_id, $method = 'GET', $query = null, $payReturnId = null)
	{
		$this->setUrl($order_id, $payReturnId);

		$headers = array(
			"Accept: text/json",
			"Content-Type: application/x-www-form-urlencoded; charset=utf-8",
		);

		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $this->url);
		curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
		curl_setopt(
			$ch,
			CURLOPT_USERPWD,
			Gateway::getConfig('provider.id') . ':'
			. Gateway::getConfig('provider.password')
		);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
		if ($query != null) {
			curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($query));
		}

		$httpResponse = curl_exec($ch);
		$httpError = curl_error($ch);
		$info = curl_getinfo($ch);
		$response = @json_decode($httpResponse);

		if (!$response || !$httpResponse || $httpError) {

			$this->curlError = (object)array(
				'code'     => $info['http_code'],
				'error'    => $httpError,
				'response' => $httpResponse,
			);

			return ($this->curlError);
		}

		return $response;
	}
}


<?php
/*******************************************************************************
 * Copyright 2009-2015 Amazon Services. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at: http://aws.amazon.com/apache2.0
 * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *******************************************************************************
 * PHP Version 5
 * @category Amazon
 * @package  MWS Finances Service
 * @version  2015-05-01
 * Library Version: 2015-09-03
 * Generated: Thu Sep 03 17:55:25 GMT 2015
 */

/**
 *  @see MWSFinancesService_Model
 */

require_once (dirname(__FILE__) . '/../Model.php');

/**
 * MWSFinancesService_Model_PayWithAmazonEvent
 *
 * Properties:
 *

 *
 *
SellerOrderId: string

 *
TransactionPostedDate: string

 *
BusinessObjectType: string

 *
SalesChannel: string

 *
Charge: MWSFinancesService_Model_ChargeComponent

 *
FeeList: array

 *
PaymentAmountType: string

 *
AmountDescription: string

 *
FulfillmentChannel: string

 *
StoreName: string

 *
 *

 */

 class MWSFinancesService_Model_PayWithAmazonEvent extends MWSFinancesService_Model {

    public function __construct($data = null)
    {
    $this->_fields = array (
    'SellerOrderId' => array('FieldValue' => null, 'FieldType' => 'string'),
    'TransactionPostedDate' => array('FieldValue' => null, 'FieldType' => 'string'),
    'BusinessObjectType' => array('FieldValue' => null, 'FieldType' => 'string'),
    'SalesChannel' => array('FieldValue' => null, 'FieldType' => 'string'),
    'Charge' => array('FieldValue' => null, 'FieldType' => 'MWSFinancesService_Model_ChargeComponent'),
    'FeeList' => array('FieldValue' => array(), 'FieldType' => array('MWSFinancesService_Model_FeeComponent'), 'ListMemberName' => 'FeeComponent'),
    'PaymentAmountType' => array('FieldValue' => null, 'FieldType' => 'string'),
    'AmountDescription' => array('FieldValue' => null, 'FieldType' => 'string'),
    'FulfillmentChannel' => array('FieldValue' => null, 'FieldType' => 'string'),
    'StoreName' => array('FieldValue' => null, 'FieldType' => 'string'),
    );
    parent::__construct($data);
    }

    /**
     * Get the value of the SellerOrderId property.
     *
     * @return String SellerOrderId.
     */
    public function getSellerOrderId()
    {
        return $this->_fields['SellerOrderId']['FieldValue'];
    }

    /**
     * Set the value of the SellerOrderId property.
     *
     * @param string sellerOrderId
     * @return this instance
     */
    public function setSellerOrderId($value)
    {
        $this->_fields['SellerOrderId']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if SellerOrderId is set.
     *
     * @return true if SellerOrderId is set.
     */
    public function isSetSellerOrderId()
    {
                return !is_null($this->_fields['SellerOrderId']['FieldValue']);
            }

    /**
     * Set the value of SellerOrderId, return this.
     *
     * @param sellerOrderId
     *             The new value to set.
     *
     * @return This instance.
     */
    public function withSellerOrderId($value)
    {
        $this->setSellerOrderId($value);
        return $this;
    }

    /**
     * Get the value of the TransactionPostedDate property.
     *
     * @return XMLGregorianCalendar TransactionPostedDate.
     */
    public function getTransactionPostedDate()
    {
        return $this->_fields['TransactionPostedDate']['FieldValue'];
    }

    /**
     * Set the value of the TransactionPostedDate property.
     *
     * @param string transactionPostedDate
     * @return this instance
     */
    public function setTransactionPostedDate($value)
    {
        $this->_fields['TransactionPostedDate']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if TransactionPostedDate is set.
     *
     * @return true if TransactionPostedDate is set.
     */
    public function isSetTransactionPostedDate()
    {
                return !is_null($this->_fields['TransactionPostedDate']['FieldValue']);
            }

    /**
     * Set the value of TransactionPostedDate, return this.
     *
     * @param transactionPostedDate
     *             The new value to set.
     *
     * @return This instance.
     */
    public function withTransactionPostedDate($value)
    {
        $this->setTransactionPostedDate($value);
        return $this;
    }

    /**
     * Get the value of the BusinessObjectType property.
     *
     * @return String BusinessObjectType.
     */
    public function getBusinessObjectType()
    {
        return $this->_fields['BusinessObjectType']['FieldValue'];
    }

    /**
     * Set the value of the BusinessObjectType property.
     *
     * @param string businessObjectType
     * @return this instance
     */
    public function setBusinessObjectType($value)
    {
        $this->_fields['BusinessObjectType']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if BusinessObjectType is set.
     *
     * @return true if BusinessObjectType is set.
     */
    public function isSetBusinessObjectType()
    {
                return !is_null($this->_fields['BusinessObjectType']['FieldValue']);
            }

    /**
     * Set the value of BusinessObjectType, return this.
     *
     * @param businessObjectType
     *             The new value to set.
     *
     * @return This instance.
     */
    public function withBusinessObjectType($value)
    {
        $this->setBusinessObjectType($value);
        return $this;
    }

    /**
     * Get the value of the SalesChannel property.
     *
     * @return String SalesChannel.
     */
    public function getSalesChannel()
    {
        return $this->_fields['SalesChannel']['FieldValue'];
    }

    /**
     * Set the value of the SalesChannel property.
     *
     * @param string salesChannel
     * @return this instance
     */
    public function setSalesChannel($value)
    {
        $this->_fields['SalesChannel']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if SalesChannel is set.
     *
     * @return true if SalesChannel is set.
     */
    public function isSetSalesChannel()
    {
                return !is_null($this->_fields['SalesChannel']['FieldValue']);
            }

    /**
     * Set the value of SalesChannel, return this.
     *
     * @param salesChannel
     *             The new value to set.
     *
     * @return This instance.
     */
    public function withSalesChannel($value)
    {
        $this->setSalesChannel($value);
        return $this;
    }

    /**
     * Get the value of the Charge property.
     *
     * @return ChargeComponent Charge.
     */
    public function getCharge()
    {
        return $this->_fields['Charge']['FieldValue'];
    }

    /**
     * Set the value of the Charge property.
     *
     * @param MWSFinancesService_Model_ChargeComponent charge
     * @return this instance
     */
    public function setCharge($value)
    {
        $this->_fields['Charge']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if Charge is set.
     *
     * @return true if Charge is set.
     */
    public function isSetCharge()
    {
                return !is_null($this->_fields['Charge']['FieldValue']);
            }

    /**
     * Set the value of Charge, return this.
     *
     * @param charge
     *             The new value to set.
     *
     * @return This instance.
     */
    public function withCharge($value)
    {
        $this->setCharge($value);
        return $this;
    }

    /**
     * Get the value of the FeeList property.
     *
     * @return List<FeeComponent> FeeList.
     */
    public function getFeeList()
    {
        if ($this->_fields['FeeList']['FieldValue'] == null)
        {
            $this->_fields['FeeList']['FieldValue'] = array();
        }
        return $this->_fields['FeeList']['FieldValue'];
    }

    /**
     * Set the value of the FeeList property.
     *
     * @param array feeList
     * @return this instance
     */
    public function setFeeList($value)
    {
        if (!$this->_isNumericArray($value)) {
            $value = array ($value);
        }
        $this->_fields['FeeList']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Clear FeeList.
     */
    public function unsetFeeList()
    {
        $this->_fields['FeeList']['FieldValue'] = array();
    }

    /**
     * Check to see if FeeList is set.
     *
     * @return true if FeeList is set.
     */
    public function isSetFeeList()
    {
                return !empty($this->_fields['FeeList']['FieldValue']);
            }

    /**
     * Add values for FeeList, return this.
     *
     * @param feeList
     *             New values to add.
     *
     * @return This instance.
     */
    public function withFeeList()
    {
        foreach (func_get_args() as $FeeList)
        {
            $this->_fields['FeeList']['FieldValue'][] = $FeeList;
        }
        return $this;
    }

    /**
     * Get the value of the PaymentAmountType property.
     *
     * @return String PaymentAmountType.
     */
    public function getPaymentAmountType()
    {
        return $this->_fields['PaymentAmountType']['FieldValue'];
    }

    /**
     * Set the value of the PaymentAmountType property.
     *
     * @param string paymentAmountType
     * @return this instance
     */
    public function setPaymentAmountType($value)
    {
        $this->_fields['PaymentAmountType']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if PaymentAmountType is set.
     *
     * @return true if PaymentAmountType is set.
     */
    public function isSetPaymentAmountType()
    {
                return !is_null($this->_fields['PaymentAmountType']['FieldValue']);
            }

    /**
     * Set the value of PaymentAmountType, return this.
     *
     * @param paymentAmountType
     *             The new value to set.
     *
     * @return This instance.
     */
    public function withPaymentAmountType($value)
    {
        $this->setPaymentAmountType($value);
        return $this;
    }

    /**
     * Get the value of the AmountDescription property.
     *
     * @return String AmountDescription.
     */
    public function getAmountDescription()
    {
        return $this->_fields['AmountDescription']['FieldValue'];
    }

    /**
     * Set the value of the AmountDescription property.
     *
     * @param string amountDescription
     * @return this instance
     */
    public function setAmountDescription($value)
    {
        $this->_fields['AmountDescription']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if AmountDescription is set.
     *
     * @return true if AmountDescription is set.
     */
    public function isSetAmountDescription()
    {
                return !is_null($this->_fields['AmountDescription']['FieldValue']);
            }

    /**
     * Set the value of AmountDescription, return this.
     *
     * @param amountDescription
     *             The new value to set.
     *
     * @return This instance.
     */
    public function withAmountDescription($value)
    {
        $this->setAmountDescription($value);
        return $this;
    }

    /**
     * Get the value of the FulfillmentChannel property.
     *
     * @return String FulfillmentChannel.
     */
    public function getFulfillmentChannel()
    {
        return $this->_fields['FulfillmentChannel']['FieldValue'];
    }

    /**
     * Set the value of the FulfillmentChannel property.
     *
     * @param string fulfillmentChannel
     * @return this instance
     */
    public function setFulfillmentChannel($value)
    {
        $this->_fields['FulfillmentChannel']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if FulfillmentChannel is set.
     *
     * @return true if FulfillmentChannel is set.
     */
    public function isSetFulfillmentChannel()
    {
                return !is_null($this->_fields['FulfillmentChannel']['FieldValue']);
            }

    /**
     * Set the value of FulfillmentChannel, return this.
     *
     * @param fulfillmentChannel
     *             The new value to set.
     *
     * @return This instance.
     */
    public function withFulfillmentChannel($value)
    {
        $this->setFulfillmentChannel($value);
        return $this;
    }

    /**
     * Get the value of the StoreName property.
     *
     * @return String StoreName.
     */
    public function getStoreName()
    {
        return $this->_fields['StoreName']['FieldValue'];
    }

    /**
     * Set the value of the StoreName property.
     *
     * @param string storeName
     * @return this instance
     */
    public function setStoreName($value)
    {
        $this->_fields['StoreName']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if StoreName is set.
     *
     * @return true if StoreName is set.
     */
    public function isSetStoreName()
    {
                return !is_null($this->_fields['StoreName']['FieldValue']);
            }

    /**
     * Set the value of StoreName, return this.
     *
     * @param storeName
     *             The new value to set.
     *
     * @return This instance.
     */
    public function withStoreName($value)
    {
        $this->setStoreName($value);
        return $this;
    }

}


<?php
/*******************************************************************************
 * Copyright 2009-2014 Amazon Services. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at: http://aws.amazon.com/apache2.0
 * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *******************************************************************************
 * PHP Version 5
 * @category Amazon
 * @package  FBA Outbound Service MWS
 * @version  2010-10-01
 * Library Version: 2014-10-20
 * Generated: Thu Oct 30 16:36:58 GMT 2014
 */

/**
 * FBAOutboundServiceMWS_Client is an implementation of FBAOutboundServiceMWS
 *
 */
class FBAOutboundServiceMWS_Client implements FBAOutboundServiceMWS_Interface
{

    const SERVICE_VERSION = '2010-10-01';
    const MWS_CLIENT_VERSION = '2014-10-20';

    /** @var string */
    private $_awsAccessKeyId = null;

    /** @var string */
    private $_awsSecretAccessKey = null;

    /** @var array */
    private $_config = array(
        'ServiceURL' => null,
        'UserAgent' => 'FBAOutboundServiceMWS PHP5 Library',
        'SignatureVersion' => 2,
        'SignatureMethod' => 'HmacSHA256',
        'ProxyHost' => null,
        'ProxyPort' => -1,
        'ProxyUsername' => null,
        'ProxyPassword' => null,
        'MaxErrorRetry' => 3,
        'Headers' => array(),
        'SSL_VerifyPeer' => true,
        'SSL_VerifyHost' => 2,
    );

    /**
     * Cancel Fulfillment Order
     * Request for Amazon to no longer attempt to fulfill an existing
     *   fulfillment order. Amazon will attempt to stop fulfillment of all
     *   items that haven't already shipped, but cannot guarantee success.
     *   Note: Items that have already shipped cannot be cancelled.
     *
     * @param mixed $request array of parameters for FBAOutboundServiceMWS_Model_CancelFulfillmentOrder request or FBAOutboundServiceMWS_Model_CancelFulfillmentOrder object itself
     * @see FBAOutboundServiceMWS_Model_CancelFulfillmentOrderRequest
     * @return FBAOutboundServiceMWS_Model_CancelFulfillmentOrderResponse
     *
     * @throws FBAOutboundServiceMWS_Exception
     */
    public function cancelFulfillmentOrder($request)
    {
        if (!($request instanceof FBAOutboundServiceMWS_Model_CancelFulfillmentOrderRequest)) {
            $request = new FBAOutboundServiceMWS_Model_CancelFulfillmentOrderRequest($request);
        }
        $parameters = $request->toQueryParameterArray();
        $parameters['Action'] = 'CancelFulfillmentOrder';
        $httpResponse = $this->_invoke($parameters);

        $response = FBAOutboundServiceMWS_Model_CancelFulfillmentOrderResponse::fromXML($httpResponse['ResponseBody']);
        $response->setResponseHeaderMetadata($httpResponse['ResponseHeaderMetadata']);
        return $response;
    }

    /**
     * Create Fulfillment Order
     * The SellerFulfillmentOrderId must be unique for all fulfillment
     *   orders created by the seller. If your system already has a
     *   unique order identifier, then that may be a good value to put in
     *   this field.
     *
     *   This DisplayableOrderDateTime will appear as the "order date" in
     *   recipient-facing materials such as the packing slip.  The format
     *   must be timestamp.
     *
     *
     *   The DisplayableOrderId will appear as the "order id" in those
     *   materials, and the DisplayableOrderComment will appear as well.
     *
     *   ShippingSpeedCategory is the Service Level Agreement for how long it
     *   will take a shipment to be transported from the fulfillment center
     *   to the recipient, once shipped. no default.
     *   The following shipping speeds are available for US domestic:
     *    * Standard, 3-5 business days
     *    * Expedited, 2 business days
     *    * Priority, 1 business day
     *
     *   Shipping speeds may vary elsewhere.  Please consult your manual for published SLAs.
     *
     *
     *   DestinationAddress is the address the items will be shipped to.
     *
     *   FulfillmentPolicy indicates how unfulfillable items should be
     *   handled. default is FillOrKill.
     *    * FillOrKill if any item is determined to be unfulfillable
     *      before any items have started shipping, the entire order is
     *      considered unfulfillable.  Once any part of the order has
     *      started shipping, as much of the order as possible will be
     *      shipped.
     *    * FillAll never consider any item unfulfillable.  Items must
     *      either be fulfilled or merchant-cancelled.
     *    * FillAllAvailable fulfill as much of the order as possible.
     *
     *   FulfillmentMethod indicates the intended recipient channel for the
     *   order whether it be a consumer order or inventory return.
     *   default is Consumer.
     *   The available methods to fulfill a given order:
     *    * Consumer indicates a customer order, this is the default.
     *    * Removal indicates that the inventory should be returned to the
     *      specified destination address.
     *
     *
     *   NotificationEmailList can be used to provide a list of e-mail
     *   addresses to receive ship-complete e-mail notifications. These
     *   e-mails are customer-facing e-mails sent by FBA on behalf of
     *   the seller.
     *
     * @param mixed $request array of parameters for FBAOutboundServiceMWS_Model_CreateFulfillmentOrder request or FBAOutboundServiceMWS_Model_CreateFulfillmentOrder object itself
     * @see FBAOutboundServiceMWS_Model_CreateFulfillmentOrderRequest
     * @return FBAOutboundServiceMWS_Model_CreateFulfillmentOrderResponse
     *
     * @throws FBAOutboundServiceMWS_Exception
     */
    public function createFulfillmentOrder($request)
    {
        if (!($request instanceof FBAOutboundServiceMWS_Model_CreateFulfillmentOrderRequest)) {
            $request = new FBAOutboundServiceMWS_Model_CreateFulfillmentOrderRequest($request);
        }
        $parameters = $request->toQueryParameterArray();
        $parameters['Action'] = 'CreateFulfillmentOrder';
        $httpResponse = $this->_invoke($parameters);

        $response = FBAOutboundServiceMWS_Model_CreateFulfillmentOrderResponse::fromXML($httpResponse['ResponseBody']);
        $response->setResponseHeaderMetadata($httpResponse['ResponseHeaderMetadata']);
        return $response;
    }

    /**
     * Get Fulfillment Order
     * Get detailed information about a FulfillmentOrder.  This includes the
     *   original fulfillment order request, the status of the order and its
     *   items in Amazon's fulfillment network, and the shipments that have been
     *   generated to fulfill the order.
     *
     * @param mixed $request array of parameters for FBAOutboundServiceMWS_Model_GetFulfillmentOrder request or FBAOutboundServiceMWS_Model_GetFulfillmentOrder object itself
     * @see FBAOutboundServiceMWS_Model_GetFulfillmentOrderRequest
     * @return FBAOutboundServiceMWS_Model_GetFulfillmentOrderResponse
     *
     * @throws FBAOutboundServiceMWS_Exception
     */
    public function getFulfillmentOrder($request)
    {
        if (!($request instanceof FBAOutboundServiceMWS_Model_GetFulfillmentOrderRequest)) {
            $request = new FBAOutboundServiceMWS_Model_GetFulfillmentOrderRequest($request);
        }
        $parameters = $request->toQueryParameterArray();
        $parameters['Action'] = 'GetFulfillmentOrder';
        $httpResponse = $this->_invoke($parameters);

        $response = FBAOutboundServiceMWS_Model_GetFulfillmentOrderResponse::fromXML($httpResponse['ResponseBody']);
        $response->setResponseHeaderMetadata($httpResponse['ResponseHeaderMetadata']);
        return $response;
    }

    /**
     * Get Fulfillment Preview
     * Get estimated shipping dates and fees for all
     *   available shipping speed given a set of seller SKUs and quantities
     *
     *   If "ShippingSpeedCategories" are inputed, only previews for those options will be returned.
     *
     *   If "ShippingSpeedCategories" are not inputed, then previews for all available options
     *   are returned.
     *
     *   The service will return the fulfillment estimates for a set of Seller
     *   SKUs and quantities.
     *
     * @param mixed $request array of parameters for FBAOutboundServiceMWS_Model_GetFulfillmentPreview request or FBAOutboundServiceMWS_Model_GetFulfillmentPreview object itself
     * @see FBAOutboundServiceMWS_Model_GetFulfillmentPreviewRequest
     * @return FBAOutboundServiceMWS_Model_GetFulfillmentPreviewResponse
     *
     * @throws FBAOutboundServiceMWS_Exception
     */
    public function getFulfillmentPreview($request)
    {
        if (!($request instanceof FBAOutboundServiceMWS_Model_GetFulfillmentPreviewRequest)) {
            $request = new FBAOutboundServiceMWS_Model_GetFulfillmentPreviewRequest($request);
        }
        $parameters = $request->toQueryParameterArray();
        $parameters['Action'] = 'GetFulfillmentPreview';
        $httpResponse = $this->_invoke($parameters);

        $response = FBAOutboundServiceMWS_Model_GetFulfillmentPreviewResponse::fromXML($httpResponse['ResponseBody']);
        $response->setResponseHeaderMetadata($httpResponse['ResponseHeaderMetadata']);
        return $response;
    }

    /**
     * Get Package Tracking Details
     * Gets the tracking details for a shipment package.
     *
     * @param mixed $request array of parameters for FBAOutboundServiceMWS_Model_GetPackageTrackingDetails request or FBAOutboundServiceMWS_Model_GetPackageTrackingDetails object itself
     * @see FBAOutboundServiceMWS_Model_GetPackageTrackingDetailsRequest
     * @return FBAOutboundServiceMWS_Model_GetPackageTrackingDetailsResponse
     *
     * @throws FBAOutboundServiceMWS_Exception
     */
    public function getPackageTrackingDetails($request)
    {
        if (!($request instanceof FBAOutboundServiceMWS_Model_GetPackageTrackingDetailsRequest)) {
            $request = new FBAOutboundServiceMWS_Model_GetPackageTrackingDetailsRequest($request);
        }
        $parameters = $request->toQueryParameterArray();
        $parameters['Action'] = 'GetPackageTrackingDetails';
        $httpResponse = $this->_invoke($parameters);

        $response = FBAOutboundServiceMWS_Model_GetPackageTrackingDetailsResponse::fromXML($httpResponse['ResponseBody']);
        $response->setResponseHeaderMetadata($httpResponse['ResponseHeaderMetadata']);
        return $response;
    }

    /**
     * Get Service Status
     * Request to poll the system for availability.
     *   Status is one of GREEN, RED representing:
     *   GREEN: The service section is operating normally.
     *   RED: The service section disruption.
     *
     * @param mixed $request array of parameters for FBAOutboundServiceMWS_Model_GetServiceStatus request or FBAOutboundServiceMWS_Model_GetServiceStatus object itself
     * @see FBAOutboundServiceMWS_Model_GetServiceStatusRequest
     * @return FBAOutboundServiceMWS_Model_GetServiceStatusResponse
     *
     * @throws FBAOutboundServiceMWS_Exception
     */
    public function getServiceStatus($request)
    {
        if (!($request instanceof FBAOutboundServiceMWS_Model_GetServiceStatusRequest)) {
            $request = new FBAOutboundServiceMWS_Model_GetServiceStatusRequest($request);
        }
        $parameters = $request->toQueryParameterArray();
        $parameters['Action'] = 'GetServiceStatus';
        $httpResponse = $this->_invoke($parameters);

        $response = FBAOutboundServiceMWS_Model_GetServiceStatusResponse::fromXML($httpResponse['ResponseBody']);
        $response->setResponseHeaderMetadata($httpResponse['ResponseHeaderMetadata']);
        return $response;
    }

    /**
     * List All Fulfillment Orders
     * Gets the first set of fulfillment orders that are currently being
     *   fulfilled or that were being fulfilled at some time in the past
     *   (as specified by the query parameters). Also returns a NextToken
     *   which can be used iterate through the remaining fulfillment orders
     *   (via the ListAllFulfillmentOrdersByNextToken operation).
     *
     *   If a NextToken is not returned, it indicates the end-of-data.
     *
     *   If the QueryStartDateTime is set, the results will include all orders
     *   currently being fulfilled, and all orders that were being fulfilled
     *   since that date and time.
     *
     * @param mixed $request array of parameters for FBAOutboundServiceMWS_Model_ListAllFulfillmentOrders request or FBAOutboundServiceMWS_Model_ListAllFulfillmentOrders object itself
     * @see FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersRequest
     * @return FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersResponse
     *
     * @throws FBAOutboundServiceMWS_Exception
     */
    public function listAllFulfillmentOrders($request)
    {
        if (!($request instanceof FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersRequest)) {
            $request = new FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersRequest($request);
        }
        $parameters = $request->toQueryParameterArray();
        $parameters['Action'] = 'ListAllFulfillmentOrders';
        $httpResponse = $this->_invoke($parameters);

        $response = FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersResponse::fromXML($httpResponse['ResponseBody']);
        $response->setResponseHeaderMetadata($httpResponse['ResponseHeaderMetadata']);
        return $response;
    }

    /**
     * List All Fulfillment Orders By Next Token
     * Gets the next set of fulfillment orders that are currently being
     *   being fulfilled or that were being fulfilled at some time in the
     *   past.
     *
     *   If a NextToken is not returned, it indicates the end-of-data.
     *
     * @param mixed $request array of parameters for FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersByNextToken request or FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersByNextToken object itself
     * @see FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersByNextTokenRequest
     * @return FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersByNextTokenResponse
     *
     * @throws FBAOutboundServiceMWS_Exception
     */
    public function listAllFulfillmentOrdersByNextToken($request)
    {
        if (!($request instanceof FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersByNextTokenRequest)) {
            $request = new FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersByNextTokenRequest($request);
        }
        $parameters = $request->toQueryParameterArray();
        $parameters['Action'] = 'ListAllFulfillmentOrdersByNextToken';
        $httpResponse = $this->_invoke($parameters);

        $response = FBAOutboundServiceMWS_Model_ListAllFulfillmentOrdersByNextTokenResponse::fromXML($httpResponse['ResponseBody']);
        $response->setResponseHeaderMetadata($httpResponse['ResponseHeaderMetadata']);
        return $response;
    }

    /**
     * Update Fulfillment Order
     * The SellerFulfillmentOrderId must be the order ID of the original
     *     order that needs to be updated.
     *
     *   This DisplayableOrderDateTime will appear as the "order date" in
     *   recipient-facing materials such as the packing slip.  The format
     *   must be timestamp.
     *
     *   The DisplayableOrderId will appear as the "order id" in those
     *   materials, and the DisplayableOrderComment will appear as well.
     *
     *   ShippingSpeedCategory is the Service Level Agreement for how long it
     *   will take a shipment to be transported from the fulfillment center
     *   to the recipient, once shipped. no default.
     *   The following shipping speeds are available for US domestic:
     *    * Standard, 3-5 business days
     *    * Expedited, 2 business days
     *    * Priority, 1 business day
     *
     *   Shipping speeds may vary elsewhere.  Please consult your manual for published SLAs.
     *
     *
     *   DestinationAddress is the address the items will be shipped to.
     *
     *   FulfillmentAction indicates whether an order will be held or shipped.
     *   Default is Hold.
     *   * Hold if the order needs to be held but does not need to be shipped.
     *   * Ship if the order is to be fulfilled and shipped out to the customer
     *   immediately.
     *
     *   FulfillmentPolicy indicates how unfulfillable items should be
     *   handled. default is FillOrKill.
     *    * FillOrKill if any item is determined to be unfulfillable
     *      before any items have started shipping, the entire order is
     *      considered unfulfillable.  Once any part of the order has
     *      started shipping, as much of the order as possible will be
     *      shipped.
     *    * FillAll never consider any item unfulfillable.  Items must
     *      either be fulfilled or merchant-cancelled.
     *    * FillAllAvailable fulfill as much of the order as possible.
     *
     *   NotificationEmailList can be used to provide a list of e-mail
     *   addresses to receive ship-complete e-mail notifications. These
     *   e-mails are customer-facing e-mails sent by FBA on behalf of
     *   the seller.
     *
     * @param mixed $request array of parameters for FBAOutboundServiceMWS_Model_UpdateFulfillmentOrder request or FBAOutboundServiceMWS_Model_UpdateFulfillmentOrder object itself
     * @see FBAOutboundServiceMWS_Model_UpdateFulfillmentOrderRequest
     * @return FBAOutboundServiceMWS_Model_UpdateFulfillmentOrderResponse
     *
     * @throws FBAOutboundServiceMWS_Exception
     */
    public function updateFulfillmentOrder($request)
    {
        if (!($request instanceof FBAOutboundServiceMWS_Model_UpdateFulfillmentOrderRequest)) {
            $request = new FBAOutboundServiceMWS_Model_UpdateFulfillmentOrderRequest($request);
        }
        $parameters = $request->toQueryParameterArray();
        $parameters['Action'] = 'UpdateFulfillmentOrder';
        $httpResponse = $this->_invoke($parameters);

        $response = FBAOutboundServiceMWS_Model_UpdateFulfillmentOrderResponse::fromXML($httpResponse['ResponseBody']);
        $response->setResponseHeaderMetadata($httpResponse['ResponseHeaderMetadata']);
        return $response;
    }

    /**
     * Construct new Client
     *
     * @param string $awsAccessKeyId AWS Access Key ID
     * @param string $awsSecretAccessKey AWS Secret Access Key
     * @param array $config configuration options.
     * Valid configuration options are:
     *

     *
ServiceURL

     *
UserAgent

     *
SignatureVersion

     *
TimesRetryOnError

     *
ProxyHost

     *
ProxyPort

     *
ProxyUsername

     *
ProxyPassword

     *
MaxErrorRetry

     *

     * @param $applicationName
     * @param $applicationVersion
     * @param null $attributes
     */
    public function __construct(
        $awsAccessKeyId,
        $awsSecretAccessKey,
        $config,
        $applicationName,
        $applicationVersion,
        $attributes = null
    ) {
        if(version_compare(PHP_VERSION, '5.6.0', '<')) {
            iconv_set_encoding('output_encoding', 'UTF-8');
            iconv_set_encoding('input_encoding', 'UTF-8');
            iconv_set_encoding('internal_encoding', 'UTF-8');
        }

        $this->_awsAccessKeyId = $awsAccessKeyId;
        $this->_awsSecretAccessKey = $awsSecretAccessKey;
        if (!is_null($config)) {
            $this->_config = array_merge($this->_config, $config);
        }
        $this->setUserAgentHeader($applicationName, $applicationVersion, $attributes);
    }

    public function setUserAgentHeader(
        $applicationName,
        $applicationVersion,
        $attributes = null
    ) {

        if (is_null($attributes)) {
            $attributes = array();
        }

        $this->_config['UserAgent'] = $this->constructUserAgentHeader($applicationName, $applicationVersion,
            $attributes);
    }

    private function constructUserAgentHeader($applicationName, $applicationVersion, $attributes = null)
    {
        if (is_null($applicationName) || $applicationName === "") {
            throw new InvalidArgumentException('$applicationName cannot be null');
        }

        if (is_null($applicationVersion) || $applicationVersion === "") {
            throw new InvalidArgumentException('$applicationVersion cannot be null');
        }

        $userAgent = $this->quoteApplicationName($applicationName) . '/' . $this->quoteApplicationVersion($applicationVersion);

        $userAgent .= ' (';
        $userAgent .= 'Language=PHP/' . phpversion();
        $userAgent .= '; ';
        $userAgent .= 'Platform=' . php_uname('s') . '/' . php_uname('m') . '/' . php_uname('r');
        $userAgent .= '; ';
        $userAgent .= 'MWSClientVersion=' . self::MWS_CLIENT_VERSION;

        foreach ($attributes as $key => $value) {
            if (empty($value)) {
                throw new InvalidArgumentException("Value for $key cannot be null or empty.");
            }

            $userAgent .= '; ' . $this->quoteAttributeName($key) . '=' . $this->quoteAttributeValue($value);
        }

        $userAgent .= ')';

        return $userAgent;
    }

    /**
     * Collapse multiple whitespace characters into a single ' ' character.
     * @param $s
     * @return string
     */
    private function collapseWhitespace($s)
    {
        return preg_replace('/ {2,}|\s/', ' ', $s);
    }

    /**
     * Collapse multiple whitespace characters into a single ' ' and backslash escape '\',
     * and '/' characters from a string.
     * @param $s
     * @return string
     */
    private function quoteApplicationName($s)
    {
        $quotedString = $this->collapseWhitespace($s);
        $quotedString = preg_replace('/\\\\/', '\\\\\\\\', $quotedString);
        $quotedString = preg_replace('/\//', '\\/', $quotedString);

        return $quotedString;
    }

    /**
     * Collapse multiple whitespace characters into a single ' ' and backslash escape '\',
     * and '(' characters from a string.
     *
     * @param $s
     * @return string
     */
    private function quoteApplicationVersion($s)
    {
        $quotedString = $this->collapseWhitespace($s);
        $quotedString = preg_replace('/\\\\/', '\\\\\\\\', $quotedString);
        $quotedString = preg_replace('/\\(/', '\\(', $quotedString);

        return $quotedString;
    }

    /**
     * Collapse multiple whitespace characters into a single ' ' and backslash escape '\',
     * and '=' characters from a string.
     *
     * @param string $s
     * @return string
     */
    private function quoteAttributeName($s)
    {
        $quotedString = $this->collapseWhitespace($s);
        $quotedString = preg_replace('/\\\\/', '\\\\\\\\', $quotedString);
        $quotedString = preg_replace('/\\=/', '\\=', $quotedString);

        return $quotedString;
    }

    /**
     * Collapse multiple whitespace characters into a single ' ' and backslash escape ';', '\',
     * and ')' characters from a string.
     *
     * @param string $s
     * @return string
     */
    private function quoteAttributeValue($s)
    {
        $quotedString = $this->collapseWhitespace($s);
        $quotedString = preg_replace('/\\\\/', '\\\\\\\\', $quotedString);
        $quotedString = preg_replace('/\\;/', '\\;', $quotedString);
        $quotedString = preg_replace('/\\)/', '\\)', $quotedString);

        return $quotedString;
    }

    // Private API ------------------------------------------------------------//

    /**
     * Invoke request and return response
     * @param array $parameters
     * @return array
     * @throws Exception
     * @throws FBAOutboundServiceMWS_Exception
     */
    private function _invoke(array $parameters)
    {
        try {
            if (empty($this->_config['ServiceURL'])) {
                throw new FBAOutboundServiceMWS_Exception(array(
                    'ErrorCode' => 'InvalidServiceURL',
                    'Message' => "Missing serviceUrl configuration value. You may obtain a list of valid MWS URLs by consulting the MWS Developer's Guide, or reviewing the sample code published along side this library."
                ));
            }
            $parameters = $this->_addRequiredParameters($parameters);
            $retries = 0;
            for (; ;) {
                $response = $this->_httpPost($parameters);
                $status = (int) $response['Status'];
                if ($status == 200) {
                    return array(
                        'ResponseBody' => $response['ResponseBody'],
                        'ResponseHeaderMetadata' => $response['ResponseHeaderMetadata']
                    );
                }
                if ($status == 500 && $this->_pauseOnRetry(++$retries)) {
                    continue;
                }
                throw $this->_reportAnyErrors($response['ResponseBody'], $status, $response['ResponseHeaderMetadata']);
            }
        } catch(FBAOutboundServiceMWS_Exception $se) {
            throw $se;
        } catch(Exception $t) {
            throw new FBAOutboundServiceMWS_Exception(array('Exception' => $t, 'Message' => $t->getMessage()));
        }
    }

    /**
     * Look for additional error strings in the response and return formatted exception
     * @param $responseBody
     * @param $status
     * @param $responseHeaderMetadata
     * @param Exception $e
     * @return FBAOutboundServiceMWS_Exception
     */
    private function _reportAnyErrors($responseBody, $status, $responseHeaderMetadata, Exception $e = null)
    {
        $exProps = array();
        $exProps["StatusCode"] = $status;
        $exProps["ResponseHeaderMetadata"] = $responseHeaderMetadata;

        libxml_use_internal_errors(true);  // Silence XML parsing errors
        $xmlBody = simplexml_load_string($responseBody);

        if ($xmlBody !== false) {  // Check XML loaded without errors
            $exProps["XML"] = $responseBody;
            $exProps["ErrorCode"] = $xmlBody->Error->Code;
            $exProps["Message"] = $xmlBody->Error->Message;
            $exProps["ErrorType"] = !empty($xmlBody->Error->Type) ? $xmlBody->Error->Type : "Unknown";
            $exProps["RequestId"] = !empty($xmlBody->RequestID) ? $xmlBody->RequestID : $xmlBody->RequestId; // 'd' in RequestId is sometimes capitalized
        } else { // We got bad XML in response, just throw a generic exception
            $exProps["Message"] = "Internal Error";
        }

        return new FBAOutboundServiceMWS_Exception($exProps);
    }

    /**
     * Perform HTTP post with exponential retries on error 500 and 503
     * @param array $parameters
     * @return array
     * @throws FBAOutboundServiceMWS_Exception
     */
    private function _httpPost(array $parameters)
    {
        $config = $this->_config;
        $query = $this->_getParametersAsString($parameters);
        $url = parse_url($config['ServiceURL']);
        $uri = array_key_exists('path', $url) ? $url['path'] : null;
        if (!isset ($uri)) {
            $uri = "/";
        }

        switch ($url['scheme']) {
            case 'https':
                $scheme = 'https://';
                $port = isset($url['port']) ? $url['port'] : 443;
                break;
            default:
                $scheme = 'http://';
                $port = isset($url['port']) ? $url['port'] : 80;
        }

        $allHeaders = $config['Headers'];
        $allHeaders['Content-Type'] = "application/x-www-form-urlencoded; charset=utf-8"; // We need to make sure to set utf-8 encoding here
        $allHeaders['Expect'] = null; // Don't expect 100 Continue
        $allHeadersStr = array();
        foreach ($allHeaders as $name => $val) {
            $str = $name . ": ";
            if (isset($val)) {
                $str = $str . $val;
            }
            $allHeadersStr[] = $str;
        }

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $scheme . $url['host'] . $uri);
        curl_setopt($ch, CURLOPT_PORT, $port);
        $this->setSSLCurlOptions($ch);
        curl_setopt($ch, CURLOPT_USERAGENT, $this->_config['UserAgent']);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $allHeadersStr);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if ($config['ProxyHost'] != null && $config['ProxyPort'] != -1) {
            curl_setopt($ch, CURLOPT_PROXY, $config['ProxyHost'] . ':' . $config['ProxyPort']);
        }
        if ($config['ProxyUsername'] != null && $config['ProxyPassword'] != null) {
            curl_setopt($ch, CURLOPT_PROXYUSERPWD, $config['ProxyUsername'] . ':' . $config['ProxyPassword']);
        }

        $response = curl_exec($ch);

        if ($response === false) {
            $exProps["Message"] = curl_error($ch);
            $exProps["ErrorType"] = "HTTP";
            curl_close($ch);
            throw new FBAOutboundServiceMWS_Exception($exProps);
        }

        curl_close($ch);
        return $this->_extractHeadersAndBody($response);
    }

    /**
     * This method will attempt to extract the headers and body of our response.
     * We need to split the raw response string by 2 'CRLF's.  2 'CRLF's should indicate the separation of the response header
     * from the response body.  However in our case we have some circumstances (certain client proxies) that result in
     * multiple responses concatenated.  We could encounter a response like
     *
     * HTTP/1.1 100 Continue
     *
     * HTTP/1.1 200 OK
     * Date: Tue, 01 Apr 2014 13:02:51 GMT
     * Content-Type: text/html; charset=iso-8859-1
     * Content-Length: 12605
     *
     * ... body ..
     *
     * This method will throw away extra response status lines and attempt to find the first full response headers and body
     *
     * return [status, body, ResponseHeaderMetadata]
     * @param $response
     * @return array
     * @throws FBAOutboundServiceMWS_Exception
     */
    private function _extractHeadersAndBody($response)
    {
        //First split by 2 'CRLF'
        $responseComponents = preg_split("/(?:\r?\n){2}/", $response, 2);
        $body = null;
        for ($count = 0; $count < count($responseComponents) && $body == null; $count++) {

            $headers = $responseComponents[$count];
            $responseStatus = $this->_extractHttpStatusCode($headers);

            if ($responseStatus != null && $this->_httpHeadersHaveContent($headers)) {

                $responseHeaderMetadata = $this->_extractResponseHeaderMetadata($headers);
                //The body will be the next item in the responseComponents array
                $body = $responseComponents[++$count];
            }
        }

        //If the body is null here then we were unable to parse the response and will throw an exception
        if ($body == null) {
            $exProps["Message"] = "Failed to parse valid HTTP response (" . $response . ")";
            $exProps["ErrorType"] = "HTTP";
            throw new FBAOutboundServiceMWS_Exception($exProps);
        }

        return array(
            'Status' => $responseStatus,
            'ResponseBody' => $body,
            'ResponseHeaderMetadata' => $responseHeaderMetadata
        );
    }

    /**
     * parse the status line of a header string for the proper format and
     * return the status code
     *
     * Example: HTTP/1.1 200 OK
     * ...
     * returns String statusCode or null if the status line can't be parsed
     * @param $headers
     * @return null
     */
    private function _extractHttpStatusCode($headers)
    {
        $statusCode = null;
        if (1 === preg_match("/(\\S+) +(\\d+) +([^\n\r]+)(?:\r?\n|\r)/", $headers, $matches)) {
            //The matches array [entireMatchString, protocol, statusCode, the rest]
            $statusCode = $matches[2];
        }
        return $statusCode;
    }

    /**
     * Tries to determine some valid headers indicating this response
     * has content.  In this case
     * return true if there is a valid "Content-Length" or "Transfer-Encoding" header
     * @param $headers
     * @return bool
     */
    private function _httpHeadersHaveContent($headers)
    {
        return (1 === preg_match("/[cC]ontent-[lL]ength: +(?:\\d+)(?:\\r?\\n|\\r|$)/",
                $headers) || 1 === preg_match("/Transfer-Encoding: +(?!identity[\r\n;= ])(?:[^\r\n]+)(?:\r?\n|\r|$)/i",
                $headers));
    }

    /**
     *  extract a ResponseHeaderMetadata object from the raw headers
     * @param $rawHeaders
     * @return FBAOutboundServiceMWS_Model_ResponseHeaderMetadata
     */
    private function _extractResponseHeaderMetadata($rawHeaders)
    {
        $inputHeaders = preg_split("/\r\n|\n|\r/", $rawHeaders);
        $headers = array();
        $headers['x-mws-request-id'] = null;
        $headers['x-mws-response-context'] = null;
        $headers['x-mws-timestamp'] = null;
        $headers['x-mws-quota-max'] = null;
        $headers['x-mws-quota-remaining'] = null;
        $headers['x-mws-quota-resetsOn'] = null;

        foreach ($inputHeaders as $currentHeader) {
            $keyValue = explode(': ', $currentHeader);
            if (isset($keyValue[1])) {
                list ($key, $value) = $keyValue;
                if (isset($headers[$key]) && $headers[$key] !== null) {
                    $headers[$key] = $headers[$key] . "," . $value;
                } else {
                    $headers[$key] = $value;
                }
            }
        }

        return new FBAOutboundServiceMWS_Model_ResponseHeaderMetadata($headers['x-mws-request-id'],
            $headers['x-mws-response-context'], $headers['x-mws-timestamp'], $headers['x-mws-quota-max'],
            $headers['x-mws-quota-remaining'], $headers['x-mws-quota-resetsOn']);
    }

    /**
     * Set curl options relating to SSL. Protected to allow overriding.
     * @param $ch resource curl handle
     */
    protected function setSSLCurlOptions($ch)
    {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->_config['SSL_VerifyPeer']);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $this->_config['SSL_VerifyHost']);
    }

    /**
     * Exponential sleep on failed request
     *
     * @param int $retries current retry
     * @return bool
     */
    private function _pauseOnRetry($retries)
    {
        if ($retries <= $this->_config['MaxErrorRetry']) {
            $delay = (int)(pow(4, $retries) * 100000);
            usleep($delay);
            return true;
        }
        return false;
    }

    /**
     * Add authentication related and version parameters
     * @param array $parameters
     * @return array
     * @throws Exception
     */
    private function _addRequiredParameters(array $parameters)
    {
        $parameters['AWSAccessKeyId'] = $this->_awsAccessKeyId;
        $parameters['Timestamp'] = $this->_getFormattedTimestamp();
        $parameters['Version'] = self::SERVICE_VERSION;
        $parameters['SignatureVersion'] = $this->_config['SignatureVersion'];
        if ($parameters['SignatureVersion'] > 1) {
            $parameters['SignatureMethod'] = $this->_config['SignatureMethod'];
        }
        $parameters['Signature'] = $this->_signParameters($parameters, $this->_awsSecretAccessKey);

        return $parameters;
    }

    /**
     * Convert paremeters to Url encoded query string
     * @param array $parameters
     * @return string
     */
    private function _getParametersAsString(array $parameters)
    {
        $queryParameters = array();
        foreach ($parameters as $key => $value) {
            $queryParameters[] = $key . '=' . $this->_urlencode($value);
        }
        return implode('&', $queryParameters);
    }

    /**
     * Computes RFC 2104-compliant HMAC signature for request parameters
     * Implements AWS Signature, as per following spec:
     *
     * If Signature Version is 0, it signs concatenated Action and Timestamp
     *
     * If Signature Version is 1, it performs the following:
     *
     * Sorts all  parameters (including SignatureVersion and excluding Signature,
     * the value of which is being created), ignoring case.
     *
     * Iterate over the sorted list and append the parameter name (in original case)
     * and then its value. It will not URL-encode the parameter values before
     * constructing this string. There are no separators.
     *
     * If Signature Version is 2, string to sign is based on following:
     *
     *    1. The HTTP Request Method followed by an ASCII newline (%0A)
     *    2. The HTTP Host header in the form of lowercase host, followed by an ASCII newline.
     *    3. The URL encoded HTTP absolute path component of the URI
     *       (up to but not including the query string parameters);
     *       if this is empty use a forward '/'. This parameter is followed by an ASCII newline.
     *    4. The concatenation of all query string components (names and values)
     *       as UTF-8 characters which are URL encoded as per RFC 3986
     *       (hex characters MUST be uppercase), sorted using lexicographic byte ordering.
     *       Parameter names are separated from their values by the '=' character
     *       (ASCII character 61), even if the value is empty.
     *       Pairs of parameter and values are separated by the '&' character (ASCII code 38).
     * @param array $parameters
     * @param $key
     * @return string
     * @throws Exception
     */
    private function _signParameters(array $parameters, $key)
    {
        $signatureVersion = $parameters['SignatureVersion'];
        $stringToSign = null;
        if (2 == $signatureVersion) {
            $algorithm = $this->_config['SignatureMethod'];
            $parameters['SignatureMethod'] = $algorithm;
            $stringToSign = $this->_calculateStringToSignV2($parameters);
        } else {
            throw new Exception("Invalid Signature Version specified");
        }
        return $this->_sign($stringToSign, $key, $algorithm);
    }

    /**
     * Calculate String to Sign for SignatureVersion 2
     * @param array $parameters request parameters
     * @return String to Sign
     */
    private function _calculateStringToSignV2(array $parameters)
    {
        $data = 'POST';
        $data .= "\n";
        $endpoint = parse_url($this->_config['ServiceURL']);
        $data .= $endpoint['host'];
        $data .= "\n";
        $uri = array_key_exists('path', $endpoint) ? $endpoint['path'] : null;
        if (!isset ($uri)) {
            $uri = "/";
        }
        $uriencoded = implode("/", array_map(array($this, "_urlencode"), explode("/", $uri)));
        $data .= $uriencoded;
        $data .= "\n";
        uksort($parameters, 'strcmp');
        $data .= $this->_getParametersAsString($parameters);
        return $data;
    }

    private function _urlencode($value)
    {
        return str_replace('%7E', '~', rawurlencode($value));
    }

    /**
     * Computes RFC 2104-compliant HMAC signature.
     * @param $data
     * @param $key
     * @param $algorithm
     * @return string
     * @throws Exception
     */
    private function _sign($data, $key, $algorithm)
    {
        if ($algorithm === 'HmacSHA1') {
            $hash = 'sha1';
        } else if ($algorithm === 'HmacSHA256') {
            $hash = 'sha256';
        } else {
            throw new Exception ("Non-supported signing method specified");
        }
        return base64_encode(hash_hmac($hash, $data, $key, true));
    }

    /**
     * Formats date as ISO 8601 timestamp
     */
    private function _getFormattedTimestamp()
    {
        return gmdate("Y-m-d\\TH:i:s.\\0\\0\\0\\Z", time());
    }
}


<?php
/*******************************************************************************
 * Copyright 2009-2014 Amazon Services. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at: http://aws.amazon.com/apache2.0
 * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *******************************************************************************
 * PHP Version 5
 * @category Amazon
 * @package  Marketplace Web Service Products
 * @version  2011-10-01
 * Library Version: 2014-10-20
 * Generated: Fri Oct 17 17:59:56 GMT 2014
 */

/**
 * MarketplaceWebServiceProducts_Model_GetMatchingProductForIdResponse
 *
 * Properties:
 *

 *
 *
GetMatchingProductForIdResult: array

 *
ResponseMetadata: MarketplaceWebServiceProducts_Model_ResponseMetadata

 *
ResponseHeaderMetadata: MarketplaceWebServiceProducts_Model_ResponseHeaderMetadata

 *
 *

 */
class MarketplaceWebServiceProducts_Model_GetMatchingProductForIdResponse extends MarketplaceWebServiceProducts_Model
{

    public function __construct($data = null)
    {
        $this->_fields = array(
            'GetMatchingProductForIdResult' => array(
                'FieldValue' => array(),
                'FieldType' => array('MarketplaceWebServiceProducts_Model_GetMatchingProductForIdResult')
            ),
            'ResponseMetadata' => array(
                'FieldValue' => null,
                'FieldType' => 'MarketplaceWebServiceProducts_Model_ResponseMetadata'
            ),
            'ResponseHeaderMetadata' => array(
                'FieldValue' => null,
                'FieldType' => 'MarketplaceWebServiceProducts_Model_ResponseHeaderMetadata'
            ),
        );
        parent::__construct($data);
    }

    /**
     * Get the value of the GetMatchingProductForIdResult property.
     *
     * @return MarketplaceWebServiceProducts_Model_GetMatchingProductForIdResult[] GetMatchingProductForIdResult.
     */
    public function getGetMatchingProductForIdResult()
    {
        if ($this->_fields['GetMatchingProductForIdResult']['FieldValue'] == null) {
            $this->_fields['GetMatchingProductForIdResult']['FieldValue'] = array();
        }
        return $this->_fields['GetMatchingProductForIdResult']['FieldValue'];
    }

    /**
     * Set the value of the GetMatchingProductForIdResult property.
     *
     * @param array $value getMatchingProductForIdResult
     * @return $this This instance
     */
    public function setGetMatchingProductForIdResult($value)
    {
        if (!$this->_isNumericArray($value)) {
            $value = array($value);
        }
        $this->_fields['GetMatchingProductForIdResult']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Clear GetMatchingProductForIdResult.
     */
    public function unsetGetMatchingProductForIdResult()
    {
        $this->_fields['GetMatchingProductForIdResult']['FieldValue'] = array();
    }

    /**
     * Check to see if GetMatchingProductForIdResult is set.
     *
     * @return true if GetMatchingProductForIdResult is set.
     */
    public function isSetGetMatchingProductForIdResult()
    {
        return !empty($this->_fields['GetMatchingProductForIdResult']['FieldValue']);
    }

    /**
     * Add values for GetMatchingProductForIdResult, return this.
     *
     * @param getMatchingProductForIdResult
     *             New values to add.
     *
     * @return $this This instance.
     */
    public function withGetMatchingProductForIdResult()
    {
        foreach (func_get_args() as $GetMatchingProductForIdResult) {
            $this->_fields['GetMatchingProductForIdResult']['FieldValue'][] = $GetMatchingProductForIdResult;
        }
        return $this;
    }

    /**
     * Get the value of the ResponseMetadata property.
     *
     * @return MarketplaceWebServiceProducts_Model_ResponseMetadata ResponseMetadata.
     */
    public function getResponseMetadata()
    {
        return $this->_fields['ResponseMetadata']['FieldValue'];
    }

    /**
     * Set the value of the ResponseMetadata property.
     *
     * @param MarketplaceWebServiceProducts_Model_ResponseMetadata $value responseMetadata
     * @return $this This instance
     */
    public function setResponseMetadata($value)
    {
        $this->_fields['ResponseMetadata']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if ResponseMetadata is set.
     *
     * @return true if ResponseMetadata is set.
     */
    public function isSetResponseMetadata()
    {
        return !is_null($this->_fields['ResponseMetadata']['FieldValue']);
    }

    /**
     * Set the value of ResponseMetadata, return this.
     *
     * @param responseMetadata
     *             The new value to set.
     *
     * @return $this This instance.
     */
    public function withResponseMetadata($value)
    {
        $this->setResponseMetadata($value);
        return $this;
    }

    /**
     * Get the value of the ResponseHeaderMetadata property.
     *
     * @return MarketplaceWebServiceProducts_Model_ResponseHeaderMetadata ResponseHeaderMetadata.
     */
    public function getResponseHeaderMetadata()
    {
        return $this->_fields['ResponseHeaderMetadata']['FieldValue'];
    }

    /**
     * Set the value of the ResponseHeaderMetadata property.
     *
     * @param MarketplaceWebServiceProducts_Model_ResponseHeaderMetadata $value responseHeaderMetadata
     * @return $this This instance
     */
    public function setResponseHeaderMetadata($value)
    {
        $this->_fields['ResponseHeaderMetadata']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Check to see if ResponseHeaderMetadata is set.
     *
     * @return true if ResponseHeaderMetadata is set.
     */
    public function isSetResponseHeaderMetadata()
    {
        return !is_null($this->_fields['ResponseHeaderMetadata']['FieldValue']);
    }

    /**
     * Set the value of ResponseHeaderMetadata, return this.
     *
     * @param responseHeaderMetadata
     *             The new value to set.
     *
     * @return $this This instance.
     */
    public function withResponseHeaderMetadata($value)
    {
        $this->setResponseHeaderMetadata($value);
        return $this;
    }

    /**
     * Construct MarketplaceWebServiceProducts_Model_GetMatchingProductForIdResponse from XML string
     *
     * @param $xml
     *        XML string to construct from
     * @return MarketplaceWebServiceProducts_Model_GetMatchingProductForIdResponse
     * @throws Exception
     */
    public static function fromXML($xml)
    {
        $dom = new DOMDocument();
        $dom->loadXML($xml);
        $xpath = new DOMXPath($dom);
        $response = $xpath->query("//*[local-name()='GetMatchingProductForIdResponse']");
        if ($response->length == 1) {
            return new MarketplaceWebServiceProducts_Model_GetMatchingProductForIdResponse(($response->item(0)));
        } else {
            throw new Exception ("Unable to construct MarketplaceWebServiceProducts_Model_GetMatchingProductForIdResponse from provided XML.
                                  Make sure that GetMatchingProductForIdResponse is a root element");
        }
    }

    /**
     * XML Representation for this object
     *
     * @return string XML for this object
     */
    public function toXML()
    {
        $xml = "";
        $xml .= "<GetMatchingProductForIdResponse xmlns=\"http://mws.amazonservices.com/schema/Products/2011-10-01\">";
        $xml .= $this->_toXMLFragment();
        $xml .= "</GetMatchingProductForIdResponse>";
        return $xml;
    }

}


<?php
/**
 *  PHP Version 5
 *
 * @category    Amazon
 * @package     MarketplaceWebService
 * @copyright   Copyright 2009 Amazon Technologies, Inc.
 * @link        http://aws.amazon.com
 * @license     http://aws.amazon.com/apache2.0  Apache License, Version 2.0
 * @version     2009-01-01
 */
/*******************************************************************************
 *  Marketplace Web Service PHP5 Library
 *  Generated: Thu May 07 13:07:36 PDT 2009
 *
 */

/**
 * MarketplaceWebService_Model_SubmitFeedRequest
 *
 * Properties:
 *

 *
 *
Marketplace: string

 *
Merchant: string

 *
MarketplaceIdList: MarketplaceWebService_Model_IdList

 *
FeedContent: string

 *
FeedType: string

 *
PurgeAndReplace: bool

 *
 *

 */
class MarketplaceWebService_Model_SubmitFeedRequest extends MarketplaceWebService_Model
{

    /**
     * Construct new MarketplaceWebService_Model_SubmitFeedRequest
     *
     * @param mixed $data DOMElement or Associative Array to construct from.
     *
     * Valid properties:
     *

     *
     *
Marketplace: string

     *
Merchant: string

     *
MarketplaceIdList: MarketplaceWebService_Model_IdList

     *
FeedContent: string

     *
FeedType: string

     *
PurgeAndReplace: bool

     *
     *

     */

    private static $DEFAULT_CONTENT_TYPE;

    public function __construct($data = null)
    {
        self::$DEFAULT_CONTENT_TYPE = new MarketplaceWebService_Model_ContentType(array('ContentType' => 'application/octet-stream'));

        // Here we're setting the content-type field directly to the object, but beware the actual
        // method of construction from associative arrays from the client interface would do something like:
        // $parameters = array ('ContentType' => array('ContentType' => 'application/octet-stream'));

        $this->fields = array(
            'Marketplace' => array('FieldValue' => null, 'FieldType' => 'string'),
            'Merchant' => array('FieldValue' => null, 'FieldType' => 'string'),
            'MWSAuthToken' => array('FieldValue' => null, 'FieldType' => 'string'),
            'MarketplaceIdList' => array('FieldValue' => null, 'FieldType' => 'MarketplaceWebService_Model_IdList'),
            'FeedContent' => array('FieldValue' => null, 'FieldType' => 'string'),
            'FeedType' => array('FieldValue' => null, 'FieldType' => 'string'),
            'PurgeAndReplace' => array('FieldValue' => null, 'FieldType' => 'bool'),
            'ContentMd5' => array('FieldValue' => null, 'FieldType' => 'string'),
            'ContentType' => array(
                'FieldValue' => self::$DEFAULT_CONTENT_TYPE,
                'FieldType' => 'MarketplaceWebService_Model_ContentType'
            )
        );

        parent::__construct($data);

        if (!is_null($this->fields['ContentType']['FieldValue'])) {
            $this->verifySupportedContentType($this->fields['ContentType']['FieldValue']);
        }

    }

    /**
     * @param $supplied
     * @throws MarketplaceWebService_Exception
     */
    private function verifySupportedContentType($supplied)
    {
        if (!($supplied == self::$DEFAULT_CONTENT_TYPE)) {
            throw new MarketplaceWebService_Exception(array(
                'Message' => "Unsupported ContentType " . $supplied->getContentType() . " ContentType must be " . self::$DEFAULT_CONTENT_TYPE->getContentType()
            ));
        }
    }

    /**
     * Gets the value of the content type
     *
     * @return MarketplaceWebService_Model_ContentType instance
     */

    public function getContentType()
    {
        return $this->fields['ContentType']['FieldValue'];
    }

    public function setContentType($value)
    {
        $this->verifySupportedContentType($value);
        $this->fields['ContentType']['FieldValue'] = $value;
        return $this;
    }

    public function isSetContentType()
    {
        return !is_null($this->fields['ContentType']['FieldValue']);
    }

    /**
     * Gets the value of the Marketplace property.
     *
     * @return string Marketplace
     */
    public function getMarketplace()
    {
        return $this->fields['Marketplace']['FieldValue'];
    }

    /**
     * Sets the value of the Marketplace property.
     *
     * @param string $value Marketplace
     * @return $this This instance
     */
    public function setMarketplace($value)
    {
        $this->fields['Marketplace']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Sets the value of the Marketplace and returns this instance
     *
     * @param string $value Marketplace
     * @return MarketplaceWebService_Model_SubmitFeedRequest instance
     */
    public function withMarketplace($value)
    {
        $this->setMarketplace($value);
        return $this;
    }

    /**
     * Checks if Marketplace is set
     *
     * @return bool true if Marketplace  is set
     */
    public function isSetMarketplace()
    {
        return !is_null($this->fields['Marketplace']['FieldValue']);
    }

    /**
     * Gets the value of the Merchant property.
     *
     * @return string Merchant
     */
    public function getMerchant()
    {
        return $this->fields['Merchant']['FieldValue'];
    }

    /**
     * Sets the value of the Merchant property.
     *
     * @param string $value Merchant
     * @return $this This instance
     */
    public function setMerchant($value)
    {
        $this->fields['Merchant']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Sets the value of the Merchant and returns this instance
     *
     * @param string $value Merchant
     * @return MarketplaceWebService_Model_SubmitFeedRequest instance
     */
    public function withMerchant($value)
    {
        $this->setMerchant($value);
        return $this;
    }

    /**
     * Checks if Merchant is set
     *
     * @return bool true if Merchant  is set
     */
    public function isSetMerchant()
    {
        return !is_null($this->fields['Merchant']['FieldValue']);
    }

    /**
     * Gets the value of the MWSAuthToken property.
     *
     * @return string MWSAuthToken
     */
    public function getMWSAuthToken()
    {
        return $this->fields['MWSAuthToken']['FieldValue'];
    }

    /**
     * Sets the value of the MWSAuthToken property.
     *
     * @param string $value MWSAuthToken
     * @return $this This instance
     */
    public function setMWSAuthToken($value)
    {
        $this->fields['MWSAuthToken']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Sets the value of the MWSAuthToken and returns this instance
     *
     * @param string $value MWSAuthToken
     * @return MarketplaceWebService_Model_SubmitFeedRequest instance
     */
    public function withMWSAuthToken($value)
    {
        $this->setMWSAuthToken($value);
        return $this;
    }

    /**
     * Checks if MWSAuthToken is set
     *
     * @return bool true if MWSAuthToken  is set
     */
    public function isSetMWSAuthToken()
    {
        return !is_null($this->fields['MWSAuthToken']['FieldValue']);
    }

    /**
     * Gets the value of the MarketplaceIdList.
     *
     * @return MarketplaceWebService_Model_IdList MarketplaceIdList
     */
    public function getMarketplaceIdList()
    {
        return $this->fields['MarketplaceIdList']['FieldValue'];
    }

    /**
     * Sets the value of the MarketplaceIdList.
     *
     * @param MarketplaceWebService_Model_IdList $value MarketplaceIdList
     * @return void
     */
    public function setMarketplaceIdList($value)
    {
        $marketplaceIdList = new MarketplaceWebService_Model_IdList();
        $marketplaceIdList->setId($value['Id']);
        $this->fields['MarketplaceIdList']['FieldValue'] = $marketplaceIdList;
        return;
    }

    /**
     * Sets the value of the MarketplaceIdList  and returns this instance
     *
     * @param MarketplaceWebService_Model_IdList $value MarketplaceIdList
     * @return MarketplaceWebService_Model_SubmitFeedRequest instance
     */
    public function withMarketplaceIdList($value)
    {
        $this->setMarketplaceIdList($value);
        return $this;
    }

    /**
     * Checks if MarketplaceIdList  is set
     *
     * @return bool true if MarketplaceIdList property is set
     */
    public function isSetMarketplaceIdList()
    {
        return !is_null($this->fields['MarketplaceIdList']['FieldValue']);

    }

    /**
     * Gets the value of the FeedContent property.
     *
     * @return string FeedContent
     */
    public function getFeedContent()
    {
        return $this->fields['FeedContent']['FieldValue'];
    }

    /**
     * Sets the value of the FeedContent property.
     *
     * @param string $value FeedContent
     * @return $this This instance
     */
    public function setFeedContent($value)
    {
        $this->fields['FeedContent']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Sets the value of the FeedContent and returns this instance
     *
     * @param string $value FeedContent
     * @return MarketplaceWebService_Model_SubmitFeedRequest instance
     */
    public function withFeedContent($value)
    {
        $this->setFeedContent($value);
        return $this;
    }

    /**
     * Checks if FeedContent is set
     *
     * @return bool true if FeedContent  is set
     */
    public function isSetFeedContent()
    {
        return !is_null($this->fields['FeedContent']['FieldValue']);
    }

    /**
     * Gets the value of the FeedType property.
     *
     * @return string FeedType
     */
    public function getFeedType()
    {
        return $this->fields['FeedType']['FieldValue'];
    }

    /**
     * Sets the value of the FeedType property.
     *
     * @param string $value FeedType
     * @return $this This instance
     */
    public function setFeedType($value)
    {
        $this->fields['FeedType']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Sets the value of the FeedType and returns this instance
     *
     * @param string $value FeedType
     * @return MarketplaceWebService_Model_SubmitFeedRequest instance
     */
    public function withFeedType($value)
    {
        $this->setFeedType($value);
        return $this;
    }

    /**
     * Checks if FeedType is set
     *
     * @return bool true if FeedType  is set
     */
    public function isSetFeedType()
    {
        return !is_null($this->fields['FeedType']['FieldValue']);
    }

    /**
     * Gets the value of the PurgeAndReplace property.
     *
     * @return bool PurgeAndReplace
     */
    public function getPurgeAndReplace()
    {
        return $this->fields['PurgeAndReplace']['FieldValue'];
    }

    /**
     * Sets the value of the PurgeAndReplace property.
     *
     * @param bool $value PurgeAndReplace
     * @return $this This instance
     */
    public function setPurgeAndReplace($value)
    {
        $this->fields['PurgeAndReplace']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Sets the value of the PurgeAndReplace and returns this instance
     *
     * @param bool $value PurgeAndReplace
     * @return MarketplaceWebService_Model_SubmitFeedRequest instance
     */
    public function withPurgeAndReplace($value)
    {
        $this->setPurgeAndReplace($value);
        return $this;
    }

    /**
     * Checks if PurgeAndReplace is set
     *
     * @return bool true if PurgeAndReplace  is set
     */
    public function isSetPurgeAndReplace()
    {
        return !is_null($this->fields['PurgeAndReplace']['FieldValue']);
    }

    /**
     * Gets the value of the ContentMd5 property.
     *
     * @return bool ContentMd5
     */
    public function getContentMd5()
    {
        return $this->fields['ContentMd5']['FieldValue'];
    }

    /**
     * Sets the value of the ContentMd5 property.
     *
     * @param bool $value ContentMd5
     * @return $this This instance
     */
    public function setContentMd5($value)
    {
        $this->fields['ContentMd5']['FieldValue'] = $value;
        return $this;
    }

    /**
     * Sets the value of the ContentMd5 and returns this instance
     *
     * @param bool $value ContentMd5
     * @return MarketplaceWebService_Model_SubmitFeedRequest instance
     */
    public function withContentMd5($value)
    {
        $this->setContentMd5($value);
        return $this;
    }

    /**
     * Checks if ContentMd5 is set
     *
     * @return bool true if ContentMd5  is set
     */
    public function isSetContentMd5()
    {
        return !is_null($this->fields['ContentMd5']['FieldValue']);
    }

}