Skip to content

Commit

Permalink
Merge pull request #73 from maikschneider/sf-event-mgt
Browse files Browse the repository at this point in the history
[FEATURE] Support for sf_event_mgt
  • Loading branch information
maikschneider authored Nov 16, 2024
2 parents 2a5a97e + 936df9c commit 75af5e8
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Blueways\BwCaptcha\EventListener;

use Blueways\BwCaptcha\Validation\Validator\CaptchaValidator;
use DERHANSEN\SfEventMgt\Event\ModifyRegistrationValidatorResultEvent;
use TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator;
use TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator;

class ModifyRegistrationValidatorResultEventListener
{
public function __invoke(ModifyRegistrationValidatorResultEvent $event): void
{
$captchaSettings = $event->getSettings()['registration']['captcha'] ?? [];
$isCaptchaEnabled = isset($captchaSettings['enabled']) && $captchaSettings['enabled'];
$isBwCaptchaEnabled = isset($captchaSettings['type']) && $captchaSettings['type'] === 'bwCaptcha';

if (!$isCaptchaEnabled || !$isBwCaptchaEnabled) {
return;
}

$validator = new ConjunctionValidator();
$validator->addValidator(new NotEmptyValidator());
$validator->addValidator(new CaptchaValidator());

$result = $validator->validate($event->getRegistration()->getCaptcha());

$event->getResult()->forProperty('captcha')->merge($result);
}
}
5 changes: 5 additions & 0 deletions Configuration/Services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ services:

Blueways\BwCaptcha\Middleware\Captcha:
public: true

Blueways\BwCaptcha\EventListener\ModifyRegistrationValidatorResultEventListener:
tags:
- name: event.listener
identifier: 'bw-captcha/sf-event-mgt-registration'
9 changes: 9 additions & 0 deletions Configuration/TypoScript/setup.typoscript
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ plugin.tx_bwcaptcha {
}
}

plugin.tx_sfeventmgt {
view {
partialRootPaths.999999 = EXT:bw_captcha/Resources/Private/SfEventMgt/
}
settings.registration.captcha {
bwCaptcha < plugin.tx_bwcaptcha.settings
}
}

captcha = PAGE
captcha {
typeNum = 3413
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,34 @@ plugin.tx_bwcaptcha {
}
```

### Usage in other Extensions

#### sf_event_mgt

To use the captcha element in the [sf_event_mgt](https://github.com/derhansen/sf_event_mgt/) extension, add the following TypoScript:

```
plugin.tx_sfeventmgt {
settings {
registration {
requiredFields = captcha
captcha {
enabled = 1
type = bwCaptcha
}
}
}
}
```

If you want to override the shipped [BwCaptcha.html](https://github.com/maikschneider/bw_captcha/blob/main/Resources/Private/SfEventMgt/Registration/Captcha/BwCaptcha.html) partial, you need to configure the partialRootPaths with a higher index:

```
plugin.tx_sfeventmgt.view.partialRootPaths.9999999 = EXT:your_ext/Resources/Private/Partials/
```

```yaml

### Overriding the captcha element

To override the captcha partial, copy it to your extension and add the partial path to
Expand Down
61 changes: 61 additions & 0 deletions Resources/Private/SfEventMgt/Registration/Captcha/BwCaptcha.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:e="http://typo3.org/ns/DERHANSEN/SfEventMgt/ViewHelpers"
data-namespace-typo3-fluid="true">

<f:if condition="{settings.registration.captcha.enabled} && {settings.registration.captcha.type} == 'bwCaptcha'">
<div class="event-registration-row captcha {e:validation.errorClass(fieldname: 'captcha')}">
<label for="captcha">
<f:translate key="formEditor.elements.Captcha" extensionName="bw_captcha" />
<span class="event-required">*</span>
</label>
<div class="captcha">
<img src="{f:uri.page(pageType:3413)}"
alt="{f:translate(extensionName:'bw_captcha',key:'partial.image.alt')}"
aria-live="polite"
loading="lazy"
onload="this.parentElement.classList.remove('captcha--reloading'); return false;"/>
<f:if condition="{settings.registration.captcha.bwCaptcha.refreshButton}">
<a class="captcha__reload"
href="#"
title="{f:translate(extensionName:'bw_captcha',key:'partial.refresh.title')}"
aria-label="{f:translate(extensionName:'bw_captcha',key:'partial.refresh.label')}"
role="button"
data-url="{f:uri.page(pageType:3413)}"
onclick="const div = this.parentElement; div.classList.add('captcha--reloading', 'captcha--spin'); let captchaUrl = this.dataset.url; this.previousElementSibling.setAttribute('src', captchaUrl + (/\?/.test(captchaUrl) ? '&' : '?') + 'now=' + Date.now()); setTimeout(function(){div.classList.remove('captcha--spin')},400); return false;">
<svg width="31" height="28" xmlns="http://www.w3.org/2000/svg">
<g fill="#000" fill-rule="evenodd">
<path d="M10 10.7 6.3 8.5a11 11 0 0 1 20 3l2.5-.8h.4v-.3A14 14 0 0 0 3.6 7L.3 5l1.8 8.3 8-2.6ZM31 23l-1.7-8-8 2.5 3.7 2.1a10.9 10.9 0 0 1-19.8-2.3l-2 .6-1 .3a13.9 13.9 0 0 0 17 9.3 14 14 0 0 0 8.4-6.4l3.4 2Z"/>
</g>
</svg>
</a>
</f:if>
<f:if condition="{settings.registration.captcha.bwCaptcha.audioButton}">
<a class="captcha__audio"
href="#"
data-url="{f:uri.page(pageType:3414)}"
title="{f:translate(extensionName:'bw_captcha',key:'partial.audio.title')}"
aria-label="{f:translate(extensionName:'bw_captcha',key:'partial.audio.label')}"
role="button"
onclick="const div = this.parentElement;window.captchaAudio = window.captchaAudio ? window.captchaAudio : new Audio();window.captchaAudio.addEventListener('ended', () => div.classList.remove('captcha--playing'));if (window.captchaAudio.paused) { div.classList.add('captcha--playing'); const img = div.querySelector('img'); const c = document.createElement('canvas'); const ctx = c.getContext('2d'); const data = new FormData(); c.width = img.naturalWidth; c.height = img.naturalHeight; ctx.drawImage(img, 0, 0); data.append('captchaDataUrl', c.toDataURL());fetch('{f:uri.page(pageType:3414)}', {method: 'POST',body: data}).then(response => response.blob()).then(blob => { window.captchaAudio.src = window.URL.createObjectURL(blob); window.captchaAudio.play(); });} else { window.captchaAudio.pause();div.classList.remove('captcha--playing')} return false;">
<svg xmlns="http://www.w3.org/2000/svg" height="35" fill="none" viewBox="0 0 115 100">
<path fill="#000"
d="M59.145 50.136v39.223c0 1.334-.135 2.667-1.65 3.256-1.521.588-2.308-.386-3.173-1.256C48.197 85.255 42.025 79.188 36 73a7.603 7.603 0 0 0-6.162-2.666c-5.734.187-11.479.078-17.23 0-3 0-3.494-.495-3.494-3.438v-33.88c0-2.666.589-3.317 3.318-3.333H30.786a5.705 5.705 0 0 0 4.48-1.87c6.067-6.078 12.203-12.146 18.322-18.307a14.896 14.896 0 0 1 1.64-1.546 2.285 2.285 0 0 1 2.392-.428 2.296 2.296 0 0 1 1.432 1.964c.114.833.146 1.677.094 2.52.02 12.71.02 25.417 0 38.121Z"/>
<path fill="#000"
class="captcha__audio__mute"
d="M67.935 29.935a3.192 3.192 0 0 1 4.515 0l15.05 15.05 15.05-15.05a3.192 3.192 0 1 1 4.515 4.515L92.015 49.5l15.05 15.05a3.192 3.192 0 1 1-4.515 4.515L87.5 54.015l-15.05 15.05a3.192 3.192 0 1 1-4.515-4.515l15.05-15.05-15.05-15.05a3.192 3.192 0 0 1 0-4.515Z"/>
<path fill="#000"
class="captcha__audio__sound"
d="M97.839 49.896a42.769 42.769 0 0 1-11.584 29.625c-.432.485-.906.927-1.416 1.334A3.642 3.642 0 0 1 80 80.563a3.737 3.737 0 0 1-.307-4.667c.463-.593.963-1.156 1.495-1.682a35.772 35.772 0 0 0 9.349-23.964 35.784 35.784 0 0 0-9.162-24.036 18.253 18.253 0 0 1-1.693-1.896 3.74 3.74 0 0 1 .532-4.864 3.57 3.57 0 0 1 4.65-.105c.59.47 1.131.995 1.615 1.573a42.513 42.513 0 0 1 11.36 28.974Z"/>
<path fill="#000"
class="captcha__audio__sound"
d="M81.333 51.667a25.566 25.566 0 0 1-6.562 16 10.73 10.73 0 0 1-1.6 1.588 3.71 3.71 0 0 1-4.88-.323A3.603 3.603 0 0 1 68 64.24c.375-.547.865-1 1.333-1.506a19.157 19.157 0 0 0-.172-25.495c-.307-.359-.65-.682-.932-1.051a3.695 3.695 0 0 1 .318-5.084 3.749 3.749 0 0 1 5.104.203c.86.85 1.646 1.766 2.349 2.745 3.495 4.64 5.333 10.177 5.333 17.615Z"/>
</svg>
</a>
</f:if>
</div>
<f:form.textfield id="captcha" property="captcha" /><br>
<f:render partial="FormErrors" arguments="{field: 'registration.captcha'}"/>
</div>
</f:if>

</html>
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
"roave/security-advisories": "dev-latest",
"typo3/cms-base-distribution": "^12.0",
"typo3/cms-lowlevel": "^12.0",
"bk2k/bootstrap-package": "dev-master",
"bk2k/bootstrap-package": "^15.0",
"friendsofphp/php-cs-fixer": "^3.12",
"saschaegerer/phpstan-typo3": "^1.9",
"helhum/typo3-console": "^8.0"
"helhum/typo3-console": "^8.0",
"derhansen/sf_event_mgt": "^7.6"
},
"extra": {
"typo3/cms": {
Expand Down

0 comments on commit 75af5e8

Please sign in to comment.