Commit d39ee248 authored by Thomas Löffler's avatar Thomas Löffler

Merge branch 'develop' into 'main'

Release 12-10-20

See merge request !398
parents 612d5fab b16cd251
Pipeline #9750 passed with stages
in 9 minutes and 43 seconds
......@@ -2,17 +2,13 @@ include:
- project: 't3o/t3olayout'
ref: main
file: '/Configuration/GitLab/t3o-builds.yml'
- remote: 'https://git.spooner.io/spooner-web/gitlab-anybadge-creator/-/raw/main/anybadges.yml'
variables:
GIT_STRATEGY: "none"
GIT_SSL_NO_VERIFY: "true"
STAGE_HOST: "typo3.dev"
PRODUCTION_HOST: "typo3.org"
DUMP_USER: "t3o-stage"
STAGE_USER: "t3o-stage"
DUMP_EXCLUDE_TABLES_LIST: "be_groups,be_sessions,be_users,cf_cache_hash,cf_cache_hash_tags,cf_cache_imagesizes,cf_cache_imagesizes_tags,cf_cache_news_category,cf_cache_news_category_tags,cf_cache_pages,cf_cache_pages_tags,cf_cache_pagesection,cf_cache_pagesection_tags,cf_cache_rootline,cf_cache_rootline_tags,cf_extbase_datamapfactory_datamap,cf_extbase_datamapfactory_datamap_tags,cf_extbase_object,cf_extbase_object_tags,cf_extbase_reflection,cf_extbase_reflection_tags,cf_tx_solr,cf_tx_solr_configuration,cf_tx_solr_configuration_tags,cf_tx_solr_tags,fe_groups,fe_sessions,fe_users,sys_domain,sys_log,tx_solr_cache,tx_solr_cache_tags"
PHP_EXECUTABLE: "/opt/php/php72/bin/php"
ADDITIONAL_TABLE_EXCLUDES: "-e 'tx_certifications_*' -e 'tx_t3odonation_domain_model_donation' -e 'tx_t3omembership_domain_model_member' -e 'tx_randombanners_domain_model_banner'"
stages:
......@@ -22,47 +18,3 @@ stages:
- layout
- deploy
- badges
- warmup
.deploy-template: &deploy_template
stage: deploy
image: composer:1
before_script:
- apk add rsync --update
- mkdir -p /root/.ssh/
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY_STAGE" | ssh-add -
- echo "$SSH_PRIVATE_KEY_PRODUCTION" | ssh-add -
- ssh-keyscan ${STAGE_HOST} >> /root/.ssh/known_hosts
- ssh-keyscan ${PRODUCTION_HOST} >> /root/.ssh/known_hosts
- composer config cache-dir /cache/composer
- composer global require deployer/deployer:6.6.0 --update-with-dependencies
- composer global require deployer/recipes
script:
- /tmp/vendor/bin/dep --file=./.gitlab-ci/deployer/deploy.php deploy -vv ${CI_BUILD_REF_NAME}
dependencies:
- layout
except:
- assets
deploy-master:
<<: *deploy_template
environment:
name: master
url: https://${PRODUCTION_HOST}
only:
- master
deploy-develop:
<<: *deploy_template
environment:
name: develop
url: https://${STAGE_HOST}
only:
- develop
"Create Badge":
stage: badges
script:
- last_master_deploy=$(git --no-pager log -1 --date=format:"%Y/%m/%d-%T" --format="%ad" origin/master)
- anybadge -l "Last Production Deployment" -v $last_master_deploy -f lastProductionDeployment.svg -c orange
master:
stage: master
main:
stage: main
hostname: typo3.org
user: t3o-prod
writable_mode: chmod
......
{
"name": "t3o/typo3.org",
"description": "Website for TYPO3.org",
"minimum-stability": "dev",
"prefer-stable": true,
"authors": [
{
"name": "t3o team",
......@@ -52,6 +50,7 @@
"brotkrueml/typo3-matomo-widgets": "^0.1.0",
"cweagans/composer-patches": "^1.6",
"derhansen/sf_event_mgt": "^5.0",
"doctrine/dbal": "~2.10.3",
"georgringer/news": "^8.0",
"gordalina/cachetool": "^4.0",
"reelworx/rx-shariff": "^13.0",
......
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "2c9572c78b7f5293aa8dae86a5048eb1",
"content-hash": "95b8c3c8b6a5e99193dde13886752ce7",
"packages": [
{
"name": "adoy/fastcgi-client",
......@@ -578,30 +578,30 @@
},
{
"name": "doctrine/dbal",
"version": "2.11.1",
"version": "2.10.3",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "6e6903cd5e3a5be60a79439e3ee8fe126f78fe86"
"reference": "03ca23afc2ee062f5d3e32426ad37c34a4770dcf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/6e6903cd5e3a5be60a79439e3ee8fe126f78fe86",
"reference": "6e6903cd5e3a5be60a79439e3ee8fe126f78fe86",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/03ca23afc2ee062f5d3e32426ad37c34a4770dcf",
"reference": "03ca23afc2ee062f5d3e32426ad37c34a4770dcf",
"shasum": ""
},
"require": {
"doctrine/cache": "^1.0",
"doctrine/event-manager": "^1.0",
"ext-pdo": "*",
"php": "^7.3"
"php": "^7.2"
},
"require-dev": {
"doctrine/coding-standard": "^8.1",
"jetbrains/phpstorm-stubs": "^2019.1",
"nikic/php-parser": "^4.4",
"phpstan/phpstan": "^0.12.40",
"phpunit/phpunit": "^9.3",
"phpunit/phpunit": "^8.5.5",
"psalm/plugin-phpunit": "^0.10.0",
"symfony/console": "^2.0.5|^3.0|^4.0|^5.0",
"vimeo/psalm": "^3.14.2"
......@@ -615,7 +615,8 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
"dev-master": "2.10.x-dev",
"dev-develop": "3.0.x-dev"
}
},
"autoload": {
......@@ -682,7 +683,7 @@
"type": "tidelift"
}
],
"time": "2020-09-27T04:09:41+00:00"
"time": "2020-09-02T01:35:42+00:00"
},
{
"name": "doctrine/event-manager",
......@@ -7787,11 +7788,11 @@
}
],
"aliases": [],
"minimum-stability": "dev",
"minimum-stability": "stable",
"stability-flags": {
"t3o/t3org_layout": 20
},
"prefer-stable": true,
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
......
......@@ -29,14 +29,6 @@ use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
*/
class DonationController extends ActionController
{
/**
* configurationUtility
*
* @var \TYPO3\CMS\Core\Configuration\ExtensionConfiguration
* @TYPO3\CMS\Extbase\Annotation\Inject
* @TYPO3\CMS\Extbase\Annotation\ORM\Lazy
*/
protected ?\TYPO3\CMS\Core\Configuration\ExtensionConfiguration $configurationUtility = null;
/**
* accountRepository
......@@ -88,22 +80,6 @@ class DonationController extends ActionController
parent::initializeAction();
}
/**
* @param string $optionName
* @return string
*/
protected function getConfigurationOption($optionName)
{
$config = $this->configurationUtility->get('t3o_donation');
if (!isset($config[$optionName])) {
return '';
}
if (!isset($config[$optionName]['value'])) {
return '';
}
return $config[$optionName]['value'];
}
/**
* action list
*/
......@@ -156,7 +132,7 @@ class DonationController extends ActionController
{
$parameters = GeneralUtility::_POST();
$verified = $this->ipnService->verify($parameters, $this->getConfigurationOption('paypal.action'));
$verified = $this->ipnService->verify($parameters, $this->settings['paypal']['action']);
if (!$verified) {
$this->addFlashMessage('Payment verification failed', 'Paypal transaction', \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR);
......
......@@ -41,7 +41,7 @@ class Account extends AbstractEntity
* @TYPO3\CMS\Extbase\Annotation\Validate("EmailAddress")
* @var string
*/
protected string $emailPaypal;
protected string $emailPaypal = '';
/**
* @return string
......
......@@ -98,7 +98,7 @@ class Donation extends AbstractEntity
/**
* @var \TYPO3\CMS\Extbase\Domain\Model\FrontendUser
*/
protected ?\TYPO3\CMS\Extbase\Domain\Model\FrontendUser $feUser = null;
protected ?\TYPO3\CMS\Extbase\Domain\Model\FrontendUser $feuser = null;
/**
* @var string
......@@ -222,19 +222,19 @@ class Donation extends AbstractEntity
}
/**
* @param \TYPO3\CMS\Extbase\Domain\Model\FrontendUser feUser
* @param \TYPO3\CMS\Extbase\Domain\Model\FrontendUser feuser
*/
public function setFeUser(\TYPO3\CMS\Extbase\Domain\Model\FrontendUser $feUser): void
public function setFeuser(\TYPO3\CMS\Extbase\Domain\Model\FrontendUser $feuser): void
{
$this->feUser = $feUser;
$this->feuser = $feuser;
}
/**
* @return \TYPO3\CMS\Extbase\Domain\Model\FrontendUser
*/
public function getFeUser(): ?\TYPO3\CMS\Extbase\Domain\Model\FrontendUser
public function getFeuser(): ?\TYPO3\CMS\Extbase\Domain\Model\FrontendUser
{
return $this->feUser;
return $this->feuser;
}
/**
......
......@@ -68,7 +68,7 @@ class Mail implements \TYPO3\CMS\Core\SingletonInterface
if ($body === null) {
$body = '';
}
$this->mailMessage->setBody($body, 'text/html');
$this->mailMessage->html($body);
$this->mailMessage->setSubject(
LocalizationUtility::translate(
'mail_notification_subject',
......@@ -129,7 +129,7 @@ class Mail implements \TYPO3\CMS\Core\SingletonInterface
if ($body === null) {
$body = '';
}
$this->mailMessage->setBody($body, 'text/html');
$this->mailMessage->html($body);
$this->mailMessage->setSubject($subject);
$this->mailMessage->setTo([
$donation->getEmail() => $donation->getName()
......
......@@ -4,6 +4,7 @@ namespace T3o\T3oDonation\Service;
use T3o\T3oDonation\Domain\Model\Donation;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Domain\Model\FrontendUser;
/**
* This file is part of the TYPO3 CMS project.
......@@ -117,7 +118,7 @@ class PayPalIpn implements \TYPO3\CMS\Core\SingletonInterface
public function createDonation(array $parameters)
{
/* @var Donation */
/* @var Donation $donation */
$donation = $this->objectManager->get(Donation::class);
$donation->setHidden(true);
$donation->setName($parameters['first_name'] . ' ' . $parameters['last_name']);
......@@ -160,9 +161,10 @@ class PayPalIpn implements \TYPO3\CMS\Core\SingletonInterface
}
}
if (isset($custom[1]) && is_numeric($custom[1])) {
/** @var FrontendUser $user */
$user = $this->frontendUserRepository->findByUid($custom[1]);
if ($user) {
$donation->setFeUser($user);
$donation->setFeuser($user);
}
}
......
......@@ -12,6 +12,7 @@
<label>PayPal Account</label>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<foreign_table>tx_t3odonation_domain_model_account</foreign_table>
<size>1</size>
<maxitems>1</maxitems>
......@@ -99,4 +100,4 @@
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>
\ No newline at end of file
</T3DataStructure>
......@@ -5,3 +5,9 @@
'Configuration/TypoScript',
'TYPO3 Donations'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['t3odonation_form'] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
't3odonation_form',
'FILE:EXT:t3o_donation/Configuration/FlexForms/donation_form.xml'
);
......@@ -11,12 +11,3 @@
'Form',
'Donation form'
);
$pluginSignature = 't3odonation_form';
$TCA['tt_content']['types']['list']['subtypes_excludelist'][$pluginSignature] = 'layout,select_key';
$TCA['tt_content']['types']['list']['subtypes_addlist'][$pluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
$pluginSignature,
'FILE:EXT:t3o_donation/Configuration/FlexForms/donation_form.xml'
);
......@@ -196,6 +196,7 @@ return [
['frontend users', '--div--'],
],
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'fe_users',
'minitems' => 0,
'maxitems' => 1,
......@@ -206,6 +207,7 @@ return [
'label' => 'LLL:EXT:t3o_donation/Resources/Private/Language/locallang_db.xlf:tx_t3odonation_domain_model_donation.account',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'tx_t3odonation_domain_model_account',
'minitems' => 1,
'maxitems' => 1,
......
......@@ -51,3 +51,73 @@ Control Flow
* cancel_return: if the user cancels the payment, the user is redirectd to the form
Testing and debugging the PayPal IPN API
----------------------------------------
PayPal documentation: https://developer.paypal.com/docs/ipn/integration-guide/IPNIntro/
Get a PayPal sandbox API account: https://developer.paypal.com/docs/api/sandbox/
Set LogLevel to DEBUG to see the full ipn requests from PayPal:
```
$GLOBALS['TYPO3_CONF_VARS']['LOG']['writerConfiguration'] = [
\TYPO3\CMS\Core\Log\LogLevel::DEBUG => [
\TYPO3\CMS\Core\Log\Writer\FileWriter::class => []
]
];
```
Watch out for `component="T3o.T3oDonation.Service.PayPalIpn"` in the log file
There is already a test page set up: https://typo3.org.ddev.site/404/donation/test-donation
This are important settings for tests:
1. TypoScript `plugin.tx_t3odonation_form.settings.paypal.action = https://www.sandbox.paypal.com/cgi-bin/webscr`
2. A PayPal sandbox "BUSINESS" email as "PayPal E-Mail" (email_paypal) in the "Donation Account". Use the id in the parameter `custom` before the pipe |
3. A fe_user to test the connection between donation and user. Use the id in the parameter `custom` after the pipe |
To test without PayPal, send a request, f.e. with cUrl. The URL is the `notify_url` in the frontend form
```
curl -X "POST" "https://typo3.org.ddev.site/404/donation/test-donation?tx_t3odonation_form%5Baction%5D=ipnLog&tx_t3odonation_form%5Bcontroller%5D=Donation&cHash=8f8f9bc36b3d8bbe7887dbcc7b180977" \
-H "Content-Type: application/x-www-form-urlencoded" \
-i \
--data-urlencode "receiver_email=sb-0yzasd4j1329439@personal.example.com" \
--data-urlencode "receiver_id=FGKADSFEH8PWYG" \
--data-urlencode "residence_country=DE" \
--data-urlencode "test_ipn=1" \
--data-urlencode "txn_type=subscr_signup" \
--data-urlencode "payer_email=sb-s5asddvb1343733@personal.example.com" \
--data-urlencode "payer_id=YQE5ADS9Y8J" \
--data-urlencode "payer_status=verified" \
--data-urlencode "first_name=John" \
--data-urlencode "last_name=Doe" \
--data-urlencode "custom=3|1" \
--data-urlencode "item_name=Regular donation" \
--data-urlencode "mc_currency=EUR" \
--data-urlencode "mc_amount3=125.00" \
--data-urlencode "notify_version=3.9" \
--data-urlencode "charset=windows-1252" \
--data-urlencode "verify_sign=AzEG6k2z2E1Rv0.uASDASDp7sQh9Ac.bLcw99NJFU35o0zQJz6ZlSRmc" \
--data-urlencode "subscr_id=I-EBASDDA3S1CX" \
--data-urlencode "business=sb-0yzasd4j1329439@personal.example.com" \
--data-urlencode "recurring=1" \
--data-urlencode "reattempt=1" \
--data-urlencode "subscr_date=02:07:18 May 04, 2020 PDT" \
--data-urlencode "period3=1 M" \
--data-urlencode "ipn_track_id=913ASDe76b59"
```
This will always return "INVALID" so you have to adjust `\T3o\T3oDonation\Service\PayPalIpn::verify` and return always `true`. More infos on https://developer.paypal.com/docs/ipn/integration-guide/IPNTesting/#local-development-testing
Final test with PayPal need a public domain
1. Start `ddev share` to get a public domain
2. Replace "typo3.org.ddev.site" in /config/sites/t3org/config.yaml with the public domain from ddev share
3. Make a donation in the frontend. Use a PayPal sandbox "PERSONAL" account to login to PayPal.
4. Have a look at the TYPO3-log. After some minutes you can see the request from PayPal and the donation record should be created and the mails should be sent to (check in MailHog).
Example log entries for regular subscription:
```
Mon, 04 May 2020 11:11:21 +0200 [DEBUG] request="2cfa3181a6647" component="T3o.T3oDonation.Service.PayPalIpn": Verifing PayPal IPN - {"transaction_subject":"Regular donation","payment_date":"02:07:20 May 04, 2020 PDT","txn_type":"subscr_payment","subscr_id":"I-EBasdasd3S1CX","last_name":"Doe","residence_country":"DE","item_name":"Regular donation","payment_gross":"","mc_currency":"EUR","business":"sb-asdsadasddfgs9439@personal.example.com","payment_type":"instant","protection_eligibility":"Ineligible","verify_sign":"AuY-F0VdsfdsfasdTEw2rk4TsQ6.pUAePTPJ7d2lnQ7Y1-SP7KizTU5GPL","payer_status":"verified","test_ipn":"1","payer_email":"sb-s5ddsfsfsad43733@personal.example.com","txn_id":"19U80424U4878220W","receiver_email":"sb-0yasdgvdfs329439@personal.example.com","first_name":"John","payer_id":"YQE5asdasd9Y8J","receiver_id":"FGKasdasd8PWYG","contact_phone":"788-843-0840","payment_status":"Completed","payment_fee":"","mc_fee":"2.73","mc_gross":"125.00","custom":"3|1","charset":"windows-1252","notify_version":"3.9","ipn_track_id":"9130b30e76b59"}
Mon, 04 May 2020 11:11:21 +0200 [DEBUG] request="2cfa3181a6647" component="T3o.T3oDonation.Service.PayPalIpn": Requesting verification from PayPal - {"form_params":{"transaction_subject":"Regular donation","payment_date":"02:07:20 May 04, 2020 PDT","txn_type":"subscr_payment","subscr_id":"I-EBasdasdS1CX","last_name":"Doe","residence_country":"DE","item_name":"Regular donation","payment_gross":"","mc_currency":"EUR","business":"sb-asdasd29439@personal.example.com","payment_type":"instant","protection_eligibility":"Ineligible","verify_sign":"AuY-F0VRY9tasdasdrk4TsQ6.pUAePTPJ7d2lnQ7Y1-SP7KizTU5GPL","payer_status":"verified","test_ipn":"1","payer_email":"sb-s5dvgfhsdf733@personal.example.com","txn_id":"19U8dfgdfU4878220W","receiver_email":"sb-0ysdfsdf39@personal.example.com","first_name":"John","payer_id":"YQasdasdRV9Y8J","receiver_id":"FGKasdasdH8PWYG","contact_phone":"788-843-0840","payment_status":"Completed","payment_fee":"","mc_fee":"2.73","mc_gross":"125.00","custom":"3|1","charset":"windows-1252","notify_version":"3.9","ipn_track_id":"9fdgdfg76b59","cmd":"_notify-validate"}}
Mon, 04 May 2020 11:11:23 +0200 [DEBUG] request="2cfa3181a6647" component="T3o.T3oDonation.Service.PayPalIpn": Got response for IPN verification. - {"body":"VERIFIED"}
```
......@@ -11,7 +11,7 @@
<input type="hidden" name="no_note" value="0">
<input type="hidden" name="return" value="{f:uri.action(action: 'thankyou', absolute: 1)}">
<input type="hidden" name="cancel_return" value="{f:uri.action(action: 'form', absolute: 1)}">
<input type="hidden" name="notify_url" value="{f:uri.action(action: 'ipnlog', absolute: 1 )}">
<input type="hidden" name="notify_url" value="{f:uri.action(action: 'ipnLog', absolute: 1)}">
<input type="hidden" name="tax" value="0">
<input type="hidden" name="lc" value="US">
<input type="hidden" name="custom" value="{account.uid}|{userId}">
......
......@@ -19,10 +19,10 @@ if (!defined('TYPO3_MODE')) {
't3o_donation',
'Form',
[
\T3o\T3oDonation\Controller\DonationController::class => 'form, thankyou, ipnlog',
\T3o\T3oDonation\Controller\DonationController::class => 'form, thankyou, ipnLog',
],
[
\T3o\T3oDonation\Controller\DonationController::class => 'form, thankyou, ipnlog',
\T3o\T3oDonation\Controller\DonationController::class => 'form, thankyou, ipnLog',
]
);
......
......@@ -67,6 +67,7 @@ return [
['Copy Editor', 2],
['Proofreader', 3],
['Translator', 4],
['Content Publisher', 5],
]
],
],
......
# check if news detail view
[request.getQueryParams()['tx_news_pi1]['news'] > 0]
page.headerData {
# remove all meta tags from cs_seo
654 >
}
config.noPageTitle = 2
temp.newsTitle = RECORDS
temp.newsTitle {
dontCheckPid = 1
tables = tx_news_domain_model_news
source {
data = GP:tx_news_pi1|news
intval = 1
}
conf.tx_news_domain_model_news = TEXT
conf.tx_news_domain_model_news {
field = title
htmlSpecialChars = 1
}
wrap = <title>|</title>
}
page.headerData.1 >
page.headerData.1 < temp.newsTitle
[end]
config.pageTitleSeparator =
......@@ -60,37 +60,3 @@ pageNewsICalendar {
linkVars >
}
}
[globalVar = GP:tx_sfeventmgt_pievent|event > 0]
# remove all meta tags from cs_seo
page.headerData.654 >
config.noPageTitle = 2
temp.eventTitle = RECORDS
temp.eventTitle {
dontCheckPid = 1
source {
data = GP:tx_sfeventmgt_pievent|event
intval = 1
}
tables = tx_sfeventmgt_domain_model_event
conf {
tx_sfeventmgt_domain_model_event >
tx_sfeventmgt_domain_model_event = TEXT
tx_sfeventmgt_domain_model_event {
field = title
htmlSpecialChars = 1
noTrimWrap = |||
}
}
}
page.headerData {
23424 = COA
23424 < temp.eventTitle
23424.wrap = <title>|</title>
}
[end]
......@@ -26,6 +26,9 @@
<trans-unit id="tx_t3org_layout.news.contributors.roles.4">
<source>Translator</source>
</trans-unit>
<trans-unit id="tx_t3org_layout.news.contributors.roles.5">
<source>Content Publisher</source>
</trans-unit>
</body>
</file>
</xliff>
......@@ -129,6 +129,28 @@ return [
],
],
'FE' => [
'cacheHash' => [
'excludedParameters' => [
'L',
'pk_campaign',
'pk_kwd',
'utm_source',
'utm_medium',
'utm_campaign',
'utm_term',
'utm_content',
'gclid',
'fbclid',
'token',
'tx',
'st',
'amt',
'cc',
'cm',
'item_number',
'item_name',
],
],
'debug' => true,
'loginSecurityLevel' => 'normal',
],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment