madj2k/t3-fe-register

FE-Users和FE-Usergroups注册扩展

安装: 120

依赖关系: 12

建议者: 1

安全性: 0

星标: 0

关注者: 2

分支: 0

公开问题: 0

类型:typo3-cms-extension

v10.4.7-stable 2024-05-24 14:54 UTC

README

特性

  • 带有双确认的注册过程
  • 普通用户登录
  • 通过链接以访客身份登录
  • 自我注册到指定的用户组,包括管理员批准
  • 广泛的GDPR同意管理
  • 删除记录的加密和匿名化(GDPR)
  • 自动清理删除的记录(GDPR)
  • 易于集成到您自己的扩展中

在您的扩展中应用

同意

1. 在您的控制器中生成同意

对于带有同意的注册,请在控制器中使用以下示例代码。请确保始终通过ObjectManager加载FrontendUserRegistration。解释

  • setData: 仅在成功同意后设置要创建的对象。在商店中可能是订单。
  • setParentData: 指向同意对象的父对象。这对于记录用户给予的同意是相关的。在商店中可能是订单的一部分产品。
  • setCategory: 这样您可以在扩展中使用自己的SignalSlots与同意过程交互
  • setRequest: 简单地说,是当前的Request选项。这对于记录用户给予的同意是相关的。
/** @var \Madj2k\FeRegister\Domain\Model\FrontendUser $frontendUser */
$frontendUser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(FrontendUser::class);
$frontendUser->setEmail($email);

/** @var \Madj2k\FeRegister\Registration\FrontendUserRegistration $registration */
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class);
$registration = $objectManager->get(FrontendUserRegistration::class);
$registration->setFrontendUser($frontendUser)
    ->setData($alert)
    ->setDataParent($project) // optional, but nice to have
    ->setCategory('YourCategory')
    ->setRequest($request)
    ->startRegistration();

如果您想在成功同意后更新前端用户的资料,可以使用方法 setFrontendUserUpdate。这将更新前端用户对象,一旦用户接受同意。这样您可以确保只有授权的更改才会发生。

2. 定义Opt-In邮件的MailService

现在您需要一个定义了Opt-In操作的MailService类

/**
* Handles opt-in event
*
* @param \Madj2k\FeRegister\Domain\Model\FrontendUser $frontendUser
* @param \Madj2k\FeRegister\Domain\Model\OptIn $optIn
* @return void
* @throws \Madj2k\Postmaster\Exception
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3Fluid\Fluid\View\Exception\InvalidTemplateResourceException
* @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException
*/
public function optIn (
    \Madj2k\FeRegister\Domain\Model\FrontendUser $frontendUser,
    \Madj2k\FeRegister\Domain\Model\OptIn $optIn
): void  {

    // get settings
    $settings = $this->getSettings(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
    $settingsDefault = $this->getSettings();

    if ($settings['view']['templateRootPaths']) {

        /** @var \Madj2k\Postmaster\Mail\MailMessage $mailService */
        $mailService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(MailMessage::class);

        // send new user an email with token
        $mailService->setTo($frontendUser, array(
            'marker' => array(
                'frontendUser' => $frontendUser,
                'optIn'        => $optIn,
                'pageUid'      => intval($GLOBALS['TSFE']->id),
                'loginPid'     => intval($settingsDefault['loginPid']),
            ),
        ));

        $mailService->getQueueMail()->setSubject(
            FrontendLocalizationUtility::translate(
                'mailService.optInAlertUser.subject',
                'your_extension',
                null,
                $frontendUser->getTxFeregisterLanguageKey()
            )
        );

        $mailService->getQueueMail()->addTemplatePaths($settings['view']['templateRootPaths']);
        $mailService->getQueueMail()->addPartialPaths($settings['view']['partialRootPaths']);

        $mailService->getQueueMail()->setPlaintextTemplate('Email/OptInAlertUser');
        $mailService->getQueueMail()->setHtmlTemplate('Email/OptInAlertUser');
        $mailService->send();
    }
}

3. 设置信号-槽

现在我们需要一个信号-槽,该槽指向发送邮件的指定方法(ext_localconf.php)

/**
 * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
 */
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class);
$signalSlotDispatcher->connect(
    Madj2k\FeRegister\Registration\AbstractRegistration::class,
    Madj2k\FeRegister\Registration\AbstractRegistration::SIGNAL_AFTER_CREATING_OPTIN  . 'YourCategory',
    Your\Extension\Service\MailService::class,
    'optInAlertUser'
);

4. 设置Opt-In邮件的模板

Opt-In电子邮件可能如下所示

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
	xmlns:postmaster="http://typo3.org/ns/Madj2k/Postmaster/ViewHelpers"
	data-namespace-typo3-fluid="true">

	<f:layout name="Email/{mailType}" />

	<!-- PLAINTEXT -->
	<f:section name="Plaintext"><postmaster:email.plaintextLineBreaks>
	    <postmaster:email.translate key="templates_email_optInAlertUser.textOptInLinkLabel" languageKey="{queueRecipient.languageCode}" extensionName="yourExtension"/>:\n
	    <postmaster:email.uri.action action="optIn" controller="Alert" extensionName="yourExtension" pluginName="yourExtension" absolute="true" pageUid="{pageUid}" additionalParams="{tx_yourextenion_plugin: {token: optIn.tokenYes, tokenUser: optIn.tokenUser}}" section="your-extension" />\n\n

        <postmaster:email.translate key="templates_email_optInAlertUser.textOptOutLinkLabel" languageKey="{queueRecipient.languageCode}" extensionName="yourExtension"/>:\n
        <postmaster:email.uri.action action="optIn" controller="Alert" extensionName="yourExtension" pluginName="yourExtension" absolute="true" pageUid="{pageUid}" additionalParams="{tx_yourextenion_plugin: {token: optIn.tokenNo, tokenUser: optIn.tokenUser}}" section="your-extension" />
    </postmaster:email.plaintextLineBreaks></f:section>

	<!-- HTML -->
	<f:section name="Html">
		<a href="<postmaster:email.uri.action action='optIn' controller='Alert' extensionName='yourExtension' pluginName='yourExtension' absolute='true' pageUid='{pageUid}' additionalParams='{tx_yourextenion_plugin: {token: optIn.tokenYes, tokenUser: optIn.tokenUser}}' section='your-extension' />"><postmaster:email.translate key="templates_email_optInAlertUser.textOptInLinkLabel" languageKey="{queueRecipient.languageCode}" extensionName="yourExtension"/></a>
		<a href="<postmaster:email.uri.action action='optIn' controller='Alert' extensionName='yourExtension' pluginName='yourExtension' absolute='true' pageUid='{pageUid}' additionalParams='{tx_yourextenion_plugin: {token: optIn.tokenNo, tokenUser: optIn.tokenUser}}' section='your-extension' />"><postmaster:email.translate key="templates_email_optInAlertUser.textOptOutLinkLabel" languageKey="{queueRecipient.languageCode}" extensionName="yourExtension"/></a>
	</f:section>

</html>

5. 检查同意

要检查同意,您可以在控制器中使用以下示例代码

public function optInAction(string $tokenUser, string $token): void
{
    /** @var \Madj2k\FeRegister\Registration\FrontendUserRegistration $registration */
    $registration = $this->objectManager->get(FrontendUserRegistration::class);
    $result = $registration->setFrontendUserToken($tokenUser)
        ->setCategory('yourExtension')
        ->setRequest($this->request)
        ->validateOptIn($token);

    if ($result >= 200 && $result < 300) {

        // sucessfull

    } elseif ($result >= 300 && $result < 400) {

        // canceled

    } else {
        // error / not found
    }
}

6. Opt-In后的扩展特定操作的信号-槽

我们需要第二个信号-槽以在同意后执行所需的操作

    $signalSlotDispatcher->connect(
        Madj2k\FeRegister\Registration\AbstractRegistration::class,
        Madj2k\FeRegister\Registration\AbstractRegistration::SIGNAL_AFTER_REGISTRATION_COMPLETED . 'YourExtension',
        Your\Extension\Alerts\AlertManager::class',
        'saveAlertByRegistration'
    );

7. 特定操作的方 法

然后我们需要定义相应的方法

    /**
     * Save alert by registration
     * Used by SignalSlot
     *
     * @param \Madj2k\FeRegister\Domain\Model\FrontendUser $frontendUser
     * @param \Madj2k\FeRegister\Domain\Model\OptIn $optIn
     * @return void
     * @api Used by SignalSlot
     */
    public function saveAlertByRegistration(
        \Madj2k\FeRegister\Domain\Model\FrontendUser $frontendUser,
        \Madj2k\FeRegister\Domain\Model\OptIn $optIn
    ) {

        if (
            ($alert = $optIn->getData())
            && ($alert instanceof \Your\Extension\Domain\Model\Alert)
        ) {

            try {
                // create alert here
            } catch (\Your\Extension\Exception $exception) {
                // do nothing here
            }
        }
    }

其他用例

  • 您还可以:** 在成功同意后发送确认电子邮件(使用SIGNAL_AFTER_ALERT_CREATED-Signal-Slot)** 在前端用户被删除时删除所有扩展特定数据(使用SIGNAL_AFTER_REGISTRATION_ENDED-Signal-Slot)** ... 做很多其他有趣的事情 ;-)

同意(隐私、条款、营销)

该扩展具有用于获取隐私、使用条款和高级营销同意的ViewHelper和验证器。为了获得同意,只需在自己的扩展中使用相应的ViewHelper即可。一旦执行了同意,相应的同意将自动记录并存储在数据库中。授予的同意将根据相关数据(IP地址、浏览器等)进行记录。此外,将存储在FrontendUser中的使用条款和营销同意,因为这些同意通常是跨页面的,并且独立于同意的相应上下文。

1. 在Fluid中

以下代码可以用于获取适当的同意。使用ViewHelper在表单中,并且通过Fluid返回FormErrors非常重要。

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
	xmlns:feRegister="http://typo3.org/ns/Madj2k/FeRegister/ViewHelpers"
	data-namespace-typo3-fluid="true">

    <f:render partial="FormErrors" arguments="{object:alert}" />

	<f:form action="create" name="alert" object="{alert}">

        [...]

        <feRegister:consent type="terms" />
        <feRegister:consent type="privacy" key="default" />
        <feRegister:consent type="marketing" />

        [...]

	</f:form>
</html>

如果您没有实际的对象要发送,也可以使用一个模拟对象。

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
	xmlns:feRegister="http://typo3.org/ns/Madj2k/FeRegister/ViewHelpers"
	data-namespace-typo3-fluid="true">

    <f:render partial="FormErrors" arguments="{object:dummyObject}" />

	<f:form action="create" name="alert" object="{dummyObject}">

        [...]

        <!-- dummy field for validator -->
        <f:form.textfield name="dummy" value="1" type="hidden" />

        <feRegister:consent type="terms" />
        <feRegister:consent type="privacy" key="default" />
        <feRegister:consent type="marketing" />

        [...]

	</f:form>
</html>

2. 在控制器中

这里只包括相应的验证器。它们始终指向表单对象。

    /**
     * action create
     *
     * @param \Your\Extension\Domain\Model\Alert $alert
     * @param string $email
     * @return void
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
     * @TYPO3\CMS\Extbase\Annotation\Validate("Madj2k\FeRegister\Validation\Consent\TermsValidator", param="alert")
     * @TYPO3\CMS\Extbase\Annotation\Validate("Madj2k\FeRegister\Validation\Consent\PrivacyValidator", param="alert")
     * @TYPO3\CMS\Extbase\Annotation\Validate("Madj2k\FeRegister\Validation\Consent\MarketingValidator", param="alert")
     */
    public function createAction(
        \Your\Extension\Domain\Model\Alert $alert,
        string $email = ''
    ): void {

        [...]
    }


    /**
     * A template method for displaying custom error flash messages, or to
     * display no flash message at all on errors. Override this to customize
     * the flash message in your action controller.
     *
     * @return string|false The flash message or FALSE if no flash message should be set
     */
    protected function getErrorFlashMessage()
    {
        return false;
    }

或者当使用模拟对象时

 /**
     * action create
     *
     * @param bool dummy
     * @return void
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
     * @TYPO3\CMS\Extbase\Annotation\Validate("Madj2k\FeRegister\Validation\Consent\TermsValidator", param="dummy")
     * @TYPO3\CMS\Extbase\Annotation\Validate("Madj2k\FeRegister\Validation\Consent\PrivacyValidator", param="dummy")
     * @TYPO3\CMS\Extbase\Annotation\Validate("Madj2k\FeRegister\Validation\Consent\MarketingValidator", param="dummy")
     */
    public function createAction(
       array $dummy
    ): void {

        [...]
    }


    /**
     * A template method for displaying custom error flash messages, or to
     * display no flash message at all on errors. Override this to customize
     * the flash message in your action controller.
     *
     * @return string|false The flash message or FALSE if no flash message should be set
     */
    protected function getErrorFlashMessage()
    {
        return false;
    }

通常不会对已登录的前端用户执行“选择加入”程序。如果您仍然想要记录注册时同意的时间,可以使用以下代码实现。

    \Madj2k\FeRegister\DataProtection\ConsentHandler::add(
        $request,
        $frontendUser,
        $alert,
        'new alert'
    );

在从rkw_registration迁移到fe_register时

在安装之前执行以下MySQL查询!

RENAME TABLE `tx_rkwregistation_domain_model_privacy` TO `tx_feregister_domain_model_consent`;
RENAME TABLE `tx_rkwregistration_domain_model_encrypteddata` TO `tx_feregister_domain_model_encrypteddata`;
RENAME TABLE `tx_rkwregistration_domain_model_shippingaddress` TO `tx_feregister_domain_model_shippingaddress`;
RENAME TABLE `tx_rkwregistration_domain_model_title` TO `tx_feregister_domain_model_title`;

在安装之后执行以下MySQL查询!

UPDATE fe_users SET tx_feregister_title = tx_rkwregistration_title;
UPDATE fe_users SET tx_feregister_gender = tx_rkwregistration_gender;
UPDATE fe_users SET tx_feregister_mobile = tx_rkwregistration_mobile;
UPDATE fe_users SET tx_feregister_twitter_url = tx_rkwregistration_twitter_url;
UPDATE fe_users SET tx_feregister_facebook_url = tx_rkwregistration_facebook_url;
UPDATE fe_users SET tx_feregister_xing_url = tx_rkwregistration_xing_url;
UPDATE fe_users SET tx_feregister_register_remote_ip = tx_rkwregistration_register_remote_ip;
UPDATE fe_users SET tx_feregister_language_key  = tx_rkwregistration_language_key;
UPDATE fe_users SET tx_feregister_login_error_count = tx_rkwregistration_login_error_count;
UPDATE fe_users SET tx_feregister_data_protection_status = tx_rkwregistration_data_protection_status;
UPDATE fe_users INNER JOIN tx_feregister_domain_model_consent ON fe_users.uid = tx_feregister_domain_model_consent.frontend_user AND tx_feregister_domain_model_consent.parent = 0 SET fe_users.tx_feregister_consent_privacy = 1, fe_users.tx_feregister_consent_terms = 1;
UPDATE tx_feregister_domain_model_consent SET consent_privacy = 1, consent_terms = 1  WHERE parent = 0;
UPDATE tt_content SET list_type = 'feregister_auth' WHERE list_type = 'rkwregistration_rkwregistration' AND pi_flexform LIKE '%<value index=\"vDEF\">Registration-&gt;loginShow;%';
UPDATE tt_content SET list_type = 'feregister_auth' WHERE list_type = 'rkwregistration_rkwregistration' AND pi_flexform LIKE '%<value index=\"vDEF\">Registration-&gt;registerShow;%';
UPDATE tt_content SET list_type = 'feregister_welcome' WHERE list_type = 'rkwregistration_rkwregistration' AND pi_flexform LIKE '%<value index=\"vDEF\">Registration-&gt;welcome;%';
UPDATE tt_content SET list_type = 'feregister_useredit' WHERE list_type = 'rkwregistration_rkwregistration' AND pi_flexform LIKE '%<value index=\"vDEF\">Registration-&gt;editUser;%';
UPDATE tt_content SET list_type = 'feregister_userdelete'WHERE list_type = 'rkwregistration_rkwregistration' AND pi_flexform LIKE '%<value index=\"vDEF\">Registration-&gt;deleteUserShow;%';
UPDATE tt_content SET list_type = 'feregister_password' WHERE list_type = 'rkwregistration_rkwregistration' AND pi_flexform LIKE '%<value index=\"vDEF\">Registration-&gt;editPassword;%';
UPDATE tt_content SET list_type = 'feregister_group' WHERE list_type = 'rkwregistration_rkwregistration' AND pi_flexform LIKE '%<value index=\"vDEF\">Service-&gt;list;%';
UPDATE tt_content SET list_type = 'feregister_auth' WHERE list_type = 'rkwregistration_rkwregistration' AND pi_flexform LIKE '%<value index=\"vDEF\">Service-&gt;optIn;%';
UPDATE tt_content SET list_type = 'feregister_logout' WHERE list_type = 'rkwregistration_rkwregistration' AND pi_flexform LIKE '%<value index=\"vDEF\">Registration-&gt;logout;%';
UPDATE tt_content SET pi_flexform = '' WHERE list_type LIKE 'feregister%';