diff --git a/app/code/Magento/Payment/Block/Info.php b/app/code/Magento/Payment/Block/Info.php index d56f2c61fe3559e242c97aecc6bc23a704fe1dd6..94c8b8c998d938519c379f72769d496179fda838 100644 --- a/app/code/Magento/Payment/Block/Info.php +++ b/app/code/Magento/Payment/Block/Info.php @@ -15,7 +15,7 @@ class Info extends \Magento\Framework\View\Element\Template * * @var \Magento\Framework\Object */ - protected $_paymentSpecificInformation = null; + protected $_paymentSpecificInformation; /** * @var string @@ -152,10 +152,6 @@ class Info extends \Magento\Framework\View\Element\Template } elseif (is_array($transport)) { $transport = new \Magento\Framework\Object($transport); } - $this->_eventManager->dispatch( - 'payment_info_block_prepare_specific_information', - ['transport' => $transport, 'payment' => $this->getInfo(), 'block' => $this] - ); $this->_paymentSpecificInformation = $transport; } return $this->_paymentSpecificInformation; diff --git a/app/code/Magento/Payment/Block/Transparent/Form.php b/app/code/Magento/Payment/Block/Transparent/Form.php index 73df0c39c87d95c38a5336530d42802c9c913101..2ff21bae0872b75e9fd03ee53eab79b25dc6564f 100644 --- a/app/code/Magento/Payment/Block/Transparent/Form.php +++ b/app/code/Magento/Payment/Block/Transparent/Form.php @@ -6,6 +6,7 @@ namespace Magento\Payment\Block\Transparent; use Magento\Framework\Exception\LocalizedException; +use Magento\Payment\Model\Method\Adapter; use Magento\Payment\Model\Method\TransparentInterface; use Magento\Checkout\Model\Session; use Magento\Payment\Model\Config; @@ -168,7 +169,11 @@ class Form extends \Magento\Payment\Block\Form\Cc */ public function getMethodConfigData($fieldName) { - return $this->getMethod()->getConfigInterface()->getValue($fieldName); + $method = $this->getMethod(); + if ($method instanceof TransparentInterface) { + return $method->getConfigInterface()->getValue($fieldName); + } + return $method->getConfigData($fieldName); } /** @@ -181,7 +186,7 @@ class Form extends \Magento\Payment\Block\Form\Cc { $method = parent::getMethod(); - if (!$method instanceof TransparentInterface) { + if (!$method instanceof TransparentInterface && !$method instanceof Adapter) { throw new LocalizedException( __('We cannot retrieve the transparent payment method model object.') ); diff --git a/app/code/Magento/Payment/Block/Transparent/Iframe.php b/app/code/Magento/Payment/Block/Transparent/Iframe.php index 3070173f92b36c0bae20d66aadce8981b7c322af..d93f0d076ab64d564bc28a946b7821a369f6b580 100644 --- a/app/code/Magento/Payment/Block/Transparent/Iframe.php +++ b/app/code/Magento/Payment/Block/Transparent/Iframe.php @@ -12,6 +12,8 @@ namespace Magento\Payment\Block\Transparent; */ class Iframe extends \Magento\Framework\View\Element\Template { + const REGISTRY_KEY = 'transparent_form_params'; + /** * Core registry * @@ -42,10 +44,8 @@ class Iframe extends \Magento\Framework\View\Element\Template */ protected function _prepareLayout() { - if ($this->hasRegistryKey()) { - $params = $this->coreRegistry->registry($this->getRegistryKey()); - $this->setParams($params); - } + $params = $this->coreRegistry->registry(self::REGISTRY_KEY); + $this->setParams($params); return parent::_prepareLayout(); } } diff --git a/app/code/Magento/Payment/Gateway/Command/CommandPool.php b/app/code/Magento/Payment/Gateway/Command/CommandPool.php index a6cafee447b83df75cc689ac349d57ed3c83bb8a..6b1014d5aa76d9fefb8a1efb80583147067f2853 100644 --- a/app/code/Magento/Payment/Gateway/Command/CommandPool.php +++ b/app/code/Magento/Payment/Gateway/Command/CommandPool.php @@ -8,21 +8,29 @@ namespace Magento\Payment\Gateway\Command; use Magento\Framework\ObjectManager\TMap; use Magento\Payment\Gateway\CommandInterface; use Magento\Framework\Exception\NotFoundException; +use Magento\Framework\ObjectManager\TMapFactory; class CommandPool implements CommandPoolInterface { /** - * @var CommandInterface[] + * @var CommandInterface[] | TMap */ private $commands; /** - * @param TMap $commands + * @param array $commands + * @param TMapFactory $tmapFactory */ public function __construct( - TMap $commands + array $commands, + TMapFactory $tmapFactory ) { - $this->commands = $commands; + $this->commands = $tmapFactory->create( + [ + 'array' => $commands, + 'type' => 'Magento\Payment\Gateway\CommandInterface' + ] + ); } /** diff --git a/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php b/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php index e2f5e25f75bad6c96dde6d0b2c2800e1f08af2f2..a6044462cded037192b2ca675ba06ce32e89549c 100644 --- a/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php +++ b/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php @@ -7,66 +7,83 @@ namespace Magento\Payment\Gateway\Command; use Magento\Payment\Gateway\CommandInterface; use Magento\Payment\Gateway\Http\ClientInterface; +use Magento\Payment\Gateway\Http\TransferFactoryInterface; use Magento\Payment\Gateway\Request; +use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Gateway\Response; +use Magento\Payment\Gateway\Response\HandlerInterface; +use Magento\Payment\Gateway\Validator\ValidatorInterface; class GatewayCommand implements CommandInterface { /** - * @var \Magento\Payment\Gateway\Request\BuilderInterface + * @var BuilderInterface */ private $requestBuilder; /** - * @var \Magento\Payment\Gateway\Http\TransferBuilderInterface + * @var TransferFactoryInterface */ - private $transferBuilder; + private $transferFactory; /** - * @var \Magento\Payment\Gateway\Http\ClientInterface + * @var ClientInterface */ - private $gateway; + private $client; /** - * @var \Magento\Payment\Gateway\Response\HandlerInterface + * @var HandlerInterface */ - private $responseHandler; + private $handler; /** - * @param \Magento\Payment\Gateway\Request\BuilderInterface $requestBuilder - * @param \Magento\Payment\Gateway\Http\TransferBuilderInterface $transferBuilder - * @param \Magento\Payment\Gateway\Http\ClientInterface $gateway - * @param \Magento\Payment\Gateway\Response\HandlerInterface $responseHandler + * @var ValidatorInterface + */ + private $validator; + + /** + * @param BuilderInterface $requestBuilder + * @param TransferFactoryInterface $transferFactory + * @param ClientInterface $client + * @param HandlerInterface $handler + * @param ValidatorInterface $validator */ public function __construct( - \Magento\Payment\Gateway\Request\BuilderInterface $requestBuilder, - \Magento\Payment\Gateway\Http\TransferBuilderInterface $transferBuilder, - ClientInterface $gateway, - \Magento\Payment\Gateway\Response\HandlerInterface $responseHandler + BuilderInterface $requestBuilder, + TransferFactoryInterface $transferFactory, + ClientInterface $client, + HandlerInterface $handler, + ValidatorInterface $validator ) { - $this->requestBuilder = $requestBuilder; - $this->transferBuilder = $transferBuilder; - $this->gateway = $gateway; - $this->responseHandler = $responseHandler; + $this->transferFactory = $transferFactory; + $this->client = $client; + $this->handler = $handler; + $this->validator = $validator; } /** * Executes command basing on business object * * @param array $commandSubject - * @return void + * @return null */ public function execute(array $commandSubject) { // @TODO implement exceptions catching - $transferO = $this->transferBuilder->build( + $transferO = $this->transferFactory->create( $this->requestBuilder->build($commandSubject) ); - $response = $this->gateway->placeRequest($transferO); + $response = $this->client->placeRequest($transferO); + + $result = $this->validator->validate(array_merge($commandSubject, ['response' => $response])); + if ($result !== null && !$result->isValid()) { + $commandSubject['payment']->getPayment()->setIsTransactionPending(true); + return; + } - $this->responseHandler->handle( + $this->handler->handle( $commandSubject, $response ); diff --git a/app/code/Magento/Payment/Gateway/Command/Result/ArrayResult.php b/app/code/Magento/Payment/Gateway/Command/Result/ArrayResult.php new file mode 100644 index 0000000000000000000000000000000000000000..fff6c1dc0125d4e62cc72640a3cd96d392b26292 --- /dev/null +++ b/app/code/Magento/Payment/Gateway/Command/Result/ArrayResult.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Gateway\Command\Result; + +use Magento\Payment\Gateway\Command\ResultInterface; + +class ArrayResult implements ResultInterface +{ + /** + * @var array + */ + private $array; + + /** + * @param array $array + */ + public function __construct(array $array = []) + { + $this->array = $array; + } + + /** + * Returns result interpretation + * + * @return array + */ + public function get() + { + return $this->array; + } +} diff --git a/app/code/Magento/Payment/Gateway/Command/ResultInterface.php b/app/code/Magento/Payment/Gateway/Command/ResultInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..bf26fc8e872516f7e6bc3913c52cf614f8d9d8ab --- /dev/null +++ b/app/code/Magento/Payment/Gateway/Command/ResultInterface.php @@ -0,0 +1,16 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Gateway\Command; + +interface ResultInterface +{ + /** + * Returns result interpretation + * + * @return mixed + */ + public function get(); +} diff --git a/app/code/Magento/Payment/Gateway/CommandInterface.php b/app/code/Magento/Payment/Gateway/CommandInterface.php index 1537c4d21a80da92d1de2956def17c5bed6815f5..44ef0ee10cf64a79646269e0fdd60a6d6ae3ef95 100644 --- a/app/code/Magento/Payment/Gateway/CommandInterface.php +++ b/app/code/Magento/Payment/Gateway/CommandInterface.php @@ -11,7 +11,7 @@ interface CommandInterface * Executes command basing on business object * * @param array $commandSubject - * @return void + * @return null|Command\ResultInterface */ public function execute(array $commandSubject); } diff --git a/app/code/Magento/Payment/Gateway/Config/ValueHandlerPool.php b/app/code/Magento/Payment/Gateway/Config/ValueHandlerPool.php index ec00f81b18046caea8c2c397384fd492bb8dbc4b..0364336a2ea5e42df84c190359218276bd2aa168 100644 --- a/app/code/Magento/Payment/Gateway/Config/ValueHandlerPool.php +++ b/app/code/Magento/Payment/Gateway/Config/ValueHandlerPool.php @@ -6,6 +6,7 @@ namespace Magento\Payment\Gateway\Config; use Magento\Framework\ObjectManager\TMap; +use Magento\Framework\ObjectManager\TMapFactory; class ValueHandlerPool implements \Magento\Payment\Gateway\Config\ValueHandlerPoolInterface { @@ -15,21 +16,28 @@ class ValueHandlerPool implements \Magento\Payment\Gateway\Config\ValueHandlerPo const DEFAULT_HANDLER = 'default'; /** - * @var ValueHandlerInterface[] + * @var ValueHandlerInterface[] | TMap */ private $handlers; /** - * @param TMap $handlers + * @param array $handlers + * @param TMapFactory $tmapFactory */ public function __construct( - TMap $handlers + array $handlers, + TMapFactory $tmapFactory ) { if (!isset($handlers[self::DEFAULT_HANDLER])) { throw new \LogicException('Default handler should be provided.'); } - $this->handlers = $handlers; + $this->handlers = $tmapFactory->create( + [ + 'array' => $handlers, + 'type' => 'Magento\Payment\Gateway\Config\ValueHandlerInterface' + ] + ); } /** diff --git a/app/code/Magento/Payment/Gateway/Data/AddressAdapterInterface.php b/app/code/Magento/Payment/Gateway/Data/AddressAdapterInterface.php index aeb1f0432f4ccf4ad45752f7835b8182cbdf7b42..ef55a1a67384bbd4ecec2601d8c308fb72bce8c5 100644 --- a/app/code/Magento/Payment/Gateway/Data/AddressAdapterInterface.php +++ b/app/code/Magento/Payment/Gateway/Data/AddressAdapterInterface.php @@ -12,7 +12,7 @@ interface AddressAdapterInterface * * @return string */ - public function getRegion(); + public function getRegionCode(); /** * Get country id diff --git a/app/code/Magento/Payment/Gateway/Data/Order/AddressAdapter.php b/app/code/Magento/Payment/Gateway/Data/Order/AddressAdapter.php index 54f312ccb5afb19081456e15a1a96a48ad526385..b057d9118240bc923e7e1c00b5ddc64344101aab 100644 --- a/app/code/Magento/Payment/Gateway/Data/Order/AddressAdapter.php +++ b/app/code/Magento/Payment/Gateway/Data/Order/AddressAdapter.php @@ -28,9 +28,9 @@ class AddressAdapter implements AddressAdapterInterface * * @return string */ - public function getRegion() + public function getRegionCode() { - return $this->address->getRegion(); + return $this->address->getRegionCode(); } /** diff --git a/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php b/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php index 08ad153f611280c1709efe4660a42d9e02c10888..f01bee1d7c77ab2b4c695ea4f00229f165e29132 100644 --- a/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php +++ b/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php @@ -86,4 +86,24 @@ class OrderAdapter implements OrderAdapterInterface ['address' => $this->order->getShippingAddress()] ); } + + /** + * Returns order store id + * + * @return int + */ + public function getStoreId() + { + return $this->order->getStoreId(); + } + + /** + * Returns order id + * + * @return int + */ + public function getId() + { + return $this->order->getEntityId(); + } } diff --git a/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php b/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php index 60698aa7d943dc28d60a7555d1c4788621d9bf39..0d925d823a9906c6d1bedbe4f488338f33493d64 100644 --- a/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php +++ b/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php @@ -41,4 +41,18 @@ interface OrderAdapterInterface * @return AddressAdapterInterface */ public function getShippingAddress(); + + /** + * Returns order store id + * + * @return int + */ + public function getStoreId(); + + /** + * Returns order id + * + * @return int + */ + public function getId(); } diff --git a/app/code/Magento/Payment/Gateway/Data/Quote/AddressAdapter.php b/app/code/Magento/Payment/Gateway/Data/Quote/AddressAdapter.php index dd846efe7a702d073ff734dba7a3466d43cece60..b73f2bb7bcdf3c04ff07b8bcda6332b0f641b66a 100644 --- a/app/code/Magento/Payment/Gateway/Data/Quote/AddressAdapter.php +++ b/app/code/Magento/Payment/Gateway/Data/Quote/AddressAdapter.php @@ -28,9 +28,9 @@ class AddressAdapter implements AddressAdapterInterface * * @return string */ - public function getRegion() + public function getRegionCode() { - return $this->address->getRegion(); + return $this->address->getRegionCode(); } /** diff --git a/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php b/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php index b6ed86aa58522080817e7837695245fadde89875..43a6a9ded86e61c539b5f64dfbbd89de57bc1c94 100644 --- a/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php +++ b/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php @@ -86,4 +86,24 @@ class QuoteAdapter implements OrderAdapterInterface ['address' => $this->quote->getShippingAddress()] ); } + + /** + * Returns order store id + * + * @return int + */ + public function getStoreId() + { + return $this->quote->getStoreId(); + } + + /** + * Returns order id + * + * @return int + */ + public function getId() + { + return $this->quote->getId(); + } } diff --git a/app/code/Magento/Payment/Gateway/Http/Client/Zend.php b/app/code/Magento/Payment/Gateway/Http/Client/Zend.php index fb3b64434c605912f383c3fd77b4a9b91b6fc5b7..0ea8ffbc871b8e49261c641a5bb71e3669e830d2 100644 --- a/app/code/Magento/Payment/Gateway/Http/Client/Zend.php +++ b/app/code/Magento/Payment/Gateway/Http/Client/Zend.php @@ -8,6 +8,8 @@ namespace Magento\Payment\Gateway\Http\Client; use Magento\Framework\HTTP\ZendClientFactory; use Magento\Framework\HTTP\ZendClient; use Magento\Payment\Gateway\Http\ClientInterface; +use Magento\Payment\Gateway\Http\ConverterInterface; +use Magento\Payment\Model\Method\Logger; class Zend implements ClientInterface { @@ -17,20 +19,28 @@ class Zend implements ClientInterface private $clientFactory; /** - * @var \Magento\Payment\Gateway\Http\ConverterInterface + * @var ConverterInterface */ private $converter; + /** + * @var Logger + */ + private $logger; + /** * @param ZendClientFactory $clientFactory - * @param \Magento\Payment\Gateway\Http\ConverterInterface $converter + * @param ConverterInterface $converter + * @param Logger $logger */ public function __construct( ZendClientFactory $clientFactory, - \Magento\Payment\Gateway\Http\ConverterInterface $converter + ConverterInterface $converter, + Logger $logger ) { $this->clientFactory = $clientFactory; $this->converter = $converter; + $this->logger = $logger; } /** @@ -38,6 +48,10 @@ class Zend implements ClientInterface */ public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject) { + $log = [ + 'request' => $transferObject->getBody() + ]; + $result = []; /** @var ZendClient $client */ $client = $this->clientFactory->create(); @@ -61,11 +75,17 @@ class Zend implements ClientInterface try { $response = $client->request(); - return $this->converter->convert($response->getBody()); + + $result = $this->converter->convert($response->getBody()); + $log['response'] = $result; } catch (\Zend_Http_Client_Exception $e) { throw new \Magento\Payment\Gateway\Http\ClientException(__($e->getMessage())); } catch (\Magento\Payment\Gateway\Http\ConverterException $e) { throw $e; + } finally { + $this->logger->debug($log); } + + return $result; } } diff --git a/app/code/Magento/Payment/Gateway/Http/Converter/HtmlFormConverter.php b/app/code/Magento/Payment/Gateway/Http/Converter/HtmlFormConverter.php new file mode 100644 index 0000000000000000000000000000000000000000..588a476bff9eeb0ebd66f37d7d3b9cce15a6a6e5 --- /dev/null +++ b/app/code/Magento/Payment/Gateway/Http/Converter/HtmlFormConverter.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Gateway\Http\Converter; + +use Magento\Payment\Gateway\Http\ConverterException; +use Magento\Payment\Gateway\Http\ConverterInterface; + +class HtmlFormConverter implements ConverterInterface +{ + /** + * Converts gateway response to ENV structure + * + * @param string $response + * @return array + * @throws ConverterException + */ + public function convert($response) + { + $document = new \DOMDocument(); + + libxml_use_internal_errors(true); + if (!$document->loadHTML($response)) { + throw new ConverterException(__('Wrong gateway response format.')); + } + libxml_use_internal_errors(false); + + $document->getElementsByTagName('input'); + + $convertedResponse = []; + /** @var \DOMNode $inputNode */ + foreach ($document->getElementsByTagName('input') as $inputNode) { + if (!$inputNode->attributes->getNamedItem('value') + || !$inputNode->attributes->getNamedItem('name') + ) { + continue; + } + $convertedResponse[$inputNode->attributes->getNamedItem('name')->nodeValue] + = $inputNode->attributes->getNamedItem('value')->nodeValue; + } + + return $convertedResponse; + } +} diff --git a/app/code/Magento/Payment/Gateway/Http/Transfer.php b/app/code/Magento/Payment/Gateway/Http/Transfer.php new file mode 100644 index 0000000000000000000000000000000000000000..6084f9f1c460b47b8f490388bd9ed6ebc091f976 --- /dev/null +++ b/app/code/Magento/Payment/Gateway/Http/Transfer.php @@ -0,0 +1,123 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Gateway\Http; + +class Transfer implements TransferInterface +{ + /** + * @var array + */ + private $clientConfig; + + /** + * @var array + */ + private $headers; + + /** + * @var string + */ + private $method; + + /** + * @var array + */ + private $body; + + /** + * @var string + */ + private $uri; + + /** + * @var bool + */ + private $encode; + + /** + * @param array $clientConfig + * @param array $headers + * @param array $body + * @param string $method + * @param string $uri + * @param bool $encode + */ + public function __construct( + array $clientConfig, + array $headers, + array $body, + $method, + $uri, + $encode = false + ) { + $this->clientConfig = $clientConfig; + $this->headers = $headers; + $this->method = $method; + $this->body = $body; + $this->uri = $uri; + $this->encode = $encode; + } + + /** + * Returns gateway client configuration + * + * @return array + */ + public function getClientConfig() + { + return $this->clientConfig; + } + + /** + * Returns method used to place request + * + * @return string|int + */ + public function getMethod() + { + return (string)$this->method; + } + + /** + * Returns headers + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Whether body should be encoded before place + * + * @return bool + */ + public function shouldEncode() + { + return (bool)$this->encode; + } + + /** + * Returns request body + * + * @return array + */ + public function getBody() + { + return $this->body; + } + + /** + * Returns URI + * + * @return string + */ + public function getUri() + { + return (string)$this->uri; + } +} diff --git a/app/code/Magento/Payment/Gateway/Http/TransferBuilderInterface.php b/app/code/Magento/Payment/Gateway/Http/TransferFactoryInterface.php similarity index 59% rename from app/code/Magento/Payment/Gateway/Http/TransferBuilderInterface.php rename to app/code/Magento/Payment/Gateway/Http/TransferFactoryInterface.php index b1a98abfa9af370c64c5e009ddda1185e917e3be..8a36ba9d1ca9186381ebd50fde4acc59edf9b83c 100644 --- a/app/code/Magento/Payment/Gateway/Http/TransferBuilderInterface.php +++ b/app/code/Magento/Payment/Gateway/Http/TransferFactoryInterface.php @@ -5,15 +5,13 @@ */ namespace Magento\Payment\Gateway\Http; -use Magento\Payment\Gateway\Http\TransferInterface; - -interface TransferBuilderInterface +interface TransferFactoryInterface { /** * Builds gateway transfer object * - * @param array $requestENV + * @param array $request * @return TransferInterface */ - public function build(array $requestENV); + public function create(array $request); } diff --git a/app/code/Magento/Payment/Gateway/Request/BuilderComposite.php b/app/code/Magento/Payment/Gateway/Request/BuilderComposite.php index 33e7df313156a02863e4c1db01d2ffeca9c35816..74395ff812d2513932228457cf5e40fcd14a1dc7 100644 --- a/app/code/Magento/Payment/Gateway/Request/BuilderComposite.php +++ b/app/code/Magento/Payment/Gateway/Request/BuilderComposite.php @@ -6,21 +6,29 @@ namespace Magento\Payment\Gateway\Request; use Magento\Framework\ObjectManager\TMap; +use Magento\Framework\ObjectManager\TMapFactory; class BuilderComposite implements BuilderInterface { /** - * @var BuilderInterface[] + * @var BuilderInterface[] | TMap */ private $builders; /** - * @param TMap $builders + * @param array $builders + * @param TMapFactory $tmapFactory */ public function __construct( - TMap $builders + array $builders, + TMapFactory $tmapFactory ) { - $this->builders = $builders; + $this->builders = $tmapFactory->create( + [ + 'array' => $builders, + 'type' => 'Magento\Payment\Gateway\Request\BuilderInterface' + ] + ); } /** diff --git a/app/code/Magento/Payment/Gateway/Response/HandlerChain.php b/app/code/Magento/Payment/Gateway/Response/HandlerChain.php index 91205ccc844a35733ca07ff903f6390bcba3c332..1425514e7e3fb87054fdb09690d49d53c0b52a72 100644 --- a/app/code/Magento/Payment/Gateway/Response/HandlerChain.php +++ b/app/code/Magento/Payment/Gateway/Response/HandlerChain.php @@ -6,21 +6,29 @@ namespace Magento\Payment\Gateway\Response; use Magento\Framework\ObjectManager\TMap; +use Magento\Framework\ObjectManager\TMapFactory; class HandlerChain implements HandlerInterface { /** - * @var HandlerInterface[] + * @var HandlerInterface[] | TMap */ private $handlers; /** - * @param TMap $handlers + * @param array $handlers + * @param TMapFactory $tmapFactory */ public function __construct( - TMap $handlers + array $handlers, + TMapFactory $tmapFactory ) { - $this->handlers = $handlers; + $this->handlers = $tmapFactory->create( + [ + 'array' => $handlers, + 'type' => 'Magento\Payment\Gateway\Response\HandlerInterface' + ] + ); } /** diff --git a/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php b/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..e82e0605445a367d1bbf528989c2081393f35c2c --- /dev/null +++ b/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Gateway\Validator; + +abstract class AbstractValidator implements ValidatorInterface +{ + /** + * @var ResultInterfaceFactory + */ + private $resultInterfaceFactory; + + /** + * @param ResultInterfaceFactory $resultFactory + */ + public function __construct( + ResultInterfaceFactory $resultFactory + ) { + $this->resultInterfaceFactory = $resultFactory; + } + + /** + * Factory method + * + * @param bool $isValid + * @param array $fails + * @return ResultInterface + */ + protected function createResult($isValid, array $fails = []) + { + return $this->resultInterfaceFactory->create(['isValid' => (bool)$isValid, 'failsDescription' => $fails]); + } +} diff --git a/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php b/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php index 6ee690a2500ee6e520656acc67c5a138ed8a3783..05a476f9743c12a930052fe27c4dfcb057e54ae5 100644 --- a/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php +++ b/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php @@ -6,12 +6,13 @@ namespace Magento\Payment\Gateway\Validator; use Magento\Framework\ObjectManager\TMap; +use Magento\Framework\ObjectManager\TMapFactory; use Magento\Payment\Gateway\Validator\ResultInterfaceFactory; class ValidatorComposite implements ValidatorInterface { /** - * @var ValidatorInterface[] + * @var ValidatorInterface[] | TMap */ private $validators; @@ -22,13 +23,20 @@ class ValidatorComposite implements ValidatorInterface /** * @param ResultInterfaceFactory $resultFactory - * @param TMap $validators + * @param array $validators + * @param TMapFactory $tmapFactory */ public function __construct( ResultInterfaceFactory $resultFactory, - TMap $validators + array $validators, + TMapFactory $tmapFactory ) { - $this->validators = $validators; + $this->validators = $tmapFactory->create( + [ + 'array' => $validators, + 'type' => 'Magento\Payment\Gateway\Validator\ValidatorInterface' + ] + ); $this->resultFactory = $resultFactory; } diff --git a/app/code/Magento/Payment/Gateway/Validator/ValidatorPool.php b/app/code/Magento/Payment/Gateway/Validator/ValidatorPool.php index c2f2b347de8acff129afbc85f596a16788961754..e2b746ea7334f480ef5fa3a83358081cea3289db 100644 --- a/app/code/Magento/Payment/Gateway/Validator/ValidatorPool.php +++ b/app/code/Magento/Payment/Gateway/Validator/ValidatorPool.php @@ -7,21 +7,29 @@ namespace Magento\Payment\Gateway\Validator; use Magento\Framework\Exception\NotFoundException; use Magento\Framework\ObjectManager\TMap; +use Magento\Framework\ObjectManager\TMapFactory; class ValidatorPool implements \Magento\Payment\Gateway\Validator\ValidatorPoolInterface { /** - * @var ValidatorInterface[] + * @var ValidatorInterface[] | TMap */ private $validators; /** - * @param TMap $validators + * @param array $validators + * @param TMapFactory $tmapFactory */ public function __construct( - TMap $validators + array $validators, + TMapFactory $tmapFactory ) { - $this->validators = $validators; + $this->validators = $tmapFactory->create( + [ + 'array' => $validators, + 'type' => 'Magento\Payment\Gateway\Validator\ValidatorInterface' + ] + ); } /** diff --git a/app/code/Magento/Payment/Model/IframeConfigProvider.php b/app/code/Magento/Payment/Model/IframeConfigProvider.php index a3a48f64f6205766194ecf4a94c7253d81eee099..03520b7b908e8ea642922fe58a67d2da751c0a37 100644 --- a/app/code/Magento/Payment/Model/IframeConfigProvider.php +++ b/app/code/Magento/Payment/Model/IframeConfigProvider.php @@ -21,6 +21,11 @@ use Psr\Log\LoggerInterface; */ class IframeConfigProvider implements ConfigProviderInterface { + /** + * Default length of Cc year field + */ + const DEFAULT_YEAR_LENGTH = 2; + /** * @var Repository */ @@ -92,6 +97,7 @@ class IframeConfigProvider implements ConfigProviderInterface 'cgiUrl' => [$this->methodCode => $this->getCgiUrl()], 'placeOrderUrl' => [$this->methodCode => $this->getPlaceOrderUrl()], 'saveOrderUrl' => [$this->methodCode => $this->getSaveOrderUrl()], + 'expireYearLength' => [$this->methodCode => $this->getExpireDateYearLength()] ] ] ]; @@ -115,6 +121,16 @@ class IframeConfigProvider implements ConfigProviderInterface return $result; } + /** + * Returns Cc expire year length + * + * @return int + */ + protected function getExpireDateYearLength() + { + return (int)$this->getMethodConfigData('cc_year_length') ?: self::DEFAULT_YEAR_LENGTH; + } + /** * Get map of cc_code, cc_num, cc_expdate for gateway * Returns json formatted string diff --git a/app/code/Magento/Payment/Model/Method/AbstractMethod.php b/app/code/Magento/Payment/Model/Method/AbstractMethod.php index c9bc85c757d5c71b4c5b423637ce17d9a3456346..441547499d81b937367dc408fda83270171d32e4 100644 --- a/app/code/Magento/Payment/Model/Method/AbstractMethod.php +++ b/app/code/Magento/Payment/Model/Method/AbstractMethod.php @@ -586,6 +586,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl * @return $this * @throws \Magento\Framework\Exception\LocalizedException * @api + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function order(\Magento\Payment\Model\InfoInterface $payment, $amount) { @@ -603,6 +604,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl * @return $this * @throws \Magento\Framework\Exception\LocalizedException * @api + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function authorize(\Magento\Payment\Model\InfoInterface $payment, $amount) { @@ -620,6 +622,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl * @return $this * @throws \Magento\Framework\Exception\LocalizedException * @api + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount) { @@ -638,6 +641,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl * @return $this * @throws \Magento\Framework\Exception\LocalizedException * @api + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function refund(\Magento\Payment\Model\InfoInterface $payment, $amount) { @@ -653,6 +657,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl * @param \Magento\Framework\Object|InfoInterface $payment * @return $this * @api + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function cancel(\Magento\Payment\Model\InfoInterface $payment) { @@ -666,6 +671,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl * @return $this * @throws \Magento\Framework\Exception\LocalizedException * @api + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function void(\Magento\Payment\Model\InfoInterface $payment) { @@ -692,6 +698,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl * @return false * @throws \Magento\Framework\Exception\LocalizedException * @api + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function acceptPayment(InfoInterface $payment) { @@ -708,6 +715,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl * @return false * @throws \Magento\Framework\Exception\LocalizedException * @api + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function denyPayment(InfoInterface $payment) { @@ -833,7 +841,11 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl */ protected function _debug($debugData) { - $this->logger->debug($debugData, $this->getDebugReplacePrivateDataKeys(), $this->getDebugFlag()); + $this->logger->debug( + $debugData, + $this->getDebugReplacePrivateDataKeys(), + $this->getDebugFlag() + ); } /** diff --git a/app/code/Magento/Payment/Model/Method/Logger.php b/app/code/Magento/Payment/Model/Method/Logger.php index 107de086bb90d5ed63e45850d082f67700fbc19f..7e7331b77df73d9f87624d733167eed0b9cdff08 100644 --- a/app/code/Magento/Payment/Model/Method/Logger.php +++ b/app/code/Magento/Payment/Model/Method/Logger.php @@ -15,38 +15,73 @@ use Psr\Log\LoggerInterface; class Logger { const DEBUG_KEYS_MASK = '****'; + /** * @var LoggerInterface */ protected $logger; + /** + * @var \Magento\Payment\Gateway\ConfigInterface + */ + private $config; + /** * @param LoggerInterface $logger + * @param \Magento\Payment\Gateway\ConfigInterface $config */ - public function __construct(LoggerInterface $logger) - { + public function __construct( + LoggerInterface $logger, + \Magento\Payment\Gateway\ConfigInterface $config = null + ) { $this->logger = $logger; + $this->config = $config; } /** * Logs payment related information used for debug * * @param array $debugData - * @param array $debugReplaceKeys - * @param bool $debugFlag + * @param array|null $debugReplaceKeys + * @param bool|null $debugFlag * @return void */ - public function debug(array $debugData, array $debugReplaceKeys, $debugFlag) + public function debug(array $debugData, array $debugReplaceKeys = null, $debugFlag = null) { - if ($debugFlag == true && !empty($debugData) && !empty($debugReplaceKeys)) { - $debugData = $this->filterDebugData( - $debugData, - $debugReplaceKeys - ); + $debugReplaceKeys = $debugReplaceKeys !== null ? $debugReplaceKeys : $this->getDebugReplaceFields(); + $debugFlag = $debugFlag !== null ? $debugFlag : $this->isDebugOn(); + if ($debugFlag === true && !empty($debugData) && !empty($debugReplaceKeys)) { + $debugData = $this->filterDebugData( + $debugData, + $debugReplaceKeys + ); $this->logger->debug(var_export($debugData, true)); } } + /** + * Returns configured keys to be replaced with mask + * + * @return array + */ + private function getDebugReplaceFields() + { + if ($this->config->getValue('debugReplaceKeys')) { + return explode(',', $this->config->getValue('debugReplaceKeys')); + } + return []; + } + + /** + * Whether debug is enabled in configuration + * + * @return bool + */ + private function isDebugOn() + { + return (bool)$this->config->getValue('debug'); + } + /** * Recursive filter data by private conventions * diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Command/CommandPoolTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Command/CommandPoolTest.php index e39384caf7849e52bef212c734d5f88f76aed083..92394d8bb330ed66ed9fb6dc98f49666fb725155 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Command/CommandPoolTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Command/CommandPoolTest.php @@ -13,9 +13,23 @@ class CommandPoolTest extends \PHPUnit_Framework_TestCase { $commandI = $this->getMockBuilder('Magento\Payment\Gateway\CommandInterface') ->getMockForAbstractClass(); + $tMapFactory = $this->getMockBuilder('Magento\Framework\ObjectManager\TMapFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') ->disableOriginalConstructor() ->getMock(); + + $tMapFactory->expects(static::once()) + ->method('create') + ->with( + [ + 'array' => ['Magento\Payment\Gateway\CommandInterface'], + 'type' => 'Magento\Payment\Gateway\CommandInterface' + ] + ) + ->willReturn($tMap); $tMap->expects(static::once()) ->method('offsetExists') ->with('command') @@ -25,7 +39,7 @@ class CommandPoolTest extends \PHPUnit_Framework_TestCase ->with('command') ->willReturn($commandI); - $pool = new CommandPool($tMap); + $pool = new CommandPool(['Magento\Payment\Gateway\CommandInterface'], $tMapFactory); static::assertSame($commandI, $pool->get('command')); } @@ -33,15 +47,30 @@ class CommandPoolTest extends \PHPUnit_Framework_TestCase public function testGetException() { $this->setExpectedException('Magento\Framework\Exception\NotFoundException'); + + $tMapFactory = $this->getMockBuilder('Magento\Framework\ObjectManager\TMapFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') ->disableOriginalConstructor() ->getMock(); + + $tMapFactory->expects(static::once()) + ->method('create') + ->with( + [ + 'array' => [], + 'type' => 'Magento\Payment\Gateway\CommandInterface' + ] + ) + ->willReturn($tMap); $tMap->expects(static::once()) ->method('offsetExists') ->with('command') ->willReturn(false); - $pool = new CommandPool($tMap); + $pool = new CommandPool([], $tMapFactory); $pool->get('command'); } } diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php index 849138ac08114dc69b17ba59f76aa98115080a03..9872e20250bbe2d34c5375f22cbac5916e69cf3a 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php @@ -16,36 +16,44 @@ class GatewayCommandTest extends \PHPUnit_Framework_TestCase protected $requestBuilderMock; /** - * @var \Magento\Payment\Gateway\Http\TransferBuilderInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Payment\Gateway\Http\TransferFactoryInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $transferBuilderMock; + protected $transferFactoryMock; /** * @var \Magento\Payment\Gateway\Http\ClientInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $gatewayMock; + protected $clientMock; /** * @var \Magento\Payment\Gateway\Response\HandlerInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $responseHandlerMock; + /** + * @var \Magento\Payment\Gateway\Validator\ValidatorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $validatorMock; + protected function setUp() { $this->requestBuilderMock = $this->getMockBuilder('Magento\Payment\Gateway\Request\BuilderInterface') ->getMockForAbstractClass(); - $this->transferBuilderMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\TransferBuilderInterface') + $this->transferFactoryMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\TransferFactoryInterface') ->getMockForAbstractClass(); - $this->gatewayMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\ClientInterface') + $this->clientMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\ClientInterface') ->getMockForAbstractClass(); $this->responseHandlerMock = $this->getMockBuilder('Magento\Payment\Gateway\Response\HandlerInterface') ->getMockForAbstractClass(); + $this->validatorMock = $this->getMockBuilder('Magento\Payment\Gateway\Validator\ValidatorInterface') + ->getMockForAbstractClass(); $this->model = new \Magento\Payment\Gateway\Command\GatewayCommand( $this->requestBuilderMock, - $this->transferBuilderMock, - $this->gatewayMock, - $this->responseHandlerMock + $this->transferFactoryMock, + $this->clientMock, + $this->responseHandlerMock, + $this->validatorMock ); } @@ -54,26 +62,35 @@ class GatewayCommandTest extends \PHPUnit_Framework_TestCase $commandSubject = ['authorize']; $request = ['request_field1' => 'request_value1', 'request_field2' => 'request_value2']; $response = ['response_field1' => 'response_value1']; + $validationResult = $this->getMockBuilder('Magento\Payment\Gateway\Validator\ResultInterface') + ->getMockForAbstractClass(); $transferO = $this->getMockBuilder('Magento\Payment\Gateway\Http\TransferInterface') ->getMockForAbstractClass(); - $this->requestBuilderMock->expects($this->once()) + $this->requestBuilderMock->expects(static::once()) ->method('build') ->with($commandSubject) ->willReturn($request); - $this->transferBuilderMock->expects($this->once()) - ->method('build') + $this->transferFactoryMock->expects(static::once()) + ->method('create') ->with($request) ->willReturn($transferO); - $this->gatewayMock->expects($this->once()) + $this->clientMock->expects(static::once()) ->method('placeRequest') ->with($transferO) ->willReturn($response); + $this->validatorMock->expects(static::once()) + ->method('validate') + ->with(array_merge($commandSubject, ['response' =>$response])) + ->willReturn($validationResult); + $validationResult->expects(static::once()) + ->method('isValid') + ->willReturn(true); - $this->responseHandlerMock->expects($this->once()) + $this->responseHandlerMock->expects(static::once()) ->method('handle') ->with($commandSubject, $response); diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Config/ValueHandlerPoolTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Config/ValueHandlerPoolTest.php index a10523f6496ce70ff9247ac11b89e7edf23d8101..266128b42f6f9ee21b26c83e5e3caf0187163998 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Config/ValueHandlerPoolTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Config/ValueHandlerPoolTest.php @@ -12,14 +12,14 @@ class ValueHandlerPoolTest extends \PHPUnit_Framework_TestCase public function testConstructorException() { $this->setExpectedException('LogicException'); - $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') + $tMapFactory = $this->getMockBuilder('Magento\Framework\ObjectManager\TMapFactory') ->disableOriginalConstructor() + ->setMethods(['create']) ->getMock(); - $tMap->expects(static::once()) - ->method('offsetExists') - ->with(ValueHandlerPool::DEFAULT_HANDLER) - ->willReturn(false); - new ValueHandlerPool($tMap); + + $tMapFactory->expects(static::never()) + ->method('create'); + new ValueHandlerPool([], $tMapFactory); } public function testGet() @@ -30,10 +30,27 @@ class ValueHandlerPoolTest extends \PHPUnit_Framework_TestCase $someValueHandler = $this->getMockBuilder('Magento\Payment\Gateway\Config\ValueHandlerInterface') ->disableOriginalConstructor() ->getMockForAbstractClass(); + $tMapFactory = $this->getMockBuilder('Magento\Framework\ObjectManager\TMapFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') ->disableOriginalConstructor() ->getMock(); - $tMap->expects(static::exactly(4)) + + $tMapFactory->expects(static::once()) + ->method('create') + ->with( + [ + 'array' => [ + ValueHandlerPool::DEFAULT_HANDLER => 'Magento\Payment\Gateway\Config\ValueHandlerInterface', + 'some_value' => 'Magento\Payment\Gateway\Config\ValueHandlerInterface' + ], + 'type' => 'Magento\Payment\Gateway\Config\ValueHandlerInterface' + ] + ) + ->willReturn($tMap); + $tMap->expects(static::exactly(3)) ->method('offsetExists') ->willReturnMap( [ @@ -50,7 +67,13 @@ class ValueHandlerPoolTest extends \PHPUnit_Framework_TestCase ] ); - $pool = new ValueHandlerPool($tMap); + $pool = new ValueHandlerPool( + [ + ValueHandlerPool::DEFAULT_HANDLER => 'Magento\Payment\Gateway\Config\ValueHandlerInterface', + 'some_value' => 'Magento\Payment\Gateway\Config\ValueHandlerInterface' + ], + $tMapFactory + ); static::assertSame($someValueHandler, $pool->get('some_value')); static::assertSame($defaultHandler, $pool->get(ValueHandlerPool::DEFAULT_HANDLER)); static::assertSame($defaultHandler, $pool->get('no_custom_logic_required')); diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Data/Order/AddressAdapterTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Data/Order/AddressAdapterTest.php index a31a859d54194ff9093018fef6c0d34d10fb199d..fc8ea141c1abe6641fd41caf6ea62cf74b90d200 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Data/Order/AddressAdapterTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Data/Order/AddressAdapterTest.php @@ -32,8 +32,8 @@ class AddressAdapterTest extends \PHPUnit_Framework_TestCase public function testGetRegion() { $expected = 'California'; - $this->orderAddressMock->expects($this->once())->method('getRegion')->willReturn($expected); - $this->assertEquals($expected, $this->model->getRegion()); + $this->orderAddressMock->expects($this->once())->method('getRegionCode')->willReturn($expected); + $this->assertEquals($expected, $this->model->getRegionCode()); } public function testGetCountryId() diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Data/Quote/AddressAdapterTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Data/Quote/AddressAdapterTest.php index 5674f0eba1c82adf6c6e812ee4079d2953625e58..84ad8947b35ec0c74b9fda544c7d1d7a2016a636 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Data/Quote/AddressAdapterTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Data/Quote/AddressAdapterTest.php @@ -32,8 +32,8 @@ class AddressAdapterTest extends \PHPUnit_Framework_TestCase public function testGetRegion() { $expected = 'California'; - $this->quoteAddressMock->expects($this->once())->method('getRegion')->willReturn($expected); - $this->assertEquals($expected, $this->model->getRegion()); + $this->quoteAddressMock->expects($this->once())->method('getRegionCode')->willReturn($expected); + $this->assertEquals($expected, $this->model->getRegionCode()); } public function testGetCountryId() diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php index ec6e6a3e04af5b6d5ceae94cc7bd46edad4d25b0..43f2a400ccd77100161afbd5596ddf4fdbc7b8b1 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php @@ -39,6 +39,11 @@ class ZendTest extends \PHPUnit_Framework_TestCase */ protected $transferObjectMock; + /** + * @var \Magento\Payment\Model\Method\Logger|\PHPUnit_Framework_MockObject_MockObject + */ + protected $loggerMock; + protected function setUp() { $this->converterMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\ConverterInterface') @@ -53,10 +58,14 @@ class ZendTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); + $this->loggerMock = $this->getMockBuilder('Magento\Payment\Model\Method\Logger') + ->disableOriginalConstructor() + ->getMock(); + $this->transferObjectMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\TransferInterface') ->getMockForAbstractClass(); - $this->model = new Zend($this->zendClientFactoryMock, $this->converterMock); + $this->model = new Zend($this->zendClientFactoryMock, $this->converterMock, $this->loggerMock); } public function testPlaceRequest() @@ -136,7 +145,7 @@ class ZendTest extends \PHPUnit_Framework_TestCase $this->transferObjectMock->expects($this->once())->method('getClientConfig')->willReturn($config); $this->transferObjectMock->expects($this->atLeastOnce())->method('getMethod')->willReturn($method); $this->transferObjectMock->expects($this->once())->method('getHeaders')->willReturn($headers); - $this->transferObjectMock->expects($this->once())->method('getBody')->willReturn($body); + $this->transferObjectMock->expects($this->atLeastOnce())->method('getBody')->willReturn($body); $this->transferObjectMock->expects($this->once())->method('shouldEncode')->willReturn($shouldEncode); $this->transferObjectMock->expects($this->once())->method('getUri')->willReturn($uri); diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Converter/HtmlFormConverterTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Converter/HtmlFormConverterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8f2792fe4b92bddc5b59b1320c52858c294193b9 --- /dev/null +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Converter/HtmlFormConverterTest.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Test\Unit\Gateway\Http\Converter; + +use Magento\Payment\Gateway\Http\Converter\HtmlFormConverter; + +class HtmlFormConverterTest extends \PHPUnit_Framework_TestCase +{ + public function testConvert() + { + $expectedResult = [ + 'parameter1' => 'val1', + 'parameter2' => 'val2', + 'parameter3' => 'val3' + ]; + + $converter = new HtmlFormConverter(); + static::assertEquals($expectedResult, $converter->convert($this->getValidFormHtml())); + } + + public function testConvertNotValidHtml() + { + $converter = new HtmlFormConverter(); + $converter->convert('Not html. Really not.'); + } + + /** + * Returns valid form HTML + * + * @return string + */ + private function getValidFormHtml() + { + return ' + <!DOCTYPE HTML> + <html> + <head> + <meta charset="utf-8"> + <title>Title</title> + </head> + <body> + + <form action="some"> + <p><input type="radio" name="parameter1" value="val1">val1<Br> + <input type="radio" name="parameter2" value="val2">val2<Br> + <input type="radio" name="parameter3" value="val3">val3</p> + <p><input type="submit"></p> + </form> + + </body> + </html> + '; + } +} diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Http/TransferTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Http/TransferTest.php new file mode 100644 index 0000000000000000000000000000000000000000..bdecd39bc83feffd20bcb00f45cc62115cb3622c --- /dev/null +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Http/TransferTest.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Test\Unit\Gateway\Http; + +use Magento\Payment\Gateway\Http\Transfer; + +class TransferTest extends \PHPUnit_Framework_TestCase +{ + public function testIO() + { + $clientConfig = ['config']; + $headers = ['Header']; + $body = ['data', 'data2']; + $method = 'POST'; + $uri = 'https://gateway.com'; + $encode = false; + + $transfer = new Transfer( + $clientConfig, + $headers, + $body, + $method, + $uri, + $encode + ); + + static::assertSame($clientConfig, $transfer->getClientConfig()); + static::assertSame($headers, $transfer->getHeaders()); + static::assertSame($body, $transfer->getBody()); + static::assertSame($method, $transfer->getMethod()); + static::assertSame($uri, $transfer->getUri()); + static::assertSame($encode, $transfer->shouldEncode()); + } +} diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Request/BuilderCompositeTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Request/BuilderCompositeTest.php index 39d9339d2d93402eee7865cd31b946dfd1097ac3..e1e5ea547456a76f23629322b483718b5cf98e61 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Request/BuilderCompositeTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Request/BuilderCompositeTest.php @@ -11,13 +11,28 @@ class BuilderCompositeTest extends \PHPUnit_Framework_TestCase { public function testBuildEmpty() { + $tMapFactory = $this->getMockBuilder('Magento\Framework\ObjectManager\TMapFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') ->disableOriginalConstructor() ->getMock(); + + $tMapFactory->expects(static::once()) + ->method('create') + ->with( + [ + 'array' => [], + 'type' => 'Magento\Payment\Gateway\Request\BuilderInterface' + ] + ) + ->willReturn($tMap); $tMap->expects(static::once()) ->method('getIterator') ->willReturn(new \ArrayIterator([])); - $builder = new BuilderComposite($tMap); + + $builder = new BuilderComposite([], $tMapFactory); static::assertEquals([], $builder->build([])); } @@ -27,12 +42,18 @@ class BuilderCompositeTest extends \PHPUnit_Framework_TestCase 'user' => 'Mrs G. Crump', 'url' => 'https://url.in', 'amount' => 10.00, - 'currecy' => 'pound', + 'currency' => 'pound', 'address' => '46 Egernon Crescent', 'item' => 'gas cooker', 'quantity' => 1 ]; - + $tMapFactory = $this->getMockBuilder('Magento\Framework\ObjectManager\TMapFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') + ->disableOriginalConstructor() + ->getMock(); $customerBuilder = $this->getMockBuilder('Magento\Payment\Gateway\Request\BuilderInterface') ->getMockForAbstractClass(); $productBuilder = $this->getMockBuilder('Magento\Payment\Gateway\Request\BuilderInterface') @@ -53,7 +74,7 @@ class BuilderCompositeTest extends \PHPUnit_Framework_TestCase ->willReturn( [ 'amount' => 10.00, - 'currecy' => 'pound', + 'currency' => 'pound', 'item' => 'gas cooker', 'quantity' => 1 ] @@ -66,14 +87,31 @@ class BuilderCompositeTest extends \PHPUnit_Framework_TestCase ] ); - $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') - ->disableOriginalConstructor() - ->getMock(); + $tMapFactory->expects(static::once()) + ->method('create') + ->with( + [ + 'array' => [ + 'customer' => 'Magento\Payment\Gateway\Request\BuilderInterface', + 'product' => 'Magento\Payment\Gateway\Request\BuilderInterface', + 'magento' => 'Magento\Payment\Gateway\Request\BuilderInterface' + ], + 'type' => 'Magento\Payment\Gateway\Request\BuilderInterface' + ] + ) + ->willReturn($tMap); $tMap->expects(static::once()) ->method('getIterator') ->willReturn(new \ArrayIterator([$customerBuilder, $productBuilder, $magentoBuilder])); - $builder = new BuilderComposite($tMap); + $builder = new BuilderComposite( + [ + 'customer' => 'Magento\Payment\Gateway\Request\BuilderInterface', + 'product' => 'Magento\Payment\Gateway\Request\BuilderInterface', + 'magento' => 'Magento\Payment\Gateway\Request\BuilderInterface' + ], + $tMapFactory + ); static::assertEquals($expectedRequest, $builder->build([])); } diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Response/HandlerChainTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Response/HandlerChainTest.php index 716fe3246ae1d8fa17f6d051e1babd42ddf2779e..c65a826a2624d79adff61fac919ce47385fac6ac 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Response/HandlerChainTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Response/HandlerChainTest.php @@ -15,10 +15,26 @@ class HandlerChainTest extends \PHPUnit_Framework_TestCase ->getMockForAbstractClass(); $handler2 = $this->getMockBuilder('Magento\Payment\Gateway\Response\HandlerInterface') ->getMockForAbstractClass(); - + $tMapFactory = $this->getMockBuilder('Magento\Framework\ObjectManager\TMapFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') ->disableOriginalConstructor() ->getMock(); + + $tMapFactory->expects(static::once()) + ->method('create') + ->with( + [ + 'array' => [ + 'handler1' => 'Magento\Payment\Gateway\Response\HandlerInterface', + 'handler2' => 'Magento\Payment\Gateway\Response\HandlerInterface' + ], + 'type' => 'Magento\Payment\Gateway\Response\HandlerInterface' + ] + ) + ->willReturn($tMap); $tMap->expects(static::once()) ->method('getIterator') ->willReturn(new \ArrayIterator([$handler1, $handler2])); @@ -32,7 +48,13 @@ class HandlerChainTest extends \PHPUnit_Framework_TestCase ->method('handle') ->with($handlingSubject, $response); - $chain = new HandlerChain($tMap); + $chain = new HandlerChain( + [ + 'handler1' => 'Magento\Payment\Gateway\Response\HandlerInterface', + 'handler2' => 'Magento\Payment\Gateway\Response\HandlerInterface' + ], + $tMapFactory + ); $chain->handle($handlingSubject, $response); } } diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Validator/ValidatorCompositeTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Validator/ValidatorCompositeTest.php index 9150e83f0e7363cee65f589cbb8980728f7ac580..8528b65ac6cecf91bd5603009334a0b47f216137 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Validator/ValidatorCompositeTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Validator/ValidatorCompositeTest.php @@ -16,10 +16,26 @@ class ValidatorCompositeTest extends \PHPUnit_Framework_TestCase ->getMockForAbstractClass(); $validator2 = $this->getMockBuilder('Magento\Payment\Gateway\Validator\ValidatorInterface') ->getMockForAbstractClass(); - + $tMapFactory = $this->getMockBuilder('Magento\Framework\ObjectManager\TMapFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') ->disableOriginalConstructor() ->getMock(); + + $tMapFactory->expects(static::once()) + ->method('create') + ->with( + [ + 'array' => [ + 'validator1' => 'Magento\Payment\Gateway\Validator\ValidatorInterface', + 'validator2' => 'Magento\Payment\Gateway\Validator\ValidatorInterface' + ], + 'type' => 'Magento\Payment\Gateway\Validator\ValidatorInterface' + ] + ) + ->willReturn($tMap); $tMap->expects(static::once()) ->method('getIterator') ->willReturn(new \ArrayIterator([$validator1, $validator2])); @@ -64,7 +80,14 @@ class ValidatorCompositeTest extends \PHPUnit_Framework_TestCase ->willReturn($compositeResult); - $validatorComposite = new ValidatorComposite($resultFactory, $tMap); + $validatorComposite = new ValidatorComposite( + $resultFactory, + [ + 'validator1' => 'Magento\Payment\Gateway\Validator\ValidatorInterface', + 'validator2' => 'Magento\Payment\Gateway\Validator\ValidatorInterface' + ], + $tMapFactory + ); static::assertSame($compositeResult, $validatorComposite->validate($validationSubject)); } } diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Validator/ValidatorPoolTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Validator/ValidatorPoolTest.php index c48aca93d6e370462cce2ce0824c5d3927baef56..becc387fab2d91b86cc6ba3b13954c8c0c29ae05 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Validator/ValidatorPoolTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Validator/ValidatorPoolTest.php @@ -16,6 +16,20 @@ class ValidatorPoolTest extends \PHPUnit_Framework_TestCase $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') ->disableOriginalConstructor() ->getMock(); + $tMapFactory = $this->getMockBuilder('Magento\Framework\ObjectManager\TMapFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $tMapFactory->expects(static::once()) + ->method('create') + ->with( + [ + 'array' => ['validator' => 'Magento\Payment\Gateway\Validator\ValidatorInterface'], + 'type' => 'Magento\Payment\Gateway\Validator\ValidatorInterface' + ] + ) + ->willReturn($tMap); $tMap->expects(static::once()) ->method('offsetExists') ->with('validator') @@ -25,7 +39,10 @@ class ValidatorPoolTest extends \PHPUnit_Framework_TestCase ->with('validator') ->willReturn($commandI); - $pool = new ValidatorPool($tMap); + $pool = new ValidatorPool( + ['validator' => 'Magento\Payment\Gateway\Validator\ValidatorInterface'], + $tMapFactory + ); static::assertSame($commandI, $pool->get('validator')); } @@ -33,15 +50,30 @@ class ValidatorPoolTest extends \PHPUnit_Framework_TestCase public function testGetException() { $this->setExpectedException('Magento\Framework\Exception\NotFoundException'); + + $tMapFactory = $this->getMockBuilder('Magento\Framework\ObjectManager\TMapFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); $tMap = $this->getMockBuilder('Magento\Framework\ObjectManager\TMap') ->disableOriginalConstructor() ->getMock(); + + $tMapFactory->expects(static::once()) + ->method('create') + ->with( + [ + 'array' => [], + 'type' => 'Magento\Payment\Gateway\Validator\ValidatorInterface' + ] + ) + ->willReturn($tMap); $tMap->expects(static::once()) ->method('offsetExists') ->with('validator') ->willReturn(false); - $pool = new ValidatorPool($tMap); + $pool = new ValidatorPool([], $tMapFactory); $pool->get('validator'); } } diff --git a/app/code/Magento/Payment/etc/payment.xml b/app/code/Magento/Payment/etc/payment.xml index b034e1695e0641056899daeaddb112e4bc47c454..5560a70f11b325ea8d12a85ec5fd2582b29593f1 100644 --- a/app/code/Magento/Payment/etc/payment.xml +++ b/app/code/Magento/Payment/etc/payment.xml @@ -32,5 +32,17 @@ <type id="OT" order="1000"> <label>Other</label> </type> + <type id="DN" order="60"> + <label>Diners</label> + </type> + <type id="JC" order="70"> + <label>JCB</label> + </type> + <type id="MI" order="80"> + <label>Maestro International</label> + </type> + <type id="MD" order="100"> + <label>Maestro Domestic</label> + </type> </credit_cards> </payment> diff --git a/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml b/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml index e9632aa0f89155238a8a659b660687a2bc4ce743..c6a429a0fbe08f624c53f03d7998879281dfde27 100644 --- a/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml +++ b/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml @@ -22,6 +22,7 @@ $code = $block->getMethodCode(); "cardFieldsMap":<?php echo $block->getCardFieldsMap() ?>, "orderSaveUrl":"<?php echo $block->getOrderUrl() ?>", "cgiUrl":"<?php echo $block->getCgiUrl() ?>", + "expireYearLength":"<?php echo $block->getMethodConfigData('cc_year_length') ?>", "nativeAction":"<?php echo $block->getUrl('*/*/save', ['_secure' => $block->getRequest()->isSecure()]) ?>" }, "validation":[]}' style="display:none;"> diff --git a/app/code/Magento/Payment/view/adminhtml/web/transparent.js b/app/code/Magento/Payment/view/adminhtml/web/transparent.js index 1317880d7f062c08ebe1c1fee96be951796b1a53..7edbb30c6318ffd45339c6b55b3b612067f76b62 100644 --- a/app/code/Magento/Payment/view/adminhtml/web/transparent.js +++ b/app/code/Magento/Payment/view/adminhtml/web/transparent.js @@ -23,7 +23,8 @@ define([ controller: null, gateway: null, dateDelim: null, - cardFieldsMap: null + cardFieldsMap: null, + expireYearLength: 2 }, _create: function() { @@ -52,6 +53,9 @@ define([ */ _orderSave: function() { var postData = "form_key="+FORM_KEY; + postData += '&cc_type=' + this.element.find( + '[data-container="' + this.options.gateway + '-cc-type"]' + ).val(); $.ajax({ url: this.options.orderSaveUrl, type: 'post', @@ -135,8 +139,8 @@ define([ this.element.find('[data-container="' + this.options.gateway + '-cc-month"]').val() , 10 ); - if (year.length > 2) { - year = year.substring(2); + if (year.length > this.options.expireYearLength) { + year = year.substring(year.length - this.options.expireYearLength); } if (month < 10) { month = '0' + month; diff --git a/app/code/Magento/Payment/view/frontend/web/js/view/review/actions/iframe.js b/app/code/Magento/Payment/view/frontend/web/js/view/review/actions/iframe.js index a5a78d731cfeac57b02fc28ff488534ea733a1cd..5349dab7b4d93202a4dec1f9924de97d0c564645 100644 --- a/app/code/Magento/Payment/view/frontend/web/js/view/review/actions/iframe.js +++ b/app/code/Magento/Payment/view/frontend/web/js/view/review/actions/iframe.js @@ -39,6 +39,9 @@ define( }, originalPlaceOrder: function(parent) { return parent.placeOrder.bind(parent); + }, + getExpireYearLength: function(parent) { + return window.checkoutConfig.payment.iframe.expireYearLength[this.getCode()]; } }); } diff --git a/app/code/Magento/Payment/view/frontend/web/template/review/actions/iframe.html b/app/code/Magento/Payment/view/frontend/web/template/review/actions/iframe.html index cd9c3342c733f9cd2f4cf3e656b533ccb7b5e655..df5212f51e03f9a2b54332ca117c38d7abb0d5ba 100644 --- a/app/code/Magento/Payment/view/frontend/web/template/review/actions/iframe.html +++ b/app/code/Magento/Payment/view/frontend/web/template/review/actions/iframe.html @@ -14,7 +14,8 @@ 'cgiUrl': getCgiUrl(), 'dateDelim': getDateDelim(), 'cardFieldsMap': getCardFieldsMap(), - 'nativeAction': getSaveOrderUrl() + 'nativeAction': getSaveOrderUrl(), + 'expireYearLength': getExpireYearLength() }, 'validation':[]}"> <!-- ko with: getCcFormView() --> <!-- ko template: getTemplate() --><!-- /ko --> diff --git a/app/code/Magento/Payment/view/frontend/web/transparent.js b/app/code/Magento/Payment/view/frontend/web/transparent.js index 570772d6d430c67d6dcd4ea10325fade6d3407b0..6394cf38fee739a4667b1845efc4e11f4582b913 100644 --- a/app/code/Magento/Payment/view/frontend/web/transparent.js +++ b/app/code/Magento/Payment/view/frontend/web/transparent.js @@ -28,7 +28,8 @@ define([ controller: null, gateway: null, dateDelim: null, - cardFieldsMap: null + cardFieldsMap: null, + expireYearLength: 2 }, _create: function() { @@ -60,6 +61,10 @@ define([ postData += '&' + $(this.options.reviewAgreementForm).serialize(); } postData += '&controller=' + this.options.controller; + postData += '&cc_type=' + this.element.find( + '[data-container="' + this.options.gateway + '-cc-type"]' + ).val(); + $.ajax({ url: this.options.orderSaveUrl, type: 'post', @@ -140,9 +145,10 @@ define([ this.element.find('[data-container="' + this.options.gateway + '-cc-month"]').val(), 10 ); - if (year.length > 2) { - year = year.substring(2); + if (year.length > this.options.expireYearLength) { + year = year.substring(year.length - this.options.expireYearLength); } + if (month < 10) { month = '0' + month; } diff --git a/app/code/Magento/Quote/Api/Data/CartInterface.php b/app/code/Magento/Quote/Api/Data/CartInterface.php index 64eb62f72a2a7590ecd9decc93d7fdeae5033576..a663618a0b81fba68dca3b123ee9f0b43466e243 100644 --- a/app/code/Magento/Quote/Api/Data/CartInterface.php +++ b/app/code/Magento/Quote/Api/Data/CartInterface.php @@ -54,6 +54,8 @@ interface CartInterface extends \Magento\Framework\Api\ExtensibleDataInterface const KEY_CUSTOMER_TAX_CLASS_ID = 'customer_tax_class_id'; + const KEY_STORE_ID = 'store_id'; + /**#@-*/ /** @@ -350,6 +352,21 @@ interface CartInterface extends \Magento\Framework\Api\ExtensibleDataInterface */ public function setCustomerTaxClassId($customerTaxClassId); + /** + * Get store identifier + * + * @return int + */ + public function getStoreId(); + + /** + * Sets store identifier + * + * @param int $storeId + * @return $this + */ + public function setStoreId($storeId); + /** * Retrieve existing extension attributes object or create a new one. * diff --git a/app/code/Magento/Quote/Model/BillingAddressManagement.php b/app/code/Magento/Quote/Model/BillingAddressManagement.php index 193232fdb2571c685440e5a6e18542ea37a17c92..c710b56797f9008902381457c7f9719967e805ea 100644 --- a/app/code/Magento/Quote/Model/BillingAddressManagement.php +++ b/app/code/Magento/Quote/Model/BillingAddressManagement.php @@ -67,6 +67,7 @@ class BillingAddressManagement implements BillingAddressManagementInterface public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address, $useForShipping = false) { $quote = $this->quoteRepository->getActive($cartId); + $this->addressValidator->validate($address); $customerAddressId = $address->getCustomerAddressId(); $shippingAddress = null; diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php index 95fa91f6c6c5c29de29ac69cdb491cacef11ee76..2dd5c4ca3add051bb7c518b939e8a1011e098a10 100644 --- a/app/code/Magento/Quote/Model/Quote.php +++ b/app/code/Magento/Quote/Model/Quote.php @@ -28,7 +28,6 @@ use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; * sales_quote_delete_before * sales_quote_delete_after * - * @method Quote setStoreId(int $value) * @method int getIsMultiShipping() * @method Quote setIsMultiShipping(int $value) * @method float getStoreToBaseRate() @@ -687,16 +686,23 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C //@codeCoverageIgnoreEnd /** - * Get quote store identifier - * - * @return int + * {@inheritdoc} */ public function getStoreId() { if (!$this->hasStoreId()) { return $this->_storeManager->getStore()->getId(); } - return $this->_getData('store_id'); + return (int)$this->_getData(self::KEY_STORE_ID); + } + + /** + * {@inheritdoc} + */ + public function setStoreId($storeId) + { + $this->setData(self::KEY_STORE_ID, (int)$storeId); + return $this; } /** diff --git a/app/code/Magento/Quote/Model/Quote/Payment.php b/app/code/Magento/Quote/Model/Quote/Payment.php index bb98b0d85ca3ac9d216eddcfac9a52f661249c4b..04f583d1c25b950c9cc5bc24b65cdaca9ee08233 100644 --- a/app/code/Magento/Quote/Model/Quote/Payment.php +++ b/app/code/Magento/Quote/Model/Quote/Payment.php @@ -5,6 +5,8 @@ */ namespace Magento\Quote\Model\Quote; +use Magento\Payment\Model\Method\AbstractMethod; + /** * Quote payment information * @@ -209,7 +211,7 @@ class Payment extends \Magento\Payment\Model\Info implements \Magento\Quote\Api\ public function getOrderPlaceRedirectUrl() { $method = $this->getMethodInstance(); - if ($method) { + if ($method && $method instanceof AbstractMethod) { return $method->getOrderPlaceRedirectUrl(); } return ''; diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php index 872cfa989fbdaf24a559265014aa37c6f650de5b..04e919863d29a21a350fd731ccecfe4ed0db00ed 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php @@ -133,7 +133,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); - $this->storeMock->expects($this->once())->method('getId')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); $this->quoteMock->expects($this->once()) ->method('load') @@ -150,7 +150,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); - $this->storeMock->expects($this->once())->method('getId')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); $this->quoteMock->expects($this->once()) ->method('load') @@ -169,7 +169,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); - $this->storeMock->expects($this->once())->method('getId')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->once()) ->method('setSharedStoreIds') ->with($sharedStoreIds) @@ -191,7 +191,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); - $this->storeMock->expects($this->once())->method('getId')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); $this->quoteMock->expects($this->once()) ->method('loadByCustomer') @@ -213,7 +213,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); - $this->storeMock->expects($this->once())->method('getId')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); $this->quoteMock->expects($this->once()) ->method('load') @@ -235,7 +235,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); - $this->storeMock->expects($this->once())->method('getId')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); $this->quoteMock->expects($this->once()) ->method('load') @@ -253,7 +253,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); - $this->storeMock->expects($this->once())->method('getId')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); $this->quoteMock->expects($this->once()) ->method('load') @@ -273,7 +273,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); - $this->storeMock->expects($this->once())->method('getId')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->once()) ->method('setSharedStoreIds') ->with($sharedStoreIds) @@ -296,7 +296,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); - $this->storeMock->expects($this->once())->method('getId')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); $this->quoteMock->expects($this->once()) ->method('loadByCustomer') diff --git a/app/code/Magento/Sales/Api/Data/OrderAddressInterface.php b/app/code/Magento/Sales/Api/Data/OrderAddressInterface.php index dfd663234daec616b0e77161aed4f89ae858bd5f..3b319b82613c61da32995e744fc8210ded8670a2 100644 --- a/app/code/Magento/Sales/Api/Data/OrderAddressInterface.php +++ b/app/code/Magento/Sales/Api/Data/OrderAddressInterface.php @@ -35,6 +35,10 @@ interface OrderAddressInterface extends \Magento\Framework\Api\ExtensibleDataInt * Region ID. */ const REGION_ID = 'region_id'; + /** + * Region code. + */ + const KEY_REGION_CODE = 'region_code'; /* * Customer ID. */ @@ -247,6 +251,13 @@ interface OrderAddressInterface extends \Magento\Framework\Api\ExtensibleDataInt */ public function getRegion(); + /** + * Gets the region code for the order address + * + * @return string|null Region code. + */ + public function getRegionCode(); + /** * Gets the region ID for the order address. * @@ -494,6 +505,14 @@ interface OrderAddressInterface extends \Magento\Framework\Api\ExtensibleDataInt */ public function setVatRequestId($id); + /** + * Set region code + * + * @param string $regionCode + * @return $this + */ + public function setRegionCode($regionCode); + /** * Sets the VAT request date for the order address. * diff --git a/app/code/Magento/Sales/Model/Order/Address.php b/app/code/Magento/Sales/Model/Order/Address.php index 9486d6e0fb34b74714d5e102c6d1bb1a289c48ab..2ffcb048799e6f7b5f7456487e4cc20cff95d922 100644 --- a/app/code/Magento/Sales/Model/Order/Address.php +++ b/app/code/Magento/Sales/Model/Order/Address.php @@ -702,6 +702,14 @@ class Address extends AbstractModel implements OrderAddressInterface, AddressMod return $this->setData(OrderAddressInterface::VAT_REQUEST_ID, $id); } + /** + * {@inheritdoc} + */ + public function setRegionCode($regionCode) + { + return $this->setData(OrderAddressInterface::KEY_REGION_CODE, $regionCode); + } + /** * {@inheritdoc} */ diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php index b190aee7f88acc5bd18af6e1f986472dd6c35627..9bc08c21c00f0379c39d9061b6da22eacb7488d5 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php @@ -7,6 +7,8 @@ */ namespace Magento\Test\Integrity; +use Magento\Framework\App\Utility\Classes; + class ClassesTest extends \PHPUnit_Framework_TestCase { /** @@ -31,7 +33,7 @@ class ClassesTest extends \PHPUnit_Framework_TestCase */ function ($file) { $contents = file_get_contents($file); - $classes = \Magento\Framework\App\Utility\Classes::getAllMatches( + $classes = Classes::getAllMatches( $contents, '/ # ::getResourceModel ::getBlockSingleton ::getModel ::getSingleton @@ -57,7 +59,7 @@ class ClassesTest extends \PHPUnit_Framework_TestCase ); // without modifier "i". Starting from capital letter is a significant characteristic of a class name - \Magento\Framework\App\Utility\Classes::getAllMatches( + Classes::getAllMatches( $contents, '/(?:\-> | parent\:\:)(?:_init | setType)\(\s* \'([A-Z][a-z\d][A-Za-z\d\\\\]+)\'(?:,\s*\'([A-Z][a-z\d][A-Za-z\d\\\\]+)\') @@ -82,7 +84,7 @@ class ClassesTest extends \PHPUnit_Framework_TestCase protected function _collectResourceHelpersPhp($contents, &$classes) { $regex = '/(?:\:\:|\->)getResourceHelper\(\s*\'([a-z\d\\\\]+)\'\s*\)/ix'; - $matches = \Magento\Framework\App\Utility\Classes::getAllMatches($contents, $regex); + $matches = Classes::getAllMatches($contents, $regex); foreach ($matches as $moduleName) { $classes[] = "{$moduleName}\\Model\\Resource\\Helper\\Mysql4"; } @@ -96,7 +98,7 @@ class ClassesTest extends \PHPUnit_Framework_TestCase * @param string $path */ function ($path) { - $classes = \Magento\Framework\App\Utility\Classes::collectClassesInConfig(simplexml_load_file($path)); + $classes = Classes::collectClassesInConfig(simplexml_load_file($path)); $this->_assertClassesExist($classes, $path); }, \Magento\Framework\App\Utility\Files::init()->getMainConfigFiles() @@ -113,26 +115,26 @@ class ClassesTest extends \PHPUnit_Framework_TestCase function ($path) { $xml = simplexml_load_file($path); - $classes = \Magento\Framework\App\Utility\Classes::getXmlNodeValues( + $classes = Classes::getXmlNodeValues( $xml, '/layout//*[contains(text(), "\\\\Block\\\\") or contains(text(), "\\\\Model\\\\") or contains(text(), "\\\\Helper\\\\")]' ); - foreach (\Magento\Framework\App\Utility\Classes::getXmlAttributeValues( + foreach (Classes::getXmlAttributeValues( $xml, '/layout//@helper', 'helper' ) as $class) { - $classes[] = \Magento\Framework\App\Utility\Classes::getCallbackClass($class); + $classes[] = Classes::getCallbackClass($class); } - foreach (\Magento\Framework\App\Utility\Classes::getXmlAttributeValues( + foreach (Classes::getXmlAttributeValues( $xml, '/layout//@module', 'module' ) as $module) { $classes[] = str_replace('_', '\\', "{$module}_Helper_Data"); } - $classes = array_merge($classes, \Magento\Framework\App\Utility\Classes::collectLayoutClasses($xml)); + $classes = array_merge($classes, Classes::collectLayoutClasses($xml)); $this->_assertClassesExist(array_unique($classes), $path); }, @@ -159,7 +161,7 @@ class ClassesTest extends \PHPUnit_Framework_TestCase $badUsages = []; foreach ($classes as $class) { try { - if (strrchr($class, '\\') == false) { + if (strrchr($class, '\\') === false and !Classes::isVirtual($class)) { $badUsages[] = $class; continue; } else { @@ -168,9 +170,9 @@ class ClassesTest extends \PHPUnit_Framework_TestCase self::$_existingClasses[$class] ) || \Magento\Framework\App\Utility\Files::init()->classFileExists( $class - ) || \Magento\Framework\App\Utility\Classes::isVirtual( + ) || Classes::isVirtual( $class - ) || \Magento\Framework\App\Utility\Classes::isAutogenerated( + ) || Classes::isAutogenerated( $class ) ); diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/ConfigTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/ConfigTest.php index 58d662260d8271730806151c01eba88e356a7b0a..6b439124a3238ac31ad21fa1e2b341c3c0be460a 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/ConfigTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/ConfigTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Test\Integrity; +use Magento\Framework\App\Utility\Classes; + class ConfigTest extends \PHPUnit_Framework_TestCase { public function testPaymentMethods() @@ -19,12 +21,14 @@ class ConfigTest extends \PHPUnit_Framework_TestCase $nodes = $config->xpath('/config/default/payment/*/model') ?: []; $formalModuleName = str_replace('_', '\\', $moduleName); foreach ($nodes as $node) { - $this->assertStringStartsWith( - $formalModuleName . '\Model\\', - (string)$node, - "'{$node}' payment method is declared in '{$configFile}' module, " . - "but doesn't belong to '{$moduleName}' module" - ); + if (!Classes::isVirtual((string)$node)) { + $this->assertStringStartsWith( + $formalModuleName . '\Model\\', + (string)$node, + "'{$node}' payment method is declared in '{$configFile}' module, " . + "but doesn't belong to '{$moduleName}' module" + ); + } } }, $this->paymentMethodsDataProvider() diff --git a/lib/internal/Magento/Framework/Intl/DateTimeFactory.php b/lib/internal/Magento/Framework/Intl/DateTimeFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..089dc90170965d0a32eb46bd9196001ccebd997a --- /dev/null +++ b/lib/internal/Magento/Framework/Intl/DateTimeFactory.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Intl; + +/** + * Class DateTimeFactory + * @package Magento\Framework + */ +class DateTimeFactory +{ + /** + * Factory method for \DateTime + * + * @param string $time + * @param \DateTimeZone $timezone + * @return \DateTime + */ + public function create($time = 'now', \DateTimeZone $timezone = null) + { + return new \DateTime($time, $timezone); + } +} diff --git a/lib/internal/Magento/Framework/Intl/README.md b/lib/internal/Magento/Framework/Intl/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7257506ebe47cde86a94a0166e8599fbdd2b39dc --- /dev/null +++ b/lib/internal/Magento/Framework/Intl/README.md @@ -0,0 +1,3 @@ +# Intl + +**Intl** provides an access to Intl extension library wrappers. diff --git a/lib/internal/Magento/Framework/ObjectManager/TMap.php b/lib/internal/Magento/Framework/ObjectManager/TMap.php index 759ed739d624497ce65ee5e2678b4d9cbe3c99a0..b15b87ed467203a7b5c9be009408e5fdbfe219da 100644 --- a/lib/internal/Magento/Framework/ObjectManager/TMap.php +++ b/lib/internal/Magento/Framework/ObjectManager/TMap.php @@ -44,24 +44,16 @@ class TMap implements \IteratorAggregate, \Countable, \ArrayAccess */ private $configInterface; - /** - * @var ClassReaderInterface - */ - private $classReaderInterface; - - /** * @param string $type * @param ObjectManagerInterface $objectManager * @param ConfigInterface $configInterface - * @param ClassReaderInterface $classReaderInterface * @param array $array */ public function __construct( $type, ObjectManagerInterface $objectManager, ConfigInterface $configInterface, - ClassReaderInterface $classReaderInterface, array $array = [] ) { if (!class_exists($this->type) && !interface_exists($type)) { @@ -72,7 +64,6 @@ class TMap implements \IteratorAggregate, \Countable, \ArrayAccess $this->objectManager = $objectManager; $this->configInterface = $configInterface; - $this->classReaderInterface = $classReaderInterface; array_walk( $array, @@ -99,7 +90,12 @@ class TMap implements \IteratorAggregate, \Countable, \ArrayAccess $this->configInterface->getPreference($instanceName) ); - if (!in_array($this->type, $this->classReaderInterface->getParents($realType), true)) { + if ( + !in_array( + $this->type, + array_unique(array_merge(class_parents($realType), class_implements($realType))), + true + )) { $this->throwTypeException($realType, $index); } } diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/TMapTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/TMapTest.php index 6ce188335d8c6aa1f9e8dba25addacfb2d116847..4e599bd2356dbe77f1e748733e3496822c59376c 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/TMapTest.php +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/TMapTest.php @@ -22,11 +22,6 @@ class TMapTest extends \PHPUnit_Framework_TestCase */ private $omConfig; - /** - * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Code\Reader\ClassReaderInterface - */ - private $cReader; - public function setUp() { $this->om = $this->getMockBuilder('Magento\Framework\ObjectManagerInterface') @@ -34,9 +29,6 @@ class TMapTest extends \PHPUnit_Framework_TestCase $this->omConfig = $this->getMockBuilder('Magento\Framework\ObjectManager\ConfigInterface') ->getMockForAbstractClass(); - - $this->cReader = $this->getMockBuilder('Magento\Framework\Code\Reader\ClassReaderInterface') - ->getMockForAbstractClass(); } public function testConstructor() @@ -154,19 +146,10 @@ class TMapTest extends \PHPUnit_Framework_TestCase ] ); - $this->cReader->expects(static::exactly($exactlyCalls)) - ->method('getParents') - ->willReturnMap( - [ - ['TClass', ['TInterface']] - ] - ); - return new TMap( 'TInterface', $this->om, $this->omConfig, - $this->cReader, $testClasses ); } diff --git a/lib/internal/Magento/Framework/View/Element/Template.php b/lib/internal/Magento/Framework/View/Element/Template.php index a7f4b683343f87bdda4c73305a248ea92b6d81c6..8e1c8e4cb27946799946680b342aff3ae78949df 100644 --- a/lib/internal/Magento/Framework/View/Element/Template.php +++ b/lib/internal/Magento/Framework/View/Element/Template.php @@ -7,7 +7,6 @@ namespace Magento\Framework\View\Element; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Filesystem; -use Magento\Framework\View\Template\Html\Minifier; /** * Base html block