first commit

This commit is contained in:
salam committed 2026-10-06 19:40:28 +02:00
commit e81864e683
2984 files changed
+267797

No files matched your search

@@ -0,0 +1,133 @@
.. include:: ../../Includes.rst.txt
.. _autoconfirmation:
Auto admin confirmation
-----------------------
Introduction
^^^^^^^^^^^^
**Available since 4.0.0**
If you turn on an adminconfirmation by adding an email address in the FlexForm field, admins normally have to confirm
new requests from users. But it's possible to implement some own magic to make a confirmation happen automaticly.
You can add own AutoAdminConfirmation classes to bring in own magic (auto confirmation for an IP-Range, etc...).
At the moment, femanager offers only one AutoAdminConfirmation class, which decided which users are auto-confirmed by
the top-level-domain of the email-address.
EmailDomainConfirmation
^^^^^^^^^^^^^^^^^^^^^^^
Small example
'''''''''''''
Accept every user profile from domains de, it, ch and at:
.. code-block:: typoscript
plugin.tx_femanager.settings {
autoAdminConfirmation {
# Femanager autoAdminConfirmation classes
10 {
class = In2code\Femanager\Domain\Service\AutoAdminConfirmation\EmailDomainConfirmation
config {
# Just look at the domains of the given Email-Addresses
confirmByEmailDomains = .de, .it, .ch, .at
}
}
}
}
Extended example
''''''''''''''''
Accept every user profile from domains de, it, ch and at but not if they are using gmail.de or gmx.de:
.. code-block:: typoscript
plugin.tx_femanager.settings {
autoAdminConfirmation {
# Femanager autoAdminConfirmation classes
10 {
class = In2code\Femanager\Domain\Service\AutoAdminConfirmation\EmailDomainConfirmation
config {
# Just look at the domains of the given Email-Addresses
confirmByEmailDomains = .de, .it, .ch, .at
confirmByEmailDomainsExceptions = gmail.de, gmx.de
}
}
}
}
YourAutoConfirmation
^^^^^^^^^^^^^^^^^^^^
Of course you can add your own classes to bring in some own magic.
Example
'''''''
TypoScript:
.. code-block:: typoscript
plugin.tx_femanager.settings {
autoAdminConfirmation {
# Femanager autoAdminConfirmation classes
100 {
# Classname that should be called with method isAutoAdminConfirmationFullfilled()
class = In2code\FemanagerExtended\Domain\Service\AutoAdminConfirmation\IpAddressConfirmation
# optional: Add configuration for your PHP
config {
ip = 127.0.0.1
foo = bar
fooCObject = TEXT
fooCObject.value = do something with this text
}
}
}
}
PHP:
.. code-block:: php
<?php
declare(strict_types=1);
namespace In2code\FemanagerExtended\Domain\Service\AutoAdminConfirmation;
use In2code\Femanager\Domain\Service\AutoAdminConfirmation\AbstractConfirmation;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Class IpAddressConfirmation
*/
class IpAddressConfirmation extends AbstractConfirmation
{
/**
* @return bool
*/
public function isAutoConfirmed(): bool
{
return GeneralUtility::getIndpEnv('REMOTE_ADDR') === $this->config['ip']);
}
}
Some notices
^^^^^^^^^^^^
* Called method in Confirmation class is always isAutoConfirmed()
* Confirmation classes must implement In2code\Femanager\Domain\Service\AutoAdminConfirmation\ConfirmationInterface or extend In2code\Femanager\Domain\Service\AutoAdminConfirmation\AbstractConfirmation
* You have to take care, that your class is included from TYPO3 autoloader otherwise it's not included
* Per default femanager offers only EmailDomainConfirmation class at the momment
@@ -0,0 +1,105 @@
.. include:: ../../Includes.rst.txt
.. _countryselect:
Using static_info_tables for country selection
----------------------------------------------
Basics
^^^^^^
- Install Extension static_info_tables
- Install Extension static_info_tables(_de)(_fr)(_pl) etc... for localized countrynames
- Import Records of the extensions via Extension Manager (see manual of static_info_tables)
- Clear Cache
- Copy all Partials from femanager to a fileadmin folder
- Set the new Partial Path via Constants: plugin.tx_femanager.view.partialRootPath = fileadmin/femanager/Partials/
- Open Partial Fields/Country.html and activate static_info_tables (see notes in HTML-File)
Details for Partial Country.html
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The idea is very simple. You can change the “options Attribute” of the form.select ViewHelper:
.. code-block:: typoscript
<femanager:form.select
id="femanager_field_country"
property="country"
options="{femanager:Form.GetCountriesFromStaticInfoTables()}"
defaultOption="{f:translate(key:'pleaseChoose')}"
class="input-block-level"
additionalAttributes="{femanager:Validation.FormValidationData(settings:'{settings}',fieldName:'country')}" />
The GetCountriesFromStaticInfoTables-ViewHelper
Possible options for this ViewHelper are:
.. t3-field-list-table::
:header-rows: 1
- :Name:
Name
:Description:
Description
:Default:
Default Value
:Examplevalue:
Example Value
- :Name:
key
:Description:
Define the Record Column of static_countries table which should be used for storing to fe_users country
Note: Please use lowerCamelCase Writing for Fieldnames
:Default:
isoCodeA3
:Examplevalue:
isoCodeA2
- :Name:
value
:Description:
Define the Record Column of static_countries table which should be visible in selection in femanager
Note: Please use lowerCamelCase Writing for Fieldnames
:Default:
officialNameLocal
:Examplevalue:
shortNameFr
- :Name:
sortbyField
:Description:
Define the Record Column of static_countries which should be used for a sorting
Note: Please use lowerCamelCase Writing for Fieldnames
:Default:
isoCodeA3
:Examplevalue:
shortNameDe
- :Name:
sorting
:Description:
Could be 'asc' or 'desc' for Ascending or Descending Sorting
:Default:
asc
:Examplevalue:
desc
Some Examples are:
.. code-block:: html
{femanager:Form.GetCountriesFromStaticInfoTables(key:'isoCodeA2',value:'shortNameDe')}
{femanager:Form.GetCountriesFromStaticInfoTables(key:'isoCodeA2',value:'shortNameFr',sortbyField:'shortNameFr')}
{femanager:Form.GetCountriesFromStaticInfoTables(key:'isoCodeA3',value:'isoCodeA3',sortbyField:'isoCodeA3',sorting:'asc')}
@@ -0,0 +1,51 @@
.. include:: ../../Includes.rst.txt
.. _fillEmailAsUsername:
Fill Email as Username during registraion
-----------------------------------------
Introduction
^^^^^^^^^^^^
**Available since 2.0**
If this setting is enabled, the mail address is taken as username. The setting can be applied in three situations:
* During registration (new)
* During edit process of an existing user (edit)
* During Invitation process (invite)
Configuration
^^^^^^^^^^^^^
Enable the "fillEmailWithUsername" option for the area (new, edit, invite), where you like to apply it.
Example for "new" area:
:typoscript:`plugin.tx_femanager.settings.new.fillEmailWithUsername = 1`
Please take care, that the username is not set to required, otherwise it will not work
:typoscript:`plugin.tx_femanager.settings.new.validation.username.required = 0`
Example
'''''''
TypoScript:
.. code-block:: typoscript
plugin.tx_femanager.settings {
new {
fillEmailWithUsername = 1
validation.username.required = 0
}
}
Remarks
^^^^^^^
Please mind, if you use this setting in the edit view, a user is able to change his username.
Therefor you should always take care, via validation settings, that a username (and also the mail address) stays
unique for your users.
@@ -0,0 +1,173 @@
.. include:: ../../Includes.rst.txt
.. _finishers:
Add own Finisher classes
------------------------
Introduction
^^^^^^^^^^^^
Let's say you want to easily add some own php functions,
that should be called after a user registered.
Maybe you want to handle the user input with:
* Send it to an API
* Store it in a logfile
* Save it into a table
* Something else...
Small example
^^^^^^^^^^^^^
Just define which classes should be used. Every method like \*Finisher() will be called - e.g. myFinisher():
.. code-block:: typoscript
plugin.tx_femanager.settings {
finishers {
1 {
class = Vendor\Ext\Finisher\DoSomethingFinisher
}
}
}
Add a php-file and extend your class with the AbstractFinisher from femanager:
.. code-block:: php
<?php
namespace Vendor\Ext\Finisher;
use In2code\Femanager\Finisher\AbstractFinisher;
/**
* Class DoSomethingFinisher
*
* @package Vendor\Ext\Finisher
*/
class DoSomethingFinisher extends AbstractFinisher
{
/**
* MyFinisher
*
* @return void
*/
public function myFinisher()
{
// ...
}
}
Extended example
^^^^^^^^^^^^^^^^
See the advanced example with some configuration
in TypoScript and with the possibility to load the file
(useful if file could not be loaded from autoloader
because it's stored in fileadmin or elsewhere)
.. code-block:: typoscript
plugin.tx_femanager.settings {
finishers {
1 {
# Classname that should be called with method *Finisher()
class = Vendor\Ext\Finisher\DoSomethingFinisher
# optional: Add configuration for your PHP
config {
foo = bar
fooCObject = TEXT
fooCObject.value = do something with this text
}
# optional: If file will not be loaded from autoloader, add path and it will be called with require_once
require = fileadmin/femanager/finisher/DoSomethingFinisher.php
}
}
}
Add your php-file again and extend your class with the AbstractFinisher from femanager:
.. code-block:: php
<?php
namespace Vendor\Ext\Finisher;
use In2code\Femanager\Domain\Model\User;
use In2code\Femanager\Finisher\AbstractFinisher;
/**
* Class DoSomethingFinisher
*
* @package Vendor\Ext\Finisher
*/
class DoSomethingFinisher extends AbstractFinisher
{
/**
* @var User
*/
protected $user;
/**
* @var array
*/
protected $configuration;
/**
* @var array
*/
protected $settings;
/**
* Will be called always at first
*
* @return void
*/
public function initializeFinisher()
{
}
/**
* Will be called before myFinisher()
*
* @return void
*/
public function initializeMyFinisher()
{
}
/**
* MyFinisher
*
* @return void
*/
public function myFinisher()
{
// get value from configuration
$foo = $this->configuration['foo'];
// get subject
$subject = $this->getMail()->getSubject();
// ...
}
}
Some notices
^^^^^^^^^^^^
* All methods which are ending with "finisher" will be called - e.g. saveFinisher()
* The method initializeFinisher() will always be called at first
* Every finisher method could have its own initialize method, which will be called before. Like initializeMyFinisher() before myFinisher()
* Classes in extensions (if namespace and filename fits) will be automaticly included from TYPO3 autoloader. If you place a single file in fileadmin, use "require" in TypoScript
* Per default 10 and 20 is already in use from femanager itself (SaveToAnyTableFinisher, SendParametersFinisher) since version 2.0
@@ -0,0 +1,110 @@
.. include:: ../Includes.rst.txt
Features
========
.. only:: html
:ref:`bestpractices` | :ref:`features`
.. _bestpractices:
Best Practices & HowTos
-----------------------
See some features or best practice parts of the extension femanager.
.. toctree::
:maxdepth: 3
:titlesonly:
:glob:
Templates/Index
ShowListUsers/Index
Countryselect/Index
FillEmailAsUsername/Index
NewFields/Index
NewValidators/Index
AutoConfirmation/Index
Finishers/Index
Signals/Index
ResendUserConfirmationRequest/Index
RateLimiter/Index
.. _features:
All Features
------------
Frontend-User Registration
^^^^^^^^^^^^^^^^^^^^^^^^^^
- One step registration with autologin
- Main configuration with Flexform
- User confirmation (Double-Opt In) (optional)
- Administration confirmation (optional)
- Refuse and Silent Refuse
- Fill email field with username (optional)
- Redirect with TypoScript standardWrap (optional)
- Prefill Formfields via TypoScript standardWrap (optional)
- Multiple Validation Possibilities (JavaScript and PHP) (required, email, min, max, intOnly, lettersOnly, unicodeLettersOnly, uniqueInPage, uniqueInDb, mustInclude(number,letter,special), inList(1,2,3))
- Same PHP Methods for JavaScript and PHP Validation
- Simply extend validation methods with your extension
- Override a lot of Email settings with TypoScript if needed
- Set mail attachments or embeded images
- Override field values on every single step (e.g. push user to usergroup1 and if he is ready confimed push him to usergroup2)
- Send user values to a third party software (e.g. a CRM like salesforce)
- Store values in other database tables (e.g. tt_address)
- Add Captcha (sr_freecap) for spam prevention
Edit Profile
^^^^^^^^^^^^
- Main configuration with Flexform
- Administration confirmation for change request (optional)
- Refuse and Silent Refuse
- Fill email field with username (optional)
- Prefill Formfields via TypoScript standardWrap (optional)
- Multiple Validation Possibilities (JavaScript and PHP) (required, email, min, max, intOnly, lettersOnly, unicodeLettersOnly, uniqueInPage, uniqueInDb, mustInclude(number,letter,special), inList(1,2,3))
- Same PHP Methods for JavaScript and PHP Validation
- Simply extend validation methods with your extension
- Override a lot of Email settings with TypoScript if needed
- Set mail attachments or embeded images
- Delete profile with TypoScript redirect
Invitation
^^^^^^^^^^
- Admin could create a new User in Frontend
- The new user receives a mail with a secured link, which leads to a password generation form
- Same validations as in edit and new
- A lot of configuration possibilities with TypoScript
Backend Module
^^^^^^^^^^^^^^
- Fulltext search for fe_users
- Hide and delete of fe_users via AJAX
- Shows Login status
- Logout of a frontend user
General
^^^^^^^
- Logging of every change
- Saltedpasswords support
- List FE-Users in the frontend
- Show a user profile in frontend
- jQuery include must activate via constants (per default no extra jQuery inclusion)
- Show fe_user crdate and tstamp for editors
- Store values in other database tables (e.g. tt_address)
- Save password as md5 or sha1 per default
- HTML with twitter bootstrap classes to reduce integration time
- Image upload with status bar
- Supports static_info_tables
- Extend this extension with new validators or new fields in fe_users (see example in best practice section) or use some SignalSlots
- Extension uses namespaces (so TYPO3 version 6.0 or higher is needed)
@@ -0,0 +1,465 @@
.. include:: ../../Includes.rst.txt
.. _newfields:
Adding new fields to fe_users with your own extension
-----------------------------------------------------
Picture
^^^^^^^
.. image:: ../../Images/femanager_edit2.png
Add new Fields to the Registraion-/Editform
Basics
^^^^^^
- Create a new extension for the new fields
- Create ext_tables.sql and Configuration/TCA/Overrides/fe_users.php for adding one or more new fields to fe_users
- Add TSConfig file to add one or more fields to the field selection in femanager flexform and include it
- Use TypoScript to add your own partials folder and add the templates for your new fields
- Create your own user model with getter/setter for your new fields that extends the user model from femanager
- Override the user model in your ext_localconf.php
See https://github.com/in2code-de/femanagerextended for an example extension how to extend femanager with new fields
and validation methods
Step by Step
^^^^^^^^^^^^
Add new fields to the flexform
""""""""""""""""""""""""""""""
.. image:: ../../Images/femanager_flexform_newfields.png
Extend Fieldselection in Flexform
Add some Page-TSConfig to extend the selection:
.. code-block:: typoscript
tx_femanager {
flexForm {
new {
addFieldOptions {
twitterId = Twitter ID
skypeId = Skype ID
userCategories = User Categories
somethingElse = LLL:EXT:yourextension/Resources/Private/Language/locallang_be.xlf:custom
}
}
edit < tx_femanager.flexForm.new
}
}
Modify the partial folder
"""""""""""""""""""""""""
“twitterId” (see TSConfig) means that femanager searches for a partial TwitterId.html to render the field in the form. So you have to copy the folder EXT:femanager/Resources/Private/Partials (e.g.) to fileadmin/Partials and set the new partial path via TypoScript Constants (see exmple below). In addition you have to add the new Partials files.
.. code-block:: typoscript
plugin.tx_femanager.view.partialRootPaths.100 = EXT:yourextension/Resources/Private/Partials/
Example file fileadmin/Partials/Fields/TwitterId.html:
.. code-block:: html
{namespace femanager=In2code\Femanager\ViewHelpers}
<div class="femanager_fieldset femanager_twitterid form-group">
<label for="femanager_field_twitterid" class="col-sm-2 control-label">
<f:translate key="tx_yourextension_domain_model_user.twitter_id" extensionName="yourextension" />
<f:if condition="{femanager:Validation.IsRequiredField(fieldName:'twitterId')}">
<span>*</span>
</f:if>
</label>
<div class="col-sm-10">
<femanager:form.textfield
id="femanager_field_twitterid"
property="twitterId"
class="form-control"
additionalAttributes="{femanager:Validation.FormValidationData(settings:settings,fieldName:'twitterId')}" />
</div>
</div>
Example file fileadmin/Partials/Fields/UserCategories.html:
.. code-block:: html
<html
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:femanager="http://typo3.org/ns/In2code/Femanager/ViewHelpers"
xmlns:femanagerextended="http://typo3.org/ns/In2code/Femanagerextended/ViewHelpers"
data-namespace-typo3-fluid="true">
<div class="femanager_fieldset femanager_user_categories form-group">
<div class="col-sm-10">
<fieldset>
<f:translate key="tx_femanagerextended_domain_model_user.user_categories" extensionName="femanagerextended" />
<f:if condition="{femanager:Validation.IsRequiredField(fieldName:'user_categories')}">
<span>*</span>
</f:if>
</fieldset>
<f:if condition="{femanager:Validation.IsRequiredField(fieldName:'user_categories')}">
<span>*</span>
</f:if>
<f:for as="category" each="{femanagerextended:form.getCategories(rootCategory:1)}">
<div class="form-check">
<f:form.checkbox property="userCategories" value="{category.uid}" multiple="true" class="form-check-input" />
<label class="form-check-label">{category.title}</label>
</div>
</f:for>
<f:comment>
<f:form.select property="userCategories" options="{femanagerextended:form.getCategories(rootCategory:1)}" optionLabelField="title" multiple="true" class="form-select" />
</f:comment>
</div>
</div>
</html>
ext_tables.sql
""""""""""""""
Example SQL file in your extension which extends fe_users with your new fields:
.. code-block:: sql
CREATE TABLE fe_users (
twitter_id varchar(255) DEFAULT '' NOT NULL,
skype_id varchar(255) DEFAULT '' NOT NULL,
user_categories tinytext DEFAULT '0'
);
Configuration/TCA/Overrides/fe_users.php
""""""""""""""""""""""""""""""""""""""""
Example Configuration/TCA/Overrides/fe_users.php file:
.. code-block:: php
$GLOBALS['TCA']['fe_users']['ctrl']['type'] = 'tx_extbase_type';
$tmpFeUsersColumns = [
'twitter_id' => [
'exclude' => 1,
'label' => 'LLL:EXT:yourextension/Resources/Private/Language/locallang_db.xlf:' .
'tx_yourextension_domain_model_user.twitter_id',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
],
],
'skype_id' => [
'exclude' => 1,
'label' => 'LLL:EXT:yourextension/Resources/Private/Language/locallang_db.xlf:' .
'tx_yourextension_domain_model_user.skype_id',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
],
],
'tx_extbase_type' => [
'config' => [
'type' => 'input',
'default' => '0',
],
],
'user_categories' => [
'exclude' => 1,
'label' => 'LLL:EXT:femanagerextended/Resources/Private/Language/locallang_db.xlf:' .
'tx_femanagerextended_domain_model_user.user_categories',
'config' => [
'type' => 'category',
'relationship' => 'oneToMany',
'treeConfig' => [
'startingPoints' => 1,
],
'minitems' => 0,
'maxitems' => 99,
]
],
];
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('fe_users', $tmpFeUsersColumns);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('fe_users', 'twitter_id, skype_id');
Own User Model
""""""""""""""
Example Model User.php which extends to the default femanager Model:
.. code-block:: php
namespace In2code\Femanagerextended\Domain\Model;
use TYPO3\CMS\Extbase\Domain\Model\Category;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
class User extends \In2code\Femanager\Domain\Model\User
{
/**
* twitterId
*
* @var string
*/
protected string $twitterId;
/**
* skypeId
*
* @var string
*/
protected string $skypeId;
/**
* @var ObjectStorage<Category>
*/
protected ObjectStorage $userCategories;
public function __construct($username = '', $password = '')
{
parent::__construct($username, $password);
$this->userCategories = new ObjectStorage();
}
/**
* Returns the twitterId
*
* @return string $twitterId
*/
public function getTwitterId(): string
{
return $this->twitterId;
}
/**
* Sets the twitterId
*
* @param string $twitterId
* @return void
*/
public function setTwitterId(string $twitterId): void
{
$this->twitterId = $twitterId;
}
/**
* Returns the skypeId
*
* @return string $skypeId
*/
public function getSkypeId(): string
{
return $this->skypeId;
}
/**
* Sets the skypeId
*
* @param string $skypeId
* @return void
*/
public function setSkypeId(string $skypeId): void
{
$this->skypeId = $skypeId;
}
/**
* @return ObjectStorage
*/
public function getUserCategories(): ObjectStorage
{
return $this->userCategories;
}
/**
* @param ObjectStorage $userCategories
*/
public function setUserCategories(ObjectStorage $userCategories): void
{
$this->userCategories = $userCategories;
}
/**
* @param Category $category
* @return void
*/
public function addUserCategory(Category $category)
{
$this->userCategories->attach($category);
}
/**
* @param Category $category
* @return void
*/
public function removeUserCategory(Category $category)
{
$this->userCategories->detach($category);
}
}
Include model with TYPO3 10.4.x
"""""""""""""""""""""""""""""""
Configuration/Extbase/Persistence/Classes.php:
.. code-block:: php
return [
\YourVendor\YourExtension\Domain\Model\User::class => [
'tableName' => 'fe_users',
'recordType' => 0,
],
];
ext_localconf.php:
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\In2code\Femanager\Domain\Model\User::class] = [
'className' => \YourVendor\YourExtension\Domain\Model\User::class,
];
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\Container\Container::class)
->registerImplementation(
\In2code\Femanager\Domain\Model\User::class,
\YourVendor\YourExtension\Domain\Model\User::class
);
TypoScript to include Model and override default controller with TYPO3 9.5.x
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.. code-block:: typoscript
config.tx_extbase{
persistence{
classes{
In2code\Femanager\Domain\Model\User {
subclasses {
0 = In2code\Femanagerextended\Domain\Model\User
}
}
In2code\Femanagerextended\Domain\Model\User {
mapping {
tableName = fe_users
recordType = 0
}
}
}
}
objects {
In2code\Femanager\Controller\NewController.className = In2code\Femanagerextended\Controller\NewController
In2code\Femanager\Controller\EditController.className = In2code\Femanagerextended\Controller\EditController
}
}
Own Controller Files with TYPO3 9.5.x
"""""""""""""""""""""""""""""""""""""
EditController.php:
.. code-block:: text
namespace In2code\Femanagerextended\Controller;
class EditController extends \In2code\Femanager\Controller\EditController {
/**
* action update
*
* @param In2code\Femanagerextended\Domain\Model\User $user
* @validate $user In2code\Femanager\Domain\Validator\ServersideValidator
* @validate $user In2code\Femanager\Domain\Validator\PasswordValidator
* @return void
*/
public function updateAction(\In2code\Femanagerextended\Domain\Model\User $user) {
parent::updateAction($user);
}
}
NewController.php:
.. code-block:: text
namespace In2code\Femanagerextended\Controller;
class NewController extends \In2code\Femanager\Controller\NewController {
/**
* action create
*
* @param In2code\Femanagerextended\Domain\Model\User $user
* @validate $user In2code\Femanager\Domain\Validator\ServersideValidator
* @validate $user In2code\Femanager\Domain\Validator\PasswordValidator
* @return void
*/
public function createAction(\In2code\Femanagerextended\Domain\Model\User $user) {
parent::createAction($user);
}
}
**Note:** If there are PHP warnings like “…should be compatible with…“ for PHP7, see discussion and solution:
https://stackoverflow.com/questions/45563671/how-to-extend-femanager-controller-under-php-7/45564378
**or try to change the Controller Files to:**
Own Controller Files with PHP 7.2 / TYPO3 9.5.x
"""""""""""""""""""""""""""""""""""""""""""""""
EditController.php:
.. code-block:: text
namespace In2code\Femanagerextended\Controller;
class EditController extends \In2code\Femanager\Controller\EditController {
/**
* action update
*
* @param In2code\Femanagerextended\Domain\Model\User $user
* @validate $user In2code\Femanager\Domain\Validator\ServersideValidator
* @validate $user In2code\Femanager\Domain\Validator\PasswordValidator
* @return void
*/
public function updateAction($user) {
parent::updateAction($user);
}
}
NewController.php:
.. code-block:: text
namespace In2code\Femanagerextended\Controller;
class NewController extends \In2code\Femanager\Controller\NewController {
/**
* action create
*
* @param In2code\Femanagerextended\Domain\Model\User $user
* @validate $user In2code\Femanager\Domain\Validator\ServersideValidator
* @validate $user In2code\Femanager\Domain\Validator\PasswordValidator
* @return void
*/
public function createAction($user) {
parent::createAction($user);
}
}
@@ -0,0 +1,129 @@
.. include:: ../../Includes.rst.txt
.. _extendvalidators:
Adding own serverside and clientside validation to femanager forms
------------------------------------------------------------------
Picture
^^^^^^^
.. image:: ../../Images/femanager_newfield1.png
Add own clientside (JavaScript) Validation
.. image:: ../../Images/femanager_newfield2.png
Add own serverside (PHP) Validation
Basics
^^^^^^
- Use TypoScript to override ValidationClass of femanager with own classes – this enables your validation methods
- Config the new validation methods via TypoScript
- Add translation labels via TypoScript
.. attention::
The following example works only with TYPO3 Version 10.4 LTS
See https://github.com/einpraegsam/femanagerextended for an example extension how to extend femanager
with new fields and validation methods
Step by Step
^^^^^^^^^^^^
New validation classes
""""""""""""""""""""""
CustomClientsideValidator.php:
.. code-block:: php
namespace YourVendor\YourExtension\Domain\Validator;
class CustomClientsideValidator extends \In2code\Femanager\Domain\Validator\ClientsideValidator
{
/**
* Custom Validator
* Activate via TypoScript - e.g. plugin.tx_femanager.settings.new.validation.username.custom = validationSetting
*
* @param string $value Given value from input field
* @param string $validationSetting TypoScript Setting for this field
* @return bool
*/
protected function validateCustom($value, $validationSetting): bool
{
// check if string has string inside
if (stristr($value, $validationSetting)) {
return true;
}
return false;
}
}
CustomServersideValidator.php:
.. code-block:: php
namespace YourVendor\YourExtension\Domain\Validator;
class CustomServersideValidator extends \In2code\Femanager\Domain\Validator\ServersideValidator
{
/**
* Custom Validator
* Activate via TypoScript - e.g. plugin.tx_femanager.settings.new.validation.username.custom = validationSetting
*
* @param string $value Given value from input field
* @param string $validationSetting TypoScript Setting for this field
* @return bool
*/
protected function validateCustom($value, $validationSetting): bool
{
// check if string has string inside
if (stristr($value, $validationSetting)) {
return true;
}
return false;
}
}
Configure override of ServersideValidator and ClientsideValidator
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
ext_localconf.php
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\In2code\Femanager\Domain\Validator\ServersideValidator::class] = [
'className' => \YourVendor\YourExtension\Domain\Validator\CustomServersideValidator::class,
];
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\In2code\Femanager\Domain\Validator\ClientsideValidator::class] = [
'className' => \YourVendor\YourExtension\Domain\Validator\CustomClientsideValidator::class,
];
TypoScript to enable new validation and set labels
""""""""""""""""""""""""""""""""""""""""""""""""""
.. code-block:: typoscript
plugin.tx_femanager {
settings.new.validation {
_enable.client = 1
_enable.server = 1
username {
# Custom Validator - check if value includes "abc"
custom = abc
}
}
_LOCAL_LANG {
default.validationErrorCustom = "abc" is missing
de.validationErrorCustom = "abc" wird erwartet
}
}
@@ -0,0 +1,31 @@
.. include:: ../../Includes.rst.txt
.. _ratelimiter:
Rate Limiter
------------
Basics
^^^^^^
If you want prevent, that your registration forms, you can enable the rate limiter.
Note: The limiter is enabled by default.
TypoScript Settings
^^^^^^^^^^^^^^^^^^^
.. code-block:: typoscript
plugin.tx_femanager {
settings {
ratelimiter {
# Number of seconds for the sliding window rate limiter
timeframe = {$plugin.tx_femanager.settings.ratelimiter.timeframe}
# Request count. How many requests are allowed in the last <timeframe> seconds. Set to 0 to disable rate limiter.
limit = {$plugin.tx_femanager.settings.ratelimiter.limit}
}
}
}
@@ -0,0 +1,54 @@
.. include:: ../../Includes.rst.txt
.. _resendUserConfirmationRequest:
Resend User Confirmation Request
--------------------------------
Introduction
^^^^^^^^^^^^
**Available since 4.2.0**
This feature adds a new view in the backend module to list user, which did not confirm their user accounts. An frontend
user admin is now able to resend the confirmation mail or decline (and delete) the user via backend.
Frontend View
^^^^^^^^^^^^^
An editor can setup a new view "resend confirmation mail". Frontend users, who started their registration process and did
not confirm their email so far, can resend a confirmation mail.
Configuration. Add the plugin "Femanager" to a page and select "resend confirmation mail".
IMPORTANT: If you want to use these new views and you did use femanager version 4.1 or older, you need open existing plugins and save them again, in order to allow the
usage of this views.
.. image:: ../../Images/femanager_plugin3.png
Sometimes unconfirmed users are trying to trigger the confirmation mail again by registering again with the same email or username. They get an error "username / email already existing". Since 4.2, an additional message with a "resend confirmation mail" link is displayed in those cases where the existing user has not yet confirmed his registration.
For this message to be displayed, you need to have the following typoscript setting configured:
::
settings.showResendUserConfirmationRequestView = {your pid}
The pid is the page uid where your "resend confirmation mail" plugin resides.
Backend View
^^^^^^^^^^^^
Lists all frontend users, which did not confirm their email so far. An admin is able, to decline (delete) users or
resend an email with a confirmation link.
.. image:: ../../Images/femanager_backend4.png
To activate the feature add the userTSConfig:
.. code-block:: typoscript
tx_femanager.UserBackend.confirmation.ResendUserConfirmationRequest = 1
@@ -0,0 +1,65 @@
.. include:: ../../Includes.rst.txt
.. _showlistusers:
Show and List Frontend Users
----------------------------
This Feature allows you to display the data of the current user, a selected user by an editor or list user and provide
a detail page.
Caution: Please take care, that you do not disclose information in public environments and be careful, which data you show in the detail view.
Show the current user
^^^^^^^^^^^^^^^^^^^^^
Useful, if you want to show a "read only view" for the current logged in
frontend user.
**Configuration:**
#. Add a femanager plugin to your page
#. choose "detail" view
#. select the tab "Detail" and choose "Logged in FE User"
.. image:: ../../Images/feature-showlistusers-loggedin-user.png
Show a given user
^^^^^^^^^^^^^^^^^
You can provide a list view of all frontend users or frontend users of selected groups
.. image:: ../../Images/feature-showlistusers-loggedin-user1.png
#. Add a femanager plugin to your page
#. choose "detail" view
#. select the tab "Detail" and select your options
.. attention::
If you add this plugin with the selected view, take care, that you do not disclose information in public environments and be careful, which data you show in the detail view.
List Users and provide a detail page
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#. Add a femanager plugin to your page
#. choose "list" view
#. select the tab "Detail" and choose a frontend user
.. attention::
By combining a list aIf you don't select any frontend user, any users can be displayed by passing the get param &tx_femanager_pi1[user]=XX to the detail page url. Be careful to avoid unwanted information disclosure!
.. image:: ../../Images/feature-showlistusers-loggedin-user2.png
Plugin Options:
* Show Searchfield: You can provide a searchfield, to filter the users
* Limit: Define, how many users are listed per page
* Order by: Choose which field should be used to order the list
* Sorting: Define sort ordering
* Show from usergroup (empty = show all): Select one or more usergroups. If you don't select a group, all frontend users are displayed
@@ -0,0 +1,306 @@
.. include:: ../../Includes.rst.txt
.. _signalslots:
Using SignalSlots (Hook pendant) to extend femanager
----------------------------------------------------
Introduction
^^^^^^^^^^^^
SignalSlots (former Hooks) are the possibility for other developer to extend the runtime of a femanager process with their own code.
As an example let's build an extension which sends username and email address of a new registered user to a defined email address.
Note: this is a little bit useless because there is already a setting in flexform to inform administrators and there is a setting in TypoScript to POST values to a third-party-software, but let's use this case for an example.
SignalSlots List
^^^^^^^^^^^^^^^^
.. t3-field-list-table::
:header-rows: 1
- :File:
File
:Located:
Located in
:Signal:
Signal Name
:Parameters:
Available Parameters
:Description:
Description
- :File:
NewController.php
:Located:
createAction()
:Signal:
createActionBeforePersist
:Parameters:
$user, $this
:Description:
Use this signal if you want to hook into the process before the new user was persisted
- :File:
NewController.php
:Located:
confirmCreateRequestAction()
:Signal:
confirmCreateRequestActionBeforePersist
:Parameters:
$user, $hash, $status, $this
:Description:
Use this signal if you want to hook into the confirmation process
- :File:
NewController.php
:Located:
createAdminConfirmationRequest()
:Signal:
createAdminConfirmationRequestAutoConfirm
:Parameters:
$user, $this
:Description:
Signal if a user was auto-confirmed
- :File:
NewController.php
:Located:
createAdminConfirmationRequest()
:Signal:
createAdminConfirmationRequestManualConfirmation
:Parameters:
$user, $this
:Description:
Signal if a user was not auto-confirmed and must be confirmed manually
- :File:
EditController.php
:Located:
updateAction()
:Signal:
updateActionBeforePersist
:Parameters:
$user, $this
:Description:
Use this signal if you want to hook into the process before the user- profile was updated
- :File:
EditController.php
:Located:
confirmUpdateRequestAction()
:Signal:
confirmUpdateRequestActionAfterPersist
:Parameters:
$user, $hash, $status, $this
:Description:
Use this signal if you want to hook after a profile was accepted or refused
- :File:
EditController.php
:Located:
deleteAction()
:Signal:
deleteAction
:Parameters:
$user, $this
:Description:
Use this signal if you want to hook into the process before the user- profile will be deleted
- :File:
InvitationController.php
:Located:
createAction()
:Signal:
confirmUpdateRequestActionBeforePersist
:Parameters:
$user, $hash, $status, $this
:Description:
Use this signal if you want to hook into the process before a new user was persisted
- :File:
InvitationController.php
:Located:
createAllConfirmed()
:Signal:
createAllConfirmedAfterPersist
:Parameters:
$user, $this
:Description:
Use this signal if you want to hook into the process after a new user was persisted
- :File:
InvitationController.php
:Located:
editAction()
:Signal:
editActionAfterPersist
:Parameters:
$user, $hash, $this
:Description:
Use this signal if you want to hook into the process before a user adds a new password (step 1)
- :File:
InvitationController.php
:Located:
updateAction()
:Signal:
updateActionAfterPersist
:Parameters:
$user, $this
:Description:
Use this signal if you want to hook into the process after a user adds a new password (step 2)
- :File:
UserController.php
:Located:
loginAsAction()
:Signal:
loginAsAction
:Parameters:
$user, $this
:Description:
Use this signal if you want to hook into the process after you simulate a frontend user login
- :File:
UserBackendController.php
:Located:
confirmUserAction()
:Signal:
confirmUserAction
:Parameters:
$user, $this
:Description:
Signal if a user profile was confirmed in backend module
- :File:
UserBackendController.php
:Located:
refuseUserAction()
:Signal:
refuseUserAction
:Parameters:
$user, $this
:Description:
Signal if a user profile was refused in backend module
- :File:
AbstractController.php
:Located:
finalCreate()
:Signal:
finalCreateAfterPersist
:Parameters:
$user, $action, $this
:Description:
Use this signal if you want to hook into the process after the new user was persisted
- :File:
AbstractController.php
:Located:
updateAllConfirmed()
:Signal:
updateAllConfirmedAfterPersist
:Parameters:
$user, $this
:Description:
Use this signal if you want to hook into the process after the new user was persisted
- :File:
?
:Located:
?
:Signal:
?
:Parameters:
?
:Description:
Do you need a new Signal in femanager? Just request one on https://github.com/in2code-de/femanager
Use a SignalSlot
^^^^^^^^^^^^^^^^
Introduction
""""""""""""
As described before, we want to send an email to a defined address every time when a new user is registered.
Creating an extension
"""""""""""""""""""""
femanagersignalslot/ext_emconf.php:
This file is important to install your new extension – write something like:
.. code-block:: php
<?php
$EM_CONF[$_EXTKEY] = array(
'title' => 'femanagersignalslot',
'description' => 'signalslotexample for femanager',
'state' => 'alpha',
'version' => '0.0.1',
'constraints' => array(
'depends' => array(
'extbase' => '6.0.0-6.1.99',
'fluid' => '6.0.0-6.1.99',
'typo3' => '6.0.0-6.1.99',
'femanager' => '1.0.0-1.0.99',
),
'conflicts' => array(
),
'suggests' => array(
),
),
);
file:`femanagersignalslot/ext_localconf.php`:
This is an example how to use a signal from femanager – in this case we decided to use the signal “createActionBeforePersist” in class “In2codeFemanagerControllerNewController” and want to call a slot in class “In2codeFemanagersignalslotDomainServiceSendMailService” with methodname “send()”
.. code-block:: php
<?php
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher');
$signalSlotDispatcher->connect(
'In2code\Femanager\Controller\NewController',
'createActionBeforePersist',
'In2code\Femanagersignalslot\Domain\Service\SendMailService',
'send',
FALSE
);
femanagersignalslot/Classes/Domain/Service/SendMailService.php:
This is our main class which is called every time a new registration process was initiated.
.. code-block:: php
<?php
namespace In2code\Femanagersignalslot\Domain\Service;
class SendMailService
{
/**
* Send mail about user information
*
* @param \In2code\Femanager\Domain\Model\User $user
* @param \In2code\Femanager\Controller\NewController $pObj
* @return void
*/
public function send($user, $pObj)
{
$message = '
New user registered
Username: ' . $user->getUsername() . '
Email: ' . $user->getEmail() . '
';
mail('your@email.com', 'SignalSlot Test', $message);
}
}
@@ -0,0 +1,68 @@
.. include:: ../../Includes.rst.txt
.. _changetemplates:
Use own HTML Templates
----------------------
Basics
^^^^^^
If you want to modify a HTML-File of femanager, you should not overwrite them directly in the extension folder.
Think about upcoming versions with important bugfixes or security-patches.
There are two ways to use own HTML-Templates (and Partials / Layouts) instead of the original Templates.
Replace all HTML Templates from Femanager with own Templates
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can copy all Files from
- EXT:femanager/Resources/Private/Templates/
- EXT:femanager/Resources/Private/Partials/
- EXT:femanager/Resources/Private/Layouts/
to a new folder in fileadmin - e.g. fileadmin/templates/femanager/ and modify them as you want.
After that, you should say femanager to use the new Templates with some lines of TypoScript setup:
.. code-block:: typoscript
plugin.tx_femanager {
view {
templateRootPath = fileadmin/templates/femanager/Templates/
partialRootPath = fileadmin/templates/femanager/Partials/
layoutRootPath = fileadmin/templates/femanager/Layouts/
}
}
Replace single HTML Template-Files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can copy only the Files that you want to modify from
- EXT:femanager/Resources/Private/Templates/
- EXT:femanager/Resources/Private/Partials/
- EXT:femanager/Resources/Private/Layouts/
to a new folder in fileadmin - e.g. fileadmin/templates/femanager/ and modify them as you want.
After that, you should say femanager to use the old folders and merge them with the new folders
.. code-block:: typoscript
plugin.tx_femanager {
view {
templateRootPath >
templateRootPaths {
10 = EXT:femanager/Resources/Private/Templates/
20 = fileadmin/templates/femanager/Templates/
}
partialRootPath >
partialRootPaths {
10 = EXT:femanager/Resources/Private/Partials/
20 = fileadmin/templates/femanager/Partials/
}
layoutRootPath >
layoutRootPaths {
10 = EXT:femanager/Resources/Private/Layouts/
20 = fileadmin/templates/femanager/Layouts/
}
}
}