diff --git a/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml b/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml index c6dd0ce00e6be2f18ee5d5385a43c7de54a83016..6c02076b5a7dbe55d9a81b7114599221c6c9f14e 100644 --- a/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml +++ b/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml @@ -5,7 +5,6 @@ */ // @codingStandardsIgnoreFile - /** * @var \Magento\Authorizenet\Block\Transparent\Iframe $block * @see \Magento\Authorizenet\Block\Transparent\Iframe @@ -24,10 +23,12 @@ $ccExpYear = $block->getInfoData('cc_exp_year'); src="<?php /* @noEscape */ echo $block->getViewFileUrl('blank.html'); ?>"> </iframe> <!-- IFRAME for request to Authorize.net --> -<iframe id="directpost-iframe" allowtransparency="true" frameborder="0" name="iframeDirectPost" style="display:none;width:100%;background-color:transparent" +<iframe id="directpost-iframe" allowtransparency="true" frameborder="0" name="iframeDirectPost" + style="display:none;width:100%;background-color:transparent" src="<?php /* @noEscape */ echo $block->getViewFileUrl('blank.html'); ?>"> </iframe> -<fieldset class="admin__fieldset payment-method" id="payment_form_<?php /* @noEscape */ echo $code; ?>" style="display:none;"> +<fieldset class="admin__fieldset payment-method" id="payment_form_<?php /* @noEscape */ echo $code; ?>" + style="display:none;"> <div class="admin__field _required"> <label for="<?php /* @noEscape */ echo $code; ?>_cc_type" class="admin__field-label"> <span><?php echo $block->escapeHtml(__('Credit Card Type')); ?></span> @@ -81,11 +82,11 @@ $ccExpYear = $block->getInfoData('cc_exp_year'); <?php if ($k == $ccExpYear): ?>selected="selected"<?php endif; ?>> <?php echo $block->escapeHtml($v); ?> </option> - <?php endforeach ?> + <?php endforeach; ?> </select> </div> </div> - <?php if ($_form->hasVerification()): ?> + <?php if ($block->hasVerification()): ?> <div class="admin__field _required"> <label for="<?php /* @noEscape */ echo $code; ?>_cc_cid"> <span><?php echo $block->escapeHtml(__('Card Verification Number')); ?></span> @@ -123,7 +124,9 @@ $ccExpYear = $block->getInfoData('cc_exp_year'); '<?php /* @noEscape */ echo $controller; ?>', '<?php /* @noEscape */ echo $orderUrl; ?>', '<?php echo $block->escapeUrl($method->getCgiUrl()); ?>', - '<?php /* @noEscape */ echo $block->getUrl('*/*/save', ['_secure' => $block->getRequest()->isSecure()]) ?>'); + '<?php /* @noEscape */ echo $block->getUrl('*/*/save', [ + '_secure' => $block->getRequest()->isSecure() + ]);?>'); <?php if (!$block->isAjaxRequest()): ?> }); diff --git a/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js index cb58db6d1d5a00283a2d87461dbac55272121dad..bf6978cfa365c38700830a02dcff602881af509d 100644 --- a/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js +++ b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js @@ -50,9 +50,8 @@ define( placeOrder: function () { var self = this; - fullScreenLoader.startLoader(); - if (this.validateHandler() && additionalValidators.validate()) { + fullScreenLoader.startLoader(); this.isPlaceOrderActionAllowed(false); $.when(setPaymentInformationAction(this.messageContainer, { 'method': self.getCode() diff --git a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml index ddd9fa5f2f18ae565d365c090d2ad2c8dd35f55a..3fbc198921448e9b6994db3d7358bbd185ae1e28 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml @@ -255,6 +255,12 @@ $numColumns = sizeof($block->getColumns()); deps.push('mage/adminhtml/grid'); + <?php if (is_array($block->getRequireJsDependencies())): ?> + <?php foreach ($block->getRequireJsDependencies() as $dependency): ?> + deps.push('<?php /* @escapeNotVerified */ echo $dependency; ?>'); + <?php endforeach; ?> + <?php endif; ?> + require(deps, function(<?php echo ($block->getDependencyJsObject() ? 'registry' : '') ?>){ <?php //TODO: getJsObjectName and getRowClickCallback has unexpected behavior. Should be removed ?> diff --git a/app/code/Magento/Braintree/etc/frontend/di.xml b/app/code/Magento/Braintree/etc/frontend/di.xml index ddc18722e8df532bf34fb3e30b4122e24e4e8445..83dc6607ed3160f5719646521ffcb74b8a822c34 100644 --- a/app/code/Magento/Braintree/etc/frontend/di.xml +++ b/app/code/Magento/Braintree/etc/frontend/di.xml @@ -21,4 +21,11 @@ </argument> </arguments> </type> + <type name="Magento\Framework\Url\SecurityInfo"> + <arguments> + <argument name="secureUrlList" xsi:type="array"> + <item name="braintree" xsi:type="string">/braintree/</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Braintree/view/adminhtml/templates/data_js.phtml b/app/code/Magento/Braintree/view/adminhtml/templates/data_js.phtml index cbfe3dcda5f9f52c183a7382e9cf4c33d5a50811..70634e81b0992114ed262c1781c46dd5c4f1fb07 100644 --- a/app/code/Magento/Braintree/view/adminhtml/templates/data_js.phtml +++ b/app/code/Magento/Braintree/view/adminhtml/templates/data_js.phtml @@ -7,21 +7,20 @@ /** * @var $block \Magento\Braintree\Block\Datajs */ -?> -<?php + $arrayData = [ "kountId" => $this->helper('Magento\Braintree\Helper\Data')->getKountId() ? $this->helper('Magento\Braintree\Helper\Data')->getKountId() : false, "formId" =>$block->getFormId(), "merchantId" => $block->getMerchantId(), - "braintreeDataJs" => $block->getJsSrc(), + "braintreeDataJs" => $block->escapeUrl($block->getJsSrc()), ]; $serializedFormData = $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($arrayData); ?> <script type="text/x-magento-init"> { "body": { - "braintreeDataJs": <?php /* @escapeNotVerified */ echo $serializedFormData ?> + "braintreeDataJs": <?php /* @noEscape */ echo $serializedFormData ?> } } </script> diff --git a/app/code/Magento/Braintree/view/adminhtml/templates/form.phtml b/app/code/Magento/Braintree/view/adminhtml/templates/form.phtml index f13f2d77b1c086e288bf87d21556e231f379c0b8..c27901cd4e8704fc7fdf044e47b8cc40db1a7e40 100644 --- a/app/code/Magento/Braintree/view/adminhtml/templates/form.phtml +++ b/app/code/Magento/Braintree/view/adminhtml/templates/form.phtml @@ -7,110 +7,143 @@ // @codingStandardsIgnoreFile /** @var \Magento\Braintree\Block\Form $block */ -$_form = $block; -$_code = $_form->getMethodCode(); -$_storedCards = $this->helper('\Magento\Braintree\Helper\Createorder')->getLoggedInCustomerCards(); -$_useVault = $block->useVault(); -$_useCvv = $block->useCvv(); -$clientToken = $block->getClientToken(); +$code = $block->getMethodCode(); +$storedCards = $this->helper('\Magento\Braintree\Helper\Createorder')->getLoggedInCustomerCards(); +$useVault = $block->useVault(); +$useCvv = $block->useCvv(); +$clientToken = $block->escapeHtml($block->getClientToken()); $isFraudDetectionEnabled = $block->isFraudDetectionEnabled(); $braintreeDataJs = $block->getBraintreeDataJs(); $formData = [ - "useVault" => $_useVault, - "useCvv" => $_useCvv, + "useVault" => $useVault, + "useCvv" => $useCvv, "clientToken" => $clientToken, - "code" => $_code, + "code" => $code, "isFraudDetectionEnabled" => $isFraudDetectionEnabled, "braintreeDataJs"=> $braintreeDataJs, ]; $serializedFormData = $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($formData); +$ccType = $block->getInfoData('cc_type'); +$ccExpMonth = $block->getInfoData('cc_exp_month'); +$ccExpYear = $block->getInfoData('cc_exp_year'); ?> -<input id="<?php /* @escapeNotVerified */ echo $_code ?>_payment_method" type="hidden" name="payment[method]" value="<?php /* @escapeNotVerified */ echo $_code ?>" /> -<div id="payment_form_<?php /* @escapeNotVerified */ echo $_code ?>" class="admin__page-section-item" style="display:none;" - data-mage-init='{"braintreeCcForm":<?php /* @escapeNotVerified */ echo $serializedFormData ?>}' +<input id="<?php /* @noEscape */ echo $code; ?>_payment_method" type="hidden" name="payment[method]" + value="<?php /* @noEscape */ echo $code; ?>" /> +<div id="payment_form_<?php /* @noEscape */ echo $code; ?>" class="admin__page-section-item" style="display:none;" + data-mage-init='{"braintreeCcForm":<?php /* @noEscape */ echo $serializedFormData; ?>}' > <input type="hidden" name="payment[payment_method_nonce]" id="braintree_nonce" value="" /> <input type="hidden" name="payment[cc_last4]" id="cc_last4" value="" /> <?php if ($isFraudDetectionEnabled): ?> - <input type="hidden" name="payment[device_data]" id="braintree_device_id" value="" /> + <input type="hidden" name="payment[device_data]" id="braintree_device_id" value="" /> <?php endif; ?> - <?php if ($_storedCards): ?> - <fieldset class="admin__fieldset"> - <div class="admin__field" id="<?php /* @escapeNotVerified */ echo $_code ?>_token_selector"> - <label class="admin__field-label" for="<?php /* @escapeNotVerified */ echo $_code ?>_cc_token"><?php /* @escapeNotVerified */ echo __('Payment Information') ?></label> - <div class="admin__field-control control"> - <select id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_token" name="payment[cc_token]" class="select admin__control-select"> - <?php foreach ($_storedCards as $creditCard): ?> - <option value="<?php /* @escapeNotVerified */ echo $creditCard->token?>" <?php echo $creditCard->default ? 'selected="selected"' : '' ?>> - <?php /* @escapeNotVerified */ echo $creditCard->maskedNumber . ' - ' . $creditCard->cardType ?> - </option> - <?php endforeach; ?> - <option value=''><?php /* @escapeNotVerified */ echo __('Add new card') ?></option> - </select> + <?php if ($storedCards): ?> + <fieldset class="admin__fieldset"> + <div class="admin__field" id="<?php /* @noEscape */ echo $code; ?>_token_selector"> + <label class="admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_cc_token"> + <?php echo $block->escapeHtml(__('Payment Information')); ?> + </label> + <div class="admin__field-control control"> + <select id="<?php /* @noEscape */ echo $code; ?>_cc_token" name="payment[cc_token]" + class="select admin__control-select"> + <?php foreach ($storedCards as $creditCard): ?> + <option value="<?php echo $block->escapeHtml($creditCard->token); ?>" + <?php /* @noEscape */ echo $creditCard->default ? ' selected="selected"' : ''; ?>> + <?php echo $block->escapeHtml($creditCard->maskedNumber); ?> - <?php echo $block->escapeHtml($creditCard->cardType); ?> + </option> + <?php endforeach; ?> + <option value=''><?php echo $block->escapeHtml(__('Add new card')); ?></option> + </select> + </div> </div> - </div> - </fieldset> + </fieldset> <?php endif; ?> <fieldset class="admin__fieldset hide_if_token_selected"> <div class="admin__field"> - <label class="label admin__field-label" for="<?php /* @escapeNotVerified */ echo $_code ?>_cc_type" ><?php /* @escapeNotVerified */ echo __('Credit Card Type') ?><span class="required">*</span></label> + <label class="label admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_cc_type" > + <?php echo $block->escapeHtml(__('Credit Card Type')); ?><span class="required">*</span> + </label> <div class="admin__field-control control"> - <select id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_type" name="payment[cc_type]" class="required-entry _required select admin__control-select validate-cc-type-select"> - <option value="">--<?php /* @escapeNotVerified */ echo __('Please Select')?>--</option> - <?php $_ccType = $_form->getInfoData('cc_type') ?> - <?php foreach ($_form->getCcAvailableTypes() as $_typeCode => $_typeName): ?> - <option value="<?php /* @escapeNotVerified */ echo $_typeCode ?>"<?php if($_typeCode==$_ccType): ?> selected="selected"<?php endif ?>><?php /* @escapeNotVerified */ echo $_typeName ?></option> - <?php endforeach ?> + <select id="<?php /* @noEscape */ echo $code; ?>_cc_type" name="payment[cc_type]" + class="required-entry _required select admin__control-select validate-cc-type-select"> + <option value="">--<?php echo $block->escapeHtml(__('Please Select')); ?>--</option> + <?php foreach ($block->getCcAvailableTypes() as $typeCode => $typeName): ?> + <option value="<?php echo $block->escapeHtml($typeCode); ?>" + <?php if($typeCode == $ccType): ?> selected="selected"<?php endif; ?>> + <?php echo $block->escapeHtml($typeName); ?> + </option> + <?php endforeach; ?> </select> </div> </div> </fieldset> <fieldset class="admin__fieldset hide_if_token_selected"> <div class="admin__field"> - <label class="label admin__field-label" for="<?php /* @escapeNotVerified */ echo $_code ?>_cc_number"><?php /* @escapeNotVerified */ echo __('Credit Card Number') ?><span class="required">*</span></label> + <label class="label admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_cc_number"> + <?php echo $block->escapeHtml(__('Credit Card Number')); ?><span class="required">*</span> + </label> <div class="admin__field-control control"> - <input type="text" id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_number" data-encrypted-name="payment[cc_number]" title="<?php /* @escapeNotVerified */ echo __('Credit Card Number') ?>" class="input-text admin__control-text validate-cc-number validate-cc-type" value="" /> + <input type="text" id="<?php /* @noEscape */ echo $code; ?>_cc_number" data-encrypted-name="payment[cc_number]" + title="<?php echo $block->escapeHtml(__('Credit Card Number')); ?>" + class="input-text admin__control-text validate-cc-number validate-cc-type" value="" /> </div> </div> </fieldset> <fieldset class="admin__fieldset hide_if_token_selected"> - <div id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_type_exp_div" class="admin__field"> - <label class="label admin__field-label" for="<?php /* @escapeNotVerified */ echo $_code ?>_expiration" ><?php /* @escapeNotVerified */ echo __('Expiration Date') ?><span class="required">*</span></label> + <div id="<?php /* @noEscape */ echo $code; ?>_cc_type_exp_div" class="admin__field"> + <label class="label admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_expiration"> + <?php echo $block->escapeHtml(__('Expiration Date')); ?><span class="required">*</span> + </label> <div class="admin__field-control control"> - <select id="<?php /* @escapeNotVerified */ echo $_code ?>_expiration" name="payment[cc_exp_month]" class="month validate-cc-exp required-entry _required select admin__control-select"> - <?php $_ccExpMonth = $_form->getInfoData('cc_exp_month') ?> - <?php foreach ($_form->getCcMonths() as $k=>$v): ?> - <option value="<?php echo $k?$k:'' ?>"<?php if($k==$_ccExpMonth): ?> selected="selected"<?php endif ?>><?php /* @escapeNotVerified */ echo $v ?></option> - <?php endforeach ?> + <select id="<?php /* @noEscape */ echo $code; ?>_expiration" name="payment[cc_exp_month]" + class="month validate-cc-exp required-entry _required select admin__control-select"> + <?php foreach ($block->getCcMonths() as $k=>$v): ?> + <option value="<?php /* @noEscape */ echo $k ? $block->escapeHtml($k) : ''; ?>" + <?php if ($k == $ccExpMonth): ?> selected="selected"<?php endif; ?>> + <?php echo $block->escapeHtml($v); ?></option> + <?php endforeach; ?> </select> - <?php $_ccExpYear = $_form->getInfoData('cc_exp_year') ?> - <select id="<?php /* @escapeNotVerified */ echo $_code ?>_expiration_yr" name="payment[cc_exp_year]" class="year required-entry _required select admin__control-select"> - <?php foreach ($_form->getCcYears() as $k=>$v): ?> - <option value="<?php echo $k?$k:'' ?>"<?php if($k==$_ccExpYear): ?> selected="selected"<?php endif ?>><?php /* @escapeNotVerified */ echo $v ?></option> + <select id="<?php /* @noEscape */ echo $code; ?>_expiration_yr" name="payment[cc_exp_year]" + class="year required-entry _required select admin__control-select"> + <?php foreach ($block->getCcYears() as $k => $v): ?> + <option value="<?php /* @noEscape */ echo $k ? $block->escapeHtml($k) : ''; ?>" + <?php if ($k == $ccExpYear): ?> selected="selected"<?php endif; ?>> + <?php echo $block->escapeHtml($v); ?> + </option> <?php endforeach ?> </select> </div> </div> </fieldset> - <?php echo $_form->getChildHtml() ?> - <?php if($_form->hasVerification()): ?> - <fieldset class="admin__fieldset hide_if_token_selected"> - <div id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_type_cvv_div" class="admin__field"> - <label class="label admin__field-label" for="<?php /* @escapeNotVerified */ echo $_code ?>_cc_cid" ><?php /* @escapeNotVerified */ echo __('Card Verification Number') ?><span class="required">*</span></label> - <div class="admin__field-control control"> - <div class="v-fix"> - <input type="text" title="<?php /* @escapeNotVerified */ echo __('Card Verification Number') ?>" class="input-text admin__control-text cvv required-entry validate-cc-cvn" id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_cid" data-encrypted-name="payment[cc_cid]" value="" /> + <?php echo $block->getChildHtml(); ?> + <?php if ($block->hasVerification()): ?> + <fieldset class="admin__fieldset hide_if_token_selected"> + <div id="<?php /* @noEscape */ echo $code; ?>_cc_type_cvv_div" class="admin__field"> + <label class="label admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_cc_cid"> + <?php echo $block->escapeHtml(__('Card Verification Number')); ?><span class="required">*</span> + </label> + + <div class="admin__field-control control"> + <div class="v-fix"> + <input type="text" title="<?php echo $block->escapeHtml(__('Card Verification Number')); ?>" + class="input-text admin__control-text cvv required-entry validate-cc-cvn" + id="<?php /* @noEscape */ echo $code; ?>_cc_cid" data-encrypted-name="payment[cc_cid]" value=""/> + </div> </div> </div> - </div> - </fieldset> + </fieldset> <?php endif; ?> <?php if($_useVault): ?> - <fieldset class="admin__fieldset hide_if_token_selected"> - <div id="<?php /* @escapeNotVerified */ echo $_code ?>_store_in_vault_div" style="text-align:left;" class=""> - <input type="checkbox" title="<?php /* @escapeNotVerified */ echo __('Save this card for future use') ?>" class="input-checkbox" id="<?php /* @escapeNotVerified */ echo $_code ?>_store_in_vault" name="payment[store_in_vault]" value="1" /> - <label for="<?php /* @escapeNotVerified */ echo $_code ?>_store_in_vault" style="float:none;"><?php /* @escapeNotVerified */ echo __('Save this card for future use') ?></label> - </div> - </fieldset> + <fieldset class="admin__fieldset hide_if_token_selected"> + <div id="<?php /* @noEscape */ echo $code; ?>_store_in_vault_div" style="text-align:left;" class=""> + <input type="checkbox" title="<?php echo $block->escapeHtml(__('Save this card for future use')); ?>" + class="input-checkbox" id="<?php /* @noEscape */ echo $code; ?>_store_in_vault" + name="payment[store_in_vault]" value="1"/> + <label for="<?php /* @noEscape */ echo $code; ?>_store_in_vault" style="float:none;"> + <?php echo $block->escapeHtml(__('Save this card for future use')); ?> + + </label> + </div> + </fieldset> <?php endif; ?> </div> \ No newline at end of file diff --git a/app/code/Magento/Braintree/view/frontend/templates/creditcard/delete.phtml b/app/code/Magento/Braintree/view/frontend/templates/creditcard/delete.phtml index b9011bdd4f54e009622789aa2992d42cd89f1fe9..cba8e56e5aa3366172f42663999757bfce6b5448 100644 --- a/app/code/Magento/Braintree/view/frontend/templates/creditcard/delete.phtml +++ b/app/code/Magento/Braintree/view/frontend/templates/creditcard/delete.phtml @@ -6,46 +6,54 @@ // @codingStandardsIgnoreFile - $creditCard = $block->creditCard(); - $token = $creditCard->token; +/** + * @var \Magento\Braintree\Block\Creditcard\Management $block + */ +$creditCard = $block->creditCard(); +$token = $block->escapeHtml($creditCard->token); ?> <?php echo $block->getLayout()->getMessagesBlock()->getGroupedHtml();?> -<form action="<?php /* @escapeNotVerified */ echo $block->getDeleteConfirmUrl() ?>" method="post" id="delete-form" +<form action="<?php echo $block->escapeUrl($block->getDeleteConfirmUrl()); ?>" method="post" id="delete-form" xmlns="http://www.w3.org/1999/html"> <fieldset class="fieldset info"> - <legend class="legend"><?php /* @escapeNotVerified */ echo __('Please confirm that you want to delete this credit card') ?></legend> + <legend class="legend"> + <?php echo $block->escapeHtml(__('Please confirm that you want to delete this credit card')); ?> + </legend> <div class="field"> <ul> <li> - <b><?php /* @escapeNotVerified */ echo __('Credit Card Number');?></b> + <b><?php echo $block->escapeHtml(__('Credit Card Number'));?></b> </li> <li> - <?php /* @escapeNotVerified */ echo $creditCard->maskedNumber;?> + <?php echo $block->escapeHtml($creditCard->maskedNumber);?> </li> <li> - <b><?php /* @escapeNotVerified */ echo __('Expiration Date');?></b> + <b><?php echo $block->escapeHtml(__('Expiration Date'));?></b> </li> <li> - <?php /* @escapeNotVerified */ echo $creditCard->expirationDate; ?> + <?php echo $block->escapeHtml($creditCard->expirationDate); ?> </li> <li> - <b><?php /* @escapeNotVerified */ echo __('Cardholder Name');?></b> + <b><?php echo $block->escapeHtml(__('Cardholder Name'));?></b> </li> <li> - <?php /* @escapeNotVerified */ echo $creditCard->cardholderName;?> + <?php echo $block->escapeHtml($creditCard->cardholderName);?> </li> </ul> </div> </fieldset> - <input type="hidden" name="token" value="<?php /* @escapeNotVerified */ echo $token ?>"> + <input type="hidden" name="token" value="<?php /* @noEscape */ echo $token; ?>"> <div class="actions-toolbar"> <div class="primary"> <button type="submit" id="opc-submit" data-role="opc-submit" class="action save primary" - title="<?php /* @escapeNotVerified */ echo __('Delete') ?>" ><?php /* @escapeNotVerified */ echo __('Delete') ?></span></button> + title="<?php echo $block->escapeHtml(__('Delete')); ?>" > + <?php echo $block->escapeHtml(__('Delete')); ?> + </button> </div> <div class="secondary"> - <a class="action back" href="<?php /* @escapeNotVerified */ echo $block->getBackUrl() ?>"><span><span><small>« </small> - <?php /* @escapeNotVerified */ echo __('Back') ?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()); ?>"> + <span><small>« </small><?php echo $block->escapeHtml(__('Back')); ?></span> + </a> </div> </div> diff --git a/app/code/Magento/Braintree/view/frontend/templates/creditcard/edit.phtml b/app/code/Magento/Braintree/view/frontend/templates/creditcard/edit.phtml index 073009c4c6eb6de718c3d85c41270ebedfedfa85..6fcac2eae9c411929472c7b79ef1038836646183 100644 --- a/app/code/Magento/Braintree/view/frontend/templates/creditcard/edit.phtml +++ b/app/code/Magento/Braintree/view/frontend/templates/creditcard/edit.phtml @@ -53,21 +53,37 @@ if ($block->isEditMode()) { $defaultPostalCode = ''; $defaultCountryCodeAlpha2 = ''; } +$streetValidationClass = $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('street'); +$default = $defaultCountryCodeAlpha2; + +$clientToken = $block->getClientToken(); +$formData = [ + "clientToken" => $clientToken, + 'ajaxSaveUrl' => $block->escapeUrl($block->getAjaxSaveUrl()), + 'isEditMode' => $block->isEditMode() ? true : false, + 'cardToken' => $block->isEditMode() ? $block->escapeHtml($creditCard->token) : '', + 'backUrl' => $block->escapeUrl($block->getBackUrl()), + 'hasVerification' => $block->hasVerification(), + "countrySpecificCardTypes" => $countrySpecificCardTypeConfig, + "applicableCardTypes" => $applicableCardTypeConfig, + "cardTypes" => $block->getCcAvailableTypes(), + "isFraudDetectionEnabled" => $block->isFraudDetectionEnabled() +]; +$serializedFormData = $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($formData); ?> <form - class="form form-edit-credit-card" - action='<?php /* @escapeNotVerified */ echo $block->getFormAction() ?>' + class="form form-edit-credit-card" action="<?php echo $block->escapeUrl($block->getFormAction()); ?>" method="post" id="form-validate" data-mage-init='{"validation":{}}'> <?php echo $block->getBlockHtml('formkey'); ?> - <fieldset class="fieldset info" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"> + <fieldset class="fieldset info" data-hasrequired="<?php echo $block->escapeHtml(__('* Required Fields')); ?>"> <legend class="legend"> - <span><?php /* @escapeNotVerified */ echo __('Credit Card') ?></span> + <span><?php echo $block->escapeHtml(__('Credit Card')); ?></span> </legend> <br> <div class="field name required"> <label for="credit_card_cardholder_name" class="label"> - <span><?php /* @escapeNotVerified */ echo __('Cardholder Name') ?></span> + <span><?php echo $block->escapeHtml(__('Cardholder Name')); ?></span> </label> <div class="control"> @@ -75,40 +91,32 @@ if ($block->isEditMode()) { type="text" class="input-text required-entry" id="credit_card_cardholder_name" - value="<?php /* @escapeNotVerified */ echo $defaultCardholder ?>" + value="<?php echo $block->escapeHtml($defaultCardholder); ?>" data-validate="{required:true}"> </div> </div> <div class="field required type"> <label for="credit_card_type" class="label"> - <span><?php /* @escapeNotVerified */ echo __('Credit Card Type') ?></span> + <span><?php echo $block->escapeHtml(__('Credit Card Type')); ?></span> </label> <div class="control"> <select name="credit_card_type" id="credit_card_type" data-container="credit_card_type" data-validate='{required:true, "validate-cc-type-select":"#credit_card_number"}'> - <option value=""><?php /* @escapeNotVerified */ echo __('--Please Select--') ?></option> - <?php - foreach ($block->getCcAvailableTypes() as $_typeCode => $_typeName) : - ?> - <option value="<?php /* @escapeNotVerified */ echo $_typeCode ?>" - <?php - if (stripos($_typeName, $defaultCcType) !== false) : - ?> selected="selected" - <?php - endif; - ?>> - <?php /* @escapeNotVerified */ echo $_typeName ?> + <option value=""><?php echo $block->escapeHtml(__('--Please Select--')); ?></option> + <?php foreach ($block->getCcAvailableTypes() as $typeCode => $typeName): ?> + <option value="<?php echo $block->escapeHtml($typeCode); ?>" + <?php if (stripos($typeName, $defaultCcType) !== false): ?> selected="selected"<?php endif; ?>> + <?php echo $block->escapeHtml($typeName); ?> </option> - <?php - endforeach; + <?php endforeach; ?> </select> </div> </div> <div class="field name required"> - <label for="credit_card_number" class="label"><span> - <?php /* @escapeNotVerified */ echo __('Credit Card Number') ?></span> + <label for="credit_card_number" class="label"> + <span><?php echo $block->escapeHtml(__('Credit Card Number')); ?></span> </label> <div class="control"> @@ -118,19 +126,13 @@ if ($block->isEditMode()) { class="input-text required-entry validate-cc-number" id="credit_card_number" autocomplete="off" - <?php - if ($block->isEditMode()) : - ?> - placeholder="<?php /* @escapeNotVerified */ echo $maskedNumber ?>" - <?php - endif; - ?> + <?php if ($block->isEditMode()): ?> placeholder="<?php echo $block->escapeHtml($maskedNumber); ?>"<?php endif; ?> data-validate="{'required-number':true, 'validate-cc-number':'#credit_card_number', 'validate-cc-type':'#credit_card_type'}"> </div> </div> <div class="field sp-methods required"> <label for="credit_card_expiration_date" class="label"> - <span><?php /* @escapeNotVerified */ echo __('Expiration Date') ?></span> + <span><?php echo $block->escapeHtml(__('Expiration Date')); ?></span> </label> <div class="control"> @@ -143,14 +145,12 @@ if ($block->isEditMode()) { id="credit_card_expiration" class="month validate-cc-exp required-entry" data-validate="{'required-number':true, 'validate-cc-exp':'#credit_card_expiration_yr'}"> - <?php - foreach ($block->getCcMonths() as $k => $v) : - ?> - <option - value="<?php echo $k ? $k : '' ?>"<?php if ($k == $defaultExpMonth) : ?> selected="selected"<?php endif ?>><?php /* @escapeNotVerified */ echo $v ?></option> - <?php - endforeach; - ?> + <?php foreach ($block->getCcMonths() as $k => $v): ?> + <option value="<?php /* @noEscape */ echo $k ? $block->escapeHtml($k) : '' ?>" + <?php if ($k == $defaultExpMonth): ?> selected="selected"<?php endif; ?>> + <?php echo $block->escapeHtml($v); ?> + </option> + <?php endforeach; ?> </select> </div> </div> @@ -163,22 +163,12 @@ if ($block->isEditMode()) { id="credit_card_expiration_yr" class="year required-entry" data-validate="{required:true}"> - <?php - foreach ($block->getCcYears() as $k => $v) : - ?> - <option - value="<?php echo $k ? $k : ''; ?>" - <?php - if ($k == $defaultExpYear) : - ?> selected="selected" - <?php - endif; - ?>> - <?php /* @escapeNotVerified */ echo $v ?> + <?php foreach ($block->getCcYears() as $k => $v): ?> + <option value="<?php /* @noEscape */ echo $k ? $k : ''; ?>" + <?php if ($k == $defaultExpYear): ?> selected="selected"<?php endif; ?>> + <?php echo $block->escapeHtml($v); ?> </option> - <?php - endforeach; - ?> + <?php endforeach; ?> </select> </div> </div> @@ -189,13 +179,13 @@ if ($block->isEditMode()) { <?php if ($block->hasVerification()): ?> <div class="field sp-methods required"> <label for="credit_card_cvv" class="label"> - <span><?php /* @escapeNotVerified */ echo __('CVV') ?></span> + <span><?php echo $block->escapeHtml(__('CVV')); ?></span> </label> <div class="control"> <input type="text" - title="<?php /* @escapeNotVerified */ echo __('Card Verification Number') ?>" + title="<?php echo $block->escapeHtml(__('Card Verification Number')); ?>" class="input-text cvv required-entry validate-cc-cvn validate-cc-cvn-autodetect" name="credit_card_cvv" data-container="credit_card_cvv" @@ -203,14 +193,14 @@ if ($block->isEditMode()) { value="" autocomplete="off" data-validate="{'required-number':true, 'validate-cc-cvn':'#credit_card_type'}"> - <?php $_content = '<img src=\"' . $block->getViewFileUrl('Magento_Checkout::cvv.png') . - '\" alt=\"' . __('Card Verification Number Visual Reference') . '\" title=\"' . - __('Card Verification Number Visual Reference') . '\" />'; ?> + <?php $content = '<img src=\"' . $block->escapeUrl($block->getViewFileUrl('Magento_Checkout::cvv.png')) . + '\" alt=\"' . $block->escapeHtml(__('Card Verification Number Visual Reference')) . '\" title=\"' . + $block->escapeHtml(__('Card Verification Number Visual Reference')) . '\" />'; ?> <div class="note"> <a href="#" id="credit_card-cvv-what-is-this" class="action cvv" title="<?php echo $block->escapeHtml(__('What is this?')); ?>" - data-mage-init='{"tooltip": {"content": "<?php /* @escapeNotVerified */ echo $_content ?>"}}'> - <span><?php /* @escapeNotVerified */ echo __('What is this?') ?></span> + data-mage-init='{"tooltip": {"content": "<?php /* @noEscape */ echo $content; ?>"}}'> + <span><?php echo $block->escapeHtml(__('What is this?')); ?></span> </a> </div> </div> @@ -224,58 +214,61 @@ if ($block->isEditMode()) { <div class="control"> <input type="checkbox" name="credit_card[options][make_default]" id="credit_card_options_make_default" - value="1" <?php /* @escapeNotVerified */ echo $isCCDefault ? "checked" : "" ?>> + value="1" <?php /* @noEscape */ echo $isCCDefault ? "checked" : "" ?>> <label for="credit_card_options_make_default" class="label"> - <span><?php /* @escapeNotVerified */ echo __('Make Default') ?></span> + <span><?php echo $block->escapeHtml(__('Make Default')); ?></span> </label> </div> </div> </fieldset> <fieldset class="fieldset info"> <legend class="legend"> - <span><?php /* @escapeNotVerified */ echo __('Billing Address') ?></span> + <span><?php echo $block->escapeHtml(__('Billing Address')); ?></span> </legend> <div class="field name billing_address_first_name required"> <label for="billing_address_first_name" class="label"> - <span><?php /* @escapeNotVerified */ echo __('First Name') ?></span> + <span><?php echo $block->escapeHtml(__('First Name')); ?></span> </label> <div class="control"> <input type="text" class="input-text required-entry " name="credit_card[billing_address][first_name]" id="billing_address_first_name" - value="<?php /* @escapeNotVerified */ echo $defaultFirstName ?>" + value="<?php echo $block->escapeHtml($defaultFirstName); ?>" data-validate="{required:true}"> </div> </div> <div class="field name billing_address_last_name required"> - <label for="billing_address_last_name" class="label"><span><?php /* @escapeNotVerified */ echo __('Last Name') ?></span></label> + <label for="billing_address_last_name" class="label"> + <span><?php echo $block->escapeHtml(__('Last Name')); ?></span> + </label> <div class="control"> <input type="text" class="input-text required-entry " name="credit_card[billing_address][last_name]" id="billing_address_last_name" - value="<?php /* @escapeNotVerified */ echo $defaultLastName ?>" + value="<?php echo $block->escapeHtml($defaultLastName); ?>" data-validate="{required:true}"> </div> </div> <div class="field name billing_address_company"> - <label for="billing_address_company" class="label"><span><?php /* @escapeNotVerified */ echo __('Company') ?></span></label> + <label for="billing_address_company" class="label"> + <span><?php echo $block->escapeHtml(__('Company')); ?></span> + </label> <div class="control"> <input type="text" class="input-text " name="credit_card[billing_address][company]" id="billing_address_company" - value="<?php /* @escapeNotVerified */ echo $defaultCompany ?>"> + value="<?php echo $block->escapeHtml($defaultCompany); ?>"> </div> </div> - <?php $_streetValidationClass = $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('street'); ?> <div class="field name billing_address_street_address required"> <label for="billing_address_street_address" class="label"> - <span><?php /* @escapeNotVerified */ echo __('Address') ?></span> + <span><?php echo $block->escapeHtml(__('Address')); ?></span> </label> <div class="control"> <input type="text" class="input-text required-entry " name="credit_card[billing_address][street_address]" id="billing_address_street_address" - value="<?php /* @escapeNotVerified */ echo $defaultStreetAddress ?>" + value="<?php echo $block->escapeHtml($defaultStreetAddress); ?>" data-validate="{required:true}"> </div> </div> @@ -287,95 +280,78 @@ if ($block->isEditMode()) { <div class="control"> <input type="text" class="input-text " name="credit_card[billing_address][extended_address]" id="billing_address_extended_address" - value="<?php /* @escapeNotVerified */ echo $defaultExtendedAddress ?>"> + value="<?php echo $block->escapeHtml($defaultExtendedAddress); ?>"> </div> </div> <div class="field name billing_address_locality required"> <label for="billing_address_locality" class="label"> - <span><?php /* @escapeNotVerified */ echo __('City') ?></span> + <span><?php echo $block->escapeHtml(__('City')); ?></span> </label> <div class="control"> <input type="text" class="input-text required-entry " name="credit_card[billing_address][locality]" id="billing_address_locality" - value="<?php /* @escapeNotVerified */ echo $defaultLocality ?>" + value="<?php echo $block->escapeHtml($defaultLocality); ?>" data-validate="{required:true}"> </div> </div> <div class="field region billing_address_region required"> <label for="billing_address_region" class="label"> - <span><?php /* @escapeNotVerified */ echo __('State/Province') ?></span> + <span><?php echo $block->escapeHtml(__('State/Province')); ?></span> </label> <div class="control"> <select id="billing_address_region_id" name="credit_card[billing_address][region_id]" - title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" class="validate-select" style="display:none;" + title="<?php echo $block->escapeHtml(__('State/Province')); ?>" class="validate-select" style="display:none;" data-validate="{'validate-select':true}"> - <option value=""><?php /* @escapeNotVerified */ echo __('Please select region, state or province') ?></option> + <option value=""><?php echo $block->escapeHtml(__('Please select region, state or province')); ?></option> </select> <input type="text" class="input-text " name="credit_card[billing_address][region]" id="billing_address_region" - value="<?php /* @escapeNotVerified */ echo $block->getPostParam('customer.creditCard.billingAddress.region', $defaultRegion) ?>"> + value="<?php echo $block->escapeHtml($block->getPostParam('customer.creditCard.billingAddress.region', $defaultRegion)); ?>"> </div> </div> <div class="field zip billing_address_postal_code required"> <label for="billing_address_postal_code" class="label"> - <span><?php /* @escapeNotVerified */ echo __('Zip/Postal Code') ?></span> + <span><?php echo $block->escapeHtml(__('Zip/Postal Code')); ?></span> </label> <div class="control"> <input type="text" class="input-text required-entry validate-zip-international " name="credit_card[billing_address][postal_code]" id="billing_address_postal_code" - value="<?php /* @escapeNotVerified */ echo $defaultPostalCode ?>" + value="<?php echo $block->escapeHtml($defaultPostalCode); ?>" data-validate="{required:true, 'validate-zip-international':true}"> </div> </div> <div class="field name billing_address_country required"> <label for="billing_address_country" class="label"> - <span><?php /* @escapeNotVerified */ echo __('Country') ?></span> + <span><?php echo $block->escapeHtml(__('Country')); ?></span> </label> <div class="control"> - <?php $default = $defaultCountryCodeAlpha2 ?> - <?php /* @escapeNotVerified */ echo $block->countrySelect('credit_card' . '[billing_address][country_code_alpha2]', 'billing_address_country', $default) ?> + <?php echo $block->escapeHtml($block->countrySelect('credit_card[billing_address][country_code_alpha2]', 'billing_address_country', $default)); ?> </div> </div> </fieldset> <div class="actions-toolbar"> <div class="primary"> <button type="submit" id="opc-submit" data-role="opc-submit" class="action save primary" - title="<?php /* @escapeNotVerified */ echo __('Submit') ?>"> - <span><?php /* @escapeNotVerified */ echo __('Submit') ?></span> + title="<?php echo $block->escapeHtml(__('Submit')); ?>"> + <span><?php echo $block->escapeHtml(__('Submit')); ?></span> </button> </div> <div class="secondary"> - <a class="action back" href="<?php /* @escapeNotVerified */ echo $block->getBackUrl() ?>"> - <span><span><small>« </small><?php /* @escapeNotVerified */ echo __('Back') ?></span> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()); ?>"> + <span><span><small>« </small><?php echo $block->escapeUrl(__('Back')); ?></span> </a> </div> </div> </form> -<?php -$clientToken = $block->getClientToken(); -$formData = [ - "clientToken" => $clientToken, - 'ajaxSaveUrl' => $block->getAjaxSaveUrl(), - 'isEditMode' => $block->isEditMode() ? true : false, - 'cardToken' => $block->isEditMode() ? $creditCard->token : '', - 'backUrl' => $block->getBackUrl(), - 'hasVerification' => $block->hasVerification(), - "countrySpecificCardTypes" => $countrySpecificCardTypeConfig, - "applicableCardTypes" => $applicableCardTypeConfig, - "cardTypes" => $block->getCcAvailableTypes(), - "isFraudDetectionEnabled" => $block->isFraudDetectionEnabled() -]; -$serializedFormData = $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($formData); -?> <script type="text/x-magento-init"> { "#form-validate": { "validation": {}, - "braintreeEditForm": <?php /* @escapeNotVerified */ echo $serializedFormData ?> + "braintreeEditForm": <?php /* @noEscape */ echo $serializedFormData; ?> }, "#billing_address_country": { "regionUpdater": { @@ -384,13 +360,11 @@ $serializedFormData = $this->helper('Magento\Framework\Json\Helper\Data')->jsonE "regionInputId": "#billing_address_region", "postcodeId": "#billing_address_region", "form": "#form-validate", - "regionJson": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, - "defaultRegion": "<?php /* @escapeNotVerified */ echo $defaultRegionId ?>", + "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson(); ?>, + "defaultRegion": "<?php echo $block->escapeHtml($defaultRegionId); ?>", "countriesWithOptionalZip": - <?php /* @escapeNotVerified */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> + <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true); ?> } } } - - </script> \ No newline at end of file diff --git a/app/code/Magento/Braintree/view/frontend/templates/creditcard/index.phtml b/app/code/Magento/Braintree/view/frontend/templates/creditcard/index.phtml index f4cef98141bd9a4f549dff973874bd8a63a706a3..fd9ee17028bb6eae399fe70103f3f8e82933681f 100644 --- a/app/code/Magento/Braintree/view/frontend/templates/creditcard/index.phtml +++ b/app/code/Magento/Braintree/view/frontend/templates/creditcard/index.phtml @@ -7,14 +7,18 @@ // @codingStandardsIgnoreFile /** @var $block \Magento\Braintree\Block\Creditcard\Management */ - $_storedCards = $block->getCurrentCustomerStoredCards(); +$storedCards = $block->getCurrentCustomerStoredCards(); ?> <div class="page-title title-buttons"> <?php if ($block->getUsesVault()): ?> - <button type="button" title="<?php /* @escapeNotVerified */ echo __('Add Credit Card') ?>" class="action subscribe primary" onclick="window.location='<?php /* @escapeNotVerified */ echo $block->getAddUrl() ?>';"><span><span><?php /* @escapeNotVerified */ echo __('Add Credit Card') ?></span></span></button> - <?php endif ?> + <button type="button" title="<?php echo $block->escapeHtml(__('Add Credit Card')); ?>" + class="action subscribe primary" + onclick="window.location='<?php echo $block->escapeUrl($block->getAddUrl()) ?>';"> + <span><span><?php echo $block->escapeHtml(__('Add Credit Card')); ?></span></span> + </button> + <?php endif; ?> </div> -<?php echo $block->getLayout()->getMessagesBlock()->getGroupedHtml() ?> +<?php echo $block->getLayout()->getMessagesBlock()->getGroupedHtml(); ?> <?php if (count($_storedCards)): ?> <table class="data-table" id="my-quotes-table"> <col width="1" /> @@ -24,23 +28,27 @@ <col width="1" /> <thead> <tr> - <th><?php /* @escapeNotVerified */ echo __('Type') ?></th> - <th><?php /* @escapeNotVerified */ echo __('Card Number') ?></th> - <th><?php /* @escapeNotVerified */ echo __('Is Default') ?></th> - <th colspan="2"><?php /* @escapeNotVerified */ echo __('Actions') ?></th> + <th><?php echo $block->escapeHtml(__('Type')); ?></th> + <th><?php echo $block->escapeHtml(__('Card Number')); ?></th> + <th><?php echo $block->escapeHtml(__('Is Default')); ?></th> + <th colspan="2"><?php echo $block->escapeHtml(__('Actions')); ?></th> </tr> </thead> <tbody> - <?php foreach ($_storedCards as $card):?> + <?php foreach ($storedCards as $card):?> <tr> - <td><?php /* @escapeNotVerified */ echo $card->cardType ?></td> - <td><?php /* @escapeNotVerified */ echo $card->maskedNumber ?></td> - <td><?php /* @escapeNotVerified */ echo ($card->default) ? __('Yes') : __('No') ?></td> + <td><?php echo $block->escapeHtml($card->cardType); ?></td> + <td><?php echo $block->escapeHtml($card->maskedNumber); ?></td> + <td><?php /* @noEscape */ echo ($card->default) ? $block->escapeHtml(__('Yes')) : $block->escapeHtml(__('No')); ?></td> <td> - <a href="<?php /* @escapeNotVerified */ echo $block->getEditUrl($card->token) ?>"><?php /* @escapeNotVerified */ echo __('Edit')?></a> + <a href="<?php echo $block->escapeUrl($block->getEditUrl($card->token)); ?>"> + <?php echo $block->escapeHtml(__('Edit')); ?> + </a> </td> <td> - <a href="<?php /* @escapeNotVerified */ echo $block->getDeleteUrl($card->token) ?>"><?php /* @escapeNotVerified */ echo __('Delete')?></a> + <a href="<?php echo $block->escapeUrl($block->getDeleteUrl($card->token)); ?>"> + <?php echo $block->escapeHtml(__('Delete'));?> + </a> </td> </tr> <?php endforeach; ?> diff --git a/app/code/Magento/Braintree/view/frontend/templates/data_js.phtml b/app/code/Magento/Braintree/view/frontend/templates/data_js.phtml index cbfe3dcda5f9f52c183a7382e9cf4c33d5a50811..14579540152c5ac6e53839cf17dfdd861f564d89 100644 --- a/app/code/Magento/Braintree/view/frontend/templates/data_js.phtml +++ b/app/code/Magento/Braintree/view/frontend/templates/data_js.phtml @@ -14,14 +14,14 @@ $arrayData = [ $this->helper('Magento\Braintree\Helper\Data')->getKountId() : false, "formId" =>$block->getFormId(), "merchantId" => $block->getMerchantId(), - "braintreeDataJs" => $block->getJsSrc(), + "braintreeDataJs" => $block->escapeUrl($block->getJsSrc()), ]; $serializedFormData = $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($arrayData); ?> <script type="text/x-magento-init"> { "body": { - "braintreeDataJs": <?php /* @escapeNotVerified */ echo $serializedFormData ?> + "braintreeDataJs": <?php /* @noEscape */ echo $serializedFormData; ?> } } </script> diff --git a/app/code/Magento/Braintree/view/frontend/templates/form.phtml b/app/code/Magento/Braintree/view/frontend/templates/form.phtml index f740ad803b188d5c3c7b53b31021d2e2b8f0edde..459a61568cff7fa67f19d3146b1a2f7e0fb5ff5d 100644 --- a/app/code/Magento/Braintree/view/frontend/templates/form.phtml +++ b/app/code/Magento/Braintree/view/frontend/templates/form.phtml @@ -7,75 +7,112 @@ // @codingStandardsIgnoreFile /** @var \Magento\Braintree\Block\Form $block */ -$_code = $block->getMethodCode(); -$_loggedIn = $block->isCustomerLoggedIn(); -$_storedCards = $block->getStoredCards(); -$_useVault = $_loggedIn && $block->useVault() && count($_storedCards); -$_autoDetection = $block->isCcDetectionEnabled(); -$clientToken = $block->getClientToken(); +$code = $block->getMethodCode(); +$loggedIn = $block->isCustomerLoggedIn(); +$storedCards = $block->getStoredCards(); +$useVault = $loggedIn && $block->useVault() && count($storedCards); +$autoDetection = $block->isCcDetectionEnabled(); +$clientToken = $block->escapeHtml($block->getClientToken()); +$formData = [ + "useVault" => $useVault, + "clientToken" => $clientToken, + "autoDetection" => $autoDetection, + "loggedIn" => $loggedIn, +]; +$serializedFormData = $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($formData); +$ccType = $block->getInfoData('cc_type'); +$ccExpMonth = $block->getInfoData('cc_exp_month'); +$ccExpYear = $block->getInfoData('cc_exp_year'); ?> -<fieldset class="fieldset items braintree" id="payment_form_<?php /* @escapeNotVerified */ echo $_code ?>" style="display:none;"> +<fieldset class="fieldset items braintree" id="payment_form_<?php /* @noEscape */ echo $code; ?>" style="display:none;"> <input type="hidden" name="payment[payment_method_nonce]" id="braintree_nonce" value="" /> - <input type="hidden" name="payment[cc_last4]" id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_last4" value="" /> - <?php if ($_autoDetection) : ?> + <input type="hidden" name="payment[cc_last4]" id="<?php /* @noEscape */ echo $code; ?>_cc_last4" value="" /> + <?php if ($autoDetection) : ?> <input type="hidden" id="card_type_autoselect" value="" /> <?php endif; ?> - <?php if ($_useVault): ?> - <li id="<?php /* @escapeNotVerified */ echo $_code ?>_token_selector"> - <label for="<?php /* @escapeNotVerified */ echo $_code ?>_cc_token"><?php /* @escapeNotVerified */ echo __('Payment Information') ?></label> + <?php if ($useVault): ?> + <li id="<?php /* @noEscape */ echo $code; ?>_token_selector"> + <label for="<?php /* @noEscape */ echo $code; ?>_cc_token"> + <?php echo $block->escapeHtml(__('Payment Information')); ?> + </label> <div class="input-box"> - <select id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_token" name="payment[cc_token]"> - <?php foreach ($_storedCards as $creditCard): ?> - <option value="<?php /* @escapeNotVerified */ echo $creditCard->token?>" <?php echo $creditCard->default ? 'selected="selected"' : '' ?>> - <?php /* @escapeNotVerified */ echo $creditCard->maskedNumber . ' - ' . $creditCard->cardType; ?> + <select id="<?php /* @noEscape */ echo $code; ?>_cc_token" name="payment[cc_token]"> + <?php foreach ($storedCards as $creditCard): ?> + <option value="<?php echo $block->escapeHtml($creditCard->token); ?>" + <?php /* @noEscape */ echo $creditCard->default ? ' selected="selected"' : ''; ?>> + <?php echo $block->escapeHtml($creditCard->maskedNumber); ?> - <?php echo $block->escapeHtml($creditCard->cardType); ?> </option> <?php endforeach; ?> - <option value=''><?php /* @escapeNotVerified */ echo __('Add new card') ?></option> + <option value=''><?php echo $block->escapeHtml(__('Add new card')); ?></option> </select> </div> </li> <?php endif; ?> <div class="field type required hide_if_token_selected"> - <label for="<?php /* @escapeNotVerified */ echo $_code ?>_cc_type" class="label"><span><?php /* @escapeNotVerified */ echo __('Credit Card Type') ?></span></label> + <label for="<?php /* @noEscape */ echo $code; ?>_cc_type" class="label"> + <span><?php echo $block->escapeHtml(__('Credit Card Type')); ?></span> + </label> <div class="control"> - <select id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_type" - data-mage-init='{"creditCardType":{"creditCardTypeContainer":"#<?php /* @escapeNotVerified */ echo $_code ?>_cc_type_ss_div"}}' - name="payment[cc_type]" data-validate='{required:true, "validate-cc-type-select":"#<?php /* @escapeNotVerified */ echo $_code ?>_cc_number"}' class="select"> - <option value=""><?php /* @escapeNotVerified */ echo __('--Please Select--')?></option> - <?php $_ccType = $block->getInfoData('cc_type') ?> - <?php foreach ($block->getCcAvailableTypes() as $_typeCode => $_typeName): ?> - <option value="<?php /* @escapeNotVerified */ echo $_typeCode ?>"<?php if ($_typeCode == $_ccType): ?> selected="selected"<?php endif ?>><?php /* @escapeNotVerified */ echo $_typeName ?></option> + <select id="<?php /* @noEscape */ echo $code; ?>_cc_type" + data-mage-init='{"creditCardType":{"creditCardTypeContainer":"#<?php /* @noEscape */ echo $code; ?>_cc_type_ss_div"}}' + name="payment[cc_type]" data-validate='{ + required:true, + "validate-cc-type-select":"#<?php /* @noEscape */ echo $code; ?>_cc_number" + }' class="select"> + <option value=""><?php echo $block->escapeHtml(__('--Please Select--')); ?></option> + <?php foreach ($block->getCcAvailableTypes() as $typeCode => $typeName): ?> + <option value="<?php echo $block->escapeHtml($typeCode); ?>" + <?php if ($typeCode == $ccType): ?> selected="selected"<?php endif; ?>> + <?php echo $block->escapeHtml($typeName); ?> + </option> <?php endforeach ?> </select> </div> </div> <div class="field number required hide_if_token_selected"> - <label for="<?php /* @escapeNotVerified */ echo $_code ?>_cc_number" class="label"><span><?php /* @escapeNotVerified */ echo __('Credit Card Number') ?></span></label> + <label for="<?php /* @noEscape */ echo $code; ?>_cc_number" class="label"> + <span><?php echo $block->escapeHtml(__('Credit Card Number')); ?></span> + </label> <div class="control"> - <input type="number" id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_number" name="payment[cc_number]" title="<?php /* @escapeNotVerified */ echo __('Credit Card Number') ?>" class="input-text" value="" data-validate='{"required-number":true, "validate-cc-number":"#<?php /* @escapeNotVerified */ echo $_code ?>_cc_type", "validate-cc-type":"#<?php /* @escapeNotVerified */ echo $_code ?>_cc_type"}'/> + <input type="number" id="<?php /* @noEscape */ echo $code; ?>_cc_number" name="payment[cc_number]" + title="<?php echo $block->escapeHtml(__('Credit Card Number')); ?>" class="input-text" value="" + data-validate='{ + "required-number":true, + "validate-cc-number":"#<?php /* @noEscape */ echo $code; ?>_cc_type", + "validate-cc-type":"#<?php /* @noEscape */ echo $code; ?>_cc_type" + }'/> </div> </div> - <div class="field date required hide_if_token_selected" id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_type_exp_div"> - <label for="<?php /* @escapeNotVerified */ echo $_code ?>_expiration" class="label"><span><?php /* @escapeNotVerified */ echo __('Expiration Date') ?></span></label> + <div class="field date required hide_if_token_selected" id="<?php /* @noEscape */ echo $code; ?>_cc_type_exp_div"> + <label for="<?php /* @noEscape */ echo $code; ?>_expiration" class="label"> + <span><?php echo $block->escapeHtml(__('Expiration Date')); ?></span> + </label> <div class="control"> <div class="fields group group-2"> <div class="field no-label month"> <div class="control"> - <select id="<?php /* @escapeNotVerified */ echo $_code ?>_expiration" name="payment[cc_exp_month]" class="select month" data-validate='{required:true, "validate-cc-exp":"#<?php /* @escapeNotVerified */ echo $_code ?>_expiration_yr"}'> - <?php $_ccExpMonth = $block->getInfoData('cc_exp_month') ?> + <select id="<?php /* @noEscape */ echo $code; ?>_expiration" name="payment[cc_exp_month]" + class="select month" data-validate='{ + required:true, "validate-cc-exp":"#<?php /* @noEscape */ echo $code; ?>_expiration_yr" + }'> <?php foreach ($block->getCcMonths() as $k => $v): ?> - <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpMonth): ?> selected="selected"<?php endif ?>><?php /* @escapeNotVerified */ echo $v ?></option> - <?php endforeach ?> + <option value="<?php echo $k ? $block->escapeHtml($k) : ''; ?>" + <?php if ($k == $ccExpMonth): ?> selected="selected"<?php endif; ?>> + <?php echo $block->escapeHtml($v); ?> + </option> + <?php endforeach; ?> </select> </div> </div> <div class="field no-label year"> <div class="control"> - <?php $_ccExpYear = $block->getInfoData('cc_exp_year') ?> - <select id="<?php /* @escapeNotVerified */ echo $_code ?>_expiration_yr" name="payment[cc_exp_year]" class="select year" data-validate='{required:true}'> + <select id="<?php /* @noEscape */ echo $code; ?>_expiration_yr" name="payment[cc_exp_year]" class="select year" data-validate='{required:true}'> <?php foreach ($block->getCcYears() as $k => $v): ?> - <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpYear): ?> selected="selected"<?php endif ?>><?php /* @escapeNotVerified */ echo $v ?></option> - <?php endforeach ?> + <option value="<?php /* @noEscape */ echo $k ? $block->escapeHtml($k) : '' ?>" + <?php if ($k == $ccExpYear): ?> selected="selected"<?php endif; ?>> + <?php echo $block->escapeHtml($v); ?> + </option> + <?php endforeach; ?> </select> </div> </div> @@ -83,39 +120,44 @@ $clientToken = $block->getClientToken(); </div> </div> <?php if ($block->hasVerification()): ?> - <div class="field cvv required hide_if_token_selected" id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_type_cvv_div"> - <label for="<?php /* @escapeNotVerified */ echo $_code ?>_cc_cid" class="label"><span><?php /* @escapeNotVerified */ echo __('Card Verification Number') ?></span></label> + <div class="field cvv required hide_if_token_selected" id="<?php /* @noEscape */ echo $code; ?>_cc_type_cvv_div"> + <label for="<?php /* @noEscape */ echo $code; ?>_cc_cid" class="label"> + <span><?php echo $block->escapeHtml(__('Card Verification Number')); ?></span> + </label> <div class="control"> - <input type="number" title="<?php /* @escapeNotVerified */ echo __('Card Verification Number') ?>" class="input-text cvv" id="<?php /* @escapeNotVerified */ echo $_code ?>_cc_cid" name="payment[cc_cid]" value="" data-validate='{"required-number":true, "validate-cc-cvn":"#<?php /* @escapeNotVerified */ echo $_code ?>_cc_type"}' /> - <?php $_content = '<img src=\"' . $block->getViewFileUrl('Magento_Checkout::cvv.png') . '\" alt=\"' . __('Card Verification Number Visual Reference') . '\" title=\"' . __('Card Verification Number Visual Reference') . '\" />'; ?> + <input type="number" title="<?php echo $block->escapeHtml(__('Card Verification Number')); ?>" + class="input-text cvv" + id="<?php /* @noEscape */ echo $code; ?>_cc_cid" name="payment[cc_cid]" value="" + data-validate='{ + "required-number":true, "validate-cc-cvn":"#<?php /* @noEscape */ echo $code; ?>_cc_type" + }' /> + <?php $content = '<img src=\"' . $block->escapeUrl($block->getViewFileUrl('Magento_Checkout::cvv.png')) . + '\" alt=\"' . $block->escapeHtml(__('Card Verification Number Visual Reference')) . + '\" title=\"' . $block->escapeHtml(__('Card Verification Number Visual Reference')) . '\" />'; ?> <div class="note"> - <a href="#" class="action cvv" title="<?php /* @escapeNotVerified */ echo __('What is this?') ?>" data-mage-init='{"tooltip": {"content": "<?php /* @escapeNotVerified */ echo $_content ?>"}}'><span><?php /* @escapeNotVerified */ echo __('What is this?') ?></span></a> + <a href="#" class="action cvv" title="<?php echo $block->escapeHtml(__('What is this?')); ?>" + data-mage-init='{"tooltip": {"content": "<?php /* @noEscape */ echo $content; ?>"}}'> + <span><?php echo $block->escapeHtml(__('What is this?')); ?></span> + </a> </div> </div> </div> <?php endif; ?> <?php if($block->canSaveCard()): ?> - <li id="<?php /* @escapeNotVerified */ echo $_code ?>_store_in_vault_div" style="text-align:left;" class="hide_if_token_selected"> - <input type="checkbox" title="<?php /* @escapeNotVerified */ echo __('Save this card for future use') ?>" class="input-checkbox" id="<?php /* @escapeNotVerified */ echo $_code ?>_store_in_vault" checked="checked" name="payment[store_in_vault]" value="1" /> - <label for="<?php /* @escapeNotVerified */ echo $_code ?>_store_in_vault" class="required" style="float:none;"><?php /* @escapeNotVerified */ echo __('Save this card for future use') ?></label> + <li id="<?php /* @noEscape */ echo $code; ?>_store_in_vault_div" style="text-align:left;" class="hide_if_token_selected"> + <input type="checkbox" title="<?php echo $block->escapeHtml(__('Save this card for future use')); ?>" class="input-checkbox" + id="<?php /* @noEscape */ echo $code; ?>_store_in_vault" checked="checked" name="payment[store_in_vault]" value="1" /> + <label for="<?php /* @noEscape */ echo $code; ?>_store_in_vault" class="required" style="float:none;"> + <?php echo $block->escapeHtml(__('Save this card for future use')); ?> + </label> </li> <?php endif; ?> </fieldset> - -<?php - $formData = [ - "useVault" => $_useVault, - "clientToken" => $clientToken, - "autoDetection" => $_autoDetection, - "loggedIn" => $_loggedIn, - ]; - $serializedFormData = $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($formData); -?> <script type="text/x-magento-init"> { "#payment_form_braintree": { - "braintreeForm": <?php /* @escapeNotVerified */ echo $serializedFormData ?> + "braintreeForm": <?php /* @noEscape */ echo $serializedFormData ?> } } </script> diff --git a/app/code/Magento/Checkout/Model/Type/Onepage.php b/app/code/Magento/Checkout/Model/Type/Onepage.php index 775c0dcb632322ab0ab4daa3c8300c4ae8d8ed8c..8d9f2ed620c1ab9c79059480f38ddb6006f5625a 100644 --- a/app/code/Magento/Checkout/Model/Type/Onepage.php +++ b/app/code/Magento/Checkout/Model/Type/Onepage.php @@ -379,149 +379,6 @@ class Onepage return []; } - /** - * Save billing address information to quote - * This method is called by One Page Checkout JS (AJAX) while saving the billing information. - * - * @param array $data - * @param int $customerAddressId - * @return array - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function saveBilling($data, $customerAddressId) - { - if (empty($data)) { - return ['error' => -1, 'message' => __('Invalid data')]; - } - - $address = $this->getQuote()->getBillingAddress(); - $addressForm = $this->_formFactory->create( - AddressMetadata::ENTITY_TYPE_ADDRESS, - 'customer_address_edit', - [], - $this->_request->isAjax(), - Form::IGNORE_INVISIBLE, - [] - ); - - if ($customerAddressId) { - try { - $customerAddress = $this->addressRepository->getById($customerAddressId); - if ($customerAddress->getCustomerId() != $this->getQuote()->getCustomerId()) { - return ['error' => 1, 'message' => __('The customer address is not valid.')]; - } - $address->importCustomerAddressData($customerAddress)->setSaveInAddressBook(0); - } catch (\Exception $e) { - return ['error' => 1, 'message' => __('Address does not exist.')]; - } - } else { - // emulate request object - $addressData = $addressForm->extractData($addressForm->prepareRequest($data)); - $addressErrors = $addressForm->validateData($addressData); - if ($addressErrors !== true) { - return ['error' => 1, 'message' => array_values($addressErrors)]; - } - $address->addData($addressForm->compactData($addressData)); - //unset billing address attributes which were not shown in form - foreach ($addressForm->getAttributes() as $attribute) { - if (!isset($data[$attribute->getAttributeCode()])) { - $address->setData($attribute->getAttributeCode(), null); - } - } - $address->setCustomerAddressId(null); - // Additional form data, not fetched by extractData (as it fetches only attributes) - $address->setSaveInAddressBook(empty($data['save_in_address_book']) ? 0 : 1); - $this->getQuote()->setBillingAddress($address); - } - - // validate billing address - if (($validateRes = $address->validate()) !== true) { - return ['error' => 1, 'message' => $validateRes]; - } - - if (true !== ($result = $this->_validateCustomerData($data))) { - return $result; - } else { - /** Even though _validateCustomerData should not modify data, it does */ - $address = $this->getQuote()->getBillingAddress(); - } - - if (!$this->getQuote()->getCustomerId() && $this->isCheckoutMethodRegister()) { - if ($this->_customerEmailExists($address->getEmail(), $this->_storeManager->getWebsite()->getId())) { - return [ - 'error' => 1, - // @codingStandardsIgnoreStart - 'message' => __( - 'This email address already belongs to a registered customer. You can sign in or create an account with a different email address.' - ) - // @codingStandardsIgnoreEnd - ]; - } - } - - if (!$this->getQuote()->isVirtual()) { - /** - * Billing address using options - */ - $usingCase = isset($data['use_for_shipping']) - ? (bool)$data['use_for_shipping'] - : self::NOT_USE_FOR_SHIPPING; - - switch ($usingCase) { - case self::NOT_USE_FOR_SHIPPING: - $shipping = $this->getQuote()->getShippingAddress(); - $shipping->setSameAsBilling(0); - $shipping->save(); - break; - case self::USE_FOR_SHIPPING: - $billing = clone $address; - $billing->unsAddressId()->unsAddressType(); - $shipping = $this->getQuote()->getShippingAddress(); - $shippingMethod = $shipping->getShippingMethod(); - - // Billing address properties that must be always copied to shipping address - $requiredBillingAttributes = ['customer_address_id']; - - // don't reset original shipping data, if it was not changed by customer - foreach ($shipping->getData() as $shippingKey => $shippingValue) { - if ($shippingValue !== null - && $billing->getData($shippingKey) !== null - && !isset($data[$shippingKey]) - && !in_array($shippingKey, $requiredBillingAttributes) - ) { - $billing->unsetData($shippingKey); - } - } - $shipping->addData($billing->getData()) - ->setSameAsBilling(1) - ->setSaveInAddressBook(0) - ->setShippingMethod($shippingMethod) - ->setCollectShippingRates(true); - $this->totalsCollector->collectAddressTotals($this->getQuote(), $shipping); - - if (!$this->isCheckoutMethodRegister()) { - $shipping->save(); - } - $this->getCheckout()->setStepData('shipping', 'complete', true); - break; - } - } - - if ($this->isCheckoutMethodRegister()) { - $this->quoteRepository->save($this->getQuote()); - } else { - $address->save(); - } - - $this->getCheckout() - ->setStepData('billing', 'allow', true) - ->setStepData('billing', 'complete', true) - ->setStepData('shipping', 'allow', true); - return []; - } - /** * Check whether checkout method is "register" * @@ -532,100 +389,6 @@ class Onepage return $this->getQuote()->getCheckoutMethod() == self::METHOD_REGISTER; } - /** - * Validate customer data and set some its data for further usage in quote - * - * Will return either true or array with error messages - * - * @param array $data - * @return bool|array - */ - protected function _validateCustomerData(array $data) - { - $quote = $this->getQuote(); - $isCustomerNew = !$quote->getCustomerId(); - $customer = $quote->getCustomer(); - $customerData = $this->extensibleDataObjectConverter->toFlatArray( - $customer, - [], - '\Magento\Customer\Api\Data\CustomerInterface' - ); - - /** @var Form $customerForm */ - $customerForm = $this->_formFactory->create( - \Magento\Customer\Api\CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, - 'checkout_register', - $customerData, - $this->_request->isAjax(), - Form::IGNORE_INVISIBLE, - [] - ); - - if ($isCustomerNew) { - $customerRequest = $customerForm->prepareRequest($data); - $customerData = $customerForm->extractData($customerRequest); - } - - $customerErrors = $customerForm->validateData($customerData); - if ($customerErrors !== true) { - return ['error' => -1, 'message' => implode(', ', $customerErrors)]; - } - - if (!$isCustomerNew) { - return true; - } - - $customer = $this->customerDataFactory->create(); - $this->dataObjectHelper->populateWithArray( - $customer, - $customerData, - '\Magento\Customer\Api\Data\CustomerInterface' - ); - - if ($quote->getCheckoutMethod() == self::METHOD_REGISTER) { - // We always have $customerRequest here, otherwise we would have been kicked off the function several - // lines above - $password = $customerRequest->getParam('customer_password'); - if ($password != $customerRequest->getParam('confirm_password')) { - return [ - 'error' => -1, - 'message' => __('Password and password confirmation are not equal.') - ]; - } - $quote->setPasswordHash($this->accountManagement->getPasswordHash($password)); - } else { - // set NOT LOGGED IN group id explicitly, - // otherwise copyFieldsetToTarget('customer_account', 'to_quote') will fill it with default group id value - $customer->setGroupId(GroupInterface::NOT_LOGGED_IN_ID); - } - - //validate customer - $result = $this->accountManagement->validate($customer); - if (!$result->isValid()) { - return [ - 'error' => -1, - 'message' => implode(', ', $result->getMessages()) - ]; - } - - // copy customer/guest email to address - $quote->getBillingAddress()->setEmail($customer->getEmail()); - - // copy customer data to quote - $this->_objectCopyService->copyFieldsetToTarget( - 'customer_account', - 'to_quote', - $this->extensibleDataObjectConverter->toFlatArray( - $customer, - [], - '\Magento\Customer\Api\Data\CustomerInterface' - ), - $quote - ); - - return true; - } - /** * Save checkout shipping address * diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Type/OnepageTest.php b/app/code/Magento/Checkout/Test/Unit/Model/Type/OnepageTest.php index 0c319e19e1f377c2deea8799eb6a5e12ff461032..15275b9c11905052e18b7e4b776d2532bde7974e 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/Type/OnepageTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/Type/OnepageTest.php @@ -367,280 +367,6 @@ class OnepageTest extends \PHPUnit_Framework_TestCase $this->assertEquals([], $this->onepage->saveCheckoutMethod('someMethod')); } - public function testSaveBillingInvalidData() - { - $this->assertEquals(['error' => -1, 'message' => 'Invalid data'], $this->onepage->saveBilling([], 0)); - } - - /** - * @dataProvider saveBillingDataProvider - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - * @SuppressWarnings(PHPMD.ExcessiveParameterList) - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - */ - public function testSaveBilling( - $data, - $customerAddressId, - $quoteCustomerId, - $addressCustomerId, - $isAddress, - $validateDataResult, - $validateResult, - $checkoutMethod, - $customerPassword, - $confirmPassword, - $validationResultMessages, - $isEmailAvailable, - $isVirtual, - $getStepDataResult, - $expected - ) { - $useForShipping = (int)$data['use_for_shipping']; - - $passwordHash = 'password hash'; - $this->requestMock->expects($this->any())->method('isAjax')->will($this->returnValue(false)); - $customerValidationResultMock = $this->getMock( - 'Magento\Customer\Api\Data\ValidationResultsInterface', [], [], '', false - ); - $customerValidationResultMock - ->expects($this->any()) - ->method('isValid') - ->will($this->returnValue(empty($validationResultMessages))); - $customerValidationResultMock - ->expects($this->any()) - ->method('getMessages') - ->will($this->returnValue($validationResultMessages)); - $this->accountManagementMock - ->expects($this->any()) - ->method('getPasswordHash') - ->with($customerPassword) - ->will($this->returnValue($passwordHash)); - $this->accountManagementMock - ->expects($this->any()) - ->method('validate') - ->will($this->returnValue($customerValidationResultMock)); - $this->accountManagementMock - ->expects($this->any()) - ->method('isEmailAvailable') - ->will($this->returnValue($isEmailAvailable)); - /** @var \Magento\Quote\Model\Quote|\PHPUnit_Framework_MockObject_MockObject $quoteMock */ - $quoteMock = $this->getMock( - 'Magento\Quote\Model\Quote', - [ - 'getData', - 'getCustomerId', - '__wakeup', - 'getBillingAddress', - 'setPasswordHash', - 'getCheckoutMethod', - 'isVirtual', - 'getShippingAddress', - 'getCustomerData', - 'collectTotals', - 'save', - 'getCustomer' - ], - [], - '', - false - ); - $customerMock = $this->getMockForAbstractClass( - 'Magento\Framework\Api\AbstractExtensibleObject', - [], - '', - false, - true, - true, - ['__toArray'] - ); - $shippingAddressMock = $this->getMock( - 'Magento\Quote\Model\Quote\Address', - [ - 'setSameAsBilling', - 'save', - 'collectTotals', - 'addData', - 'setShippingMethod', - 'setCollectShippingRates', - '__wakeup' - ], - [], - '', - false - ); - $quoteMock->expects($this->any())->method('getShippingAddress')->will($this->returnValue($shippingAddressMock)); - - $shippingAddressMock->expects($useForShipping ? $this->any() : $this->once()) - ->method('setSameAsBilling') - ->with($useForShipping) - ->will($this->returnSelf()); - - $expects = (!$useForShipping || ($checkoutMethod != Onepage::METHOD_REGISTER)) ? $this->once() : $this->never(); - $shippingAddressMock->expects($expects) - ->method('save'); - - $shippingAddressMock->expects($useForShipping ? $this->once() : $this->never()) - ->method('addData') - ->will($this->returnSelf()); - - $shippingAddressMock->expects($this->any()) - ->method('setSaveInAddressBook') - ->will($this->returnSelf()); - - $shippingAddressMock->expects($useForShipping ? $this->once() : $this->never()) - ->method('setShippingMethod') - ->will($this->returnSelf()); - - $shippingAddressMock->expects($useForShipping ? $this->once() : $this->never()) - ->method('setCollectShippingRates') - ->will($this->returnSelf()); - - if ($useForShipping === \Magento\Checkout\Model\Type\Onepage::USE_FOR_SHIPPING) { - $this->totalsCollectorMock - ->expects($this->once()) - ->method('collectAddressTotals') - ->with($quoteMock, $shippingAddressMock); - } else { - $this->totalsCollectorMock - ->expects($this->never()) - ->method('collectAddressTotals') - ->with($quoteMock, $shippingAddressMock); - } - - $quoteMock->expects($this->any())->method('setPasswordHash')->with($passwordHash); - $quoteMock->expects($this->any())->method('getCheckoutMethod')->will($this->returnValue($checkoutMethod)); - $quoteMock->expects($this->any())->method('isVirtual')->will($this->returnValue($isVirtual)); - - $addressMock = $this->getMock( - 'Magento\Quote\Model\Quote\Address', - [ - 'setSaveInAddressBook', - 'getData', - 'setEmail', - '__wakeup', - 'importCustomerAddressData', - 'validate', - 'save' - ], - [], - '', - false - ); - $addressMock->expects($this->any())->method('importCustomerAddressData')->will($this->returnSelf()); - $addressMock->expects($this->atLeastOnce())->method('validate')->will($this->returnValue($validateResult)); - $addressMock->expects($this->any())->method('getData')->will($this->returnValue([])); - - $quoteMock->expects($this->any())->method('getBillingAddress')->will($this->returnValue($addressMock)); - $quoteMock->expects($this->any())->method('getCustomerId')->will($this->returnValue($quoteCustomerId)); - - $this->quoteRepositoryMock - ->expects($checkoutMethod === Onepage::METHOD_REGISTER ? $this->once() : $this->never()) - ->method('save') - ->with($quoteMock); - - $addressMock->expects($checkoutMethod === Onepage::METHOD_REGISTER ? $this->never() : $this->once()) - ->method('save'); - - $quoteMock->expects($this->any())->method('getCustomer')->will($this->returnValue($customerMock)); - $data1 = []; - $extensibleDataObjectConverterMock = $this->getMock( - 'Magento\Framework\Api\ExtensibleDataObjectConverter', - ['toFlatArray'], - [], - '', - false - ); - $extensibleDataObjectConverterMock->expects($this->any()) - ->method('toFlatArray') - ->with($customerMock) - ->will($this->returnValue($data1)); - - $formMock = $this->getMock('Magento\Customer\Model\Metadata\Form', [], [], '', false); - $formMock->expects($this->atLeastOnce())->method('validateData')->will($this->returnValue($validateDataResult)); - - $this->formFactoryMock->expects($this->any())->method('create')->will($this->returnValue($formMock)); - $formMock->expects($this->any())->method('prepareRequest')->will($this->returnValue($this->requestMock)); - $formMock->expects($this->any()) - ->method('extractData') - ->with($this->requestMock) - ->will($this->returnValue([])); - $formMock->expects($this->any()) - ->method('validateData') - ->with([]) - ->will($this->returnValue(false)); - - $customerDataMock = $this->getMock('Magento\Customer\Api\Data\CustomerInterface', [], [], '', false); - - $this->customerDataFactoryMock - ->expects($this->any()) - ->method('create') - ->will($this->returnValue($customerDataMock)); - - $this->checkoutSessionMock->expects($this->any())->method('getQuote')->will($this->returnValue($quoteMock)); - $this->checkoutSessionMock->expects($this->any()) - ->method('getStepData') - ->will($this->returnValue($useForShipping ? true : $getStepDataResult)); - $this->checkoutSessionMock->expects($this->any())->method('setStepData')->will($this->returnSelf()); - $customerAddressMock = $this->getMockForAbstractClass( - 'Magento\Customer\Api\Data\AddressInterface', - [], - '', - false - ); - $customerAddressMock->expects($this->any()) - ->method('getCustomerId') - ->will($this->returnValue($addressCustomerId)); - $this->addressRepositoryMock->expects($this->any()) - ->method('getById') - ->will($isAddress ? $this->returnValue($customerAddressMock) : $this->throwException(new \Exception())); - - $websiteMock = $this->getMock('Magento\Store\Model\Website', [], [], '', false); - $this->storeManagerMock->expects($this->any())->method('getWebsite')->will($this->returnValue($websiteMock)); - $this->assertEquals($expected, $this->onepage->saveBilling($data, $customerAddressId)); - } - - public function saveBillingDataProvider() - { - return [ - [ - ['use_for_shipping' => 0], // $data - 1, // $customerAddressId - 1, // $quoteCustomerId - 1, // $addressCustomerId - true, //$isAddress - true, // $validateDataResult - true, // $validateResult - Onepage::METHOD_REGISTER, // $checkoutMethod - 'password', // $customerPassword - 'password', // $confirmPassword - [], // $validationResultMessages - true, // $isEmailAvailable - false, // $isVirtual - false, // $getStepDataResult - [], // $expected - ], - [ - ['use_for_shipping' => 1], // $data - 1, // $customerAddressId - 1, // $quoteCustomerId - 1, // $addressCustomerId - true, //$isAddress - true, // $validateDataResult - true, // $validateResult - Onepage::METHOD_CUSTOMER, // $checkoutMethod - 'password', // $customerPassword - 'password', // $confirmPassword - [], // $validationResultMessages - true, // $isEmailAvailable - false, // $isVirtual - false, // $getStepDataResult - [], // $expected - ] - ]; - } - public function testGetLastOrderId() { $orderIncrementId = 100001; diff --git a/app/code/Magento/Checkout/view/frontend/layout/checkout_index_index.xml b/app/code/Magento/Checkout/view/frontend/layout/checkout_index_index.xml index 696a2089c460c0c9924dc8f64008580a8cb82741..d63de55391c74e623a2f9af03e36372e78973069 100644 --- a/app/code/Magento/Checkout/view/frontend/layout/checkout_index_index.xml +++ b/app/code/Magento/Checkout/view/frontend/layout/checkout_index_index.xml @@ -334,6 +334,9 @@ <item name="displayArea" xsi:type="string">sidebar</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/sidebar</item> + <item name="deps" xsi:type="array"> + <item name="0" xsi:type="string">checkout.steps</item> + </item> </item> <item name="children" xsi:type="array"> <item name="summary" xsi:type="array"> diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js index 84979c5f0cea808d63768be867b5c0e55a736081..2090bdabfe69b2af20f08e340af079cd76d551bd 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js @@ -4,15 +4,26 @@ */ define( [ + 'jquery', 'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/model/url-builder', 'mage/storage', 'Magento_Checkout/js/model/error-processor', 'Magento_Customer/js/model/customer', 'Magento_Checkout/js/action/get-totals', - 'Magento_Checkout/js/model/full-screen-loader' + 'Magento_Checkout/js/model/full-screen-loader', + 'Magento_Checkout/js/action/get-payment-information' ], - function (quote, urlBuilder, storage, errorProcessor, customer, getTotalsAction, fullScreenLoader) { + function ($, + quote, + urlBuilder, + storage, + errorProcessor, + customer, + getTotalsAction, + fullScreenLoader, + getPaymentInformationAction + ) { 'use strict'; return function (messageContainer) { @@ -44,14 +55,21 @@ define( serviceUrl, JSON.stringify(payload) ).done( function () { - getTotalsAction([]); + var deferred = null; + + if (!quote.isVirtual()) { + getTotalsAction([]); + } else { + deferred = $.Deferred(); + getPaymentInformationAction(deferred); + $.when(deferred).done(function () { + fullScreenLoader.stopLoader(); + }); + } } ).fail( function (response) { errorProcessor.process(response, messageContainer); - } - ).always( - function () { fullScreenLoader.stopLoader(); } ); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js index 6be04c3df05fd02b02b22fc06b586fc98c42082e..80d9a5982a6ab575ab68f6500ec72d0e2117d788 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js @@ -133,6 +133,9 @@ define( if (this.selectedAddress() && this.selectedAddress() != newAddressOption) { selectBillingAddress(this.selectedAddress()); checkoutData.setSelectedBillingAddress(this.selectedAddress().getKey()); + if (window.checkoutConfig.reloadOnBillingAddress) { + setBillingAddressAction(globalMessageList); + } } else { this.source.set('params.invalid', false); this.source.trigger(this.dataScopePrefix + '.data.validate'); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index 68f02b5d5722412fa17880c59124cf5ee84cdb03..7c4025a51c2e5a66b37de845cb9f7ccf02273227 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -72,6 +72,12 @@ define([ this.isLoading(addToCartCalls > 0); sidebarInitialized = false; initSidebar(); + + /**TODO: Extra options support. Should be refactored after MAGETWO-43159. */ + setInterval(function(){ + minicart.trigger('contentUpdated'); + }, 500); + }, this); $('[data-block="minicart"]').on('contentLoading', function(event) { addToCartCalls++; diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/list.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/list.js index 7764f5ec9e0c8ddfe55af4847a6d0110becfe765..a65ec36aea72ea2b59f23585b986b49155e868c3 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/list.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/list.js @@ -30,11 +30,16 @@ define([ paymentMethods.subscribe( function (changes) { checkoutDataResolver.resolvePaymentMethod(); + //remove renderer for "deleted" payment methods + _.each(changes, function (change) { + if (change.status === 'deleted') { + this.removeRenderer(change.value.method); + } + }, this); + //add renderer for "added" payment methods _.each(changes, function (change) { if (change.status === 'added') { this.createRenderer(change.value); - } else if (change.status === 'deleted') { - this.removeRenderer(change.value.method); } }, this); }, this, 'arrayChange'); diff --git a/app/code/Magento/Cookie/View/adminhtml/requirejs-config.js b/app/code/Magento/Cookie/view/adminhtml/requirejs-config.js similarity index 100% rename from app/code/Magento/Cookie/View/adminhtml/requirejs-config.js rename to app/code/Magento/Cookie/view/adminhtml/requirejs-config.js diff --git a/app/code/Magento/Cookie/View/frontend/layout/default.xml b/app/code/Magento/Cookie/view/frontend/layout/default.xml similarity index 100% rename from app/code/Magento/Cookie/View/frontend/layout/default.xml rename to app/code/Magento/Cookie/view/frontend/layout/default.xml diff --git a/app/code/Magento/Cookie/View/frontend/requirejs-config.js b/app/code/Magento/Cookie/view/frontend/requirejs-config.js similarity index 100% rename from app/code/Magento/Cookie/View/frontend/requirejs-config.js rename to app/code/Magento/Cookie/view/frontend/requirejs-config.js diff --git a/app/code/Magento/Cookie/View/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml similarity index 100% rename from app/code/Magento/Cookie/View/frontend/templates/html/notices.phtml rename to app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml diff --git a/app/code/Magento/Cookie/View/frontend/templates/require_cookie.phtml b/app/code/Magento/Cookie/view/frontend/templates/require_cookie.phtml similarity index 100% rename from app/code/Magento/Cookie/View/frontend/templates/require_cookie.phtml rename to app/code/Magento/Cookie/view/frontend/templates/require_cookie.phtml diff --git a/app/code/Magento/Cookie/View/frontend/web/js/notices.js b/app/code/Magento/Cookie/view/frontend/web/js/notices.js similarity index 97% rename from app/code/Magento/Cookie/View/frontend/web/js/notices.js rename to app/code/Magento/Cookie/view/frontend/web/js/notices.js index 09094b971a26649ad5215ce28f573579dd15ae93..5c82ce314686ad05421be3b53447b6a4486aafa2 100644 --- a/app/code/Magento/Cookie/View/frontend/web/js/notices.js +++ b/app/code/Magento/Cookie/view/frontend/web/js/notices.js @@ -8,6 +8,7 @@ define([ "jquery/ui", "mage/cookies" ], function($){ + "use strict"; $.widget('mage.cookieNotices', { _create: function() { @@ -18,6 +19,7 @@ define([ } $(this.options.cookieAllowButtonSelector).on('click', $.proxy(function() { var cookieExpires = new Date(new Date().getTime() + this.options.cookieLifetime * 1000); + $.mage.cookies.set(this.options.cookieName, this.options.cookieValue, {expires: cookieExpires}); if ($.mage.cookies.get(this.options.cookieName)) { window.location.reload(); @@ -29,4 +31,4 @@ define([ }); return $.mage.cookieNotices; -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Cookie/View/frontend/web/js/require-cookie.js b/app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js similarity index 99% rename from app/code/Magento/Cookie/View/frontend/web/js/require-cookie.js rename to app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js index 22abfc82d56a686059fad13a7e141d8e9c7a22cc..6aedd8ac9b5b15f12e9e08c25fb05bb02805bbc0 100644 --- a/app/code/Magento/Cookie/View/frontend/web/js/require-cookie.js +++ b/app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js @@ -30,6 +30,7 @@ define([ */ _bind: function() { var events = {}; + $.each(this.options.triggers, function(index, value) { events['click ' + value] = '_checkCookie'; }); @@ -50,4 +51,4 @@ define([ }); return $.mage.requireCookie; -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php index 2faeca50ad9e158b75edac0a55191e5c40b79800..7b6191eb2556b8e4c6eb2325519a96fbc23ee21b 100644 --- a/app/code/Magento/Customer/Controller/Account/LoginPost.php +++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php @@ -92,15 +92,12 @@ class LoginPost extends Action implements AccountInterface ); $this->messageManager->addError($message); $this->session->setUsername($login['username']); - } - catch (AuthenticationException $e) { + } catch (AuthenticationException $e) { $message = __('Invalid login or password.'); $this->messageManager->addError($message); $this->session->setUsername($login['username']); } catch (\Exception $e) { - $this->messageManager->addError( - __('Something went wrong while validating the login and password.') - ); + $this->messageManager->addError(__('Invalid login or password.')); } } else { $this->messageManager->addError(__('A login and a password are required.')); diff --git a/app/code/Magento/Customer/Controller/Address/FormPost.php b/app/code/Magento/Customer/Controller/Address/FormPost.php index a3275491f6c3e4056659cbb96ded6bf7541bbd31..9360ca0f7d6d369f589a534a1cba0bd7ca489270 100644 --- a/app/code/Magento/Customer/Controller/Address/FormPost.php +++ b/app/code/Magento/Customer/Controller/Address/FormPost.php @@ -106,7 +106,6 @@ class FormPost extends \Magento\Customer\Controller\Address array_merge($existingAddressData, $attributeValues), '\Magento\Customer\Api\Data\AddressInterface' ); - $addressDataObject->setCustomerId($this->_getSession()->getCustomerId()) ->setIsDefaultBilling($this->getRequest()->getParam('default_billing', false)) ->setIsDefaultShipping($this->getRequest()->getParam('default_shipping', false)); @@ -118,12 +117,16 @@ class FormPost extends \Magento\Customer\Controller\Address * Retrieve existing address data * * @return array + * @throws \Exception */ protected function getExistingAddressData() { $existingAddressData = []; if ($addressId = $this->getRequest()->getParam('id')) { $existingAddress = $this->_addressRepository->getById($addressId); + if ($existingAddress->getCustomerId() !== $this->_getSession()->getCustomerId()) { + throw new \Exception(); + } $existingAddressData = $this->_dataProcessor->buildOutputDataArray( $existingAddress, '\Magento\Customer\Api\Data\AddressInterface' @@ -175,6 +178,7 @@ class FormPost extends \Magento\Customer\Controller\Address */ public function execute() { + $redirectUrl = null; if (!$this->_formKeyValidator->validate($this->getRequest())) { return $this->resultRedirectFactory->create()->setPath('*/*/'); } @@ -198,11 +202,16 @@ class FormPost extends \Magento\Customer\Controller\Address $this->messageManager->addError($error->getMessage()); } } catch (\Exception $e) { + $redirectUrl = $this->_buildUrl('*/*/index'); $this->messageManager->addException($e, __('We can\'t save the address.')); } - $this->_getSession()->setAddressFormData($this->getRequest()->getPostValue()); - $url = $this->_buildUrl('*/*/edit', ['id' => $this->getRequest()->getParam('id')]); + $url = $redirectUrl; + if (!$redirectUrl) { + $this->_getSession()->setAddressFormData($this->getRequest()->getPostValue()); + $url = $this->_buildUrl('*/*/edit', ['id' => $this->getRequest()->getParam('id')]); + } + return $this->resultRedirectFactory->create()->setUrl($this->_redirect->error($url)); } } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat/Validate.php b/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat/Validate.php index b20ff74c9039ffb4a623a9e2c2931f50a9d7eb41..f1f638a852e2e21d213cd0bb6a89b49f69a7695a 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat/Validate.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat/Validate.php @@ -1,40 +1,45 @@ <?php /** - * - * Copyright © 2015 Magento. All rights reserved. + * * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Customer\Controller\Adminhtml\System\Config\Validatevat; +use Magento\Framework\Controller\Result\JsonFactory; + class Validate extends \Magento\Customer\Controller\Adminhtml\System\Config\Validatevat { /** - * @var \Magento\Framework\Controller\Result\RawFactory + * @var JsonFactory */ - protected $resultRawFactory; + protected $resultJsonFactory; /** * @param \Magento\Backend\App\Action\Context $context - * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory + * @param JsonFactory $resultJsonFactory */ public function __construct( \Magento\Backend\App\Action\Context $context, - \Magento\Framework\Controller\Result\RawFactory $resultRawFactory + JsonFactory $resultJsonFactory ) { parent::__construct($context); - $this->resultRawFactory = $resultRawFactory; + $this->resultJsonFactory = $resultJsonFactory; } /** * Check whether vat is valid * - * @return \Magento\Framework\Controller\Result\Raw + * @return \Magento\Framework\Controller\Result\Json */ public function execute() { $result = $this->_validate(); - /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */ - $resultRaw = $this->resultRawFactory->create(); - return $resultRaw->setContents((int)$result->getIsValid()); + + /** @var \Magento\Framework\Controller\Result\Json $resultJson */ + $resultJson = $this->resultJsonFactory->create(); + return $resultJson->setData([ + 'valid' => (int)$result->getIsValid(), + 'message' => $result->getRequestMessage(), + ]); } } diff --git a/app/code/Magento/Customer/Controller/Ajax/Login.php b/app/code/Magento/Customer/Controller/Ajax/Login.php index 8491d5b08e4092774ed5b441d6d0010c63456c80..4258ebf1ef0e18d1c4042425036a343860e8ab38 100644 --- a/app/code/Magento/Customer/Controller/Ajax/Login.php +++ b/app/code/Magento/Customer/Controller/Ajax/Login.php @@ -116,7 +116,7 @@ class Login extends \Magento\Framework\App\Action\Action } catch (\Exception $e) { $response = [ 'errors' => true, - 'message' => __('Something went wrong while validating the login and password.') + 'message' => __('Invalid login or password.') ]; } /** @var \Magento\Framework\Controller\Result\Json $resultJson */ diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php index 53cd1bcc12a9af2777b734a6af62f65bce1c50af..4516a33962aeaf0dc49c9494185833f9b70da240 100644 --- a/app/code/Magento/Customer/Model/Customer.php +++ b/app/code/Magento/Customer/Model/Customer.php @@ -22,7 +22,7 @@ use Magento\Framework\Indexer\StateInterface; * Customer model * * @method int getWebsiteId() getWebsiteId() - * @method Customer setWebsiteId(int) + * @method Customer setWebsiteId($value) * @method int getStoreId() getStoreId() * @method string getEmail() getEmail() * @method ResourceCustomer _getResource() diff --git a/app/code/Magento/Customer/Model/Vat.php b/app/code/Magento/Customer/Model/Vat.php index 78fd927507f72990fd8d637d5cbe7de8ac7891de..43c883b5d0e6947b4a94ef95f1d55a3a1273d19c 100644 --- a/app/code/Magento/Customer/Model/Vat.php +++ b/app/code/Magento/Customer/Model/Vat.php @@ -166,7 +166,8 @@ class Vat 'is_valid' => false, 'request_date' => '', 'request_identifier' => '', - 'request_success' => false + 'request_success' => false, + 'request_message' => __('Error during VAT Number verification.'), ]); if (!extension_loaded('soap')) { @@ -194,6 +195,12 @@ class Vat $gatewayResponse->setRequestDate((string)$result->requestDate); $gatewayResponse->setRequestIdentifier((string)$result->requestIdentifier); $gatewayResponse->setRequestSuccess(true); + + if ($gatewayResponse->getIsValid()) { + $gatewayResponse->setRequestMessage(__('VAT Number is valid.')); + } else { + $gatewayResponse->setRequestMessage(__('Please enter a valid VAT number.')); + } } catch (\Exception $exception) { $gatewayResponse->setIsValid(false); $gatewayResponse->setRequestDate(''); diff --git a/app/code/Magento/Customer/Setup/UpgradeData.php b/app/code/Magento/Customer/Setup/UpgradeData.php index 7f43ee046bdd2afe812cc15260a87976a8013047..1f4da520fd0b28394e89e32e1a5cf04a4cfd580e 100644 --- a/app/code/Magento/Customer/Setup/UpgradeData.php +++ b/app/code/Magento/Customer/Setup/UpgradeData.php @@ -286,6 +286,13 @@ class UpgradeData implements UpgradeDataInterface ); } + if (version_compare($context->getVersion(), '2.0.6', '<')) { + $setup->getConnection()->delete( + $setup->getTable('customer_form_attribute'), + ['form_code = ?' => 'checkout_register'] + ); + } + $indexer = $this->indexerRegistry->get(Customer::CUSTOMER_GRID_INDEXER_ID); $indexer->reindexAll(); $this->eavConfig->clear(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php index 6c2d57a9f95a8f3a098600fb66fb7c442e429625..e71e413d7e11738df8aa86059139958cd34584d8 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php @@ -423,7 +423,7 @@ class LoginPostTest extends \PHPUnit_Framework_TestCase case '\Exception': $this->messageManager->expects($this->once()) ->method('addError') - ->with(__('Something went wrong while validating the login and password.')) + ->with(__('Invalid login or password.')) ->willReturnSelf(); break; } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Address/FormPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Address/FormPostTest.php index 3b351f5160cb0a7cdf58cf86f47438887b94afa4..39fa2018cff7a821bf4fbfa42055ed74aec74986 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Address/FormPostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Address/FormPostTest.php @@ -528,7 +528,10 @@ class FormPostTest extends \PHPUnit_Framework_TestCase ], ]); - $this->session->expects($this->once()) + $this->session->expects($this->atLeastOnce()) + ->method('getCustomerId') + ->willReturn($customerId); + $this->addressData->expects($this->once()) ->method('getCustomerId') ->willReturn($customerId); @@ -682,11 +685,11 @@ class FormPostTest extends \PHPUnit_Framework_TestCase $this->request->expects($this->once()) ->method('isPost') ->willReturn(true); - $this->request->expects($this->exactly(2)) + $this->request->expects($this->once()) ->method('getParam') ->with('id') ->willReturn($addressId); - $this->request->expects($this->once()) + $this->request->expects($this->never()) ->method('getPostValue') ->willReturn($postValue); @@ -701,7 +704,7 @@ class FormPostTest extends \PHPUnit_Framework_TestCase ->with($exception, __('We can\'t save the address.')) ->willReturnSelf(); - $this->session->expects($this->once()) + $this->session->expects($this->never()) ->method('setAddressFormData') ->with($postValue) ->willReturnSelf(); @@ -710,7 +713,7 @@ class FormPostTest extends \PHPUnit_Framework_TestCase ->getMockForAbstractClass(); $urlBuilder->expects($this->once()) ->method('getUrl') - ->with('*/*/edit', ['id' => $addressId]) + ->with('*/*/index') ->willReturn($url); $this->objectManager->expects($this->once()) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/System/Config/Validatevat/ValidateTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/System/Config/Validatevat/ValidateTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ac5625eadef26d993703ae10a3a29d25d43653ec --- /dev/null +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/System/Config/Validatevat/ValidateTest.php @@ -0,0 +1,130 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Customer\Test\Unit\Controller\Adminhtml\System\Config\Validatevat; + +class ValidateTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Customer\Controller\Adminhtml\System\Config\Validatevat\Validate + */ + protected $controller; + + /** + * @var \Magento\Backend\App\Action\Context + */ + protected $context; + + /** + * @var \Magento\Framework\Controller\Result\Json | \PHPUnit_Framework_MockObject_MockObject + */ + protected $resultJson; + + /** + * @var \Magento\Framework\ObjectManagerInterface | \PHPUnit_Framework_MockObject_MockObject + */ + protected $objectManager; + + /** + * @var \Magento\Framework\App\Request\Http | \PHPUnit_Framework_MockObject_MockObject + */ + protected $request; + + protected function setUp() + { + $resultJsonFactory = $this->mockResultJson(); + + $this->request = $this->getMockBuilder('Magento\Framework\App\Request\Http') + ->disableOriginalConstructor() + ->getMock(); + + $this->objectManager = $this->getMockBuilder('Magento\Framework\ObjectManagerInterface') + ->getMockForAbstractClass(); + + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->context = $objectManager->getObject( + 'Magento\Backend\App\Action\Context', + [ + 'request' => $this->request, + 'objectManager' => $this->objectManager, + ] + ); + $this->controller = $objectManager->getObject( + 'Magento\Customer\Controller\Adminhtml\System\Config\Validatevat\Validate', + [ + 'context' => $this->context, + 'resultJsonFactory' => $resultJsonFactory, + ] + ); + } + + public function testExecute() + { + $country = 'US'; + $vat = '123456789'; + + $isValid = true; + $requestMessage = 'test'; + + $json = '{"valid":' . (int)$isValid . ',"message":"' . $requestMessage . '"}'; + + $gatewayResponse = new \Magento\Framework\DataObject([ + 'is_valid' => $isValid, + 'request_message' => $requestMessage, + ]); + + $this->request->expects($this->any()) + ->method('getParam') + ->willReturnMap([ + ['country', null, $country], + ['vat', null, $vat], + ]); + + $vatMock = $this->getMockBuilder('Magento\Customer\Model\Vat') + ->disableOriginalConstructor() + ->getMock(); + + $vatMock->expects($this->once()) + ->method('checkVatNumber') + ->with($country, $vat) + ->willReturn($gatewayResponse); + + $this->objectManager->expects($this->once()) + ->method('get') + ->with('Magento\Customer\Model\Vat') + ->willReturn($vatMock); + + $this->resultJson->expects($this->once()) + ->method('setData') + ->with([ + 'valid' => $gatewayResponse->getIsValid(), + 'message' => $gatewayResponse->getRequestMessage() + ]) + ->willReturn($json); + + $this->assertEquals($json, $this->controller->execute()); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function mockResultJson() + { + $this->resultJson = $this->getMockBuilder('Magento\Framework\Controller\Result\Json') + ->disableOriginalConstructor() + ->getMock(); + + $resultJsonFactory = $this->getMockBuilder('Magento\Framework\Controller\Result\JsonFactory') + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $resultJsonFactory->expects($this->any()) + ->method('create') + ->willReturn($this->resultJson); + + return $resultJsonFactory; + } +} diff --git a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml index d9916cb30d0d24873fa52d22c669268651caab7d..208394342e1f4e3a3db8363077a020a275cbccc8 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml @@ -27,11 +27,13 @@ require(['prototype'], function(){ new Ajax.Request('<?php /* @escapeNotVerified */ echo $block->getAjaxUrl() ?>', { parameters: params, onSuccess: function(response) { - result = '<?php /* @escapeNotVerified */ echo __('Please enter a valid VAT number.') ?>'; + var result = '<?php /* @escapeNotVerified */ echo __('Error during VAT Number verification.') ?>'; try { - response = response.responseText; - if (response == 1) { - result = '<?php /* @escapeNotVerified */ echo __('VAT Number is valid.') ?>'; + if (response.responseText.isJSON()) { + response = response.responseText.evalJSON(); + result = response.message; + } + if (response.valid == 1) { validationMessage.removeClassName('hidden').addClassName('success') } else { validationMessage.removeClassName('hidden').addClassName('error') diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml index ade28198142c2e515ab19be9c1f4ad6f4a67832b..74b855e01b140d3a9f93e922c494b9e10b0be65f 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml @@ -7,7 +7,7 @@ // @codingStandardsIgnoreFile /** - * Template for block \Magento\Customer\Block\Adminhtml\Edit\Tab\View\Status\PersonalInfo + * @var $block \Magento\Customer\Block\Adminhtml\Edit\Tab\View\PersonalInfo */ $lastLoginDateAdmin = $block->getLastLoginDate(); diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index f4f79932d397cd5ee11cc9a4ad1435547efcac1c..bfec0bf920246edbbacbeba286727b53d23b0c30 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -107,6 +107,9 @@ define([ if (_.isEmpty(storage.keys())) { this.reload([], false); } else if (this.needReload()) { + _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) { + buffer.notify(sectionName, sectionData); + }); this.reload(this.getExpiredKeys(), false); } else { _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) { diff --git a/app/code/Magento/CustomerImportExport/etc/import.xml b/app/code/Magento/CustomerImportExport/etc/import.xml index 8a0fa98d2b2053c664fb771ebbf04fdefc53341a..5c625b53804b22c0ffb36eede408321c6164dabd 100644 --- a/app/code/Magento/CustomerImportExport/etc/import.xml +++ b/app/code/Magento/CustomerImportExport/etc/import.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_ImportExport:etc/import.xsd"> - <entity name="customer_composite" label="Customers" model="Magento\CustomerImportExport\Model\Import\CustomerComposite" behaviorModel="Magento\ImportExport\Model\Source\Import\Behavior\Basic" /> + <entity name="customer_composite" label="Customers and Addresses (single file)" model="Magento\CustomerImportExport\Model\Import\CustomerComposite" behaviorModel="Magento\ImportExport\Model\Source\Import\Behavior\Basic" /> <entity name="customer" label="Customers Main File" model="Magento\CustomerImportExport\Model\Import\Customer" behaviorModel="Magento\ImportExport\Model\Source\Import\Behavior\Custom" /> <entity name="customer_address" label="Customer Addresses" model="Magento\CustomerImportExport\Model\Import\Address" behaviorModel="Magento\ImportExport\Model\Source\Import\Behavior\Custom" /> </config> diff --git a/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php b/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php index 8bbdbef28307a9d0a8fd6ae8ef5d2f14808ed5a0..efd63ae579a5c9408560825c0118b8525b4d4d82 100644 --- a/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php +++ b/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php @@ -31,8 +31,9 @@ class CountryProvider */ public function getCountry(Quote $quote) { - return $quote->isVirtual() - ? $this->directoryHelper->getDefaultCountry() - : $quote->getShippingAddress()->getCountry(); + $address = $quote->isVirtual() ? $quote->getBillingAddress() : $quote->getShippingAddress(); + return $address + ? $address->getCountry() + : $this->directoryHelper->getDefaultCountry(); } } diff --git a/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php b/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php index 13f1ad7d41451b30dc1e7c5a5fb8afab37d755e2..89fac656c32c26e2e679b285bbe9111944c9ea9e 100644 --- a/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php +++ b/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php @@ -33,14 +33,27 @@ class CountryProviderTest extends \PHPUnit_Framework_TestCase $this->assertEquals(1, $this->model->getCountry($quoteMock)); } - public function testGetCountryForVirtualQuote() + public function testGetCountryForVirtualQuoteWhenBillingAddressNotExist() { $quoteMock = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false, false); $quoteMock->expects($this->once())->method('isVirtual')->willReturn(true); $addressMock = $this->getMock('Magento\Quote\Model\Quote\Address', [], [], '', false, false); $addressMock->expects($this->never())->method('getCountry'); $quoteMock->expects($this->never())->method('getShippingAddress'); + $quoteMock->expects($this->once())->method('getBillingAddress')->willReturn(null); $this->directoryMock->expects($this->once())->method('getDefaultCountry')->willReturn(10); $this->assertEquals(10, $this->model->getCountry($quoteMock)); } + + public function testGetCountryForVirtualQuoteWhenBillingAddressExist() + { + $quoteMock = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false, false); + $quoteMock->expects($this->once())->method('isVirtual')->willReturn(true); + $addressMock = $this->getMock('Magento\Quote\Model\Quote\Address', [], [], '', false, false); + $addressMock->expects($this->once())->method('getCountry')->willReturn(10); + $quoteMock->expects($this->never())->method('getShippingAddress'); + $quoteMock->expects($this->once())->method('getBillingAddress')->willReturn($addressMock); + $this->directoryMock->expects($this->never())->method('getDefaultCountry'); + $this->assertEquals(10, $this->model->getCountry($quoteMock)); + } } diff --git a/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml b/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml index 9980563201013c5afd144b026df184fcfaac7738..2ce70dcad46a2f0b06e69eecf856cc6fe6bb9c05 100644 --- a/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml +++ b/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml @@ -9,10 +9,11 @@ * @var \Magento\Payment\Block\Info $block * @see \Magento\Payment\Block\Info */ +$specificInfo = $block->getSpecificInformation(); ?> <?php echo $block->escapeHtml($block->getMethod()->getTitle()); ?> -<?php if ($_specificInfo = $block->getSpecificInformation()):?> +<?php if ($specificInfo): ?> <table class="data-table admin__table-secondary"> <?php foreach ($specificInfo as $label => $value):?> <tr> 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 92c44c6c5d4b9ccadda17fe6fbbec87b46ad3451..1bb248e6fd5662bced43e2f7ee9d4c5a942a1f69 100644 --- a/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml +++ b/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml @@ -10,6 +10,7 @@ $code = $block->getMethodCode(); $ccType = $block->getInfoData('cc_type'); $ccExpYear = $block->getInfoData('cc_exp_year'); +$ccExpMonth = $block->getInfoData('cc_exp_month'); ?> <!-- IFRAME for request to Payment Gateway --> @@ -87,11 +88,10 @@ $ccExpYear = $block->getInfoData('cc_exp_year'); data-container="<?php /* @noEscape */ echo $code; ?>-cc-month" class="admin__control-select admin__control-select-month" data-validate='{required:true, "validate-cc-exp":"#<?php /* @noEscape */ echo $code; ?>_expiration_yr"}'> - <?php $_ccExpMonth = $block->getInfoData('cc_exp_month') ?> <?php foreach ($block->getCcMonths() as $k => $v): ?> <option - value="<?php /* @noEscape */ echo $k ? $block->escapeHtml($k) : '' ?>" - <?php if ($k == $_ccExpMonth): ?> selected="selected"<?php endif ?>> + value="<?php /* @noEscape */ echo $k ? $block->escapeHtml($k) : ''; ?>" + <?php if ($k == $ccExpMonth): ?> selected="selected"<?php endif; ?>> <?php echo $block->escapeHtml($v); ?> </option> <?php endforeach ?> diff --git a/app/code/Magento/Payment/view/frontend/templates/transparent/form.phtml b/app/code/Magento/Payment/view/frontend/templates/transparent/form.phtml index eeaa13ee814cc4d420fdbbc0ec7e66eb84c58aa7..64ea503996cd280d8b29dc154b4dc20e9e47f69d 100644 --- a/app/code/Magento/Payment/view/frontend/templates/transparent/form.phtml +++ b/app/code/Magento/Payment/view/frontend/templates/transparent/form.phtml @@ -10,6 +10,7 @@ $code = $block->getMethodCode(); $ccExpMonth = $block->getInfoData('cc_exp_month'); $ccExpYear = $block->getInfoData('cc_exp_year'); +$ccType = $block->getInfoData('cc_type'); $content = '<img src=\"' . $block->getViewFileUrl('Magento_Checkout::cvv.png') . '\" alt=\"' . $block->escapeHtml(__('Card Verification Number Visual Reference')) . '\" title=\"' . $block->escapeHtml(__('Card Verification Number Visual Reference')) . '\" />'; @@ -46,10 +47,9 @@ $content = '<img src=\"' . $block->getViewFileUrl('Magento_Checkout::cvv.png') . "validate-cc-type-select":"#<?php /* @noEscape */ echo $code; ?>_cc_number" }'> <option value=""><?php echo $block->escapeHtml(__('--Please Select--'));?></option> - <?php $_ccType = $block->getInfoData('cc_type') ?> <?php foreach ($block->getCcAvailableTypes() as $typeCode => $typeName): ?> <option value="<?php echo $block->escapeHtml($typeCode); ?>" - <?php if ($typeCode == $_ccType): ?> selected="selected"<?php endif; ?>> + <?php if ($typeCode == $ccType): ?> selected="selected"<?php endif; ?>> <?php echo $block->escapeHtml($typeName); ?></option> <?php endforeach ?> </select> diff --git a/app/code/Magento/Paypal/Model/Express/Checkout.php b/app/code/Magento/Paypal/Model/Express/Checkout.php index d9b9d986f1b31c0db42b578c6074e0f53dbc5453..d3b0cf72fc76bf9047b4a82e4cdc663380834123 100644 --- a/app/code/Magento/Paypal/Model/Express/Checkout.php +++ b/app/code/Magento/Paypal/Model/Express/Checkout.php @@ -1191,10 +1191,10 @@ class Checkout /** * Set shipping options to api * @param \Magento\Paypal\Model\Cart $cart - * @param \Magento\Quote\Model\Quote\Address $address + * @param \Magento\Quote\Model\Quote\Address|null $address * @return void */ - private function setShippingOptions(PaypalCart $cart, Address $address) + private function setShippingOptions(PaypalCart $cart, Address $address = null) { // for included tax always disable line items (related to paypal amount rounding problem) $this->_api->setIsLineItemsEnabled($this->_config->getValue(PaypalConfig::TRANSFER_CART_LINE_ITEMS)); diff --git a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflowpro-method.js b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflowpro-method.js index a7a031848124e90d904a433912a4cdc722a27ed6..f0095877bbc9cb3a3831de67668c3234a287ec75 100644 --- a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflowpro-method.js +++ b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflowpro-method.js @@ -51,9 +51,8 @@ define( placeOrder: function () { var self = this; - fullScreenLoader.startLoader(); - if (this.validateHandler() && additionalValidators.validate()) { + fullScreenLoader.startLoader(); this.isPlaceOrderActionAllowed(false); $.when(setPaymentInformationAction(this.messageContainer, { 'method': self.getCode() diff --git a/app/code/Magento/ProductVideo/Block/Adminhtml/Product/Edit/NewVideo.php b/app/code/Magento/ProductVideo/Block/Adminhtml/Product/Edit/NewVideo.php index 6be990b549ceaed78dd80e8a6078d97167e16c5f..fbc2132db4999b1ee5993bb86656f4f43142f606 100644 --- a/app/code/Magento/ProductVideo/Block/Adminhtml/Product/Edit/NewVideo.php +++ b/app/code/Magento/ProductVideo/Block/Adminhtml/Product/Edit/NewVideo.php @@ -12,6 +12,11 @@ use Magento\Framework\Data\Form\Element\Fieldset; */ class NewVideo extends \Magento\Backend\Block\Widget\Form\Generic { + /** + * @var \Magento\ProductVideo\Helper\Media + */ + protected $mediaHelper; + /** * @var \Magento\Framework\Json\EncoderInterface */ @@ -19,6 +24,7 @@ class NewVideo extends \Magento\Backend\Block\Widget\Form\Generic /** * @param \Magento\Backend\Block\Template\Context $context + * @param \Magento\ProductVideo\Helper\Media $mediaHelper * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Data\FormFactory $formFactory @@ -29,9 +35,11 @@ class NewVideo extends \Magento\Backend\Block\Widget\Form\Generic \Magento\Framework\Registry $registry, \Magento\Framework\Data\FormFactory $formFactory, \Magento\Framework\Json\EncoderInterface $jsonEncoder, + \Magento\ProductVideo\Helper\Media $mediaHelper, array $data = [] ) { parent::__construct($context, $registry, $formFactory, $data); + $this->mediaHelper = $mediaHelper; $this->jsonEncoder = $jsonEncoder; $this->setUseContainer(true); } @@ -171,6 +179,11 @@ class NewVideo extends \Magento\Backend\Block\Widget\Form\Generic $this->setForm($form); } + /** + * Get html id + * + * @return mixed + */ public function getHtmlId() { if (null === $this->getData('id')) { @@ -180,6 +193,8 @@ class NewVideo extends \Magento\Backend\Block\Widget\Form\Generic } /** + * Get widget options + * * @return string */ public function getWidgetOptions() @@ -189,6 +204,7 @@ class NewVideo extends \Magento\Backend\Block\Widget\Form\Generic 'saveVideoUrl' => $this->getUrl('catalog/product_gallery/upload'), 'saveRemoteVideoUrl' => $this->getUrl('product_video/product_gallery/retrieveImage'), 'htmlId' => $this->getHtmlId(), + 'youTubeApiKey' => $this->mediaHelper->getYouTubeApiKey() ] ); } @@ -214,8 +230,9 @@ class NewVideo extends \Magento\Backend\Block\Widget\Form\Generic */ protected function addMediaRoleAttributes(Fieldset $fieldset) { + $fieldset->addField('roleLabel', 'note', ['text' => __('Role')]); $mediaRoles = $this->getProduct()->getMediaAttributes(); - asort($mediaRoles); + ksort($mediaRoles); foreach ($mediaRoles as $mediaRole) { $fieldset->addField( 'video_' . $mediaRole->getAttributeCode(), diff --git a/app/code/Magento/ProductVideo/Helper/Media.php b/app/code/Magento/ProductVideo/Helper/Media.php index 5d7abc74aedc180cdd055c6571564fcefe39a012..657c81f3aaedeac0506cdf976f216b610a318f4a 100644 --- a/app/code/Magento/ProductVideo/Helper/Media.php +++ b/app/code/Magento/ProductVideo/Helper/Media.php @@ -7,6 +7,7 @@ namespace Magento\ProductVideo\Helper; use Magento\Framework\App\Area; +use Magento\Framework\App\Helper\Context; use Magento\Framework\View\ConfigInterface; use Magento\Framework\View\DesignInterface; @@ -40,6 +41,11 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper */ const MEDIA_TYPE_CONFIG_NODE = 'videos'; + /** + * Configuration path + */ + const XML_PATH_YOUTUBE_API_KEY = 'catalog/product_video/youtube_api_key'; + /** * @var ConfigInterface */ @@ -60,11 +66,14 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper /** * @param ConfigInterface $configInterface * @param DesignInterface $designInterface + * @param Context $context */ public function __construct( ConfigInterface $configInterface, - DesignInterface $designInterface + DesignInterface $designInterface, + Context $context ) { + parent::__construct($context); $this->viewConfig = $configInterface; $this->currentTheme = $designInterface->getDesignTheme(); $this->initConfig(); @@ -139,4 +148,14 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper return $videoAttributes[self::NODE_CONFIG_VIDEO_AUTO_RESTART]; } } + + /** + * Retrieve YouTube API key + * + * @return string + */ + public function getYouTubeApiKey() + { + return $this->scopeConfig->getValue(self::XML_PATH_YOUTUBE_API_KEY); + } } diff --git a/app/code/Magento/ProductVideo/Test/Unit/Block/Adminhtml/Product/Edit/NewVideoTest.php b/app/code/Magento/ProductVideo/Test/Unit/Block/Adminhtml/Product/Edit/NewVideoTest.php index 55fe3af0f92a436b1757a96005a84a3992cd1e14..e07d3144baa89d6cdb5c93e99f18b71e32980042 100644 --- a/app/code/Magento/ProductVideo/Test/Unit/Block/Adminhtml/Product/Edit/NewVideoTest.php +++ b/app/code/Magento/ProductVideo/Test/Unit/Block/Adminhtml/Product/Edit/NewVideoTest.php @@ -86,7 +86,8 @@ class NewVideoTest extends \PHPUnit_Framework_TestCase $value = [ 'saveVideoUrl' => $saveVideoUrl, 'saveRemoteVideoUrl' => $saveRemoteVideoUrl, - 'htmlId' => 'id_' . $rand + 'htmlId' => 'id_' . $rand, + 'youTubeApiKey' => null ]; $this->jsonEncoderMock->expects($this->once())->method('encode')->with( $value diff --git a/app/code/Magento/ProductVideo/etc/adminhtml/system.xml b/app/code/Magento/ProductVideo/etc/adminhtml/system.xml new file mode 100644 index 0000000000000000000000000000000000000000..f475ab5b70d54cb2a671e5cf41c0b1b1116f7d4b --- /dev/null +++ b/app/code/Magento/ProductVideo/etc/adminhtml/system.xml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> + <system> + <section id="catalog"> + <group id="product_video" translate="label" type="text" sortOrder="350" showInDefault="1" showInWebsite="1" showInStore="1"> + <label>Product Video</label> + <field id="youtube_api_key" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> + <label>YouTube API key</label> + </field> + </group> + </section> + </system> +</config> diff --git a/app/code/Magento/ProductVideo/view/adminhtml/layout/catalog_product_new.xml b/app/code/Magento/ProductVideo/view/adminhtml/layout/catalog_product_new.xml index eff4727524c00cbcde913abfb8ca5395199165e7..000134b212f98a4452f89a9efb848d9797a06486 100755 --- a/app/code/Magento/ProductVideo/view/adminhtml/layout/catalog_product_new.xml +++ b/app/code/Magento/ProductVideo/view/adminhtml/layout/catalog_product_new.xml @@ -7,7 +7,6 @@ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <head> - <css src="Magento_ProductVideo::css/productvideo.css"/> <link src="Magento_ProductVideo::js/get-video-information.js"/> </head> <body> diff --git a/app/code/Magento/ProductVideo/view/adminhtml/templates/product/edit/slideout/form.phtml b/app/code/Magento/ProductVideo/view/adminhtml/templates/product/edit/slideout/form.phtml index 6e2418f119622fbf9f5d352bca0afea590eae6c0..50d5324fc43e6b5fadb082b61c5dceee79bed424 100644 --- a/app/code/Magento/ProductVideo/view/adminhtml/templates/product/edit/slideout/form.phtml +++ b/app/code/Magento/ProductVideo/view/adminhtml/templates/product/edit/slideout/form.phtml @@ -17,7 +17,7 @@ }); }); </script> - <div id="video-player-preview-location"> + <div id="video-player-preview-location" class="video-player-sidebar"> <div class="video-player-container"></div> <div class="video-information title"> <label><?php /* @escapeNotVerified */ echo __('Title:') ?> </label><span></span> diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/css/productvideo.css b/app/code/Magento/ProductVideo/view/adminhtml/web/css/productvideo.css deleted file mode 100755 index e2aa3047a68925dd1d7bd50909d12024ac67abc8..0000000000000000000000000000000000000000 --- a/app/code/Magento/ProductVideo/view/adminhtml/web/css/productvideo.css +++ /dev/null @@ -1,261 +0,0 @@ - /** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -.image.video-placeholder { - position: relative; - display: inline-block; - text-decoration: none; -} - -.image.video-placeholder:before { - background: url(../images/gallery-sprite.png) no-repeat left bottom; - content: ''; - position: absolute; - height: 49px; - width: 49px; - left: 50%; - top: 18px; - margin-left: -24px; - opacity: 0.7; - z-index: 1; -} - -.video-placeholder .image-placeholder-text { - font-weight: 400; -} - -.admin__field.field-video_image .admin__field-control, -.admin__field.field-video_small_image .admin__field-control, -.admin__field.field-video_thumbnail .admin__field-control, -.admin__field.field-video_swatch_image .admin__field-control, -.admin__field.field-new_video_disabled .admin__field-control { - width: 82px; - margin-left: calc((100%) * .33333333 - 30px); -} - -.admin__field.field-video_image .admin__field-control input, -.admin__field.field-video_small_image .admin__field-control input, -.admin__field.field-video_thumbnail .admin__field-control input, -.admin__field.field-video_swatch_image .admin__field-control input, -.admin__field.field-new_video_disabled .admin__field-control input { - float: right; -} - -.admin__field.field-video_image .admin__field-label, -.admin__field.field-video_small_image .admin__field-label, -.admin__field.field-video_thumbnail .admin__field-label, -.admin__field.field-video_swatch_image .admin__field-label, -.admin__field.field-new_video_disabled .admin__field-label { - width: 200px; - position: absolute; - margin-left: calc((100%) * .33333333 - 30px + 90px); - left: 0px; -} - -.admin__field.field-video_image .admin__field-label:before, -.admin__field.field-video_small_image .admin__field-label:before, -.admin__field.field-video_thumbnail .admin__field-label:before, -.admin__field.field-video_swatch_image .admin__field-label:before, -.admin__field.field-new_video_disabled .admin__field-label:before { - content: none; -} - -.admin__field.field-video_image .admin__field-label span, -.admin__field.field-video_small_image .admin__field-label span, -.admin__field.field-video_thumbnail .admin__field-label span, -.admin__field.field-video_swatch_image .admin__field-label span, -.admin__field.field-new_video_disabled .admin__field-label span { - float: left; -} - -.admin__field.field-video_image, -.admin__field.field-video_small_image, -.admin__field.field-video_thumbnail, -.admin__field.field-video_swatch_image { - margin-bottom: 20px !important; -} - -.admin__field.field-new_video_disabled { - margin-top: 32px !important; -} - -.admin__field.field-video_image .admin__field-control { - position: relative; -} - -.admin__field.field-video_image .admin__field-control:after { - content: 'Role'; - position: absolute; - color: #000; - width: 34px; - height: 20px; - left: 1px; - top: -2px; - font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; - font-size: 1.4rem; - font-weight: 600; -} - -.preview_hidden_image_input_button { - display: none; -} - -.video-item { - position: relative; -} - -.video-item:after { - content: ''; - position: absolute; - bottom: 0; - right: 0; - background: url(../images/gallery-sprite.png) bottom left; - width: 49px; - height: 40px; - z-index: 3; - left: 0; - top: 10px; - margin: auto; -} - -.mage-new-video-dialog #new_video_form { - width: 65%; - float: left; -} - -.mage-new-video-dialog #video-player-preview-location { - width: 34.99999%; - float: left; -} - -.video-player-container { - width: 100%; - height: 20vw; - margin-bottom: 30px; - border: 1px solid #e3e3e3; - position: relative; -} - -.video-player-container:after { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - margin: auto; - width: 93px; - height: 60px; - background: url(../images/camera.png) no-repeat center; - z-index: 1; -} - -.video-information { - margin-bottom: 7px; - display: none; -} - -.video-information:after { - content: " "; /* Older browser do not support empty content */ - visibility: hidden; - display: block; - height: 0; - clear: both; -} - -.video-information label { - font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; - font-size: 1.4rem; - font-weight: 600; - display: block; - width: 25%; - float: left; - text-align: right; -} - -.video-information span { - font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; - font-size: 1.4rem; - font-weight: 300; - display: block; - width: 74.9999%; - float: left; - padding-left: 20px; -} - -.product-video { - width: 100%; - z-index: 20; - height: 100%; - position: relative; -} - -.image.video-placeholder > button[data-role="add-video-button"], -.image.video-placeholder > button { - width: 100%; - height: 100%; - border: 0; - background: transparent; - z-index: 10; - position: relative; -} - -.add-video-button-container { - float: right; - margin-bottom: 10px; -} - -.admin__field.field.field-new_video_screenshot { - margin-bottom: 5px; -} - -.admin__field.field.field-new_video_screenshot_preview { - margin-bottom: 50px; -} - -.image .action-make-base:after { - -webkit-font-smoothing: antialiased; - font-size: 1.8rem; - line-height: inherit; - color: #9e9e9e; - content: '\e63b'; - font-family: 'Admin Icons'; - vertical-align: middle; - display: inline-block; - font-weight: normal; - overflow: hidden; - speak: none; - text-align: center; - position: absolute; - top: -7px; - left: -4px; -} - -.image .action-make-base:hover:after { - color: #7d7d7d; -} - -.admin__scope-old .gallery .image .action-make-base { - border: 0; - width: 0; - height: 0; - position: absolute; - margin: 0; - bottom: 9px; - right: 9px; - left: auto; - background: transparent; -} - -.image .action-make-base span { - display: none; -} - -.admin__scope-old .base-image .image-label { - display: block; -} - -.image.base-image:hover .image-label { - display: none; -} diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js b/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js index d692aaf4eccf6c56a26f9bbd3e0dea29a125f874..52171f1537a254ef6b19645419a8951bd0b39083 100644 --- a/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js +++ b/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js @@ -322,7 +322,10 @@ require([ $.widget('mage.videoData', { options: { - youtubeKey: 'AIzaSyDwqDWuw1lra-LnpJL2Mr02DYuFmkuRSns' //sample data, change later! + youtubeKey: '', + noKeyErrorTxt: 'You have not entered youtube API key. ' + + 'No information about youtube video will be retrieved.', + eventSource: '' //where is data going from - focus out or click on button }, _REQUEST_VIDEO_INFORMATION_TRIGGER: 'update_video_information', @@ -337,6 +340,11 @@ require([ * @private */ _init: function () { + if (!this.options.youtubeKey && this.options.eventSource === 'click') { + alert({ + content: this.options.noKeyErrorTxt + }); + } this._onRequestHandler(); }, @@ -365,18 +373,58 @@ require([ } /** + * + * @param {Object} data * @private */ function _onYouTubeLoaded(data) { var tmp, uploadedFormatted, - respData; + respData, + createErrorMessage; + + /** + * Create errors message + * + * @returns {String} + */ + createErrorMessage = function () { + var error = data.error, + errors = error.errors, + i, + errLength = errors.length, + tmpError, + errReason, + errorsMessage = []; + + for (i = 0; i < errLength; i++) { + tmpError = errors[i]; + errReason = tmpError.reason; + + if (['keyInvalid'].indexOf(errReason) !== -1) { + errorsMessage.push('Youtube API key is an invalid'); + + break; + } - if (data.items.length < 1) { + errorsMessage.push(tmpError.message); + } + + return 'Video can\'t be shown by reason: ' + $.unique(errorsMessage).join(', '); + }; + + if (data.error && data.error.code === 400) { + this._onRequestError(createErrorMessage()); + + return; + } + + if (!data.items || data.items.length < 1) { this._onRequestError('Video not found'); return; } + tmp = data.items[0]; uploadedFormatted = tmp.snippet.publishedAt.replace('T', ' ').replace(/\..+/g, ''); respData = { @@ -429,8 +477,17 @@ require([ googleapisUrl = 'https://www.googleapis.com/youtube/v3/videos?id=' + id + '&part=snippet,contentDetails,statistics,status&key=' + - this.options.youtubeKey; - $.get(googleapisUrl, $.proxy(_onYouTubeLoaded, this)); + this.options.youtubeKey + '&alt=json&callback=?'; + $.getJSON(googleapisUrl, + { + format: 'json' + }, + $.proxy(_onYouTubeLoaded, self) + ).fail( + function () { + self._onRequestError('Video not found'); + } + ); } else if (type === 'vimeo') { $.getJSON('http://www.vimeo.com/api/v2/video/' + id + '.json?callback=?', { @@ -493,7 +550,8 @@ require([ _validateURL: function (href, forceVideo) { var id, type, - ampersandPosition; + ampersandPosition, + vimeoRegex; if (typeof href !== 'string') { return href; @@ -518,7 +576,10 @@ require([ type = 'youtube'; } else if (href.host.match(/vimeo\.com/)) { type = 'vimeo'; - id = href.pathname.replace(/^\/(video\/)?/, '').replace(/\/.*/, ''); + vimeoRegex = new RegExp(['https?:\\/\\/(?:www\\.)?vimeo.com\\/(?:channels\\/(?:\\w+\\/)', + '?|groups\\/([^\\/]*)\\/videos\\/|album\\/(\\d+)\\/video\\/|)(\\d+)(?:$|\\/|\\?)' + ].join('')); + id = href.href.match(vimeoRegex)[3]; } if ((!id || !type) && forceVideo) { diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js b/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js index 980ac3a2e4ddb814ba445a8e873d12a5846e7982..e5efb668b51e946a2ae44b0ef3c629b0ed8630e8 100644 --- a/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js +++ b/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js @@ -93,7 +93,7 @@ define([ $(this.options.metaData.DOM.uploader).html( '<a href="https://youtube.com/channel/' + this.options.metaData.data.uploaderUrl + - '">' + + '" target="_blank">' + this.options.metaData.data.uploader + '</a>' ); @@ -102,7 +102,7 @@ define([ $(this.options.metaData.DOM.uploader).html( '<a href="' + this.options.metaData.data.uploaderUrl + - '">' + this.options.metaData.data.uploader + + '" target="_blank">' + this.options.metaData.data.uploader + '</a>'); } $('.' + this.options.videoClass).productVideoLoader(); @@ -243,7 +243,10 @@ define([ this._on(events); - this._videoUrlWidget = $(this._videoUrlSelector).videoData(); + this._videoUrlWidget = $(this._videoUrlSelector).videoData({ + youtubeKey: this.options.youTubeApiKey, + eventSource: 'focusout' + }); this._videoInformationGetBtn = $(this._videoInformationBtnSelector); this._videoInformationGetUrlField = $(this._videoUrlSelector); this._videoInformationGetEditBtn = $(this._editVideoBtnSelector); @@ -262,7 +265,10 @@ define([ _onGetVideoInformationClick: function () { this._onlyVideoPlayer = false; this._isEditPage = false; - this._videoInformationGetUrlField.videoData(); + this._videoInformationGetUrlField.videoData({ + youtubeKey: this.options.youTubeApiKey, + eventSource: 'click' + }); this._videoUrlWidget.trigger('update_video_information'); }, @@ -271,7 +277,10 @@ define([ * @private */ _onGetVideoInformationFocusOut: function () { - this._videoInformationGetUrlField.videoData(); + this._videoInformationGetUrlField.videoData({ + youtubeKey: this.options.youTubeApiKey, + eventSource: 'focusout' + }); this._videoUrlWidget.trigger('update_video_information'); }, @@ -282,7 +291,10 @@ define([ _onGetVideoInformationEditClick: function () { this._onlyVideoPlayer = true; this._isEditPage = true; - this._videoInformationGetUrlField.videoData(); + this._videoInformationGetUrlField.videoData({ + youtubeKey: this.options.youTubeApiKey, + eventSource: 'click' + }); this._videoUrlWidget.trigger('update_video_information'); }, diff --git a/app/code/Magento/ProductVideo/view/frontend/layout/catalog_product_view.xml b/app/code/Magento/ProductVideo/view/frontend/layout/catalog_product_view.xml index a8fd6ae7725fbd2078aae76c822a2bcfc48fde12..18417e1619da5d56717ce8602c53bf6359d44ac5 100644 --- a/app/code/Magento/ProductVideo/view/frontend/layout/catalog_product_view.xml +++ b/app/code/Magento/ProductVideo/view/frontend/layout/catalog_product_view.xml @@ -7,7 +7,8 @@ --> <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <head> - <css src="Magento_ProductVideo::css/product-video.css"/> + <link src="Magento_ProductVideo::js/fotorama-add-video-events.js"/> + <link src="Magento_ProductVideo::js/load-player.js"/> </head> <body> <referenceContainer name="product.info.media"> diff --git a/app/code/Magento/ProductVideo/view/frontend/web/css/product-video.css b/app/code/Magento/ProductVideo/view/frontend/web/css/product-video.css deleted file mode 100644 index 0198f8c98ecb9fe70db81e8259a78cc554f4488f..0000000000000000000000000000000000000000 --- a/app/code/Magento/ProductVideo/view/frontend/web/css/product-video.css +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -.fotorama-video-container.video-unplayed:after { - content: ''; - position: absolute; - bottom: 0; - right: 0; - background: url(../img/gallery-sprite.png) bottom right; - width: 100px; - height: 100px; - left: 0; - top: 12px; - margin: auto; -} -.fotorama-video-container .magnify-lens { - display: none !important; -} -.fotorama-video-container.video-unplayed:hover img { - opacity: 0.6; -} -.fotorama-video-container.video-unplayed:hover:after { - transform: scale(1.25); -} -.video-thumb-icon:after { - content: ''; - position: absolute; - bottom: 0; - right: 0; - background: url(../img/gallery-sprite.png) bottom left; - width: 49px; - height: 40px; - left: 0; - top: 10px; - margin: auto; -} -.video-timing { - width: auto; - height: 30px; - background: rgba(0, 0, 0, 0.75); - padding: 0 17px; - color: #fff; - position: absolute; - right: 0; - line-height: 2; - transition: 0.3s; - bottom: -30px; -} -.video-timing.fadeIn { - bottom: 0; -} -.product-video { - position: absolute; - top: 0; - width: 100%; - height: 85%; - margin-top: 15%; -} -.product-video iframe { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 9999; -} -.fotorama__arr.hidden-video { - z-index: -1; -} -.fotorama__video-close { - bottom: 89%; - top: auto; -} diff --git a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js index 8b8f92f5b447b99b22ca364dd5c58e7c148f36a7..3fa62c44903df5eb4163bd8ca9b0aceaccec1ac4 100644 --- a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js +++ b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js @@ -28,16 +28,15 @@ define([ function parseURL(href, forceVideo) { var id, type, - ampersandPosition; + ampersandPosition, + vimeoRegex; /** * Get youtube ID - * @param {String} srchref + * @param {String} srcid * @returns {{}} */ - function _getYoutubeId(srchref) { - var srcid = srchref.search.split('v=')[1]; - + function _getYoutubeId(srcid) { if (srcid) { ampersandPosition = srcid.indexOf('&'); @@ -69,7 +68,10 @@ define([ type = 'youtube'; } else if (href.host.match(/vimeo\.com/)) { type = 'vimeo'; - id = href.pathname.replace(/^\/(video\/)?/, '').replace(/\/.*/, ''); + vimeoRegex = new RegExp(['https?:\\/\\/(?:www\\.)?vimeo.com\\/(?:channels\\/(?:\\w+\\/)', + '?|groups\\/([^\\/]*)\\/videos\\/|album\\/(\\d+)\\/video\\/|)(\\d+)(?:$|\\/|\\?)' + ].join('')); + id = href.href.match(vimeoRegex)[3]; } if ((!id || !type) && forceVideo) { @@ -283,7 +285,6 @@ define([ _isVideoBase: function () { var allVideoData = this.options.VideoData, videoItem, - videoSettings, allVideoDataKeys, key, i; @@ -293,10 +294,9 @@ define([ for (i = 0; i < allVideoDataKeys.length; i++) { key = allVideoDataKeys[i]; videoItem = allVideoData[key]; - videoSettings = allVideoData[videoItem]; if ( - videoSettings.mediaType === this.VID && videoSettings.isBase && + videoItem.mediaType === this.VID && videoItem.isBase && this.options.VideoSettings[0].playIfBase ) { this.Base = true; diff --git a/app/code/Magento/Ui/Component/Form/Element/MultiSelect.php b/app/code/Magento/Ui/Component/Form/Element/MultiSelect.php new file mode 100644 index 0000000000000000000000000000000000000000..93fd7f600e0f3a95032164f880a0cc46ba3b437a --- /dev/null +++ b/app/code/Magento/Ui/Component/Form/Element/MultiSelect.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Ui\Component\Form\Element; + +class MultiSelect extends Select +{ + const NAME = 'multiselect'; + + const DEFAULT_SIZE = 6; + + /** + * @inheritDoc + */ + public function prepare() + { + $config['size'] = self::DEFAULT_SIZE; + $this->setData('config', array_replace_recursive((array)$this->getData('config'), $config)); + parent::prepare(); + } +} diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml index b8485998fec512fafd41dc1aa3dcf606a16b6e7e..090c3a9e277a5a1766d28d2dd804c87f44d38311 100755 --- a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml +++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml @@ -199,7 +199,7 @@ </item> </argument> </select> - <multiselect class="Magento\Ui\Component\Form\Element\Select"> + <multiselect class="Magento\Ui\Component\Form\Element\MultiSelect"> <argument name="data" xsi:type="array"> <item name="template" xsi:type="string">ui/form/element/multiselect</item> <item name="js_config" xsi:type="array"> @@ -209,6 +209,9 @@ <item name="elementTmpl" xsi:type="string">ui/form/element/multiselect</item> </item> </item> + <item name="config" xsi:type="array"> + <item name="size" xsi:type="string">6</item> + </item> </argument> </multiselect> <textarea class="Magento\Ui\Component\Form\Element\Textarea"> diff --git a/app/design/adminhtml/Magento/backend/Magento_ProductVideo/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_ProductVideo/web/css/source/_module.less new file mode 100644 index 0000000000000000000000000000000000000000..7f4e8a590acf9c902b378a441875ac8994a5af14 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_ProductVideo/web/css/source/_module.less @@ -0,0 +1,236 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +.image.video-placeholder { + display: inline-block; + position: relative; + text-decoration: none; + &:before { + background: url(../Magento_ProductVideo/images/gallery-sprite.png) no-repeat left bottom; + content: ''; + height: 49px; + left: 50%; + margin-left: -24px; + opacity: 0.7; + position: absolute; + top: 18px; + width: 49px; + z-index: 1; + } + .image-placeholder-text { + font-weight: 400; + } +} + +//re-arrange checkboxes fields in slideout video panel (base, small image etc) +.admin__field { + &.field-video_image, + &.field-video_small_image, + &.field-video_thumbnail, + &.field-video_swatch_image, + &.field-new_video_disabled { + .admin__field-control { + #mix-grid .column(3, @field-grid__columns); + float: left; + margin-left: 80px; + position: relative; + input { + float: right; + } + } + .admin__field-label { + left: 0; + margin-left: 35%; + padding-left: 45px; + position: absolute; + width: 250px; + &:before { + content: none; + } + span { + float: left; + } + } + } + &.field-new_video_disabled { + margin-top: 32px; + } + &.field.field-new_video_screenshot { + margin-bottom: 5px; + } + &.field.field-new_video_screenshot_preview { + margin-bottom: 50px; + } + &.field-roleLabel { + height: 0; + .admin__field-control { + #mix-grid .column(3, @field-grid__columns); + float: left; + margin-left: 80px; + position: relative; + .control-value { + color: @color-black; + font-family: 'Open Sans', @font-family__sans-serif; + font-size: @font-size__s + 0.2; + font-weight: @font-weight__semibold; + float: right; + position: relative; + right: 50px; + top: 21px; + } + } + } +} + +.admin__scope-old { + .fieldset .admin__field { + &.field-video_image, + &.field-video_small_image, + &.field-video_thumbnail, + &.field-video_swatch_image { + margin-bottom: 20px; + } + } + .gallery .image .action-make-base, + .images .image .action-make-base { + .lib-button( + @_button-background: transparent, + @_button-border: none, + @_button-background-hover: transparent, + @_button-border-hover: none, + @_button-background-active: transparent, + @_button-border-active: none, + @_button-font-content: '\e63b', + @_button-icon-use: true, + @_button-icon-font: 'Admin Icons', + @_button-icon-font-text-hide: true, + @_button-icon-font-size: @font-size__xl, + @_button-icon-font-color: @color-gray62, + @_button-icon-font-color-hover: @color-gray52, + @_button-icon-font-color-active: @color-gray52, + @_button-margin: 0 + ); + bottom: 9px; + left: auto; + position: absolute; + right: 9px; + width: 0 !important; + &:before { + left: 16px; + position: absolute; + top: -2px; + } + } + .base-image .image-label { + display: block; + } +} + +.preview_hidden_image_input_button { + display: none; +} + +.video-item { + position: relative; + &:after { + background: url(../Magento_ProductVideo/images/gallery-sprite.png) bottom left; + bottom: 0; + content: ''; + height: 40px; + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 10px; + width: 49px; + z-index: 3; + } +} + +//style slideout panel add video +.mage-new-video-dialog { + form.admin__scope-old { + float: left; + width: 65%; + } + .video-player-sidebar { + width: 34.99999%; + float: left; + } + .video-player-container { + width: 100%; + height: 20vw; + margin-bottom: 30px; + border: 1px solid #e3e3e3; + position: relative; + &:after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: auto; + width: 93px; + height: 60px; + background: url(../Magento_ProductVideo/images/camera.png) no-repeat center; + z-index: 1; + } + } + .video-information { + margin-bottom: 7px; + display: none; + &:after { + content: ""; + visibility: hidden; + display: block; + height: 0; + clear: both; + } + label { + font-family: 'Open Sans', @font-family__sans-serif; + font-size: @font-size__s + 0.2; + font-weight: @font-weight__semibold; + display: block; + width: 25%; + float: left; + text-align: right; + } + span { + font-family: 'Open Sans', @font-family__sans-serif; + font-size: @font-size__s + 0.2; + font-weight: @font-weight__light; + display: block; + width: 74.9999%; + float: left; + padding-left: 20px; + } + } + .product-video { + width: 100%; + z-index: 20; + height: 100%; + position: relative; + } +} + +.image.video-placeholder > button[data-role="add-video-button"], +.image.video-placeholder > button { + background: transparent; + border: 0; + height: 100%; + position: relative; + width: 100%; + z-index: 10; +} + +.add-video-button-container { + float: right; + margin-bottom: 10px; +} + +.image.base-image:hover .image-label { + display: none; +} diff --git a/app/design/frontend/Magento/blank/Magento_ProductVideo/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_ProductVideo/web/css/source/_module.less new file mode 100644 index 0000000000000000000000000000000000000000..d51b978a97e0f74dad2a83121c0b331830e6a051 --- /dev/null +++ b/app/design/frontend/Magento/blank/Magento_ProductVideo/web/css/source/_module.less @@ -0,0 +1,70 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +.fotorama-video-container { + &:after { + background: url(../Magento_ProductVideo/img/gallery-sprite.png) bottom right; + bottom: 0; + content: ''; + height: 100px; + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 12px; + width: 100px; + } + .magnify-lens { + display: none !important; + } + &.video-unplayed { + &:hover { + img { + opacity: 0.6; + } + &:after { + transform: scale(1.25); + } + } + } +} + +.video-thumb-icon:after { + background: url(../Magento_ProductVideo/img/gallery-sprite.png) bottom left; + bottom: 0; + content: ''; + height: 40px; + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 10px; + width: 49px; +} + +.product-video { + height: 85%; + margin-top: 15%; + position: absolute; + top: 0; + width: 100%; + iframe { + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + z-index: 9999; + } +} + +.fotorama__arr.hidden-video { + z-index: -1; +} + +.fotorama__video-close { + bottom: 89%; + top: auto; +} diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Block/Adminhtml/Product/Edit/Tab/ImagesAndVideos.php b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Block/Adminhtml/Product/Edit/Tab/ImagesAndVideos.php index efbf9ac19ef2cadf83593911322353f99b0a5a3d..c490b2dbaf13b2cfaba9787a46afa4fc6fc22f7a 100755 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Block/Adminhtml/Product/Edit/Tab/ImagesAndVideos.php +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Block/Adminhtml/Product/Edit/Tab/ImagesAndVideos.php @@ -20,7 +20,7 @@ class ImagesAndVideos extends Tab * * @var string */ - protected $addVideoButton = '#product_info_tabs_images-and-videos_content #add_video_button'; + protected $addVideoButton = '#product_info_tabs_image-management_content #add_video_button'; /** * Video dialog CSS locator. diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Block/Adminhtml/Product/ProductForm.xml index 94e28feef713c0c1e8a6746f2f6749d02fd73e8b..5a3c8fbe3fd8a2ad7b6aa3e97d29357ef2a9a0a5 100755 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Block/Adminhtml/Product/ProductForm.xml +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Block/Adminhtml/Product/ProductForm.xml @@ -8,7 +8,7 @@ <tabs> <images-and-videos> <class>\Magento\ProductVideo\Test\Block\Adminhtml\Product\Edit\Tab\ImagesAndVideos</class> - <selector>#product_info_tabs_images-and-videos</selector> + <selector>#product_info_tabs_image-management</selector> <strategy>css selector</strategy> <fields> <position /> diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Repository/ConfigData.xml new file mode 100755 index 0000000000000000000000000000000000000000..5227236ce505b0b23ac486f1b3cffcf509cbe6e4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Repository/ConfigData.xml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd"> + <repository class="Magento\Config\Test\Repository\ConfigData"> + <dataset name="youtube_api_key"> + <field name="catalog/product_video/youtube_api_key" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="label" xsi:type="string"/> + <item name="value" xsi:type="string">AIzaSyDwqDWuw1lra-LnpJL2Mr02DYuFmkuRSns</item> + </field> + </dataset> + <dataset name="youtube_api_key_rollback"> + <field name="catalog/product_video/youtube_api_key" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="label" xsi:type="string"/> + <item name="value" xsi:type="string"/> + </field> + </dataset> + </repository> +</config> diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateSimpleProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateSimpleProductEntityTest.xml index 6a151535f05f02ed372dbe0fec9671a6235b4840..74f73a10f81e37277a67c839ac9318704cda1712 100755 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateSimpleProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateSimpleProductEntityTest.xml @@ -34,6 +34,7 @@ <data name="product/data/media_gallery/images/0/video_url" xsi:type="string">https://youtu.be/WMp2PvU2qi8</data> <data name="product/data/media_gallery/images/0/video_title" xsi:type="string">Foo Test 1</data> <data name="product/data/media_gallery/images/0/video_description" xsi:type="string">This is a test "Foo Test 1"</data> + <data name="configData" xsi:type="string">youtube_api_key</data> <constraint name="Magento\ProductVideo\Test\Constraint\AssertVideoCategoryView" /> <constraint name="Magento\ProductVideo\Test\Constraint\AssertVideoProductView" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> @@ -50,18 +51,19 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> </variation> <variation name="AddVideoToPCFTestVariation3"> - <data name="initialProduct/dataset" xsi:type="string">product_with_category</data> - <data name="product/data/sku" xsi:type="string">simple_product_with_category_%isolation%</data> + <data name="initialProduct/dataset" xsi:type="string">product_with_category</data> + <data name="product/data/sku" xsi:type="string">simple_product_with_category_%isolation%</data> <data name="product/data/sku" xsi:type="string">sku_simple_product_with_video_%isolation%</data> <data name="product/data/media_gallery/images/0/video_url" xsi:type="string">https://youtu.be/WMp2PvU2qi8</data> <data name="product/data/media_gallery/images/0/video_title" xsi:type="string">Foo Test 1</data> + <data name="configData" xsi:type="string">youtube_api_key</data> <constraint name="Magento\ProductVideo\Test\Constraint\AssertVideoCategoryView" /> <constraint name="Magento\ProductVideo\Test\Constraint\AssertVideoProductView" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> </variation> <variation name="AddVideoToPCFTestVariation4"> - <data name="initialProduct/dataset" xsi:type="string">product_with_category</data> - <data name="product/data/sku" xsi:type="string">simple_product_with_category_%isolation%</data> + <data name="initialProduct/dataset" xsi:type="string">product_with_category</data> + <data name="product/data/sku" xsi:type="string">simple_product_with_category_%isolation%</data> <data name="product/data/media_gallery/images/0/video_url" xsi:type="string">https://vimeo.com/21776334</data> <data name="product/data/media_gallery/images/0/video_title" xsi:type="string">Foo Test 2</data> <constraint name="Magento\ProductVideo\Test\Constraint\AssertVideoCategoryView" /> @@ -73,6 +75,7 @@ <data name="initialProduct/dataset" xsi:type="string">product_with_video_youtube</data> <data name="product/data/sku" xsi:type="string">sku_simple_product_with_video_%isolation%</data> <data name="product/data/media_gallery/images/0/video_url" xsi:type="string">https://youtu.be/bpOSxM0rNPM</data> + <data name="configData" xsi:type="string">youtube_api_key</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> </variation> <variation name="UpdateVideoInPCFTestVariation2"> @@ -97,6 +100,7 @@ <data name="productVideo/data/media_gallery/images/0/video_url" xsi:type="string">https://youtu.be/bpOSxM0rNPM</data> <data name="productVideo/data/media_gallery/images/0/video_title" xsi:type="string">Edit Test</data> <data name="productVideo/data/media_gallery/images/0/video_description" xsi:type="string">This is an edit test</data> + <data name="configData" xsi:type="string">youtube_api_key</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> </variation> <variation name="GetVideoInfoTestVariation1"> @@ -105,6 +109,7 @@ <data name="product/data/sku" xsi:type="string">simple_product_with_category_%isolation%</data> <data name="product/data/media_gallery/images/0/video_url" xsi:type="string">https://youtu.be/WMp2PvU2qi8</data> <data name="video/video_title" xsi:type="string">Foo Fighters - Congregation</data> + <data name="configData" xsi:type="string">youtube_api_key</data> <constraint name="Magento\ProductVideo\Test\Constraint\AssertGetVideoInfoDataIsCorrect" /> </variation> <variation name="GetVideoInfoTestVariation2"> diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Model/Type/OnepageTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Model/Type/OnepageTest.php deleted file mode 100644 index 617b9c0dc522d649d9f2b11e3f3d989e249f4fe5..0000000000000000000000000000000000000000 --- a/dev/tests/integration/testsuite/Magento/Checkout/Model/Type/OnepageTest.php +++ /dev/null @@ -1,560 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Checkout\Model\Type; - -use Magento\TestFramework\Helper\Bootstrap; - -/** - * @magentoDataFixture Magento/Checkout/_files/quote_with_product_and_payment.php - * @magentoAppArea frontend - */ -class OnepageTest extends \PHPUnit_Framework_TestCase -{ - /** @var \Magento\Checkout\Model\Type\Onepage */ - protected $_model; - - /** @var \Magento\Quote\Model\Quote */ - protected $_currentQuote; - - protected function setUp() - { - parent::setUp(); - $this->_model = Bootstrap::getObjectManager()->create('Magento\Checkout\Model\Type\Onepage'); - /** @var \Magento\Quote\Model\ResourceModel\Quote\Collection $quoteCollection */ - $quoteCollection = Bootstrap::getObjectManager()->create('Magento\Quote\Model\ResourceModel\Quote\Collection'); - /** @var \Magento\Quote\Model\Quote $quote */ - $this->_currentQuote = $quoteCollection->getLastItem(); - $this->_model->setQuote($this->_currentQuote); - } - - /** - * @magentoAppIsolation enabled - * @magentoDbIsolation enabled - * @magentoDataFixture Magento/Customer/_files/customer.php - * @magentoDataFixture Magento/Customer/_files/customer_address.php - */ - public function testSaveShippingWithCustomerId() - { - $this->_currentQuote->setCustomerId(1)->save(); - $data = [ - 'address_id' => '', - 'firstname' => 'Joe', - 'lastname' => 'Black', - 'company' => 'Lunatis', - 'street' => ['1100 Parmer', 'ln.'], - 'city' => 'Austin', - 'region_id' => '57', - 'region' => '', - 'postcode' => '78757', - 'country_id' => 'US', - 'telephone' => '(512) 999-9999', - 'fax' => '', - 'save_in_address_book' => 1, - ]; - $this->_model->saveShipping($data, 1); - - $address = $this->_currentQuote->getShippingAddress(); - - /* Verify that data from Customer Address identified by id=1 is set */ - $this->assertEquals('John', $address->getFirstname()); - $this->assertEquals('Smith', $address->getLastname()); - $this->assertEquals(['Green str, 67'], $address->getStreet()); - $this->assertEquals('CityM', $address->getCity()); - $this->assertEquals('Alabama', $address->getRegion()); - $this->assertEquals(1, $address->getRegionId()); - $this->assertEquals('75477', $address->getPostcode()); - $this->assertEquals('US', $address->getCountryId()); - $this->assertEquals('3468676', $address->getTelephone()); - $this->assertEquals('customer@example.com', $address->getEmail()); - $this->assertTrue($address->getCollectShippingRates()); - $this->assertEquals(1, $address->getCustomerAddressId()); - } - - /** - * @magentoAppIsolation enabled - * @magentoDbIsolation enabled - * @magentoDataFixture Magento/Customer/_files/customer.php - * @magentoDataFixture Magento/Customer/_files/customer_address.php - */ - public function testSaveShippingWithData() - { - $data = [ - 'address_id' => '', - 'firstname' => 'Joe', - 'lastname' => 'Black', - 'company' => 'Lunatis', - 'street' => ['1100 Parmer', 'ln.'], - 'city' => 'Austin', - 'region_id' => '57', - 'region' => '', - 'postcode' => '78757', - 'country_id' => 'US', - 'telephone' => '(512) 999-9999', - 'save_in_address_book' => 1, - ]; - $this->_model->saveShipping($data, null); - - $address = $this->_currentQuote->getShippingAddress(); - - /* Verify that data from the form is set */ - $this->assertEquals('Joe', $address->getFirstname()); - $this->assertEquals('Black', $address->getLastname()); - $this->assertEquals('Lunatis', $address->getCompany()); - $this->assertEquals("1100 Parmer\nln.", $address->getData('street')); - $this->assertEquals('Austin', $address->getCity()); - $this->assertEquals('US', $address->getCountryId()); - $this->assertEquals('Texas', $address->getRegion()); - $this->assertEquals('57', $address->getRegionId()); - $this->assertEquals('78757', $address->getPostcode()); - $this->assertEquals('(512) 999-9999', $address->getTelephone()); - $this->assertNull($address->getCustomerAddressId()); - } - - /** - * @magentoAppIsolation enabled - */ - public function testSaveOrder() - { - $this->markTestIncomplete('MAGETWO-31257'); - $this->_model->saveBilling($this->_getCustomerData(), null); - $this->_prepareQuote($this->_getQuote()); - - $this->_model->saveOrder(); - - /** @var $order \Magento\Sales\Model\Order */ - $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order'); - $order->loadByIncrementId($this->_model->getLastOrderId()); - - $this->assertNotEmpty( - $this->_model->getQuote()->getShippingAddress()->getCustomerAddressId(), - 'Quote shipping CustomerAddressId should not be empty' - ); - $this->assertNotEmpty( - $this->_model->getQuote()->getBillingAddress()->getCustomerAddressId(), - 'Quote billing CustomerAddressId should not be empty' - ); - - $this->assertNotEmpty( - $order->getShippingAddress()->getCustomerAddressId(), - 'Order shipping CustomerAddressId should not be empty' - ); - $this->assertNotEmpty( - $order->getBillingAddress()->getCustomerAddressId(), - 'Order billing CustomerAddressId should not be empty' - ); - } - - /** - * @magentoAppIsolation enabled - * @magentoDataFixture Magento/Customer/_files/customer.php - */ - public function testInitCheckoutNotLoggedIn() - { - /* The customer session must be cleared before the real test begins. Need to - have a customer via the data fixture to actually log out. */ - /** @var $customerSession \Magento\Customer\Model\Session*/ - $customerSession = Bootstrap::getObjectManager()->create('Magento\Customer\Model\Session'); - $customerSession->setCustomerId(1); - $customerSession->logout(); - - $this->_model->saveBilling($this->_getCustomerData(), null); - $this->_prepareQuote($this->_getQuote()); - $this->assertTrue($this->_model->getCheckout()->getSteps()['shipping']['allow']); - $this->assertTrue($this->_model->getCheckout()->getSteps()['billing']['allow']); - $this->_model->initCheckout(); - $this->assertFalse($this->_model->getCheckout()->getSteps()['shipping']['allow']); - $this->assertFalse($this->_model->getCheckout()->getSteps()['billing']['allow']); - $this->assertNull($this->_model->getQuote()->getCustomer()->getEmail()); - } - - /** - * @magentoAppIsolation enabled - * @magentoDataFixture Magento/Customer/_files/customer.php - */ - public function testInitCheckoutLoggedIn() - { - $this->_model->saveBilling($this->_getCustomerData(), null); - $this->_prepareQuote($this->_getQuote()); - $customerIdFromFixture = 1; - $emailFromFixture = 'customer@example.com'; - /** @var $customerSession \Magento\Customer\Model\Session*/ - $customerSession = Bootstrap::getObjectManager()->create('Magento\Customer\Model\Session'); - /** @var $customerRepository \Magento\Customer\Api\CustomerRepositoryInterface */ - $customerRepository = Bootstrap::getObjectManager()->create( - 'Magento\Customer\Api\CustomerRepositoryInterface' - ); - $customerData = $customerRepository->getById($customerIdFromFixture); - $customerSession->setCustomerDataObject($customerData); - $this->_model = Bootstrap::getObjectManager()->create( - 'Magento\Checkout\Model\Type\Onepage', - ['customerSession' => $customerSession] - ); - $this->assertTrue($this->_model->getCheckout()->getSteps()['shipping']['allow']); - $this->assertTrue($this->_model->getCheckout()->getSteps()['billing']['allow']); - $this->_model->initCheckout(); - $this->assertFalse($this->_model->getCheckout()->getSteps()['shipping']['allow']); - //When the user is logged in and for Step billing - allow is not reset to true - $this->assertTrue($this->_model->getCheckout()->getSteps()['billing']['allow']); - $this->assertEquals($emailFromFixture, $this->_model->getQuote()->getCustomer()->getEmail()); - } - - /** - * New customer, the same address should be used for shipping and billing, it should be persisted to DB. - * - * @magentoAppIsolation enabled - * @magentoDbIsolation enabled - */ - public function testSaveBillingSameAsShipping() - { - $quote = $this->_model->getQuote(); - - /** Preconditions */ - $customerData = $this->_getCustomerData(); - $customerAddressId = false; - $this->assertEquals(1, $customerData['use_for_shipping'], "Precondition failed: use_for_shipping is invalid"); - $this->assertEquals( - 1, - $customerData['save_in_address_book'], - "Precondition failed: save_in_address_book is invalid" - ); - $this->assertEmpty( - $quote->getBillingAddress()->getId(), - "Precondition failed: billing address must not be initialized." - ); - $this->assertEmpty( - $quote->getShippingAddress()->getId(), - "Precondition failed: billing address must not be initialized." - ); - - /** Execute SUT */ - $result = $this->_model->saveBilling($customerData, $customerAddressId); - $this->assertEquals([], $result, 'Return value is invalid'); - - /** Ensure that quote addresses were persisted correctly */ - $billingAddress = $quote->getBillingAddress(); - $shippingAddress = $quote->getShippingAddress(); - - $quoteAddressFieldsToCheck = [ - 'quote_id' => $quote->getId(), - 'firstname' => 'John', - 'lastname' => 'Smith', - 'email' => 'John.Smith@example.com', - 'street' => '6131 Monterey Rd, Apt 1', - 'city' => 'Los Angeles', - 'postcode' => '90042', - 'country_id' => 'US', - 'region_id' => '1', - 'region' => 'Alabama', - 'telephone' => '(323) 255-5861', - 'customer_id' => null, - 'customer_address_id' => null, - ]; - - foreach ($quoteAddressFieldsToCheck as $field => $value) { - $this->assertEquals($value, $billingAddress->getData($field), "{$field} value is invalid"); - $this->assertEquals($value, $shippingAddress->getData($field), "{$field} value is invalid"); - } - $this->assertEquals('1', $shippingAddress->getData('same_as_billing'), "same_as_billing value is invalid"); - $this->assertGreaterThan(0, $shippingAddress->getData('address_id'), "address_id value is invalid"); - $this->assertGreaterThan(0, $billingAddress->getData('address_id'), "address_id value is invalid"); - $this->assertEquals( - 1, - $billingAddress->getData('save_in_address_book'), - "save_in_address_book value is invalid" - ); - $this->assertEquals( - 0, - $shippingAddress->getData('save_in_address_book'), - "As soon as 'same_as_billing' is set to 1, 'save_in_address_book' of shipping should be 0" - ); - - /** Ensure that customer-related data was ported to quote correctly */ - $quoteFieldsToCheck = [ - 'customer_firstname' => 'John', - 'customer_lastname' => 'Smith', - 'customer_email' => 'John.Smith@example.com', - ]; - foreach ($quoteFieldsToCheck as $field => $value) { - $this->assertEquals($value, $quote->getData($field), "{$field} value is set to quote incorrectly."); - } - - /** Perform if checkout steps status was correctly updated in session */ - /** @var \Magento\Checkout\Model\Session $checkoutSession */ - $checkoutSession = Bootstrap::getObjectManager()->get('Magento\Checkout\Model\Session'); - $this->assertTrue($checkoutSession->getStepData('billing', 'allow'), 'Billing step should be allowed.'); - $this->assertTrue($checkoutSession->getStepData('billing', 'complete'), 'Billing step should be completed.'); - $this->assertTrue($checkoutSession->getStepData('shipping', 'allow'), 'Shipping step should be allowed.'); - } - - /** - * New customer, billing address should not be used as shipping address, it should be persisted to DB. - * - * @magentoAppIsolation enabled - * @magentoDbIsolation enabled - */ - public function testSaveBilling() - { - $quote = $this->_model->getQuote(); - - /** Preconditions */ - $customerData = $this->_getCustomerData(); - $customerData['use_for_shipping'] = 0; - $customerAddressId = false; - $this->assertEquals( - 1, - $customerData['save_in_address_book'], - "Precondition failed: save_in_address_book is invalid" - ); - $this->assertEmpty( - $quote->getBillingAddress()->getId(), - "Precondition failed: billing address must not be initialized." - ); - $this->assertEmpty( - $quote->getShippingAddress()->getId(), - "Precondition failed: billing address must not be initialized." - ); - - /** Execute SUT */ - $result = $this->_model->saveBilling($customerData, $customerAddressId); - $this->assertEquals([], $result, 'Return value is invalid'); - - /** Ensure that quote addresses were persisted correctly */ - $billingAddress = $quote->getBillingAddress(); - $shippingAddress = $quote->getShippingAddress(); - - $quoteAddressFieldsToCheck = [ - 'quote_id' => $quote->getId(), - 'firstname' => 'John', - 'lastname' => 'Smith', - 'email' => 'John.Smith@example.com', - 'street' => '6131 Monterey Rd, Apt 1', - 'city' => 'Los Angeles', - 'postcode' => '90042', - 'country_id' => 'US', - 'region_id' => '1', - 'region' => 'Alabama', - 'telephone' => '(323) 255-5861', - 'customer_id' => null, - 'customer_address_id' => null, - ]; - - foreach ($quoteAddressFieldsToCheck as $field => $value) { - $this->assertEquals($value, $billingAddress->getData($field), "{$field} value is invalid"); - } - $this->assertGreaterThan(0, $billingAddress->getData('address_id'), "address_id value is invalid"); - $this->assertEmpty( - $shippingAddress->getData('firstname'), - "Shipping address should not be populated with billing address data when 'same_as_billing' is set to 0." - ); - $this->assertEquals( - 1, - $billingAddress->getData('save_in_address_book'), - "save_in_address_book value is invalid" - ); - - /** Ensure that customer-related data was ported to quote correctly */ - $quoteFieldsToCheck = [ - 'customer_firstname' => 'John', - 'customer_lastname' => 'Smith', - 'customer_email' => 'John.Smith@example.com', - ]; - foreach ($quoteFieldsToCheck as $field => $value) { - $this->assertEquals($value, $quote->getData($field), "{$field} value is set to quote incorrectly."); - } - - /** Perform if checkout steps status was correctly updated in session */ - /** @var \Magento\Checkout\Model\Session $checkoutSession */ - $checkoutSession = Bootstrap::getObjectManager()->get('Magento\Checkout\Model\Session'); - $this->assertTrue($checkoutSession->getStepData('billing', 'allow'), 'Billing step should be allowed.'); - $this->assertTrue($checkoutSession->getStepData('billing', 'complete'), 'Billing step should be completed.'); - $this->assertTrue($checkoutSession->getStepData('shipping', 'allow'), 'Shipping step should be allowed.'); - } - - /** - * New address, address data is invalid. - */ - public function testSaveBillingValidationErrorNewAddress() - { - /** Preconditions */ - $customerData = $this->_getCustomerData(); - unset($customerData['firstname']); - $customerAddressId = false; - - /** Execute SUT */ - $result = $this->_model->saveBilling($customerData, $customerAddressId); - $validationErrors = [ - '"First Name" is a required value.', - '"First Name" length must be equal or greater than 1 characters.', - ]; - $this->assertEquals( - ['error' => 1, 'message' => $validationErrors], - $result, - 'Validation error is invalid.' - ); - } - - /** - * Existing address, address data is invalid. - * - * @magentoDataFixture Magento/Customer/_files/customer.php - * @magentoDataFixture Magento/Customer/_files/customer_address.php - */ - public function testSaveBillingExistingAddressInvalidData() - { - /** Preconditions */ - $addressIdFromFixture = 1; - $customerIdFromFixture = 1; - $customerData = $this->_getCustomerData(); - unset($customerData['firstname']); - $this->_getQuote()->setCustomerId($customerIdFromFixture); - - /** Execute SUT */ - /** - * If customer address is available, provided customer data is not validated, - * that's why no error occurs when invalid data is provided - */ - $result = $this->_model->saveBilling($customerData, $addressIdFromFixture); - $this->assertEquals([], $result, 'No errors expected.'); - } - - /** - * Address exists, but it does not belong to the current customer which is set to quote. - * - * @magentoDataFixture Magento/Customer/_files/customer.php - * @magentoDataFixture Magento/Customer/_files/customer_address.php - */ - public function testSaveBillingInvalidAddressId() - { - /** Preconditions */ - $addressIdFromFixture = 1; - $customerData = $this->_getCustomerData(); - unset($customerData['firstname']); - /** Any ID can be used, which is not equal to ID of customer to which current address belongs. */ - $secondCustomerId = 2; - $this->_getQuote()->setCustomerId($secondCustomerId); - - /** Execute SUT */ - $result = $this->_model->saveBilling($customerData, $addressIdFromFixture); - $validationErrors = 'The customer address is not valid.'; - $this->assertEquals( - ['error' => 1, 'message' => $validationErrors], - $result, - 'Validation error is invalid.' - ); - } - - /** - * Empty data. - */ - public function testSaveBillingEmptyData() - { - /** Execute SUT */ - $customerData = []; - $customerAddressId = false; - $result = $this->_model->saveBilling($customerData, $customerAddressId); - $this->assertEquals( - ['error' => -1, 'message' => 'Invalid data'], - $result, - 'Validation error is invalid.' - ); - } - - /** - * Address does not exist, but existing email is specified in address data. - * - * @magentoDataFixture Magento/Customer/_files/customer.php - */ - public function testSaveBillingNewAddressErrorExistingEmail() - { - /** Preconditions */ - $customerData = $this->_getCustomerData(); - $fixtureCustomerEmail = 'customer@example.com'; - $customerData['email'] = $fixtureCustomerEmail; - $customerAddressId = false; - $this->_getQuote()->setCheckoutMethod(\Magento\Checkout\Model\Type\Onepage::METHOD_REGISTER); - - /** Execute SUT */ - $result = $this->_model->saveBilling($customerData, $customerAddressId); - $this->assertArrayHasKey('message', $result, 'Error message was expected to be set'); - $this->assertStringStartsWith( - 'This email address already belongs to a registered customer.', - (string)$result['message'], - 'Validation error is invalid.' - ); - } - - /** - * New address, customer address is invalid (customer validation should fail, not address validation). - */ - public function testSaveBillingInvalidCustomerData() - { - /** Preconditions */ - $customerData = $this->_getCustomerData(); - $customerData['email'] = 'invalidemail'; - $this->_getQuote()->setCheckoutMethod(\Magento\Checkout\Model\Type\Onepage::METHOD_REGISTER); - $customerAddressId = false; - - /** Execute SUT */ - $result = $this->_model->saveBilling($customerData, $customerAddressId); - $validationErrors = '"Email" is not a valid email address.'; - $this->assertEquals( - ['error' => -1, 'message' => $validationErrors], - $result, - 'Validation error is invalid.' - ); - } - - /** - * @return \Magento\Quote\Model\Quote - */ - protected function _getQuote() - { - return $this->_currentQuote; - } - - /** - * Prepare Quote - * - * @param \Magento\Quote\Model\Quote $quote - */ - protected function _prepareQuote($quote) - { - /** @var $rate \Magento\Quote\Model\Quote\Address\Rate */ - $rate = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Quote\Model\Quote\Address\Rate' - ); - $rate->setCode('freeshipping_freeshipping'); - $rate->getPrice(1); - - $quote->getShippingAddress()->setShippingMethod('freeshipping_freeshipping'); - $quote->getShippingAddress()->addShippingRate($rate); - $quote->setCheckoutMethod(\Magento\Checkout\Model\Type\Onepage::METHOD_REGISTER); - } - - /** - * Customer data for quote - * - * @return array - */ - protected function _getCustomerData() - { - return [ - 'firstname' => 'John', - 'lastname' => 'Smith', - 'email' => 'John.Smith@example.com', - 'street' => ['6131 Monterey Rd, Apt 1', ''], - 'city' => 'Los Angeles', - 'postcode' => '90042', - 'country_id' => 'US', - 'region_id' => '1', - 'telephone' => '(323) 255-5861', - 'customer_password' => 'password', - 'confirm_password' => 'password', - 'save_in_address_book' => '1', - 'use_for_shipping' => '1' - ]; - } -} diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt index 02aa8c3d20512a666f0a1d817c1bf30f99e1c0cd..70168b63a4efb5f06f978a00c9896b0c1a6d5f12 100644 --- a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt +++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt @@ -173,10 +173,10 @@ app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summ app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js app/code/Magento/ConfigurableProduct/view/frontend/requirejs-config.js app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js -app/code/Magento/Cookie/View/adminhtml/requirejs-config.js -app/code/Magento/Cookie/View/frontend/requirejs-config.js -app/code/Magento/Cookie/View/frontend/web/js/notices.js -app/code/Magento/Cookie/View/frontend/web/js/require-cookie.js +app/code/Magento/Cookie/view/adminhtml/requirejs-config.js +app/code/Magento/Cookie/view/frontend/requirejs-config.js +app/code/Magento/Cookie/view/frontend/web/js/notices.js +app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js app/code/Magento/Customer/view/adminhtml/requirejs-config.js app/code/Magento/Customer/view/adminhtml/web/edit/tab/js/addresses.js app/code/Magento/Customer/view/frontend/requirejs-config.js diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php index de26ad30530193f0d3b0c830297e4885a1f9d94b..813aababf3b6b393e739692e1c2f8f211256c4cd 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php @@ -14,6 +14,9 @@ use Magento\Framework\App\Utility\Files; use Magento\Framework\App\Utility\AggregateInvoker; use Magento\TestFramework\Utility\ChangedFiles; +/** + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + */ class ObsoleteCodeTest extends \PHPUnit_Framework_TestCase { /**@#+ @@ -871,7 +874,7 @@ class ObsoleteCodeTest extends \PHPUnit_Framework_TestCase public function testMageMethodsObsolete() { - $ignored = $this->getBlacklistFiles(); + $ignored = $this->getBlacklistFiles(true); $files = Files::init()->getPhpFiles( Files::INCLUDE_APP_CODE | Files::INCLUDE_TESTS @@ -900,18 +903,43 @@ class ObsoleteCodeTest extends \PHPUnit_Framework_TestCase ); } + /** + * @param string $appPath + * @param string $pattern + * @return array + * @throws \Exception + */ + private function processPattern($appPath, $pattern) + { + $files = []; + $relativePathStart = strlen($appPath); + + $fileSet = glob($appPath . DIRECTORY_SEPARATOR . $pattern, GLOB_NOSORT); + foreach ($fileSet as $file) { + $files[] = substr($file, $relativePathStart); + } + + return $files; + } + /** * Reads list of blacklisted files * + * @param bool $absolutePath * @return array + * @throws \Exception */ - private function getBlacklistFiles() + private function getBlacklistFiles($absolutePath = false) { $blackList = include __DIR__ . '/_files/blacklist/obsolete_mage.php'; $ignored = []; $appPath = Files::init()->getPathToSource(); foreach ($blackList as $file) { - $ignored = array_merge($ignored, glob($appPath . '/' . $file, GLOB_NOSORT)); + if ($absolutePath) { + $ignored = array_merge($ignored, glob($appPath . DIRECTORY_SEPARATOR . $file, GLOB_NOSORT)); + } else { + $ignored = array_merge($ignored, $this->processPattern($appPath, $file)); + } } return $ignored; }