First upload

This commit is contained in:
Nikolai Fesenko
2025-02-02 13:37:56 +01:00
commit 8d227c9191
3281 changed files with 362319 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
$sLangName = 'Deutsch';
$aLang = [
'charset' => 'UTF-8', // Supports german language specific chars like: ä, ö. ß, etc.
'OEGDPROPTIN_STORE_DELIVERY_ADDRESS' => "Ich bin damit einverstanden, dass meine Lieferadresse dauerhaft gespeichert wird. Unter 'Mein Konto' kann ich die Lieferadresse endgültig löschen.",
'OEGDPROPTIN_CONFIRM_STORE_DELIVERY_ADDRESS' => 'Bitte stimmen Sie dem Speichern der Lieferadresse zu!',
'OEGDPROPTIN_CONTACT_FORM_ERROR_MESSAGE' => 'Bitte stimmen Sie den Bedingungen der Verarbeitung Ihrer Daten zu!',
'OEGDPROPTIN_CONTACT_FORM_MESSAGE_DELETION' => 'Ihre Kontaktdaten werden nach Bearbeitung der Anfrage gelöscht.',
'OEGDPROPTIN_CONTACT_FORM_MESSAGE_STATISTICAL' => 'Ich stimme der Verwendung meiner Daten zur Beantwortung dieser Anfrage und für statistische Zwecke zu.',
'OEGDPROPTIN_USER_REGISTRATION_OPTIN' => 'Ich bin damit einverstanden, dass meine Daten dauerhaft für das Kundenkonto verwendet werden. Ein Widerruf meiner Einwilligung ist jederzeit mit Wirkung für die Zukunft möglich.',
'OEGDPROPTIN_CONFIRM_USER_REGISTRATION_OPTIN' => 'Bitte stimmen Sie dem Speichern der Daten zu!',
'OEGDPROPTIN_REVIEW_FORM_MESSAGE' => 'Ich stimme zu, dass meine Bewertung und mein Name auf dieser Seite veröffentlicht werden. Diese Einwilligung kann ich jederzeit mit Wirkung für die Zukunft widerrufen.',
'OEGDPROPTIN_REVIEW_FORM_ERROR_MESSAGE' => 'Bitte stimmen Sie der Veröffentlichung Ihrer Bewertung und Ihres Namens zu!',
'OEGDPROPTIN_STORE_INVOICE_ADDRESS' => "Ich bin damit einverstanden, dass meine Rechnungsadresse dauerhaft gespeichert wird.",
'OEGDPROPTIN_CONFIRM_STORE_INVOICE_ADDRESS' => 'Bitte stimmen Sie dem Speichern der Rechnungsadresse zu!',
];

View File

@@ -0,0 +1,36 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
$sLangName = 'English';
$aLang = [
'charset' => 'UTF-8',
'OEGDPROPTIN_STORE_DELIVERY_ADDRESS' => "I agree that my shipping address will be permanently stored. Under 'My account' I am able to remove the shipping address definitively.",
'OEGDPROPTIN_CONFIRM_STORE_DELIVERY_ADDRESS' => 'Please agree to shipping address being stored!',
'OEGDPROPTIN_CONTACT_FORM_ERROR_MESSAGE' => "Please agree to the conditions of processing your data!",
'OEGDPROPTIN_CONTACT_FORM_MESSAGE_DELETION' => "Your contact details will be deleted after processing the request.",
'OEGDPROPTIN_CONTACT_FORM_MESSAGE_STATISTICAL' => "I agree to the use of my data to answer this request and for statistical purposes.",
'OEGDPROPTIN_USER_REGISTRATION_OPTIN' => "I agree that my data will be used permanently for the customer account. A revocation of my consent is possible at any time with effect for the future.",
'OEGDPROPTIN_CONFIRM_USER_REGISTRATION_OPTIN' => 'Please agree to your data being stored!',
'OEGDPROPTIN_REVIEW_FORM_MESSAGE' => "I agree that my review and name will be published on this page. I may revoke this consent at any time, with effect for the future.",
'OEGDPROPTIN_REVIEW_FORM_ERROR_MESSAGE' => 'Please agree to your review and name being published here!',
'OEGDPROPTIN_STORE_INVOICE_ADDRESS' => "I agree that my invoice address will be permanently stored.",
'OEGDPROPTIN_CONFIRM_STORE_INVOICE_ADDRESS' => 'Please agree to invoice address being stored!',
];

View File

@@ -0,0 +1,37 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
$sLangName = 'Deutsch';
$aLang = [
'charset' => 'UTF-8', // Supports german language specific chars like: ä, ö. ß, etc.
'oegdproptin' => 'OE GDPR Opt-in Modul',
'SHOP_MODULE_GROUP_oegdproptin_settings' => 'DSGVO-Einstellungen',
'SHOP_MODULE_blOeGdprOptinInvoiceAddress' => 'Opt-in für Rechnungsadresse anzeigen',
'SHOP_MODULE_blOeGdprOptinDeliveryAddress' => 'Opt-in für Lieferadresse anzeigen',
'SHOP_MODULE_blOeGdprOptinUserRegistration' => 'Opt-in für die Benutzerregistrierung anzeigen',
'SHOP_MODULE_blOeGdprOptinProductReviews' => 'Opt-in für Artikelbewertungen anzeigen',
'SHOP_MODULE_GROUP_oegdproptin_contact_form' => 'Einstellungen für das Kontaktformular',
'SHOP_MODULE_OeGdprOptinContactFormMethod' => '', // right side of the inputs, if some notes will be needed
'SHOP_MODULE_OeGdprOptinContactFormMethod_deletion' => 'Hinweis auf Löschen der Daten nach Verarbeitung anzeigen',
'SHOP_MODULE_OeGdprOptinContactFormMethod_statistical' => 'Opt-in für Verarbeitung und statistische Verwendung der Daten anzeigen',
];

View File

@@ -0,0 +1,37 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
$sLangName = 'English';
$aLang = [
'charset' => 'UTF-8',
'oegdproptin' => 'OE GDPR opt-in module',
'SHOP_MODULE_GROUP_oegdproptin_settings' => 'GDPR settings',
'SHOP_MODULE_blOeGdprOptinInvoiceAddress' => 'Show opt-in for invoice address',
'SHOP_MODULE_blOeGdprOptinDeliveryAddress' => 'Show opt-in for shipping address',
'SHOP_MODULE_blOeGdprOptinUserRegistration' => 'Show opt-in for user registration',
'SHOP_MODULE_blOeGdprOptinProductReviews' => 'Show opt-in for product reviews',
'SHOP_MODULE_GROUP_oegdproptin_contact_form' => 'Settings for the contact form',
'SHOP_MODULE_OeGdprOptinContactFormMethod' => '', // right side of the inputs, if some notes will be needed
'SHOP_MODULE_OeGdprOptinContactFormMethod_deletion' => 'Show a note for deletion of the data after processing',
'SHOP_MODULE_OeGdprOptinContactFormMethod_statistical' => 'Show an opt-in for processing and statistical usage of the data',
];

View File

@@ -0,0 +1,21 @@
[{$smarty.block.parent}]
<div class="form-group">
<div class="col-lg-offset-[{$leftCol|default:2}] col-lg-[{$rightCol|default:10}]">
[{if $oView->isOptInValidationRequired()}]
<label for="c_oegdproptin">
<input type="hidden" name="c_oegdproptin" value="0">
<input type="checkbox"
name="c_oegdproptin"
id="c_oegdproptin"
value="1">
<strong>[{oxmultilang ident="OEGDPROPTIN_CONTACT_FORM_MESSAGE_STATISTICAL" }]</strong>
</label>
[{if $oView->isOptInError()}]
<div class="text-danger">[{oxmultilang ident="OEGDPROPTIN_CONTACT_FORM_ERROR_MESSAGE" }]</div>
[{/if}]
[{else}]
[{oxmultilang ident="OEGDPROPTIN_CONTACT_FORM_MESSAGE_DELETION"}]
[{/if}]
</div>
</div>

View File

@@ -0,0 +1,21 @@
[{if !isset($oConfig)}]
[{assign var="oConfig" value=$oViewConf->getConfig()}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinDeliveryAddress')}]
[{if $Errors.oegdproptin_deliveryaddress}]
[{assign var=oError value=$Errors.oegdproptin_deliveryaddress.0}]
<div class="alert alert-danger">[{$oError->getOxMessage()}]</div>
<div class="help-block"></div>
[{/if}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinInvoiceAddress')}]
[{if $Errors.oegdproptin_invoiceaddress}]
[{assign var=oError value=$Errors.oegdproptin_invoiceaddress.0}]
<div class="alert alert-danger">[{$oError->getOxMessage()}]</div>
<div class="help-block"></div>
[{/if}]
[{/if}]
[{$smarty.block.parent}]

View File

@@ -0,0 +1,21 @@
[{$smarty.block.parent}]
[{if !isset($oConfig)}]
[{assign var="oConfig" value=$oViewConf->getConfig()}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinUserRegistration')}]
<div class="form-group row">
<div class="col-lg-9 col-lg-offset-3 offset-lg-3">
<div class="checkbox">
<label for="oegdproptin_userregistration">
<input type="checkbox" name="oegdproptin_userregistration" id="oegdproptin_userregistration" value="1"> [{oxmultilang ident="OEGDPROPTIN_USER_REGISTRATION_OPTIN"}]
</label>
</div>
[{if $Errors.oegdproptin_userregistration}]
[{assign var=oError value=$Errors.oegdproptin_userregistration.0}]
<div class="text-danger">[{$oError->getOxMessage()}]</div>
[{/if}]
</div>
</div>
[{/if}]

View File

@@ -0,0 +1,51 @@
[{if !isset($oConfig)}]
[{assign var="oConfig" value=$oViewConf->getConfig()}]
[{/if}]
[{if $oxcmp_user}]
[{assign var="delivadr" value=$oxcmp_user->getSelectedAddress()}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinDeliveryAddress')}]
[{if $delivadr}]
[{oxscript add="$('#showShipAddress').change( function() { $('#GdprShippingAddressOptin, #shippingAddressForm').hide($(this).is(':checked'));});"}]
[{oxscript add="$('.dd-edit-shipping-address').click(function(){ $('#GdprShippingAddressOptin').toggle($(this).is(':not(:checked)')); document.getElementById('oegdproptin_changeDelAddress').value=1; });"}]
[{oxscript add="$('.dd-add-delivery-address').click( function(){ $('#GdprShippingAddressOptin').toggle($(this).is(':not(:checked)')); });"}]
[{else}]
[{oxscript add="$('#showShipAddress').change( function() { $('#GdprShippingAddressOptin').toggle($(this).is(':not(:checked)')); });"}]
[{/if}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinInvoiceAddress')}]
[{oxscript add="$('#userChangeAddress').click( function() { $('#GdprInvoiceAddressOptin').show();$('#userChangeAddress').hide();return false;});"}]
[{/if}]
[{capture assign="optinValidationJS"}]
[{strip}]
$("#accUserSaveTop").click(function(event){
$("#oegdproptin_deliveryaddress_error").hide();
$("#oegdproptin_invoiceaddress_error").hide();
var success = true;
if ( $('#oegdproptin_invoiceaddress').is(':visible') && $('#oegdproptin_invoiceaddress').is(':not(:checked)') )
{
event.preventDefault();
$("#oegdproptin_invoiceaddress_error").show();
}
if ($('#oegdproptin_deliveryaddress').is(':visible') && $('#oegdproptin_deliveryaddress').is(':not(:checked)'))
{
event.preventDefault();
$("#oegdproptin_deliveryaddress_error").show();
}
$(this).submit();
if (!success){
return false;
}
});
[{/strip}]
[{/capture}]
[{oxscript add=$optinValidationJS}]
[{$smarty.block.parent}]

View File

@@ -0,0 +1,22 @@
[{$smarty.block.parent}]
[{if !isset($oConfig)}]
[{assign var="oConfig" value=$oViewConf->getConfig()}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinInvoiceAddress')}]
<div class="form-group[{if $Errors.oegdproptin_invoiceaddress}] oxInValid[{/if}]" id="GdprInvoiceAddressOptin" style="display: none;">
<div class="col-lg-9 col-lg-offset-3 offset-lg-3">
<div class="checkbox">
<label for="oegdproptin_invoiceaddress">
<input type="hidden" class="hidden" id="oegdproptin_changeInvAddress" name="oegdproptin_changeInvAddress" value="0">
<input type="checkbox" name="oegdproptin_invoiceaddress" id="oegdproptin_invoiceaddress" value="1"> <strong>[{oxmultilang ident="OEGDPROPTIN_STORE_INVOICE_ADDRESS"}]</strong>
</label>
</div>
</div>
<div class="col-lg-9 col-lg-offset-3 offset-lg-3">
<div id="oegdproptin_invoiceaddress_error" style="display:none;" class="text-danger">[{oxmultilang ident="OEGDPROPTIN_CONFIRM_STORE_INVOICE_ADDRESS" }]</div>
<div class="help-block"></div>
</div>
</div>
[{/if}]

View File

@@ -0,0 +1,59 @@
[{if !isset($oConfig)}]
[{assign var="oConfig" value=$oViewConf->getConfig()}]
[{/if}]
[{$smarty.block.parent}]
[{if $oxcmp_user}]
[{assign var="delivadr" value=$oxcmp_user->getSelectedAddress()}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinDeliveryAddress')}]
[{if $delivadr}]
[{oxscript add="function toggleGdprOptinShipAddress() { $('#GdprOptinShipAddress, #shippingAddressForm').hide($(this).is(':checked'));}"}]
[{oxscript add="$('#showShipAddress').change(toggleGdprOptinShipAddress);"}]
[{oxscript add="toggleGdprOptinShipAddress.bind($('#showShipAddress')[0])();"}]
[{oxscript add="$( '.dd-edit-shipping-address' ).click(function(){ $('#GdprOptinShipAddress').toggle($(this).is(':not(:checked)')); document.getElementById('oegdproptin_changeDelAddress').value=1; });"}]
[{oxscript add="$( '.dd-add-delivery-address' ).click( function(){ $('#GdprOptinShipAddress').toggle($(this).is(':not(:checked)')); });"}]
[{else}]
[{oxscript add="function toggleGdprOptinShipAddress() { $('#GdprOptinShipAddress').toggle($(this).is(':not(:checked)'));}"}]
[{oxscript add="toggleGdprOptinShipAddress.bind($('#showShipAddress')[0])();"}]
[{oxscript add="$('#showShipAddress').change(toggleGdprOptinShipAddress);"}]
[{/if}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinInvoiceAddress')}]
[{oxscript add="$('#userChangeAddress').click( function() { $('#GdprInvoiceAddressOptin').toggle();return false;});"}]
[{/if}]
[{if !isset($oConfig)}]
[{assign var="oConfig" value=$oViewConf->getConfig()}]
[{/if}]
[{capture assign="optinValidationJS"}]
[{strip}]
$("#userNextStepBottom, #userNextStepTop").click(function(event){
$("#oegdproptin_deliveryaddress_error").hide();
$("#oegdproptin_invoiceaddress_error").hide();
var success = true;
if ( $('#oegdproptin_invoiceaddress').is(':visible') && $('#oegdproptin_invoiceaddress').is(':not(:checked)') )
{
event.preventDefault();
$("#oegdproptin_invoiceaddress_error").show();
}
if ($('#oegdproptin_deliveryaddress').is(':visible') && $('#oegdproptin_deliveryaddress').is(':not(:checked)'))
{
event.preventDefault();
$("#oegdproptin_deliveryaddress_error").show();
}
$(this).submit();
if (!success){
return false;
}
});
[{/strip}]
[{/capture}]
[{oxscript add=$optinValidationJS}]

View File

@@ -0,0 +1,22 @@
[{$smarty.block.parent}]
[{if !isset($oConfig)}]
[{assign var="oConfig" value=$oViewConf->getConfig()}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinDeliveryAddress')}]
<div class="form-group[{if $Errors.oegdproptin_deliveryaddress}] oxInValid[{/if}]" id="GdprOptinShipAddress" style="display: none;">
<div class="col-lg-9 col-lg-offset-3 offset-lg-3">
<div class="checkbox">
<label for="oegdproptin_deliveryaddress">
<input type="hidden" class="hidden" id="oegdproptin_changeDelAddress" name="oegdproptin_changeDelAddress" value="0">
<input type="checkbox" name="oegdproptin_deliveryaddress" id="oegdproptin_deliveryaddress" value="1"> <strong>[{oxmultilang ident="OEGDPROPTIN_STORE_DELIVERY_ADDRESS"}]</strong>
</label>
</div>
</div>
<div class="col-lg-9 col-lg-offset-3 offset-lg-3">
<div id="oegdproptin_deliveryaddress_error" style="display:none;" class="text-danger">[{oxmultilang ident="OEGDPROPTIN_CONFIRM_STORE_DELIVERY_ADDRESS" }]</div>
<div class="help-block"></div>
</div>
</div>
[{/if}]

View File

@@ -0,0 +1,21 @@
[{$smarty.block.parent}]
[{if !isset($oConfig)}]
[{assign var="oConfig" value=$oViewConf->getConfig()}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinInvoiceAddress')}]
<div class="clearfix"></div>
<div id="GdprInvoiceAddressOptin" class="form-group" style="display: none;">
<div class="col-lg-9 col-lg-offset-3 offset-lg-3">
<div class="checkbox">
<label class="req">
<input type="hidden" class="hidden" id="oegdproptin_changeInvAddress" name="oegdproptin_changeInvAddress" value="0">
<input type="checkbox" name="oegdproptin_invoiceaddress" id="oegdproptin_invoiceaddress" value="1" >
<strong>[{oxmultilang ident="OEGDPROPTIN_STORE_INVOICE_ADDRESS"}]</strong>
</label>
</div>
<div id="oegdproptin_invoiceaddress_error" style="display:none;" class="text-danger">[{oxmultilang ident="OEGDPROPTIN_CONFIRM_STORE_INVOICE_ADDRESS" }]</div>
</div>
</div>
[{/if}]

View File

@@ -0,0 +1,25 @@
[{if !isset($oConfig)}]
[{assign var="oConfig" value=$oViewConf->getConfig()}]
[{/if}]
[{$smarty.block.parent}]
[{if $oxcmp_user}]
[{assign var="delivadr" value=$oxcmp_user->getSelectedAddress()}]
[{/if}]
[{if true == $oConfig->getConfigParam('blOeGdprOptinDeliveryAddress')}]
<div class="clearfix"></div>
<div id="GdprShippingAddressOptin" class="form-group" style="[{if $delivadr || !$oView->showShipAddress()}]display: none;[{/if}]">
<div class="col-lg-9 col-lg-offset-3 offset-lg-3">
<div class="checkbox">
<label class="req">
<input type="hidden" class="hidden" id="oegdproptin_changeDelAddress" name="oegdproptin_changeDelAddress" value="0">
<input type="checkbox" name="oegdproptin_deliveryaddress" id="oegdproptin_deliveryaddress" value="1" >
<strong>[{oxmultilang ident="OEGDPROPTIN_STORE_DELIVERY_ADDRESS"}]</strong>
</label>
</div>
<div id="oegdproptin_deliveryaddress_error" style="display:none;" class="text-danger">[{oxmultilang ident="OEGDPROPTIN_CONFIRM_USER_REGISTRATION_OPTIN" }]</div>
</div>
</div>
[{/if}]

View File

@@ -0,0 +1,37 @@
[{capture name="optInJs" assign="optInJs"}]
$("#rvw_oegdproptin").parents("form").first().submit(function(event){
event.preventDefault();
$("#rvw_oegdproptin_error").addClass("hidden");
if ($("#rvw_oegdproptin:checked").length === 1) {
this.submit();
} else {
$("#rvw_oegdproptin_error").removeClass("hidden");
}
});
[{/capture}]
[{capture name="optIn" assign="optIn"}]
[{if $oView->isReviewOptInValidationRequired()}]
<div style="margin-top:10px;" class="rvw_oegdproptin_block">
<input type="hidden" name="rvw_oegdproptin" value="0">
<label for="rvw_oegdproptin">
<input type="checkbox"
name="rvw_oegdproptin"
id="rvw_oegdproptin"
value="1">
<strong>[{oxmultilang ident="OEGDPROPTIN_REVIEW_FORM_MESSAGE" }]</strong>
</label>
<div id="rvw_oegdproptin_error"
class="[{if !$oView->isReviewOptInError()}]hidden [{/if}] text-danger">
[{oxmultilang ident="OEGDPROPTIN_REVIEW_FORM_ERROR_MESSAGE" }]
</div>
</div>
[{oxscript add=$optInJs}]
[{/if}]
[{/capture}]
[{$smarty.block.parent}]
[{$smarty.capture.optIn}]

View File

@@ -0,0 +1,119 @@
# Change Log for O3-Shop GDPR Opt-In Module
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased]
## [v1.0.1] - 2023-04-25
### Changed
- annotate class instance to prevent IDE error messages
## [v1.0.0] - 2023-03-05
# [O3-Shop]
> All changes from this moment on will be published as O3-Shop.
> Earlier code components were created by OXID eSales AG and published under the GNU General Public License v3.0.
> The version number is reset to 1.0.0. All references to version numbers refer to the new versioning.
* * * * * * * * * *
## [v2.3.3] - 2021-04-09
### Fixed
- Fix tests for 6.3 compilation testing library
## [v2.3.2] - 2021-03-12
### Fixed
- Remove deprecated getSession method usage
- Renamed language files to be coherent with other modules naming [PR-9](https://github.com/OXID-eSales/gdpr-optin-module/pull/9)
## [v2.3.1] - 2020-07-08
### Changed
- Improved the documentation
## [v2.3.0] - 2019-10-22
### Changed
- Dropped support for PHP 7.0.
## [v2.2.2] - 2020-11-27
### Changed
- Documentation was removed from repository. Check readme file for the new documentation location.
### Fixed
- Fixed compatibility section in readme
## [v2.2.1] - 2019-10-21
### Fixed
- Add checkboxes offset class for wave theme in registration, billing and shipping forms
- Fix checkboxes highlight on click (green text) in registration form to work separately for each checkbox.
- Module version number is now correct.
## [v2.2.0] - 2019-07-12
### Added
- Column witdth is now flexible in contact form [PR-8](https://github.com/OXID-eSales/gdpr-optin-module/pull/8)
### Changed
- Dropped support for PHP 5.6.
### Fixed
- Check if checkbox should be visible on load [PR-7](https://github.com/OXID-eSales/gdpr-optin-module/pull/7)
## [v2.1.2] - 2018-10-11
### Fixed
- Fix unclosed "<strong>" elements [PR-6](https://github.com/OXID-eSales/gdpr-optin-module/pull/6)
- Remove unnecessary "checkbox" class usage [PR-6](https://github.com/OXID-eSales/gdpr-optin-module/pull/6)
## [v2.1.1] - 2018-07-06
### Changed
- Use dropdown instead of radio buttons for contact form module settings.
## [v2.1.0] - 2018-05-07
### Added
- Added opt-in for updating invoice address.
* New module setting blOeGdprOptinInvoiceAddress.
* Application/views/blocks/user_checkout_billing_feedback.tpl
* Application/views/blocks/user_invoice_address_form.tpl
### Changed
- The following templates have been changed
* Application/views/blocks/user_shipping_address.tpl renamed to Application/views/blocks/user_address.tpl
* Application/views/blocks/user_checkout_shipping_change.tpl renamed to Application/views/blocks/user_checkout_change.tpl
* Application/views/blocks/user.tpl
* Application/views/blocks/user_shipping_address_form.tpl
* Application/views/blocks/user_checkout_shipping_feedback.tpl
- Documentation was updated.
## [v2.0.0] - 2018-04-06
### Changed
- The GDPR Opt-In Module was fully ported as described in
[modules porting guide](https://docs.oxid-esales.com/developer/en/6.0/update/eshop_from_53_to_6/modules.html).
[v1.0.1]: https://gitlab.o3-shop.com/o3/gdpr-optin-module/-/compare/v1.0.0...v1.0.1
[v1.0.0]: https://gitlab.o3-shop.com/o3/gdpr-optin-module/-/tags/v1.0.0
[O3-Shop]: https://www.o3-shop.com/
[v2.3.3]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v2.3.2...v2.3.3
[v2.3.2]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v2.3.1...v2.3.2
[v2.3.1]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v2.3.0...v2.3.1
[v2.3.0]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v2.2.1...v2.3.0
[v2.2.2]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v2.2.1...v2.2.2
[v2.2.1]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v2.2.0...v2.2.1
[v2.2.0]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v2.1.2...v2.2.0
[v2.1.2]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v2.1.1...v2.1.2
[v2.1.1]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v2.1.0...v2.1.1
[v2.1.0]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v2.0.0...v2.1.0
[v2.0.0]: https://github.com/OXID-eSales/gdpr-optin-module/compare/v1.0.0...v2.0.0

View File

@@ -0,0 +1,170 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Component;
/**
* Class oeGdprOptinOxcmp_user.
* Extends oxcmp_user.
*
* @see \OxidEsales\Eshop\Application\Component\UserComponent
*/
class UserComponent extends UserComponent_parent
{
/**
* Create new user.
*
* @return mixed
*/
public function createUser()
{
if (false == $this->validateRegistrationOptin()) {
//show error message on submit but not on page reload.
if ($this->getRequestParameter('stoken')) {
\OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\UtilsView::class)->addErrorToDisplay('OEGDPROPTIN_CONFIRM_USER_REGISTRATION_OPTIN', false, true);
\OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\UtilsView::class)->addErrorToDisplay('OEGDPROPTIN_CONFIRM_USER_REGISTRATION_OPTIN', false, true, 'oegdproptin_userregistration');
}
} else {
return parent::createUser();
}
}
/**
* Mostly used for customer profile editing screen (O3-Shop ->
* MY ACCOUNT). Checks if oUser is set (\OxidEsales\Eshop\Application\Component\UserComponent::oUser) - if
* not - executes \OxidEsales\Eshop\Application\Component\UserComponent::_loadSessionUser(). If user unchecked newsletter
* subscription option - removes him from this group. There is an
* additional MUST FILL fields checking. Function returns true or false
* according to user data submission status.
*
* Session variables:
* <b>ordrem</b>
*
* @return bool true on success, false otherwise
*/
protected function _changeUser_noRedirect()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
if (!$session->checkSessionChallenge()) {
return;
}
// no user ?
$user = $this->getUser();
if (!$user) {
return;
}
$deliveryOptinValid = $this->validateDeliveryAddressOptIn();
$invoiceOptinValid = $this->validateInvoiceAddressOptIn();
if (false == $deliveryOptinValid) {
\OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\UtilsView::class)->addErrorToDisplay('OEGDPROPTIN_CONFIRM_STORE_DELIVERY_ADDRESS', false, true);
\OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\UtilsView::class)->addErrorToDisplay('OEGDPROPTIN_CONFIRM_STORE_DELIVERY_ADDRESS', false, true, 'oegdproptin_deliveryaddress');
}
if (false == $invoiceOptinValid) {
\OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\UtilsView::class)->addErrorToDisplay('OEGDPROPTIN_CONFIRM_STORE_INVOICE_ADDRESS', false, true);
\OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\UtilsView::class)->addErrorToDisplay('OEGDPROPTIN_CONFIRM_STORE_INVOICE_ADDRESS', false, true, 'oegdproptin_invoiceaddress');
}
$return = false;
if ( (true == $deliveryOptinValid) && (true == $invoiceOptinValid)) {
$return = parent::_changeUser_noRedirect();
}
return $return;
}
/**
* Validate delivery address optin.
* Needed if we get delivery address data from request.
*
* @return bool
*/
protected function validateDeliveryAddressOptIn()
{
$return = true;
$optin = (int) $this->getRequestParameter('oegdproptin_deliveryaddress');
$changeExistigAddress = (int) $this->getRequestParameter('oegdproptin_changeDelAddress');
$addressId = $this->getRequestParameter('oxaddressid');
$deliveryAddressData = $this->_getDelAddressData();
if (\OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('blOeGdprOptinDeliveryAddress')
&& ((null == $addressId) || ('-1' == $addressId) || (1 == $changeExistigAddress))
&& !empty($deliveryAddressData)
&& (1 !== $optin)
) {
$return = false;
}
return $return;
}
/**
* Validate user registration optin.
*
* @return bool
*/
protected function validateRegistrationOptin()
{
$return = true;
$optin = (int) $this->getRequestParameter('oegdproptin_userregistration');
//1 is for guest buy, 3 for account creation
$registrationOption = (int) $this->getRequestParameter('option');
if (\OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('blOeGdprOptinUserRegistration') && (3 == $registrationOption) && (1 !== $optin)) {
$return = false;
}
return $return;
}
/**
* Validate invoice address optin.
* Needed if user changes invoice address.
*
* @return bool
*/
protected function validateInvoiceAddressOptIn()
{
$return = true;
$optin = (int) $this->getRequestParameter('oegdproptin_invoiceaddress');
$changeExistigAddress = (int) $this->getRequestParameter('oegdproptin_changeInvAddress');
if (\OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('blOeGdprOptinInvoiceAddress')
&& (1 == $changeExistigAddress)
&& (1 !== $optin)
) {
$return = false;
}
return $return;
}
/**
* Wrapper for \OxidEsales\Eshop\Core\Request::getRequestParameter()
*
* @param string $name Parameter name
*
* @return mixed
*/
protected function getRequestParameter($name)
{
$request = \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\Request::class);
return $request->getRequestParameter($name);
}
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Component\Widget;
/**
* Class ArticleDetails
* Extends \OxidEsales\Eshop\Application\Component\Widget\ArticleDetails
*
* @package OxidEsales\GdprOptinModule\Component\Widget
* @see \OxidEsales\Eshop\Application\Component\Widget\ArticleDetails
*/
class ArticleDetails extends ArticleDetails_parent
{
/**
* Is optin for product review required.
*
* @return bool
*/
public function isReviewOptInValidationRequired()
{
$review = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
return $review->isReviewOptInValidationRequired();
}
/**
* Was there an error for shop side review optin validation?
*
* @return bool
*/
public function isReviewOptInError()
{
$review = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
return $review->isReviewOptInError();
}
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Component\Widget;
/**
* Class Review
* Extends \OxidEsales\Eshop\Application\Component\Widget\Review.
*
* @package OxidEsales\GdprOptinModule\Component\Widget
* @see \OxidEsales\Eshop\Application\Component\Widget\Review
*/
class Review extends Review_parent
{
/**
* Is optin for product review required.
*
* @return bool
*/
public function isReviewOptInValidationRequired()
{
$review = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
return $review->isReviewOptInValidationRequired();
}
/**
* Was there an error for shop side review optin validation?
*
* @return bool
*/
public function isReviewOptInError()
{
$review = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
return $review->isReviewOptInError();
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Controller;
/**
* Class ArticleDetailsController
* Extends \OxidEsales\Eshop\Application\Controller\ArticleDetailsController.
*
* @package OxidEsales\GdprOptinModule\Controller
* @see \OxidEsales\Eshop\Application\Controller\ArticleDetailsController
*/
class ArticleDetailsController extends ArticleDetailsController_parent
{
/**
* Saves user ratings and review text (oxReview object)
*
* @return null
*/
public function saveReview()
{
$reviewController = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
if (!$reviewController->validateOptIn()) {
\OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\UtilsView::class)->addErrorToDisplay('OEGDPROPTIN_REVIEW_FORM_ERROR_MESSAGE');
return false;
}
return parent::saveReview();
}
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Controller;
/**
* Class ContactController
* Extends \OxidEsales\Eshop\Application\Controller\ContactController
*
* @package OxidEsales\GdprOptinModule\Controller
*/
class ContactController extends ContactController_parent
{
const CONTACT_FORM_METHOD_DEFAULT = 'deletion';
/**
* Flag which shows if validation failed because of optin is not checked
*
* @var bool
*/
protected $optInError = false;
/**
* Validation and contacts email sending
*
* @return bool
*/
public function send()
{
$optInValue = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter('c_oegdproptin');
if ($this->isOptInValidationRequired() && !$optInValue) {
\OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\UtilsView::class)->addErrorToDisplay('OEGDPROPTIN_CONTACT_FORM_ERROR_MESSAGE');
$this->optInError = true;
return false;
}
return parent::send();
}
/**
* Check if validation failed because of the optin checkbox not checked
*
* @return bool
*/
public function isOptInError()
{
return $this->optInError;
}
/**
* Check if opt in validation is required.
*
* @return bool
*/
public function isOptInValidationRequired()
{
return $this->getContactFormMethod() != self::CONTACT_FORM_METHOD_DEFAULT;
}
/**
* Get currently selected contact form opt in method
*
* @return string
*/
private function getContactFormMethod()
{
$method = self::CONTACT_FORM_METHOD_DEFAULT;
if ($configMethod = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('OeGdprOptinContactFormMethod')) {
$method = $configMethod;
}
return $method;
}
}

View File

@@ -0,0 +1,91 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Controller;
/**
* Class ReviewController
* Extends \OxidEsales\Eshop\Application\Controller\ArticleDetailsController.
*
* @package OxidEsales\GdprOptinModule\Controller
* @see \OxidEsales\Eshop\Application\Controller\ArticleDetailsController
*/
class ReviewController extends ReviewController_parent
{
const REVIEW_OPTIN_PARAM = 'blOeGdprOptinProductReviews';
/**
* Saves user ratings and review text (oxReview object)
*
* @return null
*/
public function saveReview()
{
if (!$this->validateOptIn()) {
\OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\UtilsView::class)->addErrorToDisplay('OEGDPROPTIN_REVIEW_FORM_ERROR_MESSAGE');
return false;
}
return parent::saveReview();
}
/**
* Check if opt in validation for review is required.
*
* @return bool
*/
public function isReviewOptInValidationRequired()
{
return (bool)\OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam(self::REVIEW_OPTIN_PARAM);
}
/**
* Validate current request data, regardless if form was submitted or not
*
* @return bool
*/
public function validateOptIn()
{
$optInValue = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter('rvw_oegdproptin');
if ($this->isReviewOptInValidationRequired() && !$optInValue) {
return false;
}
return true;
}
/**
* Check if form was sent but optin not checked when required
*
* @return bool
*/
public function isReviewOptInError()
{
$formSent = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter('rvw_oegdproptin') !== null;
$review = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
$result = false;
if ($formSent && !$review->validateOptIn()) {
$result = true;
}
return $result;
}
}

View File

@@ -0,0 +1,131 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Core;
/**
* Class GdprOptinModule
* Handles module setup, provides additional tools and module related helpers.
*
* @codeCoverageIgnore
*
* @package OxidEsales\GdprOptinModule\Core
*/
class GdprOptinModule extends \OxidEsales\Eshop\Core\Module\Module
{
/**
* Class constructor.
* Sets current module main data and loads the rest module info.
*/
public function __construct()
{
$moduleId = 'oegdproptin';
$this->setModuleData(
[
'id' => $moduleId,
'title' => 'oegdproptin',
'description' => 'OE GDPR opt-in Module',
]
);
$this->load($moduleId);
\OxidEsales\Eshop\Core\Registry::set('oeGdprOptinModule', $this);
}
/**
* Module activation script.
*/
public static function onActivate()
{
self::clearTmp();
}
/**
* Module deactivation script.
*/
public static function onDeactivate()
{
self::clearTmp();
}
/**
* Clean temp folder content.
*
* @param string $clearFolderPath Sub-folder path to delete from. Should be a full, valid path inside temp folder.
*
* @return boolean
*/
public static function clearTmp($clearFolderPath = '')
{
$folderPath = self::_getFolderToClear($clearFolderPath);
$directoryHandler = opendir($folderPath);
if (!empty($directoryHandler)) {
while (false !== ($fileName = readdir($directoryHandler))) {
$filePath = $folderPath . DIRECTORY_SEPARATOR . $fileName;
self::_clear($fileName, $filePath);
}
closedir($directoryHandler);
}
return true;
}
/**
* Check if provided path is inside Shop `tpm/` folder or use the `tmp/` folder path.
*
* @param string $clearFolderPath
*
* @return string
*/
protected static function _getFolderToClear($clearFolderPath = '')
{
$templateFolderPath = (string) \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('sCompileDir');
if (!empty($clearFolderPath) and (strpos($clearFolderPath, $templateFolderPath) !== false)) {
$folderPath = $clearFolderPath;
} else {
$folderPath = $templateFolderPath;
}
return $folderPath;
}
/**
* Check if resource could be deleted, then delete it's a file or
* call recursive folder deletion if it's a directory.
*
* @param string $fileName
* @param string $filePath
*/
protected static function _clear($fileName, $filePath)
{
if (!in_array($fileName, ['.', '..', '.gitkeep', '.htaccess'])) {
if (is_file($filePath)) {
@unlink($filePath);
} else {
self::clearTmp($filePath);
}
}
}
}

View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View File

@@ -0,0 +1,29 @@
GDPR opt-in module
==================
Module adds opt-in functionality which is required for GDPR law.
### Installation
System requirements and installation instructions are described in the module documentation: https://docs.o3-shop.com/modules/gdpr-optin/de/2.3/installation.html.
### Module installation via composer
* **composer require o3-shop/gdpr-optin-module:^1.0** to install the released version compatible with O3-Shop 1.x compilation
### Features
Module allows to control:
* the opt-in option for delivery addresses to be conform with GDPR
* the opt-in option for user registration to be conform with GDPR
* the opt-in option for review writing form to be conform with GDPR
* the information customer is shown regarding what happens to the contact form data
after the request has been processed.
### Bugs and Issues
If you experience any bugs or issues, please report them in the section **Module GDPR Opt-in** of https://issues.o3-shop.com.
### Documentation
The module documentation can be found on our documentation platform: https://docs.o3-shop.com/modules/gdpr-optin/de/2.3/index.html.

View File

@@ -0,0 +1,66 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Tests\Integration;
/**
* Class ContactControllerTest
*
* @package OxidEsales\GdprOptinModule\Tests\Integration
*/
class ContactControllerTest extends \OxidEsales\TestingLibrary\UnitTestCase
{
/**
* Test checkbox validation.
*
* @dataProvider dataProviderOptInValidationRequired
*/
public function testOptInValidationRequired($configValue, $expected)
{
\OxidEsales\Eshop\Core\Registry::getConfig()->setConfigParam('OeGdprOptinContactFormMethod', $configValue);
$controller = oxNew(\OxidEsales\Eshop\Application\Controller\ContactController::class);
$this->assertSame($expected, $controller->isOptInValidationRequired());
}
/**
* @return array
*/
public function dataProviderOptInValidationRequired()
{
return [
'formMethod-deletion' => ['deletion', false],
'formMethod-statistical' => ['statistical', true],
];
}
/**
* Test validation error appears if needed
*/
public function testSendError()
{
\OxidEsales\Eshop\Core\Registry::getConfig()->setConfigParam('OeGdprOptinContactFormMethod', "statistical");
$controller = oxNew(\OxidEsales\Eshop\Application\Controller\ContactController::class);
$this->assertFalse($controller->isOptInError());
$this->assertFalse($controller->send());
$this->assertTrue($controller->isOptInError());
}
}

View File

@@ -0,0 +1,536 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Tests\Integration;
use OxidEsales\Eshop\Application\Component\BasketComponent;
use OxidEsales\Eshop\Application\Component\Widget\ArticleDetails;
use OxidEsales\Eshop\Application\Controller\AccountUserController;
use OxidEsales\Eshop\Application\Controller\ContactController;
use OxidEsales\Eshop\Application\Controller\RegisterController;
use OxidEsales\Eshop\Application\Controller\UserController;
use OxidEsales\Eshop\Application\Model\Article;
use OxidEsales\Eshop\Application\Model\Basket;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\DatabaseProvider;
use OxidEsales\Eshop\Core\Field;
use OxidEsales\Eshop\Core\Output;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\UtilsView;
use OxidEsales\TestingLibrary\UnitTestCase;
/**
* Class FrontendTest
*
* @package OxidEsales\GdprOptinModule\Tests\Integration
*/
class FrontendTest extends UnitTestCase
{
const TEST_USER_ID = '_gdprtest';
const TEST_ARTICLE_OXID = '_gdpr_test_product';
/**
* Test product.
*
* @var Article
*/
private $product =null;
/**
* Test set up.
*/
protected function setUp(): void
{
parent::setUp();
$this->replaceBlocks();
$this->createTestUser();
$this->createTestProduct();
$this->createBasket();
Registry::get(UtilsView::class)->getSmarty(true);
}
/**
* Tear down.
*/
protected function tearDown(): void
{
$this->cleanUpTable('oxuser', 'oxid');
$this->cleanUpTable('oxarticles', 'oxid');
$this->cleanUpTable('oxtplblocks', 'oxid');
parent::tearDown();
}
/**
* @return array
*/
public function providerDeliveryAddressOptin()
{
return [
'enable_optin_true_flow' => [true, 'doAssertStringContainsString', 'flow'],
'enable_optin_false_flow' => [false, 'doAssertStringNotContainsString', 'flow']
];
}
/**
* Test checkbox visibility.
*
* @dataProvider providerDeliveryAddressOptin
*
* @param bool $reqireOptinDeliveryAddress
* @param string $assertMethod
* @param string $theme
*/
public function testDeliveryAddressOptinForCheckout($reqireOptinDeliveryAddress, $assertMethod, $theme)
{
Registry::getSession()->setVariable('blshowshipaddress', true);
Registry::getConfig()->setConfigParam('blOeGdprOptinDeliveryAddress', $reqireOptinDeliveryAddress);
Registry::getConfig()->setConfigParam('sTheme', $theme);
$content = $this->getTemplateOutput(UserController::class, 'form/user_checkout_change.tpl');
$this->$assertMethod('id="oegdproptin_deliveryaddress"', $content);
}
/**
* Test checkbox visibility.
*
* @dataProvider providerDeliveryAddressOptin
*
* @param bool $reqireOptinDeliveryAddress
* @param string $assertMethod
* @param string $theme
*/
public function testDeliveryAddressOptinForUserAccount($reqireOptinDeliveryAddress, $assertMethod, $theme)
{
Registry::getSession()->setVariable('blshowshipaddress', true);
Registry::getConfig()->setConfigParam('blOeGdprOptinDeliveryAddress', $reqireOptinDeliveryAddress);
Registry::getConfig()->setConfigParam('sTheme', $theme);
$content = $this->getTemplateOutput(AccountUserController::class, 'form/user.tpl');
$this->$assertMethod('id="oegdproptin_deliveryaddress"', $content);
}
/**
* @return array
*/
public function providerInvoiceAddressOptin()
{
return [
'enable_optin_true_flow' => [true, 'doAssertStringContainsString', 'flow'],
'enable_optin_false_flow' => [false, 'doAssertStringNotContainsString', 'flow']
];
}
/**
* Test checkbox visibility.
*
* @dataProvider providerInvoiceAddressOptin
*
* @param bool $reqireOptinInvoiceAddress
* @param string $assertMethod
* @param string $theme
*/
public function testInvoiceAddressOptinForCheckout($reqireOptinInvoiceAddress, $assertMethod, $theme)
{
Registry::getConfig()->setConfigParam('blOeGdprOptinInvoiceAddress', $reqireOptinInvoiceAddress);
Registry::getConfig()->setConfigParam('sTheme', $theme);
$content = $this->getTemplateOutput(UserController::class, 'form/user_checkout_change.tpl');
$this->$assertMethod('id="oegdproptin_invoiceaddress"', $content);
}
/**
* Test checkbox visibility.
*
* @dataProvider providerInvoiceAddressOptin
*
* @param bool $reqireOptinInvoiceAddress
* @param string $assertMethod
* @param string $theme
*/
public function testInvoiceAddressOptinForUserAccount($reqireOptinInvoiceAddress, $assertMethod, $theme)
{
Registry::getConfig()->setConfigParam('blOeGdprOptinInvoiceAddress', $reqireOptinInvoiceAddress);
Registry::getConfig()->setConfigParam('sTheme', $theme);
$content = $this->getTemplateOutput(AccountUserController::class, 'form/user.tpl');
$this->$assertMethod('id="oegdproptin_invoiceaddress"', $content);
}
/**
* @return array
*/
public function providerUserRegistrationOptin()
{
return [
'enable_optin_true_flow' => [true, 'doAssertStringContainsString', 'flow'],
'enable_optin_false_flow' => [false, 'doAssertStringNotContainsString', 'flow']
];
}
/**
* Test checkbox visibility.
* NOTE: user must not be logged in here. Need to simulate user registration.
*
* @dataProvider providerUserRegistrationOptin
*
* @param bool $blOeGdprOptinUserRegistration
* @param string $assertMethod
* @param string $theme
*/
public function testUserRegistrationOptin($blOeGdprOptinUserRegistration, $assertMethod, $theme)
{
Registry::getConfig()->setConfigParam('blOeGdprOptinUserRegistration', $blOeGdprOptinUserRegistration);
Registry::getConfig()->setConfigParam('sTheme', $theme);
Registry::getSession()->setUser(null);
$addViewData = [];
$addViewData['oxcmp_basket'] = oxNew(Basket::class);
$addViewData['oConfig'] = Registry::getConfig();
$addViewData['sidebar'] = '';
$content = $this->getTemplateOutput(RegisterController::class, 'page/account/register.tpl', $addViewData);
$this->$assertMethod('id="oegdproptin_userregistration"', $content);
}
/**
* @return array
*/
public function providerUserCheckoutRegistrationOptin()
{
return [
'enable_optin_true_flow_noreg' => [true, 'doAssertStringNotContainsString', 'flow', 1],
'enable_optin_false_flow_noreg' => [false, 'doAssertStringNotContainsString', 'flow', 1],
'enable_optin_true_flow_reg' => [true, 'doAssertStringContainsString', 'flow', 3],
'enable_optin_false_flow_reg' => [false, 'doAssertStringNotContainsString', 'flow', 3]
];
}
/**
* Test checkbox visibility during registration.
* NOTE: user must not be logged in here. Need to simulate user registration.
*
* @dataProvider providerUserCheckoutRegistrationOptin
*
* @param bool $blOeGdprOptinUserRegistration
* @param string $assertMethod
* @param string $theme
* @param int $option
*/
public function testUserRegistrationOptinDuringCheckout($blOeGdprOptinUserRegistration, $assertMethod, $theme, $option)
{
$this->setRequestParameter('option', $option);
Registry::getConfig()->setConfigParam('blOeGdprOptinUserRegistration', $blOeGdprOptinUserRegistration);
Registry::getConfig()->setConfigParam('sTheme', $theme);
Registry::getSession()->setUser(null);
$addViewData = [];
$addViewData['oxcmp_basket'] = oxNew(Basket::class);
$addViewData['oConfig'] = Registry::getConfig();
$addViewData['sidebar'] = '';
$content = $this->getTemplateOutput(UserController::class, 'page/checkout/user.tpl', $addViewData);
$this->$assertMethod('id="oegdproptin_userregistration"', $content);
}
/**
* Test contact form deletion optin
*/
public function testContactFormDeletionOptIn()
{
Registry::getConfig()->setConfigParam('OeGdprOptinContactFormMethod', 'deletion');
Registry::getConfig()->setConfigParam('sTheme', 'flow');
$expected = Registry::getLang()->translateString("OEGDPROPTIN_CONTACT_FORM_MESSAGE_DELETION");
$content = $this->getTemplateOutput(ContactController::class, 'form/contact.tpl');
$this->doAssertStringContainsString($expected, $content);
$this->doAssertStringNotContainsString('name="c_oegdproptin"', $content);
}
/**
* Test contact form statistical optin
*/
public function testContactFormStatisticalOptIn()
{
Registry::getConfig()->setConfigParam('OeGdprOptinContactFormMethod', 'statistical');
Registry::getConfig()->setConfigParam('sTheme', 'flow');
$expected = Registry::getLang()->translateString("OEGDPROPTIN_CONTACT_FORM_MESSAGE_STATISTICAL");
$content = $this->getTemplateOutput(ContactController::class, 'form/contact.tpl');
$this->doAssertStringContainsString($expected, $content);
$this->doAssertStringContainsString('name="c_oegdproptin"', $content);
}
/**
* Creates filled basket object and stores it in session.
*/
private function createBasket()
{
Registry::getSession()->getBasket();
$this->assertNull(Registry::getSession()->getVariable('_newitem'));
$basketComponent = oxNew(BasketComponent::class);
$basketComponent->toBasket(self::TEST_ARTICLE_OXID, 1);
$basket = $basketComponent->render();
$this->assertEquals(1, $basket->getProductsCount());
Registry::getSession()->setBasket($basket);
}
/**
* Create a test product.
*/
private function createTestProduct()
{
$product = oxNew(Article::class);
$product->setId(self::TEST_ARTICLE_OXID);
$product->oxarticles__oxshopid = new Field(1);
$product->oxarticles__oxtitle = new Field(self::TEST_ARTICLE_OXID);
$product->oxarticles__oxprice = new Field(6.66);
$product->save();
$this->product = $product;
}
/**
* Create a test user.
*/
private function createTestUser()
{
$user = oxNew(User::class);
$user->setId(self::TEST_USER_ID);
$user->assign(
[
'oxfname' => 'Max',
'oxlname' => 'Mustermann',
'oxusername' => 'gdpruser@oxid.de',
'oxpassword' => md5('agent'),
'oxactive' => 1,
'oxshopid' => 1,
'oxcountryid' => 'a7c40f631fc920687.20179984',
'oxboni' => '600',
'oxstreet' => 'Teststreet',
'oxstreetnr' => '101',
'oxcity' => 'Hamburg',
'oxzip' => '22769'
]
);
$user->save();
//Ensure we have it in session and as active user
$this->ensureActiveUser();
}
/**
* Make sure we have the test user as active user.
*/
private function ensureActiveUser()
{
$this->setSessionParam('usr', self::TEST_USER_ID);
$this->setSessionParam('auth', self::TEST_USER_ID);
$user = oxNew(User::class);
$user->load(self::TEST_USER_ID);
Registry::getSession()->setUser($user);
$user->setUser($user);
$this->assertTrue($user->loadActiveUser());
}
/**
* Test helper to replace header and footer as they are not needed for our tests.
*/
private function replaceBlocks()
{
$shopId = Registry::getConfig()->getShopId();
$query = "INSERT INTO oxtplblocks (OXID, OXACTIVE, OXSHOPID, OXTEMPLATE, OXBLOCKNAME, OXPOS, OXFILE, OXMODULE) VALUES " .
"('_test_header', 1, '{$shopId}', 'layout/page.tpl', 'layout_header', 1, 'Tests/Integration/views/blocks/empty.tpl', 'oegdproptin'), " .
"('_test_footer', 1, '{$shopId}', 'layout/footer.tpl', 'footer_main', 1, 'Tests/Integration/views/blocks/empty.tpl', 'oegdproptin'), " .
"('_test_sidebar', 1, '{$shopId}', 'layout/sidebar.tpl', 'sidebar', 1, 'Tests/Integration/views/blocks/empty.tpl', 'oegdproptin'), " .
"('_test_sgvo_icons', 1, '{$shopId}', 'layout/base.tpl', 'theme_svg_icons', 1, 'Tests/Integration/views/blocks/empty.tpl', 'oegdproptin'), " .
"('_test_listitem', 1, '{$shopId}', 'page/review/review.tpl', 'widget_product_listitem_line_picturebox', 1, 'Tests/Integration/views/blocks/empty.tpl', 'oegdproptin')";
DatabaseProvider::getDb()->execute($query);
}
/**
* @return array
*/
public function providerContactForm()
{
return [
'flow' => ['flow']
];
}
/**
* @return array
*/
public function providerDetailsReviewOptin()
{
return [
'enable_optin_true_flow_art' => [true, 'doAssertStringContainsString', 'flow', 'oxwArticleDetails'],
'enable_optin_false_flow_art' => [false, 'doAssertStringNotContainsString', 'flow', 'oxwArticleDetails']
];
}
/**
* Test review form optin visibility.
*
* @dataProvider providerDetailsReviewOptin
*
* @param bool $blOeGdprOptinProductReviews
* @param string $assertMethod
* @param string $theme
* @param string $class
*/
public function testDetailsReviewFormOptIn($blOeGdprOptinProductReviews, $assertMethod, $theme, $class)
{
Registry::getConfig()->setConfigParam('blOeGdprOptinProductReviews', $blOeGdprOptinProductReviews);
Registry::getConfig()->setConfigParam('sTheme', $theme);
$content = $this->getTemplateOutput($class, 'widget/reviews/reviews.tpl', null, true);
$this->$assertMethod('id="rvw_oegdproptin"', $content);
//Error message always present in DOM, if checkbox present, but is hidden by default
$message = Registry::getLang()->translateString("OEGDPROPTIN_REVIEW_FORM_ERROR_MESSAGE");
$this->$assertMethod($message, $content);
}
/**
* @return array
*/
public function providerOxwArticleDetailsReviewOptinError()
{
return [
'enable_optin_true_flow_art' => [true, 'doAssertStringContainsString', 'flow', 1],
'enable_optin_false_flow_art' => [false, 'doAssertStringNotContainsString', 'flow', 0]
];
}
/**
* Test review form optin error message visibility.
*
* @dataProvider providerOxwArticleDetailsReviewOptinError
*
* @param bool $blOeGdprOptinProductReviews
* @param string $assertMethod
* @param string $theme
* @param int $count
*/
public function testOxwArticleDetailsReviewFormOptInError($blOeGdprOptinProductReviews, $assertMethod, $theme, $count)
{
Registry::getConfig()->setConfigParam('blOeGdprOptinProductReviews', $blOeGdprOptinProductReviews);
Registry::getConfig()->setConfigParam('sTheme', $theme);
$controller = $this->getMock(ArticleDetails::class, ['isReviewOptInError']);
$controller->expects($this->exactly($count))->method('isReviewOptInError')->will($this->returnValue(true));
$controller->init();
$controller->setViewProduct($this->product);
$content = $this->doRender($controller, 'widget/reviews/reviews.tpl');
$expected = Registry::getLang()->translateString("OEGDPROPTIN_REVIEW_FORM_ERROR_MESSAGE");
$this->$assertMethod($expected, $content);
}
/**
* @param string $controllerName
* @param string $template
* @param null $addViewData
* @param bool $setProduct Set true to add test product to view (needed for review tests)
*
* @return mixed
*/
protected function getTemplateOutput($controllerName, $template, $addViewData = null, $setProduct = false)
{
$controller = oxNew($controllerName);
$controller->init();
if ($setProduct) {
$controller->setViewProduct($this->product);
}
return $this->doRender($controller, $template, $addViewData);
}
/**
* Test helper to render output.
*
* @param object $controller
* @param string $template
*
* @return string
*/
protected function doRender($controller, $template, $addViewData = null)
{
//prepare output
$output = oxNew(Output::class);
$viewData = $output->processViewArray($controller->getViewData(), $controller->getClassName());
if (is_array($addViewData)) {
$viewData = array_merge($viewData, $addViewData);
} else {
$viewData['oxcmp_user'] = Registry::getSession()->getUser();
$viewData['oxcmp_basket'] = Registry::getSession()->getBasket();
$viewData['oConfig'] = Registry::getConfig();
}
$controller->setViewData($viewData);
return Registry::get(UtilsView::class)->getTemplateOutput($template, $controller);
}
/**
* @param string $needle
* @param string $haystack
* @param string $message
*/
protected function doAssertStringContainsString($needle, $haystack, $message = '')
{
if (method_exists($this, 'assertStringContainsString')) {
parent::assertStringContainsString($needle, $haystack, $message);
} else {
parent::assertContains($needle, $haystack, $message);
}
}
/**
* @param string $needle
* @param string $haystack
* @param string $message
*/
protected function doAssertStringNotContainsString($needle, $haystack, $message = '')
{
if (method_exists($this, 'assertStringNotContainsString')) {
parent::assertStringNotContainsString($needle, $haystack, $message);
} else {
parent::assertNotContains($needle, $haystack, $message);
}
}
}

View File

@@ -0,0 +1,137 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Tests\Integration;
use OxidEsales\GdprOptinModule\Controller\ReviewController;
/**
* Class ReviewControllerTest
*
* @package OxidEsales\GdprOptinModule\Tests\Integration
*/
class ReviewControllerTest extends \OxidEsales\TestingLibrary\UnitTestCase
{
/**
* Test validation error appears if needed
*/
public function testSendError()
{
/** @var ReviewController $controller */
$controller = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
\OxidEsales\Eshop\Core\Registry::getConfig()->setConfigParam($controller::REVIEW_OPTIN_PARAM, true);
$this->assertFalse($controller->saveReview());
}
/**
* Test validation error appears if needed
*/
public function testSendNotError()
{
/** @var ReviewController $controller */
$controller = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
\OxidEsales\Eshop\Core\Registry::getConfig()->setConfigParam($controller::REVIEW_OPTIN_PARAM, false);
$this->assertNull($controller->saveReview());
}
/**
* Test if validation is required.
*
* @dataProvider dataProviderReviewOptInValidationRequired
*/
public function testReviewOptInValidationRequired($configValue, $expected)
{
/** @var ReviewController $controller */
$controller = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
\OxidEsales\Eshop\Core\Registry::getConfig()->setConfigParam($controller::REVIEW_OPTIN_PARAM, $configValue);
$this->assertSame($expected, $controller->isReviewOptInValidationRequired());
}
/**
* @return array
*/
public function dataProviderReviewOptInValidationRequired()
{
return [
'required' => [true, true],
'not-required' => [false, false]
];
}
/**
* Test opt in validation
*
* @dataProvider dataProviderValidateOptIn
*/
public function testValidateOptIn($configValue, $checkboxStatus, $expectedValue)
{
/** @var ReviewController $controller */
$controller = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
\OxidEsales\Eshop\Core\Registry::getConfig()->setConfigParam($controller::REVIEW_OPTIN_PARAM, $configValue);
$this->setRequestParameter('rvw_oegdproptin', $checkboxStatus);
$this->assertSame($expectedValue, $controller->validateOptIn());
}
/**
* @return array
*/
public function dataProviderValidateOptIn()
{
return [
'required-checked' => [true, 1, true],
'required-not-checked' => [true, 0, false],
'required-not-exist' => [true, null, false],
'not-required-checked' => [false, 1, true],
'not-required-not-checked' => [false, 0, true],
'not-required-not-exits' => [false, null, true]
];
}
/**
* Test opt in validation
*
* @dataProvider dataProviderReviewOptInError
*/
public function testReviewOptInError($configValue, $checkboxStatus, $expectedValue)
{
/** @var ReviewController $controller */
$controller = oxNew(\OxidEsales\Eshop\Application\Controller\ReviewController::class);
\OxidEsales\Eshop\Core\Registry::getConfig()->setConfigParam($controller::REVIEW_OPTIN_PARAM, $configValue);
$this->setRequestParameter('rvw_oegdproptin', $checkboxStatus);
$this->assertSame($expectedValue, $controller->isReviewOptInError());
}
/**
* @return array
*/
public function dataProviderReviewOptInError()
{
return [
'required-checked' => [true, 1, false],
'required-not-checked' => [true, 0, true],
'required-not-exist' => [true, null, false],
'not-required-checked' => [false, 1, false],
'not-required-not-checked' => [false, 0, false],
'not-required-not-exits' => [false, null, false]
];
}
}

View File

@@ -0,0 +1,365 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\GdprOptinModule\Tests\Integration;
use OxidEsales\Eshop\Application\Component\UserComponent;
use OxidEsales\Eshop\Application\Controller\RegisterController;
use OxidEsales\Eshop\Application\Controller\UserController;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\TestingLibrary\UnitTestCase;
/**
* Class UserComponentTest
*
* @package OxidEsales\GdprOptinModule\Tests\Integration
*/
class UserComponentTest extends UnitTestCase
{
const TEST_USER_ID = '_gdprtest';
/**
* Test set up.
*/
protected function setUp(): void
{
parent::setUp();
$this->createTestUser();
}
/**
* Tear down.
*/
protected function tearDown(): void
{
$this->cleanUpTable('oxuser', 'oxid');
parent::tearDown();
}
/**
* @return array
*/
public function providerDeliveryAddressOptin()
{
//Optin will only be required on changed or new address.
$addAddress = ['oxaddressid' => '-1'];
$changedAddress = ['oxaddressid' => 'someuniqueid', 'oegdproptin_changeDelAddress' => '1'];
return [
'optin_true_checkbox_true_show_true_new' => [true, true, 'assertFalse', true, $addAddress],
'optin_true_checkbox_true_show_true_change' => [true, true, 'assertFalse', true, $changedAddress],
'optin_true_checkbox_true_show_true' => [true, true, 'assertFalse', true, []],
'optin_true_checkbox_false_show_true_new' => [true, false, 'assertTrue', true, $addAddress],
'optin_true_checkbox_false_show_true_change' => [true, false, 'assertTrue', true, $changedAddress],
'optin_true_checkbox_false_show_true' => [true, false, 'assertTrue', true, []],
'optin_false_checkbox_true_show_true' => [false, true, 'assertFalse', true, []],
'optin_false_checkbox_false_show_true' => [false, false, 'assertFalse', true, []],
'optin_true_checkbox_true_show_false' => [true, true, 'assertFalse', false, []],
'optin_true_checkbox_false_show_false' => [true, false, 'assertFalse', false, []],
'optin_false_checkbox_true_show_false' => [false, true, 'assertFalse', false, []],
'optin_false_checkbox_false_show_false' => [false, false, 'assertFalse', false, []],
];
}
/**
* Test checkbox validation.
*
* @dataProvider providerDeliveryAddressOptin
*
* @param bool $requireGdprOptinDeliveryAddress
* @param bool $checkboxChecked
* @param string $assertDisplayExc
* @param bool $showShip
* @param array $parameters
*/
public function testDeliveryAddressOptinValidationCheckoutUser($requireGdprOptinDeliveryAddress, $checkboxChecked, $assertDisplayExc, $showShip, $parameters)
{
Registry::getConfig()->setConfigParam('blOeGdprOptinDeliveryAddress', $requireGdprOptinDeliveryAddress);
$parameters['oegdproptin_deliveryaddress'] = (int) $checkboxChecked;
$parameters['blshowshipaddress'] = (int) $showShip;
$this->addRequestParameters($parameters);
$cmpUser = oxNew(UserComponent::class);
$cmpUser->changeuser();
$displayErrors = Registry::getSession()->getVariable('Errors');
$this->$assertDisplayExc(array_key_exists('oegdproptin_deliveryaddress', $displayErrors));
}
/**
* Test checkbox validation.
*
* @dataProvider providerDeliveryAddressOptin
*
* @param bool $requireGdprOptinDeliveryAddress
* @param bool $checkboxChecked
* @param string $assertDisplayExc
* @param bool $showShip
* @param array $parameters
*/
public function testDeliveryAddressOptinValidationAccountUser($requireGdprOptinDeliveryAddress, $checkboxChecked, $assertDisplayExc, $showShip, $parameters)
{
Registry::getConfig()->setConfigParam('blOeGdprOptinDeliveryAddress', $requireGdprOptinDeliveryAddress);
$parameters['oegdproptin_deliveryaddress'] = (int) $checkboxChecked;
$parameters['blshowshipaddress'] = (int) $showShip;
$this->addRequestParameters($parameters);
$cmpUser = oxNew(UserComponent::class);
$cmpUser->changeuser_testvalues();
$displayErrors = Registry::getSession()->getVariable('Errors');
$this->$assertDisplayExc(array_key_exists('oegdproptin_deliveryaddress', $displayErrors));
}
/**
* @return array
*/
public function providerInvoiceAddressOptin()
{
//Optin will be required on changed invoice address
$changedAddress = ['oegdproptin_changeInvAddress' => '1'];
return [
'optin_true_checkbox_true_change' => [true, true, 'assertFalse', $changedAddress],
'optin_true_checkbox_true_no_change' => [true, true, 'assertFalse', []],
'optin_true_checkbox_false_change' => [true, false, 'assertTrue', $changedAddress],
'optin_true_checkbox_false_no_change' => [true, false, 'assertFalse', []],
'optin_false_checkbox_false_change' => [false, false, 'assertFalse', $changedAddress],
'optin_false_checkbox_false_no_change' => [false, false, 'assertFalse', []],
'optin_false_checkbox_true_change' => [false, true, 'assertFalse', $changedAddress],
'optin_false_checkbox_true_no_change' => [false, true, 'assertFalse', []],
];
}
/**
* Test checkbox validation.
*
* @dataProvider providerInvoiceAddressOptin
*
* @param bool $requireGdprOptinInvoiceAddress
* @param bool $checkboxChecked
* @param string $assertDisplayExc
* @param array $parameters
*/
public function testInvoiceAddressOptinValidationCheckoutUser($requireGdprOptinInvoiceAddress, $checkboxChecked, $assertDisplayExc, $parameters)
{
Registry::getConfig()->setConfigParam('blOeGdprOptinInvoiceAddress', $requireGdprOptinInvoiceAddress);
$parameters['oegdproptin_invoiceaddress'] = (int) $checkboxChecked;
$this->addRequestParameters($parameters);
$cmpUser = oxNew(UserComponent::class);
$cmpUser->changeuser();
$displayErrors = Registry::getSession()->getVariable('Errors');
$this->$assertDisplayExc(array_key_exists('oegdproptin_invoiceaddress', $displayErrors));
}
/**
* Test checkbox validation.
*
* @dataProvider providerInvoiceAddressOptin
*
* @param bool $requireGdprOptinInvoiceAddress
* @param bool $checkboxChecked
* @param string $assertDisplayExc
* @param array $parameters
*/
public function testInvoiceAddressOptinValidationAccountUser($requireGdprOptinInvoiceAddress, $checkboxChecked, $assertDisplayExc, $parameters)
{
Registry::getConfig()->setConfigParam('blOeGdprOptinInvoiceAddress', $requireGdprOptinInvoiceAddress);
$parameters['oegdproptin_invoiceaddress'] = (int) $checkboxChecked;
$this->addRequestParameters($parameters);
$cmpUser = oxNew(UserComponent::class);
$cmpUser->changeuser_testvalues();
$displayErrors = Registry::getSession()->getVariable('Errors');
$this->$assertDisplayExc(array_key_exists('oegdproptin_invoiceaddress', $displayErrors));
}
/**
* @return array
*/
public function providerUserRegistrationOptin()
{
return [
'enable_true_optin_true_register' => [true, true, 'assertFalse'],
'enable_true_optin_false_register' => [true, false, 'assertTrue'],
'enable_false_optin_true_register' => [false, true, 'assertFalse'],
'enable_false_optin_false_register' => [false, false, 'assertFalse']
];
}
/**
* Test checkbox validation.
*
* @dataProvider providerUserRegistrationOptin
*
* @param bool $oeGdprUserRegistrationAddress
* @param bool $checkboxChecked
* @param string $assertDisplayExc
* @param string $parent
*/
public function testUserRegistrationOptinValidation($oeGdprUserRegistrationAddress, $checkboxChecked, $assertDisplayExc)
{
Registry::getSession()->setUser(null);
Registry::getConfig()->setConfigParam('blOeGdprOptinUserRegistration', $oeGdprUserRegistrationAddress);
$parameters = ['oegdproptin_userregistration' => (int) $checkboxChecked,
'option' => 3];
$this->addRequestParameters($parameters);
$cmpUser = oxNew(UserComponent::class);
$parentView = oxNew(RegisterController::class);
$cmpUser->setParent($parentView);
$cmpUser->createUser();
$displayErrors = Registry::getSession()->getVariable('Errors');
$this->$assertDisplayExc(array_key_exists('oegdproptin_userregistration', $displayErrors));
}
/**
* @return array
*/
public function providerUserCheckoutRegistrationOptin()
{
return [
'enable_true_optin_true_guestbuy' => [true, true, 'assertFalse', 1],
'enable_true_optin_false_guestbuy' => [true, false, 'assertFalse', 1],
'enable_false_optin_true_guestbuy' => [false, true, 'assertFalse', 1],
'enable_false_optin_false_guestbuy' => [false, false, 'assertFalse', 1],
'enable_true_optin_true_createuser' => [true, true, 'assertFalse', 3],
'enable_true_optin_false_createuser' => [true, false, 'assertTrue', 3],
'enable_false_optin_true_createuser' => [false, true, 'assertFalse', 3],
'enable_false_optin_false_createuser' => [false, false, 'assertFalse', 3]
];
}
/**
* Test checkbox validation.
*
* @dataProvider providerUserCheckoutRegistrationOptin
*
* @param bool $oeGdprUserRegistrationAddress
* @param bool $checkboxChecked
* @param string $assertDisplayExc
* @param int $option (1 = guest buy/no optin, 3 = create account)
*/
public function testUserRegistrationOptinValidationCheckoutUser($oeGdprUserRegistrationAddress, $checkboxChecked, $assertDisplayExc, $option)
{
Registry::getSession()->setUser(null);
Registry::getConfig()->setConfigParam('blOeGdprOptinUserRegistration', $oeGdprUserRegistrationAddress);
$parameters = ['oegdproptin_userregistration' => (int) $checkboxChecked,
'option' => $option];
$this->addRequestParameters($parameters);
$cmpUser = oxNew(UserComponent::class);
$parentView = oxNew(UserController::class);
$cmpUser->setParent($parentView);
$cmpUser->createUser();
$displayErrors = Registry::getSession()->getVariable('Errors');
$this->$assertDisplayExc(array_key_exists('oegdproptin_userregistration', $displayErrors));
}
/**
* Create a test user.
*/
private function createTestUser()
{
$user = oxNew(User::class);
$user->setId(self::TEST_USER_ID);
$user->assign(
[
'oxfname' => 'Max',
'oxlname' => 'Mustermann',
'oxusername' => 'gdpruser@oxid.de',
'oxpassword' => md5('agent'),
'oxactive' => 1,
'oxshopid' => 1,
'oxcountryid' => 'a7c40f631fc920687.20179984',
'oxboni' => '600',
'oxstreet' => 'Teststreet',
'oxstreetnr' => '101',
'oxcity' => 'Hamburg',
'oxzip' => '22769'
]
);
$user->save();
//Ensure we have it in session and as active user
$this->ensureActiveUser();
}
/**
* Make sure we have the test user as active user.
*/
private function ensureActiveUser()
{
$this->setSessionParam('usr', self::TEST_USER_ID);
$this->setSessionParam('auth', self::TEST_USER_ID);
$user = oxNew(User::class);
$user->load(self::TEST_USER_ID);
Registry::getSession()->setUser($user);
$user->setUser($user);
$this->assertTrue($user->loadActiveUser());
}
/**
* Test helper for setting requets parameters.
*
* @param array $parameters
*/
private function addRequestParameters($additionalParameters = [])
{
$address = 'a:13:{s:16:"oxaddress__oxsal";s:2:"MR";s:18:"oxaddress__oxfname";s:4:"Moxi";' .
's:18:"oxaddress__oxlname";s:6:"Muster";s:20:"oxaddress__oxcompany";s:0:"";' .
's:20:"oxaddress__oxaddinfo";s:0:"";s:19:"oxaddress__oxstreet";s:10:"Nicestreet";' .
's:21:"oxaddress__oxstreetnr";s:3:"666";s:16:"oxaddress__oxzip";s:5:"12345";' .
's:17:"oxaddress__oxcity";s:9:"Somewhere";s:22:"oxaddress__oxcountryid";' .
's:26:"a7c40f631fc920687.20179984";s:20:"oxaddress__oxstateid";s:0:"";' .
's:16:"oxaddress__oxfon";s:0:"";s:16:"oxaddress__oxfax";s:0:"";}';
$deliveryAddress = unserialize($address);
$parameters = ['deladr' => $deliveryAddress,
'stoken' => Registry::getSession()->getSessionChallengeToken()];
$parameters = array_merge($parameters, $additionalParameters);
foreach ($parameters as $key => $value) {
$this->setRequestParameter($key, $value);
}
}
}

View File

@@ -0,0 +1 @@
[{* empty *}]

View File

@@ -0,0 +1,24 @@
<phpunit backupGlobals="true"
backupStaticAttributes="false"
cacheTokens="true"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
printerClass="\OxidEsales\TestingLibrary\Printer"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
verbose="false">
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">../Component</directory>
<directory suffix=".php">../Controller</directory>
<directory suffix=".php">../Core</directory>
<directory suffix=".php">../Application</directory>
</whitelist>
</filter>
</phpunit>

View File

@@ -0,0 +1,43 @@
{
"name": "o3-shop/gdpr-optin-module",
"description": "This is the GDPR opt-in module for the O3-Shop.",
"type": "oxideshop-module",
"keywords": ["o3-shop", "modules", "eShop"],
"homepage": "https://www.o3-shop.com/",
"license": [
"GPL-3.0-only"
],
"author": [
{
"name": "OXID eSales AG",
"email": "info@oxid-esales.com",
"homepage": "https://oxid-esales.com",
"role": "Developer"
},
{
"name": "O3-Shop",
"email": "info@o3-shop.com",
"homepage": "https://www.o3-shop.com",
"role": "Developer"
}
],
"extra": {
"oxideshop": {
"blacklist-filter": [
"documentation/**/*.*"
],
"target-directory": "oe/gdproptin"
}
},
"require": {
"php": ">=7.1"
},
"autoload": {
"psr-4": {
"OxidEsales\\GdprOptinModule\\": "../../../source/modules/oe/gdproptin"
}
},
"replace": {
"oxid-esales/gdpr-optin-module": "2.3.3"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -0,0 +1,141 @@
<?php
/**
* This file is part of O3-Shop GDPR opt-in module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
/**
* Metadata version
*/
$sMetadataVersion = '2.0';
/**
* Module information
*/
$aModule = [
'id' => 'oegdproptin',
'title' => [
'de' => 'GDPR Opt-in',
'en' => 'GDPR Opt-in',
],
'description' => [
'de' => 'Das Modul stellt Opt-in-Funktionalit&auml;t f&uuml;r die Datenschutz-Grundverordnung (DSGVO) bereit',
'en' => 'This module provides the opt-in functionality for the European General Data Protection Regulation (GDPR)',
],
'thumbnail' => 'logo.png',
'version' => '1.0.1',
'author' => 'O3-Shop',
'url' => 'https://www.o3-shop.com/',
'email' => '',
'extend' => [
\OxidEsales\Eshop\Application\Component\Widget\ArticleDetails::class => \OxidEsales\GdprOptinModule\Component\Widget\ArticleDetails::class,
\OxidEsales\Eshop\Application\Component\Widget\Review::class => \OxidEsales\GdprOptinModule\Component\Widget\Review::class,
\OxidEsales\Eshop\Application\Component\UserComponent::class => \OxidEsales\GdprOptinModule\Component\UserComponent::class,
\OxidEsales\Eshop\Application\Controller\ReviewController::class => \OxidEsales\GdprOptinModule\Controller\ReviewController::class,
\OxidEsales\Eshop\Application\Controller\ArticleDetailsController::class => \OxidEsales\GdprOptinModule\Controller\ArticleDetailsController::class,
\OxidEsales\Eshop\Application\Controller\ContactController::class => \OxidEsales\GdprOptinModule\Controller\ContactController::class
],
'blocks' => [
[
'template' => 'form/user.tpl',
'block' => 'user_billing_address_form',
'file' => 'Application/views/blocks/user_invoice_address_form.tpl',
],
[
'template' => 'form/user.tpl',
'block' => 'user_shipping_address_form',
'file' => 'Application/views/blocks/user_shipping_address_form.tpl',
],
[
'template' => 'form/user.tpl',
'block' => 'user_form',
'file' => 'Application/views/blocks/user_address.tpl',
],
[
'template' => 'form/user.tpl',
'block' => 'user',
'file' => 'Application/views/blocks/user.tpl',
],
[
'template' => 'form/user_checkout_change.tpl',
'block' => 'user_checkout_change',
'file' => 'Application/views/blocks/user_checkout_change.tpl',
],
[
'template' => 'form/user_checkout_change.tpl',
'block' => 'user_checkout_shipping_feedback',
'file' => 'Application/views/blocks/user_checkout_shipping_feedback.tpl',
],
[
'template' => 'form/user_checkout_change.tpl',
'block' => 'user_checkout_billing_feedback',
'file' => 'Application/views/blocks/user_checkout_billing_feedback.tpl',
],
[
'template' => 'form/fieldset/user_account.tpl',
'block' => 'user_account_newsletter',
'file' => 'Application/views/blocks/user_account_newsletter.tpl',
],
[
'template' => 'form/contact.tpl',
'block' => 'contact_form_fields',
'file' => 'Application/views/blocks/contact_form_fields.tpl',
],
[
'template' => 'widget/reviews/reviews.tpl',
'block' => 'widget_reviews_form_fields',
'file' => 'Application/views/blocks/widget_reviews_form_fields.tpl',
]
],
'settings' => [
[
'group' => 'oegdproptin_settings',
'name' => 'blOeGdprOptinInvoiceAddress',
'type' => 'bool',
'value' => 'false'
],
[
'group' => 'oegdproptin_settings',
'name' => 'blOeGdprOptinDeliveryAddress',
'type' => 'bool',
'value' => 'false'
],
[
'group' => 'oegdproptin_settings',
'name' => 'blOeGdprOptinUserRegistration',
'type' => 'bool',
'value' => 'false'
],
[
'group' => 'oegdproptin_settings',
'name' => 'blOeGdprOptinProductReviews',
'type' => 'bool',
'value' => 'false'
],
[
'group' => 'oegdproptin_contact_form',
'name' => 'OeGdprOptinContactFormMethod',
'type' => 'select',
'value' => 'deletion',
'constraints' => 'deletion|statistical',
],
],
'events' => [
'onActivate' => '\OxidEsales\GdprOptinModule\Core\GdprOptinModule::onActivate',
'onDeactivate' => '\OxidEsales\GdprOptinModule\Core\GdprOptinModule::onDeactivate',
],
];

View File

@@ -0,0 +1,210 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Component;
/**
* Basket component
*
* @mixin \OxidEsales\Eshop\Application\Component\BasketComponent
*/
class BasketComponent extends BasketComponent_parent
{
/**
* Show ECS PopUp
*
* @var bool
*/
protected $shopPopUp = false;
/**
* Method returns URL to checkout products OR to show popup.
*
* @return string
*/
public function actionExpressCheckoutFromDetailsPage()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$validator = $this->getValidator();
$currentArticle = $this->getCurrentArticle();
$validator->setItemToValidate($currentArticle);
$validator->setBasket($session->getBasket());
if ($validator->isArticleValid()) {
//Make express checkout
$res = $this->actionAddToBasketAndGoToCheckout();
} else {
$res = $this->_getRedirectUrl();
//if amount is more than 0, do not redirect, show ESC popup instead
if ($currentArticle->getArticleAmount() > 0) {
$this->shopPopUp = true;
$res = null;
}
}
return $res;
}
/**
* Returns whether ECS popup should be shown
*
* @return bool
*/
public function shopECSPopUp()
{
return $this->shopPopUp;
}
/**
* Action method to add product to basket and return checkout URL.
*
* @return string
*/
public function actionAddToBasketAndGoToCheckout()
{
parent::tobasket();
return $this->getExpressCheckoutUrl();
}
/**
* Action method to return checkout URL.
*
* @return string
*/
public function actionNotAddToBasketAndGoToCheckout()
{
return $this->getExpressCheckoutUrl();
}
/**
* Returns express checkout URL
*
* @return string
*/
protected function getExpressCheckoutUrl()
{
return 'oepaypalexpresscheckoutdispatcher?fnc=setExpressCheckout&displayCartInPayPal=' . (int) $this->getRequest()->getPostParameter('displayCartInPayPal') . '&oePayPalCancelURL=' . $this->getPayPalCancelURL();
}
/**
* Method returns serialized current article params.
*
* @return string
*/
public function getCurrentArticleInfo()
{
$products = $this->_getItems();
$currentArticleId = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter('aid');
$params = null;
if (!is_null($products[$currentArticleId])) {
$params = $products[$currentArticleId];
}
return $params;
}
/**
* Method sets params for article and returns it's object.
*
* @return \OxidEsales\PayPalModule\Model\ArticleToExpressCheckoutCurrentItem
*/
protected function getCurrentArticle()
{
$currentItem = oxNew(\OxidEsales\PayPalModule\Model\ArticleToExpressCheckoutCurrentItem::class);
$currentArticleId = $this->getRequest()->getPostParameter('aid');
$products = $this->_getItems();
$productInfo = $products[$currentArticleId];
$currentItem->setArticleId($currentArticleId);
$currentItem->setSelectList($productInfo['sel']);
$currentItem->setPersistParam($productInfo['persparam']);
$currentItem->setArticleAmount($productInfo['am']);
return $currentItem;
}
/**
* Method returns request object.
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
protected function getRequest()
{
return oxNew(\OxidEsales\PayPalModule\Core\Request::class);
}
/**
* Method sets params for validator and returns it's object.
*
* @return \OxidEsales\PayPalModule\Model\ArticleToExpressCheckoutValidator
*/
protected function getValidator()
{
$validator = oxNew(\OxidEsales\PayPalModule\Model\ArticleToExpressCheckoutValidator::class);
return $validator;
}
/**
* Changes oePayPalCancelURL by changing popup showing parameter.
*
* @return string
*/
public function getPayPalCancelURL()
{
$url = $this->formatUrl($this->_getRedirectUrl());
$replacedURL = str_replace('showECSPopup=1', 'showECSPopup=0', $url);
return urlencode($replacedURL);
}
/**
* Formats Redirect URL to normal url
*
* @param string $unformedUrl
*
* @return string
*/
protected function formatUrl($unformedUrl)
{
$myConfig = \OxidEsales\Eshop\Core\Registry::getConfig();
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$params = explode('?', $unformedUrl);
$pageParams = isset($params[1]) ? $params[1] : null;
$params = explode('/', $params[0]);
$className = $params[0];
$header = ($className) ? "cl=$className&" : ''; // adding view name
$header .= ($pageParams) ? "$pageParams&" : ''; // adding page params
$header .= $session->sid(); // adding session Id
$url = $myConfig->getCurrentShopUrl($this->isAdmin());
$url = "{$url}index.php?{$header}";
$url = \OxidEsales\Eshop\Core\Registry::getUtilsUrl()->processUrl($url);
$seoIsActive = \OxidEsales\Eshop\Core\Registry::getUtils()->seoIsActive();
if ($seoIsActive && $seoUrl = \OxidEsales\Eshop\Core\Registry::getSeoEncoder()->getStaticUrl($url)) {
$url = $seoUrl;
}
return $url;
}
}

View File

@@ -0,0 +1,122 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Component\Widget;
/**
* Article box widget
*
* @mixin \OxidEsales\Eshop\Application\Component\Widget\ArticleDetails
*/
class ArticleDetails extends ArticleDetails_parent
{
/**
* Returns products amount to .tpl pages.
*
* @return int
*/
public function oePayPalGetArticleAmount()
{
$article = $this->oePayPalGetECSArticle();
return isset($article['am']) ? (int) $article['am'] : 1;
}
/**
* Returns persistent parameter.
*
* @return string
*/
public function oePayPalGetPersistentParam()
{
$article = $this->oePayPalGetECSArticle();
return $article['persparam']['details'];
}
/**
* Returns selections array.
*
* @return array
*/
public function oePayPalGetSelection()
{
$article = $this->oePayPalGetECSArticle();
return $article['sel'];
}
/**
* Checks if showECSPopup parameter was passed.
*
* @return bool
*/
public function oePayPalShowECSPopup()
{
return $this->getComponent('oxcmp_basket')->shopECSPopUp();
}
/**
* Checks if showECSPopup parameter was passed.
*
* @return bool
*/
public function oePayPalGetCancelUrl()
{
return $this->getComponent('oxcmp_basket')->getPayPalCancelURL();
}
/**
* Checks if displayCartInPayPal parameter was passed.
*
* @return bool
*/
public function oePayPalDisplayCartInPayPal()
{
$displayCartInPayPal = false;
if ($this->oePayPalGetRequest()->getPostParameter('displayCartInPayPal')) {
$displayCartInPayPal = true;
}
return $displayCartInPayPal;
}
/**
* Method returns request object.
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
protected function oePayPalGetRequest()
{
return oxNew(\OxidEsales\PayPalModule\Core\Request::class);
}
/**
* Gets ECSArticle, unserializes and returns it.
*
* @return array
*/
protected function oePayPalGetECSArticle()
{
$products = $this->getComponent('oxcmp_basket')->getCurrentArticleInfo();
return $products;
}
}

View File

@@ -0,0 +1,86 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller\Admin;
/**
* Adds additional functionality needed for PayPal when managing delivery sets.
*
* @mixin \OxidEsales\Eshop\Application\Controller\Admin\DeliverySetMain
*/
class DeliverySetMain extends DeliverySetMain_parent
{
/**
* Add default PayPal mobile payment.
*
* @return string
*/
public function render()
{
$template = parent::render();
$deliverySetId = $this->getEditObjectId();
if ($deliverySetId != "-1" && isset($deliverySetId)) {
/** @var \OxidEsales\PayPalModule\Core\Config $config */
$config = oxNew(\OxidEsales\PayPalModule\Core\Config::class);
$isPayPalDefaultMobilePayment = ($deliverySetId == $config->getMobileECDefaultShippingId());
$this->_aViewData['isPayPalDefaultMobilePayment'] = $isPayPalDefaultMobilePayment;
}
return $template;
}
/**
* Saves default PayPal mobile payment.
*/
public function save()
{
parent::save();
$config = \OxidEsales\Eshop\Core\Registry::getConfig();
/** @var \OxidEsales\PayPalModule\Core\Config $payPalConfig */
$payPalConfig = oxNew(\OxidEsales\PayPalModule\Core\Config::class);
$deliverySetId = $this->getEditObjectId();
$deliverySetMarked = (bool) $config->getRequestParameter('isPayPalDefaultMobilePayment');
$mobileECDefaultShippingId = $payPalConfig->getMobileECDefaultShippingId();
if ($deliverySetMarked && $deliverySetId != $mobileECDefaultShippingId) {
$this->saveECDefaultShippingId($config, $deliverySetId, $payPalConfig);
} elseif (!$deliverySetMarked && $deliverySetId == $mobileECDefaultShippingId) {
$this->saveECDefaultShippingId($config, '', $payPalConfig);
}
}
/**
* Save default shipping id.
*
* @param \OxidEsales\Eshop\Core\Config $config Config object to save.
* @param string $shippingId Shipping id.
* @param \OxidEsales\PayPalModule\Core\Config $payPalConfig PayPal config.
*/
protected function saveECDefaultShippingId($config, $shippingId, $payPalConfig)
{
$payPalModuleId = 'module:' . $payPalConfig->getModuleId();
$config->saveShopConfVar('string', 'sOEPayPalMECDefaultShippingId', $shippingId, null, $payPalModuleId);
}
}

View File

@@ -0,0 +1,185 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller\Admin;
/**
* Order class wrapper for PayPal module
*/
class OrderController extends \OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController
{
/**
* Executes parent method parent::render(), creates oxOrder object,
* passes it's data to Smarty engine and returns
* name of template file "order_paypal.tpl".
*
* @return string
*/
public function render()
{
parent::render();
$this->_aViewData["sOxid"] = $this->getEditObjectId();
if ($this->isNewPayPalOrder()) {
$this->_aViewData['oOrder'] = $this->getEditObject();
} else {
$this->_aViewData['sMessage'] = $this->isPayPalOrder() ? \OxidEsales\Eshop\Core\Registry::getLang()->translateString("OEPAYPAL_ONLY_FOR_NEW_PAYPAL_PAYMENT") :
\OxidEsales\Eshop\Core\Registry::getLang()->translateString("OEPAYPAL_ONLY_FOR_PAYPAL_PAYMENT");
}
return "order_paypal.tpl";
}
/**
* Processes PayPal actions.
*/
public function processAction()
{
try {
/** @var \OxidEsales\PayPalModule\Core\Request $request */
$request = oxNew(\OxidEsales\PayPalModule\Core\Request::class);
$action = $request->getRequestParameter('action');
$order = $this->getEditObject();
/** @var \OxidEsales\PayPalModule\Model\Action\OrderActionFactory $actionFactory */
$actionFactory = oxNew(\OxidEsales\PayPalModule\Model\Action\OrderActionFactory::class, $request, $order);
$action = $actionFactory->createAction($action);
$action->process();
} catch (\OxidEsales\Eshop\Core\Exception\StandardException $exception) {
$this->_aViewData["error"] = $exception->getMessage();
}
}
/**
* Returns PayPal order action manager.
*
* @return \OxidEsales\PayPalModule\Model\OrderActionManager
*/
public function getOrderActionManager()
{
/** @var \OxidEsales\PayPalModule\Model\OrderActionManager $manager */
$manager = oxNew(\OxidEsales\PayPalModule\Model\OrderActionManager::class);
$manager->setOrder($this->getEditObject()->getPayPalOrder());
return $manager;
}
/**
* Returns PayPal order action manager
*
* @return \OxidEsales\PayPalModule\Model\OrderPaymentActionManager
*/
public function getOrderPaymentActionManager()
{
$manager = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentActionManager::class);
return $manager;
}
/**
* Returns PayPal order action manager
*
* @return \OxidEsales\PayPalModule\Model\OrderPaymentStatusCalculator
*/
public function getOrderPaymentStatusCalculator()
{
/** @var \OxidEsales\PayPalModule\Model\OrderPaymentStatusCalculator $statusCalculator */
$statusCalculator = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentStatusCalculator::class);
$statusCalculator->setOrder($this->getEditObject()->getPayPalOrder());
return $statusCalculator;
}
/**
* Returns PayPal order action manager
*
* @return \OxidEsales\PayPalModule\Model\OrderPaymentStatusList
*/
public function getOrderPaymentStatusList()
{
$list = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentStatusList::class);
return $list;
}
/**
* Returns editable order object
*
* @return \OxidEsales\PayPalModule\Model\Order
*/
public function getEditObject()
{
$soxId = $this->getEditObjectId();
if ($this->_oEditObject === null && isset($soxId) && $soxId != '-1') {
$this->_oEditObject = oxNew(\OxidEsales\Eshop\Application\Model\Order::class);
$this->_oEditObject->load($soxId);
}
return $this->_oEditObject;
}
/**
* Method checks if order was made with current PayPal module, but not eFire PayPal module
*
* @return bool
*/
public function isNewPayPalOrder()
{
$active = false;
$order = $this->getEditObject();
$orderPayPal = $order->getPayPalOrder();
if ($this->isPayPalOrder() && $orderPayPal->isLoaded()) {
$active = true;
}
return $active;
}
/**
* Method checks is order was made with any PayPal module
*
* @return bool
*/
public function isPayPalOrder()
{
$active = false;
$order = $this->getEditObject();
if ($order && $order->getFieldData('oxpaymenttype') == 'oxidpaypal') {
$active = true;
}
return $active;
}
/**
* Template getter for price formatting
*
* @param double $price price
*
* @return string
*/
public function formatPrice($price)
{
return \OxidEsales\Eshop\Core\Registry::getLang()->formatCurrency($price);
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller\Admin;
/**
* Order list class wrapper for PayPal module
*
* @mixin \OxidEsales\Eshop\Application\Controller\Admin\OrderList
*/
class OrderList extends OrderList_parent
{
/**
* Executes parent method parent::render() and returns name of template
* file "order_list.tpl".
*
* @return string
*/
public function render()
{
$template = parent::render();
$paymentStatus = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter("paypalpaymentstatus");
$payment = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter("paypalpayment");
$this->_aViewData["spaypalpaymentstatus"] = $paymentStatus ? $paymentStatus : -1;
$this->_aViewData["opaypalpaymentstatuslist"] = new \OxidEsales\PayPalModule\Model\OrderPaymentStatusList();
$this->_aViewData["paypalpayment"] = $payment ? $payment : -1;
/** @var \OxidEsales\Eshop\Core\Model\ListModel $paymentList */
$paymentList = oxNew(\OxidEsales\Eshop\Core\Model\ListModel::class);
$paymentList->init(\OxidEsales\Eshop\Application\Model\Payment::class);
$this->_aViewData["oPayments"] = $paymentList->getList();
return $template;
}
/**
* Builds and returns SQL query string. Adds additional order check.
*
* @param object $listObject list main object.
*
* @return string
*/
protected function _buildSelectString($listObject = null)
{
$query = parent::_buildSelectString($listObject);
$viewNameGenerator = \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\TableViewNameGenerator::class);
$viewName = $viewNameGenerator->getViewName("oxpayments");
$queryPart = ", `oepaypal_order`.`oepaypal_paymentstatus`, `payments`.`oxdesc` as `paymentname` from oxorder
LEFT JOIN `oepaypal_order` ON `oepaypal_order`.`oepaypal_orderid` = `oxorder`.`oxid`
LEFT JOIN `" . $viewName . "` AS `payments` on `payments`.oxid=oxorder.oxpaymenttype ";
$query = str_replace('from oxorder', $queryPart, $query);
return $query;
}
/**
* Adding folder check.
*
* @param array $where SQL condition array.
* @param string $sqlFull SQL query string.
*
* @return string
*/
protected function _prepareWhereQuery($where, $fullQuery)
{
$database = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
$query = parent::_prepareWhereQuery($where, $fullQuery);
$paymentStatus = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter("paypalpaymentstatus");
$paymentStatusList = new \OxidEsales\PayPalModule\Model\OrderPaymentStatusList();
if ($paymentStatus && $paymentStatus != '-1' && in_array($paymentStatus, $paymentStatusList->getArray())) {
$query .= " AND ( `oepaypal_order`.`oepaypal_paymentstatus` = " . $database->quote($paymentStatus) . " )";
$query .= " AND ( `oepaypal_order`.`oepaypal_orderid` IS NOT NULL ) ";
}
$payment = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter("paypalpayment");
if ($payment && $payment != '-1') {
$query .= " and ( oxorder.oxpaymenttype = " . $database->quote($payment) . " )";
}
return $query;
}
}

View File

@@ -0,0 +1,168 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller;
use OxidEsales\PayPalModule\Model\PaymentManager;
/**
* Abstract PayPal Dispatcher class
*/
abstract class Dispatcher extends \OxidEsales\PayPalModule\Controller\FrontendController
{
/**
* Service type identifier - Standard Checkout = 1
*
* @var int
*/
protected $serviceType = PaymentManager::PAYPAL_SERVICE_TYPE_STANDARD;
/**
* PayPal checkout service
*
* @var \OxidEsales\PayPalModule\Core\PayPalService
*/
protected $payPalCheckoutService;
/**
* Default user action for checkout process
*
* @var string
*/
protected $userAction = "continue";
/** @var PaymentManager */
protected $paymentManager = null;
/**
* Executes "GetExpressCheckoutDetails" and on SUCCESS response - saves
* user information and redirects to order page, on failure - sets error
* message and redirects to basket page
*/
abstract public function getExpressCheckoutDetails();
/**
* Sets PayPal checkout service.
*
* @param \OxidEsales\PayPalModule\Core\PayPalService $payPalCheckoutService
*/
public function setPayPalCheckoutService($payPalCheckoutService)
{
$this->payPalCheckoutService = $payPalCheckoutService;
}
/**
* Returns PayPal service
*
* @return \OxidEsales\PayPalModule\Core\PayPalService
*/
public function getPayPalCheckoutService()
{
if ($this->payPalCheckoutService === null) {
$this->payPalCheckoutService = oxNew(\OxidEsales\PayPalModule\Core\PayPalService::class);
}
return $this->payPalCheckoutService;
}
protected function getPaymentManager(): PaymentManager
{
if (is_null($this->paymentManager)) {
$this->paymentManager = oxNew(PaymentManager::class, $this->getPayPalCheckoutService());
}
return $this->paymentManager;
}
/**
* @return \OxidEsales\Eshop\Core\UtilsView
*/
protected function getUtilsView()
{
return \OxidEsales\Eshop\Core\Registry::getUtilsView();
}
/**
* Formats given float/int value into PayPal friendly form
*
* @param float $in value to format
*
* @return string
*/
protected function formatFloat($in)
{
return sprintf("%.2f", $in);
}
/**
* Returns oxUtils instance
*
* @return \OxidEsales\Eshop\Core\Utils
*/
protected function getUtils()
{
return \OxidEsales\Eshop\Core\Registry::getUtils();
}
/**
* Returns base url, which is used to construct Callback, Return and Cancel Urls
*
* @return string
*/
protected function getBaseUrl()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$url = \OxidEsales\Eshop\Core\Registry::getConfig()->getSslShopUrl() . "index.php?lang=" . \OxidEsales\Eshop\Core\Registry::getLang()->getBaseLanguage() . "&sid=" . $session->getId() . "&rtoken=" . $session->getRemoteAccessToken();
$url .= "&shp=" . \OxidEsales\Eshop\Core\Registry::getConfig()->getShopId();
return $url;
}
/**
* Returns PayPal order object
*
* @return \OxidEsales\Eshop\Application\Model\Order|null
*/
protected function getPayPalOrder()
{
$order = oxNew(\OxidEsales\Eshop\Application\Model\Order::class);
if ($order->loadPayPalOrder()) {
return $order;
}
}
/**
* Returns PayPal payment object
*
* @return \OxidEsales\Eshop\Application\Model\Payment|null
*/
protected function getPayPalPayment()
{
$userPayment = null;
if (($order = $this->getPayPalOrder())) {
$userPayment = oxNew(\OxidEsales\Eshop\Application\Model\UserPayment::class);
$userPayment->load($order->oxorder__oxpaymentid->value);
}
return $userPayment;
}
}

View File

@@ -0,0 +1,697 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller;
use OxidEsales\Eshop\Core\Registry as EshopRegistry;
use OxidEsales\PayPalModule\Model\PaymentManager;
use OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails;
/**
* PayPal Express Checkout dispatcher class
*/
class ExpressCheckoutDispatcher extends \OxidEsales\PayPalModule\Controller\Dispatcher
{
/**
* Service type identifier - Express Checkout = 2
*
* @var int
*/
protected $serviceType = PaymentManager::PAYPAL_SERVICE_TYPE_EXPRESS;
/**
* Processes PayPal callback for graphql
*/
public function processGraphQLCallBack()
{
$basketId = $this->getRequest()->getRequestParameter("basketid");
$sessionBasket = $this->getPaymentManager()->prepareCallback($basketId);
EshopRegistry::getSession()->setBasket($sessionBasket);
$this->processCallBack();
}
/**
* Processes PayPal callback
*/
public function processCallBack()
{
$payPalService = $this->getPayPalCheckoutService();
$this->setParamsForCallbackResponse($payPalService);
$request = $payPalService->callbackResponse();
EshopRegistry::getUtils()->showMessageAndExit($request);
}
/**
* Executes "SetExpressCheckout" and on SUCCESS response - redirects to PayPal
* login/registration page, on error - returns to configured view (default is "basket"),
* which means - redirect to configured view (default basket) and display error message
*
* @return string
*/
public function setExpressCheckout()
{
$session = EshopRegistry::getSession();
$session->setVariable("oepaypal", PaymentManager::PAYPAL_SERVICE_TYPE_EXPRESS);
try {
$session->setVariable('paymentid', 'oxidpaypal');
$shippingId = '';
if ($this->getPayPalConfig()->isDeviceMobile()) {
$shippingId = (string) $this->getPayPalConfig()->getMobileECDefaultShippingId();
}
$result = $this->getPaymentManager()->setExpressCheckout(
$session->getBasket(),
$this->getUser() ?: null,
$this->getReturnUrl(),
$this->getCancelUrl(),
$this->getCallBackUrl(),
(bool)$this->getRequest()->getRequestParameter("displayCartInPayPal"),
$shippingId
);
} catch (\OxidEsales\Eshop\Core\Exception\StandardException $excp) {
// error - unable to set order info - display error message
$this->getUtilsView()->addErrorToDisplay($excp);
// return to requested view
$returnTo = $this->getRequestedControllerKey();
$returnTo = !empty($returnTo) ? $returnTo : 'basket';
return $returnTo;
}
// saving PayPal token into session
$session->setVariable("oepaypal-token", $result->getToken());
// extracting token and building redirect url
$url = $this->getPayPalConfig()->getPayPalCommunicationUrl($result->getToken(), $this->userAction);
// redirecting to PayPal's login/registration page
$this->getUtils()->redirect($url, false);
}
/**
* Executes "GetExpressCheckoutDetails" and on SUCCESS response - saves
* user information and redirects to order page, on failure - sets error
* message and redirects to basket page
*
* @return string
*/
public function getExpressCheckoutDetails()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$basket = $session->getBasket();
try {
/** @var ResponseGetExpressCheckoutDetails $details */
$details = $this->getPaymentManager()->getExpressCheckoutDetails();
// Remove flag of "new item added" to not show "Item added" popup when returning to checkout from paypal
$basket->isNewItemAdded();
// creating new or using session user
$user = $this->initializeUserData($details);
} catch (\OxidEsales\Eshop\Core\Exception\StandardException $excp) {
$this->getUtilsView()->addErrorToDisplay($excp);
$logger = $this->getLogger();
$logger->log("PayPal error: " . $excp->getMessage());
return "basket";
}
// setting PayPal as current active payment
$session->setVariable('paymentid', "oxidpaypal");
$basket->setPayment("oxidpaypal");
if (!$this->isPaymentValidForUserCountry($user)) {
$this->getUtilsView()->addErrorToDisplay('MESSAGE_PAYMENT_SELECT_ANOTHER_PAYMENT');
$logger = $this->getLogger();
$logger->log("Shop error: PayPal payment validation by user country failed. Payment is not valid for this country.");
return "payment";
}
$shippingId = $this->extractShippingId(urldecode($details->getShippingOptionName()), $user);
$this->setAnonymousUser($basket, $user);
$basket->setShipping($shippingId);
$basket->onUpdate();
$basket->calculateBasket(true);
$basketPrice = $basket->getPrice()->getBruttoPrice();
if (!$this->isPayPalPaymentValid($user, $basketPrice, $basket->getShippingId())) {
$this->getUtilsView()->addErrorToDisplay("OEPAYPAL_SELECT_ANOTHER_SHIPMENT");
return "order";
}
// Checking if any additional discount was applied after we returned from PayPal.
if ($basketPrice != $details->getAmount()) {
$this->getUtilsView()->addErrorToDisplay("OEPAYPAL_ORDER_TOTAL_HAS_CHANGED");
return "basket";
}
$session->setVariable("oepaypal-payerId", $details->getPayerId());
$session->setVariable("oepaypal-userId", $user->getId());
$session->setVariable("oepaypal-basketAmount", $details->getAmount());
$next = "order";
if ($this->getPayPalConfig()->finalizeOrderOnPayPalSide()) {
$next .= "?fnc=execute";
$next .= "&sDeliveryAddressMD5=" . $user->getEncodedDeliveryAddress();
$next .= "&stoken=" . $session->getSessionChallengeToken();
}
return $next;
}
/**
* Returns transaction mode.
*
* @param \OxidEsales\Eshop\Application\Model\Basket $basket
*
* @return string
*
* @deprecated Please use OxidEsales\PayPalModule\Model\PaymentManager::getTransactionMode
*/
protected function getTransactionMode($basket)
{
$paymentManager = $this->getPaymentManager();
return $paymentManager->getTransactionMode($basket, $this->getPayPalConfig());
}
/**
* Returns RETURN URL
*
* @return string
*/
protected function getReturnUrl()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$controllerKey = \OxidEsales\Eshop\Core\Registry::getControllerClassNameResolver()->getIdByClassName(get_class());
return $session->processUrl($this->getBaseUrl() . "&cl=" . $controllerKey . "&fnc=getExpressCheckoutDetails");
}
/**
* Returns CANCEL URL
*
* @return string
*/
protected function getCancelUrl()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$cancelURLFromRequest = $this->getRequest()->getRequestParameter('oePayPalCancelURL');
$cancelUrl = $session->processUrl($this->getBaseUrl() . "&cl=basket");
if ($cancelURLFromRequest) {
$cancelUrl = html_entity_decode(urldecode($cancelURLFromRequest));
} elseif ($requestedControllerKey = $this->getRequestedControllerKey()) {
$cancelUrl = $session->processUrl($this->getBaseUrl() . '&cl=' . $requestedControllerKey);
}
return $cancelUrl;
}
/**
* Extract requested controller key.
* In case the key makes sense (we find a matching class) it will be returned.
*
* @return mixed|null
*/
protected function getRequestedControllerKey()
{
$return = null;
$requestedControllerKey = $this->getRequest()->getRequestParameter('oePayPalRequestedControllerKey');
if (!empty($requestedControllerKey) &&
\OxidEsales\Eshop\Core\Registry::getControllerClassNameResolver()->getClassNameById($requestedControllerKey)) {
$return = $requestedControllerKey;
}
return $return;
}
/**
* Returns CALLBACK URL
*
* @return string
*/
protected function getCallBackUrl()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$controllerKey = \OxidEsales\Eshop\Core\Registry::getControllerClassNameResolver()->getIdByClassName(get_class());
return $session->processUrl($this->getBaseUrl() . "&cl=" . $controllerKey . "&fnc=processCallBack");
}
/**
* Initialize new user from user data.
*
* @param array $data User data array.
*
* @return \OxidEsales\Eshop\Application\Model\User
*/
protected function getCallBackUser($data)
{
// simulating user object
$user = oxNew(\OxidEsales\Eshop\Application\Model\User::class);
$user->initializeUserForCallBackPayPalUser($data);
return $user;
}
/**
* Sets parameters to PayPal callback
*
* @param \OxidEsales\PayPalModule\Core\PayPalService $payPalService PayPal service
*
* @return null
*/
protected function setParamsForCallbackResponse($payPalService)
{
//logging request from PayPal
$logger = $this->getLogger();
$logger->setTitle("CALLBACK REQUEST FROM PAYPAL");
$logger->log(http_build_query($_REQUEST, "", "&"));
// initializing user..
$user = $this->getCallBackUser($_REQUEST);
// unknown country?
if (!$this->getUserShippingCountryId($user)) {
$logger = $this->getLogger();
$logger->log("Callback error: NO SHIPPING COUNTRY ID");
// unknown country - no delivery
$this->setPayPalIsNotAvailable($payPalService);
return;
}
//basket
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$basket = $session->getBasket();
// get possible delivery sets
$delSetList = $this->getDeliverySetList($user);
//no shipping methods for user country
if (empty($delSetList)) {
$logger = $this->getLogger();
$logger->log("Callback error: NO DELIVERY LIST SET");
$this->setPayPalIsNotAvailable($payPalService);
return;
}
$deliverySetList = $this->makeUniqueNames($delSetList);
// checking if PayPal is valid payment for selected user country
if (!$this->isPaymentValidForUserCountry($user)) {
$logger->log("Callback error: NOT VALID COUNTRY ID");
// PayPal payment is not possible for user country
$this->setPayPalIsNotAvailable($payPalService);
return;
}
$session->setVariable('oepaypal-oxDelSetList', $deliverySetList);
$totalDeliveries = $this->setDeliverySetListForCallbackResponse($payPalService, $deliverySetList, $user, $basket);
// if none of deliveries contain PayPal - disabling PayPal
if ($totalDeliveries == 0) {
$logger->log("Callback error: DELIVERY SET LIST HAS NO PAYPAL");
$this->setPayPalIsNotAvailable($payPalService);
return;
}
$payPalService->setParameter("OFFERINSURANCEOPTION", "false");
}
/**
* Sets delivery sets parameters to PayPal callback
*
* @param \OxidEsales\PayPalModule\Core\PayPalService $payPalService PayPal service.
* @param array $deliverySetList Delivery list.
* @param \OxidEsales\Eshop\Application\Model\User $user User object.
* @param \OxidEsales\Eshop\Application\Model\Basket $basket Basket object.
*
* @return int Total amount of deliveries
*/
protected function setDeliverySetListForCallbackResponse($payPalService, $deliverySetList, $user, $basket)
{
$maxDeliveryAmount = $this->getPayPalConfig()->getMaxPayPalDeliveryAmount();
$cur = \OxidEsales\Eshop\Core\Registry::getConfig()->getActShopCurrencyObject();
$basketPrice = $basket->getPriceForPayment() / $cur->rate;
$actShipSet = $basket->getShippingId();
$hasActShipSet = false;
$cnt = 0;
// VAT for delivery will be calculated always
$delVATPercent = $basket->getAdditionalServicesVatPercent();
foreach ($deliverySetList as $delSetId => $delSetName) {
// checking if PayPal is valid payment for selected delivery set
if (!$this->isPayPalInDeliverySet($delSetId, $basketPrice, $user)) {
continue;
}
$deliveryListProvider = oxNew(\OxidEsales\Eshop\Application\Model\DeliveryList::class);
$deliveryList = array();
// list of active delivery costs
if ($deliveryListProvider->hasDeliveries($basket, $user, $this->getUserShippingCountryId($user), $delSetId)) {
$deliveryList = $deliveryListProvider->getDeliveryList($basket, $user, $this->getUserShippingCountryId($user), $delSetId);
}
if (is_array($deliveryList) && !empty($deliveryList)) {
$price = 0;
if (\OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('bl_perfLoadDelivery')) {
foreach ($deliveryList as $delivery) {
$price += $delivery->getDeliveryPrice($delVATPercent)->getBruttoPrice();
}
}
if ($price <= $maxDeliveryAmount) {
$payPalService->setParameter("L_SHIPPINGOPTIONNAME{$cnt}", \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($delSetName));
$payPalService->setParameter("L_SHIPPINGOPTIONLABEL{$cnt}", \OxidEsales\Eshop\Core\Registry::getLang()->translateString("OEPAYPAL_PRICE"));
$payPalService->setParameter("L_SHIPPINGOPTIONAMOUNT{$cnt}", $this->formatFloat($price));
//setting active delivery set
if ($delSetId == $actShipSet) {
$hasActShipSet = true;
$payPalService->setParameter("L_SHIPPINGOPTIONISDEFAULT{$cnt}", "true");
} else {
$payPalService->setParameter("L_SHIPPINGOPTIONISDEFAULT{$cnt}", "false");
}
if ($basket->isCalculationModeNetto()) {
$payPalService->setParameter("L_TAXAMT{$cnt}", $this->formatFloat($basket->getPayPalBasketVatValue()));
} else {
$payPalService->setParameter("L_TAXAMT{$cnt}", $this->formatFloat(0));
}
}
$cnt++;
}
}
//checking if active delivery set was set - if not, setting first in the list
if ($cnt > 0 && !$hasActShipSet) {
$payPalService->setParameter("L_SHIPPINGOPTIONISDEFAULT0", "true");
}
return $cnt;
}
/**
* Makes delivery set array with unique names
*
* @param array $deliverySetList delivery list
*
* @return array
*
* @deprecated Please use OxidEsales\PayPalModule\Model\PaymentManager::makeUniqueNames
*/
public function makeUniqueNames($deliverySetList)
{
return $this->getPaymentManager()->makeUniqueNames($deliverySetList);
}
/**
* Returns PayPal user
*
* @return \OxidEsales\Eshop\Application\Model\User
*/
protected function getPayPalUser()
{
$user = oxNew(\OxidEsales\Eshop\Application\Model\User::class);
if (!$user->loadUserPayPalUser()) {
$user = $this->getUser();
}
return $user;
}
/**
* Extracts shipping id from given parameter
*
* @param string $shippingOptionName Shipping option name, which comes from PayPal.
* @param \OxidEsales\Eshop\Application\Model\User $user User object.
*
* @return string
*/
protected function extractShippingId($shippingOptionName, $user)
{
$deliverySetList = \OxidEsales\Eshop\Core\Registry::getSession()->getVariable("oepaypal-oxDelSetList");
return $this->getPaymentManager()->extractShippingId($shippingOptionName, $user, $deliverySetList);
}
/**
* Creates new or returns session user
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails $details
*
* @throws \OxidEsales\Eshop\Core\Exception\StandardException
*
* @return \OxidEsales\Eshop\Application\Model\User
*/
protected function initializeUserData($details)
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$userEmail = $details->getEmail();
$loggedUser = $this->getUser();
if ($loggedUser) {
$userEmail = $loggedUser->oxuser__oxusername->value;
}
$user = oxNew(\OxidEsales\Eshop\Application\Model\User::class);
if ($userId = $user->isRealPayPalUser($userEmail)) {
// if user exist
$user->load($userId);
if (!$loggedUser) {
if (!$user->isSamePayPalUser($details)) {
/**
* @var $exception \OxidEsales\Eshop\Core\Exception\StandardException
*/
$exception = oxNew(\OxidEsales\Eshop\Core\Exception\StandardException::class);
$exception->setMessage('OEPAYPAL_ERROR_USER_ADDRESS');
throw $exception;
}
} elseif (!$user->isSameAddressUserPayPalUser($details) || !$user->isSameAddressPayPalUser($details)) {
// user has selected different address in PayPal (not equal with usr shop address)
// so adding PayPal address as new user address to shop user account
$this->createUserAddress($details, $userId);
} else {
// removing custom shipping address ID from session as user uses billing
// address for shipping
$session->deleteVariable('deladrid');
}
} else {
$user->createPayPalUser($details);
}
$session->setVariable('usr', $user->getId());
return $user;
}
/**
* Creates user address and sets address id into session
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails $details User address info.
* @param string $userId User id.
*
* @return bool
*/
protected function createUserAddress($details, $userId)
{
$address = oxNew(\OxidEsales\Eshop\Application\Model\Address::class);
return $address->createPayPalAddress($details, $userId);
}
/**
* Checking if PayPal payment is available in user country
*
* @param \OxidEsales\Eshop\Application\Model\User $user User object.
*
* @return boolean
*/
protected function isPaymentValidForUserCountry($user)
{
$payment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
$payment->load("oxidpaypal");
$paymentCountries = $payment->getCountries();
if (!is_array($paymentCountries) || empty($paymentCountries)) {
// not assigned to any country - valid to all countries
return true;
}
return in_array($this->getUserShippingCountryId($user), $paymentCountries);
}
/**
* Checks if selected delivery set has PayPal payment.
*
* @param string $delSetId Delivery set ID.
* @param double $basketPrice Basket price.
* @param \OxidEsales\Eshop\Application\Model\User $user User object.
*
* @return boolean
*/
protected function isPayPalInDeliverySet($delSetId, $basketPrice, $user)
{
$paymentList = \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Application\Model\PaymentList::class);
$paymentList = $paymentList->getPaymentList($delSetId, $basketPrice, $user);
if (is_array($paymentList) && array_key_exists("oxidpaypal", $paymentList)) {
return true;
}
return false;
}
/**
* Disables PayPal payment in PayPal side
*
* @param \OxidEsales\PayPalModule\Core\PayPalService $payPalService PayPal service.
*/
protected function setPayPalIsNotAvailable($payPalService)
{
// "NO_SHIPPING_OPTION_DETAILS" works only in version 61, so need to switch version
$payPalService->setParameter("CALLBACKVERSION", "61.0");
$payPalService->setParameter("NO_SHIPPING_OPTION_DETAILS", "1");
}
/**
* Get delivery set list for PayPal callback
*
* @param \OxidEsales\Eshop\Application\Model\User $user User object.
*
* @return array
*/
protected function getDeliverySetList($user)
{
$delSetList = oxNew(\OxidEsales\Eshop\Application\Model\DeliverySetList::class);
return $delSetList->getDeliverySetList($user, $this->getUserShippingCountryId($user));
}
/**
* Returns user shipping address country id.
*
* @param \OxidEsales\Eshop\Application\Model\User $user
*
* @return string
*/
protected function getUserShippingCountryId($user)
{
if ($user->getSelectedAddressId() && $user->getSelectedAddress()) {
$countryId = $user->getSelectedAddress()->oxaddress__oxcountryid->value;
} else {
$countryId = $user->oxuser__oxcountryid->value;
}
return $countryId;
}
/**
* Checks whether PayPal payment is available
*
* @param \OxidEsales\Eshop\Application\Model\User $user
* @param double $basketPrice
* @param string $shippingId
*
* @return bool
*/
protected function isPayPalPaymentValid($user, $basketPrice, $shippingId)
{
$valid = true;
$payPalPayment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
$payPalPayment->load('oxidpaypal');
if (!$payPalPayment->isValidPayment(null, null, $user, $basketPrice, $shippingId)) {
$valid = $this->isEmptyPaymentValid($user, $basketPrice, $shippingId);
}
return $valid;
}
/**
* Checks whether Empty payment is available.
*
* @param \OxidEsales\Eshop\Application\Model\User $user
* @param double $basketPrice
* @param string $shippingId
*
* @return bool
*/
protected function isEmptyPaymentValid($user, $basketPrice, $shippingId)
{
$valid = true;
$emptyPayment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
$emptyPayment->load('oxempty');
if (!$emptyPayment->isValidPayment(null, null, $user, $basketPrice, $shippingId)) {
$valid = false;
}
return $valid;
}
/**
* PayPal express checkout might be called before user is set to basket.
* This happens if user is not logged in to the Shop
* and it goes to PayPal from details page or basket first step.
*
* @param \OxidEsales\Eshop\Application\Model\Basket $basket
* @param \OxidEsales\Eshop\Application\Model\User $user
*/
private function setAnonymousUser($basket, $user)
{
$basket->setBasketUser($user);
}
/**
* @param string $input
*
* @deprecated Please use OxidEsales\PayPalModule\Model\PaymentManager::reencodeHtmlEntities
*/
private function reencodeHtmlEntities($input)
{
$charset = $this->getPayPalConfig()->getCharset();
return htmlentities(html_entity_decode($input, ENT_QUOTES, $charset), ENT_QUOTES, $charset);
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller;
/**
* Main PayPal controller
*/
class FrontendController extends \OxidEsales\Eshop\Application\Controller\FrontendController
{
/**
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $request = null;
/**
* @var \OxidEsales\PayPalModule\Core\Logger
*/
protected $logger = null;
/**
* @var \OxidEsales\PayPalModule\Core\Config
*/
protected $payPalConfig = null;
/**
* Return request object
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getRequest()
{
if (is_null($this->request)) {
$this->request = oxNew(\OxidEsales\PayPalModule\Core\Request::class);
}
return $this->request;
}
/**
* Return PayPal logger
*
* @return \OxidEsales\PayPalModule\Core\Logger
*/
public function getLogger()
{
if (is_null($this->logger)) {
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$this->logger = oxNew(\OxidEsales\PayPalModule\Core\Logger::class);
$this->logger->setLoggerSessionId($session->getId());
}
return $this->logger;
}
/**
* Return PayPal config
*
* @return \OxidEsales\PayPalModule\Core\Config
*/
public function getPayPalConfig()
{
if (is_null($this->payPalConfig)) {
$this->setPayPalConfig(oxNew(\OxidEsales\PayPalModule\Core\Config::class));
}
return $this->payPalConfig;
}
/**
* Set PayPal config
*
* @param \OxidEsales\PayPalModule\Core\Config $payPalConfig config
*/
public function setPayPalConfig($payPalConfig)
{
$this->payPalConfig = $payPalConfig;
}
/**
* Logs passed value.
*
* @param mixed $value
*/
public function log($value)
{
if ($this->getPayPalConfig()->isLoggingEnabled()) {
$this->getLogger()->log($value);
}
}
}

View File

@@ -0,0 +1,197 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller;
/**
* PayPal IPN handler class.
*
* Handle PayPal notifications.
* - Extract data.
* - Check if valid.
* - Call order methods to save data.
*/
class IPNHandler extends \OxidEsales\PayPalModule\Controller\FrontendController
{
/**
* Current class default template name.
*
* @var string
*/
protected $_sThisTemplate = 'ipnhandler.tpl';
/**
* PayPal request handler.
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $payPalRequest = null;
/**
* @var \OxidEsales\PayPalModule\Model\IPNRequestVerifier
*/
protected $ipnRequestVerifier = null;
/**
* @var \OxidEsales\PayPalModule\Model\IPNProcessor
*/
protected $processor = null;
/**
* Set object to handle request.
*
* @param \OxidEsales\PayPalModule\Core\Request $payPalRequest object to set.
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
/**
* Create object \OxidEsales\PayPalModule\Core\Request to get PayPal request information.
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getPayPalRequest()
{
if ($this->payPalRequest === null) {
$this->payPalRequest = oxNew(\OxidEsales\PayPalModule\Core\Request::class);
}
return $this->payPalRequest;
}
/**
* Sets IPN request verifier.
*
* @param \OxidEsales\PayPalModule\Model\IPNRequestVerifier $ipnRequestVerifier
*/
public function setIPNRequestVerifier($ipnRequestVerifier)
{
$this->ipnRequestVerifier = $ipnRequestVerifier;
}
/**
* Returns IPN request verifier.
*
* @return \OxidEsales\PayPalModule\Model\IPNRequestVerifier
*/
public function getIPNRequestVerifier()
{
if (is_null($this->ipnRequestVerifier)) {
$ipnRequestVerifier = oxNew(\OxidEsales\PayPalModule\Model\IPNRequestVerifier::class);
$this->setIPNRequestVerifier($ipnRequestVerifier);
}
return $this->ipnRequestVerifier;
}
/**
* \OxidEsales\PayPalModule\Model\IPNProcessor setter.
*
* @param \OxidEsales\PayPalModule\Model\IPNProcessor $processor
*/
public function setProcessor($processor)
{
$this->processor = $processor;
}
/**
* Returns \OxidEsales\PayPalModule\Model\IPNProcessor object. If object is not set, than it creates it and sets.
*
* @return \OxidEsales\PayPalModule\Model\IPNProcessor
*/
public function getProcessor()
{
if (is_null($this->processor)) {
$processor = oxNew(\OxidEsales\PayPalModule\Model\IPNProcessor::class);
$this->setProcessor($processor);
}
return $this->processor;
}
/**
* IPN handling function.
* - Call to check if request is valid (from PayPal and to correct shop).
* - Initiate payment status changes according to IPN information.
*
* @return void
*/
public function handleRequest()
{
$requestHandled = false;
$requestId = md5(microtime(true));
$request = $this->getPayPalRequest();
$logger = $this->getLogger();
$logger->setTitle("IPN Request by PayPal");
$logger->log([
'Request ID' => $requestId,
'GET parameters' => $request->getGet(),
'POST parameters' => $request->getPost()
]);
$requestValid = $this->requestValid();
if ($requestValid) {
$lang = $this->getPayPalConfig()->getLang();
$processor = $this->getProcessor();
$processor->setRequest($request);
$processor->setLang($lang);
$requestHandled = $processor->process();
}
$logger->setTitle("IPN Process result");
$logger->log([
'Request ID' => $requestId,
'Result' => $requestHandled
]);
}
/**
* IPN handling function.
* - Verify request with PayPal (if request from PayPal and to correct shop).
*
* @return bool
*/
public function requestValid()
{
$requestValid = true;
$request = $this->getRequest();
$ipnRequestVerifier = $this->getIPNRequestVerifier();
$ipnRequestVerifier->setRequest($request);
$ipnRequestVerifier->setShopOwner($this->getPayPalConfig()->getUserEmail());
$requestCorrect = $ipnRequestVerifier->requestCorrect();
if (!$requestCorrect) {
$requestValid = false;
$logger = $this->getLogger();
$logger->setTitle("IPN VERIFICATION FAILURE BY PAYPAL");
$logger->log($ipnRequestVerifier->getFailureMessage());
}
return $requestValid;
}
}

View File

@@ -0,0 +1,146 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller;
use OxidEsales\Eshop\Core\Registry;
/**
* Order class wrapper for PayPal module
*
* @mixin \OxidEsales\Eshop\Application\Controller\OrderController
*/
class OrderController extends OrderController_parent
{
/**
* Checks if payment action is processed by PayPal
*
* @return bool
*/
public function isPayPal()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
return ($session->getVariable("paymentid") == "oxidpaypal");
}
/**
* Returns PayPal user
*
* @return \OxidEsales\Eshop\Application\Model\User
*/
public function getUser()
{
$user = parent::getUser();
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$userId = $session->getVariable("oepaypal-userId");
if ($this->isPayPal() && $userId) {
$payPalUser = oxNew(\OxidEsales\Eshop\Application\Model\User::class);
if ($payPalUser->load($userId)) {
$user = $payPalUser;
}
}
return $user;
}
/**
* Returns PayPal payment object if PayPal is on, or returns parent::getPayment()
*
* @return \OxidEsales\Eshop\Application\Model\Payment
*/
public function getPayment()
{
if (!$this->isPayPal()) {
// removing PayPal payment type from session
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$session->deleteVariable('oepaypal');
$session->deleteVariable('oepaypal-basketAmount');
return parent::getPayment();
}
if ($this->payment === null) {
// payment is set ?
$payment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
if ($payment->load('oxidpaypal')) {
$this->payment = $payment;
}
}
return $this->payment;
}
/**
* Make sure orderId is set in sess_challenge session field.
* If it's not set and the option to finalize order on paypal checkout is enabled,
* the last checkout step - thank you page - will redirect the user to home.
*
* @return string
*/
public function execute()
{
$nextStep = parent::execute();
$session = Registry::getSession();
if (!$session->getVariable('sess_challenge')) {
$orderId = $this->getBasket()->getOrderId();
$session->setVariable('sess_challenge', $orderId);
}
return $nextStep;
}
/**
* Returns current order object
*
* @return \OxidEsales\Eshop\Application\Model\Order
*/
protected function getOrder()
{
$order = oxNew(\OxidEsales\Eshop\Application\Model\Order::class);
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$order->load($session->getVariable('sess_challenge'));
return $order;
}
/**
* Checks if order payment is PayPal and redirects to payment processing part.
*
* @param int $success order state
*
* @return string
*/
protected function getNextStep($success)
{
$nextStep = parent::_getNextStep($success);
// Detecting PayPal & loading order & execute payment only if go wrong
if ($this->isPayPal() && ($success == \OxidEsales\Eshop\Application\Model\Order::ORDER_STATE_PAYMENTERROR)) {
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$payPalType = (int) $session->getVariable("oepaypal");
$nextStep = ($payPalType == 2) ? "basket" : "order";
}
return $nextStep;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller;
use OxidEsales\PayPalModule\Model\PaymentManager;
use OxidEsales\PayPalModule\Core\PayPalService;
/**
* Payment class wrapper for PayPal module
*
* @mixin \OxidEsales\Eshop\Application\Controller\PaymentController
*/
class PaymentController extends PaymentController_parent
{
/**
* Detects is current payment must be processed by PayPal and instead of standard validation
* redirects to standard PayPal dispatcher
*
* @return bool
*/
public function validatePayment()
{
$paymentId = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter('paymentid');
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$basket = $session->getBasket();
if ($paymentId === 'oxidpaypal' && !$this->isConfirmedByPayPal($basket)) {
$session->setVariable('paymentid', 'oxidpaypal');
return 'oepaypalstandarddispatcher?fnc=setExpressCheckout'
. '&displayCartInPayPal=' . ((int) \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter('displayCartInPayPal'));
}
return parent::validatePayment();
}
/**
* Detects if current payment was already successfully processed by PayPal
*
* @param \OxidEsales\Eshop\Application\Model\Basket $basket basket object
*
* @return bool
*/
public function isConfirmedByPayPal($basket)
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$oldBasketAmount = $session->getVariable("oepaypal-basketAmount");
if (!$oldBasketAmount) {
return false;
}
$paypalService = oxNew(PayPalService::class);
$paymentManager = oxNew(PaymentManager::class, $paypalService);
return $paymentManager->validateApprovedBasketAmount($basket->getPrice()->getBruttoPrice(), $oldBasketAmount);
}
}

View File

@@ -0,0 +1,149 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller;
use OxidEsales\PayPalModule\Model\PaymentManager;
/**
* PayPal Standard Checkout dispatcher class
*/
class StandardDispatcher extends \OxidEsales\PayPalModule\Controller\Dispatcher
{
/**
* Executes "SetExpressCheckout" and on SUCCESS response - redirects to PayPal
* login/registration page, on error - returns "basket", which means - redirect
* to basket view and display error message
*
* @return string|void
*/
public function setExpressCheckout()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$session->setVariable("oepaypal", PaymentManager::PAYPAL_SERVICE_TYPE_STANDARD);
try {
$selectedAddressId = $this->getUser() ? (string) $this->getUser()->getSelectedAddressId() : '';
$paymentManager = $this->getPaymentManager();
$result = $paymentManager->setStandardCheckout(
$session->getBasket(),
$this->getUser() ?: null,
$this->getReturnUrl(),
$this->getCancelUrl(),
(bool)$this->getRequest()->getRequestParameter("displayCartInPayPal"),
$selectedAddressId
);
} catch (\OxidEsales\Eshop\Core\Exception\StandardException $excp) {
// error - unable to set order info - display error message
$this->getUtilsView()->addErrorToDisplay($excp);
// return to basket view
return "basket";
}
// saving PayPal token into session
$session->setVariable("oepaypal-token", $result->getToken());
// extracting token and building redirect url
$url = $this->getPayPalConfig()->getPayPalCommunicationUrl($result->getToken(), $this->userAction);
// redirecting to PayPal's login/registration page
$this->getUtils()->redirect($url, false);
}
/**
* Returns transaction mode.
*
* @param \OxidEsales\Eshop\Application\Model\Basket $basket
*
* @return string
*
* @deprecated Please use OxidEsales\PayPalModule\Model\PaymentManager::getTransactionMode
*/
protected function getTransactionMode($basket)
{
$paymentManager = $this->getPaymentManager();
return $paymentManager->getTransactionMode($basket, $this->getPayPalConfig());
}
/**
* Executes "GetExpressCheckoutDetails" and on SUCCESS response - saves
* user information and redirects to order page, on failure - sets error
* message and redirects to basket page
*
* @return string
*/
public function getExpressCheckoutDetails()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
try {
$paymentManager = $this->getPaymentManager();
$details = $paymentManager->getExpressCheckoutDetails();
$user = $this->getUser();
} catch (\OxidEsales\Eshop\Core\Exception\StandardException $excp) {
// display error message
$this->getUtilsView()->addErrorToDisplay($excp);
// problems fetching user info - redirect to payment selection
return 'payment';
}
$session->setVariable("oepaypal-payerId", $details->getPayerId());
$session->setVariable("oepaypal-basketAmount", $details->getAmount());
// next step - order page
$next = 'order';
// finalize order on paypal side?
if ($this->getPayPalConfig()->finalizeOrderOnPayPalSide()) {
$next .= "?fnc=execute";
$next .= "&sDeliveryAddressMD5=" . $user->getEncodedDeliveryAddress();
$next .= "&stoken=" . $session->getSessionChallengeToken();
}
// everything is fine - redirect to order
return $next;
}
/**
* Returns RETURN URL
*
* @return string
*/
public function getReturnUrl()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$controllerKey = \OxidEsales\Eshop\Core\Registry::getControllerClassNameResolver()->getIdByClassName(get_class());
return $session->processUrl($this->getBaseUrl() . "&cl=" . $controllerKey . "&fnc=getExpressCheckoutDetails");
}
/**
* Returns CANCEL URL
*
* @return string
*/
public function getCancelUrl()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
return $session->processUrl($this->getBaseUrl() . "&cl=payment");
}
}

View File

@@ -0,0 +1,65 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Controller;
/**
* PayPal Wrapping class
*
* @mixin \OxidEsales\Eshop\Application\Controller\WrappingController
*/
class WrappingController extends WrappingController_parent
{
/**
* Checks if payment action is processed by PayPal
*
* @return bool
*/
public function isPayPal()
{
$session = \OxidEsales\Eshop\Core\Registry::getSession();
return ($session->getVariable("paymentid") == "oxidpaypal") ? true : false;
}
/**
* Detects is current payment must be processed by PayPal and instead of standard validation
* redirects to standard PayPal dispatcher
*
* @return bool
*/
public function changeWrapping()
{
$return = parent::changeWrapping();
// in case user adds wrapping, basket info must be resubmitted..
if ($this->isPayPal()) {
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$payPalType = (int) $session->getVariable("oepaypal");
if ($payPalType == 1) {
$return = "payment";
} else {
$return = "basket";
}
}
return $return;
}
}

View File

@@ -0,0 +1,225 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
use OxidEsales\PayPalModule\Core\Exception\PayPalResponseException;
/**
* PayPal caller service class
*/
class Caller
{
/**
* Service call parameters.
*
* @var array
*/
protected $params = array();
/**
* PayPal logger.
*
* @var \OxidEsales\PayPalModule\Core\Logger
*/
protected $logger = null;
/**
* PayPal curl object.
*
* @var \OxidEsales\PayPalModule\Core\Curl
*/
protected $curl = null;
/**
* Setter for logger.
*
* @param \OxidEsales\PayPalModule\Core\Logger $logger logger
*/
public function setLogger($logger)
{
$this->logger = $logger;
}
/**
* Getter for PayPal logger.
*
* @return \OxidEsales\PayPalModule\Core\Logger
*/
public function getLogger()
{
return $this->logger;
}
/**
* Sets PayPal curl object.
*
* @param \OxidEsales\PayPalModule\Core\Curl $payPalCurl PayPal curl object.
*/
public function setCurl($payPalCurl)
{
$this->curl = $payPalCurl;
}
/**
* Returns curl instance
*
* @return \OxidEsales\PayPalModule\Core\Curl
*/
public function getCurl()
{
if (is_null($this->curl)) {
$curl = oxNew(\OxidEsales\PayPalModule\Core\Curl::class);
$this->setCurl($curl);
}
return $this->curl;
}
/**
* PayPal request parameters setter.
*
* @param string $paramName parameter name
* @param mixed $paramValue parameter value
*/
public function setParameter($paramName, $paramValue)
{
$this->params[$paramName] = $paramValue;
}
/**
* PayPal request parameters setter.
*
* @param array $parameters parameters to use to build request.
*/
public function setParameters($parameters)
{
$this->params = array_merge($this->params, $parameters);
}
/**
* Returns PayPal request parameters array.
*
* @return array
*/
public function getParameters()
{
return $this->params;
}
/**
* Calls given remote PayPal method.
*
* @param string $methodName .
*
* @return array
*/
public function call($methodName = null)
{
$this->setMethod($methodName);
$curl = $this->getCurl();
$curl->setParameters($this->getParameters());
$this->log($this->getParameters(), 'Request to PayPal');
$response = $curl->execute();
$this->log($response, 'Response from PayPal');
$this->validateResponse($response);
return $response;
}
/**
* Set method name to execute like DoExpressCheckoutPayment or GetExpressCheckoutDetails.
*
* @param string $name Name of a method
*/
protected function setMethod($name)
{
if (!is_null($name)) {
$this->setParameter("METHOD", $name);
}
}
/**
* Validates response from PayPal errors.
*
* @param array $response
*
* @throws PayPalResponseException if response has error from PayPal
*/
protected function validateResponse($response)
{
if (in_array($response['ACK'], ['SuccessWithWarning', 'FailureWithWarning'])) {
$this->log($response, 'Response with warning from PayPal');
}
if (in_array($response['ACK'], ['Failure', 'FailureWithWarning'])) {
throw new PayPalResponseException($response['L_LONGMESSAGE0'], $response['L_ERRORCODE0']);
}
}
/**
* Outputs given request data.
*
* @param string $methodName
*
* @return string
*/
public function getCallBackResponse($methodName)
{
$this->setParameter("METHOD", $methodName);
$curl = $this->getCurl();
$curl->setParameters($this->getParameters());
$request = $curl->getQuery();
$this->log($request, 'Callback response from O3-Shop to PayPal');
return $request;
}
/**
* Logs given request and responds parameters to log file.
*
* @param mixed $value request / response parameters
* @param string $title section title in log file
*/
public function log($value, $title = '')
{
if (!is_null($this->getLogger())) {
$this->getLogger()->setTitle($title);
$this->getLogger()->log($value);
}
}
/**
* Set parameter from request.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request request
*/
public function setRequest(\OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request)
{
$this->setParameters($request->getData());
}
}

View File

@@ -0,0 +1,803 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* PayPal config class
*/
class Config
{
/**
* PayPal payment was triggered via standard checkout by selecting PP as the payment method.
*
* @var int
*/
const OEPAYPAL_ECS = 1;
/**
* PayPal payment was triggered by shortcut button in basket step.
*
* @var int
*/
const OEPAYPAL_SHORTCUT = 2;
/**
* Name of session variable that marks how payment was triggered.
*
* @var string
*/
const OEPAYPAL_TRIGGER_NAME = 'oepaypal';
/**
* Name of partnercode array key in case payment was triggered by shortcut button.
*
* @var string
*/
const PARTNERCODE_SHORTCUT_KEY = 'SHORTCUT';
/**
* PayPal module id.
*
* @var string
*/
protected $payPalId = 'oepaypal';
/**
* PayPal host.
*
* @var string
*/
protected $payPalHost = 'api-3t.paypal.com';
/**
* PayPal sandbox host.
*
* @var string
*/
protected $payPalSandboxHost = 'api-3t.sandbox.paypal.com';
/**
* PayPal sandbox Url where user must be redirected after his session gets PayPal token.
*
* @var string
*/
protected $payPalSandboxUrl = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
/**
* PayPal Url where user must be redirected after his session gets PayPal token.
*
* @var string
*/
protected $payPalUrl = 'https://www.paypal.com/cgi-bin/webscr';
/**
* PayPal sandbox API url.
*
* @var string
*/
protected $payPalSandboxApiUrl = 'https://api-3t.sandbox.paypal.com/nvp';
/**
* PayPal API url.
*
* @var string
*/
protected $payPalApiUrl = 'https://api-3t.paypal.com/nvp';
/**
* Maximum possible delivery costs value.
*
* @var double
*/
protected $maxDeliveryAmount = 30;
/**
* Please do not change this place.
* It is important to guarantee the future development of this O3-Shop extension and to keep it free of charge.
* Thanks!
*
* @var array Partner codes based on edition
*/
protected $partnerCodes = array(
'CE' => 'O3SHOP_Cart_CommunityECS',
'SHORTCUT' => 'O3SHOP_Cart_ECS_Shortcut'
);
/**
* Return PayPal module id.
*
* @return string
*/
public function getModuleId()
{
return $this->payPalId;
}
/**
* Sets PayPal host.
*
* @param string $payPalHost
*/
public function setPayPalHost($payPalHost)
{
$this->payPalHost = $payPalHost;
}
/**
* Returns PayPal host.
*
* @return string
*/
public function getPayPalHost()
{
$host = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('sPayPalHost');
if ($host) {
$this->setPayPalHost($host);
}
return $this->payPalHost;
}
/**
* Sets PayPal sandbox host.
*
* @param string $payPalSandboxHost
*/
public function setPayPalSandboxHost($payPalSandboxHost)
{
$this->payPalSandboxHost = $payPalSandboxHost;
}
/**
* Returns PayPal sandbox host.
*
* @return string
*/
public function getPayPalSandboxHost()
{
$host = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('sPayPalSandboxHost');
if ($host) {
$this->setPayPalSandboxHost($host);
}
return $this->payPalSandboxHost;
}
/**
* Returns PayPal OR PayPal sandbox host.
*
* @return string
*/
public function getHost()
{
if ($this->isSandboxEnabled()) {
$url = $this->getPayPalSandboxHost();
} else {
$url = $this->getPayPalHost();
}
return $url;
}
/**
* Api Url setter
*
* @param string $payPalApiUrl
*/
public function setPayPalApiUrl($payPalApiUrl)
{
$this->payPalApiUrl = $payPalApiUrl;
}
/**
* Api Url getter
*
* @return string
*/
public function getPayPalApiUrl()
{
$url = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('sPayPalApiUrl');
if ($url) {
$this->setPayPalApiUrl($url);
}
return $this->payPalApiUrl;
}
/**
* PayPal sandbox api url setter
*
* @param string $payPalSandboxApiUrl
*/
public function setPayPalSandboxApiUrl($payPalSandboxApiUrl)
{
$this->payPalSandboxApiUrl = $payPalSandboxApiUrl;
}
/**
* PayPal sandbox api url getter
*
* @return string
*/
public function getPayPalSandboxApiUrl()
{
$url = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('sPayPalSandboxApiUrl');
if ($url) {
$this->setPayPalSandboxApiUrl($url);
}
return $this->payPalSandboxApiUrl;
}
/**
* Returns end point url
*
* @return string
*/
public function getApiUrl()
{
if ($this->isSandboxEnabled()) {
$url = $this->getPayPalSandboxApiUrl();
} else {
$url = $this->getPayPalApiUrl();
}
return $url;
}
/**
* PayPal Url Setter
*
* @param string $payPalUrl
*/
public function setPayPalUrl($payPalUrl)
{
$this->payPalUrl = $payPalUrl;
}
/**
* PayPal sandbox url setter
*
* @param string $payPalSandboxUrl
*/
public function setPayPalSandboxUrl($payPalSandboxUrl)
{
$this->payPalSandboxUrl = $payPalSandboxUrl;
}
/**
* PayPal sandbox url getter
*
* @return string
*/
public function getPayPalUrl()
{
$url = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('sPayPalUrl');
if ($url) {
$this->setPayPalUrl($url);
}
return $this->payPalUrl;
}
/**
* PayPal sandbox url getter
*
* @return string
*/
public function getPayPalSandboxUrl()
{
$url = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('sPayPalSandboxUrl');
if ($url) {
$this->setPayPalSandboxUrl($url);
}
return $this->payPalSandboxUrl;
}
/**
* Get PayPal url.
*
* @return string
*/
public function getUrl()
{
if ($this->isSandboxEnabled()) {
$url = $this->getPayPalSandboxUrl();
} else {
$url = $this->getPayPalUrl();
}
return $url;
}
/**
* Returns module config parameter value
*
* @param string $paramName parameter name
*
* @return mixed
*/
public function getParameter($paramName)
{
return \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam($paramName);
}
/**
* Returns true if Express Checkout is ON
*
* @return bool
*/
public function isExpressCheckoutEnabled()
{
return $this->getParameter('blOEPayPalExpressCheckout');
}
/**
* Returns true if Express Checkout is ON in mini basket
*
* @return bool
*/
public function isExpressCheckoutInMiniBasketEnabled()
{
return $this->getParameter('blOEPayPalECheckoutInMiniBasket');
}
/**
* Returns true if Standard PayPal Checkout is ON
*
* @return bool
*/
public function isStandardCheckoutEnabled()
{
return $this->getParameter('blOEPayPalStandardCheckout');
}
/**
* Returns true if logging request/response to PayPal is enabled
*
* @return bool
*/
public function isLoggingEnabled()
{
return $this->getParameter('blPayPalLoggerEnabled');
}
/**
* Returns Brand/Shop name [OXID ESHOP]
*
* @return string
*/
public function getBrandName()
{
$shopName = $this->getParameter('sOEPayPalBrandName');
if (empty($shopName)) {
$shop = \OxidEsales\Eshop\Core\Registry::getConfig()->getActiveShop();
$shopName = $shop->oxshops__oxname->value;
}
return $shopName;
}
/**
* Returns custom cart border color which is displayed in PayPal side
*
* @return string
*/
public function getBorderColor()
{
return $this->getParameter('sOEPayPalBorderColor');
}
/**
* Returns TRUE if order finalization on PayPal side is on
*
* @return bool
*/
public function finalizeOrderOnPayPalSide()
{
$finalize = $this->getParameter('blOEPayPalFinalizeOrderOnPayPal');
return $finalize !== null ? $finalize : false;
}
/**
* Send order info to PayPal or not
*
* @return bool
*/
public function sendOrderInfoToPayPal()
{
return $this->getParameter('blOEPayPalSendToPayPal');
}
/**
* Send order info to PayPal or not config's default value: checked or not
*
* @return bool
*/
public function sendOrderInfoToPayPalDefault()
{
return $this->getParameter('blOEPayPalDefaultUserChoice');
}
/**
* Guest buy mode getter
*
* @return bool
*/
public function isGuestBuyEnabled()
{
return $this->getParameter('blOEPayPalGuestBuyRole');
}
/**
* Returns true of GiroPay is ON (not implemented yet)
*
* @return bool
*/
public function isGiroPayEnabled()
{
return false;
}
/**
* Returns true of sandbox mode is ON
*
* @return bool
*/
public function isSandboxEnabled()
{
return $this->getParameter('blOEPayPalSandboxMode');
}
/**
* Returns Empty Stock Level
*
* @return string
*/
public function getEmptyStockLevel()
{
return $this->getParameter('sOEPayPalEmptyStockLevel');
}
/**
* Returns PayPal password
*
* @return string
*/
public function getPassword()
{
if ($this->isSandboxEnabled()) {
// sandbox password
return $this->getParameter('sOEPayPalSandboxPassword');
}
// password
return $this->getParameter('sOEPayPalPassword');
}
/**
* Returns PayPal user name
*
* @return string
*/
public function getUserName()
{
if ($this->isSandboxEnabled()) {
// sandbox login
return $this->getParameter('sOEPayPalSandboxUsername');
}
// login
return $this->getParameter('sOEPayPalUsername');
}
/**
* Returns PayPal user name
*
* @return string
*/
public function getUserEmail()
{
if ($this->isSandboxEnabled()) {
// sandbox login
return $this->getParameter('sOEPayPalSandboxUserEmail');
}
// login
return $this->getParameter('sOEPayPalUserEmail');
}
/**
* Returns PayPal signature
*
* @return string
*/
public function getSignature()
{
if ($this->isSandboxEnabled()) {
// sandbox signature
return $this->getParameter('sOEPayPalSandboxSignature');
}
// test sandbox signature
return $this->getParameter('sOEPayPalSignature');
}
/**
* Returns PayPal transaction mode
*
* @return string
*/
public function getTransactionMode()
{
return $this->getParameter('sOEPayPalTransactionMode');
}
/**
* Returns redirect url.
*
* @param string $token token to append to redirect url.
* @param string $userAction checkout button action - continue (standard checkout) or commit (express checkout)
*
* @return string
*/
public function getPayPalCommunicationUrl($token = null, $userAction = 'continue')
{
return $this->getUrl() . '&cmd=_express-checkout&token=' . (string) $token . '&useraction=' . (string) $userAction;
}
/**
* Get logo Url based on selected settings
* Returns shop url, or false
*
* @return string|bool
*/
public function getLogoUrl()
{
$logoUrl = false;
$logoName = $this->getLogoImageName();
if (!empty($logoName)) {
$logo = oxNew(\OxidEsales\PayPalModule\Core\ShopLogo::class);
$logo->setImageDir(\OxidEsales\Eshop\Core\Registry::getConfig()->getImageDir());
$logo->setImageDirUrl(\OxidEsales\Eshop\Core\Registry::getConfig()->getImageUrl());
$logo->setImageName($logoName);
$logo->setImageHandler(\OxidEsales\Eshop\Core\Registry::getUtilsPic());
$logoUrl = $logo->getShopLogoUrl();
}
return $logoUrl;
}
/**
* Returns IPN callback url
*
* @return string
*/
public function getIPNCallbackUrl()
{
return $this->getShopUrl() . 'index.php?cl=oepaypalipnhandler&fnc=handleRequest&shp=' . $this->getShopId();
}
/**
* Methods checks if sending of IPN callback url to PayPal is supressed by configuration.
*
* @return bool
*/
public function suppressIPNCallbackUrl()
{
return (bool) \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('OEPayPalDisableIPN');
}
/**
* Returns SSL or non SSL shop URL without index.php depending on Mall
* affecting environment is admin mode and current ssl usage status
*
* @param bool $admin if admin
*
* @return string
*/
public function getShopUrl($admin = null)
{
return \OxidEsales\Eshop\Core\Registry::getConfig()->getCurrentShopUrl($admin);
}
/**
* Wrapper to get language object from registry.
*
* @return \OxidEsales\Eshop\Core\Language
*/
public function getLang()
{
return \OxidEsales\Eshop\Core\Registry::getLang();
}
/**
* Wrapper to get utils object from registry.
*
* @return \OxidEsales\Eshop\Core\Utils
*/
public function getUtils()
{
return \OxidEsales\Eshop\Core\Registry::getUtils();
}
/**
* Returns shop charset
*
* @return string
*/
public function getCharset()
{
$charset = 'UTF-8';
return $charset;
}
/**
* @deprecated in dev-master (2018-04-27); Use OxidEsales\PayPalModule\Core\IPnConfig::getIPNResponseUrl()
*
* Returns Url for IPN response call to notify PayPal
*
* @return string
*/
public function getIPNResponseUrl()
{
return $this->getUrl() . '&cmd=_notify-validate';
}
/**
* Returns true if Express Checkout is in details page
*
* @return bool
*/
public function isExpressCheckoutInDetailsPage()
{
return $this->getParameter('blOEPayPalECheckoutInDetails');
}
/**
* Returns current URL
*
* @return string
*/
public function getCurrentUrl()
{
return \OxidEsales\Eshop\Core\Registry::getUtilsUrl()->getCurrentUrl();
}
/**
* Returns max delivery amount.
*
* @return integer
*/
public function getMaxPayPalDeliveryAmount()
{
$maxDeliveryAmount = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('dMaxPayPalDeliveryAmount');
if (!$maxDeliveryAmount) {
$maxDeliveryAmount = $this->maxDeliveryAmount;
}
return $maxDeliveryAmount;
}
/**
* Please do not change this place.
* It is important to guarantee the future development of this O3-Shop extension and to keep it free of charge.
* Thanks!
*
* @return string partner code.
*/
public function getPartnerCode()
{
$facts = new \OxidEsales\Facts\Facts();
$key = $this->isShortcutPayment() ? self::PARTNERCODE_SHORTCUT_KEY : $facts->getEdition();
return $this->partnerCodes[$key];
}
/**
* Detects device type
*
* @return bool
*/
public function isDeviceMobile()
{
$userAgent = oxNew(\OxidEsales\PayPalModule\Core\UserAgent::class);
return ($userAgent->getDeviceType() == 'mobile');
}
/**
* Returns id of shipping assigned for EC for mobile devices
*
* @return string
*/
public function getMobileECDefaultShippingId()
{
return \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('sOEPayPalMECDefaultShippingId');
}
/**
* Returns logo image name according to parameter
*
* @return mixed|string
*/
protected function getLogoImageName()
{
$option = $this->getParameter('sOEPayPalLogoImageOption');
switch ($option) {
case 'shopLogo':
$logo = $this->getParameter('sShopLogo');
break;
case 'customLogo':
$logo = $this->getParameter('sOEPayPalCustomShopLogoImage');
break;
case 'noLogo':
default:
$logo = '';
return $logo;
}
return $logo;
}
/**
* Returns active shop id
*
* @return string
*/
protected function getShopId()
{
return \OxidEsales\Eshop\Core\Registry::getConfig()->getShopId();
}
/**
* Returns oxConfig instance
*
* @return \OxidEsales\Eshop\Core\Config
*/
protected function getConfig()
{
return \OxidEsales\Eshop\Core\Registry::getConfig();
}
/**
* Was the payment triggered by shortcut button or not?
*
* @return bool
*/
protected function isShortcutPayment()
{
$trigger = (int) \OxidEsales\Eshop\Core\Registry::getSession()->getVariable(self::OEPAYPAL_TRIGGER_NAME);
return (bool) ($trigger == self::OEPAYPAL_SHORTCUT);
}
}

View File

@@ -0,0 +1,473 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
if (!defined('CURL_SSLVERSION_TLSV1_2')) {
define('CURL_SSLVERSION_TLSV1_2', 6);
}
/**
* PayPal Curl class
*/
class Curl
{
/**
* Host for header.
*
* @var string
*/
protected $host = null;
/**
* Curl instance.
*
* @var resource
*/
protected $curl = null;
/**
* Connection Charset.
*
* @var string
*/
protected $connectionCharset = "UTF-8";
/**
* Data Charset.
*
* @var string
*/
protected $dataCharset = "UTF-8";
/**
* Curl default parameters.
*
* @var array
*/
protected $environmentParameters = array(
'CURLOPT_VERBOSE' => 0,
'CURLOPT_SSL_VERIFYPEER' => false,
'CURLOPT_SSL_VERIFYHOST' => false,
'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSV1_2,
'CURLOPT_RETURNTRANSFER' => 1,
'CURLOPT_POST' => 1,
'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1,
);
/**
* Parameter to be added to call url
*
* @var array | null
*/
protected $parameters = null;
/**
* PayPal URL to call. Usually API address.
*
* @var string | null
*/
protected $urlToCall = null;
/**
* Query like "param1=value1&param2=values2.."
*
* @return string
*/
protected $query = null;
/**
* Curl call header.
*
* @var array
*/
protected $header = null;
/**
* Sets host.
*
* @param string $host
*/
public function setHost($host)
{
$this->host = $host;
}
/**
* Returns host.
*
* @return string
*/
public function getHost()
{
return $this->host;
}
/**
* Set header.
*
* @param array $header
*/
public function setHeader($header)
{
$this->header = $header;
}
/**
* Forms header from host.
*
* @return array
*/
public function getHeader()
{
if (is_null($this->header)) {
$host = $this->getHost();
$header = array();
$header[] = 'POST /cgi-bin/webscr HTTP/1.1';
$header[] = 'Content-Type: application/x-www-form-urlencoded';
if (isset($host)) {
$header[] = 'Host: ' . $host;
}
$header[] = 'Connection: close';
$this->setHeader($header);
}
return $this->header;
}
/**
* Set connection charset
*
* @param string $charset charset
*/
public function setConnectionCharset($charset)
{
$this->connectionCharset = $charset;
}
/**
* Return connection charset
*
* @return string
*/
public function getConnectionCharset()
{
return $this->connectionCharset;
}
/**
* Set data charset
*
* @param string $dataCharset
*/
public function setDataCharset($dataCharset)
{
$this->dataCharset = $dataCharset;
}
/**
* Return data charset
*
* @return string
*/
public function getDataCharset()
{
return $this->dataCharset;
}
/**
* Return environment parameters
*
* @return array
*/
public function getEnvironmentParameters()
{
return $this->environmentParameters;
}
/**
* Sets one of Curl parameter.
*
* @param string $name Curl parameter name.
* @param mixed $value Curl parameter value
*/
public function setEnvironmentParameter($name, $value)
{
$this->environmentParameters[$name] = $value;
}
/**
* Sets parameters to be added to call url.
*
* @param array $parameters parameters
*/
public function setParameters($parameters)
{
$this->parameters = $parameters;
}
/**
* Return parameters to be added to call url.
*
* @return array
*/
public function getParameters()
{
return $this->parameters;
}
/**
* Set query like "param1=value1&param2=values2.."
*
* @param string $query
*/
public function setQuery($query)
{
$this->query = $query;
}
/**
* Builds query like "param1=value1&param2=values2.."
*
* @return string
*/
public function getQuery()
{
if (is_null($this->query)) {
$params = $this->getParameters();
$params = array_map(array($this, 'htmlDecode'), $params);
$params = array_map(array($this, 'encode'), $params);
$this->setQuery(http_build_query($params, "", "&"));
}
return $this->query;
}
/**
* Set PayPal URL to call.
*
* @param string $urlToCall PayPal URL to call.
*
* @throws \OxidEsales\PayPalModule\Core\Exception\PayPalException if url is not valid
*/
public function setUrlToCall($urlToCall)
{
if (false === filter_var($urlToCall, FILTER_VALIDATE_URL)) {
/**
* @var \OxidEsales\PayPalModule\Core\Exception\PayPalException $exception
*/
$exception = oxNew(\OxidEsales\PayPalModule\Core\Exception\PayPalException::class, 'URL to call is not valid.');
throw $exception;
}
$this->urlToCall = $urlToCall;
}
/**
* Get url
*
* @return string
*/
public function getUrlToCall()
{
return $this->urlToCall;
}
/**
* Sets resource
*
* @param resource $curl curl.
*/
protected function setResource($curl)
{
$this->curl = $curl;
}
/**
* Returns curl resource
*
* @return resource
*/
protected function getResource()
{
if (is_null($this->curl)) {
$this->setResource(curl_init());
}
return $this->curl;
}
/**
* Executes curl call and returns response data as associative array.
*
* @return array
*/
public function execute()
{
$this->setOptions();
$response = $this->parseResponse($this->curlExecute());
$this->close();
return $response;
}
/**
* Set Curl Parameters.
*/
protected function setOptions()
{
foreach ($this->getEnvironmentParameters() as $name => $value) {
$this->setOption(constant($name), $value);
}
$this->setOption(CURLOPT_HTTPHEADER, $this->getHeader());
$this->setOption(CURLOPT_URL, $this->getUrlToCall());
$this->setOption(CURLOPT_POSTFIELDS, $this->getQuery());
}
/**
* Wrapper function to be mocked for testing.
*
* @param string $name curl field name to set value to.
* @param mixed $value curl field value to set.
*/
protected function setOption($name, $value)
{
curl_setopt($this->getResource(), $name, $value);
}
/**
* Wrapper function to be mocked for testing.
*
* @return string
*
* @throws \OxidEsales\PayPalModule\Core\Exception\PayPalException on curl errors
*/
protected function curlExecute()
{
$response = curl_exec($this->getResource());
$curlErrorNumber = $this->getErrorNumber();
if ($curlErrorNumber) {
/**
* @var \OxidEsales\PayPalModule\Core\Exception\PayPalException $exception
*/
$exception = oxNew(\OxidEsales\PayPalModule\Core\Exception\PayPalException::class, 'Curl error: ' . $curlErrorNumber);
throw $exception;
}
return $response;
}
/**
* Wrapper function to be mocked for testing.
*/
protected function close()
{
curl_close($this->getResource());
}
/**
* Parse curl response and strip it to safe form.
*
* @param string $response curl response.
*
* @return array
*/
protected function parseResponse($response)
{
$result = [];
// processing results
parse_str($response, $result);
// stripping slashes
$result = array_map(array($this, 'decode'), $result);
return $result;
}
/**
* Check if curl has errors. Set error message if has.
*
* @return int
*/
protected function getErrorNumber()
{
return curl_errno($this->getResource());
}
/**
* Decode (if needed) given query from UTF8
*
* @param string $string query
*
* @return string
*/
protected function htmlDecode($string)
{
$string = html_entity_decode($string, ENT_QUOTES, $this->getConnectionCharset());
return $string;
}
/**
* Decode (if needed) given query from UTF8
*
* @param string $string query
*
* @return string
*/
protected function decode($string)
{
$charset = $this->getDataCharset();
if ($charset !== $this->getConnectionCharset()) {
$string = iconv($this->getConnectionCharset(), $charset, $string);
}
if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
return $string;
}
/**
* Encodes (if needed) given query to UTF8
*
* @param string $string query
*
* @return string
*/
protected function encode($string)
{
$charset = $this->getDataCharset();
if ($charset !== $this->getConnectionCharset()) {
$string = iconv($charset, $this->getConnectionCharset(), $string);
}
return $string;
}
}

View File

@@ -0,0 +1,93 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* PayPal escape class
*/
class Escape
{
/**
* Checks if passed parameter has special chars and replaces them.
* Returns checked value.
*
* @param mixed $value value to process escaping
*
* @return mixed
*/
public function escapeSpecialChars($value)
{
if (is_object($value)) {
return $value;
}
if (is_array($value)) {
$value = $this->escapeArraySpecialChars($value);
} elseif (is_string($value)) {
$value = $this->escapeStringSpecialChars($value);
}
return $value;
}
/**
* Checks if passed parameter has special chars and replaces them.
* Returns checked value.
*
* @param array $value value to process escaping
*
* @return array
*/
private function escapeArraySpecialChars($value)
{
$newValue = array();
foreach ($value as $key => $val) {
$validKey = $key;
$validKey = $this->escapeSpecialChars($validKey);
$val = $this->escapeSpecialChars($val);
if ($validKey != $key) {
unset($value[$key]);
}
$newValue[$validKey] = $val;
}
return $newValue;
}
/**
* Checks if passed parameter has special chars and replaces them.
* Returns checked value.
*
* @param string $value value to process escaping
*
* @return string
*/
private function escapeStringSpecialChars($value)
{
$value = str_replace(
array('&', '<', '>', '"', "'", chr(0), '\\'),
array('&amp;', '&lt;', '&gt;', '&quot;', '&#039;', '', '&#092;'),
$value
);
return $value;
}
}

View File

@@ -0,0 +1,314 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* Class defines what module does on Shop events.
*/
class Events
{
/**
* Add additional fields: payment status, captured amount, refunded amount in oxOrder table
*/
public static function addOrderTable()
{
$query = "CREATE TABLE IF NOT EXISTS `oepaypal_order` (
`OEPAYPAL_ORDERID` char(32) character set latin1 collate latin1_general_ci NOT NULL,
`OEPAYPAL_PAYMENTSTATUS` enum('pending','completed','failed','canceled') NOT NULL DEFAULT 'pending',
`OEPAYPAL_CAPTUREDAMOUNT` decimal(9,2) NOT NULL,
`OEPAYPAL_REFUNDEDAMOUNT` decimal(9,2) NOT NULL,
`OEPAYPAL_VOIDEDAMOUNT` decimal(9,2) NOT NULL,
`OEPAYPAL_TOTALORDERSUM` decimal(9,2) NOT NULL,
`OEPAYPAL_CURRENCY` varchar(32) NOT NULL,
`OEPAYPAL_TRANSACTIONMODE` enum('Sale','Authorization') NOT NULL DEFAULT 'Sale',
`OEPAYPAL_TIMESTAMP` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`OEPAYPAL_ORDERID`),
KEY `OEPAYPAL_PAYMENTSTATUS` (`OEPAYPAL_PAYMENTSTATUS`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
}
/**
* Add PayPal payment method set EN and DE long descriptions
*/
public static function addPaymentMethod()
{
$paymentDescriptions = array(
'en' => '<div>When selecting this payment method you are being redirected to PayPal where you can login into your account or open a new account. In PayPal you are able to authorize the payment. As soon you have authorized the payment, you are again redirected to our shop where you can confirm your order.</div> <div style="margin-top: 5px">Only after confirming the order, transfer of money takes place.</div>',
'de' => '<div>Bei Auswahl der Zahlungsart PayPal werden Sie im nächsten Schritt zu PayPal weitergeleitet. Dort können Sie sich in Ihr PayPal-Konto einloggen oder ein neues PayPal-Konto eröffnen und die Zahlung autorisieren. Sobald Sie Ihre Daten für die Zahlung bestätigt haben, werden Sie automatisch wieder zurück in den Shop geleitet, um die Bestellung abzuschließen.</div> <div style="margin-top: 5px">Erst dann wird die Zahlung ausgeführt.</div>'
);
$payment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
if (!$payment->load('oxidpaypal')) {
$payment->setId('oxidpaypal');
$payment->oxpayments__oxactive = new \OxidEsales\Eshop\Core\Field(1);
$payment->oxpayments__oxdesc = new \OxidEsales\Eshop\Core\Field('PayPal');
$payment->oxpayments__oxaddsum = new \OxidEsales\Eshop\Core\Field(0);
$payment->oxpayments__oxaddsumtype = new \OxidEsales\Eshop\Core\Field('abs');
$payment->oxpayments__oxfromboni = new \OxidEsales\Eshop\Core\Field(0);
$payment->oxpayments__oxfromamount = new \OxidEsales\Eshop\Core\Field(0);
$payment->oxpayments__oxtoamount = new \OxidEsales\Eshop\Core\Field(10000);
$language = \OxidEsales\Eshop\Core\Registry::getLang();
$languages = $language->getLanguageIds();
foreach ($paymentDescriptions as $languageAbbreviation => $description) {
$languageId = array_search($languageAbbreviation, $languages);
if ($languageId !== false) {
$payment->setLanguage($languageId);
$payment->oxpayments__oxlongdesc = new \OxidEsales\Eshop\Core\Field($description);
$payment->save();
}
}
}
}
/**
* Check if PayPal is used for sub-shops.
*
* @return bool
*/
public static function isPayPalActiveOnSubShops()
{
$active = false;
$config = \OxidEsales\Eshop\Core\Registry::getConfig();
$extensionChecker = oxNew(\OxidEsales\PayPalModule\Core\ExtensionChecker::class);
$shops = $config->getShopIds();
$activeShopId = $config->getShopId();
foreach ($shops as $shopId) {
if ($shopId != $activeShopId) {
$extensionChecker->setShopId($shopId);
$extensionChecker->setExtensionId('oepaypal');
if ($extensionChecker->isActive()) {
$active = true;
break;
}
}
}
return $active;
}
/**
* Disables PayPal payment method
*/
public static function disablePaymentMethod()
{
$payment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
if ($payment->load('oxidpaypal')) {
$payment->oxpayments__oxactive = new \OxidEsales\Eshop\Core\Field(0);
$payment->save();
}
}
/**
* Activates PayPal payment method
*/
public static function enablePaymentMethod()
{
$payment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
$payment->load('oxidpaypal');
$payment->oxpayments__oxactive = new \OxidEsales\Eshop\Core\Field(1);
$payment->save();
}
/**
* Creates Order payments table in to database if not exist
*/
public static function addOrderPaymentsTable()
{
$query = "CREATE TABLE IF NOT EXISTS `oepaypal_orderpayments` (
`OEPAYPAL_PAYMENTID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`OEPAYPAL_ACTION` enum('capture', 'authorization', 're-authorization', 'refund', 'void') NOT NULL DEFAULT 'capture',
`OEPAYPAL_ORDERID` char(32) character set latin1 collate latin1_general_ci NOT NULL,
`OEPAYPAL_TRANSACTIONID` varchar(32) NOT NULL,
`OEPAYPAL_CORRELATIONID` varchar(32) NOT NULL,
`OEPAYPAL_AMOUNT` decimal(9,2) NOT NULL,
`OEPAYPAL_CURRENCY` varchar(3) NOT NULL,
`OEPAYPAL_REFUNDEDAMOUNT` decimal(9,2) NOT NULL,
`OEPAYPAL_DATE` datetime NOT NULL,
`OEPAYPAL_STATUS` varchar(20) NOT NULL,
`OEPAYPAL_TIMESTAMP` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`OEPAYPAL_PAYMENTID`),
KEY `OEPAYPAL_ORDERID` (`OEPAYPAL_ORDERID`),
KEY `OEPAYPAL_DATE` (`OEPAYPAL_DATE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
}
/**
* Creates Order payments Comments table in to database if not exist
*/
public static function addOrderPaymentsCommentsTable()
{
$query = "CREATE TABLE IF NOT EXISTS `oepaypal_orderpaymentcomments` (
`OEPAYPAL_COMMENTID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`OEPAYPAL_PAYMENTID` int(11) unsigned NOT NULL,
`OEPAYPAL_COMMENT` varchar(256) NOT NULL,
`OEPAYPAL_DATE` datetime NOT NULL,
`OEPAYPAL_TIMESTAMP` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`OEPAYPAL_COMMENTID`),
KEY `OEPAYPAL_ORDERID` (`OEPAYPAL_PAYMENTID`),
KEY `OEPAYPAL_DATE` (`OEPAYPAL_DATE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
}
/**
* Enables PayPal RDF
*
* @return null
*/
public static function enablePayPalRDFA()
{
// If PayPal activated on other sub shops do not change global RDF setting.
if ('EE' == \OxidEsales\Eshop\Core\Registry::getConfig()->getEdition() && self::isPayPalActiveOnSubShops()) {
return;
}
$query = "INSERT IGNORE INTO `oxobject2payment` (`OXID`, `OXPAYMENTID`, `OXOBJECTID`, `OXTYPE`) VALUES('oepaypalrdfa', 'oxidpaypal', 'PayPal', 'rdfapayment')";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
}
/**
* Disable PayPal RDF
*/
public static function disablePayPalRDFA()
{
$query = "DELETE FROM `oxobject2payment` WHERE `OXID` = 'oepaypalrdfa'";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
}
/**
* Add missing field if it activates on old DB
*/
public static function addMissingFieldsOnUpdate()
{
$dbMetaDataHandler = oxNew(\OxidEsales\Eshop\Core\DbMetaDataHandler::class);
$tableFields = array(
'oepaypal_order' => 'OEPAYPAL_TIMESTAMP',
'oepaypal_orderpayments' => 'OEPAYPAL_TIMESTAMP',
'oepaypal_orderpaymentcomments' => 'OEPAYPAL_TIMESTAMP',
);
foreach ($tableFields as $tableName => $fieldName) {
if (!$dbMetaDataHandler->fieldExists($fieldName, $tableName)) {
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute(
"ALTER TABLE `" . $tableName
. "` ADD `" . $fieldName . "` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP;"
);
}
}
}
/**
* Update tables and its fields encoding/collation if activated on old DB
*/
public static function ensureCorrectFieldsEncodingOnUpdate()
{
$dbMetaDataHandler = oxNew(\OxidEsales\Eshop\Core\DbMetaDataHandler::class);
if ($dbMetaDataHandler->tableExists("oepaypal_order")) {
$query = "ALTER TABLE `oepaypal_order` DEFAULT CHARACTER SET utf8 collate utf8_general_ci;";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
$query = "ALTER TABLE `oepaypal_orderpaymentcomments` DEFAULT CHARACTER SET utf8 collate utf8_general_ci;";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
$query = "ALTER TABLE `oepaypal_orderpayments` DEFAULT CHARACTER SET utf8 collate utf8_general_ci;";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
$query = "ALTER TABLE `oepaypal_order`
MODIFY `OEPAYPAL_CURRENCY` varchar(32) character set utf8 collate utf8_general_ci NOT NULL,
MODIFY `OEPAYPAL_PAYMENTSTATUS` enum('pending','completed','failed','canceled') CHARACTER SET utf8 collate utf8_general_ci NOT NULL DEFAULT 'pending',
MODIFY `OEPAYPAL_TRANSACTIONMODE` enum('Sale','Authorization') CHARACTER SET utf8 collate utf8_general_ci NOT NULL DEFAULT 'Sale';";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
$query = "ALTER TABLE `oepaypal_orderpaymentcomments`
MODIFY `OEPAYPAL_COMMENT` varchar(256) character set utf8 collate utf8_general_ci NOT NULL;";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
$query = "ALTER TABLE `oepaypal_orderpayments`
MODIFY `OEPAYPAL_ACTION` enum('capture','authorization','re-authorization','refund','void') CHARACTER SET utf8 collate utf8_general_ci NOT NULL DEFAULT 'capture',
MODIFY `OEPAYPAL_TRANSACTIONID` varchar(32) character set utf8 collate utf8_general_ci NOT NULL,
MODIFY `OEPAYPAL_CORRELATIONID` varchar(32) character set utf8 collate utf8_general_ci NOT NULL,
MODIFY `OEPAYPAL_CURRENCY` varchar(3) character set utf8 collate utf8_general_ci NOT NULL,
MODIFY `OEPAYPAL_STATUS` varchar(20) character set utf8 collate utf8_general_ci NOT NULL;";
\OxidEsales\Eshop\Core\DatabaseProvider::getDb()->execute($query);
}
}
/**
* Execute action on activate event
*/
public static function onActivate()
{
// add additional field to order
self::addOrderTable();
// create orders payments table
self::addOrderPaymentsTable();
// payment comments
self::addOrderPaymentsCommentsTable();
self::addMissingFieldsOnUpdate();
self::ensureCorrectFieldsEncodingOnUpdate();
// adding record to oxPayment table
self::addPaymentMethod();
// enabling PayPal payment method
self::enablePaymentMethod();
// enable PayPal RDF
self::enablePayPalRDFA();
}
/**
* Delete the basket object, which is saved in the session, as it is an instance of \OxidEsales\PayPalModule\Model\Basket
* and it is no longer a valid object after the module has been deactivated.
*/
public static function deleteSessionBasket()
{
\OxidEsales\Eshop\Core\Registry::getSession()->delBasket();
}
/**
* Execute action on deactivate event
*
* @return null
*/
public static function onDeactivate()
{
// If PayPal activated on other sub shops do not remove payment method and RDF setting
if ('EE' == \OxidEsales\Eshop\Core\Registry::getConfig()->getEdition() && self::isPayPalActiveOnSubShops()) {
return;
}
self::disablePaymentMethod();
self::disablePayPalRDFA();
self::deleteSessionBasket();
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core\Exception;
/**
* Exception base class for PayPal
*/
class PayPalException extends \OxidEsales\Eshop\Core\Exception\StandardException
{
/**
* Exception constructor.
*
* @param string $message exception message
* @param integer $code exception code
*/
public function __construct($message = "", $code = 0)
{
parent::__construct($message, $code);
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core\Exception;
/**
* Exception Invalid Action exception
*/
class PayPalInvalidActionException extends \OxidEsales\PayPalModule\Core\Exception\PayPalException
{
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core\Exception;
/**
* Exception missing parameter exception
*/
class PayPalMissingParameterException extends \OxidEsales\PayPalModule\Core\Exception\PayPalException
{
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core\Exception;
/**
* Exception class for PayPal returned exceptions
*/
class PayPalResponseException extends \OxidEsales\PayPalModule\Core\Exception\PayPalException
{
/**
* Exception constructor. Adds additional prefix string to error message.
*
* @param string $message exception message
* @param integer $code exception code
*/
public function __construct($message = "", $code = 0)
{
$prefix = \OxidEsales\Eshop\Core\Registry::getLang()->translateString("OEPAYPAL_RESPONSE_FROM_PAYPAL");
parent::__construct($prefix . $message, $code);
}
}

View File

@@ -0,0 +1,157 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* PayPal Extension checker, check if extension is active on shop/sub-shop
*/
class ExtensionChecker
{
/**
* Shop id
*
* @var string
*/
protected $shopId = null;
/**
* Extension id
*
* @var string
*/
protected $extensionId = '';
/**
* Set shop id
*
* @param string $shopId shop id
*/
public function setShopId($shopId)
{
$this->shopId = $shopId;
}
/**
* Return shop id
*
* @return string
*/
public function getShopId()
{
if (is_null($this->shopId)) {
$this->setShopId(\OxidEsales\Eshop\Core\Registry::getConfig()->getShopId());
}
return $this->shopId;
}
/**
* Set extension id
*
* @param string $extensionId extension id
*/
public function setExtensionId($extensionId)
{
$this->extensionId = $extensionId;
}
/**
* Return extension id
*
* @return string
*/
public function getExtensionId()
{
return $this->extensionId;
}
/**
* Return return extended classes array
*
* @return array
*/
protected function getExtendedClasses()
{
return $this->getConfigValue('aModules');
}
/**
* Return disabled modules array
*
* @return array
*/
protected function getDisabledModules()
{
return $this->getConfigValue('aDisabledModules');
}
/**
* Return config value
*
* @param string $configName - config parameter name were stored arrays od extended classes
*
* @return array
*/
protected function getConfigValue($configName)
{
$db = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
$config = \OxidEsales\Eshop\Core\Registry::getConfig();
$select = "SELECT `oxvarvalue` " .
"FROM `oxconfig` WHERE `oxvarname` = " . $db->quote($configName) . " AND `oxshopid` = " . $db->quote($this->getShopId());
return unserialize($db->getOne($select));
}
/**
* Check if module is active.
*
* @return bool
*/
public function isActive()
{
$moduleId = $this->getExtensionId();
$moduleIsActive = false;
$modules = $this->getExtendedClasses();
if (is_array($modules)) {
// Check if module was ever installed.
$moduleExists = false;
foreach ($modules as $extendPath) {
if (false !== strpos($extendPath, '/' . $moduleId . '/')) {
$moduleExists = true;
break;
}
}
// If module exists, check if it is not disabled.
if ($moduleExists) {
$disabledModules = $this->getDisabledModules();
if (!(is_array($disabledModules) && in_array($moduleId, $disabledModules))) {
$moduleIsActive = true;
}
}
}
return $moduleIsActive;
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* Class for splitting user name.
*
* @package core
*/
class FullName
{
/** @var string */
private $firstName = '';
/** @var string */
private $lastName = '';
/**
* User first name and second name.
*
* @param string $fullName
*/
public function __construct($fullName)
{
$this->split($fullName);
}
/**
* Return user first name.
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Return user second name.
*
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Split user full name to first name and second name.
*
* @param string $fullName
*/
protected function split($fullName)
{
$names = explode(" ", trim($fullName), 2);
$this->firstName = trim($names[0]);
$this->lastName = trim($names[1]);
}
}

View File

@@ -0,0 +1,290 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* PayPal IPN config class
*/
class IpnConfig
{
/**
* Name of sandbox IPN host configuration variable.
*
* @var string
*/
const OEPAYPAL_SANDBOX_IPNHOST_CONFIGVAR = 'sPayPalSandboxIpnHost';
/**
* Name of sandbox mode configuration variable.
*
* @var string
*/
const OEPAYPAL_IPNHOST_CONFIGVAR = 'sPayPalIpnHost';
/**
* Name of sandbox IPN url configuration variable.
*
* @var string
*/
const OEPAYPAL_SANDBOX_IPN_URL_CONFIGVAR = 'sPayPalSandboxIpnUrl';
/**
* Name of IPN url configuration variable.
*
* @var string
*/
const OEPAYPAL_IPN_URL_CONFIGVAR = 'sPayPalIpnUrl';
/**
* PayPal IPN host.
*
* @var string
*/
const OEPAYPAL_IPN_HOST = 'ipnpb.paypal.com';
/**
* PayPal IPN sandbox host.
*
* @var string
*/
const OEPAYPAL_IPN_SANDBOX_HOST = 'ipnpb.sandbox.paypal.com';
/**
* PayPal sandbox url to send IPN callback to for verification.
*
* @var string
*/
const OEPAYPAL_SANDBOX_IPN_CALLBACK_URL = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr';
/**
* PayPal sandbox url to send IPN callback to for verification.
*
* @var string
*/
const OEPAYPAL_IPN_CALLBACK_URL = 'https://ipnpb.paypal.com/cgi-bin/webscr';
/**
* @var
*/
protected $payPalConfig = null;
/**
* PayPal IPN host.
*
* @var string
*/
protected $payPalIpnHost = '';
/**
* PayPal IPN sandbox host.
*
* @var string
*/
protected $payPalIpnSandboxHost = '';
/**
* PayPal sandbox url to send IPN callback to for verification.
*
* @var string
*/
protected $payPalSandboxIpnUrl = '';
/**
* PayPal sandbox url to send IPN callback to for verification.
*
* @var string
*/
protected $payPalIpnUrl = '';
/**
* IpnConfig constructor.
*/
public function __construct()
{
if ($host = $this->getPayPalConfig()->getParameter(self::getPayPalIpnHost())) {
$this->setPayPalIpnHost($host);
}
if ($sandboxHost = $this->getPayPalConfig()->getParameter(self::OEPAYPAL_SANDBOX_IPNHOST_CONFIGVAR)) {
$this->setPayPalSandboxIpnHost($sandboxHost);
}
if ($url = $this->getPayPalConfig()->getParameter(self::OEPAYPAL_IPN_URL_CONFIGVAR)) {
$this->setPayPalIpnUrl($url);
}
if ($sandboxUrl = $this->getPayPalConfig()->getParameter(self::OEPAYPAL_SANDBOX_IPN_URL_CONFIGVAR)) {
$this->setPayPalSandboxIPNUrl($sandboxUrl);
}
}
/**
* Sets PayPal IPN host.
*
* @param string $payPalIpnHost
*/
public function setPayPalIpnHost($payPalIpnHost)
{
$this->payPalIpnHost = $payPalIpnHost;
}
/**
* Returns PayPal IPN host.
*
* @return string
*/
public function getPayPalIpnHost()
{
if (empty($this->payPalIpnHost)) {
$this->payPalIpnHost = self::OEPAYPAL_IPN_HOST;
}
return $this->payPalIpnHost;
}
/**
* Sets PayPal IPN sandbox host.
*
* @param string $payPalIpnSandboxHost
*/
public function setPayPalSandboxIpnHost($payPalIpnSandboxHost)
{
$this->payPalIpnSandboxHost = $payPalIpnSandboxHost;
}
/**
* Returns PayPal sandbox host.
*
* @return string
*/
public function getPayPalSandboxIpnHost()
{
if (empty($this->payPalIpnSandboxHost)) {
$this->payPalIpnSandboxHost = self::OEPAYPAL_IPN_SANDBOX_HOST;
}
return $this->payPalIpnSandboxHost;
}
/**
* Returns PayPal OR PayPal IPN sandbox host.
*
* @return string
*/
public function getIpnHost()
{
if ($this->getPayPalConfig()->isSandboxEnabled()) {
$url = $this->getPayPalSandboxIpnHost();
} else {
$url = $this->getPayPalIpnHost();
}
return $url;
}
/**
* PayPal IPN Url Setter
*
* @param string $payPalUrl
*/
public function setPayPalIpnUrl($payPalIpnUrl)
{
$this->payPalIpnUrl = $payPalIpnUrl;
}
/**
* IPN Url getter
*
* @return string
*/
public function getPayPalIpnUrl()
{
if (empty($this->payPalIpnUrl)) {
$this->payPalIpnUrl = self::OEPAYPAL_IPN_CALLBACK_URL;
}
return $this->payPalIpnUrl;
}
/**
* PayPal sandbox IPN url setter
*
* @param string $payPalSandboxIPNUrl
*/
public function setPayPalSandboxIpnUrl($payPalSandboxIpnUrl)
{
$this->payPalSandboxIpnUrl = $payPalSandboxIpnUrl;
}
/**
* PayPal sandbox IPN url getter
*
* @return string
*/
public function getPayPalSandboxIpnUrl()
{
if (empty($this->payPalSandboxIpnUrl)) {
$this->payPalSandboxIpnUrl = self::OEPAYPAL_SANDBOX_IPN_CALLBACK_URL;
}
return $this->payPalSandboxIpnUrl;
}
/**
* Returns end point url
*
* @return string
*/
public function getIpnUrl()
{
if ($this->getPayPalConfig()->isSandboxEnabled()) {
$url = $this->getPayPalSandboxIpnUrl();
} else {
$url = $this->getPayPalIpnUrl();
}
return $url;
}
/**
* Returns Url for IPN response call to notify PayPal
*
* @return string
*/
public function getIPNResponseUrl()
{
return $this->getIpnUrl() . '&cmd=_notify-validate';
}
/**
* Getter for oepaypal config.
*
* @return \OxidEsales\PayPalModule\Core\Config
*/
protected function getPayPalConfig()
{
if (is_null($this->payPalConfig)) {
$this->payPalConfig = oxNew(\OxidEsales\PayPalModule\Core\Config::class);
}
return $this->payPalConfig;
}
}

View File

@@ -0,0 +1,124 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* Base logger class
*/
class Logger
{
/**
* Logger session id.
*
* @var string
*/
protected $loggerSessionId;
/**
* Log title
*/
protected $logTitle = '';
/**
* Sets logger session id.
*
* @param string $id session id
*/
public function setLoggerSessionId($id)
{
$this->loggerSessionId = $id;
}
/**
* Returns loggers session id.
*
* @return string
*/
public function getLoggerSessionId()
{
return $this->loggerSessionId;
}
/**
* Returns full log file path.
*
* @return string
*/
protected function getLogFilePath()
{
$logDirectoryPath = \OxidEsales\Eshop\Core\Registry::getConfig()->getLogsDir();
return $logDirectoryPath . 'oepaypal.log';
}
/**
* Set log title.
*
* @param string $title Log title
*/
public function setTitle($title)
{
$this->logTitle = $title;
}
/**
* Get title.
*
* @return string
*/
public function getTitle()
{
return $this->logTitle;
}
/**
* Writes log message.
*
* @param mixed $logData logger data
*/
public function log($logData)
{
$handle = fopen($this->getLogFilePath(), "a+");
if ($handle !== false) {
if (is_string($logData)) {
parse_str($logData, $result);
} else {
$result = $logData;
}
if (is_array($result)) {
foreach ($result as $key => $value) {
if (is_string($value)) {
$result[$key] = urldecode($value);
}
}
}
fwrite($handle, "======================= " . $this->getTitle() . " [" . date("Y-m-d H:i:s") . "] ======================= #\n\n");
fwrite($handle, "SESS ID: " . $this->getLoggerSessionId() . "\n");
fwrite($handle, trim(var_export($result, true)) . "\n\n");
fclose($handle);
}
//resetting log title
$this->setTitle('');
}
}

View File

@@ -0,0 +1,185 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* Abstract model class
*/
abstract class Model
{
/**
* Data base gateway.
*
* @var \OxidEsales\PayPalModule\Core\ModelDbGateway
*/
protected $dbGateway = null;
/**
* Model data.
*
* @var array
*/
protected $data = null;
/**
* Was object information found in database.
*
* @var bool
*/
protected $isLoaded = false;
/**
* Set response data.
*
* @param array $data model data
*/
public function setData($data)
{
$data = array_change_key_case($data, CASE_LOWER);
$this->data = $data;
}
/**
* Return response data.
*
* @return array
*/
public function getData()
{
return $this->data;
}
/**
* Return value from data by given key.
*
* @param string $key key of data value
*
* @return string
*/
protected function getValue($key)
{
$data = $this->getData();
return $data[$key];
}
/**
* Return value from data by given key.
*
* @param string $key key of data value
* @param string $value data value
*/
protected function setValue($key, $value)
{
$this->data[$key] = $value;
}
/**
* Returns model database gateway.
*
* @var $dbGateway
*/
abstract protected function getDbGateway();
/**
* Set model database gateway.
*
* @param \OxidEsales\PayPalModule\Core\ModelDbGateway $dbGateway
*/
protected function setDbGateway($dbGateway)
{
$this->dbGateway = $dbGateway;
}
/**
* Method for model saving (insert and update data).
*
* @return int|false
*/
public function save()
{
$id = $this->getDbGateway()->save($this->getData());
$this->setId($id);
return $id;
}
/**
* Delete model data from db.
*
* @param string $id model id
*
* @return bool
*/
public function delete($id = null)
{
if (!is_null($id)) {
$this->setId($id);
}
return $this->getDbGateway()->delete($this->getId());
}
/**
* Method for loading model, if loaded returns true.
*
* @param string $id model id
*
* @return bool
*/
public function load($id = null)
{
if (!is_null($id)) {
$this->setId($id);
}
$this->isLoaded = false;
$data = $this->getDbGateway()->load($this->getId());
if ($data) {
$this->setData($data);
$this->isLoaded = true;
}
return $this->isLoaded();
}
/**
* Returns whether object information found in database.
*
* @return bool
*/
public function isLoaded()
{
return $this->isLoaded;
}
/**
* Abstract method for delete model.
*
* @param string $id model id
*/
abstract public function setId($id);
/**
* Abstract method for getting id.
*/
abstract public function getId();
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* Abstract model db gateway class.
*
* @todo: maybe this class lives better in the \OxidEsales\PayPalModule\Model namespace as DbGateway?!
*/
abstract class ModelDbGateway
{
/**
* Returns data base resource.
*
* @return \OxidEsales\Eshop\Core\Database\Adapter\DatabaseInterface
*/
protected function getDb()
{
return \OxidEsales\Eshop\Core\DatabaseProvider::getDb(\OxidEsales\Eshop\Core\DatabaseProvider::FETCH_MODE_ASSOC);
}
/**
* Abstract method for data saving (insert and update).
*
* @param array $data model data
*/
abstract public function save($data);
/**
* Abstract method for loading model data.
*
* @param string $id model id
*/
abstract public function load($id);
/**
* Abstract method for delete model data.
*
* @param string $id model id
*/
abstract public function delete($id);
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* Validates changed basket amount. Checks if it is bigger than previous price.
* Than returns false to recheck new basket amount in PayPal.
*/
class PayPalCheckValidator
{
/**
* Basket new amount
*
* @var double
*/
protected $newBasketAmount = null;
/**
* Basket old amount
*
* @var double
*/
protected $oldBasketAmount = null;
/**
* Returns if order should be rechecked by PayPal
*
* @return bool
*/
public function isPayPalCheckValid()
{
$newBasketAmount = $this->getNewBasketAmount();
$prevBasketAmount = $this->getOldBasketAmount();
// check only if new price is different and bigger than old price
if ($newBasketAmount > $prevBasketAmount) {
return false;
}
return true;
}
/**
* Sets new basket amount
*
* @param double $newBasketAmount changed basket amount
*/
public function setNewBasketAmount($newBasketAmount)
{
$this->newBasketAmount = $newBasketAmount;
}
/**
* Returns new basket amount
*
* @return double
*/
public function getNewBasketAmount()
{
return (float) $this->newBasketAmount;
}
/**
* Sets old basket amount
*
* @param double $oldBasketAmount old basket amount
*/
public function setOldBasketAmount($oldBasketAmount)
{
$this->oldBasketAmount = $oldBasketAmount;
}
/**
* Returns old basket amount
*
* @return double
*/
public function getOldBasketAmount()
{
return (float) $this->oldBasketAmount;
}
}

View File

@@ -0,0 +1,206 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
use Countable;
use Iterator;
/**
* List manager class.
*/
class PayPalList implements Iterator, Countable
{
/**
* Array of objects (some object list).
*
* @var array $_aArray
*/
protected $array = array();
/**
* Save the state, that active element was unset
* needed for proper foreach iterator functionality.
*
* @var bool $_blRemovedActive
*/
protected $removedActive = false;
/**
* Flag if array is ok or not.
*
* @var boolean $_blValid
*/
private $valid = true;
/**
* -----------------------------------------------------------------------------------------------------
*
* Implementation of SPL Array classes functions follows here
*
* -----------------------------------------------------------------------------------------------------
*/
/**
* Returns SPL array keys.
*
* @return array
*/
public function arrayKeys()
{
return array_keys($this->array);
}
/**
* Rewind for SPL.
*/
public function rewind()
{
$this->removedActive = false;
$this->valid = (false !== reset($this->array));
}
/**
* Current for SPL.
*
* @return mixed
*/
public function current()
{
return current($this->array);
}
/**
* Key for SPL.
*
* @return mixed
*/
public function key()
{
return key($this->array);
}
/**
* Previous / first array element.
*
* @return mixed
*/
public function prev()
{
$var = prev($this->array);
if ($var === false) {
// the first element, reset pointer
$var = reset($this->array);
}
$this->removedActive = false;
return $var;
}
/**
* Next for SPL.
*/
public function next()
{
if ($this->removedActive === true && current($this->array)) {
$var = $this->prev();
} else {
$var = next($this->array);
}
$this->valid = (false !== $var);
}
/**
* Valid for SPL.
*
* @return boolean
*/
public function valid()
{
return $this->valid;
}
/**
* Count for SPL.
*
* @return integer
*/
public function count()
{
return count($this->array);
}
/**
* Clears/destroys list contents.
*/
public function clear()
{
$this->array = array();
}
/**
* copies a given array over the objects internal array (something like old $myList->aList = $array).
*
* @param array $array array of list items
*/
public function setArray($array)
{
$this->array = $array;
}
/**
* Returns the array reversed, the internal array remains untouched.
*
* @return array
*/
public function reverse()
{
return array_reverse($this->array);
}
/**
* -----------------------------------------------------------------------------------------------------
* SPL implementation end
* -----------------------------------------------------------------------------------------------------
*/
/**
* Backward compatibility method.
*
* @param string $name Variable name
*
* @return mixed
*/
public function __get($name)
{
return $this->array;
}
/**
* Returns list items array.
*
* @return array
*/
public function getArray()
{
return $this->array;
}
}

View File

@@ -0,0 +1,327 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* PayPal Service class
*/
class PayPalService
{
/**
* PayPal Caller
*
* @var \OxidEsales\PayPalModule\Core\Caller
*/
protected $caller = null;
/**
* PayPal Caller.
*
* @var \OxidEsales\PayPalModule\Core\Config
*/
protected $payPalConfig = null;
/**
* PayPal IPN config.
*
* @var \OxidEsales\PayPalModule\Core\IpnConfig
*/
protected $payPalIpnConfig = null;
/**
* PayPal config setter.
*
* @param \OxidEsales\PayPalModule\Core\Config $payPalConfig
*/
public function setPayPalConfig($payPalConfig)
{
$this->payPalConfig = $payPalConfig;
}
/**
* PayPal config getter.
*
* @return \OxidEsales\PayPalModule\Core\Config
*/
public function getPayPalConfig()
{
if (is_null($this->payPalConfig)) {
$this->setPayPalConfig(oxNew(\OxidEsales\PayPalModule\Core\Config::class));
}
return $this->payPalConfig;
}
/**
* PayPal Ipn config setter.
*
* @param \OxidEsales\PayPalModule\Core\IpnConfig $payPalIpnConfig
*/
public function setPayPalIpnConfig($payPalIpnConfig)
{
$this->payPalIpnConfig = $payPalIpnConfig;
}
/**
* PayPal config getter.
*
* @return \OxidEsales\PayPalModule\Core\IpnConfig
*/
public function getPayPalIpnConfig()
{
if (is_null($this->payPalIpnConfig)) {
$this->setPayPalIPnConfig(oxNew(\OxidEsales\PayPalModule\Core\IpnConfig::class));
}
return $this->payPalIpnConfig;
}
/**
* PayPal caller setter.
*
* @param \OxidEsales\PayPalModule\Core\Caller $caller
*/
public function setCaller($caller)
{
$this->caller = $caller;
}
/**
* PayPal caller getter.
*
* @return \OxidEsales\PayPalModule\Core\Caller
*/
public function getCaller()
{
if (is_null($this->caller)) {
/**
* @var \OxidEsales\PayPalModule\Core\Caller $caller
*/
$caller = oxNew(\OxidEsales\PayPalModule\Core\Caller::class);
$config = $this->getPayPalConfig();
$caller->setParameter('VERSION', '84.0');
$caller->setParameter('PWD', $config->getPassword());
$caller->setParameter('USER', $config->getUserName());
$caller->setParameter('SIGNATURE', $config->getSignature());
$curl = oxNew(\OxidEsales\PayPalModule\Core\Curl::class);
$curl->setDataCharset($config->getCharset());
$curl->setHost($config->getHost());
$curl->setUrlToCall($config->getApiUrl());
$caller->setCurl($curl);
if ($config->isLoggingEnabled()) {
$logger = oxNew(\OxidEsales\PayPalModule\Core\Logger::class);
$logger->setLoggerSessionId(\OxidEsales\Eshop\Core\Registry::getSession()->getId());
$caller->setLogger($logger);
}
$this->setCaller($caller);
}
return $this->caller;
}
/**
* Executes "SetExpressCheckout". Returns response object from PayPal.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
*
* @return \OxidEsales\PayPalModule\Model\Response\ResponseSetExpressCheckout
*/
public function setExpressCheckout($request)
{
$caller = $this->getCaller();
$caller->setRequest($request);
$response = oxNew(\OxidEsales\PayPalModule\Model\Response\ResponseSetExpressCheckout::class);
$response->setData($caller->call('SetExpressCheckout'));
return $response;
}
/**
* Executes "GetExpressCheckoutDetails". Returns response object from PayPal.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
*
* @return \OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails
*/
public function getExpressCheckoutDetails($request)
{
$caller = $this->getCaller();
$caller->setRequest($request);
$response = oxNew(\OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails::class);
$response->setData($caller->call('GetExpressCheckoutDetails'));
return $response;
}
/**
* Executes "DoExpressCheckoutPayment". Returns response object from PayPal.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
*
* @return \OxidEsales\PayPalModule\Model\Response\ResponseDoExpressCheckoutPayment
*/
public function doExpressCheckoutPayment($request)
{
$caller = $this->getCaller();
$caller->setRequest($request);
$response = oxNew(\OxidEsales\PayPalModule\Model\Response\ResponseDoExpressCheckoutPayment::class);
$response->setData($caller->call('DoExpressCheckoutPayment'));
return $response;
}
/**
* Executes PayPal callback request
*
* @return string
*/
public function callbackResponse()
{
// cleanup
$this->getCaller()->setParameter("VERSION", null);
$this->getCaller()->setParameter("PWD", null);
$this->getCaller()->setParameter("USER", null);
$this->getCaller()->setParameter("SIGNATURE", null);
return $this->getCaller()->getCallBackResponse("CallbackResponse");
}
/**
* Executes "DoVoid". Returns response array from PayPal
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
*
* @return \OxidEsales\PayPalModule\Model\Response\Response
*/
public function doVoid($request)
{
$caller = $this->getCaller();
$caller->setRequest($request);
$response = oxNew(\OxidEsales\PayPalModule\Model\Response\ResponseDoVoid::class);
$response->setData($caller->call('DoVoid'));
return $response;
}
/**
* Executes "RefundTransaction". Returns response array from PayPal
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
*
* @return \OxidEsales\PayPalModule\Model\Response\Response
*/
public function refundTransaction($request)
{
$caller = $this->getCaller();
$caller->setRequest($request);
$response = oxNew(\OxidEsales\PayPalModule\Model\Response\ResponseDoRefund::class);
$response->setData($caller->call('RefundTransaction'));
return $response;
}
/**
* Executes "DoCapture". Returns response array from PayPal
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request request
*
* @return \OxidEsales\PayPalModule\Model\Response\Response
*/
public function doCapture($request)
{
$caller = $this->getCaller();
$caller->setRequest($request);
$response = oxNew(\OxidEsales\PayPalModule\Model\Response\ResponseDoCapture::class);
$response->setData($caller->call('DoCapture'));
return $response;
}
/**
* Executes "DoReauthorization". Returns response array from PayPal.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
*
* @return \OxidEsales\PayPalModule\Model\Response\Response
*/
public function doReAuthorization($request)
{
$caller = $this->getCaller();
$caller->setRequest($request);
$response = oxNew(\OxidEsales\PayPalModule\Model\Response\ResponseDoReAuthorize::class);
$response->setData($caller->call('DoReauthorization'));
return $response;
}
/**
* Executes call to PayPal IPN.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
* @param string $charset
*
* @return \OxidEsales\PayPalModule\Model\Response\Response
*/
public function doVerifyWithPayPal($request, $charset)
{
$caller = $this->getCaller();
$caller->setRequest($request);
$caller = $this->getCaller();
$curl = $caller->getCurl();
$curl->setConnectionCharset($charset);
$curl->setDataCharset($charset);
$curl->setHost($this->getPayPalIpnConfig()->getIpnHost());
$curl->setUrlToCall($this->getPayPalIpnConfig()->getIPNResponseUrl());
$response = oxNew(\OxidEsales\PayPalModule\Model\Response\ResponseDoVerifyWithPayPal::class);
$response->setData($caller->call());
return $response;
}
/**
* Set parameter to caller by it's key.
*
* @param string $key
* @param string $value
*
* @deprecated still use in callback.
*/
public function setParameter($key, $value)
{
$this->getCaller()->setParameter($key, $value);
}
}

View File

@@ -0,0 +1,141 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* PayPal Request class
*/
class Request
{
/**
* Get post.
*
* @return array
*/
public function getPost()
{
$post = array();
if (!empty($_POST)) {
$post = $_POST;
}
return $post;
}
/**
* Get get.
*
* @return array
*/
public function getGet()
{
$get = array();
if (!empty($_GET)) {
$get = $_GET;
}
return $get;
}
/**
* Returns value of parameter stored in POST,GET.
*
* @param string $name Name of parameter
* @param bool $raw mark to return not escaped parameter
*
* @return mixed
*/
public function getRequestParameter($name, $raw = false)
{
$value = null;
$value = $this->getPostParameter($name, $raw);
if (!isset($value)) {
$value = $this->getGetParameter($name, $raw);
}
return $value;
}
/**
* Returns value of parameter stored in POST.
*
* @param string $name Name of parameter
* @param bool $raw mark to return not escaped parameter
*
* @return mixed
*/
public function getPostParameter($name, $raw = false)
{
$value = null;
$post = $this->getPost();
if (isset($post[$name])) {
$value = $post[$name];
}
if ($value !== null && !$raw) {
$value = $this->escapeSpecialChars($value);
}
return $value;
}
/**
* Returns value of parameter stored in GET.
*
* @param string $name Name of parameter
* @param bool $raw mark to return not escaped parameter
*
* @return mixed
*/
public function getGetParameter($name, $raw = false)
{
$value = null;
$get = $this->getGet();
if (isset($get[$name])) {
$value = $get[$name];
}
if ($value !== null && !$raw) {
$value = $this->escapeSpecialChars($value);
}
return $value;
}
/**
* Wrapper for PayPal escape class.
*
* @param mixed $value value to escape
*
* @return mixed
*/
public function escapeSpecialChars($value)
{
$payPalEscape = oxNew(\OxidEsales\PayPalModule\Core\Escape::class);
return $payPalEscape->escapeSpecialChars($value);
}
}

View File

@@ -0,0 +1,386 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* PayPal shop logo class.
*/
class ShopLogo
{
/**
* Suffix for image resizing.
*
* @var string
*/
protected $_suffix = "resized_";
/**
* Image directory to work in.
*
* @var string
*/
protected $imageDir = null;
/**
* Image directory to work in.
*
* @var string
*/
protected $imageDirUrl = null;
/**
* Image name.
*
* @var string
*/
protected $imageName = null;
/**
* Path to an image, not null only when it exists.
*
* @var string
*/
protected $imagePath = null;
/**
* Image maximum width.
*
* @var int
*/
protected $width = 190;
/**
* Image maximum height.
*
* @var int
*/
protected $height = 160;
/**
* Provided image handler.
*
* @var \OxidEsales\Eshop\Core\UtilsPic
*/
protected $imageHandler = null;
/**
* Set image handler to handle images.
* Needs to have resizeImage method.
*
* @param \OxidEsales\Eshop\Core\UtilsPic $imageHandler
*/
public function setImageHandler($imageHandler)
{
$this->imageHandler = $imageHandler;
}
/**
* Returns image handler object.
*
* @return object|oxUtilsPic
*/
public function getImageHandler()
{
return $this->imageHandler;
}
/**
* Sets image maximum width.
*
* @param int $width
*/
public function setWidth($width)
{
$this->width = $width;
}
/**
* Return image maximum width.
*
* @return int
*/
public function getWidth()
{
return $this->width;
}
/**
* Sets image maximum height.
*
* @param int $height
*/
public function setHeight($height)
{
$this->height = $height;
}
/**
* Return image maximum height.
*
* @return int
*/
public function getHeight()
{
return $this->height;
}
/**
* Calculates if logo should be resized.
*
* @return bool
*/
protected function getResize()
{
$resize = false;
$imagePath = $this->getImagePath();
if ($imagePath) {
$imageSize = $this->getImageSize($imagePath);
if ($imageSize['width'] > $this->getWidth() ||
$imageSize['height'] > $this->getHeight()
) {
$resize = true;
}
}
return $resize;
}
/**
* Sets image directory.
*
* @param string $imagePath
*/
public function setImageDir($imagePath)
{
$this->imageDir = $imagePath;
}
/**
* Returns image directory.
*
* @return string
*/
public function getImageDir()
{
return $this->imageDir;
}
/**
* Set image directory URL.
*
* @param string $imageDirUrl
*/
public function setImageDirUrl($imageDirUrl)
{
$this->imageDirUrl = $imageDirUrl;
}
/**
* Getter for image directory URL.
*
* @return string
*/
public function getImageDirUrl()
{
return $this->imageDirUrl;
}
/**
* Set name of an image.
*
* @param string $imageName
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
}
/**
* Get name of an image.
*
* @return string
*/
public function getImageName()
{
return $this->imageName;
}
/**
* Gives new name for image to be resized.
*
* @return string
*/
protected function getResizedImageName()
{
$resizedImageName = "";
if ($this->getImageName()) {
$resizedImageName = $this->_suffix . $this->getImageName();
}
return $resizedImageName;
}
/**
* Returns path to an image.
*
* @return string
*/
protected function getImagePath()
{
if (null == $this->imagePath) {
$dir = $this->getImageDir();
$name = $this->getImageName();
if ($dir && $name && $this->fileExists($dir . $name)) {
$this->imagePath = $dir . $name;
}
}
return $this->imagePath;
}
/**
* Returns path to an image.
*
* @return string
*/
protected function getImageUrl()
{
$imageUrl = "";
if ($this->getImagePath()) {
$imageUrl = $this->getImageDirUrl() . $this->getImageName();
}
return $imageUrl;
}
/**
* Returns resized image path.
*
* @return string
*/
protected function getResizedImagePath()
{
$resizedImagePath = "";
$dir = $this->getImageDir();
$name = $this->getResizedImageName();
if ($dir && $name) {
$resizedImagePath = $dir . $name;
}
return $resizedImagePath;
}
/**
* Returns resized image path.
*
* @return string
*/
protected function getResizedImageUrl()
{
$imageUrl = "";
if ($this->getResizedImagePath()) {
$imageUrl = $this->getImageDirUrl() . $this->getResizedImageName();
}
return $imageUrl;
}
/**
* Get logo image path for PayPal express checkout.
*
* @return string
*/
public function getShopLogoUrl()
{
$imagePath = $this->getImageUrl();
$resizedImagePath = $this->getResizedImageUrl();
if ($this->getResize()) {
$shopLogoPath = $resizedImagePath;
if (!$this->fileExists($resizedImagePath)) {
if (!$this->resizeImage()) {
// fallback to original image if can not be resized
$shopLogoPath = $imagePath;
}
}
} else {
$shopLogoPath = $imagePath;
}
return $shopLogoPath;
}
/**
* Checks if given image file exists.
*
* @param string $path
*
* @return bool
*/
protected function fileExists($path)
{
return file_exists($path);
}
/**
* Returns array with width and height of given image
*
* @param string $imagePath
*
* @return array
*/
protected function getImageSize($imagePath)
{
$imageSize = getimagesize($imagePath);
return array(
'width' => $imageSize[0],
'height' => $imageSize[1]
);
}
/**
* Resizes logo if needed to the size provided
* Returns false when image does'nt exist, or can't be resized
* Returns original image name when image is within boundaries
* Returns resized image name when image is too large than defined
*
* @return bool
*/
protected function resizeImage()
{
$resized = false;
if ($utilsPic = $this->getImageHandler()) {
// checks if image can be resized, and resizes the image
if ($utilsPic->resizeImage($this->getImagePath(), $this->getResizedImagePath(), $this->getWidth(), $this->getHeight())) {
$resized = true;
}
}
return $resized;
}
}

View File

@@ -0,0 +1,102 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
/**
* Class for User Agent.
*
* @package core
*/
class UserAgent
{
/**
* Detected device type
*
* @var string
*/
protected $deviceType = null;
/**
* Mobile device types.
*
* @var string
*/
protected $mobileDevicesTypes = 'iphone|ipod|android|webos|htc|fennec|iemobile|blackberry|symbianos|opera mobi';
/**
* Function returns all supported mobile devices types.
*
* @return string
*/
public function getMobileDeviceTypes()
{
return $this->mobileDevicesTypes;
}
/**
* Returns device type: mobile | desktop.
*
* @return string
*/
public function getDeviceType()
{
if ($this->deviceType === null) {
$this->setDeviceType($this->detectDeviceType());
}
return $this->deviceType;
}
/**
* Set device type.
*
* @param string $deviceType
*/
public function setDeviceType($deviceType)
{
$this->deviceType = $deviceType;
}
/**
* Set mobile device types.
*
* @param string $mobileDeviceTypes
*/
public function setMobileDeviceTypes($mobileDeviceTypes)
{
$this->mobileDevicesTypes = $mobileDeviceTypes;
}
/**
* Detects device type from global variable. Device types: mobile, desktop.
*
* @return string
*/
protected function detectDeviceType()
{
$deviceType = 'desktop';
if (preg_match('/(' . $this->getMobileDeviceTypes() . ')/is', $_SERVER['HTTP_USER_AGENT'])) {
$deviceType = 'mobile';
}
return $deviceType;
}
}

View File

@@ -0,0 +1,446 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Core;
use OxidEsales\Eshop\Core\Registry;
/**
* ViewConfig class wrapper for PayPal module.
*
* @mixin \OxidEsales\Eshop\Core\ViewConfig
*/
class ViewConfig extends ViewConfig_parent
{
/** @var null \OxidEsales\PayPalModule\Core\Config */
protected $payPalConfig = null;
/**
* PayPal payment object.
*
* @var \OxidEsales\Eshop\Application\Model\Payment|bool
*/
protected $payPalPayment = null;
/**
* Status if Express checkout is ON.
*
* @var bool
*/
protected $expressCheckoutEnabled = null;
/**
* Status if Standard checkout is ON.
*
* @var bool
*/
protected $standardCheckoutEnabled = null;
/**
* Status if PayPal is ON.
*
* @var bool
*/
protected $payPalEnabled = null;
/**
* PayPal Payment Validator object.
*
* @var \OxidEsales\PayPalModule\Model\PaymentValidator
*/
protected $paymentValidator = null;
/**
* Set \OxidEsales\PayPalModule\Model\PaymentValidator.
*
* @param \OxidEsales\PayPalModule\Model\PaymentValidator $paymentValidator
*/
public function setPaymentValidator($paymentValidator)
{
$this->paymentValidator = $paymentValidator;
}
/**
* Get \OxidEsales\PayPalModule\Model\PaymentValidator. Create new if does not exist.
*
* @return \OxidEsales\PayPalModule\Model\PaymentValidator
*/
public function getPaymentValidator()
{
if (is_null($this->paymentValidator)) {
$this->setPaymentValidator(oxNew(\OxidEsales\PayPalModule\Model\PaymentValidator::class));
}
return $this->paymentValidator;
}
/**
* Returns TRUE if express checkout is enabled.
* Does payment amount or user country/group check.
*
* @return bool
*/
public function isExpressCheckoutEnabled()
{
if ($this->expressCheckoutEnabled === null) {
$this->expressCheckoutEnabled = false;
if ($this->getPayPalConfig()->isExpressCheckoutEnabled()) {
$user = $this->getUser();
$validator = $this->getPaymentValidator();
$validator->setUser($user);
$validator->setConfig(\OxidEsales\Eshop\Core\Registry::getConfig());
$validator->setCheckCountry(false);
$this->expressCheckoutEnabled = $validator->isPaymentValid();
}
}
return $this->expressCheckoutEnabled;
}
/**
* Returns TRUE if express checkout and displaying it in mini basket is enabled.
*
* @return bool
*/
public function isExpressCheckoutEnabledInMiniBasket()
{
$expressCheckoutEnabledInMiniBasket = false;
if ($this->isExpressCheckoutEnabled() && $this->getPayPalConfig()->isExpressCheckoutInMiniBasketEnabled()) {
$expressCheckoutEnabledInMiniBasket = true;
}
return $expressCheckoutEnabledInMiniBasket;
}
/**
* Returns TRUE if express checkout is enabled.
* Does payment amount or user country/group check.
*
* @return bool
*/
public function isExpressCheckoutEnabledInDetails()
{
$expressCheckoutEnabledInDetails = false;
if ($this->isExpressCheckoutEnabled() && $this->getPayPalConfig()->isExpressCheckoutInDetailsPage()) {
$expressCheckoutEnabledInDetails = true;
}
return $expressCheckoutEnabledInDetails;
}
/**
* Returns TRUE if standard checkout is enabled.
* Does payment amount or user country/group check.
*
* @return bool
*/
public function isStandardCheckoutEnabled()
{
if ($this->standardCheckoutEnabled === null) {
$this->standardCheckoutEnabled = false;
if ($this->getPayPalConfig()->isStandardCheckoutEnabled()) {
$user = $this->getUser();
$validator = $this->getPaymentValidator();
$validator->setUser($user);
$validator->setConfig(\OxidEsales\Eshop\Core\Registry::getConfig());
$this->standardCheckoutEnabled = $validator->isPaymentValid();
}
}
return $this->standardCheckoutEnabled;
}
/**
* Checks if PayPal standard or express checkout is enabled.
* Does not do payment amount or user country/group check.
*
* @return bool
*/
public function isPayPalActive()
{
return $this->getPaymentValidator()->isPaymentActive();
}
/**
* Returns PayPal payment description text.
*
* @return string
*/
public function getPayPalPaymentDescription()
{
$desc = "";
if (($payPalPayment = $this->getPayPalPayment())) {
$desc = $payPalPayment->oxpayments__oxlongdesc->getRawValue();
}
return $desc;
}
/**
* Returns PayPal payment object.
*
* @return \OxidEsales\Eshop\Application\Model\Payment
*/
public function getPayPalPayment()
{
if ($this->payPalPayment === null) {
$this->payPalPayment = false;
$payPalPayment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
// payment is not available/active?
if ($payPalPayment->load("oxidpaypal") && $payPalPayment->oxpayments__oxactive->value) {
$this->payPalPayment = $payPalPayment;
}
}
return $this->payPalPayment;
}
/**
* Returns state if order info should be send to PayPal.
*
* @return bool
*/
public function sendOrderInfoToPayPal()
{
$sendInfoToPayPalEnabled = $this->getPayPalConfig()->sendOrderInfoToPayPal();
if ($sendInfoToPayPalEnabled) {
/** @var \OxidEsales\PayPalModule\Model\Basket $basket */
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$basket = $session->getBasket();
$sendInfoToPayPalEnabled = !$basket->isFractionQuantityItemsPresent();
}
return $sendInfoToPayPalEnabled;
}
/**
* Returns default (on/off) state if order info should be send to PayPal.
*
* @return bool
*/
public function sendOrderInfoToPayPalDefault()
{
return $this->getPayPalConfig()->sendOrderInfoToPayPalDefault();
}
/**
* Returns PayPal config.
*
* @return \OxidEsales\PayPalModule\Core\Config
*/
protected function getPayPalConfig()
{
if (is_null($this->payPalConfig)) {
$this->payPalConfig = oxNew(\OxidEsales\PayPalModule\Core\Config::class);
}
return $this->payPalConfig;
}
/**
* Returns current URL.
*
* @return string
*/
public function getCurrentUrl()
{
return $this->getPayPalConfig()->getCurrentUrl();
}
/**
* @return string
*/
public function getPayPalClientId(): string
{
return Registry::getConfig()->getConfigParam('oePayPalClientId');
}
/**
* Returns whether PayPal banners should be shown on the start page
*
* @return bool
*/
public function showPayPalBannerOnStartPage()
{
$config = Registry::getConfig();
return (
!$config->getConfigParam('oePayPalBannersHideAll') &&
$config->getConfigParam('oePayPalBannersStartPage') &&
$config->getConfigParam('oePayPalBannersStartPageSelector') &&
$config->getConfigParam('bl_perfLoadPrice')
);
}
/**
* Returns PayPal banners selector for the start page
*
* @return string
*/
public function getPayPalBannerStartPageSelector()
{
$config = Registry::getConfig();
return $config->getConfigParam('oePayPalBannersStartPageSelector');
}
/**
* Returns whether PayPal banners should be shown on the category page
*
* @return bool
*/
public function showPayPalBannerOnCategoryPage()
{
$config = Registry::getConfig();
return (
!$config->getConfigParam('oePayPalBannersHideAll') &&
$config->getConfigParam('oePayPalBannersCategoryPage') &&
$config->getConfigParam('oePayPalBannersCategoryPageSelector') &&
$config->getConfigParam('bl_perfLoadPrice')
);
}
/**
* Returns PayPal banners selector for the category page
*
* @return string
*/
public function getPayPalBannerCategoryPageSelector()
{
$config = Registry::getConfig();
return $config->getConfigParam('oePayPalBannersCategoryPageSelector');
}
/**
* Returns whether PayPal banners should be shown on the search results page
*
* @return bool
*/
public function showPayPalBannerOnSearchResultsPage()
{
$config = Registry::getConfig();
return (
!$config->getConfigParam('oePayPalBannersHideAll') &&
$config->getConfigParam('oePayPalBannersSearchResultsPage') &&
$config->getConfigParam('oePayPalBannersSearchResultsPageSelector') &&
$config->getConfigParam('bl_perfLoadPrice')
);
}
/**
* Returns PayPal banners selector for the search page
*
* @return string
*/
public function getPayPalBannerSearchPageSelector()
{
$config = Registry::getConfig();
return $config->getConfigParam('oePayPalBannersSearchResultsPageSelector');
}
/**
* Returns whether PayPal banners should be shown on the product details page
*
* @return bool
*/
public function showPayPalBannerOnProductDetailsPage()
{
$config = Registry::getConfig();
return (
!$config->getConfigParam('oePayPalBannersHideAll') &&
$config->getConfigParam('oePayPalBannersProductDetailsPage') &&
$config->getConfigParam('oePayPalBannersProductDetailsPageSelector') &&
$config->getConfigParam('bl_perfLoadPrice')
);
}
/**
* Returns PayPal banners selector for the product detail page
*
* @return string
*/
public function getPayPalBannerProductDetailsPageSelector()
{
$config = Registry::getConfig();
return $config->getConfigParam('oePayPalBannersProductDetailsPageSelector');
}
/**
* Returns whether PayPal banners should be shown on the checkout page
*
* @return bool
*/
public function showPayPalBannerOnCheckoutPage()
{
$showBanner = false;
$actionClassName = $this->getActionClassName();
$config = Registry::getConfig();
if ($actionClassName === 'basket') {
$showBanner = (
!$config->getConfigParam('oePayPalBannersHideAll') &&
$config->getConfigParam('oePayPalBannersCheckoutPage') &&
$config->getConfigParam('oePayPalBannersCartPageSelector') &&
$config->getConfigParam('bl_perfLoadPrice')
);
} elseif ($actionClassName === 'payment') {
$showBanner = (
!$config->getConfigParam('oePayPalBannersHideAll') &&
$config->getConfigParam('oePayPalBannersCheckoutPage') &&
$config->getConfigParam('oePayPalBannersPaymentPageSelector') &&
$config->getConfigParam('bl_perfLoadPrice')
);
}
return $showBanner;
}
/**
* Returns PayPal banners selector for the cart page
*
* @return string
*/
public function getPayPalBannerCartPageSelector()
{
$config = Registry::getConfig();
return $config->getConfigParam('oePayPalBannersCartPageSelector');
}
/**
* Returns PayPal banners selector for the payment page
*
* @return string
*/
public function getPayPalBannerPaymentPageSelector()
{
$config = Registry::getConfig();
return $config->getConfigParam('oePayPalBannersPaymentPageSelector');
}
/**
* Returns the PayPal banners colour scheme
*
* @return string
*/
public function getPayPalBannersColorScheme()
{
return Registry::getConfig()->getConfigParam('oePayPalBannersColorScheme');
}
}

View File

@@ -0,0 +1,135 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Controller;
use OxidEsales\GraphQL\Storefront\Basket\Service\Basket as StorefrontBasketService;
use OxidEsales\PayPalModule\GraphQL\DataType\PayPalCommunicationInformation;
use OxidEsales\PayPalModule\GraphQL\DataType\PayPalTokenStatus;
use OxidEsales\PayPalModule\GraphQL\Exception\GraphQLServiceNotFound;
use OxidEsales\PayPalModule\GraphQL\Service\Basket as BasketService;
use OxidEsales\PayPalModule\GraphQL\Service\Payment as PaymentService;
use TheCodingMachine\GraphQLite\Annotations\Logged;
use TheCodingMachine\GraphQLite\Annotations\Query;
use TheCodingMachine\GraphQLite\Annotations\Right;
use TheCodingMachine\GraphQLite\Types\ID;
final class Payment
{
/** @var PaymentService */
private $paymentService;
/** @var BasketService */
private $basketService;
/** @var StorefrontBasketService */
private $storefrontBasketService;
public function __construct(
PaymentService $paymentService,
BasketService $basketService,
StorefrontBasketService $storefrontBasketService = null
) {
$this->paymentService = $paymentService;
$this->basketService = $basketService;
$this->storefrontBasketService = $storefrontBasketService;
}
/**
* @Query
* @Logged()
*/
public function paypalApprovalProcess(
ID $basketId,
string $returnUrl,
string $cancelUrl,
bool $displayBasketInPayPal
): PayPalCommunicationInformation {
$this->validateState();
$basket = $this->storefrontBasketService->getAuthenticatedCustomerBasket($basketId);
// validate if basket payment method is correct
$this->basketService->validateBasketPaymentMethod($basket);
$communicationInformation = $this->paymentService->getPayPalCommunicationInformation(
$basket,
$returnUrl,
$cancelUrl,
$displayBasketInPayPal
);
$this->basketService->updateBasketToken($basket, $communicationInformation->getToken());
return $communicationInformation;
}
/**
* @Query
* @Right("PAYPAL_EXPRESS_APPROVAL")
*/
public function paypalExpressApprovalProcess(
ID $basketId,
string $returnUrl,
string $cancelUrl,
bool $displayBasketInPayPal
): PayPalCommunicationInformation
{
$this->validateState();
$basket = $this->storefrontBasketService->getAuthenticatedCustomerBasket($basketId);
// validate if pp express payment is available
$this->basketService->validateBasketExpressPaymentMethod();
$communicationInformation = $this->paymentService->getPayPalExpressCommunicationInformation(
$basket,
$returnUrl,
$cancelUrl,
$displayBasketInPayPal
);
$this->basketService->updateExpressBasketInformation(
$basket,
$communicationInformation->getToken()
);
return $communicationInformation;
}
/**
* @Query()
* @Right("PAYPAL_TOKEN_STATUS")
*/
public function paypalTokenStatus(string $paypalToken): PayPalTokenStatus
{
return $this->paymentService->getPayPalTokenStatus($paypalToken);
}
protected function validateState(): void
{
if (is_null($this->storefrontBasketService)) {
throw GraphQLServiceNotFound::byServiceName(StorefrontBasketService::class);
}
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\DataType;
use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;
/**
* @Type()
*/
final class PayPalCommunicationInformation
{
/** @var string */
private $token;
/** @var string */
private $communicationUrl;
public function __construct(string $token, string $communicationUrl)
{
$this->token = $token;
$this->communicationUrl = $communicationUrl;
}
/**
* @Field()
*/
public function getToken(): string
{
return $this->token;
}
/**
* @Field()
*/
public function getCommunicationUrl(): string
{
return $this->communicationUrl;
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\DataType;
use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;
/**
* @Type()
*/
final class PayPalTokenStatus
{
/** @var string */
private $token;
/** @var bool */
private $status;
/** @var string */
private $payerId;
public function __construct(string $token, bool $status, string $payerId)
{
$this->token = $token;
$this->status = $status;
$this->payerId = $payerId;
}
/**
* @Field()
*/
public function getToken(): string
{
return $this->token;
}
/**
* @Field()
*/
public function isTokenApproved(): bool
{
return $this->status;
}
// for internal user only
public function getPayerId(): string
{
return $this->payerId;
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Exception;
use OxidEsales\GraphQL\Base\Exception\InvalidRequest;
final class BasketCommunication extends InvalidRequest
{
public static function notStarted(string $basketId): self
{
return new self(sprintf("PayPal communication for basket %s is not started", $basketId));
}
public static function notConfirmed(string $basketId): self
{
return new self(sprintf("PayPal communication for basket %s is not confirmed", $basketId));
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Exception;
use OxidEsales\GraphQL\Base\Exception\InvalidRequest;
final class BasketValidation extends InvalidRequest
{
public static function basketChange(string $basketId): self
{
return new self(sprintf("Content change discovered for basket %s. Please run paypal approval process again.", $basketId));
}
public static function basketAddressChange(string $basketId): self
{
return new self(sprintf("Address change discovered for basket %s. Please run paypal approval process again.", $basketId));
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Exception;
use Exception;
final class GraphQLServiceNotFound extends Exception
{
public static function byServiceName(string $name): self
{
return new self(sprintf("GraphQL service %s is not available.", $name));
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Exception;
use OxidEsales\GraphQL\Base\Exception\InvalidRequest;
final class PaymentValidation extends InvalidRequest
{
public static function paymentMethodIsNotPaypal(): self
{
return new self('Payment method should be PayPal.');
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Infrastructure;
use OxidEsales\PayPalModule\Core\Config as PayPalConfig;
use OxidEsales\PayPalModule\Core\PayPalService;
use OxidEsales\PayPalModule\Model\PaymentManager;
final class Request
{
public function getPaymentManager(): PaymentManager
{
$payPalCheckoutService = oxNew(PayPalService::class);
return oxNew(PaymentManager::class, $payPalCheckoutService);
}
public function getPayPalConfig(): PayPalConfig
{
return oxNew(PayPalConfig::class);
}
}

View File

@@ -0,0 +1,144 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Service;
use OxidEsales\Eshop\Core\Registry as EshopRegistry;
use OxidEsales\GraphQL\Storefront\Basket\DataType\Basket as BasketDataType;
use OxidEsales\GraphQL\Storefront\Basket\Service\BasketRelationService;
use OxidEsales\GraphQL\Storefront\Payment\DataType\Payment as PaymentDataType;
use OxidEsales\GraphQL\Storefront\Payment\Exception\PaymentNotFound;
use OxidEsales\GraphQL\Storefront\Payment\Exception\UnavailablePayment;
use OxidEsales\GraphQL\Storefront\Payment\Service\Payment as StorefrontPaymentService;
use OxidEsales\PayPalModule\Core\Config as PayPalConfig;
use OxidEsales\PayPalModule\GraphQL\Exception\GraphQLServiceNotFound;
use OxidEsales\PayPalModule\GraphQL\Exception\PaymentValidation;
use OxidEsales\PayPalModule\Model\PaymentManager;
final class Basket
{
/** @var BasketRelationService */
private $basketRelationService;
/** @var StorefrontPaymentService */
private $storefrontPaymentService;
/** @var PayPalConfig */
private $paypalConfig;
public function __construct(
BasketRelationService $basketRelationService = null,
StorefrontPaymentService $storefrontPaymentService = null,
PayPalConfig $paypalConfig
) {
$this->basketRelationService = $basketRelationService;
$this->storefrontPaymentService = $storefrontPaymentService;
$this->paypalConfig = $paypalConfig;
}
public function checkBasketPaymentMethodIsPayPal(BasketDataType $basket): bool
{
$this->validateState();
$paymentMethod = $this->basketRelationService->payment($basket);
$result = false;
if (!is_null($paymentMethod) && $paymentMethod->getId()->val() === 'oxidpaypal') {
$result = true;
}
return $result;
}
/**
* @throws PaymentValidation
*/
public function validateBasketPaymentMethod(BasketDataType $basket): void
{
if (!$this->checkBasketPaymentMethodIsPayPal($basket)) {
throw PaymentValidation::paymentMethodIsNotPaypal();
}
if (!$this->paypalConfig->isStandardCheckoutEnabled()) {
throw UnavailablePayment::byId('oxidpaypal');
}
}
public function validateBasketExpressPaymentMethod(): void
{
if (!$this->paypalConfig->isExpressCheckoutEnabled()) {
throw UnavailablePayment::byId('oxidpaypal');
}
try {
$payment = $this->storefrontPaymentService->payment('oxidpaypal');
} catch (PaymentNotFound $e) {
throw UnavailablePayment::byId('oxidpaypal');
}
if (!$payment instanceof PaymentDataType) {
throw UnavailablePayment::byId('oxidpaypal');
}
}
public function updateBasketToken(BasketDataType $basket, string $token): void
{
/**
* @TODO: check if we can/need to revoke the old token.
*/
$userBasketModel = $basket->getEshopModel();
$userBasketModel->assign([
'OEPAYPAL_PAYMENT_TOKEN' => $token
]);
$userBasketModel->save();
}
public function updateExpressBasketInformation(BasketDataType $basket, string $token): void
{
$userBasketModel = $basket->getEshopModel();
$userBasketModel->assign(
[
'OEPAYPAL_PAYMENT_TOKEN' => $token,
'OEPAYPAL_SERVICE_TYPE' => PaymentManager::PAYPAL_SERVICE_TYPE_EXPRESS,
'OEGQL_PAYMENTID' => 'oxidpaypal'
]
);
$userBasketModel->save();
EshopRegistry::getSession()->setVariable(
PayPalConfig::OEPAYPAL_TRIGGER_NAME,
PaymentManager::PAYPAL_SERVICE_TYPE_EXPRESS
);
}
protected function validateState(): void
{
if (is_null($this->basketRelationService)) {
throw GraphQLServiceNotFound::byServiceName(BasketRelationService::class);
}
if (is_null($this->storefrontPaymentService)) {
throw GraphQLServiceNotFound::byServiceName(StorefrontPaymentService::class);
}
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Service;
use OxidEsales\GraphQL\Storefront\Basket\DataType\Basket as BasketDataType;
use TheCodingMachine\GraphQLite\Annotations\ExtendType;
use TheCodingMachine\GraphQLite\Annotations\Field;
/**
* @ExtendType(class=BasketDataType::class)
*/
final class BasketExtendType
{
/**
* @Field()
*/
public function paypalToken(BasketDataType $basket): string
{
return $basket->getEshopModel()->getFieldData('OEPAYPAL_PAYMENT_TOKEN');
}
/**
* @Field()
*/
public function paypalServiceType(BasketDataType $basket): int
{
return (int) $basket->getEshopModel()->getFieldData('OEPAYPAL_SERVICE_TYPE');
}
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Service;
use OxidEsales\Eshop\Core\Registry as EshopRegistry;
use OxidEsales\GraphQL\Storefront\Basket\Event\BeforePlaceOrder as BeforePlaceOrderEvent;
use OxidEsales\PayPalModule\Core\Config as PayPalConfig;
use OxidEsales\PayPalModule\GraphQL\Exception\BasketCommunication;
use OxidEsales\PayPalModule\GraphQL\Service\Basket as BasketService;
use OxidEsales\PayPalModule\GraphQL\Service\Payment as PaymentService;
use OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails;
use OxidEsales\GraphQL\Storefront\Basket\Service\Basket as StorefrontBasketService;
use OxidEsales\PayPalModule\GraphQL\Exception\GraphQLServiceNotFound;
final class BeforePlaceOrder
{
/** @var PaymentService */
private $paymentService;
/** @var BasketService */
private $basketService;
/** @var StorefrontBasketService */
private $storefrontBasketService;
public function __construct(
PaymentService $paymentService,
BasketService $basketService,
StorefrontBasketService $storefrontBasketService = null
) {
$this->paymentService = $paymentService;
$this->basketService = $basketService;
$this->storefrontBasketService = $storefrontBasketService;
}
public function handle(BeforePlaceOrderEvent $event): void
{
$this->validateState();
$userBasket = $this->storefrontBasketService->getAuthenticatedCustomerBasket($event->getBasketId());
if ($this->basketService->checkBasketPaymentMethodIsPayPal($userBasket)) {
$extendUserBasket = new BasketExtendType();
$token = $extendUserBasket->paypalToken($userBasket);
if (!$token) {
throw BasketCommunication::notStarted($userBasket->id()->val());
}
//call PayPal API once for ExpressCheckoutDetails
/** @var ResponseGetExpressCheckoutDetails $expressCheckoutDetails */
$expressCheckoutDetails = $this->paymentService->getExpressCheckoutDetails($token);
$tokenStatus = $this->paymentService->getPayPalTokenStatus($token, $expressCheckoutDetails);
if (!$tokenStatus->isTokenApproved()) {
throw BasketCommunication::notConfirmed($userBasket->id()->val());
}
$sessionBasket = $this->paymentService->getValidEshopBasketModel($userBasket, $expressCheckoutDetails);
// In order to be able to finalize order, using PayPal as payment method,
// we need to prepare the following session variables.
$session = EshopRegistry::getSession();
$session->setBasket($sessionBasket);
$session->setVariable('oepaypal-token', $token);
$session->setVariable("oepaypal-userId", $sessionBasket->getUser()->getId());
$session->setVariable('oepaypal-payerId', $tokenStatus->getPayerId());
$session->setVariable(
PayPalConfig::OEPAYPAL_TRIGGER_NAME,
$extendUserBasket->paypalServiceType($userBasket)
);
}
}
protected function validateState(): void
{
if (is_null($this->storefrontBasketService)) {
throw GraphQLServiceNotFound::byServiceName(StorefrontBasketService::class);
}
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Service;
final class NamespaceMapper
{
public function getControllerNamespaceMapping(): array
{
return [
'\\OxidEsales\\PayPalModule\\GraphQL\\Controller' => __DIR__ . '/../Controller/',
];
}
public function getTypeNamespaceMapping(): array
{
return [
'\\OxidEsales\\PayPalModule\\GraphQL\\DataType' => __DIR__ . '/../DataType/',
'\\OxidEsales\\PayPalModule\\GraphQL\\Service' => __DIR__ . '/../Service/',
];
}
}

View File

@@ -0,0 +1,297 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Service;
use OxidEsales\Eshop\Core\Model\BaseModel;
use OxidEsales\Eshop\Core\Registry as EshopRegistry;
use OxidEsales\GraphQL\Base\Exception\InvalidLogin;
use OxidEsales\GraphQL\Storefront\Basket\DataType\Basket as BasketDataType;
use OxidEsales\GraphQL\Storefront\Basket\DataType\BasketOwner as BasketOwnerDataType;
use OxidEsales\GraphQL\Storefront\Customer\Exception\CustomerNotFound;
use OxidEsales\GraphQL\Storefront\Shared\Infrastructure\Basket as SharedBasketInfrastructure;
use OxidEsales\GraphQL\Storefront\Basket\Service\BasketRelationService;
use OxidEsales\PayPalModule\GraphQL\DataType\PayPalCommunicationInformation;
use OxidEsales\PayPalModule\GraphQL\DataType\PayPalTokenStatus;
use OxidEsales\PayPalModule\GraphQL\Exception\BasketValidation;
use OxidEsales\PayPalModule\GraphQL\Exception\GraphQLServiceNotFound;
use OxidEsales\PayPalModule\GraphQL\Infrastructure\Request as RequestInfrastructure;
use OxidEsales\PayPalModule\Model\PaymentManager;
use OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails;
use OxidEsales\Eshop\Application\Model\Basket as EshopBasketModel;
use OxidEsales\Eshop\Application\Model\User as EshopUserModel;
use OxidEsales\Eshop\Application\Model\Address as EshopAddressModel;
final class Payment
{
/** @var RequestInfrastructure */
private $requestInfrastructure;
/** @var SharedBasketInfrastructure */
private $sharedBasketInfrastructure;
/** @var BasketRelationService */
private $basketRelationService;
public function __construct(
RequestInfrastructure $requestInfrastructure,
SharedBasketInfrastructure $sharedBasketInfrastructure = null,
BasketRelationService $basketRelationService = null
) {
$this->requestInfrastructure = $requestInfrastructure;
$this->sharedBasketInfrastructure = $sharedBasketInfrastructure;
$this->basketRelationService = $basketRelationService;
}
public function getPayPalTokenStatus(
string $token,
ResponseGetExpressCheckoutDetails $details = null
): PayPalTokenStatus {
//NOTE: only when the approval was finished on PayPal site
//(payment channel and delivery address registered with PayPal)
//the getExpressCheckoutResponse will contain the PayerId. So we can use this to get information
//about token status. If anything is amiss, PayPal will no let the order pass.
if (is_null($details)) {
$details = $this->getExpressCheckoutDetails($token);
}
$payerId = $details->getPayerId();
return new PayPalTokenStatus(
$token,
$payerId ? true : false,
$payerId
);
}
public function getExpressCheckoutDetails(string $token): ResponseGetExpressCheckoutDetails
{
$paymentManager = $this->requestInfrastructure->getPaymentManager();
return $paymentManager->getExpressCheckoutDetails($token);
}
/**
* @throws BasketValidation
*/
public function getValidEshopBasketModel(
BasketDataType $userBasket,
ResponseGetExpressCheckoutDetails $expressCheckoutDetails
): EshopBasketModel {
$this->validateState();
//At this point we need to check if we have PayPal Express or paypal as standard payment method checkout
// and act accordingly
if (PaymentManager::PAYPAL_SERVICE_TYPE_EXPRESS == $userBasket->getEshopModel()->getFieldData('OEPAYPAL_SERVICE_TYPE')) {
$paymentManager = $this->requestInfrastructure->getPaymentManager();
$user = $paymentManager->initializeUserData($expressCheckoutDetails, (string) $userBasket->getUserId());
$userBasket->getEshopModel()->setUser($user);
if (is_null($user->getSelectedAddressId())) {
EshopRegistry::getSession()->deleteVariable('deladrid');
}
EshopRegistry::getSession()->setVariable('usr', $user->getId());
EshopRegistry::getSession()->setUser($user);
$deliveryMethodId = $paymentManager->extractShippingId($expressCheckoutDetails->getShippingOptionName(), $user);
$userBasket->getEshopModel()->assign([
'OEGQL_DELIVERYMETHODID' => $deliveryMethodId,
'OEGQL_DELADDRESSID' => $user->getSelectedAddressId()
]);
$userBasket->getEshopModel()->save();
}
$sessionBasket = $this->sharedBasketInfrastructure->getCalculatedBasket($userBasket);
$this->validateApprovedBasketAmount($sessionBasket, $expressCheckoutDetails, $userBasket);
$this->validateApprovedBasketAddress($sessionBasket, $expressCheckoutDetails, $userBasket);
return $sessionBasket;
}
private function validateApprovedBasketAddress(
EshopBasketModel $sessionBasket,
ResponseGetExpressCheckoutDetails $expressCheckoutDetails,
BasketDataType $userBasket
): void {
$modelWithAddress = $this->calculateDeliveryAddressModel($sessionBasket, $userBasket);
//Ensure delivery address registered with PayPal is the same as shop will use
$paypalAddressModel = oxNew(EshopAddressModel::class);
$paypalAddressData = $paypalAddressModel->prepareDataPayPalAddress($expressCheckoutDetails);
$compareWith = [];
foreach ($paypalAddressData as $key => $value) {
$compareWith[$key] = $modelWithAddress->getFieldData($key);
}
$diff = array_diff($paypalAddressData, $compareWith);
if (!empty($diff)) {
throw BasketValidation::basketAddressChange($userBasket->id()->val());
}
}
/**
* Delivery address is currently related to user basket
* if that one is null, the user's invoice address is used as delivery address
*/
private function calculateDeliveryAddressModel(
EshopBasketModel $sessionBasket,
BasketDataType $userBasket
): BaseModel {
$this->validateState();
$shipToAddress = $this->basketRelationService->deliveryAddress($userBasket);
if (!is_null($shipToAddress)) {
/** @var EshopAddressModel $eshopModel */
$modelWithAddress = $shipToAddress->getEshopModel();
} else {
/** @var EshopUserModel $modelWithAddress */
$modelWithAddress = $sessionBasket->getUser();
}
return $modelWithAddress;
}
private function validateApprovedBasketAmount(
EshopBasketModel $sessionBasket,
ResponseGetExpressCheckoutDetails $expressCheckoutDetails,
BasketDataType $userBasket
): void {
$paymentManager = $this->requestInfrastructure->getPaymentManager();
/** @var \OxidEsales\Eshop\Core\Price $price */
$price = $sessionBasket->getPrice();
if (
!$price ||
!$paymentManager->validateApprovedBasketAmount(
$price->getBruttoPrice(),
$expressCheckoutDetails->getAmount()
)
) {
throw BasketValidation::basketChange($userBasket->id()->val());
}
}
public function getPayPalCommunicationInformation(
BasketDataType $basket,
string $returnUrl,
string $cancelUrl,
bool $displayBasketInPayPal
): PayPalCommunicationInformation {
$this->validateState();
$paymentManager = $this->requestInfrastructure->getPaymentManager();
$shipToAddress = $this->basketRelationService->deliveryAddress($basket);
$shipToAddressId = $shipToAddress ? (string) $shipToAddress->id(): '';
$response = $paymentManager->setStandardCheckout(
$this->sharedBasketInfrastructure->getBasket($basket),
$this->basketRelationService->owner($basket)->getEshopModel(),
$returnUrl,
$cancelUrl,
$displayBasketInPayPal,
$shipToAddressId
);
$token = (string) $response->getToken();
return new PayPalCommunicationInformation(
$token,
$this->getPayPalCommunicationUrl($token)
);
}
public function getPayPalExpressCommunicationInformation(
BasketDataType $basket,
string $returnUrl,
string $cancelUrl,
bool $displayBasketInPayPal
): PayPalCommunicationInformation {
$this->validateState();
$paymentManager = $this->requestInfrastructure->getPaymentManager();
$shipToAddressId = $this->getDeliveryAddressId($basket);
$deliveryMethod = $this->basketRelationService->deliveryMethod($basket);
$shippingMethodId = $deliveryMethod ? (string) $deliveryMethod->id() : 'oxidstandard';
//for Express checkout, the user might not yet exist (anonymous user)
try {
/** @var BasketOwnerDataType $customer */
$owner = $this->basketRelationService->owner($basket);
$user = $owner->getEshopModel();
$user->setSelectedAddressId($shipToAddressId);
} catch (CustomerNotFound $e) {
$user = null;
}
$response = $paymentManager->setExpressCheckout(
$this->sharedBasketInfrastructure->getBasket($basket),
$user,
$returnUrl,
$cancelUrl,
$paymentManager->getGraphQLCallBackUrl((string) $basket->id()),
$displayBasketInPayPal,
$shippingMethodId
);
$token = (string) $response->getToken();
return new PayPalCommunicationInformation(
$token,
$this->getPayPalCommunicationUrl($token)
);
}
public function getPayPalCommunicationUrl($token): string
{
$payPalConfig = $this->requestInfrastructure->getPayPalConfig();
return $payPalConfig->getPayPalCommunicationUrl($token);
}
protected function validateState(): void
{
if (is_null($this->sharedBasketInfrastructure)) {
throw GraphQLServiceNotFound::byServiceName(SharedBasketInfrastructure::class);
}
if (is_null($this->basketRelationService)) {
throw GraphQLServiceNotFound::byServiceName(BasketRelationService::class);
}
}
protected function getDeliveryAddressId(BasketDataType $basket): String
{
try {
//use might be logged in to his existing shop account
$shipToAddress = $this->basketRelationService->deliveryAddress($basket);
} catch (InvalidLogin $e) {
//in case of anonymous user access of delivery address is forbidden
}
return $shipToAddress ? (string) $shipToAddress->id(): '';
}
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Service;
final class PermissionProvider
{
public function getPermissions(): array
{
return [
'oxidcustomer' => [
'PAYPAL_EXPRESS_APPROVAL',
'PAYPAL_TOKEN_STATUS'
],
'oxidnotyetordered' => [
'PAYPAL_EXPRESS_APPROVAL',
'PAYPAL_TOKEN_STATUS'
],
'oxidanonymous' => [
'CREATE_BASKET',
'VIEW_BASKET',
'ADD_PRODUCT_TO_BASKET',
'REMOVE_BASKET_PRODUCT',
'ADD_VOUCHER',
'REMOVE_VOUCHER',
'PLACE_ORDER',
'PAYPAL_EXPRESS_APPROVAL',
'PAYPAL_TOKEN_STATUS'
],
];
}
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Subscriber;
use OxidEsales\Eshop\Core\Registry as EshopRegistry;
use OxidEsales\EshopCommunity\Internal\Framework\Event\AbstractShopAwareEventSubscriber;
use OxidEsales\GraphQL\Storefront\Basket\Event\BeforeBasketPayments as BeforeBasketPaymentsEvent;
use OxidEsales\GraphQL\Storefront\Basket\Service\Basket as StorefrontBasketService;
use OxidEsales\PayPalModule\Core\Config as PayPalConfig;
use OxidEsales\PayPalModule\GraphQL\Exception\GraphQLServiceNotFound;
use OxidEsales\PayPalModule\GraphQL\Service\Basket as BasketService;
use OxidEsales\PayPalModule\GraphQL\Service\BasketExtendType;
class BeforeBasketPayments extends AbstractShopAwareEventSubscriber
{
/** @var BasketService */
private $basketService;
/** @var StorefrontBasketService */
private $storefrontBasketService;
public function __construct(
BasketService $basketService,
StorefrontBasketService $storefrontBasketService = null
) {
$this->basketService = $basketService;
$this->storefrontBasketService = $storefrontBasketService;
}
public function handle(BeforeBasketPaymentsEvent $event): BeforeBasketPaymentsEvent
{
$this->validateState();
$basketDataType = $this->storefrontBasketService->getAuthenticatedCustomerBasket($event->getBasketId());
if ($this->basketService->checkBasketPaymentMethodIsPayPal($basketDataType)) {
$extendUserBasket = new BasketExtendType();
$session = EshopRegistry::getSession();
$session->setVariable(
PayPalConfig::OEPAYPAL_TRIGGER_NAME,
$extendUserBasket->paypalServiceType($basketDataType)
);
}
return $event;
}
public static function getSubscribedEvents()
{
return [
'OxidEsales\GraphQL\Storefront\Basket\Event\BeforeBasketPayments' => 'handle'
];
}
protected function validateState(): void
{
if (is_null($this->storefrontBasketService)) {
throw GraphQLServiceNotFound::byServiceName(StorefrontBasketService::class);
}
}
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
declare(strict_types=1);
namespace OxidEsales\PayPalModule\GraphQL\Subscriber;
use OxidEsales\PayPalModule\GraphQL\Exception\GraphQLServiceNotFound;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use OxidEsales\EshopCommunity\Internal\Framework\Event\AbstractShopAwareEventSubscriber;
use OxidEsales\PayPalModule\GraphQL\Service\BeforePlaceOrder as BeforePlaceOrderService;
class BeforePlaceOrder extends AbstractShopAwareEventSubscriber
{
/** @var BeforePlaceOrderService */
private $beforePlaceOrderService;
public function __construct(BeforePlaceOrderService $beforePlaceOrderService)
{
$this->beforePlaceOrderService = $beforePlaceOrderService;
}
public function handle(Event $event): Event
{
$this->validateState();
$this->beforePlaceOrderService->handle($event);
return $event;
}
public static function getSubscribedEvents()
{
return [
'OxidEsales\GraphQL\Storefront\Basket\Event\BeforePlaceOrder' => 'handle'
];
}
protected function validateState(): void
{
if (is_null($this->beforePlaceOrderService)) {
throw GraphQLServiceNotFound::byServiceName(BeforePlaceOrderService::class);
}
}
}

View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View File

@@ -0,0 +1,103 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Data;
/**
* PayPal order action factory class
*/
class OrderActionData
{
/**
* Request object
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $request = null;
/**
* Order object
*
* @var \OxidEsales\PayPalModule\Model\Order
*/
protected $order = null;
/**
* Sets dependencies.
*
* @param \OxidEsales\PayPalModule\Core\Request $request
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order
*/
public function __construct($request, $order)
{
$this->request = $request;
$this->order = $order;
}
/**
* Returns Request object
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Returns PayPal Order object
*
* @return \OxidEsales\PayPalModule\Model\Order
*/
public function getOrder()
{
return $this->order;
}
/**
* returns action amount
*
* @return string
*/
public function getAuthorizationId()
{
return $this->getOrder()->oxorder__oxtransid->value;
}
/**
* returns comment
*
* @return string
*/
public function getComment()
{
return $this->getRequest()->getRequestParameter('action_comment');
}
/**
* Returns order status
*
* @return string
*/
public function getOrderStatus()
{
return $this->getRequest()->getRequestParameter('order_status');
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Data;
/**
* PayPal order action factory class
*/
class OrderCaptureActionData extends \OxidEsales\PayPalModule\Model\Action\Data\OrderActionData
{
/**
* returns action type
*
* @return string
*/
public function getType()
{
return $this->getRequest()->getRequestParameter('capture_type');
}
/**
* returns action amount
*
* @return string
*/
public function getAmount()
{
$amount = $this->getRequest()->getRequestParameter('capture_amount');
$validDecimalAmount = preg_replace('/,(?=\d{0,2}$)/', '.', $amount) ?? $amount;
return $validDecimalAmount ? $validDecimalAmount : $this->getOrder()->getPayPalOrder()->getRemainingOrderSum();
}
/**
* returns currency
*
* @return string
*/
public function getCurrency()
{
return $this->getOrder()->getPayPalOrder()->getCurrency();
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Data;
/**
* PayPal order action factory class.
*/
class OrderReauthorizeActionData extends \OxidEsales\PayPalModule\Model\Action\Data\OrderActionData
{
/**
* Returns action amount.
*
* @return string
*/
public function getAmount()
{
return $this->getOrder()->getPayPalOrder()->getRemainingOrderSum();
}
/**
* Returns currency.
*
* @return string
*/
public function getCurrency()
{
return $this->getOrder()->getPayPalOrder()->getCurrency();
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Data;
/**
* PayPal order action factory class
*/
class OrderRefundActionData extends \OxidEsales\PayPalModule\Model\Action\Data\OrderActionData
{
/**
* @var \OxidEsales\PayPalModule\Model\OrderPayment::class
*/
public $paymentBeingRefunded = null;
/**
* Returns action type.
*
* @return string
*/
public function getType()
{
return $this->getRequest()->getRequestParameter('refund_type');
}
/**
* Returns action amount.
*
* @return string
*/
public function getTransactionId()
{
return $this->getRequest()->getRequestParameter('transaction_id');
}
/**
* Returns amount to refund.
*
* @return float
*/
public function getAmount()
{
$amount = $this->getRequest()->getRequestParameter('refund_amount');
$validDecimalAmount = preg_replace('/,(?=\d{0,2}$)/', '.', $amount) ?? $amount;
return $validDecimalAmount ? $validDecimalAmount : $this->getPaymentBeingRefunded()->getRemainingRefundAmount();
}
/**
* Returns currency.
*
* @return string
*/
public function getCurrency()
{
return $this->getOrder()->getPayPalOrder()->getCurrency();
}
/**
* Returns payment to refund.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
public function getPaymentBeingRefunded()
{
if (is_null($this->paymentBeingRefunded)) {
$this->paymentBeingRefunded = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$this->paymentBeingRefunded->loadByTransactionId($this->getTransactionId());
}
return $this->paymentBeingRefunded;
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Data;
/**
* PayPal order action factory class
*/
class OrderVoidActionData extends \OxidEsales\PayPalModule\Model\Action\Data\OrderActionData
{
/**
* Returns action amount.
*
* @return string
*/
public function getAmount()
{
return $this->getOrder()->getPayPalOrder()->getRemainingOrderSum();
}
/**
* Returns currency.
*
* @return string
*/
public function getCurrency()
{
return $this->getOrder()->getPayPalOrder()->getCurrency();
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Handler;
/**
* PayPal order action class
*/
abstract class OrderActionHandler
{
/**
* @var object
*/
protected $data = null;
/**
* @var \OxidEsales\PayPalModule\Core\PayPalService
*/
protected $payPalService = null;
/**
* PayPal order
*
* @var \OxidEsales\PayPalModule\Model\PayPalOrder
*/
protected $payPalRequestBuilder = null;
/**
* Sets data object.
*
* @param object $data
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Returns Data object
*
* @return object
*/
public function getData()
{
return $this->data;
}
/**
* Sets PayPal request builder
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequestBuilder $builder
*/
public function setPayPalRequestBuilder($builder)
{
$this->payPalRequestBuilder = $builder;
}
/**
* Returns PayPal request builder
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequestBuilder
*/
public function getPayPalRequestBuilder()
{
if ($this->payPalRequestBuilder === null) {
$this->payPalRequestBuilder = oxNew(\OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequestBuilder::class);
}
return $this->payPalRequestBuilder;
}
/**
* Sets PayPal service
*
* @param \OxidEsales\PayPalModule\Core\PayPalService $service
*/
public function setPayPalService($service)
{
$this->payPalService = $service;
}
/**
* Returns PayPal service
*
* @return \OxidEsales\PayPalModule\Core\PayPalService
*/
public function getPayPalService()
{
if ($this->payPalService === null) {
$this->payPalService = oxNew(\OxidEsales\PayPalModule\Core\PayPalService::class);
}
return $this->payPalService;
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Handler;
/**
* PayPal order action capture class
*/
class OrderCaptureActionHandler extends \OxidEsales\PayPalModule\Model\Action\Handler\OrderActionHandler
{
/**
* PayPal Request
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $payPalRequest = null;
/**
* Returns PayPal response; calls PayPal if not set
*
* @return mixed
*/
public function getPayPalResponse()
{
$service = $this->getPayPalService();
$request = $this->getPayPalRequest();
return $service->doCapture($request);
}
/**
* Returns PayPal request; initializes if not set
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if (is_null($this->payPalRequest)) {
$requestBuilder = $this->getPayPalRequestBuilder();
$data = $this->getData();
$requestBuilder->setAuthorizationId($data->getAuthorizationId());
$requestBuilder->setAmount($data->getAmount(), $data->getCurrency());
$requestBuilder->setCompleteType($data->getType());
$requestBuilder->setComment($data->getComment());
$this->payPalRequest = $requestBuilder->getRequest();
}
return $this->payPalRequest;
}
/**
* Sets PayPal request
*
* @param \OxidEsales\PayPalModule\Core\Request $payPalRequest
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Handler;
/**
* PayPal order action reauthorize class
*/
class OrderReauthorizeActionHandler extends \OxidEsales\PayPalModule\Model\Action\Handler\OrderActionHandler
{
/**
* PayPal Request.
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $payPalRequest = null;
/**
* Returns PayPal response; initiates if not set.
*
* @return \OxidEsales\PayPalModule\Model\Response\ResponseDoRefund|\OxidEsales\PayPalModule\Model\Response\Response
*/
public function getPayPalResponse()
{
$service = $this->getPayPalService();
$request = $this->getPayPalRequest();
return $service->doReAuthorization($request);
}
/**
* Returns PayPal request; initiates if not set.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if (is_null($this->payPalRequest)) {
$requestBuilder = $this->getPayPalRequestBuilder();
$data = $this->getData();
$requestBuilder->setAuthorizationId($data->getAuthorizationId());
$requestBuilder->setAmount($data->getAmount(), $data->getCurrency());
$this->payPalRequest = $requestBuilder->getRequest();
}
return $this->payPalRequest;
}
/**
* Sets PayPal request.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $payPalRequest
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Handler;
/**
* PayPal order action refund class
*/
class OrderRefundActionHandler extends \OxidEsales\PayPalModule\Model\Action\Handler\OrderActionHandler
{
/**
* PayPal Request
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $payPalRequest = null;
/**
* Returns PayPal response; calls PayPal if not set
*
* @return mixed
*/
public function getPayPalResponse()
{
$service = $this->getPayPalService();
$request = $this->getPayPalRequest();
return $service->refundTransaction($request);
}
/**
* Returns PayPal request; initiates if not set
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if (is_null($this->payPalRequest)) {
$requestBuilder = $this->getPayPalRequestBuilder();
$data = $this->getData();
$requestBuilder->setTransactionId($data->getTransactionId());
$requestBuilder->setAmount($data->getAmount(), $data->getCurrency());
$requestBuilder->setRefundType($data->getType());
$requestBuilder->setComment($data->getComment());
$this->payPalRequest = $requestBuilder->getRequest();
}
return $this->payPalRequest;
}
/**
* Sets PayPal request
*
* @param \OxidEsales\PayPalModule\Core\Request $payPalRequest
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Handler;
/**
* PayPal order action void class.
*/
class OrderVoidActionHandler extends \OxidEsales\PayPalModule\Model\Action\Handler\OrderActionHandler
{
/**
* PayPal Request.
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $payPalRequest = null;
/**
* Returns PayPal response; initiates if not set.
*
* @return mixed
*/
public function getPayPalResponse()
{
$service = $this->getPayPalService();
$request = $this->getPayPalRequest();
return $service->doVoid($request);
}
/**
* Returns PayPal request; initiates if not set.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if (is_null($this->payPalRequest)) {
$requestBuilder = $this->getPayPalRequestBuilder();
$data = $this->getData();
$requestBuilder->setAuthorizationId($data->getAuthorizationId());
$requestBuilder->setAmount($data->getAmount(), $data->getCurrency());
$requestBuilder->setComment($data->getComment());
$this->payPalRequest = $requestBuilder->getRequest();
}
return $this->payPalRequest;
}
/**
* Sets PayPal request.
*
* @param \OxidEsales\PayPalModule\Core\Request $payPalRequest Request object.
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action;
/**
* PayPal order action class
*/
abstract class OrderAction
{
/**
*
* @var \OxidEsales\PayPalModule\Model\PayPalOrder
*/
protected $_oOrder = null;
/**
* @var string
*/
protected $orderStatus = null;
/**
* @var \OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler
*/
protected $handler = null;
/**
* Sets handler and order.
*
* @param \OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler $handler
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order
*/
public function __construct($handler, $order)
{
$this->handler = $handler;
$this->order = $order;
}
/**
* Returns \OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler object.
*
* @return \OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler
*/
public function getHandler()
{
return $this->handler;
}
/**
* Returns \OxidEsales\PayPalModule\Model\PayPalOrder object.
*
* @return \OxidEsales\PayPalModule\Model\PayPalOrder
*/
public function getOrder()
{
return $this->order;
}
/**
* Returns formatted date
*
* @return string
*/
public function getDate()
{
$utilsDate = \OxidEsales\Eshop\Core\Registry::getUtilsDate();
return date('Y-m-d H:i:s', $utilsDate->getTime());
}
/**
* Processes PayPal action
*/
abstract public function process();
}

View File

@@ -0,0 +1,144 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action;
/**
* PayPal order action factory class
*/
class OrderActionFactory
{
/**
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $_oRequest = null;
/**
* @var \OxidEsales\PayPalModule\Model\Order
*/
protected $order = null;
/**
* Sets dependencies
*
* @param \OxidEsales\PayPalModule\Core\Request $request
* @param \OxidEsales\PayPalModule\Model\Order $order
*/
public function __construct($request, $order)
{
$this->request = $request;
$this->order = $order;
}
/**
* Returns Request object
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Returns Order object
*
* @return \OxidEsales\PayPalModule\Model\Order
*/
public function getOrder()
{
return $this->order;
}
/**
* Creates action object by given action name.
*
* @param string $action
*
* @return object
*
* @throws \OxidEsales\PayPalModule\Core\Exception\PayPalInvalidActionException
*/
public function createAction($action)
{
$method = "get" . ucfirst($action) . "Action";
if (!method_exists($this, $method)) {
/** @var \OxidEsales\PayPalModule\Core\Exception\PayPalInvalidActionException $exception */
$exception = oxNew(\OxidEsales\PayPalModule\Core\Exception\PayPalInvalidActionException::class);
throw $exception;
}
return $this->$method();
}
/**
* Returns capture action object
*
* @return \OxidEsales\PayPalModule\Model\Action\OrderCaptureAction
*/
public function getCaptureAction()
{
$order = $this->getOrder();
$request = $this->getRequest();
$data = oxNew(\OxidEsales\PayPalModule\Model\Action\Data\OrderCaptureActionData::class, $request, $order);
$handler = oxNew(\OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler::class, $data);
$reauthorizeData = oxNew(\OxidEsales\PayPalModule\Model\Action\Data\OrderReauthorizeActionData::class, $request, $order);
$reauthorizeHandler = oxNew(\OxidEsales\PayPalModule\Model\Action\Handler\OrderReauthorizeActionHandler::class, $reauthorizeData);
$action = oxNew(\OxidEsales\PayPalModule\Model\Action\OrderCaptureAction::class, $handler, $order->getPayPalOrder(), $reauthorizeHandler);
return $action;
}
/**
* Returns refund action object
*
* @return \OxidEsales\PayPalModule\Model\Action\OrderRefundAction
*/
public function getRefundAction()
{
$order = $this->getOrder();
$data = oxNew(\OxidEsales\PayPalModule\Model\Action\Data\OrderRefundActionData::class, $this->getRequest(), $order);
$handler = oxNew(\OxidEsales\PayPalModule\Model\Action\Handler\OrderRefundActionHandler::class, $data);
$action = oxNew(\OxidEsales\PayPalModule\Model\Action\OrderRefundAction::class, $handler, $order->getPayPalOrder());
return $action;
}
/**
* Returns void action object
*
* @return \OxidEsales\PayPalModule\Model\Action\OrderVoidAction
*/
public function getVoidAction()
{
$order = $this->getOrder();
$data = oxNew(\OxidEsales\PayPalModule\Model\Action\Data\OrderVoidActionData::class, $this->getRequest(), $order);
$handler = oxNew(\OxidEsales\PayPalModule\Model\Action\Handler\OrderVoidActionHandler::class, $data);
$action = oxNew(\OxidEsales\PayPalModule\Model\Action\OrderVoidAction::class, $handler, $order->getPayPalOrder());
return $action;
}
}

View File

@@ -0,0 +1,154 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action;
/**
* PayPal order action capture class
*/
class OrderCaptureAction extends \OxidEsales\PayPalModule\Model\Action\OrderAction
{
/**
* @var \OxidEsales\PayPalModule\Model\Action\Handler\OrderReauthorizeActionHandler
*/
protected $reauthorizeHandler = null;
/**
* Sets dependencies.
*
* @param \OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler $handler
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order
* @param \OxidEsales\PayPalModule\Model\Action\Handler\OrderReauthorizeActionHandler $reauthorizeHandler
*/
public function __construct($handler, $order, $reauthorizeHandler)
{
parent::__construct($handler, $order);
$this->reauthorizeHandler = $reauthorizeHandler;
}
/**
* Returns reauthorize action handler.
*
* @return \OxidEsales\PayPalModule\Model\Action\Handler\OrderReauthorizeActionHandler
*/
public function getReauthorizeHandler()
{
return $this->reauthorizeHandler;
}
/**
* Processes PayPal response.
*/
public function process()
{
$this->reauthorize();
$handler = $this->getHandler();
$response = $handler->getPayPalResponse();
$data = $handler->getData();
$this->updateOrder($response, $data);
$payment = $this->createPayment($response);
$paymentList = $this->getOrder()->getPaymentList();
$payment = $paymentList->addPayment($payment);
$this->addComment($payment, $data->getComment());
}
/**
* Reauthorizes payment if order was captured at least once.
*/
protected function reauthorize()
{
$order = $this->getOrder();
if ($order->getCapturedAmount() > 0) {
$handler = $this->getReauthorizeHandler();
try {
$response = $handler->getPayPalResponse();
$payment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$payment->setDate($this->getDate());
$payment->setTransactionId($response->getAuthorizationId());
$payment->setCorrelationId($response->getCorrelationId());
$payment->setAction('re-authorization');
$payment->setStatus($response->getPaymentStatus());
$order->getPaymentList()->addPayment($payment);
} catch (\OxidEsales\PayPalModule\Core\Exception\PayPalResponseException $e) {
// Ignore PayPal response exceptions
}
}
}
/**
* Updates order with PayPal response info.
*
* @param object $response
* @param object $data
*/
protected function updateOrder($response, $data)
{
$order = $this->getOrder();
$order->addCapturedAmount($response->getCapturedAmount());
$order->setPaymentStatus($data->getOrderStatus());
$order->save();
}
/**
* Creates Payment object with PayPal response data.
*
* @param object $response
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment::class
*/
protected function createPayment($response)
{
$payment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$payment->setDate($this->getDate());
$payment->setTransactionId($response->getTransactionId());
$payment->setCorrelationId($response->getCorrelationId());
$payment->setAction('capture');
$payment->setStatus($response->getPaymentStatus());
$payment->setAmount($response->getCapturedAmount());
$payment->setCurrency($response->getCurrency());
return $payment;
}
/**
* Adds comment to given Payment object.
*
* @param object $payment
* @param string $comment
*/
protected function addComment($payment, $commentContent)
{
if ($commentContent) {
$comment = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentComment::class);
$comment->setComment($commentContent);
$payment->addComment($comment);
}
}
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action;
/**
* PayPal order action refund class
*/
class OrderRefundAction extends \OxidEsales\PayPalModule\Model\Action\OrderAction
{
/**
* Processes PayPal response
*/
public function process()
{
$handler = $this->getHandler();
$response = $handler->getPayPalResponse();
$data = $handler->getData();
$order = $this->getOrder();
$order->addRefundedAmount($response->getRefundAmount());
$order->setPaymentStatus($data->getOrderStatus());
$order->save();
$payment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$payment->setDate($this->getDate());
$payment->setTransactionId($response->getTransactionId());
$payment->setCorrelationId($response->getCorrelationId());
$payment->setAction('refund');
$payment->setStatus($response->getPaymentStatus());
$payment->setAmount($response->getRefundAmount());
$payment->setCurrency($response->getCurrency());
$refundedPayment = $data->getPaymentBeingRefunded();
$refundedPayment->addRefundedAmount($response->getRefundAmount());
$refundedPayment->save();
$payment = $order->getPaymentList()->addPayment($payment);
if ($data->getComment()) {
$comment = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentComment::class);
$comment->setComment($data->getComment());
$payment->addComment($comment);
}
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action;
/**
* PayPal order action void class
*/
class OrderVoidAction extends \OxidEsales\PayPalModule\Model\Action\OrderAction
{
/**
* Processes PayPal response
*/
public function process()
{
$handler = $this->getHandler();
$response = $handler->getPayPalResponse();
$data = $handler->getData();
$order = $this->getOrder();
$amount = $order->getRemainingOrderSum();
$order->setVoidedAmount($amount);
$order->setPaymentStatus($data->getOrderStatus());
$order->save();
$payment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$payment->setDate($this->getDate());
$payment->setTransactionId($response->getAuthorizationId());
$payment->setCorrelationId($response->getCorrelationId());
$payment->setAction('void');
$payment->setStatus('Voided');
$payment->setAmount($amount);
$payment = $order->getPaymentList()->addPayment($payment);
if ($data->getComment()) {
$comment = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentComment::class);
$comment->setComment($data->getComment());
$payment->addComment($comment);
}
}
}

Some files were not shown because too many files have changed in this diff Show More