<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Struct\Fop;

use Amadeus\Client\RequestOptions\Fop\MopInfo;
use Amadeus\Client\Struct\Fop\CreateFormOfPayment\MopDescription14;
use Amadeus\Client\Struct\Fop\CreateFormOfPayment\PaymentModule14;
use Amadeus\Client\Struct\WsMessageUtility;

/**
 * MopDescription
 *
 * @package Amadeus\Client\Struct\Fop
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class MopDescription extends WsMessageUtility
{
    /**
     * @var FopSequenceNumber
     */
    public $fopSequenceNumber;
    /**
     * @var FopMasterElementReference
     */
    public $fopMasterElementReference;
    /**
     * @var StakeholderPayerReference
     */
    public $stakeholderPayerReference;
    /**
     * @var MopDetails
     */
    public $mopDetails;
    /**
     * @var PaymentModule
     */
    public $paymentModule;

    /**
     * MopDescription constructor.
     *
     * @param MopInfo $options
     */
    public function __construct(MopInfo $options)
    {
        if (!is_null($options->sequenceNr)) {
            $this->fopSequenceNumber = new FopSequenceNumber($options->sequenceNr);
        }

        $this->loadMopDetails($options);

        $this->loadPaymentModule($options);
    }

    /**
     * load Method of Payment Details
     *
     * @param MopInfo $options
     */
    protected function loadMopDetails(MopInfo $options)
    {
        $this->mopDetails = new MopDetails();

        if ($this->checkAnyNotEmpty($options->fopCode, $options->fopStatus)) {
            $this->mopDetails->fopPNRDetails = new FopPNRDetails(
                $options->fopCode,
                $options->fopStatus
            );
        }

        if (!empty($options->freeFlowText)) {
            $this->mopDetails->oldFopFreeflow = new OldFopFreeflow(
                $options->freeFlowText,
                $options->freeFlowEncoding
            );
        }

        if (!empty($options->supplementaryData)) {
            $this->mopDetails->pnrSupplementaryData[] = new PnrSupplementaryData(
                DataAndSwitchMap::TYPE_DATA_INFORMATION,
                $options->supplementaryData
            );
        }
        if (!empty($options->supplementarySwitches)) {
            $this->mopDetails->pnrSupplementaryData[] = new PnrSupplementaryData(
                DataAndSwitchMap::TYPE_SWITCH_INFORMATION,
                $options->supplementarySwitches
            );
        }
    }

    /**
     * Payment Module information
     *
     * @param MopInfo $options
     */
    protected function loadPaymentModule(MopInfo $options)
    {
        if ($this->checkAnyNotEmpty(
            $options->fopType,
            $options->payMerchant,
            $options->payments,
            $options->installmentsInfo,
            $options->mopPaymentType,
            $options->creditCardInfo,
            $options->fraudScreening,
            $options->payIds,
            $options->paySupData
        )) {
            if ($this instanceof MopDescription14) {
                $this->paymentModule = new PaymentModule14($options->fopType);
            } else {
                $this->paymentModule = new PaymentModule($options->fopType);
            }
            $this->paymentModule->loadPaymentData($options);

            $this->loadMopInformation($options);

            $this->loadPaymentSupplementaryData($options);
        }
    }

    /**
     * Load Supplementary data
     *
     * @param MopInfo $options
     */
    protected function loadPaymentSupplementaryData(MopInfo $options)
    {
        foreach ($options->paySupData as $paySupData) {
            $this->paymentModule->paymentSupplementaryData[] = new PaymentSupplementaryData(
                $paySupData->function,
                $paySupData->data
            );
        }
    }

    /**
     * Load MopInformation
     *
     * @param MopInfo $options
     */
    protected function loadMopInformation(MopInfo $options)
    {
        if (!empty($options->mopPaymentType)) {
            $this->checkAndCreateMopInformation();
            $this->paymentModule->mopInformation->fopInformation = new FopInformation($options->mopPaymentType);
        }

        if (!empty($options->creditCardInfo)) {
            $this->checkAndCreateMopInformation();
            $this->paymentModule->mopInformation->creditCardData = new CreditCardData($options->creditCardInfo);
            if ($this->checkAnyNotEmpty(
                $options->creditCardInfo->approvalCode,
                $options->creditCardInfo->threeDSecure
            )
            ) {
                $this->checkAndCreateMopDetailedData($options->fopType);
                $this->paymentModule->mopDetailedData->creditCardDetailedData = new CreditCardDetailedData(
                    $options->creditCardInfo->approvalCode,
                    $options->creditCardInfo->sourceOfApproval,
                    $options->creditCardInfo->threeDSecure
                );
            }
        }

        if (!empty($options->invoiceInfo)) {
            $this->checkAndCreateMopInformation();
            $this->paymentModule->mopInformation->invoiceDataGroup = new InvoiceDataGroup($options->invoiceInfo);
        }
    }

    /**
     * Create MopInformation node if needed
     */
    private function checkAndCreateMopInformation()
    {
        if (is_null($this->paymentModule->mopInformation)) {
            $this->paymentModule->mopInformation = new MopInformation();
        }
    }

    /**
     * Create MopDetailedData node if needed
     *
     * @param string $fopType
     */
    private function checkAndCreateMopDetailedData($fopType)
    {
        if (is_null($this->paymentModule->mopDetailedData)) {
            $this->paymentModule->mopDetailedData = new MopDetailedData($fopType);
        }
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Struct\Pnr\TransferOwnership;

/**
 * OfficeIdentification
 *
 * @package Amadeus\Client\Struct\Pnr\TransferOwnership
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class OfficeIdentification
{
    /**
     * @var OfficeIdentificator
     */
    public $officeIdentificator;

    /**
     * @var SpecificChanges[]
     */
    public $specificChanges = [];

    /**
     * OfficeIdentification constructor.
     *
     * @param string|null $inHouseIdentification1
     * @param string|null $inHouseIdentification2
     */
    public function __construct($inHouseIdentification1 = null, $inHouseIdentification2 = null)
    {
        $this->officeIdentificator = new OfficeIdentificator(
            $inHouseIdentification1,
            $inHouseIdentification2
        );
    }

    /**
     * Load Specific Changes
     *
     * @param bool $changeTicketing Change Ticketing office?
     * @param bool $changeQueueing Change Queueing office?
     * @param bool $changeOptQueueEl Change the office specified in the option queue element?
     */
    public function loadSpecificChanges($changeTicketing, $changeQueueing, $changeOptQueueEl)
    {
        if ($changeTicketing) {
            $this->specificChanges[] = new SpecificChanges(
                SpecificChanges::ACTION_TICKETING_OFFICE
            );
        }
        if ($changeQueueing) {
            $this->specificChanges[] = new SpecificChanges(
                SpecificChanges::ACTION_QUEUEING_OFFICE
            );
        }
        if ($changeOptQueueEl) {
            $this->specificChanges[] = new SpecificChanges(
                SpecificChanges::ACTION_OPT_QUEUE_ELEMENT
            );
        }
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Struct\PointOfRef;

use Amadeus\Client\RequestOptions\PointOfRefSearchOptions;
use Amadeus\Client\Struct\BaseWsMessage;
use Amadeus\Client\Struct\PointOfRef\Search\Area;
use Amadeus\Client\Struct\PointOfRef\Search\BusinessId;
use Amadeus\Client\Struct\PointOfRef\Search\GeoCode;
use Amadeus\Client\Struct\PointOfRef\Search\Name;
use Amadeus\Client\Struct\PointOfRef\Search\PorFndQryParams;

/**
 * PointOfRef_Search request message structure
 *
 * @package Amadeus\Client\Struct\PointOfRef
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class Search extends BaseWsMessage
{
    /**
     * @var PorFndQryParams
     */
    public $porFndQryParams;

    /**
     * Search constructor.
     *
     * @param PointOfRefSearchOptions $params
     */
    public function __construct(PointOfRefSearchOptions $params)
    {
        $this->loadBasic($params);
        $this->loadGeoCode($params);
        $this->loadCountryStateIata($params);
        $this->loadBusinessId($params);
    }

    /**
     * @param PointOfRefSearchOptions $params
     */
    protected function loadBasic($params)
    {
        $this->porFndQryParams = new PorFndQryParams($params->targetCategoryCode);

        if ($params->listType !== null) {
            $this->porFndQryParams->resultListType = $params->listType;
        }

        if ($params->searchRadius !== null) {
            $this->porFndQryParams->radius = $params->searchRadius;
        }

        if ($params->name !== null) {
            $this->porFndQryParams->name = new Name($params->name);
        }

        if ($params->maxNrOfResults !== null) {
            $this->porFndQryParams->resultMaxItems = $params->maxNrOfResults;
        }
    }

    /**
     * Search by geocode?
     *
     * @param PointOfRefSearchOptions $params
     */
    protected function loadGeoCode(PointOfRefSearchOptions $params)
    {
        if ($this->checkAllNotEmpty($params->latitude, $params->longitude)) {
            $this->porFndQryParams->geoCode = new GeoCode(
                $params->longitude,
                $params->latitude
            );
        }
    }

    /**
     * Search by country/state/iata code?
     *
     * @param PointOfRefSearchOptions $params
     */
    protected function loadCountryStateIata(PointOfRefSearchOptions $params)
    {
        if ($this->checkAnyNotEmpty($params->country, $params->state, $params->iata)) {
            $this->porFndQryParams->area = new Area(
                $params->country,
                $params->state,
                $params->iata
            );
        }
    }

    /**
     * Search by Business ID?
     *
     * @param PointOfRefSearchOptions $params
     */
    protected function loadBusinessId(PointOfRefSearchOptions $params)
    {
        if ($this->checkAnyNotEmpty($params->businessCategory, $params->businessForeignKey)) {
            $this->porFndQryParams->businessId = new BusinessId(
                $params->businessCategory,
                $params->businessForeignKey
            );
        }
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Util;

/**
 * SomewhatRandomGenerator - for generating somewhat random strings.
 *
 * Utilized to generate a base random string used to generate a Nonce
 * for the Soap Header 4 message headers.
 *
 * @package Amadeus\Client\Util
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class SomewhatRandomGenerator
{
    /**
     * Generates a somewhat random string of a given length
     *
     * @param int $length
     * @return string
     */
    public static function generateSomewhatRandomString($length = 22)
    {
        $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        srand((double) microtime() * 1000000);
        $i = 0;
        $somewhatRandom = '';

        while ($i < $length) {
            $num = rand() % 60;
            $tmp = substr($chars, $num, 1);
            $somewhatRandom = $somewhatRandom.$tmp;
            $i++;
        }

        return $somewhatRandom;
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\ResponseHandler\PNR;

use Amadeus\Client\ResponseHandler\StandardResponseHandler;
use Amadeus\Client\Result;
use Amadeus\Client\Session\Handler\SendResult;

/**
 * HandlerDisplayHistory
 *
 * @package Amadeus\Client\ResponseHandler\PNR
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class HandlerDisplayHistory extends StandardResponseHandler
{
    /**
     * Analysing a PNR_DisplayHistoryReply
     *
     * @param SendResult $response
     * @return Result
     */
    public function analyze(SendResult $response)
    {
        $analyzeResponse = new Result($response);

        $domXpath = $this->makeDomXpath($response->responseXml);

        $queryAllErrorCodes = "//m:generalErrorGroup//m:errorNumber/m:errorDetails/m:errorCode";
        $queryAllErrorMsg = "//m:generalErrorGroup/m:genrealErrorText/m:freeText";

        $errorCodeNodeList = $domXpath->query($queryAllErrorCodes);

        if ($errorCodeNodeList->length > 0) {
            $analyzeResponse->status = Result::STATUS_ERROR;

            $code = $errorCodeNodeList->item(0)->nodeValue;
            $errorTextNodeList = $domXpath->query($queryAllErrorMsg);
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);

            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message));
        }

        return $analyzeResponse;
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Struct;

/**
 * WsMessageUtility - provides utility functions when constructing web service messages
 *
 * @package Amadeus\Client\Struct
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class WsMessageUtility
{
    /**
     * Check if any parameter to the current function is not empty
     *
     * @param mixed
     * @return boolean true if at least 1 parameter is not empty
     */
    protected function checkAnyNotEmpty()
    {
        $foundNotEmpty = false;

        $args = func_get_args();

        foreach ($args as $arg) {
            if (!empty($arg)) {
                $foundNotEmpty = true;
                break;
            }
        }

        return $foundNotEmpty;
    }

    /**
     * Check if all parameters to the current function are not empty
     *
     * @param mixed
     * @return boolean true if all parameters are not empty
     */
    protected function checkAllNotEmpty()
    {
        $foundEmpty = false;

        $args = func_get_args();

        foreach ($args as $arg) {
            if (empty($arg)) {
                $foundEmpty = true;
                break;
            }
        }

        return !$foundEmpty;
    }

    /**
     * Check if all parameters to the current function are integers
     *
     * @param mixed
     * @return boolean true if all parameters are integers
     */
    protected function checkAllIntegers()
    {
        $foundNonInt = false;

        $args = func_get_args();

        foreach ($args as $arg) {
            if (!is_int($arg)) {
                $foundNonInt = true;
                break;
            }
        }

        return !$foundNonInt;
    }

    /**
     * Check if any parameter to the current function is true
     *
     * @param mixed
     * @return boolean true if at least 1 parameter is true
     */
    protected function checkAnyTrue()
    {
        $foundTrue = false;

        $args = func_get_args();

        foreach ($args as $arg) {
            if ($arg === true) {
                $foundTrue = true;
                break;
            }
        }

        return $foundTrue;
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Session\Handler;

use Amadeus\Client;
use Amadeus\Client\Params\SessionHandlerParams;
use Amadeus\Client\Util\SomewhatRandomGenerator;

/**
 * HandlerFactory generates the correct Session Handler based on the incoming params.
 *
 * @package Amadeus\Client\Session\Handler
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class HandlerFactory
{
    /**
     * @param SessionHandlerParams|null $handlerParams
     * @return HandlerInterface
     * @throws \InvalidArgumentException when the parameters to create the handler do not make sense.
     */
    public static function createHandler($handlerParams)
    {
        if (!($handlerParams instanceof SessionHandlerParams) ||
            !($handlerParams->authParams instanceof Client\Params\AuthParams)) {
            throw new \InvalidArgumentException('Invalid parameters');
        }

        $handlerParams = self::loadNonceBase($handlerParams);

        switch ($handlerParams->soapHeaderVersion) {
            case Client::HEADER_V4:
                $theHandler = new SoapHeader4($handlerParams);
                break;
            case Client::HEADER_V2:
                $theHandler = new SoapHeader2($handlerParams);
                break;
            case Client::HEADER_V1:
            default:
                //TODO implement Client::HEADER_V1
                throw new \InvalidArgumentException(
                    'No Session Handler found for soapHeaderVersion '.$handlerParams->soapHeaderVersion
                );
        }

        return $theHandler;
    }

    /**
     * Get the NONCE base to be used when generating somewhat random nonce strings
     *
     * From the NONCE base file, or fallback is a new somewhat random string each instantiation.
     *
     * @param SessionHandlerParams $handlerParams
     * @return SessionHandlerParams
     */
    protected static function loadNonceBase($handlerParams)
    {
        if (empty($handlerParams->authParams->nonceBase)) {
            $handlerParams->authParams->nonceBase = SomewhatRandomGenerator::generateSomewhatRandomString();
        }

        return $handlerParams;
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Struct\PriceXplorer;

use Amadeus\Client\RequestOptions\PriceXplorerExtremeSearchOptions;
use Amadeus\Client\Struct\BaseWsMessage;

/**
 * ExtremeSearch
 *
 * @package Amadeus\Client\Struct\PriceXplorer
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class ExtremeSearch extends BaseWsMessage
{
    /**
     * Itinerary information group
     *
     * @var ItineraryGrp[]
     */
    public $itineraryGrp = [];

    /**
     * Budget info
     *
     * @var Budget
     */
    public $budget;

    /**
     * Departure dates ranges
     *
     * @var TravelDates
     */
    public $travelDates;

    /**
     * Stay duration and flexibility
     *
     * @var StayDuration
     */
    public $stayDuration;

    /**
     * Attribute Information
     *
     * @var AttributeInfo[]
     */
    public $attributeInfo = [];

    /**
     * Option description : Price result distribution, ...
     *
     * @var SelectionDetailsGroup[]
     */
    public $selectionDetailsGroup = [];

    /**
     * List of departure days
     *
     * @var DepartureDays[]
     */
    public $departureDays = [];

    /**
     * Airline information
     *
     * @var AirlineInfo[]
     */
    public $airlineInfo = [];

    /**
     * List of Office Id Details
     *
     * @var OfficeIdInfo[]
     */
    public $officeIdInfo = [];

    /**
     * Construct PriceXplorer_ExtremeSearch Request message
     *
     * @param PriceXplorerExtremeSearchOptions $params
     */
    public function __construct(PriceXplorerExtremeSearchOptions $params)
    {
        $this->itineraryGrp[] = new ItineraryGrp($params->origin);

        $this->loadDepartureDateLimits($params);

        if ($params->searchOffice !== null) {
            $this->officeIdInfo[] = new OfficeIdInfo($params->searchOffice);
        }

        $this->loadBudget($params->maxBudget, $params->minBudget, $params->currency);

        $this->loadDestinations($params);

        $this->loadDepartureDaysOutIn($params);

        $this->loadStayDuration($params->stayDurationDays, $params->stayDurationFlexibilityDays);

        $this->loadCheapestQualifiers($params->returnCheapestNonStop, $params->returnCheapestOverall);

        $this->loadResultAggregation($params->resultAggregationOption);
    }

    /**
     * @param int|null $maxBudget
     * @param int|null $minBudget
     * @param string|null $currency
     */
    protected function loadBudget($maxBudget, $minBudget, $currency)
    {
        if (($maxBudget !== null || $minBudget !== null) && $currency !== null) {
            $this->budget = new Budget(
                $maxBudget,
                $minBudget,
                $currency
            );
        }
    }

    /**
     * @param int|null $stayDuration
     * @param int|null $flexibility
     */
    protected function loadStayDuration($stayDuration, $flexibility)
    {
        if ($stayDuration !== null) {
            $this->stayDuration = new StayDuration($stayDuration);

            if ($flexibility !== null) {
                $this->stayDuration->flexibilityInfo = new FlexibilityInfo($flexibility);
            }
        }
    }

    /**
     * @param bool $cheapestNonStop
     * @param bool $cheapestOverall
     */
    protected function loadCheapestQualifiers($cheapestNonStop, $cheapestOverall)
    {
        if ($cheapestNonStop || $cheapestOverall) {
            $this->selectionDetailsGroup[] = new SelectionDetailsGroup($cheapestNonStop, $cheapestOverall);
        }
    }

    /**
     * @param string $resultAggregationOption
     */
    protected function loadResultAggregation($resultAggregationOption)
    {
        if ($resultAggregationOption !== null) {
            $groupTypes = $this->makeAggregationGroupTypes($resultAggregationOption);

            $this->attributeInfo[] = new AttributeInfo(
                AttributeInfo::FUNC_GROUPING,
                $groupTypes
            );
        }
    }

    /**
     * @param string $groupTypeString
     * @return array
     */
    protected function makeAggregationGroupTypes($groupTypeString)
    {
        $result = [];

        switch ($groupTypeString) {
            case PriceXplorerExtremeSearchOptions::AGGR_DEST:
                $result[] = AttributeDetails::TYPE_DESTINATION;
                break;
            case PriceXplorerExtremeSearchOptions::AGGR_COUNTRY:
                $result[] = AttributeDetails::TYPE_COUNTRY;
                break;
            case PriceXplorerExtremeSearchOptions::AGGR_DEST_WEEK:
                $result[] = AttributeDetails::TYPE_DESTINATION;
                $result[] = AttributeDetails::TYPE_WEEK;
                break;
            case PriceXplorerExtremeSearchOptions::AGGR_DEST_WEEK_DEPART:
                $result[] = AttributeDetails::TYPE_DESTINATION;
                $result[] = AttributeDetails::TYPE_WEEK;
                $result[] = AttributeDetails::TYPE_DEPARTURE_DAY;
                break;
            case PriceXplorerExtremeSearchOptions::AGGR_DEST_WEEK_DEPART_STAY:
                $result[] = AttributeDetails::TYPE_DESTINATION;
                $result[] = AttributeDetails::TYPE_WEEK;
                $result[] = AttributeDetails::TYPE_DEPARTURE_DAY;
                $result[] = AttributeDetails::TYPE_STAY_DURATION;
                break;
        }

        return $result;
    }

    /**
     * @param PriceXplorerExtremeSearchOptions $params
     *
     */
    protected function loadDepartureDateLimits(PriceXplorerExtremeSearchOptions $params)
    {
        if ($params->earliestDepartureDate instanceof \DateTime || $params->latestDepartureDate instanceof \DateTime) {
            $this->travelDates = new TravelDates($params->earliestDepartureDate, $params->latestDepartureDate);
        }
    }

    /**
     * @param PriceXplorerExtremeSearchOptions $params
     *
     */
    protected function loadDestinations(PriceXplorerExtremeSearchOptions $params)
    {
        foreach ($params->destinations as $destination) {
            $this->itineraryGrp[] = new ItineraryGrp(null, $destination);
        }

        foreach ($params->destinationCountries as $destinationCountry) {
            $tmpGrp = new ItineraryGrp();

            $tmpGrp->locationInfo = new LocationInfo(LocationInfo::LOC_COUNTRY);

            $tmpGrp->locationInfo->locationDescription = new LocationIdentificationType();
            $tmpGrp->locationInfo->locationDescription->qualifier = LocationIdentificationType::QUAL_DESTINATION;
            $tmpGrp->locationInfo->locationDescription->code = $destinationCountry;

            $this->itineraryGrp[] = $tmpGrp;
        }
    }

    /**
     * @param PriceXplorerExtremeSearchOptions $params
     *
     */
    protected function loadDepartureDaysOutIn(PriceXplorerExtremeSearchOptions $params)
    {
        if (!empty($params->departureDaysInbound)) {
            $this->departureDays[] = new DepartureDays(
                $params->departureDaysInbound,
                SelectionDetails::OPT_INBOUND_DEP_DAYS
            );
        }
        if (!empty($params->departureDaysOutbound)) {
            $this->departureDays[] = new DepartureDays(
                $params->departureDaysOutbound,
                SelectionDetails::OPT_OUTBOUND_DEP_DAYS
            );
        }
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Struct\Pnr\AddMultiElements;

/**
 * Fop
 *
 * @package Amadeus\Client\Struct\Pnr\AddMultiElements
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class Fop
{
    const IDENT_CASH = "CA";
    const IDENT_CHECK = "CK";
    const IDENT_CREDITCARD = "CC";
    const IDENT_MISC = "MS";

    /**
     * @var string
     */
    public $identification;
    /**
     * @var mixed
     */
    public $amount;
    /**
     * @var mixed
     */
    public $creditCardCode;
    /**
     * @var mixed
     */
    public $accountNumber;
    /**
     * @var mixed
     */
    public $expiryDate;
    /**
     * @var mixed
     */
    public $approvalCode;
    /**
     * @var mixed
     */
    public $customerAccountNumber;
    /**
     * @var mixed
     */
    public $paymentTimeReference;
    /**
     * @var mixed
     */
    public $freetext;
    /**
     * @var mixed
     */
    public $currencyCode;

    /**
     * @param string|null $identification One of the constants IDENT_* defined in this class.
     */
    public function __construct($identification = null)
    {
        if (!is_null($identification) && strlen($identification) == 2 && self::isValidFopType($identification)) {
            $this->identification = $identification;
        }
    }

    /**
     * Check if the given Form Of Payment type is valid
     *
     * @param string $fopType
     * @return boolean
     */
    public static function isValidFopType($fopType)
    {
        return ($fopType == self::IDENT_CASH
            || $fopType == self::IDENT_CHECK
            || $fopType == self::IDENT_CREDITCARD
            || $fopType == self::IDENT_MISC);
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client;

use Amadeus\Client\Params\AuthParams;
use Amadeus\Client\Params\RequestCreatorParams;
use Amadeus\Client\Params\SessionHandlerParams;
use Amadeus\Client\RequestCreator\RequestCreatorInterface;
use Amadeus\Client\ResponseHandler\ResponseHandlerInterface;
use Amadeus\Client\Session;

/**
 * Params
 *
 * @package Amadeus\Client
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class Params
{
    /**
     * For injecting a custom Request Creator
     *
     * @var RequestCreatorInterface
     */
    public $requestCreator;

    /**
     * For injecting a custom session handler
     *
     * @var Session\Handler\HandlerInterface
     */
    public $sessionHandler;

    /**
     * For injecting a custom response handler
     *
     * @var ResponseHandlerInterface
     */
    public $responseHandler;

    /**
     * Parameters for authenticating to the Amadeus Web Services
     *
     * @var Params\AuthParams
     */
    public $authParams;

    /**
     * Parameters required to create the Session Handler
     *
     * @var Params\SessionHandlerParams
     */
    public $sessionHandlerParams;

    /**
     * Parameters required to create the Request Creator
     *
     * @var Params\RequestCreatorParams
     */
    public $requestCreatorParams;

    /**
     * Whether to request the response XML string in the response by default or not.
     *
     * If true, the Amadeus\Client\Result object will
     * contain the response XML message in the 'responseXml' property by default.
     *
     * This can be overridden for specific messages by adding a 'returnXml' key with a boolean in
     * the second parameter of a message call.
     *
     * @var bool
     */
    public $returnXml = true;

    /**
     * @param array $params
     */
    public function __construct($params = [])
    {
        $this->loadFromArray($params);
    }

    /**
     * Load parameters from an associative array
     *
     * @param array $params
     * @return void
     */
    protected function loadFromArray(array $params)
    {
        if (isset($params['returnXml']) && is_bool($params['returnXml'])) {
            $this->returnXml = $params['returnXml'];
        }

        $this->loadRequestCreator($params);
        $this->loadSessionHandler($params);
        $this->loadResponseHandler($params);

        $this->loadAuthParams($params);

        $this->loadSessionHandlerParams($params);
        $this->loadRequestCreatorParams($params);
    }

    /**
     * Load Request Creator
     *
     * @param array $params
     * @return void
     */
    protected function loadRequestCreator($params)
    {
        if (isset($params['requestCreator']) && $params['requestCreator'] instanceof RequestCreatorInterface) {
            $this->requestCreator = $params['requestCreator'];
        }
    }

    /**
     * Load Session Handler
     *
     * @param array $params
     * @return void
     */
    protected function loadSessionHandler($params)
    {
        if (isset($params['sessionHandler']) && $params['sessionHandler'] instanceof Session\Handler\HandlerInterface) {
            $this->sessionHandler = $params['sessionHandler'];
        }
    }

    /**
     * Load Response Handler
     *
     * @param array $params
     * @return void
     */
    protected function loadResponseHandler($params)
    {
        if (isset($params['responseHandler']) && $params['responseHandler'] instanceof ResponseHandlerInterface) {
            $this->responseHandler = $params['responseHandler'];
        }
    }

    /**
     * Load Authentication Parameters
     *
     * @param array $params
     * @return void
     */
    protected function loadAuthParams($params)
    {
        if (isset($params['authParams'])) {
            if ($params['authParams'] instanceof AuthParams) {
                $this->authParams = $params['authParams'];
            } elseif (is_array($params['authParams'])) {
                $this->authParams = new AuthParams($params['authParams']);
            }
        }
    }

    /**
     * Load Session Handler Parameters
     *
     * @param array $params
     * @return void
     */
    protected function loadSessionHandlerParams($params)
    {
        if (isset($params['sessionHandlerParams'])) {
            if ($params['sessionHandlerParams'] instanceof SessionHandlerParams) {
                $this->sessionHandlerParams = $params['sessionHandlerParams'];
            } elseif (is_array($params['sessionHandlerParams'])) {
                $this->sessionHandlerParams = new SessionHandlerParams($params['sessionHandlerParams']);
            }
        }
    }

    /**
     * Load Request Creator Parameters
     *
     * @param array $params
     * @return void
     */
    protected function loadRequestCreatorParams($params)
    {
        if (isset($params['requestCreatorParams'])) {
            if ($params['requestCreatorParams'] instanceof RequestCreatorParams) {
                $this->requestCreatorParams = $params['requestCreatorParams'];
            } elseif (is_array($params['requestCreatorParams'])) {
                $this->requestCreatorParams = new RequestCreatorParams($params['requestCreatorParams']);
            }
        }
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Struct\Ticket;

use Amadeus\Client\RequestOptions\Fare\PricePnr\AwardPricing;
use Amadeus\Client\RequestOptions\Fare\PricePnr\ExemptTax;
use Amadeus\Client\RequestOptions\Fare\PricePnr\FareBasis;
use Amadeus\Client\RequestOptions\Fare\PricePnr\Tax;
use Amadeus\Client\RequestOptions\Ticket\ExchangeInfoOptions;
use Amadeus\Client\RequestOptions\Ticket\MultiRefOpt;
use Amadeus\Client\RequestOptions\Ticket\PaxSegRef;
use Amadeus\Client\RequestOptions\TicketRepricePnrWithBookingClassOptions;
use Amadeus\Client\Struct\BaseWsMessage;
use Amadeus\Client\Struct\Fare\PricePnr13\CarrierInformation;
use Amadeus\Client\Struct\Fare\PricePnr13\Currency;
use Amadeus\Client\Struct\Fare\PricePnr13\FrequentFlyerInformation;
use Amadeus\Client\Struct\Fare\PricePnr13\FrequentTravellerDetails;
use Amadeus\Client\Struct\Fare\PricePnr13\LocationInformation;
use Amadeus\Client\Struct\Fare\PricePnr13\OptionDetail;
use Amadeus\Client\Struct\Fare\PricePnr13\PaxSegTstReference;
use Amadeus\Client\Struct\Fare\PricePnr13\PenDisInformation;
use Amadeus\Client\Struct\Fare\PricePnr13\TaxData;
use Amadeus\Client\Struct\Fare\PricePnr13\TaxInformation;
use Amadeus\Client\Struct\Ticket\RepricePnrWithBookingClass\ExchangeInformationGroup;
use Amadeus\Client\Struct\Ticket\RepricePnrWithBookingClass\PricingOption;
use Amadeus\Client\Struct\Ticket\RepricePnrWithBookingClass\PricingOptionKey;

/**
 * Ticket_RepricePNRWithBookingClass request structure
 *
 * @package Amadeus\Client\Struct\Ticket
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class RepricePnrWithBookingClass extends BaseWsMessage
{
    /**
     * @var ExchangeInformationGroup[]
     */
    public $exchangeInformationGroup = [];

    /**
     * @var PricingOption[]
     */
    public $pricingOption = [];

    /**
     * RepricePnrWithBookingClass constructor.
     *
     * @param TicketRepricePnrWithBookingClassOptions $options
     */
    public function __construct($options)
    {
        if (!is_null($options)) {
            $this->loadExchangeInfo($options->exchangeInfo);

            $this->pricingOption = $this->loadPricingOptionsFromRequestOptions($options);
        }
    }

    /**
     * @param ExchangeInfoOptions[] $exchangeInfo
     */
    protected function loadExchangeInfo($exchangeInfo)
    {
        foreach ($exchangeInfo as $info) {
            if ($info instanceof ExchangeInfoOptions) {
                $this->exchangeInformationGroup[] = new ExchangeInformationGroup($info);
            }
        }
    }

    /**
     * @param TicketRepricePnrWithBookingClassOptions $options
     * @return PricingOption[]
     */
    protected function loadPricingOptionsFromRequestOptions(TicketRepricePnrWithBookingClassOptions $options)
    {
        $priceOptions = [];

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->makePricingOptionForCarrier(
                $options->validatingCarrier,
                PricingOptionKey::OPTION_VALIDATING_CARRIER
            )
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->makePricingOptionForCarrier(
                $options->controllingCarrier,
                PricingOptionKey::OPTION_OVERRIDE_CONTROLLING_CARRIER
            )
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->loadCorpUniFares($options->corporateUniFares, $options->awardPricing)
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->makePricingOptionFareBasisOverride($options->pricingsFareBasis)
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->loadTaxes($options->taxes)
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->loadExemptTaxes($options->exemptTaxes)
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->makePricingOptionForCurrencyOverride($options->currencyOverride)
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->makePricingOptionForSelection($options->multiReferences)
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->makeBreakpointOptions(
                $options->forceBreakPointRefs,
                $options->noBreakPointRefs
            )
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->loadPaxDiscount($options->paxDiscountCodes, $options->paxDiscountCodeRefs)
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->loadPointOverrides(
                $options->pointOfSaleOverride,
                $options->pointOfTicketingOverride
            )
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->loadWaiverCode($options->waiverCode)
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->loadOverrideReusableAmount($options->overrideReusableAmountRefs)
        );

        $priceOptions = $this->mergeOptions(
            $priceOptions,
            $this->makeOverrideOptions($options->overrideOptions, $priceOptions)
        );

        // All options processed, no options found:
        if (empty($priceOptions)) {
            $priceOptions[] = new PricingOption(PricingOptionKey::OPTION_NO_OPTION);
        }

        return $priceOptions;
    }

    /**
     * Merges Pricing options
     *
     * @param PricingOption[] $existingOptions
     * @param PricingOption[] $newOptions
     * @return PricingOption[] merged array
     */
    protected function mergeOptions($existingOptions, $newOptions)
    {
        if (!empty($newOptions)) {
            $existingOptions = array_merge(
                $existingOptions,
                $newOptions
            );
        }

        return $existingOptions;
    }

    /**
     * @param string|null $carrier
     * @param string $pricingOptionKey PricingOptionKey::OPTION_*
     * @return PricingOption[]
     */
    protected function makePricingOptionForCarrier($carrier, $pricingOptionKey)
    {
        $opt = [];

        if ($carrier !== null) {
            $po = new PricingOption($pricingOptionKey);

            $po->carrierInformation = new CarrierInformation($carrier);

            $opt[] = $po;
        }

        return $opt;
    }

    /**
     * @param MultiRefOpt[] $multiReferences
     * @return PricingOption[]
     */
    protected function makePricingOptionForSelection($multiReferences)
    {
        $opt = [];

        foreach ($multiReferences as $multiReference) {
            $opt[] = $this->makePricingOptionWithPaxSegTstRefs(
                $multiReference->references,
                PricingOptionKey::OPTION_PAX_SEG_LINE_TST_SELECTION
            );
        }

        return $opt;
    }

    /**
     * @param PaxSegRef[] $forceBreakPointRefs
     * @param PaxSegRef[] $noBreakPointRefs
     * @return PricingOption[]
     */
    protected function makeBreakpointOptions($forceBreakPointRefs, $noBreakPointRefs)
    {
        $opt = [];

        if (!empty($forceBreakPointRefs)) {
            $opt[] = $this->makePricingOptionWithPaxSegTstRefs(
                $forceBreakPointRefs,
                PricingOptionKey::OPTION_FORCE_FEE_BREAK_POINT
            );
        }

        if (!empty($noBreakPointRefs)) {
            $opt[] = $this->makePricingOptionWithPaxSegTstRefs(
                $noBreakPointRefs,
                PricingOptionKey::OPTION_NO_BREAKPOINT
            );
        }

        return $opt;
    }

    /**
     * @param PaxSegRef[] $refs
     * @param string $pricingOptionKey PricingOptionKey::OPTION_*
     * @return PricingOption
     */
    protected function makePricingOptionWithPaxSegTstRefs($refs, $pricingOptionKey)
    {
        $po = new PricingOption($pricingOptionKey);

        $po->paxSegTstReference = new PaxSegTstReference($refs);

        return $po;
    }

    /**
     * Load corporate unifares
     *
     * @param string[] $corporateUniFares
     * @param AwardPricing|null $awardPricing
     * @return PricingOption[]
     */
    protected function loadCorpUniFares($corporateUniFares, $awardPricing)
    {
        $opt = [];

        if (!empty($corporateUniFares)) {
            $po = new PricingOption(PricingOptionKey::OPTION_CORPORATE_UNIFARES);
            $po->optionDetail = new OptionDetail($corporateUniFares);
            $opt[] = $po;

            if (!empty($awardPricing)) {
                $opt[] = $this->loadAwardPricing($awardPricing);
            }
        }

        return $opt;
    }

    /**
     * @param AwardPricing $awardPricing
     * @return PricingOption
     */
    protected function loadAwardPricing($awardPricing)
    {
        $po = new PricingOption(PricingOptionKey::OPTION_AWARD);

        $po->carrierInformation = new CarrierInformation($awardPricing->carrier);

        $po->frequentFlyerInformation = new FrequentFlyerInformation();
        $po->frequentFlyerInformation->frequentTravellerDetails[] = new FrequentTravellerDetails(
            $awardPricing->tierLevel
        );

        return $po;
    }

    /**
     * @param FareBasis[] $pricingsFareBasis
     * @return PricingOption[]
     */
    protected function makePricingOptionFareBasisOverride($pricingsFareBasis)
    {
        $opt = [];

        if ($pricingsFareBasis !== null) {
            foreach ($pricingsFareBasis as $pricingFareBasis) {
                $po = new PricingOption(PricingOptionKey::OPTION_FARE_BASIS_SIMPLE_OVERRIDE);

                //Support for legacy fareBasisPrimaryCode to be removed when breaking BC:
                $po->optionDetail = new OptionDetail(
                    $pricingFareBasis->fareBasisPrimaryCode.$pricingFareBasis->fareBasisCode
                );

                //Support for legacy segmentReference to be removed when breaking BC:
                $po->paxSegTstReference = new PaxSegTstReference(
                    $pricingFareBasis->references,
                    $pricingFareBasis->segmentReference
                );

                $opt[] = $po;
            }
        }

        return $opt;
    }

    /**
     * @param Tax[] $taxes
     * @return PricingOption[]
     */
    protected function loadTaxes($taxes)
    {
        $opt = [];

        if (!empty($taxes)) {
            $po = new PricingOption(PricingOptionKey::OPTION_ADD_TAX);

            foreach ($taxes as $tax) {
                $qualifier = (!empty($tax->amount)) ? TaxData::QUALIFIER_AMOUNT : TaxData::QUALIFIER_PERCENTAGE;
                $rate = (!empty($tax->amount)) ? $tax->amount : $tax->percentage;

                $po->taxInformation[] = new TaxInformation(
                    $tax->countryCode,
                    $tax->taxNature,
                    $qualifier,
                    $rate
                );
            }
            $opt[] = $po;
        }

        return $opt;
    }

    /**
     * @param ExemptTax[] $exemptTaxes
     * @return PricingOption[]
     */
    protected function loadExemptTaxes($exemptTaxes)
    {
        $opt = [];

        if (!empty($exemptTaxes)) {
            $po = new PricingOption(PricingOptionKey::OPTION_EXEMPT_TAXES);

            foreach ($exemptTaxes as $tax) {
                $po->taxInformation[] = new TaxInformation(
                    $tax->countryCode,
                    $tax->taxNature
                );
            }

            $opt[] = $po;
        }

        return $opt;
    }

    /**
     * @param string|null $currency
     * @return PricingOption[]
     */
    protected function makePricingOptionForCurrencyOverride($currency)
    {
        $opt = [];

        if ($currency !== null) {
            $po = new PricingOption(PricingOptionKey::OPTION_FARE_CURRENCY_OVERRIDE);

            $po->currency = new Currency($currency);

            $opt[] = $po;
        }

        return $opt;
    }

    /**
     * @param string[] $paxDiscount
     * @param PaxSegRef[] $paxDiscountCodeRefs
     * @return PricingOption[]
     */
    protected function loadPaxDiscount($paxDiscount, $paxDiscountCodeRefs)
    {
        $opt = [];

        if (!empty($paxDiscount)) {
            $po = new PricingOption(PricingOptionKey::OPTION_PASSENGER_DISCOUNT_PTC);

            $po->penDisInformation = new PenDisInformation(
                PenDisInformation::QUAL_DISCOUNT,
                $paxDiscount
            );

            if (!empty($paxDiscountCodeRefs)) {
                $po->paxSegTstReference = new PaxSegTstReference($paxDiscountCodeRefs);
            }

            $opt[] = $po;
        }

        return $opt;
    }

    /**
     * @param string|null $posOverride
     * @param string|null $potOverride
     * @return PricingOption[]
     */
    protected function loadPointOverrides($posOverride, $potOverride)
    {
        $opt = [];

        if (!empty($posOverride)) {
            $po = new PricingOption(PricingOptionKey::OPTION_POINT_OF_SALE_OVERRIDE);

            $po->locationInformation = new LocationInformation(
                LocationInformation::TYPE_POINT_OF_SALE,
                $posOverride
            );

            $opt[] = $po;
        }

        if (!empty($potOverride)) {
            $po2 = new PricingOption(PricingOptionKey::OPTION_POINT_OF_TICKETING_OVERRIDE);

            $po2->locationInformation = new LocationInformation(
                LocationInformation::TYPE_POINT_OF_TICKETING,
                $potOverride
            );

            $opt[] = $po2;
        }

        return $opt;
    }

    /**
     * @param string|null $waiverCode
     * @return PricingOption[]
     */
    protected function loadWaiverCode($waiverCode)
    {
        $opt = [];

        if (!empty($waiverCode)) {
            $po = new PricingOption(PricingOptionKey::OPTION_WAIVER_OPTION);

            $po->optionDetail = new OptionDetail($waiverCode);

            $opt[] = $po;
        }

        return $opt;
    }

    /**
     * @param PaxSegRef[] $overrideReusableAmountRefs
     * @return PricingOption[]
     */
    protected function loadOverrideReusableAmount($overrideReusableAmountRefs)
    {
        $opt = [];

        if (!empty($overrideReusableAmountRefs)) {
            $opt[] = $this->makePricingOptionWithPaxSegTstRefs(
                $overrideReusableAmountRefs,
                PricingOptionKey::OPTION_OVERRIDE_REUSABLE_AMOUNT
            );
        }

        return $opt;
    }

    /**
     * @param string[] $overrideOptions
     * @param PricingOption[] $priceOptions
     * @return PricingOption[]
     */
    protected function makeOverrideOptions($overrideOptions, $priceOptions)
    {
        $opt = [];

        foreach ($overrideOptions as $overrideOption) {
            if (!$this->hasPricingOption($overrideOption, $priceOptions)) {
                $opt[] = new PricingOption($overrideOption);
            }
        }

        return $opt;
    }

    /**
     * Avoid double pricing groups when combining an explicitly provided override option with a specific parameter
     * that uses the same override option.
     *
     * @param string $optionKey
     * @param PricingOption[] $priceOptions
     * @return bool
     */
    protected function hasPricingOption($optionKey, $priceOptions)
    {
        $found = false;

        foreach ($priceOptions as $pog) {
            if ($pog->pricingOptionKey->pricingOptionKey === $optionKey) {
                $found = true;
            }
        }

        return $found;
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Struct\Pnr\AddMultiElements;

use Amadeus\Client\RequestOptions\Pnr\Segment;
use Amadeus\Client\RequestOptions\Pnr\Segment\Miscellaneous;
use Amadeus\Client\RequestOptions\Pnr\Segment\Air;
use Amadeus\Client\RequestOptions\Pnr\Segment\ArrivalUnknown;
use Amadeus\Client\Struct\InvalidArgumentException;

/**
 * AirAuxItinerary
 *
 * @package Amadeus\Client\Struct\Pnr\AddMultiElements
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class AirAuxItinerary
{
    /**
     * @var TravelProduct
     */
    public $travelProduct;

    /**
     * @var MessageAction
     */
    public $messageAction;

    /**
     * @var RelatedProduct
     */
    public $relatedProduct;

    /**
     * @var SelectionDetailsAir
     */
    public $selectionDetailsAir;

    /**
     * @var ReservationInfoSell
     */
    public $reservationInfoSell;

    /**
     * @var FreetextItinerary
     */
    public $freetextItinerary;

    /**
     * AirAuxItinerary constructor.
     *
     * @param string $segmentType The type of segment to be constructed
     * @param Segment|Miscellaneous|Air|ArrivalUnknown $segmentContent The segment's content.
     */
    public function __construct($segmentType, $segmentContent)
    {
        switch ($segmentType) {
            case 'Miscellaneous':
                $this->loadMiscellaneous($segmentContent);
                break;
            case 'ArrivalUnknown':
                $this->loadArnk($segmentContent);
                break;
            case 'Air':
                $this->loadAir($segmentContent);
                break;
            default:
                throw new InvalidArgumentException('Segment type '.$segmentType.' is not supported');
                break;
        }
    }

    /**
     * @param Segment\Miscellaneous $segment
     */
    protected function loadMiscellaneous(Segment\Miscellaneous $segment)
    {
        $this->travelProduct = new TravelProduct(
            $segment->date,
            $segment->cityCode,
            $segment->company
        );
        $this->messageAction = new MessageAction(Business::FUNC_MISC);

        $this->relatedProduct = new RelatedProduct($segment->status, $segment->quantity);

        $this->freetextItinerary = new FreetextItinerary($segment->freeText);
    }

    /**
     * Load Arrival Unknown element
     *
     * @param Segment\ArrivalUnknown $segment
     */
    protected function loadArnk(Segment\ArrivalUnknown $segment)
    {
        $this->travelProduct = new TravelProduct();
        $this->travelProduct->productDetails = new ProductDetails($segment->identification);
        $this->messageAction = new MessageAction(Business::FUNC_ARNK);
    }

    /**
     * @param Segment\Air $segment
     */
    protected function loadAir(Segment\Air $segment)
    {
        $this->travelProduct = new TravelProduct(
            $segment->date,
            $segment->origin,
            $segment->company
        );

        $this->travelProduct->offpointDetail = new BoardOffPointDetail($segment->destination);
        $this->travelProduct->productDetails = new ProductDetails($segment->flightNumber);
        $this->travelProduct->productDetails->classOfService = $segment->bookingClass;

        $this->messageAction = new MessageAction(Business::FUNC_AIR);

        $this->relatedProduct = new RelatedProduct($segment->status, $segment->quantity);

        $this->selectionDetailsAir = new SelectionDetailsAir($segment->sellType);
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\ResponseHandler\PNR;

use Amadeus\Client\ResponseHandler\StandardResponseHandler;
use Amadeus\Client\Result;
use Amadeus\Client\Session\Handler\SendResult;

/**
 * HandlerRetrieve
 *
 * @package Amadeus\Client\ResponseHandler\PNR
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class HandlerRetrieve extends StandardResponseHandler
{
    const Q_G_ERR = "//m:generalErrorInfo//m:errorOrWarningCodeDetails/m:errorDetails/m:errorCode";
    const Q_G_MSG = "//m:generalErrorInfo/m:errorWarningDescription/m:freeText";
    const Q_G_OLD_ERR = "//m:generalErrorInfo//m:messageErrorInformation/m:errorDetail/m:errorCode";
    const Q_G_OLD_MSG = "//m:generalErrorInfo/m:messageErrorText/m:text";
    const Q_S_ERR = "//m:originDestinationDetails//m:errorInfo/m:errorOrWarningCodeDetails/m:errorDetails/m:errorCode";
    const Q_S_MSG = "//m:originDestinationDetails//m:errorInfo/m:errorWarningDescription/m:freeText";
    const Q_E_ERR = "//m:dataElementsIndiv/m:elementErrorInformation/m:errorOrWarningCodeDetails//m:errorCode";
    const Q_E_MSG = "//m:dataElementsIndiv//m:elementErrorInformation/m:errorWarningDescription/m:freeText";
    const Q_P_ERR = "//m:travellerInfo/m:nameError/m:errorOrWarningCodeDetails//m:errorCode";
    const Q_P_MSG = "//m:travellerInfo/m:nameError/m:errorWarningDescription/m:freeText";

    /**
     * Analysing a PNR_Reply
     *
     * @param SendResult $response
     * @return Result
     */
    public function analyze(SendResult $response)
    {
        $analyzeResponse = new Result($response);

        $domXpath = $this->makeDomXpath($response->responseXml);

        //General Errors:
        $errorCodeNodeList = $domXpath->query(self::Q_G_ERR);

        if ($errorCodeNodeList->length > 0) {
            $analyzeResponse->status = Result::STATUS_ERROR;

            $code = $errorCodeNodeList->item(0)->nodeValue;
            $errorTextNodeList = $domXpath->query(self::Q_G_MSG);
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);

            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message), 'general');
        }

        //General Errors - PNR_Reply v 14.1 and below:
        $errorCodeNodeList = $domXpath->query(self::Q_G_OLD_ERR);

        if ($errorCodeNodeList->length > 0) {
            $analyzeResponse->status = Result::STATUS_ERROR;

            $code = $errorCodeNodeList->item(0)->nodeValue;
            $errorTextNodeList = $domXpath->query(self::Q_G_OLD_MSG);
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);

            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message), 'general');
        }

        //Passenger error
        $errorCodeNodeList = $domXpath->query(self::Q_P_ERR);

        if ($errorCodeNodeList->length > 0) {
            $analyzeResponse->status = Result::STATUS_ERROR;

            $code = $errorCodeNodeList->item(0)->nodeValue;
            $errorTextNodeList = $domXpath->query(self::Q_P_MSG);
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);

            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message), 'passenger');
        }

        //Segment errors:
        $errorCodeNodeList = $domXpath->query(self::Q_S_ERR);

        if ($errorCodeNodeList->length > 0) {
            $analyzeResponse->status = Result::STATUS_ERROR;

            $code = $errorCodeNodeList->item(0)->nodeValue;
            $errorTextNodeList = $domXpath->query(self::Q_S_MSG);
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);

            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message), 'segment');
        }

        //Element errors:
        $errorCodeNodeList = $domXpath->query(self::Q_E_ERR);

        if ($errorCodeNodeList->length > 0) {
            $analyzeResponse->status = Result::STATUS_ERROR;

            $code = $errorCodeNodeList->item(0)->nodeValue;

            $errorTextNodeList = $domXpath->query(self::Q_E_MSG);
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);

            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message), 'element');
        }

        return $analyzeResponse;
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Struct\Fare;

use Amadeus\Client\RequestOptions\Fare\MPTicketingPriceScheme;
use Amadeus\Client\RequestOptions\Fare\MPFareFamily;
use Amadeus\Client\RequestOptions\Fare\MPItinerary;
use Amadeus\Client\RequestOptions\FareMasterPricerCalendarOptions;
use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch;
use Amadeus\Client\RequestOptions\TicketAtcShopperMpTbSearchOptions;
use Amadeus\Client\Struct\Fare\MasterPricer;

/**
 * Fare_MasterPricerTravelBoardSearch message structure
 *
 * Also used for Fare_MasterPricerCalendar and Ticket_ATCShopperMasterPricerTravelBoardSearch
 *
 * @package Amadeus\Client\Struct\Fare
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class MasterPricerTravelBoardSearch extends BaseMasterPricerMessage
{
    /**
     * @var mixed
     */
    public $globalOptions;
    /**
     * @var MasterPricer\CustomerRef
     */
    public $customerRef;
    /**
     * @var mixed
     */
    public $formOfPaymentByPassenger;
    /**
     * @var mixed
     */
    public $solutionFamily;
    /**
     * @var mixed[]
     */
    public $passengerInfoGrp = [];
    /**
     * @var MasterPricer\FareFamilies[]
     */
    public $fareFamilies = [];
    /**
     * @var MasterPricer\PriceToBeat
     */
    public $priceToBeat;
    /**
     * @var mixed
     */
    public $taxInfo;
    /**
     * @var MasterPricer\TravelFlightInfo
     */
    public $travelFlightInfo;
    /**
     * @var array
     */
    public $valueSearch = [];
    /**
     * @var array
     */
    public $buckets = [];
    /**
     * Itinerary
     *
     * @var MasterPricer\Itinerary[]
     */
    public $itinerary = [];
    /**
     * @var MPTicketingPriceScheme
     */
    public $ticketingPriceScheme;
    /**
     * @var mixed
     */
    public $ticketChangeInfo;
    /**
     * @var mixed
     */
    public $combinationFareFamilies;
    /**
     * @var MasterPricer\FeeOption[]
     */
    public $feeOption;
    /**
     * @var MasterPricer\OfficeIdDetails[]
     */
    public $officeIdDetails;

    /**
     * MasterPricerTravelBoardSearch constructor.
     *
     * @param FareMasterPricerTbSearch|FareMasterPricerCalendarOptions|TicketAtcShopperMpTbSearchOptions|null $options
     */
    public function __construct($options = null)
    {
        if ($options instanceof FareMasterPricerTbSearch) {
            $this->loadOptions($options);
        }
    }

    /**
     * @param FareMasterPricerTbSearch|FareMasterPricerCalendarOptions|TicketAtcShopperMpTbSearchOptions $options
     */
    protected function loadOptions($options)
    {
        $this->loadNumberOfUnits($options);

        $this->loadFareOptions($options);

        $passengerCounter = 1;
        $infantCounter = 1;
        foreach ($options->passengers as $passenger) {
            $this->loadPassenger($passenger, $passengerCounter, $infantCounter);
        }

        $segmentCounter = 1;
        foreach ($options->itinerary as $itinerary) {
            $this->loadItinerary($itinerary, $segmentCounter);
        }

        foreach ($options->officeIds as $officeId) {
            $this->loadOfficeId($officeId);
        }

        if ($this->checkAnyNotEmpty(
            $options->cabinClass,
            $options->cabinOption,
            $options->requestedFlightTypes,
            $options->airlineOptions,
            $options->progressiveLegsMin,
            $options->progressiveLegsMax,
            $options->maxLayoverPerConnectionHours,
            $options->maxLayoverPerConnectionMinutes,
            $options->noAirportChange,
            $options->maxElapsedFlyingTime
        )) {
            $this->travelFlightInfo = new MasterPricer\TravelFlightInfo(
                $options->cabinClass,
                $options->cabinOption,
                $options->requestedFlightTypes,
                $options->airlineOptions,
                $options->progressiveLegsMin,
                $options->progressiveLegsMax,
                $options->maxLayoverPerConnectionHours,
                $options->maxLayoverPerConnectionMinutes,
                $options->noAirportChange,
                $options->maxElapsedFlyingTime
            );
        }

        if (!is_null($options->priceToBeat)) {
            $this->priceToBeat = new MasterPricer\PriceToBeat(
                $options->priceToBeat,
                $options->priceToBeatCurrency
            );
        }

        $this->loadFareFamilies($options->fareFamilies);

        $this->loadCustomerRefs($options->dkNumber);

        $this->loadFeeOptions($options->feeOption);
    }

    /**
     * @param string $officeId
     */
    protected function loadOfficeId($officeId)
    {
        $this->officeIdDetails[] = new MasterPricer\OfficeIdDetails($officeId);
    }

    /**
     * @param MPItinerary $opt
     * @param int $counter BYREF
     */
    protected function loadItinerary($opt, &$counter)
    {
        $segmentRef = $counter;

        if (!empty($opt->segmentReference)) {
            $segmentRef = $opt->segmentReference;
        }

        $tmpItinerary = new MasterPricer\Itinerary($segmentRef);

        $tmpItinerary->departureLocalization = new MasterPricer\DepartureLocalization(
            $opt->departureLocation
        );
        $tmpItinerary->arrivalLocalization = new MasterPricer\ArrivalLocalization(
            $opt->arrivalLocation
        );
        $tmpItinerary->timeDetails = new MasterPricer\TimeDetails($opt->date);

        if ($this->checkAnyNotEmpty(
            $opt->airlineOptions,
            $opt->requestedFlightTypes,
            $opt->includedConnections,
            $opt->excludedConnections,
            $opt->nrOfConnections,
            $opt->noAirportChange,
            $opt->cabinClass,
            $opt->cabinOption
        )) {
            $tmpItinerary->flightInfo = new MasterPricer\FlightInfo(
                $opt->airlineOptions,
                $opt->requestedFlightTypes,
                $opt->includedConnections,
                $opt->excludedConnections,
                $opt->nrOfConnections,
                $opt->noAirportChange,
                $opt->cabinClass,
                $opt->cabinOption
            );
        }

        $this->itinerary[] = $tmpItinerary;

        $counter++;
    }

    /**
     * @param MPFareFamily[] $fareFamilies
     */
    protected function loadFareFamilies($fareFamilies)
    {
        foreach ($fareFamilies as $fareFamily) {
            $this->fareFamilies[] = new MasterPricer\FareFamilies($fareFamily);
        }
    }

    /**
     * Load Customer references
     *
     * @param string $dkNumber
     */
    protected function loadCustomerRefs($dkNumber)
    {
        if (!is_null($dkNumber)) {
            $this->customerRef = new MasterPricer\CustomerRef();
            $this->customerRef->customerReferences[] = new MasterPricer\CustomerReferences(
                $dkNumber,
                MasterPricer\CustomerReferences::QUAL_AGENCY_GROUPING_ID
            );
        }
    }

    private function loadFeeOptions($feeOptions)
    {
        if (!is_null($feeOptions)) {
            foreach ($feeOptions as $feeOption) {
                $this->feeOption[] = new MasterPricer\FeeOption($feeOption);
            }
        }
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Struct\Pnr;

use Amadeus\Client\RequestOptions\PnrCancelOptions;
use Amadeus\Client\Struct\BaseWsMessage;
use Amadeus\Client\Struct\Pnr\AddMultiElements\PnrActions;
use Amadeus\Client\Struct\Pnr\Cancel\Element;
use Amadeus\Client\Struct\Pnr\Cancel\Elements;

/**
 * PNR_Cancel message structure
 *
 * @package Amadeus\Client\Struct\Pnr
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class Cancel extends BaseWsMessage
{
    /**
     * @var ReservationInfo
     */
    public $reservationInfo;

    /**
     * @var PnrActions
     */
    public $pnrActions;

    /**
     * @var Cancel\Elements[]
     */
    public $cancelElements = [];

    /**
     * Cancel constructor.
     *
     * @param PnrCancelOptions $params
     */
    public function __construct(PnrCancelOptions $params)
    {
        if (is_string($params->recordLocator) && strlen($params->recordLocator) >= 6) {
            $this->reservationInfo = new ReservationInfo($params->recordLocator);
        }

        $this->pnrActions = new PnrActions($params->actionCode);

        if ($params->cancelItinerary === true) {
            $this->cancelElements[] = new Cancel\Elements(Elements::ENTRY_ITINERARY);
        }

        $this->loadElements($params);

        $this->loadSegments($params);

        $this->loadGroupPassengers($params);

        $this->loadPassengers($params);

        $this->loadOffers($params);
    }

    /**
     * @param PnrCancelOptions $params
     * @return void
     */
    protected function loadElements(PnrCancelOptions $params)
    {
        if (!empty($params->elementsByTattoo)) {
            $tmp = new Cancel\Elements(Elements::ENTRY_ELEMENT);

            foreach ($params->elementsByTattoo as $tattoo) {
                $tmp->element[] = new Element($tattoo, Element::IDENT_OTHER_TATTOO);
            }

            $this->cancelElements[] = $tmp;
        }
    }

    /**
     * @param PnrCancelOptions $params
     * @return void
     */
    protected function loadSegments(PnrCancelOptions $params)
    {
        if (!empty($params->segments)) {
            $tmp = new Cancel\Elements(Elements::ENTRY_ELEMENT);

            foreach ($params->segments as $tatoo) {
                $tmp->element[] = new Element($tatoo, Element::IDENT_SEGMENT_TATTOO);
            }

            $this->cancelElements[] = $tmp;
        }
    }

    /**
     * @param PnrCancelOptions $params
     * @return void
     */
    protected function loadGroupPassengers(PnrCancelOptions $params)
    {
        if (!empty($params->groupPassengers)) {
            $tmp = new Cancel\Elements(Elements::ENTRY_NAME_INTEGRATION);

            foreach ($params->groupPassengers as $offerRef) {
                $tmp->element[] = new Element($offerRef, Element::IDENT_PASSENGER_TATTOO);
            }

            $this->cancelElements[] = $tmp;
        }
    }

    /**
     * @param PnrCancelOptions $params
     * @return void
     */
    protected function loadPassengers(PnrCancelOptions $params)
    {
        if (!empty($params->passengers)) {
            $tmp = new Cancel\Elements(Elements::ENTRY_ELEMENT);

            foreach ($params->passengers as $offerRef) {
                $tmp->element[] = new Element($offerRef, Element::IDENT_PASSENGER_TATTOO);
            }

            $this->cancelElements[] = $tmp;
        }
    }

    /**
     * @param PnrCancelOptions $params
     * @return void
     *
     */
    protected function loadOffers(PnrCancelOptions $params)
    {
        if (!empty($params->offers)) {
            $tmp = new Cancel\Elements(Elements::ENTRY_ELEMENT);

            foreach ($params->offers as $offerRef) {
                $tmp->element[] = new Element($offerRef, Element::IDENT_OFFER_TATTOO);
            }

            $this->cancelElements[] = $tmp;
        }
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Params;

/**
 * AuthParams defines necessary authentication parameters for Amadeus Web Service client authentication.
 *
 * @package Amadeus\Client\Params
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class AuthParams
{
    /**
     * The Amadeus Office ID to sign in to
     *
     * @var string
     */
    public $officeId;

    /**
     * Originator Typecode
     *
     * @var string
     */
    public $originatorTypeCode = "U";

    /**
     * Duty code
     *
     * @var string
     */
    public $dutyCode = "SU";

    /**
     * User ID / Originator
     *
     * @var string
     */
    public $userId;

    /**
     * Organization ID
     *
     * @var string
     */
    public $organizationId;

    /**
     * Password Length of plain password.
     *
     * Only for SoapHeader < 4.
     *
     * @var int
     */
    public $passwordLength;

    /**
     * Password Data (base-64 encoded password)
     *
     * @var string
     */
    public $passwordData;

    /**
     * Custom Nonce base to use when generating nonces for authentication
     *
     * Only applies to Soap Header V4
     *
     * If you do not provide one, the Session HandlerFactory will generate a random string.
     *
     * @var string
     */
    public $nonceBase;

    /**
     * @param array $params
     */
    public function __construct($params = [])
    {
        $this->loadFromArray($params);
    }

    /**
     * Load parameters from an associative array
     *
     * @param array $params
     * @return void
     */
    protected function loadFromArray(array $params)
    {
        if (count($params) > 0) {
            $this->officeId = $params['officeId'];
            $this->originatorTypeCode = (isset($params['originatorTypeCode'])) ? $params['originatorTypeCode'] : "U";
            $this->dutyCode = (isset($params['dutyCode'])) ? $params['dutyCode'] : "SU";
            $this->userId = $params['userId'];
            $this->organizationId = (isset($params['organizationId'])) ? $params['organizationId'] : null;
            $this->passwordLength = (isset($params['passwordLength'])) ? $params['passwordLength'] : null;
            $this->passwordData = $params['passwordData'];

            if (isset($params['nonceBase'])) {
                $this->nonceBase = $params['nonceBase'];
            }
        }
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Params;

use Amadeus\Client;
use Psr\Log\LoggerInterface;

/**
 * SessionHandlerParams contains all parameters for setting up the session handler
 *
 * @package Amadeus\Client\Params
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class SessionHandlerParams
{

    /**
     * Full file & path to the WSDL file to be used
     *
     * @var string[]
     */
    public $wsdl = [];

    /**
     * Which Soap Header version to be used
     *
     * @var string
     */
    public $soapHeaderVersion = Client::HEADER_V4;

    /**
     * @var AuthParams
     */
    public $authParams;

    /**
     * The default setting for sending messages (if not specified)
     *
     * Set to FALSE to enable stateless messages - only applies to SOAP header v4 and higher!
     *
     * @var bool
     */
    public $stateful = true;

    /**
     * @var LoggerInterface
     */
    public $logger;

    /**
     * Override the default \SoapClient options
     *
     * used when constructing \SoapClient
     *
     * See Amadeus\Client\Session\Handler\Base::$soapClientOptions for defaults
     *
     * @var array
     */
    public $soapClientOptions = [];

    /**
     * Overridden soap client
     *
     * @var \SoapClient
     */
    public $overrideSoapClient;

    /**
     * Override SoapClient WSDL name
     *
     * @var string
     */
    public $overrideSoapClientWsdlName;

    /**
     * Enable the TransactionFlowLink SOAP Header?
     *
     * @var bool
     */
    public $enableTransactionFlowLink = false;

    /**
     * Consumer ID for Transaction Flow Link
     *
     * @var string|null
     */
    public $consumerId = null;

    /**
     * @param array $params
     */
    public function __construct($params = [])
    {
        $this->loadFromArray($params);
    }

    /**
     * Load parameters from an associative array
     *
     * @param array $params
     * @return void
     */
    protected function loadFromArray(array $params)
    {
        if (count($params) > 0) {
            if (isset($params['soapHeaderVersion'])) {
                $this->soapHeaderVersion = $params['soapHeaderVersion'];
            }

            $this->loadWsdl($params);
            $this->loadStateful($params);
            $this->loadLogger($params);

            $this->loadAuthParams($params);

            $this->loadOverrideSoapClient($params);
            $this->loadSoapClientOptions($params);

            $this->loadTransactionFlowLink($params);
        }
    }

    /**
     * Load WSDL from config
     *
     * Either a single WSDL location as string or a list of WSDL locations as array.
     *
     * @param array $params
     * @return void
     */
    protected function loadWsdl($params)
    {
        if (isset($params['wsdl'])) {
            if (is_string($params['wsdl'])) {
                $this->wsdl = [
                    $params['wsdl']
                ];
            } elseif (is_array($params['wsdl'])) {
                $this->wsdl = $params['wsdl'];
            }
        }
    }

    /**
     * Load Stateful param from config
     *
     * @param array $params
     * @return void
     */
    protected function loadStateful($params)
    {
        $this->stateful = (isset($params['stateful'])) ? $params['stateful'] : true;
    }

    /**
     * Load Logger from config
     *
     * @param array $params
     * @return void
     */
    protected function loadLogger($params)
    {
        if ((isset($params['logger']) && $params['logger'] instanceof LoggerInterface)) {
            $this->logger = $params['logger'];
        }
    }

    /**
     * Load Authentication parameters from config
     *
     * @param array $params
     * @return void
     */
    protected function loadAuthParams($params)
    {
        if (isset($params['authParams'])) {
            if ($params['authParams'] instanceof AuthParams) {
                $this->authParams = $params['authParams'];
            } elseif (is_array($params['authParams'])) {
                $this->authParams = new AuthParams($params['authParams']);
            }
        }
    }

    /**
     * Load Override SoapClient parameter from config
     *
     * @param array $params
     * @return void
     */
    protected function loadOverrideSoapClient($params)
    {
        if (isset($params['overrideSoapClient']) && $params['overrideSoapClient'] instanceof \SoapClient) {
            $this->overrideSoapClient = $params['overrideSoapClient'];
        }
        if (isset($params['overrideSoapClientWsdlName'])) {
            $this->overrideSoapClientWsdlName = $params['overrideSoapClientWsdlName'];
        }
    }

    /**
     * Load SoapClient Options from config
     *
     * @param array $params
     * @return void
     */
    protected function loadSoapClientOptions($params)
    {
        if (isset($params['soapClientOptions']) && is_array($params['soapClientOptions'])) {
            $this->soapClientOptions = $params['soapClientOptions'];
        }
    }

    /**
     * Load TransactionFlowLink options from config
     *
     * @param array $params
     * @return void
     */
    protected function loadTransactionFlowLink($params)
    {
        if (isset($params['enableTransactionFlowLink']) && $params['enableTransactionFlowLink'] === true) {
            $this->enableTransactionFlowLink = true;
            $this->consumerId = (isset($params['consumerId'])) ? $params['consumerId'] : null;
        }
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\Session\Handler;

use Amadeus\Client;

/**
 * SoapHeader2: Session Handler for web service applications using Amadeus WS Soap Header v2.
 *
 * @package Amadeus\Client\Session\Handler
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class SoapHeader2 extends Base
{
    /**
     * Namespace of SoapHeader V2
     */
    const CORE_WS_V2_SESSION_NS = 'http://xml.amadeus.com/ws/2009/01/WBS_Session-2.0.xsd';

    /**
     * Node for Session
     */
    const NODENAME_SESSION = "Session";

    /**
     * Node for Session ID
     */
    const NODENAME_SESSIONID = "SessionId";
    /**
     * Node for Session Sequence Number
     */
    const NODENAME_SEQENCENR = "SequenceNumber";
    /**
     * Node for Session Security Token
     */
    const NODENAME_SECURITYTOKEN = "SecurityToken";

    /**
     * Prepare to send a next message and checks if authenticated
     *
     * @param string $messageName
     * @param array $messageOptions
     * @throws InvalidSessionException When trying to send a message without session.
     */
    protected function prepareForNextMessage($messageName, $messageOptions)
    {
        if (!$this->isAuthenticated && $messageName !== 'Security_Authenticate') {
            throw new InvalidSessionException('No active session');
        }

        $this->getSoapClient($messageName)->__setSoapHeaders(null);

        if ($this->isAuthenticated === true && is_int($this->sessionData['sequenceNumber'])) {
            $this->sessionData['sequenceNumber']++;

            $session = new Client\Struct\HeaderV2\Session(
                $this->sessionData['sessionId'],
                $this->sessionData['sequenceNumber'],
                $this->sessionData['securityToken']
            );

            $this->getSoapClient($messageName)->__setSoapHeaders(
                new \SoapHeader(self::CORE_WS_V2_SESSION_NS, self::NODENAME_SESSION, $session)
            );
        }
    }

    /**
     * Handles post message actions
     *
     * Handles session state based on received response
     *
     * @param string $messageName
     * @param string $lastResponse
     * @param array $messageOptions
     * @param mixed $result
     */
    protected function handlePostMessage($messageName, $lastResponse, $messageOptions, $result)
    {
        if ($messageName === "Security_Authenticate") {
            $this->sessionData = $this->getSessionDataFromHeader($lastResponse);
            $this->isAuthenticated = (!empty($this->sessionData['sessionId']) &&
                !empty($this->sessionData['sequenceNumber']) &&
                !empty($this->sessionData['securityToken']));
        }
    }

    /**
     * @param string $responseMsg the full response XML received.
     * @return array
     */
    protected function getSessionDataFromHeader($responseMsg)
    {
        $newSessionData = [
            'sessionId' => null,
            'sequenceNumber' => null,
            'securityToken' => null
        ];

        $responseDomDoc = new \DOMDocument('1.0', 'UTF-8');
        $ok = $responseDomDoc->loadXML($responseMsg);

        if ($ok) {
            $sessionId = $responseDomDoc->getElementsByTagName(self::NODENAME_SESSIONID)->item(0)->nodeValue;
            if ($sessionId) {
                $newSessionData['sessionId'] = $sessionId;
            }
            $sequence = (int) $responseDomDoc->getElementsByTagName(self::NODENAME_SEQENCENR)->item(0)->nodeValue;
            if ($sequence) {
                $newSessionData['sequenceNumber'] = $sequence;
            }
            $securityToken = $responseDomDoc->getElementsByTagName(self::NODENAME_SECURITYTOKEN)->item(0)->nodeValue;
            if ($securityToken) {
                $newSessionData['securityToken'] = $securityToken;
            }
        }

        unset($responseDomDoc);

        return $newSessionData;
    }

    /**
     * Cannot set stateless on Soap Header v2
     *
     * @param bool $stateful
     * @throws UnsupportedOperationException
     */
    public function setStateful($stateful)
    {
        if ($stateful === false) {
            throw new UnsupportedOperationException('Stateful messages are mandatory on SoapHeader 2');
        }
    }

    /**
     * Soap Header 2 sessions are always stateful
     *
     * @return bool
     */
    public function isStateful()
    {
        return true;
    }

    /**
     * Is the TransactionFlowLink header enabled?
     *
     * @return bool
     */
    public function isTransactionFlowLinkEnabled()
    {
        return false; //Not supported
    }

    /**
     * Enable or disable TransactionFlowLink header
     *
     * @throws UnsupportedOperationException when used on unsupported WSAP versions
     * @param bool $enabled
     */
    public function setTransactionFlowLink($enabled)
    {
        if ($enabled === true) {
            throw new UnsupportedOperationException('TransactionFlowLink header is not supported on SoapHeader 2');
        }
    }

    /**
     * Get the TransactionFlowLink Consumer ID
     *
     * @return string|null
     */
    public function getConsumerId()
    {
        return null; //Not supported
    }

    /**
     * Set the TransactionFlowLink Consumer ID
     *
     * @throws UnsupportedOperationException when used on unsupported WSAP versions
     * @param string $id
     * @return void
     */
    public function setConsumerId($id)
    {
        if (!is_null($id)) {
            throw new UnsupportedOperationException('TransactionFlowLink header is not supported on SoapHeader 2');
        }
    }

    /**
     * Make SoapClient options for Soap Header 2 handler
     *
     * @return array
     */
    protected function makeSoapClientOptions()
    {
        $options = $this->soapClientOptions;
        $options['classmap'] = array_merge(Classmap::$soapheader2map, Classmap::$map);

        if (!empty($this->params->soapClientOptions)) {
            $options = array_merge($options, $this->params->soapClientOptions);
        }

        return $options;
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\ResponseHandler\PNR;

use Amadeus\Client\ResponseHandler\StandardResponseHandler;
use Amadeus\Client\Result;
use Amadeus\Client\Session\Handler\SendResult;

/**
 * HandlerNameChange
 *
 * @package Amadeus\Client\ResponseHandler\PNR
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class HandlerNameChange extends StandardResponseHandler
{
    /**
     * Analysing a PNR_NameChangeReply
     *
     * @param SendResult $response
     * @return Result
     */
    public function analyze(SendResult $response)
    {
        $analyzeResponse = new Result($response);

        $domXpath = $this->makeDomXpath($response->responseXml);

        $qPassErrors = "//m:passengerErrorInEnhancedData//m:errorDetails/m:errorCode";
        $qPassErrorCat = "//m:passengerErrorInEnhancedData//m:errorDetails/m:errorCategory";
        $qPassErrorMsg = "//m:passengerErrorInEnhancedData//m:freeText";

        $errorCodeNodeList = $domXpath->query($qPassErrors);

        if ($errorCodeNodeList->length > 0) {
            $analyzeResponse->status = Result::STATUS_ERROR;

            $errorCatNode = $domXpath->query($qPassErrorCat)->item(0);
            if ($errorCatNode instanceof \DOMNode) {
                $analyzeResponse->status = $this->makeStatusFromErrorQualifier($errorCatNode->nodeValue);
            }

            $code = $errorCodeNodeList->item(0)->nodeValue;
            $errorTextNodeList = $domXpath->query($qPassErrorMsg);
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);

            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message), 'passenger');
        }

        if (empty($analyzeResponse->messages) && $analyzeResponse->status === Result::STATUS_OK) {
            $analyzeResponse = $this->analyzeSimpleResponseErrorCodeAndMessage($response);
        }

        return $analyzeResponse;
    }
}


<?php
/**
 * amadeus-ws-client
 *
 * Copyright 2015 Amadeus Benelux NV
 *
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * @package Amadeus
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
 */

namespace Amadeus\Client\ResponseHandler\Queue;

use Amadeus\Client\ResponseHandler\StandardResponseHandler;
use Amadeus\Client\Result;
use Amadeus\Client\Session\Handler\SendResult;

/**
 * HandlerList
 *
 * @package Amadeus\Client\ResponseHandler\Queue
 * @author Dieter Devlieghere <dermikagh@gmail.com>
 */
class HandlerList extends StandardResponseHandler
{
    public function analyze(SendResult $response)
    {
        $analysisResponse = new Result($response);

        $domDoc = $this->loadDomDocument($response->responseXml);

        $errorCodeNode = $domDoc->getElementsByTagName("errorCode")->item(0);

        if (!is_null($errorCodeNode)) {
            $analysisResponse->status = Result::STATUS_WARN;

            $errorCode = $errorCodeNode->nodeValue;
            $errorMessage = $this->getErrorTextFromQueueErrorCode($errorCode);

            $analysisResponse->messages[] = new Result\NotOk($errorCode, $errorMessage);
        }

        return $analysisResponse;
    }

    /**
     * Returns the errortext from a Queue_*Reply errorcode
     *
     * This function is necessary because the core only responds
     * with errorcode but does not send an errortext.
     *
     * The errorcodes for all Queue_*Reply messages are the same.
     *
     * @link https://webservices.amadeus.com/extranet/viewArea.do?id=10
     * @param string $errorCode
     * @return string the errortext for this errorcode.
     */
    protected function getErrorTextFromQueueErrorCode($errorCode)
    {
        $recognizedErrors = [
            '1' => 'Invalid date',
            '360' => 'Invalid PNR file address',
            '723' => 'Invalid category',
            '727' => 'Invalid amount',
            '79A' => 'Invalid office identification',
            '79B' => 'Already working another queue',
            '79C' => 'Not allowed to access queues for specified office identification',
            '79D' => 'Queue identifier has not been assigned for specified office identification',
            '79E' => 'Attempting to perform a queue function when not associated with a queue',
            '79F' => 'Queue placement or add new queue item is not allowed for the specified office and queue',
            '911' => 'Unable to process - system error',
            '912' => 'Incomplete message - data missing in query',
            '913' => 'Item/data not found or data not existing in processing host',
            '914' => 'Invalid format/data - data does not match EDIFACT rules',
            '915' => 'No action - processing host cannot support function',
            '916' => 'EDIFACT version not supported',
            '917' => 'EDIFACT message size exceeded',
            '918' => 'Enter message in remarks',
            '919' => 'No PNR in AAA',
            '91A' => 'Inactive queue bank',
            '91B' => 'Nickname not found',
            '91C' => 'Invalid record locator',
            '91D' => 'Invalid format',
            '91F' => 'Invalid queue number',
            '920' => 'Queue/date range empty',
            '921' => 'Target not specified',
            '922' => 'Targetted queue has wrong queue type',
            '923' => 'Invalid time',
            '924' => 'Invalid date range',
            '925' => 'Queue number not specified',
            '926' => 'Queue category empty',
            '927' => 'No items exist',
            '928' => 'Queue category not assigned',
            '929' => 'No more items',
            '92A' => '>ueue category full'
        ];

        $errorMessage = (array_key_exists($errorCode, $recognizedErrors)) ? $recognizedErrors[$errorCode] : '';

        if ($errorMessage === '') {
            $errorMessage = "QUEUE ERROR '".$errorCode."' (Error message unavailable)";
        }

        return $errorMessage;
    }
}