first commit
This commit is contained in:
commit
e81864e683
2984 files changed
+267797
No files matched your search
@@ -0,0 +1,546 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\DataProcessor\DataProcessorRunner;
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Repository\UserGroupRepository;
|
||||
use In2code\Femanager\Domain\Repository\UserRepository;
|
||||
use In2code\Femanager\Domain\Service\SendMailService;
|
||||
use In2code\Femanager\Event\FinalCreateEvent;
|
||||
use In2code\Femanager\Event\FinalUpdateEvent;
|
||||
use In2code\Femanager\Finisher\FinisherRunner;
|
||||
use In2code\Femanager\Utility\BackendUtility;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\HashUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\LogUtility;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility as BackendUtilityCore;
|
||||
use TYPO3\CMS\Core\Http\ApplicationType;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||
use TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class AbstractController
|
||||
*/
|
||||
abstract class AbstractController extends ActionController
|
||||
{
|
||||
/**
|
||||
* @var UserRepository
|
||||
*/
|
||||
protected $userRepository;
|
||||
|
||||
/**
|
||||
* @var UserGroupRepository
|
||||
*/
|
||||
protected $userGroupRepository;
|
||||
|
||||
/**
|
||||
* @var PersistenceManager
|
||||
*/
|
||||
protected $persistenceManager;
|
||||
|
||||
/**
|
||||
* @var SendMailService
|
||||
*/
|
||||
protected $sendMailService;
|
||||
|
||||
/**
|
||||
* @var FinisherRunner
|
||||
*/
|
||||
protected $finisherRunner;
|
||||
|
||||
/**
|
||||
* @var LogUtility
|
||||
*/
|
||||
protected $logUtility;
|
||||
|
||||
/**
|
||||
* Content Object
|
||||
*
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
public $contentObject;
|
||||
|
||||
/**
|
||||
* Former known as piVars
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $pluginVariables;
|
||||
|
||||
/**
|
||||
* TypoScript
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $config;
|
||||
|
||||
/**
|
||||
* Complete Configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $allConfig;
|
||||
|
||||
/**
|
||||
* Module Configuration for Backend
|
||||
* this is a merge configuration -> TypoScript -> PageTSConfig -> UserTSConfig
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $moduleConfig;
|
||||
|
||||
/**
|
||||
* Current logged in user object
|
||||
*
|
||||
* @var User
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* All available usergroups
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $allUserGroups;
|
||||
|
||||
/**
|
||||
* AbstractController constructor.
|
||||
*
|
||||
* @param UserRepository $userRepository
|
||||
* @param UserGroupRepository $userGroupRepository
|
||||
* @param PersistenceManager $persistenceManager
|
||||
* @param SendMailService $sendMailService
|
||||
* @param FinisherRunner $finisherRunner
|
||||
* @param LogUtility $logUtility
|
||||
*/
|
||||
public function __construct(
|
||||
UserRepository $userRepository,
|
||||
UserGroupRepository $userGroupRepository,
|
||||
PersistenceManager $persistenceManager,
|
||||
SendMailService $sendMailService,
|
||||
FinisherRunner $finisherRunner,
|
||||
LogUtility $logUtility
|
||||
) {
|
||||
$this->userRepository = $userRepository;
|
||||
$this->userGroupRepository = $userGroupRepository;
|
||||
$this->persistenceManager = $persistenceManager;
|
||||
$this->sendMailService = $sendMailService;
|
||||
$this->finisherRunner = $finisherRunner;
|
||||
$this->logUtility = $logUtility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix method to createAction()
|
||||
* Create Confirmation from Admin is not necessary
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function createAllConfirmed(User $user)
|
||||
{
|
||||
$this->userRepository->add($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->logUtility->log(Log::STATUS_NEWREGISTRATION, $user);
|
||||
$this->finalCreate($user, 'new', 'createStatus');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix method to updateAction()
|
||||
* Update Confirmation from Admin is not necessary
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function updateAllConfirmed(User $user)
|
||||
{
|
||||
// send notify email to admin
|
||||
$existingUser = clone $this->userRepository->findByUid($user->getUid());
|
||||
|
||||
if (ConfigurationUtility::notifyAdminAboutEdits($this->settings) === true) {
|
||||
$this->sendMailService->send(
|
||||
'updateNotify',
|
||||
StringUtility::makeEmailArray(
|
||||
ConfigurationUtility::getValue('edit/email/notifyAdmin/receiver/email/value', $this->settings) ?:
|
||||
ConfigurationUtility::getValue('edit/notifyAdmin', $this->settings),
|
||||
$this->settings['edit']['email']['notifyAdmin']['receiver']['name']['value'] ?? null
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'Profile update',
|
||||
[
|
||||
'user' => $user,
|
||||
'changes' => UserUtility::getDirtyPropertiesFromUser($user),
|
||||
'settings' => $this->settings,
|
||||
],
|
||||
$this->config['edit.']['email.']['notifyAdmin.'] ?? []
|
||||
);
|
||||
}
|
||||
|
||||
$this->userRepository->update($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
|
||||
$this->eventDispatcher->dispatch(new FinalUpdateEvent($user));
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATED, $user, ['existingUser' => $existingUser]);
|
||||
$this->redirectByAction('edit');
|
||||
$this->addFlashMessage(LocalizationUtility::translate('update'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix method to updateAction(): Update must be confirmed by Admin
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function updateRequest($user)
|
||||
{
|
||||
if ($this->settings['edit']['confirmByAdmin'] ?? null) {
|
||||
$dirtyProperties = UserUtility::getDirtyPropertiesFromUser($user);
|
||||
$user = UserUtility::rollbackUserWithChangeRequest($user, $dirtyProperties);
|
||||
$this->sendMailService->send(
|
||||
'updateRequest',
|
||||
StringUtility::makeEmailArray(
|
||||
$this->settings['edit']['confirmByAdmin'] ?? '',
|
||||
$this->settings['edit']['email']['updateRequest']['sender']['name']['value'] ?? null
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'New Profile change request',
|
||||
[
|
||||
'user' => $user,
|
||||
'changes' => $dirtyProperties,
|
||||
'hash' => HashUtility::createHashForUser($user),
|
||||
],
|
||||
$this->config['edit.']['email.']['updateRequest.'] ?? []
|
||||
);
|
||||
$this->logUtility->log(
|
||||
Log::STATUS_PROFILEUPDATEREFUSEDADMIN,
|
||||
$user,
|
||||
['dirtyProperties' => $dirtyProperties]
|
||||
);
|
||||
$this->redirectByAction('edit', 'requestRedirect');
|
||||
$this->addFlashMessage(LocalizationUtility::translate('updateRequest'));
|
||||
} else {
|
||||
$this->logUtility->log(
|
||||
Log::STATUS_PROFILEUPDATEREFUSEDADMIN,
|
||||
$user,
|
||||
['message' => 'settings[edit][confirmByAdmin] is missing!']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some additional actions after profile creation
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $action
|
||||
* @param string $redirectByActionName Action to redirect
|
||||
* @param bool $login Login after creation
|
||||
* @param string $status
|
||||
* @param bool $backend Don't redirect if called from backend action
|
||||
*/
|
||||
public function finalCreate(
|
||||
$user,
|
||||
string $action,
|
||||
string $redirectByActionName,
|
||||
bool $login = true,
|
||||
string $status = '',
|
||||
bool $backend = false
|
||||
): void {
|
||||
$this->loginPreflight($user, $login);
|
||||
$variables = ['user' => $user, 'settings' => $this->settings, 'hash' => HashUtility::createHashForUser($user)];
|
||||
if (ConfigurationUtility::getValue(
|
||||
'new./email./createUserNotify./sender./email./value',
|
||||
$this->config
|
||||
) && ConfigurationUtility::getValue('new./email./createUserNotify./sender./name./value', $this->config)) {
|
||||
$this->sendMailService->send(
|
||||
'createUserNotify',
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getFirstName() . ' ' . $user->getLastName()),
|
||||
StringUtility::makeEmailArray(
|
||||
ConfigurationUtility::getValue(
|
||||
'new./email./createUserNotify./sender./email./value',
|
||||
$this->config
|
||||
),
|
||||
ConfigurationUtility::getValue('new./email./createUserNotify./sender./name./value', $this->config)
|
||||
),
|
||||
$this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('new./email./createUserNotify./subject', $this->config),
|
||||
(array)ConfigurationUtility::getValue('new./email./createUserNotify./subject.', $this->config),
|
||||
),
|
||||
$variables,
|
||||
ConfigurationUtility::getValue('new./email./createUserNotify.', $this->config)
|
||||
);
|
||||
}
|
||||
|
||||
$createAdminNotify = ConfigurationUtility::getValue(
|
||||
'new./email./createAdminNotify./receiver./email./value',
|
||||
$this->config
|
||||
);
|
||||
if (!$createAdminNotify) {
|
||||
$createAdminNotify = $this->settings['new']['notifyAdmin'];
|
||||
}
|
||||
|
||||
// send notify email to admin
|
||||
if ($createAdminNotify) {
|
||||
$this->sendMailService->send(
|
||||
'createNotify',
|
||||
StringUtility::makeEmailArray(
|
||||
$createAdminNotify
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
$this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('new./email./createAdminNotify./subject', $this->config),
|
||||
(array)ConfigurationUtility::getValue('new./email./createAdminNotify./subject.', $this->config)
|
||||
),
|
||||
$variables,
|
||||
ConfigurationUtility::getValue('new./email./createAdminNotify.', $this->config)
|
||||
);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(new FinalCreateEvent($user, $action));
|
||||
$this->finisherRunner->callFinishers($user, $this->actionMethodName, $this->settings, $this->contentObject);
|
||||
|
||||
if ($backend === false) {
|
||||
$this->redirectByAction($action, ($status ? $status . 'Redirect' : 'redirect'));
|
||||
$this->addFlashMessage(LocalizationUtility::translate('create'));
|
||||
$this->redirect($redirectByActionName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log user in
|
||||
*
|
||||
* @param User $user
|
||||
* @param $login
|
||||
* @throws IllegalObjectTypeException
|
||||
*/
|
||||
protected function loginPreflight(User $user, $login)
|
||||
{
|
||||
if ($login) {
|
||||
// persist user (otherwise login may not be possible)
|
||||
$this->userRepository->update($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
if (ConfigurationUtility::getValue('new./login', $this->config) === '1') {
|
||||
UserUtility::login($user, ConfigurationUtility::getValue('persistence./storagePid', $this->allConfig));
|
||||
$this->addFlashMessage(LocalizationUtility::translate('login'), '', AbstractMessage::NOTICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect by TypoScript setting
|
||||
* [userConfirmation|userConfirmationRefused|adminConfirmation|
|
||||
* adminConfirmationRefused|adminConfirmationRefusedSilent]Redirect
|
||||
*
|
||||
* @param string $action "new", "edit"
|
||||
* @param string $category "redirect", "requestRedirect" value from TypoScript
|
||||
*/
|
||||
protected function redirectByAction($action = 'new', $category = 'redirect')
|
||||
{
|
||||
$target = null;
|
||||
// redirect from TypoScript cObject
|
||||
if ($this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue($action . './' . $category, $this->config),
|
||||
(array)ConfigurationUtility::getValue($action . './' . $category . '.', $this->config),
|
||||
)
|
||||
) {
|
||||
$target = $this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue($action . './' . $category, $this->config),
|
||||
array_merge_recursive(
|
||||
(array)ConfigurationUtility::getValue($action . './' . $category . '.', $this->config),
|
||||
[
|
||||
'linkAccessRestrictedPages' => 1,
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// if redirect target
|
||||
if ($target) {
|
||||
$this->redirectToUri(StringUtility::removeDoubleSlashesFromUri($target));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is authenticated and params are valid
|
||||
*
|
||||
* @param User $user
|
||||
* @param int $uid Given fe_users uid
|
||||
* @param string $receivedToken Token
|
||||
*/
|
||||
protected function isSpoof($user, $uid, $receivedToken)
|
||||
{
|
||||
$errorOnProfileUpdate = false;
|
||||
$knownToken = GeneralUtility::hmac($user->getUid(), (string)$user->getCrdate()->getTimestamp());
|
||||
|
||||
//check if the params are valid
|
||||
if (!is_string($receivedToken) || !hash_equals($knownToken, $receivedToken)) {
|
||||
$errorOnProfileUpdate = true;
|
||||
}
|
||||
|
||||
//check if the logged user is allowed to edit / delete this record
|
||||
if ($user->getUid() !== (int)$uid && $uid > 0) {
|
||||
$errorOnProfileUpdate = true;
|
||||
}
|
||||
|
||||
if ($errorOnProfileUpdate === true) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns all values, which should be available in all views
|
||||
*/
|
||||
public function assignForAll()
|
||||
{
|
||||
$jsLabels = [
|
||||
'loading_states' => LocalizationUtility::translate('js.loading_states'),
|
||||
'please_choose' => LocalizationUtility::translate('pleaseChoose'),
|
||||
];
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'languageUid' => FrontendUtility::getFrontendLanguageUid(),
|
||||
'storagePid' => $this->allConfig['persistence']['storagePid'] ?? 0,
|
||||
'Pid' => FrontendUtility::getCurrentPid(),
|
||||
'data' => $this->contentObject->data,
|
||||
'useStaticInfoTables' => ExtensionManagementUtility::isLoaded('static_info_tables'),
|
||||
'jsLabels' => json_encode($jsLabels),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function initializeAction()
|
||||
{
|
||||
$this->controllerContext = $this->buildControllerContext();
|
||||
$this->user = UserUtility::getCurrentUser();
|
||||
$this->contentObject = $this->configurationManager->getContentObject();
|
||||
$this->pluginVariables = $this->request->getArguments();
|
||||
$this->moduleConfig = [];
|
||||
$this->allConfig = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK
|
||||
);
|
||||
$this->config = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
|
||||
);
|
||||
|
||||
$this->config = $this->config[BackendUtility::getPluginOrModuleString() . '.']['tx_femanager.']['settings.'] ?? [];
|
||||
|
||||
if (ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend()) {
|
||||
$config = BackendUtility::loadTS($this->allConfig['settings']['configPID'] ?? null);
|
||||
if (is_array($config['plugin.']['tx_femanager.']['settings.'] ?? null)) {
|
||||
$this->config = $config['plugin.']['tx_femanager.']['settings.'];
|
||||
$this->settings = $this->config;
|
||||
}
|
||||
|
||||
$this->moduleConfig = $config['module.']['tx_femanager.'] ?? '';
|
||||
|
||||
// Retrieve page TSconfig of the current page
|
||||
$pageTsConfig = BackendUtilityCore::getPagesTSconfig(BackendUtility::getPageIdentifier());
|
||||
if (is_array($pageTsConfig['module.']['tx_femanager.'] ?? null)) {
|
||||
$this->moduleConfig = array_merge($this->moduleConfig, $pageTsConfig['module.']['tx_femanager.'] ?? []);
|
||||
}
|
||||
|
||||
// Retrieve user TSconfig of currently logged in user
|
||||
$userTsConfig = $GLOBALS['BE_USER']->getTSConfig();
|
||||
|
||||
if ((is_array($userTsConfig['tx_femanager.']) ?? null) && (is_array($this->moduleConfig)?? null)) {
|
||||
$this->moduleConfig = array_merge_recursive($this->moduleConfig, $userTsConfig['tx_femanager.']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->setAllUserGroups();
|
||||
$this->checkTypoScript();
|
||||
$this->checkStoragePid();
|
||||
|
||||
$dataProcessorRunner = $this->objectManager->get(DataProcessorRunner::class);
|
||||
$this->pluginVariables = $dataProcessorRunner->callClasses(
|
||||
$this->request->getArguments(),
|
||||
$this->settings,
|
||||
$this->contentObject,
|
||||
$this->arguments
|
||||
);
|
||||
$this->request->setArguments($this->pluginVariables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate errormessages in flashmessages
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function getErrorFlashMessage()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function checkStoragePid()
|
||||
{
|
||||
if ((int)($this->allConfig['persistence']['storagePid'] ?? 0) === 0
|
||||
&& GeneralUtility::_GP('type') !== '1548935210'
|
||||
) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('error_no_storagepid'), '', AbstractMessage::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
protected function checkTypoScript()
|
||||
{
|
||||
if (ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'] ?? null)->isBackend()) {
|
||||
if (($this->config['_TypoScriptIncluded'] ?? '1') !== '1') {
|
||||
$this->addFlashMessage(
|
||||
(string)LocalizationUtility::translate('error_no_typoscript_be'),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$typoscriptIncluded = ConfigurationUtility::getValue('_TypoScriptIncluded', $this->settings);
|
||||
if ($typoscriptIncluded !== '1' && !GeneralUtility::_GP('eID')) {
|
||||
$this->addFlashMessage(
|
||||
(string)LocalizationUtility::translate('error_no_typoscript'),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function setAllUserGroups()
|
||||
{
|
||||
$controllerName = strtolower($this->controllerContext->getRequest()->getControllerName());
|
||||
$removeFromUserGroupSelection = $this->settings[$controllerName]['misc']['removeFromUserGroupSelection'] ?? '';
|
||||
$this->allUserGroups = $this->userGroupRepository->findAllForFrontendSelection($removeFromUserGroupSelection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email to user for confirmation
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function sendCreateUserConfirmationMail(User $user)
|
||||
{
|
||||
$this->sendMailService->send(
|
||||
'createUserConfirmation',
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
[
|
||||
ConfigurationUtility::getValue('new./email./createUserConfirmation./sender./email./value', $this->config) =>
|
||||
ConfigurationUtility::getValue('new./email./createUserConfirmation./sender./name./value', $this->config),
|
||||
],
|
||||
$this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('new./email./createUserConfirmation./subject', $this->config),
|
||||
(array)ConfigurationUtility::getValue('new./email./createUserConfirmation./subject.', $this->config)
|
||||
),
|
||||
[
|
||||
'user' => $user,
|
||||
'hash' => HashUtility::createHashForUser($user),
|
||||
],
|
||||
ConfigurationUtility::getValue('new./email./createUserConfirmation.', $this->config)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Service\RatelimiterService;
|
||||
|
||||
abstract class AbstractFrontendController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @var RatelimiterService
|
||||
*/
|
||||
protected $ratelimiterService;
|
||||
|
||||
public function injectRatelimiterService(RatelimiterService $ratelimiterService): void
|
||||
{
|
||||
$this->ratelimiterService = $ratelimiterService;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\DataProvider\CountryZonesDataProvider;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||
|
||||
class DataController extends ActionController
|
||||
{
|
||||
protected $countryZonesDataProvider;
|
||||
|
||||
public function __construct(CountryZonesDataProvider $countryZonesDataProvider)
|
||||
{
|
||||
$this->countryZonesDataProvider = $countryZonesDataProvider;
|
||||
}
|
||||
|
||||
public function getStatesForCountryAction(string $country): ResponseInterface
|
||||
{
|
||||
$countryZones = $this->countryZonesDataProvider->getCountryZonesForCountryIso3($country);
|
||||
$jsonData = [];
|
||||
foreach ($countryZones as $countryZone) {
|
||||
$jsonData[$countryZone->getIsoCode()] = $countryZone->getLocalName();
|
||||
}
|
||||
|
||||
return $this->jsonResponse(json_encode($jsonData));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Model\UserGroup;
|
||||
use In2code\Femanager\Event\AfterUserUpdateEvent;
|
||||
use In2code\Femanager\Event\BeforeUpdateUserEvent;
|
||||
use In2code\Femanager\Event\DeleteUserEvent;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\HashUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\ObjectUtility;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Annotation\Validate;
|
||||
use TYPO3\CMS\Extbase\Http\ForwardResponse;
|
||||
|
||||
/**
|
||||
* Class EditController
|
||||
*/
|
||||
class EditController extends AbstractFrontendController
|
||||
{
|
||||
public function editAction(): ResponseInterface
|
||||
{
|
||||
$token = '';
|
||||
if ($this->user) {
|
||||
$token = GeneralUtility::hmac($this->user->getUid(), (string)$this->user->getCrdate()->getTimestamp());
|
||||
}
|
||||
$this->view->assignMultiple([
|
||||
'user' => $this->user,
|
||||
'allUserGroups' => $this->allUserGroups,
|
||||
'token' => $token
|
||||
]);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
public function initializeUpdateAction()
|
||||
{
|
||||
if ($this->keepPassword()) {
|
||||
unset($this->pluginVariables['user']['password']);
|
||||
unset($this->pluginVariables['password_repeat']);
|
||||
}
|
||||
$this->request->setArguments($this->pluginVariables);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @Validate("In2code\Femanager\Domain\Validator\ServersideValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\PasswordValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\CaptchaValidator", param="user")
|
||||
*/
|
||||
public function updateAction(User $user)
|
||||
{
|
||||
$currentUser = UserUtility::getCurrentUser();
|
||||
$userValues = $this->request->getArgument('user') ?? [];
|
||||
$token = $this->request->getArgument('token') ?? null;
|
||||
$identity = (int)($userValues['__identity'] ?? 0);
|
||||
$isSpoof = $this->isSpoof($currentUser, $identity, $token);
|
||||
|
||||
if (!$currentUser instanceof User || $identity === 0 || $token === null || $isSpoof) {
|
||||
$logStatus = $isSpoof ? Log::STATUS_PROFILEUPDATEATTEMPTEDSPOOF : Log::STATUS_PROFILEUPDATEREFUSEDSECURITY;
|
||||
$logContext = $isSpoof ? $currentUser : $user;
|
||||
$this->logUtility->log($logStatus, $logContext);
|
||||
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEREFUSEDSECURITY),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
return new ForwardResponse('edit');
|
||||
}
|
||||
|
||||
$response = $this->redirectIfNoChangesOnObject($user);
|
||||
if ($response !== null) {
|
||||
return $response;
|
||||
}
|
||||
$user = FrontendUtility::forceValues(
|
||||
$user,
|
||||
ConfigurationUtility::getValue('edit./forceValues./beforeAnyConfirmation.', $this->config)
|
||||
);
|
||||
|
||||
$this->emailForUsername($user);
|
||||
UserUtility::convertPassword(
|
||||
$user,
|
||||
ConfigurationUtility::getValue('edit/misc/passwordSave', $this->settings)
|
||||
);
|
||||
|
||||
$this->eventDispatcher->dispatch(new BeforeUpdateUserEvent($user));
|
||||
if (!empty($this->settings['edit']['confirmByAdmin'])) {
|
||||
$this->updateRequest($user);
|
||||
} else {
|
||||
$this->updateAllConfirmed($user);
|
||||
}
|
||||
$this->redirect('edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user User object
|
||||
* @param string $hash
|
||||
* @param string $status could be "confirm", "refuse", "silentRefuse"
|
||||
*/
|
||||
public function confirmUpdateRequestAction(User $user, $hash, $status = 'confirm'): ResponseInterface
|
||||
{
|
||||
$this->view->assign('user', $user);
|
||||
if (!HashUtility::validHash($hash, $user) || !$user->getTxFemanagerChangerequest()) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('updateFailedProfile'), '', AbstractMessage::ERROR);
|
||||
return $this->htmlResponse(null);
|
||||
}
|
||||
switch ($status) {
|
||||
case 'confirm':
|
||||
$this->statusConfirm($user);
|
||||
break;
|
||||
case 'refuse':
|
||||
$this->statusRefuse($user);
|
||||
break;
|
||||
case 'silentRefuse':
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATEREFUSEDADMIN, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEREFUSEDADMIN));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
$user->setTxFemanagerChangerequest('');
|
||||
$this->userRepository->update($user);
|
||||
|
||||
$this->eventDispatcher->dispatch(new AfterUserUpdateEvent($user, $hash, $status));
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Status update confirmation
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
protected function statusConfirm(User $user)
|
||||
{
|
||||
$values = GeneralUtility::xml2array($user->getTxFemanagerChangerequest());
|
||||
foreach ((array)$values as $field => $value) {
|
||||
if ($field !== 'usergroup' && method_exists($user, 'set' . ucfirst($field))) {
|
||||
$user->{'set' . ucfirst($field)}($value['new']);
|
||||
} else {
|
||||
$user->removeAllUsergroups();
|
||||
$usergroupUids = GeneralUtility::trimExplode(',', $value['new'], true);
|
||||
foreach ($usergroupUids as $usergroupUid) {
|
||||
/** @var UserGroup $usergroup */
|
||||
$usergroup = $this->userGroupRepository->findByUid($usergroupUid);
|
||||
$user->addUsergroup($usergroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
$user = FrontendUtility::forceValues($user, $this->config['edit.']['forceValues.']['onAdminConfirmation.']);
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATECONFIRMEDADMIN, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translate('updateProfile'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Status update refused
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
protected function statusRefuse(User $user)
|
||||
{
|
||||
$this->sendMailService->send(
|
||||
'updateRequestRefused',
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getFirstName() . ' ' . $user->getLastName()),
|
||||
['sender@femanager.org' => 'Sender Name'],
|
||||
'Your change request was refused',
|
||||
[
|
||||
'user' => $user,
|
||||
'settings' => $this->settings
|
||||
],
|
||||
$this->config['edit.']['email.']['updateRequestRefused.']
|
||||
);
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATEREFUSEDADMIN, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEREFUSEDADMIN));
|
||||
}
|
||||
|
||||
/**
|
||||
* action delete
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function deleteAction(User $user)
|
||||
{
|
||||
$currentUser = UserUtility::getCurrentUser();
|
||||
$token = $this->request->hasArgument('token') ? $this->request->getArgument('token') : null;
|
||||
$uid = $this->request->hasArgument('user') ? $this->request->getArgument('user') : null;
|
||||
if ($currentUser === null ||
|
||||
$token === null ||
|
||||
$uid === null ||
|
||||
$this->isSpoof($currentUser, (int)$uid, $token)
|
||||
) {
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATEREFUSEDSECURITY, $user);
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEREFUSEDSECURITY),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
return new ForwardResponse('edit');
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(new DeleteUserEvent($user));
|
||||
$this->logUtility->log(Log::STATUS_PROFILEDELETE, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translateByState(Log::STATUS_PROFILEDELETE));
|
||||
$this->userRepository->remove($user);
|
||||
$this->redirectByAction('delete');
|
||||
$this->redirect('edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if password should be kept
|
||||
*
|
||||
* If password is empty
|
||||
* If password repeat is also empty
|
||||
* If keepPasswordIfEmpty configuration is turned on
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function keepPassword()
|
||||
{
|
||||
return !empty($this->settings['edit']['misc']['keepPasswordIfEmpty']) &&
|
||||
empty($this->pluginVariables['user']['password']) &&
|
||||
empty($this->pluginVariables['password_repeat']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check: If there are no changes, simple redirect back
|
||||
*/
|
||||
protected function redirectIfNoChangesOnObject(User $user)
|
||||
{
|
||||
if (!ObjectUtility::isDirtyObject($user)) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('noChanges'), '', AbstractMessage::NOTICE);
|
||||
return $this->redirect('edit');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
protected function emailForUsername(User $user)
|
||||
{
|
||||
$fillEmailWithUsername = ConfigurationUtility::getValue('edit/fillEmailWithUsername', $this->settings);
|
||||
if ($fillEmailWithUsername === '1') {
|
||||
$user->setEmail($user->getUsername());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Event\InviteUserConfirmedEvent;
|
||||
use In2code\Femanager\Event\InviteUserCreateEvent;
|
||||
use In2code\Femanager\Event\InviteUserEditEvent;
|
||||
use In2code\Femanager\Event\InviteUserUpdateEvent;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\HashUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Annotation\Validate;
|
||||
use TYPO3\CMS\Extbase\Http\ForwardResponse;
|
||||
|
||||
/**
|
||||
* Class InvitationController
|
||||
*/
|
||||
class InvitationController extends AbstractFrontendController
|
||||
{
|
||||
/**
|
||||
* action new
|
||||
*/
|
||||
public function newAction(): ResponseInterface
|
||||
{
|
||||
$permissionCheck = $this->allowedUserForInvitationNewAndCreate();
|
||||
if ($permissionCheck instanceof ResponseInterface) {
|
||||
return $permissionCheck;
|
||||
}
|
||||
$this->view->assign('allUserGroups', $this->allUserGroups);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* action create
|
||||
*
|
||||
* @param User $user
|
||||
* @Validate("In2code\Femanager\Domain\Validator\ServersideValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\PasswordValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\CaptchaValidator", param="user")
|
||||
*/
|
||||
public function createAction(User $user)
|
||||
{
|
||||
if ($this->ratelimiterService->isLimited()) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('ratelimiter_too_many_attempts'),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
$this->redirect('status');
|
||||
}
|
||||
|
||||
$permissionCheck = $this->allowedUserForInvitationNewAndCreate();
|
||||
if ($permissionCheck instanceof ResponseInterface) {
|
||||
return $permissionCheck;
|
||||
}
|
||||
$user->setDisable(true);
|
||||
$user = FrontendUtility::forceValues(
|
||||
$user,
|
||||
ConfigurationUtility::getValue('invitation./forceValues./beforeAnyConfirmation.', $this->config)
|
||||
);
|
||||
$user = UserUtility::fallbackUsernameAndPassword($user);
|
||||
if (ConfigurationUtility::getValue('invitation/fillEmailWithUsername', $this->settings) === '1') {
|
||||
$user->setEmail($user->getUsername());
|
||||
}
|
||||
UserUtility::hashPassword(
|
||||
$user,
|
||||
ConfigurationUtility::getValue('invitation/misc/passwordSave', $this->settings)
|
||||
);
|
||||
$this->eventDispatcher->dispatch(new InviteUserCreateEvent($user));
|
||||
$this->ratelimiterService->consumeSlot();
|
||||
$this->createAllConfirmed($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix method to createAction()
|
||||
* Create Confirmation from Admin is not necessary
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function createAllConfirmed(User $user)
|
||||
{
|
||||
$this->userRepository->add($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createAndInvited'));
|
||||
$this->logUtility->log(Log::STATUS_INVITATIONPROFILECREATED, $user);
|
||||
|
||||
// send confirmation mail to user
|
||||
$this->sendMailService->send(
|
||||
'invitation',
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'Profile creation with invitation',
|
||||
[
|
||||
'user' => $user,
|
||||
'settings' => $this->settings,
|
||||
'hash' => HashUtility::createHashForUser($user)
|
||||
],
|
||||
$this->config['invitation.']['email.']['invitation.']
|
||||
);
|
||||
|
||||
// send notify email to admin
|
||||
$notifyAdminStep1 = ConfigurationUtility::getValue('invitation/notifyAdminStep1', $this->settings);
|
||||
if ($notifyAdminStep1) {
|
||||
$this->sendMailService->send(
|
||||
'invitationNotifyStep1',
|
||||
StringUtility::makeEmailArray(
|
||||
$notifyAdminStep1,
|
||||
ConfigurationUtility::getValue('invitation/email/invitationAdminNotifyStep1/receiver/name/value', $this->settings)
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'Profile creation with invitation - Step 1',
|
||||
[
|
||||
'user' => $user,
|
||||
'settings' => $this->settings
|
||||
],
|
||||
ConfigurationUtility::getValue('invitation./email./invitationAdminNotifyStep1.', $this->config)
|
||||
);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(new InviteUserConfirmedEvent($user));
|
||||
|
||||
$this->redirectByAction('invitation', 'redirectStep1');
|
||||
$this->redirect('new');
|
||||
}
|
||||
|
||||
/**
|
||||
* action edit
|
||||
*
|
||||
* @param int $user User UID
|
||||
* @param string $hash
|
||||
*/
|
||||
public function editAction($user, $hash = null): ResponseInterface
|
||||
{
|
||||
$user = $this->userRepository->findByUid($user);
|
||||
|
||||
// User must exist and hash must be valid
|
||||
if ($user === null || !HashUtility::validHash($hash, $user)) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createFailedProfile'), '', AbstractMessage::ERROR);
|
||||
$this->redirect('status');
|
||||
}
|
||||
|
||||
// User must not be deleted (deleted = 0) and not be activated (disable = 1)
|
||||
if ($user->getDisable() == 0) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('userAlreadyConfirmed'), '', AbstractMessage::ERROR);
|
||||
$this->redirect('status');
|
||||
}
|
||||
|
||||
$user->setDisable(false);
|
||||
$this->userRepository->update($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
|
||||
$this->eventDispatcher->dispatch(new InviteUserEditEvent($user, $hash));
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'hash' => $hash
|
||||
]
|
||||
);
|
||||
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* action update
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $hash
|
||||
* @Validate("In2code\Femanager\Domain\Validator\ServersideValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\PasswordValidator", param="user")
|
||||
*/
|
||||
public function updateAction(User $user, $hash = null)
|
||||
{
|
||||
if (!HashUtility::validHash($hash, $user)) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEREFUSEDSECURITY),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
$this->redirect('status');
|
||||
}
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createAndInvitedFinished'));
|
||||
$this->logUtility->log(Log::STATUS_INVITATIONPROFILEENABLED, $user);
|
||||
$notifyAdmin = ConfigurationUtility::getValue('invitation/notifyAdmin', $this->settings);
|
||||
if ($notifyAdmin) {
|
||||
$this->sendMailService->send(
|
||||
'invitationNotify',
|
||||
StringUtility::makeEmailArray(
|
||||
$notifyAdmin,
|
||||
ConfigurationUtility::getValue('invitation/email/invitationAdminNotify/receiver/name/value', $this->settings)
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'Profile creation with invitation - Final',
|
||||
[
|
||||
'user' => $user,
|
||||
'settings' => $this->settings
|
||||
],
|
||||
ConfigurationUtility::getValue('invitation./email./invitationAdminNotify.', $this->config)
|
||||
);
|
||||
}
|
||||
$user = UserUtility::overrideUserGroup($user, $this->settings, 'invitation');
|
||||
UserUtility::hashPassword($user, ConfigurationUtility::getValue('invitation/misc/passwordSave', $this->settings));
|
||||
$this->userRepository->update($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->eventDispatcher->dispatch(new InviteUserUpdateEvent($user));
|
||||
$this->redirectByAction('invitation', 'redirectPasswordChanged');
|
||||
$this->redirect('status');
|
||||
}
|
||||
|
||||
/**
|
||||
* action delete
|
||||
*
|
||||
* @param int $user User UID
|
||||
* @param string $hash
|
||||
*/
|
||||
public function deleteAction($user, $hash = null)
|
||||
{
|
||||
$user = $this->userRepository->findByUid($user);
|
||||
|
||||
if ($user !== null && HashUtility::validHash($hash, $user)) {
|
||||
$this->logUtility->log(Log::STATUS_PROFILEDELETE, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translateByState(Log::STATUS_INVITATIONPROFILEDELETEDUSER));
|
||||
|
||||
// send notify email to admin
|
||||
$notifyAdmin = ConfigurationUtility::getValue('invitation/notifyAdmin', $this->settings);
|
||||
if ($notifyAdmin) {
|
||||
$this->sendMailService->send(
|
||||
'invitationRefused',
|
||||
StringUtility::makeEmailArray(
|
||||
$notifyAdmin,
|
||||
ConfigurationUtility::getValue('invitation/email/invitationRefused/receiver/name/value', $this->settings)
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'Profile deleted from User after invitation - Step 1',
|
||||
[
|
||||
'user' => $user,
|
||||
'settings' => $this->settings
|
||||
],
|
||||
$this->config['invitation.']['email.']['invitationRefused.']
|
||||
);
|
||||
}
|
||||
|
||||
$this->userRepository->remove($user);
|
||||
$this->redirectByAction('invitation', 'redirectDelete');
|
||||
$this->redirect('status');
|
||||
} else {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translateByState(Log::STATUS_INVITATIONHASHERROR),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
$this->redirect('status');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restricted Action to show messages
|
||||
*/
|
||||
public function statusAction(): ResponseInterface
|
||||
{
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is allowed to see this action
|
||||
*
|
||||
* @return true|ForwardResponse
|
||||
*/
|
||||
protected function allowedUserForInvitationNewAndCreate()
|
||||
{
|
||||
if (empty($this->settings['invitation']['allowedUserGroups'] ?? [])) {
|
||||
return true;
|
||||
}
|
||||
$allowedUsergroupUids = GeneralUtility::trimExplode(
|
||||
',',
|
||||
$this->settings['invitation']['allowedUserGroups'] ?? [],
|
||||
true
|
||||
);
|
||||
$currentUsergroupUids = UserUtility::getCurrentUsergroupUids();
|
||||
|
||||
// compare allowedUsergroups with currentUsergroups
|
||||
if (count(array_intersect($allowedUsergroupUids, $currentUsergroupUids))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// current user is not allowed
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translateByState(Log::STATUS_INVITATIONRESTRICTEDPAGE),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
return new ForwardResponse('status');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,562 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Service\AutoAdminConfirmationService;
|
||||
use In2code\Femanager\Event\BeforeUserConfirmEvent;
|
||||
use In2code\Femanager\Event\BeforeUserCreateEvent;
|
||||
use In2code\Femanager\Event\CreateConfirmationRequestEvent;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\HashUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Core\Crypto\PasswordHashing\InvalidPasswordHashException;
|
||||
use TYPO3\CMS\Core\Http\ServerRequestFactory;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Annotation\Validate;
|
||||
use TYPO3\CMS\Extbase\Event\Mvc\AfterRequestDispatchedEvent;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
|
||||
use TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException;
|
||||
|
||||
/**
|
||||
* Class NewController
|
||||
*/
|
||||
class NewController extends AbstractFrontendController
|
||||
{
|
||||
/**
|
||||
* Render registration form
|
||||
*
|
||||
*/
|
||||
public function newAction(): ResponseInterface
|
||||
{
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'allUserGroups' => $this->allUserGroups
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* action create
|
||||
*
|
||||
* @param User $user
|
||||
* @throws InvalidPasswordHashException
|
||||
* @throws StopActionException
|
||||
* @Validate("In2code\Femanager\Domain\Validator\ServersideValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\PasswordValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\CaptchaValidator", param="user")
|
||||
*/
|
||||
public function createAction(User $user)
|
||||
{
|
||||
if ($this->ratelimiterService->isLimited()) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('ratelimiter_too_many_attempts'),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
$this->redirect('createStatus');
|
||||
}
|
||||
$user = UserUtility::overrideUserGroup($user, $this->settings);
|
||||
$configuration = ConfigurationUtility::getValue('new./forceValues./beforeAnyConfirmation.', $this->config);
|
||||
$user = FrontendUtility::forceValues($user, $configuration);
|
||||
$user = UserUtility::fallbackUsernameAndPassword($user);
|
||||
$user = UserUtility::takeEmailAsUsername($user, $this->settings);
|
||||
|
||||
UserUtility::hashPassword($user, ConfigurationUtility::getValue('new/misc/passwordSave', $this->settings));
|
||||
|
||||
$this->eventDispatcher->dispatch(new BeforeUserCreateEvent($user));
|
||||
$this->ratelimiterService->consumeSlot();
|
||||
|
||||
if ($this->isAllConfirmed()) {
|
||||
$this->createAllConfirmed($user);
|
||||
} else {
|
||||
$this->createRequest($user);
|
||||
}
|
||||
|
||||
$this->redirect('createStatus');
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatcher action for every confirmation request
|
||||
*
|
||||
* @param int $user User UID (user could be hidden)
|
||||
* @param string $hash Given hash
|
||||
* @param string $status
|
||||
* "userConfirmation", "userConfirmationRefused", "adminConfirmation",
|
||||
* "adminConfirmationRefused", "adminConfirmationRefusedSilent"
|
||||
* @param string $adminHash
|
||||
* @throws IllegalObjectTypeException
|
||||
* @throws StopActionException
|
||||
*/
|
||||
public function confirmCreateRequestAction(int $user, string $hash, string $status = 'adminConfirmation', string $adminHash = null)
|
||||
{
|
||||
$backend = false;
|
||||
$furtherFunctions = false;
|
||||
|
||||
$user = $this->userRepository->findByUid($user);
|
||||
|
||||
$this->eventDispatcher->dispatch(new BeforeUserConfirmEvent($user, $hash, $status));
|
||||
|
||||
if ($user === null) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('missingUserInDatabase'), '', AbstractMessage::ERROR);
|
||||
$this->redirect('new');
|
||||
}
|
||||
|
||||
$request = ServerRequestFactory::fromGlobals();
|
||||
// check if the the request was triggered via Backend
|
||||
if ($request->hasHeader('Accept')) {
|
||||
$accept = $request->getHeader('Accept')[0];
|
||||
if (false !== strpos($accept, 'application/json')) {
|
||||
$backend = true;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($status) {
|
||||
case 'userConfirmation':
|
||||
if ($status === 'userConfirmation' && ConfigurationUtility::getValue(
|
||||
'new./email./createUserConfirmation./confirmUserConfirmation',
|
||||
$this->config
|
||||
) == '1') {
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmUser',
|
||||
'hash' => $hash,
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
$furtherFunctions = $this->statusUserConfirmation($user, $hash, $status);
|
||||
break;
|
||||
|
||||
case 'confirmDeletion':
|
||||
$furtherFunctions = $this->statusUserConfirmationRefused($user, $hash);
|
||||
break;
|
||||
|
||||
case 'confirmedByUser':
|
||||
$furtherFunctions = $this->statusUserConfirmation($user, $hash, $status);
|
||||
break;
|
||||
|
||||
case 'userConfirmationRefused':
|
||||
if (ConfigurationUtility::getValue('new./email./createUserConfirmation./confirmUserConfirmationRefused', $this->config) == '1') {
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmDeletion',
|
||||
'hash' =>$hash
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
$furtherFunctions = $this->statusUserConfirmationRefused($user, $hash);
|
||||
break;
|
||||
|
||||
case 'adminConfirmation':
|
||||
if ($status === 'adminConfirmation' && ConfigurationUtility::getValue(
|
||||
'new./email./createUserConfirmation./confirmAdminConfirmation',
|
||||
$this->config
|
||||
) == '1') {
|
||||
|
||||
if (!HashUtility::validHash($adminHash, $user, 'admin')) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('error_not_authorized'),
|
||||
'',
|
||||
ContextualFeedbackSeverity::ERROR
|
||||
);
|
||||
throw new PropagateResponseException($this->redirect('new'), 1743766811);
|
||||
}
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmAdmin',
|
||||
'hash' => $hash,
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
if (($status === 'adminConfirmationRefused' || $status === 'adminConfirmationRefusedSilent') &&
|
||||
ConfigurationUtility::getValue(
|
||||
'new./email./createUserConfirmation./confirmAdminConfirmation',
|
||||
$this->config
|
||||
) == '1') {
|
||||
|
||||
if (!HashUtility::validHash($adminHash, $user, 'admin')) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('error_not_authorized'),
|
||||
'',
|
||||
ContextualFeedbackSeverity::ERROR
|
||||
);
|
||||
throw new PropagateResponseException($this->redirect('new'), 1743766811);
|
||||
}
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmAdminRefused',
|
||||
'silent' => $status === 'adminConfirmationRefusedSilent',
|
||||
'hash' => $hash,
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
$furtherFunctions = $this->statusAdminConfirmation($user, $hash, $status, $backend);
|
||||
break;
|
||||
|
||||
case 'confirmedByAdmin':
|
||||
$furtherFunctions = $this->statusAdminConfirmation($user, $hash, $status, $backend);
|
||||
break;
|
||||
|
||||
case 'confirmedByAdminRefused':
|
||||
$furtherFunctions = $this->statusAdminConfirmationRefused($user, $hash, $status, $backend);
|
||||
break;
|
||||
|
||||
case 'adminConfirmationRefused':
|
||||
// Admin refuses profile
|
||||
if (ConfigurationUtility::getValue(
|
||||
'new./email./createUserConfirmation./confirmAdminConfirmation',
|
||||
$this->config
|
||||
) == '1') {
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmAdminRefused',
|
||||
'hash' => $hash,
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'adminConfirmationRefusedSilent':
|
||||
// Admin refuses profile
|
||||
if (ConfigurationUtility::getValue(
|
||||
'new./email./createUserConfirmation./confirmAdminConfirmation',
|
||||
$this->config
|
||||
) == '1') {
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmAdminRefused',
|
||||
'hash' => $hash,
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
$furtherFunctions = $this->statusAdminConfirmationRefused($user, $hash, $status);
|
||||
break;
|
||||
case 'confirmedByAdminRefusedSilent':
|
||||
$furtherFunctions = $this->statusAdminConfirmationRefused($user, $hash, $status);
|
||||
break;
|
||||
|
||||
default:
|
||||
$furtherFunctions = false;
|
||||
}
|
||||
|
||||
if ($backend) {
|
||||
$this->eventDispatcher->dispatch(new AfterRequestDispatchedEvent($this->request, $this->response));
|
||||
$this->persistenceManager->persistAll();
|
||||
// this request was triggered via Backend Module "Frontend users", so we stop here and provide a feedback to the BE
|
||||
echo json_encode(['status' => 'okay']) . PHP_EOL;
|
||||
die();
|
||||
}
|
||||
|
||||
if ($furtherFunctions) {
|
||||
$this->redirectByAction('new', $status . 'Redirect');
|
||||
}
|
||||
|
||||
$this->redirect('new');
|
||||
}
|
||||
|
||||
/**
|
||||
* Status action: User confirmation
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $hash
|
||||
* @param string $status
|
||||
* @return bool allow further functions
|
||||
* @throws UnsupportedRequestTypeException
|
||||
* @throws IllegalObjectTypeException
|
||||
*/
|
||||
protected function statusUserConfirmation(User $user, string $hash, string $status)
|
||||
{
|
||||
if (HashUtility::validHash($hash, $user)) {
|
||||
if ($user->getTxFemanagerConfirmedbyuser()) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('userAlreadyConfirmed'), '', AbstractMessage::ERROR);
|
||||
$this->redirect('new');
|
||||
}
|
||||
|
||||
$user = FrontendUtility::forceValues($user, ConfigurationUtility::getValue('new./forceValues./onUserConfirmation.', $this->config));
|
||||
$user->setTxFemanagerConfirmedbyuser(true);
|
||||
$this->userRepository->update($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->logUtility->log(Log::STATUS_REGISTRATIONCONFIRMEDUSER, $user);
|
||||
|
||||
if ($this->isAdminConfirmationMissing($user)) {
|
||||
$this->createAdminConfirmationRequest($user);
|
||||
} else {
|
||||
$user->setDisable(false);
|
||||
$this->logUtility->log(Log::STATUS_NEWREGISTRATION, $user);
|
||||
$this->finalCreate($user, 'new', 'createStatus', true, $status);
|
||||
}
|
||||
} else {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createFailedProfile'), '', AbstractMessage::ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status action: User confirmation refused
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $hash
|
||||
* @return bool allow further functions
|
||||
* @throws IllegalObjectTypeException
|
||||
*/
|
||||
protected function statusUserConfirmationRefused(User $user, $hash)
|
||||
{
|
||||
if (HashUtility::validHash($hash, $user)) {
|
||||
$this->logUtility->log(Log::STATUS_REGISTRATIONREFUSEDUSER, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createProfileDeleted'));
|
||||
$this->userRepository->remove($user);
|
||||
} else {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createFailedProfile'), '', AbstractMessage::ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status action: Admin confirmation
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $hash
|
||||
* @param string $status
|
||||
* @return bool allow further functions
|
||||
*/
|
||||
protected function statusAdminConfirmation(User $user, $hash, $status, $backend = false)
|
||||
{
|
||||
if (HashUtility::validHash($hash, $user)) {
|
||||
if ($user->getTxFemanagerConfirmedbyadmin()) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('userAlreadyConfirmed'), '', AbstractMessage::ERROR);
|
||||
$this->redirect('new');
|
||||
}
|
||||
|
||||
$user = FrontendUtility::forceValues($user, ConfigurationUtility::getValue('new./forceValues./onAdminConfirmation.', $this->config));
|
||||
$user->setTxFemanagerConfirmedbyadmin(true);
|
||||
$user->setDisable(false);
|
||||
$this->userRepository->update($user);
|
||||
$this->logUtility->log(Log::STATUS_REGISTRATIONCONFIRMEDADMIN, $user);
|
||||
$this->finalCreate($user, 'new', 'createStatus', false, $status, $backend);
|
||||
} else {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createFailedProfile'), '', AbstractMessage::ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status action: Admin refused profile creation (normal or silent)
|
||||
*
|
||||
* @param User $user
|
||||
* @param $hash
|
||||
* @param $status
|
||||
* @return bool allow further functions
|
||||
* @throws IllegalObjectTypeException
|
||||
*/
|
||||
protected function statusAdminConfirmationRefused(User $user, $hash, $status)
|
||||
{
|
||||
if (HashUtility::validHash($hash, $user)) {
|
||||
$this->logUtility->log(Log::STATUS_REGISTRATIONREFUSEDADMIN, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createProfileDeleted'));
|
||||
if ($status !== 'adminConfirmationRefusedSilent') {
|
||||
$this->sendMailService->send(
|
||||
'CreateUserNotifyRefused',
|
||||
StringUtility::makeEmailArray(
|
||||
$user->getEmail(),
|
||||
$user->getFirstName() . ' ' . $user->getLastName()
|
||||
),
|
||||
['sender@femanager.org' => 'Sender Name'],
|
||||
'Your profile was refused',
|
||||
['user' => $user],
|
||||
ConfigurationUtility::getValue('new./email./createUserNotifyRefused.', $this->config)
|
||||
);
|
||||
}
|
||||
$this->userRepository->remove($user);
|
||||
} else {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createFailedProfile'), '', AbstractMessage::ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just for showing informations after user creation
|
||||
*/
|
||||
public function createStatusAction(): ResponseInterface
|
||||
{
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Postfix method to createAction(): Create must be confirmed by Admin or User
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
protected function createRequest(User $user)
|
||||
{
|
||||
$user->setDisable(true);
|
||||
$this->userRepository->add($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->logUtility->log(Log::STATUS_PROFILECREATIONREQUEST, $user);
|
||||
if (!empty($this->settings['new']['confirmByUser'])) {
|
||||
$this->createUserConfirmationRequest($user);
|
||||
$this->redirectByAction('new', 'requestRedirect');
|
||||
} elseif (!empty($this->settings['new']['confirmByAdmin'])) {
|
||||
$this->createAdminConfirmationRequest($user);
|
||||
$this->redirectByAction('new', 'requestRedirect');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email to user for confirmation
|
||||
*
|
||||
* @param User $user
|
||||
* @throws UnsupportedRequestTypeException
|
||||
*/
|
||||
protected function createUserConfirmationRequest(User $user)
|
||||
{
|
||||
$this->sendCreateUserConfirmationMail($user);
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createRequestWaitingForUserConfirm'));
|
||||
$this->redirectByAction('new', 'requestRedirect');
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email to admin for confirmation
|
||||
*
|
||||
* @param User $user
|
||||
* @throws UnsupportedRequestTypeException
|
||||
*/
|
||||
protected function createAdminConfirmationRequest(User $user)
|
||||
{
|
||||
$aacService = $this->objectManager->get(
|
||||
AutoAdminConfirmationService::class,
|
||||
$user,
|
||||
$this->settings,
|
||||
$this->contentObject
|
||||
);
|
||||
if ($aacService->isAutoAdminConfirmationFullfilled()) {
|
||||
$user->setDisable(false);
|
||||
$this->eventDispatcher->dispatch(
|
||||
new CreateConfirmationRequestEvent($user, CreateConfirmationRequestEvent::MODE_AUTOMATIC)
|
||||
);
|
||||
$this->createAllConfirmed($user);
|
||||
} else {
|
||||
$this->eventDispatcher->dispatch(
|
||||
new CreateConfirmationRequestEvent($user, CreateConfirmationRequestEvent::MODE_MANUAL)
|
||||
);
|
||||
$this->sendMailService->send(
|
||||
'createAdminConfirmation',
|
||||
StringUtility::makeEmailArray(
|
||||
$this->settings['new']['confirmByAdmin'] ?? '',
|
||||
$this->settings['new']['email']['createAdminConfirmation']['receiver']['name']['value'] ?? ''
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'New Registration request',
|
||||
[
|
||||
'user' => $user,
|
||||
'hash' => HashUtility::createHashForUser($user),
|
||||
'adminHash' => HashUtility::createHashForUser($user, 'admin'),
|
||||
],
|
||||
ConfigurationUtility::getValue('new./email./createAdminConfirmation.', $this->config)
|
||||
);
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createRequestWaitingForAdminConfirm'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAllConfirmed()
|
||||
{
|
||||
return empty($this->settings['new']['confirmByUser']) && empty($this->settings['new']['confirmByAdmin']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAdminConfirmationMissing(User $user)
|
||||
{
|
||||
return !empty($this->settings['new']['confirmByAdmin']) && !$user->getTxFemanagerConfirmedbyadmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Just for showing empty dialogue to resend confirmation mail
|
||||
*/
|
||||
public function resendConfirmationDialogueAction(): ResponseInterface
|
||||
{
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* re-sends a confirmation email if given mail is valid
|
||||
*
|
||||
* @throws UnsupportedRequestTypeException
|
||||
* @throws StopActionException
|
||||
*/
|
||||
public function resendConfirmationMailAction()
|
||||
{
|
||||
// @todo find a better way to fetch the data
|
||||
$result = GeneralUtility::_GP('tx_femanager_pi1');
|
||||
if (is_array($result)) {
|
||||
if (GeneralUtility::validEmail($result['user']['email'])) {
|
||||
$user = $this->userRepository->findFirstByEmail($result['user']['email']);
|
||||
if (is_a($user, User::class)) {
|
||||
$this->sendCreateUserConfirmationMail($user);
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('resendConfirmationMailSend'),
|
||||
'',
|
||||
AbstractMessage::INFO
|
||||
);
|
||||
$this->redirect('resendConfirmationDialogue');
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('resendConfirmationMailFail'),
|
||||
LocalizationUtility::translate('validationError'),
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
$this->redirect('resendConfirmationDialogue');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Event\AdminConfirmationUserEvent;
|
||||
use In2code\Femanager\Event\RefuseUserEvent;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\HashUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Site\SiteFinder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Http\ForwardResponse;
|
||||
|
||||
/**
|
||||
* Class UserBackendController
|
||||
*/
|
||||
class UserBackendController extends AbstractController
|
||||
{
|
||||
protected $configPID;
|
||||
|
||||
/**
|
||||
* @param array $filter
|
||||
*/
|
||||
public function listAction(array $filter = []): ResponseInterface
|
||||
{
|
||||
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'users' => $this->userRepository->findAllInBackend($filter),
|
||||
'moduleUri' => $uriBuilder->buildUriFromRoute('tce_db'),
|
||||
'action' => 'list',
|
||||
'loginAsEnabled' => $this->loginAsEnabled()
|
||||
]
|
||||
);
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $filter
|
||||
*/
|
||||
public function confirmationAction(array $filter = []): ResponseInterface
|
||||
{
|
||||
$this->configPID = $this->getConfigPID();
|
||||
|
||||
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'users' => $this->userRepository->findAllInBackendForConfirmation(
|
||||
$filter,
|
||||
ConfigurationUtility::isBackendModuleFilterUserConfirmation()
|
||||
),
|
||||
'moduleUri' => $uriBuilder->buildUriFromRoute('tce_db'),
|
||||
'action' => 'confirmation'
|
||||
]
|
||||
);
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function userLogoutAction(User $user)
|
||||
{
|
||||
$queryParams = $this->request->getQueryParams();
|
||||
if (empty($queryParams['id']) || $queryParams['id'] !== (string)$user->getPid()) {
|
||||
return new ForwardResponse('list');
|
||||
}
|
||||
UserUtility::removeFrontendSessionToUser($user);
|
||||
$this->addFlashMessage('User successfully logged out');
|
||||
$this->redirect('list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userIdentifier
|
||||
*/
|
||||
public function confirmUserAction(int $userIdentifier)
|
||||
{
|
||||
$this->configPID = $this->getConfigPID();
|
||||
|
||||
$user = $this->userRepository->findByUid($userIdentifier);
|
||||
$queryParams = $this->request->getQueryParams();
|
||||
if (empty($queryParams['id']) || $user === null || $queryParams['id'] !== (string)$user->getPid()) {
|
||||
return new ForwardResponse('list');
|
||||
}
|
||||
$this->eventDispatcher->dispatch(new AdminConfirmationUserEvent($user));
|
||||
|
||||
$jsonResult = $this->getFrontendRequestResult('adminConfirmation', $userIdentifier, $user);
|
||||
|
||||
if ($jsonResult['status'] ?? false) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageConfirmed',
|
||||
'femanager',
|
||||
[$user->getUsername()]
|
||||
),
|
||||
'User Confirmation'
|
||||
);
|
||||
} else {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageFailed',
|
||||
'femanager',
|
||||
[$user->getUsername()]
|
||||
),
|
||||
'User Confirmation',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
}
|
||||
|
||||
$this->redirect('confirmation');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userIdentifier
|
||||
*/
|
||||
public function refuseUserAction(int $userIdentifier)
|
||||
{
|
||||
$this->configPID = $this->getConfigPID();
|
||||
|
||||
$user = $this->userRepository->findByUid($userIdentifier);
|
||||
$queryParams = $this->request->getQueryParams();
|
||||
if (empty($queryParams['id']) || $user === null || $queryParams['id'] !== (string)$user->getPid()) {
|
||||
return new ForwardResponse('list');
|
||||
}
|
||||
$this->eventDispatcher->dispatch(new RefuseUserEvent($user));
|
||||
|
||||
$jsonResult = $this->getFrontendRequestResult('adminConfirmationRefused', $userIdentifier, $user);
|
||||
|
||||
if ($jsonResult['status'] ?? false) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageRefused',
|
||||
'femanager',
|
||||
[$user->getUsername()]
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageFailed',
|
||||
'femanager',
|
||||
[$user->getUsername()]
|
||||
),
|
||||
'User Confirmation',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
}
|
||||
|
||||
$this->redirect('confirmation');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $filter
|
||||
*/
|
||||
public function listOpenUserConfirmationsAction(array $filter = []): ResponseInterface
|
||||
{
|
||||
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'users' => $this->userRepository->findAllInBackendForConfirmation(
|
||||
$filter,
|
||||
false
|
||||
),
|
||||
'moduleUri' => $uriBuilder->buildUriFromRoute('tce_db'),
|
||||
'action' => 'listOpenUserConfirmations'
|
||||
]
|
||||
);
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userIdentifier
|
||||
*/
|
||||
public function resendUserConfirmationRequestAction(int $userIdentifier)
|
||||
{
|
||||
$user = $this->userRepository->findByUid($userIdentifier);
|
||||
$queryParams = $this->request->getQueryParams();
|
||||
if (empty($queryParams['id']) || $user === null || $queryParams['id'] !== (string)$user->getPid()) {
|
||||
return new ForwardResponse('list');
|
||||
}
|
||||
$this->sendCreateUserConfirmationMail($user);
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageReSend',
|
||||
'femanager',
|
||||
[$user->getUsername()]
|
||||
),
|
||||
'',
|
||||
AbstractMessage::OK
|
||||
);
|
||||
$this->redirect('listOpenUserConfirmations');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getConfigPID()
|
||||
{
|
||||
if (isset($this->moduleConfig['settings.']['configPID']) && $this->moduleConfig['settings.']['configPID'] > 0) {
|
||||
return (int)$this->moduleConfig['settings.']['configPID'];
|
||||
}
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendMissingConfigPID',
|
||||
'femanager'
|
||||
),
|
||||
'Backend Configuration',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $status
|
||||
* @param $userIdentifier
|
||||
* @param $user
|
||||
*/
|
||||
public function getFrontendRequestResult($status, $userIdentifier, $user)
|
||||
{
|
||||
/** @var SiteFinder $siteFinder */
|
||||
$siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
|
||||
|
||||
$site = $siteFinder->getSiteByPageId($this->configPID);
|
||||
$url = $site->getRouter()->generateUri(
|
||||
$this->configPID,
|
||||
[
|
||||
'tx_femanager_pi1' => [
|
||||
'user' => $userIdentifier,
|
||||
'hash' => HashUtility::createHashForUser($user),
|
||||
'status' => $status,
|
||||
'action' => 'confirmCreateRequest',
|
||||
'controller' => 'New'
|
||||
]
|
||||
]
|
||||
);
|
||||
|
||||
$response = GeneralUtility::makeInstance(RequestFactory::class)->request((string)$url, 'GET', ['headers' => ['accept' => 'application/json']]);
|
||||
if ($response->getStatusCode() >= 300) {
|
||||
$content = $response->getReasonPhrase();
|
||||
$GLOBALS['BE_USER']->writelog(4, 0, 1, 0, 'femanager: Frontend request failed.', $content);
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageFailed',
|
||||
'femanager'
|
||||
),
|
||||
'User Confirmation',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
} else {
|
||||
$content = $response->getBody()->getContents();
|
||||
return json_decode($content, true);
|
||||
}
|
||||
}
|
||||
|
||||
private function loginAsEnabled(): bool
|
||||
{
|
||||
if ($GLOBALS['BE_USER']->user['admin'] === 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$tsConfigEnableLoginAs = (int)($GLOBALS['BE_USER']->getTSConfig()['tx_femanager.']['UserBackend.']['enableLoginAs'] ?? 0);
|
||||
|
||||
return $tsConfigEnableLoginAs === 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Validator\ClientsideValidator;
|
||||
use In2code\Femanager\Event\ImpersonateEvent;
|
||||
use In2code\Femanager\Utility\BackendUserUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Core\Error\Http\UnauthorizedException;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
|
||||
/**
|
||||
* Class UserController
|
||||
*/
|
||||
class UserController extends AbstractFrontendController
|
||||
{
|
||||
/**
|
||||
* @param array $filter
|
||||
*/
|
||||
public function listAction(array $filter = []): ResponseInterface
|
||||
{
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'users' => $this->userRepository->findByUsergroups(
|
||||
$this->settings['list']['usergroup'] ?? '',
|
||||
$this->settings,
|
||||
$filter
|
||||
),
|
||||
'filter' => $filter
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce user setting from FlexForm and ignore &tx_femanager_pi1[user]=421
|
||||
*/
|
||||
public function initializeShowAction()
|
||||
{
|
||||
$arguments = $this->request->getArguments();
|
||||
if (!empty($this->settings['show']['user']) ?? '') {
|
||||
unset($arguments['user']);
|
||||
}
|
||||
$this->request->setArguments($arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function showAction(User $user = null): ResponseInterface
|
||||
{
|
||||
$this->view->assign('user', $this->getUser($user));
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function imageDeleteAction(User $user)
|
||||
{
|
||||
if (UserUtility::getCurrentUser() !== $user) {
|
||||
throw new UnauthorizedException('You are not allowed to delete this image', 1516373759972);
|
||||
}
|
||||
$user->setImage($this->objectManager->get(ObjectStorage::class));
|
||||
$this->userRepository->update($user);
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATEIMAGEDELETE, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEIMAGEDELETE));
|
||||
$this->redirectToUri(FrontendUtility::getUriToCurrentPage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this Action from eID to validate field values
|
||||
*
|
||||
* @param string $validation Validation string like "required, email, min(10)"
|
||||
* @param string $value Given Field value
|
||||
* @param string $field Fieldname like "username" or "email"
|
||||
* @param User $user Existing User
|
||||
* @param string $additionalValue Additional Values
|
||||
* @param int $plugin tt_content.uid of the femanager plugin
|
||||
* @param string $referrerAction current action name
|
||||
*/
|
||||
public function validateAction(
|
||||
$validation = null,
|
||||
$value = null,
|
||||
$field = null,
|
||||
User $user = null,
|
||||
$additionalValue = '',
|
||||
int $plugin = 0,
|
||||
string $referrerAction = ''
|
||||
): ResponseInterface {
|
||||
$clientsideValidator = $this->objectManager->get(ClientsideValidator::class);
|
||||
$result = $clientsideValidator
|
||||
->setValidationSettingsString($validation)
|
||||
->setValue($value)
|
||||
->setFieldName($field)
|
||||
->setUser($user)
|
||||
->setAdditionalValue($additionalValue)
|
||||
->setPlugin($plugin)
|
||||
->setActionName($referrerAction)
|
||||
->validateField();
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'isValid' => $result,
|
||||
'messages' => $clientsideValidator->getMessages(),
|
||||
'validation' => $validation,
|
||||
'value' => $value,
|
||||
'fieldname' => $field,
|
||||
'user' => $user
|
||||
]
|
||||
);
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate frontenduser login for backend adminstrators only
|
||||
*
|
||||
* @param User $user
|
||||
* @throws UnauthorizedException
|
||||
*/
|
||||
public function loginAsAction(User $user)
|
||||
{
|
||||
$this->eventDispatcher->dispatch(new ImpersonateEvent($user));
|
||||
|
||||
if (!BackendUserUtility::isAdminAuthentication()) {
|
||||
throw new UnauthorizedException(LocalizationUtility::translate('error_not_authorized'), 1516373787864);
|
||||
}
|
||||
UserUtility::login($user);
|
||||
$this->redirectByAction('loginAs', 'redirect');
|
||||
$this->redirectToUri('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return User
|
||||
*/
|
||||
protected function getUser(User $user = null)
|
||||
{
|
||||
if ($user === null) {
|
||||
if (is_numeric($this->settings['show']['user'])) {
|
||||
$user = $this->userRepository->findByUid($this->settings['show']['user']);
|
||||
} elseif ($this->settings['show']['user'] === '[this]') {
|
||||
$user = $this->user;
|
||||
}
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\DataProcessor;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class AbstractDataProcessor
|
||||
*/
|
||||
abstract class AbstractDataProcessor implements DataProcessorInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* @var ContentObjectRenderer|null
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* @var Arguments|null
|
||||
*/
|
||||
protected $controllerArguments;
|
||||
|
||||
/**
|
||||
* AbstractDataProcessor constructor.
|
||||
*
|
||||
* @param array $configuration
|
||||
* @param array $settings
|
||||
* @param ContentObjectRenderer $contentObject
|
||||
* @param Arguments $controllerArguments
|
||||
*/
|
||||
public function __construct(
|
||||
array $configuration,
|
||||
array $settings,
|
||||
ContentObjectRenderer $contentObject,
|
||||
Arguments $controllerArguments
|
||||
) {
|
||||
$this->configuration = $configuration;
|
||||
$this->settings = $settings;
|
||||
$this->contentObject = $contentObject;
|
||||
$this->controllerArguments = $controllerArguments;
|
||||
}
|
||||
|
||||
public function initializeDataProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return mixed
|
||||
*/
|
||||
public function getConfiguration(string $path = '')
|
||||
{
|
||||
$configuration = $this->configuration;
|
||||
if (!empty($path)) {
|
||||
$configuration = ArrayUtility::getValueByPath($configuration, $path, '.');
|
||||
}
|
||||
return $configuration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\DataProcessor;
|
||||
|
||||
/**
|
||||
* Class CleanUserGroup to clean empty usergroup arguments
|
||||
*/
|
||||
class CleanUserGroup extends AbstractDataProcessor
|
||||
{
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @return array
|
||||
*/
|
||||
public function process(array $arguments): array
|
||||
{
|
||||
if (is_array($arguments['user']['usergroup'] ?? null) && empty($arguments['user']['usergroup'][0]) && empty($arguments['user']['usergroup'][0]['__identity'])) {
|
||||
unset($arguments['user']['usergroup'][0]);
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\DataProcessor;
|
||||
|
||||
/**
|
||||
* Interface DataProcessorInterface
|
||||
*/
|
||||
interface DataProcessorInterface
|
||||
{
|
||||
public function initializeDataProcessor();
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @return array
|
||||
*/
|
||||
public function process(array $arguments): array;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\DataProcessor;
|
||||
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2017 Alex Kellner <alexander.kellner@in2code.de>, in2code.de
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project 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.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script 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.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
/**
|
||||
* Class DataProcessorRunner
|
||||
*/
|
||||
class DataProcessorRunner
|
||||
{
|
||||
/**
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* TypoScript settings
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $interface = DataProcessorInterface::class;
|
||||
|
||||
/**
|
||||
* Call classes after submit but before action
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param array $settings
|
||||
* @param ContentObjectRenderer $contentObject
|
||||
* @param Arguments $controllerArguments
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function callClasses(
|
||||
array $arguments,
|
||||
array $settings,
|
||||
ContentObjectRenderer $contentObject,
|
||||
Arguments $controllerArguments
|
||||
): array {
|
||||
foreach ($this->getClasses($settings) as $configuration) {
|
||||
$class = $configuration['class'];
|
||||
if (!class_exists($class)) {
|
||||
throw new \UnexpectedValueException(
|
||||
'DataProcessor class ' . $class . ' does not exists - check if file is loaded correctly',
|
||||
1516373818752
|
||||
);
|
||||
}
|
||||
if (is_subclass_of($class, $this->interface)) {
|
||||
/** @var AbstractDataProcessor $dataProcessor */
|
||||
/** @noinspection PhpMethodParametersCountMismatchInspection */
|
||||
$dataProcessor = GeneralUtility::makeInstance(
|
||||
$class,
|
||||
$configuration['config'] ?? [],
|
||||
$settings,
|
||||
$contentObject,
|
||||
$controllerArguments
|
||||
);
|
||||
$dataProcessor->initializeDataProcessor();
|
||||
$arguments = $dataProcessor->process($arguments);
|
||||
} else {
|
||||
throw new \UnexpectedValueException('Finisher does not implement ' . $this->interface, 1516373829946);
|
||||
}
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all classes to this event from typoscript and sort them
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
protected function getClasses(array $settings): array
|
||||
{
|
||||
$allDataProcessors = ConfigurationUtility::getValue('dataProcessors', $settings);
|
||||
ksort($allDataProcessors);
|
||||
$dataProcessors = [];
|
||||
foreach ($allDataProcessors as $dataProcessor) {
|
||||
if (isset($dataProcessor['events']) === true && $dataProcessor['events'] !== []) {
|
||||
foreach ($dataProcessor['events'] as $controllerName => $actionList) {
|
||||
if ($controllerName === FrontendUtility::getControllerName()) {
|
||||
if (GeneralUtility::inList($actionList, FrontendUtility::getActionName())) {
|
||||
$dataProcessors[] = $dataProcessor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dataProcessors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\DataProcessor;
|
||||
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
|
||||
|
||||
/**
|
||||
* Class DateConverter
|
||||
*/
|
||||
class DateConverter extends AbstractDataProcessor
|
||||
{
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @return array
|
||||
*/
|
||||
public function process(array $arguments): array
|
||||
{
|
||||
if (!empty($this->controllerArguments['user'])) {
|
||||
foreach (GeneralUtility::trimExplode(',', $this->getConfiguration('fieldNames'), true) as $fieldName) {
|
||||
$this->controllerArguments['user']
|
||||
->getPropertyMappingConfiguration()
|
||||
->forProperty($fieldName)
|
||||
->setTypeConverterOption(
|
||||
DateTimeConverter::class,
|
||||
DateTimeConverter::CONFIGURATION_DATE_FORMAT,
|
||||
LocalizationUtility::translate('tx_femanager_domain_model_user.dateFormat')
|
||||
);
|
||||
}
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\DataProcessor;
|
||||
|
||||
use In2code\Femanager\Domain\Service\FileService;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\FileUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\ObjectUtility;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use TYPO3\CMS\Core\Utility\File\BasicFileUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class ImageManipulation
|
||||
*/
|
||||
class ImageManipulation extends AbstractDataProcessor
|
||||
{
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @return array
|
||||
*/
|
||||
public function process(array $arguments): array
|
||||
{
|
||||
$this->allowImageProperties();
|
||||
foreach ($this->getPropertiesForUpload() as $property) {
|
||||
if ($this->isFileIdentifierGiven($arguments, $property) || $this->isUploadError($arguments, $property)) {
|
||||
unset($arguments['user'][$property]);
|
||||
} else {
|
||||
// Convert property name
|
||||
$property = lcfirst(GeneralUtility::underscoredToUpperCamelCase($property));
|
||||
|
||||
// file upload given
|
||||
foreach ($arguments['user'][$property] ?? [] as $fileItem) {
|
||||
/** @noinspection PhpMethodParametersCountMismatchInspection */
|
||||
$fileService = GeneralUtility::makeInstance(
|
||||
FileService::class,
|
||||
$this->getNewImageName($fileItem),
|
||||
$fileItem
|
||||
);
|
||||
if ($fileService->isEverythingValid()) {
|
||||
FileUtility::createFolderIfNotExists($this->getUploadFolder());
|
||||
$pathAndFilename = $this->upload($fileItem);
|
||||
$fileIdentifier = $fileService->indexFile($pathAndFilename);
|
||||
$identifier = $this->createSysFileRelation($fileIdentifier);
|
||||
$arguments['user'][$property] = [$identifier];
|
||||
} else {
|
||||
unset($arguments['user'][$property]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fileIdentifier
|
||||
* @return int
|
||||
*/
|
||||
protected function createSysFileRelation(int $fileIdentifier): int
|
||||
{
|
||||
$properties = [
|
||||
'pid' => FrontendUtility::getCurrentPid(),
|
||||
'uid_local' => $fileIdentifier,
|
||||
'tstamp' => time(),
|
||||
'crdate' => time()
|
||||
];
|
||||
foreach ($this->getConfiguration('sysFileRelation') as $field => $value) {
|
||||
$properties[$field] = $value;
|
||||
}
|
||||
|
||||
$databaseConnectionForPages = ObjectUtility::getConnectionPool()->getConnectionForTable('sys_file_reference');
|
||||
$databaseConnectionForPages->insert(
|
||||
'sys_file_reference',
|
||||
$properties
|
||||
);
|
||||
|
||||
return (int)$databaseConnectionForPages->lastInsertId('sys_file_reference');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fileItem
|
||||
* @return string New filename (absolute with path)
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function upload(array $fileItem): string
|
||||
{
|
||||
$basicFileFunctions = GeneralUtility::makeInstance(BasicFileUtility::class);
|
||||
$uniqueFileName = $basicFileFunctions->getUniqueName(
|
||||
$this->getNewImageName($fileItem),
|
||||
$this->getUploadFolder()
|
||||
);
|
||||
if (GeneralUtility::upload_copy_move($fileItem['tmp_name'], $uniqueFileName)) {
|
||||
return $uniqueFileName;
|
||||
}
|
||||
throw new \UnexpectedValueException(
|
||||
'File "' . $this->getNewImageName($fileItem) . '" could not be uploaded!',
|
||||
1516373841798
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getPropertiesForUpload(): array
|
||||
{
|
||||
$propertylist = $this->getConfiguration('propertyNamesForUpload');
|
||||
return GeneralUtility::trimExplode(',', $propertylist, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fileItem
|
||||
* @return string
|
||||
*/
|
||||
protected function getNewImageName(array $fileItem): string
|
||||
{
|
||||
$imageName = '';
|
||||
if (!empty($fileItem['name'])) {
|
||||
$imageName = $fileItem['name'];
|
||||
}
|
||||
$imageName = StringUtility::cleanString($imageName);
|
||||
return $imageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $absolute
|
||||
* @return string
|
||||
*/
|
||||
protected function getUploadFolder(bool $absolute = true): string
|
||||
{
|
||||
$path = (string)ConfigurationUtility::getConfiguration('misc.uploadFolder');
|
||||
if ($absolute === true) {
|
||||
$path = GeneralUtility::getFileAbsFileName($path);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
protected function allowImageProperties()
|
||||
{
|
||||
if (!empty($this->controllerArguments['user'])) {
|
||||
$this->controllerArguments['user']->getPropertyMappingConfiguration()->forProperty(
|
||||
'image'
|
||||
)->allowProperties(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param $property
|
||||
* @return bool
|
||||
*/
|
||||
protected function isFileIdentifierGiven(array $arguments, $property): bool
|
||||
{
|
||||
return !empty($arguments['user'][$property][0]['__identity']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param $property
|
||||
* @return bool
|
||||
*/
|
||||
protected function isUploadError(array $arguments, $property): bool
|
||||
{
|
||||
return !empty($arguments['user'][$property][0]['error']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\DataProvider;
|
||||
|
||||
use SJBR\StaticInfoTables\Domain\Model\Country;
|
||||
use SJBR\StaticInfoTables\Domain\Repository\CountryRepository;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
class CountryDataProvider
|
||||
{
|
||||
protected $countryRepository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->countryRepository = GeneralUtility::makeInstance(CountryRepository::class);
|
||||
}
|
||||
|
||||
/** @return Country[] */
|
||||
public function getCountries(): array
|
||||
{
|
||||
return $this->countryRepository->findAllOrderedBy('shortNameLocal')->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\DataProvider;
|
||||
|
||||
use SJBR\StaticInfoTables\Domain\Model\Country;
|
||||
use SJBR\StaticInfoTables\Domain\Model\CountryZone;
|
||||
use SJBR\StaticInfoTables\Domain\Repository\CountryRepository;
|
||||
use SJBR\StaticInfoTables\Domain\Repository\CountryZoneRepository;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
class CountryZonesDataProvider
|
||||
{
|
||||
private $countryZoneRepository;
|
||||
|
||||
private $countryRepository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Can not autowire optional dependencies
|
||||
$this->countryZoneRepository = GeneralUtility::makeInstance(CountryZoneRepository::class);
|
||||
$this->countryRepository = GeneralUtility::makeInstance(CountryRepository::class);
|
||||
}
|
||||
|
||||
/** @return CountryZone[] */
|
||||
public function getCountryZonesForCountryIso3(string $countryIso3): array
|
||||
{
|
||||
$country = $this->getCountryForIsoCode3($countryIso3);
|
||||
if (null === $country) {
|
||||
return [];
|
||||
}
|
||||
$countryZones = $this->countryZoneRepository->findByCountry($country)->toArray();
|
||||
usort(
|
||||
$countryZones,
|
||||
function (CountryZone $left, CountryZone $right) {
|
||||
return strcasecmp($left->getLocalName(), $right->getLocalName());
|
||||
}
|
||||
);
|
||||
return $countryZones;
|
||||
}
|
||||
|
||||
public function hasCountryZonesForCountryIso3(string $countryIso3): bool
|
||||
{
|
||||
return $this->countryZoneRepository->countByCountryIsoCodeA3($countryIso3) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $countryIso3
|
||||
* @return Country|null
|
||||
*/
|
||||
private function getCountryForIsoCode3(string $countryIso3): ?Country
|
||||
{
|
||||
$countries = $this->countryRepository->findAllowedByIsoCodeA3($countryIso3);
|
||||
$country = null;
|
||||
if (count($countries) === 1) {
|
||||
$country = array_values($countries)[0];
|
||||
}
|
||||
return $country;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\DataProvider;
|
||||
|
||||
class FallbackCountryDataProvider
|
||||
{
|
||||
protected static $countries = [
|
||||
'AND' => 'Andorra',
|
||||
'ARE' => 'الإمارات العربيّة المتّحدة',
|
||||
'AFG' => 'افغانستان',
|
||||
'ATG' => 'Antigua and Barbuda',
|
||||
'AIA' => 'Anguilla',
|
||||
'ALB' => 'Shqipëria',
|
||||
'ARM' => 'Հայաստան',
|
||||
'ANT' => 'Nederlandse Antillen',
|
||||
'AGO' => 'Angola',
|
||||
'ATA' => 'Antarctica',
|
||||
'ARG' => 'Argentina',
|
||||
'ASM' => 'Amerika Samoa',
|
||||
'AUT' => 'Österreich',
|
||||
'AUS' => 'Australia',
|
||||
'ABW' => 'Aruba',
|
||||
'AZE' => 'Azərbaycan',
|
||||
'BIH' => 'BiH/БиХ',
|
||||
'BRB' => 'Barbados',
|
||||
'BGD' => 'বাংলাদেশ',
|
||||
'BEL' => 'Belgique',
|
||||
'BFA' => 'Burkina',
|
||||
'BGR' => 'България (Bulgaria)',
|
||||
'BHR' => 'البحري',
|
||||
'BDI' => 'Burundi',
|
||||
'BEN' => 'Bénin',
|
||||
'BMU' => 'Bermuda',
|
||||
'BRN' => 'دارالسلام',
|
||||
'BOL' => 'Bolivia',
|
||||
'BRA' => 'Brasil',
|
||||
'BHS' => 'The Bahamas',
|
||||
'BTN' => 'Druk-Yul',
|
||||
'BVT' => 'Bouvet Island',
|
||||
'BWA' => 'Botswana',
|
||||
'BLR' => 'Беларусь',
|
||||
'BLZ' => 'Belize',
|
||||
'CAN' => 'Canada',
|
||||
'CCK' => 'Cocos (Keeling) Islands',
|
||||
'COD' => 'Congo',
|
||||
'CAF' => 'Centrafrique',
|
||||
'COG' => 'Congo-Brazzaville',
|
||||
'CHE' => 'Schweiz',
|
||||
'CIV' => 'Côte d’Ivoire',
|
||||
'COK' => 'Cook Islands',
|
||||
'CHL' => 'Chile',
|
||||
'CMR' => 'Cameroun',
|
||||
'CHN' => '中华',
|
||||
'COL' => 'Colombia',
|
||||
'CRI' => 'Costa Rica',
|
||||
'CUB' => 'Cuba',
|
||||
'CPV' => 'Cabo Verde',
|
||||
'CXR' => 'Christmas Island',
|
||||
'CYP' => 'Κύπρος / Kıbrıs',
|
||||
'CZE' => 'Česko',
|
||||
'DEU' => 'Deutschland',
|
||||
'DJI' => 'Djibouti',
|
||||
'DNK' => 'Danmark',
|
||||
'DMA' => 'Dominica',
|
||||
'DOM' => 'Quisqueya',
|
||||
'DZA' => 'الجزائ',
|
||||
'ECU' => 'Ecuador',
|
||||
'EST' => 'Eesti',
|
||||
'EGY' => 'مصر',
|
||||
'ESH' => 'الصحراء الغربي',
|
||||
'ERI' => 'ኤርትራ',
|
||||
'ESP' => 'España',
|
||||
'ETH' => 'ኢትዮጵያ',
|
||||
'FIN' => 'Suomi',
|
||||
'FJI' => 'Fiji / Viti',
|
||||
'FLK' => 'Falkland Islands',
|
||||
'FSM' => 'Micronesia',
|
||||
'FRO' => 'Føroyar / Færøerne',
|
||||
'FRA' => 'France',
|
||||
'GAB' => 'Gabon',
|
||||
'GBR' => 'United Kingdom',
|
||||
'GRD' => 'Grenada',
|
||||
'GEO' => 'საქართველო',
|
||||
'GUF' => 'Guyane française',
|
||||
'GHA' => 'Ghana',
|
||||
'GIB' => 'Gibraltar',
|
||||
'GRL' => 'Grønland',
|
||||
'GMB' => 'Gambia',
|
||||
'GIN' => 'Guinée',
|
||||
'GLP' => 'Guadeloupe',
|
||||
'GNQ' => 'Guinea Ecuatorial',
|
||||
'GRC' => 'Ελλάδα',
|
||||
'SGS' => 'South Georgia and the South Sandwich Islands',
|
||||
'GTM' => 'Guatemala',
|
||||
'GUM' => 'Guåhån',
|
||||
'GNB' => 'Guiné-Bissau',
|
||||
'GUY' => 'Guyana',
|
||||
'HKG' => '香港',
|
||||
'HND' => 'Honduras',
|
||||
'HRV' => 'Hrvatska',
|
||||
'HTI' => 'Ayiti',
|
||||
'HUN' => 'Magyarország',
|
||||
'IDN' => 'Indonesia',
|
||||
'IRL' => 'Éire',
|
||||
'ISR' => 'ישראל',
|
||||
'IND' => 'India',
|
||||
'IOT' => 'British Indian Ocean Territory',
|
||||
'IRQ' => 'العراق / عيَراق',
|
||||
'IRN' => 'ايران',
|
||||
'ISL' => 'Ísland',
|
||||
'ITA' => 'Italia',
|
||||
'JAM' => 'Jamaica',
|
||||
'JOR' => 'أردنّ',
|
||||
'JPN' => '日本',
|
||||
'KEN' => 'Kenya',
|
||||
'KGZ' => 'Кыргызстан',
|
||||
'KHM' => 'Kâmpŭchea',
|
||||
'KIR' => 'Kiribati',
|
||||
'COM' => 'اتحاد القمر',
|
||||
'KNA' => 'Saint Kitts and Nevis',
|
||||
'PRK' => '북조선',
|
||||
'KOR' => '한국',
|
||||
'KWT' => 'الكويت',
|
||||
'CYM' => 'Cayman Islands',
|
||||
'KAZ' => 'Қазақстан /Казахстан',
|
||||
'LAO' => 'ເມືອງລາວ',
|
||||
'LBN' => 'لبنان',
|
||||
'LCA' => 'Saint Lucia',
|
||||
'LIE' => 'Liechtenstein',
|
||||
'LKA' => 'ශ්රී ලංකා / இலங்கை',
|
||||
'LBR' => 'Liberia',
|
||||
'LSO' => 'Lesotho',
|
||||
'LTU' => 'Lietuva',
|
||||
'LUX' => 'Luxemburg',
|
||||
'LVA' => 'Latvija',
|
||||
'LBY' => 'ليبيا',
|
||||
'MAR' => 'المغربية',
|
||||
'MCO' => 'Monaco',
|
||||
'MDA' => 'Moldova',
|
||||
'MDG' => 'Madagascar',
|
||||
'MHL' => 'Marshall Islands',
|
||||
'MKD' => 'Македонија',
|
||||
'MLI' => 'Mali',
|
||||
'MMR' => 'Myanmar',
|
||||
'MNG' => 'Монгол Улс',
|
||||
'MAC' => '澳門 / Macau',
|
||||
'MNP' => 'Northern Marianas',
|
||||
'MTQ' => 'Martinique',
|
||||
'MRT' => 'الموريتانية',
|
||||
'MSR' => 'Montserrat',
|
||||
'MLT' => 'Malta',
|
||||
'MUS' => 'Mauritius',
|
||||
'MDV' => 'ޖުމުހޫރިއްޔ',
|
||||
'MWI' => 'Malawi',
|
||||
'MEX' => 'México',
|
||||
'MYS' => 'مليسيا',
|
||||
'MOZ' => 'Moçambique',
|
||||
'NAM' => 'Namibia',
|
||||
'NCL' => 'Nouvelle-Calédonie',
|
||||
'NER' => 'Niger',
|
||||
'NFK' => 'Norfolk Island',
|
||||
'NGA' => 'Nigeria',
|
||||
'NIC' => 'Nicaragua',
|
||||
'NLD' => 'Nederland',
|
||||
'NOR' => 'Norge',
|
||||
'NPL' => 'नेपाल',
|
||||
'NRU' => 'Naoero',
|
||||
'NIU' => 'Niue',
|
||||
'NZL' => 'New Zealand / Aotearoa',
|
||||
'OMN' => 'عُمان',
|
||||
'PAN' => 'Panamá',
|
||||
'PER' => 'Perú',
|
||||
'PYF' => 'Polynésie française',
|
||||
'PNG' => 'Papua New Guinea / Papua Niugini',
|
||||
'PHL' => 'Philippines',
|
||||
'PAK' => 'پاکستان',
|
||||
'POL' => 'Polska',
|
||||
'SPM' => 'Saint-Pierre-et-Miquelon',
|
||||
'PCN' => 'Pitcairn Islands',
|
||||
'PRI' => 'Puerto Rico',
|
||||
'PRT' => 'Portugal',
|
||||
'PLW' => 'Belau / Palau',
|
||||
'PRY' => 'Paraguay',
|
||||
'QAT' => 'قطر',
|
||||
'REU' => 'Réunion',
|
||||
'ROU' => 'România',
|
||||
'RUS' => 'Россия',
|
||||
'RWA' => 'Rwanda',
|
||||
'SAU' => 'السعودية',
|
||||
'SLB' => 'Solomon Islands',
|
||||
'SYC' => 'Seychelles',
|
||||
'SDN' => 'Sénégal',
|
||||
'SWE' => 'Sverige',
|
||||
'SGP' => 'Singapore',
|
||||
'SHN' => 'Saint Helena, Ascension and Tristan da Cunha',
|
||||
'SVN' => 'Slovenija',
|
||||
'SJM' => 'Svalbard',
|
||||
'SVK' => 'Slovensko',
|
||||
'SLE' => 'Sierra Leone',
|
||||
'SMR' => 'San Marino',
|
||||
'SEN' => 'Sénégal',
|
||||
'SOM' => 'Soomaaliya',
|
||||
'SUR' => 'Suriname',
|
||||
'STP' => 'São Tomé e Príncipe',
|
||||
'SLV' => 'El Salvador',
|
||||
'SYR' => 'سوري',
|
||||
'SWZ' => 'weSwatini',
|
||||
'TCA' => 'Turks and Caicos Islands',
|
||||
'TCD' => 'Tchad',
|
||||
'ATF' => 'Terres australes fran‡aises',
|
||||
'TGO' => 'Togo',
|
||||
'THA' => 'ไทย',
|
||||
'TJK' => 'Тоҷикистон',
|
||||
'TKL' => 'Tokelau',
|
||||
'TKM' => 'Türkmenistan',
|
||||
'TUN' => 'التونسية',
|
||||
'TON' => 'Tonga',
|
||||
'TLS' => 'Timor Lorosa\'e',
|
||||
'TUR' => 'Türkiye',
|
||||
'TTO' => 'Trinidad and Tobago',
|
||||
'TUV' => 'Tuvalu',
|
||||
'TWN' => '中華',
|
||||
'TZA' => 'Tanzania',
|
||||
'UKR' => 'Україна',
|
||||
'UGA' => 'Uganda',
|
||||
'UMI' => 'United States Minor Outlying Islands',
|
||||
'USA' => 'United States',
|
||||
'URY' => 'Uruguay',
|
||||
'UZB' => 'O‘zbekiston',
|
||||
'VAT' => 'Vaticano',
|
||||
'VCT' => 'Saint Vincent and the Grenadines',
|
||||
'VEN' => 'Venezuela',
|
||||
'VGB' => 'British Virgin Islands',
|
||||
'VIR' => 'US Virgin Islands',
|
||||
'VNM' => 'Việt Nam',
|
||||
'VUT' => 'Vanuatu',
|
||||
'WLF' => 'Wallis and Futuna',
|
||||
'WSM' => 'Samoa',
|
||||
'YEM' => 'اليمنية',
|
||||
'MYT' => 'Mayotte',
|
||||
'ZAF' => 'Afrika-Borwa',
|
||||
'ZMB' => 'Zambia',
|
||||
'ZWE' => 'Zimbabwe',
|
||||
'PSE' => 'فلسطين',
|
||||
'CSG' => 'Србија и Црна Гора',
|
||||
'ALA' => 'Åland',
|
||||
'HMD' => 'Heard Island and McDonald Islands',
|
||||
'MNE' => 'Crna Gora',
|
||||
'SRB' => 'Srbija',
|
||||
'JEY' => 'Jersey',
|
||||
'GGY' => 'Guernsey',
|
||||
'IMN' => 'Mann / Mannin',
|
||||
'MAF' => 'Saint-Martin',
|
||||
'BLM' => 'Saint-Barthélemy',
|
||||
'BES' => 'Bonaire, Sint Eustatius en Saba',
|
||||
'CUW' => 'Curaçao',
|
||||
'SXM' => 'Sint Maarten',
|
||||
'SSD' => 'South Sudan'
|
||||
];
|
||||
|
||||
/** @return string[] */
|
||||
public function getCountries(): array
|
||||
{
|
||||
return self::$countries;
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\DependencyInjection\CompilerPass;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap;
|
||||
|
||||
class ChangeClassDatamapPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition(DataMap::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->findDefinition(DataMap::class);
|
||||
$definition->setClass(\In2code\Femanager\Persistence\Generic\Mapper\DataMap::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Model;
|
||||
|
||||
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
|
||||
|
||||
/**
|
||||
* Class Log
|
||||
*/
|
||||
class Log extends AbstractEntity
|
||||
{
|
||||
const STATUS_NEWREGISTRATION = 101;
|
||||
const STATUS_REGISTRATIONCONFIRMEDUSER = 102;
|
||||
const STATUS_REGISTRATIONCONFIRMEDADMIN = 103;
|
||||
const STATUS_REGISTRATIONREFUSEDUSER = 104;
|
||||
const STATUS_REGISTRATIONREFUSEDADMIN = 105;
|
||||
const STATUS_PROFILECREATIONREQUEST = 106;
|
||||
const STATUS_PROFILEUPDATED = 201;
|
||||
const STATUS_PROFILEUPDATECONFIRMEDADMIN = 202;
|
||||
const STATUS_PROFILEUPDATEREFUSEDADMIN = 203;
|
||||
const STATUS_PROFILEUPDATEREQUEST = 204;
|
||||
const STATUS_PROFILEUPDATEREFUSEDSECURITY = 205;
|
||||
const STATUS_PROFILEUPDATEIMAGEDELETE = 206;
|
||||
const STATUS_PROFILEUPDATEATTEMPTEDSPOOF = 207;
|
||||
const STATUS_PROFILEDELETE = 301;
|
||||
const STATUS_INVITATIONPROFILECREATED = 401;
|
||||
const STATUS_INVITATIONPROFILEDELETEDUSER = 402;
|
||||
const STATUS_INVITATIONHASHERROR = 403;
|
||||
const STATUS_INVITATIONRESTRICTEDPAGE = 404;
|
||||
const STATUS_INVITATIONPROFILEENABLED = 405;
|
||||
|
||||
/**
|
||||
* title
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $title;
|
||||
|
||||
/**
|
||||
* state
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* user
|
||||
*
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
* @return Log
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $state
|
||||
* @return Log
|
||||
*/
|
||||
public function setState($state)
|
||||
{
|
||||
$this->state = $state;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user
|
||||
*
|
||||
* @param User $user
|
||||
* @return Log
|
||||
*/
|
||||
public function setUser(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Model;
|
||||
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Domain\Model\FrontendUser;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
|
||||
/**
|
||||
* Class User
|
||||
*/
|
||||
class User extends FrontendUser
|
||||
{
|
||||
const TABLE_NAME = 'fe_users';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $txFemanagerChangerequest;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $crdate;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $tstamp;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $disable;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $txFemanagerConfirmedbyuser;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $txFemanagerConfirmedbyadmin;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isOnline = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $ignoreDirty = false;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $gender;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $dateOfBirth;
|
||||
|
||||
/**
|
||||
* termsAndConditions
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $terms = false;
|
||||
|
||||
/**
|
||||
* the datetime the user accepted the terms
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $termsDateOfAcceptance;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $txExtbaseType;
|
||||
|
||||
/**
|
||||
* Created Password in Cleartext (if generated Password)
|
||||
* will of course not be persistent and lives until runtime end
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $passwordAutoGenerated;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $state = '';
|
||||
|
||||
public function removeAllUsergroups()
|
||||
{
|
||||
$this->usergroup = new ObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $txFemanagerChangerequest
|
||||
* @return User
|
||||
*/
|
||||
public function setTxFemanagerChangerequest($txFemanagerChangerequest)
|
||||
{
|
||||
$this->txFemanagerChangerequest = $txFemanagerChangerequest;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTxFemanagerChangerequest()
|
||||
{
|
||||
return $this->txFemanagerChangerequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $crdate
|
||||
* @return User
|
||||
*/
|
||||
public function setCrdate($crdate)
|
||||
{
|
||||
$this->crdate = $crdate;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCrdate()
|
||||
{
|
||||
if ($this->crdate === null) {
|
||||
// timestamp is zero
|
||||
$this->crdate = new \DateTime('01.01.1970');
|
||||
}
|
||||
return $this->crdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $tstamp
|
||||
* @return User
|
||||
*/
|
||||
public function setTstamp($tstamp)
|
||||
{
|
||||
$this->tstamp = $tstamp;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getTstamp()
|
||||
{
|
||||
return $this->tstamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $disable
|
||||
* @return User
|
||||
*/
|
||||
public function setDisable($disable)
|
||||
{
|
||||
$this->disable = $disable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getDisable()
|
||||
{
|
||||
return $this->disable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \bool $txFemanagerConfirmedbyadmin
|
||||
* @return User
|
||||
*/
|
||||
public function setTxFemanagerConfirmedbyadmin($txFemanagerConfirmedbyadmin)
|
||||
{
|
||||
$this->txFemanagerConfirmedbyadmin = $txFemanagerConfirmedbyadmin;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \bool
|
||||
*/
|
||||
public function getTxFemanagerConfirmedbyadmin()
|
||||
{
|
||||
return $this->txFemanagerConfirmedbyadmin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \bool $txFemanagerConfirmedbyuser
|
||||
* @return User
|
||||
*/
|
||||
public function setTxFemanagerConfirmedbyuser($txFemanagerConfirmedbyuser)
|
||||
{
|
||||
$this->txFemanagerConfirmedbyuser = $txFemanagerConfirmedbyuser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \bool
|
||||
*/
|
||||
public function getTxFemanagerConfirmedbyuser()
|
||||
{
|
||||
return $this->txFemanagerConfirmedbyuser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $ignoreDirty
|
||||
* @return User
|
||||
*/
|
||||
public function setIgnoreDirty($ignoreDirty)
|
||||
{
|
||||
$this->ignoreDirty = $ignoreDirty;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getIgnoreDirty()
|
||||
{
|
||||
return $this->ignoreDirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gender
|
||||
*
|
||||
* @return int $gender
|
||||
*/
|
||||
public function getGender()
|
||||
{
|
||||
return $this->gender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the gender
|
||||
*
|
||||
* @param int $gender
|
||||
* @return User
|
||||
*/
|
||||
public function setGender($gender)
|
||||
{
|
||||
$this->gender = $gender;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dateOfBirth
|
||||
*
|
||||
* @return \DateTime $dateOfBirth
|
||||
*/
|
||||
public function getDateOfBirth()
|
||||
{
|
||||
return $this->dateOfBirth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dateOfBirth
|
||||
*
|
||||
* @param \DateTime $dateOfBirth
|
||||
* @return User
|
||||
*/
|
||||
public function setDateOfBirth($dateOfBirth)
|
||||
{
|
||||
if ($dateOfBirth instanceof \DateTime) {
|
||||
$dateOfBirth->setTime(0, 0, 0);
|
||||
}
|
||||
$this->dateOfBirth = $dateOfBirth;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns, whether the user has accepted terms and conditions
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isTerms(): bool
|
||||
{
|
||||
return $this->terms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the user has accepted terms and conditions
|
||||
*
|
||||
* @param bool $terms
|
||||
* @return User
|
||||
*/
|
||||
public function setTerms(bool $terms)
|
||||
{
|
||||
$this->terms = $terms;
|
||||
$this->setTermsDateOfAcceptance();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getTermsDateOfAcceptance()
|
||||
{
|
||||
return $this->termsDateOfAcceptance;
|
||||
}
|
||||
|
||||
/**
|
||||
* set terms date to now if it's not set yet
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
protected function setTermsDateOfAcceptance()
|
||||
{
|
||||
if ($this->termsDateOfAcceptance === null) {
|
||||
$now = new \DateTime();
|
||||
$this->termsDateOfAcceptance = $now;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsOnline(): bool
|
||||
{
|
||||
return $this->isOnline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if last FE login was within the last 2h
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOnline(): bool
|
||||
{
|
||||
if ($this->getLastlogin() !== null && method_exists($this->getLastlogin(), 'getTimestamp')
|
||||
&& $this->getLastlogin()->getTimestamp() > (time() - 2 * 60 * 60)
|
||||
&& UserUtility::checkFrontendSessionToUser($this)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return $this->isOnline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $txExtbaseType
|
||||
* @return User
|
||||
*/
|
||||
public function setTxExtbaseType($txExtbaseType)
|
||||
{
|
||||
$this->txExtbaseType = $txExtbaseType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTxExtbaseType()
|
||||
{
|
||||
return $this->txExtbaseType;
|
||||
}
|
||||
|
||||
public function getFirstImage()
|
||||
{
|
||||
$images = $this->getImage();
|
||||
foreach ($images as $image) {
|
||||
return $image;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $passwordAutoGenerated
|
||||
* @return User
|
||||
*/
|
||||
public function setPasswordAutoGenerated($passwordAutoGenerated)
|
||||
{
|
||||
$this->passwordAutoGenerated = $passwordAutoGenerated;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPasswordAutoGenerated()
|
||||
{
|
||||
return $this->passwordAutoGenerated;
|
||||
}
|
||||
|
||||
public function getState(): string
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
public function setState(string $state): void
|
||||
{
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
public function getInactiveSince(): ?\DateTime
|
||||
{
|
||||
$timestampLastSession = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getConnectionForTable('fe_sessions')
|
||||
->select(['ses_tstamp'], 'fe_sessions', ['ses_userid' => $this->getUid()])
|
||||
->fetchOne();
|
||||
|
||||
if ($timestampLastSession) {
|
||||
$inactiveSince = new \DateTime();
|
||||
$inactiveSince->setTimestamp($timestampLastSession);
|
||||
|
||||
return $inactiveSince;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround to disable persistence in updateAction
|
||||
*
|
||||
* @param null $propertyName
|
||||
* @return bool
|
||||
*/
|
||||
public function _isDirty($propertyName = null)
|
||||
{
|
||||
return $this->getIgnoreDirty() ? false : parent::_isDirty($propertyName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Model;
|
||||
|
||||
use TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup;
|
||||
|
||||
/**
|
||||
* Class UserGroup
|
||||
*/
|
||||
class UserGroup extends FrontendUserGroup
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Repository;
|
||||
|
||||
use TYPO3\CMS\Extbase\Persistence\Repository;
|
||||
|
||||
/**
|
||||
* Class LogRepository
|
||||
*/
|
||||
class LogRepository extends Repository
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Repository;
|
||||
|
||||
use Doctrine\DBAL\Driver\Exception;
|
||||
use Doctrine\DBAL\ForwardCompatibility\Result;
|
||||
use In2code\Femanager\Utility\ObjectUtility;
|
||||
use LogicException;
|
||||
use PDO;
|
||||
use TYPO3\CMS\Core\Service\FlexFormService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class PluginRepository
|
||||
*/
|
||||
class PluginRepository
|
||||
{
|
||||
const TABLE_NAME = 'tt_content';
|
||||
|
||||
protected FlexFormService $flexFormService;
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected array $scaString = [
|
||||
'new' => 'New->new;New->create;New->createStatus;New->confirmCreateRequest;',
|
||||
'edit' => 'Edit->edit;Edit->update;Edit->delete;Edit->confirmUpdateRequest;User->imageDelete;',
|
||||
'invitation' => 'Invitation->new;Invitation->create;Invitation->edit;'
|
||||
. 'Invitation->update;Invitation->delete;Invitation->status;',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param FlexFormService|null $flexFormService
|
||||
*/
|
||||
public function __construct(FlexFormService $flexFormService = null)
|
||||
{
|
||||
$this->flexFormService = $flexFormService ?? GeneralUtility::makeInstance(FlexFormService::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $contentIdentifier
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getControllerNameByPluginSettings(int $contentIdentifier): string
|
||||
{
|
||||
$queryBuilder = ObjectUtility::getQueryBuilder(self::TABLE_NAME);
|
||||
$flexFormQuery = $queryBuilder
|
||||
->select('pi_flexform')
|
||||
->from(self::TABLE_NAME)
|
||||
->where('uid=' . $contentIdentifier)
|
||||
->execute();
|
||||
if (! $flexFormQuery instanceof Result) {
|
||||
throw new \Exception(
|
||||
'Something went wrong while getting FlexForm-value from Query.',
|
||||
1638443805
|
||||
);
|
||||
}
|
||||
$flexForm = (string)$flexFormQuery->fetchOne();
|
||||
|
||||
return $this->getViewFromFlexForm($flexForm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $view can be "new", "edit" or "invitation"
|
||||
* @param int $pageIdentifier
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function isPluginWithViewOnGivenPage(string $view, int $pageIdentifier): bool
|
||||
{
|
||||
$queryBuilder = ObjectUtility::getQueryBuilder(self::TABLE_NAME);
|
||||
$pluginConfigurationQuery = $queryBuilder
|
||||
->select('pi_flexform')
|
||||
->from(self::TABLE_NAME)
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pageIdentifier, PDO::PARAM_INT)),
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('list')),
|
||||
$queryBuilder->expr()->eq('list_type', $queryBuilder->createNamedParameter('femanager_pi1'))
|
||||
)
|
||||
->execute();
|
||||
if (! $pluginConfigurationQuery instanceof Result) {
|
||||
throw new \Exception(
|
||||
'Something went wrong while getting PluginConfigurations from query.',
|
||||
1638443806
|
||||
);
|
||||
}
|
||||
$pluginConfigurations = $pluginConfigurationQuery->fetchAllAssociative();
|
||||
foreach ($pluginConfigurations as $pluginConfiguration) {
|
||||
if ($this->isViewInPluginConfiguration($view, (string)$pluginConfiguration['pi_flexform'])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $flexForm
|
||||
* @return string
|
||||
*/
|
||||
protected function getViewFromFlexForm(string $flexForm): string
|
||||
{
|
||||
$view = '';
|
||||
$settings = $this->flexFormService->convertFlexFormContentToArray($flexForm);
|
||||
if (!empty($settings['switchableControllerActions'])
|
||||
&& in_array($settings['switchableControllerActions'], $this->scaString)) {
|
||||
$view = array_search($settings['switchableControllerActions'], $this->scaString);
|
||||
}
|
||||
if (! is_string($view)) {
|
||||
return '';
|
||||
}
|
||||
return $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $view
|
||||
* @param string $pluginConfiguration
|
||||
* @return bool
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function isViewInPluginConfiguration(string $view, string $pluginConfiguration): bool
|
||||
{
|
||||
$flexFormArray = $this->flexFormService->convertFlexFormContentToArray($pluginConfiguration);
|
||||
if (array_key_exists($view, $this->scaString)) {
|
||||
return $this->scaString[$view] === $flexFormArray['switchableControllerActions'];
|
||||
}
|
||||
throw new LogicException('Given view is not allowed', 1541506310);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Repository;
|
||||
|
||||
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
|
||||
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
|
||||
use TYPO3\CMS\Extbase\Persistence\Repository;
|
||||
|
||||
/**
|
||||
* Class UserGroupRepository
|
||||
*/
|
||||
class UserGroupRepository extends Repository
|
||||
{
|
||||
/**
|
||||
* Find all groups and respect exclude list
|
||||
*
|
||||
* @param string $removeList commaseparated list
|
||||
* @return QueryResultInterface
|
||||
*/
|
||||
public function findAllForFrontendSelection($removeList)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
if ($removeList) {
|
||||
$query->matching($query->logicalNot($query->in('uid', explode(',', $removeList))));
|
||||
}
|
||||
$query->setOrderings(['title' => QueryInterface::ORDER_ASCENDING]);
|
||||
return $query->execute();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Domain\Repository;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Utility\BackendUserUtility;
|
||||
use In2code\Femanager\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Database\QueryGenerator;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
|
||||
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
|
||||
use TYPO3\CMS\Extbase\Persistence\Repository;
|
||||
|
||||
/**
|
||||
* Class UserRepository
|
||||
*/
|
||||
class UserRepository extends Repository
|
||||
{
|
||||
/**
|
||||
* Overload Find by UID to also get hidden records
|
||||
*
|
||||
* @param int $uid fe_users UID
|
||||
* @return User
|
||||
*/
|
||||
public function findByUid($uid)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$this->ignoreEnableFieldsAndStoragePage($query);
|
||||
$query->getQuerySettings()->setRespectSysLanguage(false);
|
||||
$and = [$query->equals('uid', $uid)];
|
||||
|
||||
/** @var User $user */
|
||||
$user = $query->matching($query->logicalAnd($and))->execute()->getFirst();
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find users by commaseparated usergroup list
|
||||
*
|
||||
* @param string $userGroupList commaseparated list of usergroup uids
|
||||
* @param array $settings Flexform and TypoScript Settings
|
||||
* @param array $filter Filter Array
|
||||
* @return QueryResultInterface|array
|
||||
*/
|
||||
public function findByUsergroups($userGroupList, $settings, $filter)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
|
||||
// where
|
||||
$and = [
|
||||
$query->greaterThan('uid', 0)
|
||||
];
|
||||
if (!empty($userGroupList)) {
|
||||
$selectedUsergroups = GeneralUtility::trimExplode(',', $userGroupList, true);
|
||||
$logicalOr = [];
|
||||
foreach ($selectedUsergroups as $group) {
|
||||
$logicalOr[] = $query->contains('usergroup', $group);
|
||||
}
|
||||
$and[] = $query->logicalOr($logicalOr);
|
||||
}
|
||||
if (!empty($filter['searchword'])) {
|
||||
$searchwords = GeneralUtility::trimExplode(' ', $filter['searchword'], true);
|
||||
$fieldsToSearch = GeneralUtility::trimExplode(
|
||||
',',
|
||||
$settings['list']['filter']['searchword']['fieldsToSearch'],
|
||||
true
|
||||
);
|
||||
foreach ($searchwords as $searchword) {
|
||||
$logicalOr = [];
|
||||
foreach ($fieldsToSearch as $searchfield) {
|
||||
$logicalOr[] = $query->like($searchfield, '%' . $searchword . '%');
|
||||
}
|
||||
$and[] = $query->logicalOr($logicalOr);
|
||||
}
|
||||
}
|
||||
$query->matching($query->logicalAnd($and));
|
||||
|
||||
// sorting
|
||||
$sorting = QueryInterface::ORDER_ASCENDING;
|
||||
if ($settings['list']['sorting'] === 'desc') {
|
||||
$sorting = QueryInterface::ORDER_DESCENDING;
|
||||
}
|
||||
$field = preg_replace('/[^a-zA-Z0-9_-]/', '', $settings['list']['orderby']);
|
||||
$query->setOrderings([$field => $sorting]);
|
||||
|
||||
// set limit
|
||||
if ((int)$settings['list']['limit'] > 0) {
|
||||
$query->setLimit((int)$settings['list']['limit']);
|
||||
}
|
||||
|
||||
$users = $query->execute();
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is already an entry in the table
|
||||
*
|
||||
* @param $field
|
||||
* @param $value
|
||||
* @param User $user Existing User
|
||||
* @return User|null
|
||||
*/
|
||||
public function checkUniqueDb($field, $value, User $user = null)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$this->ignoreEnableFieldsAndStoragePageAndStarttime($query);
|
||||
|
||||
$and = [$query->equals($field, $value)];
|
||||
if ($user !== null && method_exists($user, 'getUid')) {
|
||||
$and[] = $query->logicalNot($query->equals('uid', $user->getUid()));
|
||||
}
|
||||
$constraint = $query->logicalAnd($and);
|
||||
|
||||
$query->matching($constraint);
|
||||
|
||||
/** @var User $user */
|
||||
$user = $query->execute()->getFirst();
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is already an entry in the table on current page
|
||||
*
|
||||
* @param $field
|
||||
* @param $value
|
||||
* @param User $user Existing User
|
||||
* @return User|null
|
||||
*/
|
||||
public function checkUniquePage($field, $value, User $user = null)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$query->getQuerySettings()->setIgnoreEnableFields(true);
|
||||
|
||||
$and = [
|
||||
$query->equals($field, $value),
|
||||
$query->equals('deleted', 0)
|
||||
];
|
||||
if ($user !== null && method_exists($user, 'getUid')) {
|
||||
$and[] = $query->logicalNot($query->equals('uid', (int)$user->getUid()));
|
||||
}
|
||||
$constraint = $query->logicalAnd($and);
|
||||
|
||||
$query->matching($constraint);
|
||||
|
||||
/** @var User $user */
|
||||
$user = $query->execute()->getFirst();
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find All for Backend Actions
|
||||
*
|
||||
* @param array $filter Filter Array
|
||||
* @return QueryResultInterface|array
|
||||
*/
|
||||
public function findAllInBackend(array $filter)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$this->ignoreEnableFieldsAndStoragePage($query);
|
||||
$and = [$query->greaterThan('uid', 0)];
|
||||
$and = $this->filterByPage($and, $query);
|
||||
$and = $this->filterBySearchword($filter, $query, $and);
|
||||
$query->matching($query->logicalAnd($and));
|
||||
$query->setOrderings(['username' => QueryInterface::ORDER_ASCENDING]);
|
||||
$records = $query->execute();
|
||||
|
||||
return $records;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find All for Backend Actions
|
||||
*
|
||||
* @param array $filter Filter Array
|
||||
* @param bool $userConfirmation Show only fe_users which are confirmed by the user?
|
||||
* @return QueryResultInterface|array
|
||||
*/
|
||||
public function findAllInBackendForConfirmation(array $filter, bool $userConfirmation = false)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$this->ignoreEnableFieldsAndStoragePage($query);
|
||||
$and = [$query->equals('disable', true)];
|
||||
$and = $this->filterByPage($and, $query);
|
||||
$and = $this->filterBySearchword($filter, $query, $and);
|
||||
$and = $this->filterByUserConfirmation($and, $query, $userConfirmation);
|
||||
$query->matching($query->logicalAnd($and));
|
||||
$query->setOrderings(['username' => QueryInterface::ORDER_ASCENDING]);
|
||||
$records = $query->execute();
|
||||
|
||||
return $records;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all users from current page or from any subpage
|
||||
* If no page id given or if on rootpage (pid 0):
|
||||
* - Don't show any users for editors
|
||||
* - Show all users for admins
|
||||
*
|
||||
* @param array $and
|
||||
* @param QueryInterface $query
|
||||
* @return array
|
||||
*/
|
||||
protected function filterByPage(array $and, QueryInterface $query): array
|
||||
{
|
||||
if (BackendUtility::getPageIdentifier() > 0) {
|
||||
$and[] = $query->in('pid', $this->getTreeList(BackendUtility::getPageIdentifier()));
|
||||
} else {
|
||||
if (!BackendUserUtility::isAdminAuthentication()) {
|
||||
$and[] = $query->equals('uid', 0);
|
||||
}
|
||||
}
|
||||
|
||||
return $and;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $filter
|
||||
* @param QueryInterface $query
|
||||
* @param array $and
|
||||
* @return array
|
||||
*/
|
||||
protected function filterBySearchword(array $filter, QueryInterface $query, array $and): array
|
||||
{
|
||||
if (!empty($filter['searchword'])) {
|
||||
$searchwords = GeneralUtility::trimExplode(' ', $filter['searchword'], true);
|
||||
foreach ($searchwords as $searchword) {
|
||||
$or = [];
|
||||
$or[] = $query->like('address', '%' . $searchword . '%');
|
||||
$or[] = $query->like('city', '%' . $searchword . '%');
|
||||
$or[] = $query->like('company', '%' . $searchword . '%');
|
||||
$or[] = $query->like('country', '%' . $searchword . '%');
|
||||
$or[] = $query->like('email', '%' . $searchword . '%');
|
||||
$or[] = $query->like('fax', '%' . $searchword . '%');
|
||||
$or[] = $query->like('first_name', '%' . $searchword . '%');
|
||||
$or[] = $query->like('image', '%' . $searchword . '%');
|
||||
$or[] = $query->like('last_name', '%' . $searchword . '%');
|
||||
$or[] = $query->like('middle_name', '%' . $searchword . '%');
|
||||
$or[] = $query->like('name', '%' . $searchword . '%');
|
||||
$or[] = $query->like('telephone', '%' . $searchword . '%');
|
||||
$or[] = $query->like('title', '%' . $searchword . '%');
|
||||
$or[] = $query->like('usergroup.title', '%' . $searchword . '%');
|
||||
$or[] = $query->like('username', '%' . $searchword . '%');
|
||||
$or[] = $query->like('www', '%' . $searchword . '%');
|
||||
$or[] = $query->like('zip', '%' . $searchword . '%');
|
||||
$and[] = $query->logicalOr($or);
|
||||
}
|
||||
}
|
||||
|
||||
return $and;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $and
|
||||
* @param QueryInterface $query
|
||||
* @param bool $userConfirmation
|
||||
* @return array
|
||||
*/
|
||||
protected function filterByUserConfirmation(array $and, QueryInterface $query, bool $userConfirmation): array
|
||||
{
|
||||
$and[] = $query->equals('txFemanagerConfirmedbyuser', $userConfirmation);
|
||||
|
||||
return $and;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all children pids of a start pid
|
||||
*
|
||||
* @param int $pageIdentifier
|
||||
* @return array
|
||||
*/
|
||||
protected function getTreeList($pageIdentifier)
|
||||
{
|
||||
$queryGenerator = $this->objectManager->get(QueryGenerator::class);
|
||||
$treeList = $queryGenerator->getTreeList($pageIdentifier, 99, 0, '1');
|
||||
|
||||
return GeneralUtility::trimExplode(',', $treeList, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param QueryInterface $query
|
||||
*/
|
||||
protected function ignoreEnableFieldsAndStoragePage(QueryInterface $query)
|
||||
{
|
||||
$query->getQuerySettings()->setRespectStoragePage(false);
|
||||
$query->getQuerySettings()->setIgnoreEnableFields(true);
|
||||
$query->getQuerySettings()->setEnableFieldsToBeIgnored(['disabled']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param QueryInterface $query
|
||||
*/
|
||||
protected function ignoreEnableFieldsAndStoragePageAndStarttime(QueryInterface $query)
|
||||
{
|
||||
$this->ignoreEnableFieldsAndStoragePage($query);
|
||||
$query->getQuerySettings()->setEnableFieldsToBeIgnored(['disabled', 'starttime']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find All
|
||||
*
|
||||
* @param string $mail
|
||||
* @return QueryResultInterface|array
|
||||
*/
|
||||
public function findFirstByEmail(string $mail)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$this->ignoreEnableFieldsAndStoragePage($query);
|
||||
$and = [
|
||||
$query->equals('txFemanagerConfirmedbyuser', false),
|
||||
$query->equals('email', $mail)
|
||||
];
|
||||
$query->matching($query->logicalAnd($and));
|
||||
|
||||
$query->setOrderings(['uid' => QueryInterface::ORDER_DESCENDING]);
|
||||
|
||||
return $query->execute()->getFirst();
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Service\AutoAdminConfirmation;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class AbstractConfirmation
|
||||
*/
|
||||
abstract class AbstractConfirmation implements ConfirmationInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config = [];
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* AbstractConfirmation constructor.
|
||||
*
|
||||
* @param array $config
|
||||
* @param User $user
|
||||
* @param array $settings
|
||||
* @param ContentObjectRenderer $contentObject
|
||||
*/
|
||||
public function __construct(array $config, User $user, array $settings, ContentObjectRenderer $contentObject)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->user = $user;
|
||||
$this->settings = $settings;
|
||||
$this->contentObject = $contentObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip manual confirmation from admin?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutoConfirmed(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getConfig(): array
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User
|
||||
*/
|
||||
public function getUser(): User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSettings(): array
|
||||
{
|
||||
return $this->settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ContentObjectRenderer
|
||||
*/
|
||||
public function getContentObject(): ContentObjectRenderer
|
||||
{
|
||||
return $this->contentObject;
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Service\AutoAdminConfirmation;
|
||||
|
||||
/**
|
||||
* Interface ConfirmationInterface
|
||||
*/
|
||||
interface ConfirmationInterface
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutoConfirmed(): bool;
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Service\AutoAdminConfirmation;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class EmailDomainConfirmation
|
||||
*/
|
||||
class EmailDomainConfirmation extends AbstractConfirmation
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutoConfirmed(): bool
|
||||
{
|
||||
if (!$this->isException() && $this->isGivenDomainsPartOfEmail()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function isGivenDomainsPartOfEmail(): bool
|
||||
{
|
||||
$domains = GeneralUtility::trimExplode(',', $this->getConfig()['confirmByEmailDomains'], true);
|
||||
foreach ($domains as $domain) {
|
||||
if (stristr($this->getEmailDomain(), $domain)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function isException(): bool
|
||||
{
|
||||
$exceptionDomains =
|
||||
GeneralUtility::trimExplode(',', $this->getConfig()['confirmByEmailDomainsExceptions'], true);
|
||||
return in_array($this->getEmailDomain(), $exceptionDomains);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get domain of an email address: "alex@in2code.de" => "in2code.de"
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getEmailDomain(): string
|
||||
{
|
||||
$email = $this->getUser()->getEmail();
|
||||
$parts = explode('@', $email);
|
||||
return $parts[1];
|
||||
}
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Service;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Service\AutoAdminConfirmation\ConfirmationInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class AutoAdminConfirmationService
|
||||
*/
|
||||
class AutoAdminConfirmationService
|
||||
{
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $confirmInterface = ConfirmationInterface::class;
|
||||
|
||||
/**
|
||||
* AutoAdminConfirmationService constructor.
|
||||
*
|
||||
* @param User $user
|
||||
* @param array $settings
|
||||
* @param ContentObjectRenderer $contentObject
|
||||
*/
|
||||
public function __construct(User $user, array $settings, ContentObjectRenderer $contentObject)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->settings = $settings;
|
||||
$this->contentObject = $contentObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through all AutoAdminConfirmation classes
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutoAdminConfirmationFullfilled(): bool
|
||||
{
|
||||
$autoConfirmation = false;
|
||||
foreach ($this->getConfirmationClasses() as $classConfiguration) {
|
||||
/** @var ConfirmationInterface $confirmation */
|
||||
$confirmation = GeneralUtility::makeInstance(
|
||||
$classConfiguration['class'],
|
||||
$classConfiguration['config'],
|
||||
$this->user,
|
||||
$this->settings,
|
||||
$this->contentObject
|
||||
);
|
||||
if ($confirmation->isAutoConfirmed() === true) {
|
||||
$autoConfirmation = true;
|
||||
}
|
||||
}
|
||||
return $autoConfirmation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getConfirmationClasses(): array
|
||||
{
|
||||
$classes = [];
|
||||
if (!empty($this->settings['autoAdminConfirmation'])) {
|
||||
foreach ($this->settings['autoAdminConfirmation'] as $configuration) {
|
||||
$className = $configuration['class'];
|
||||
if (!class_exists($className)) {
|
||||
throw new \UnexpectedValueException(
|
||||
'Class ' . $className . ' does not exists - check if file was loaded with autoloader',
|
||||
1516373867533
|
||||
);
|
||||
}
|
||||
if (!is_subclass_of($className, $this->confirmInterface)) {
|
||||
throw new \UnexpectedValueException(
|
||||
'Class ' . $className . ' does not implement interface ' . $this->confirmInterface,
|
||||
1516373878882
|
||||
);
|
||||
}
|
||||
$classes[] = $configuration;
|
||||
}
|
||||
}
|
||||
return $classes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Service;
|
||||
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use TYPO3\CMS\Core\Resource\ResourceFactory;
|
||||
use TYPO3\CMS\Core\Resource\Security\FileNameValidator;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
|
||||
/**
|
||||
* Class FileService
|
||||
*/
|
||||
class FileService
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fileName = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fileArray = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fallbackExtensions = 'jpg,jpeg,png,gif,bmp,tif,tiff';
|
||||
|
||||
/**
|
||||
* FileService constructor.
|
||||
*
|
||||
* @param string $filename Filename like (upload.png)
|
||||
* @param array $fileArray From PHP with tmp_name, etc...
|
||||
*/
|
||||
public function __construct(string $filename, array $fileArray)
|
||||
{
|
||||
$this->fileName = $filename;
|
||||
$this->fileArray = $fileArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @todo add filesize check
|
||||
*/
|
||||
public function isEverythingValid(): bool
|
||||
{
|
||||
return $this->validFileExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check extension of given filename
|
||||
*
|
||||
* @return bool If Extension is allowed
|
||||
*/
|
||||
protected function validFileExtension(): bool
|
||||
{
|
||||
$extensionList = ConfigurationUtility::getConfiguration('misc.uploadFileExtension');
|
||||
if (!empty($extensionList)) {
|
||||
$extensionList = str_replace(' ', '', $extensionList);
|
||||
} else {
|
||||
$extensionList = $this->fallbackExtensions;
|
||||
}
|
||||
$fileInfo = pathinfo($this->fileName);
|
||||
|
||||
return !empty($fileInfo['extension']) &&
|
||||
GeneralUtility::inList($extensionList, strtolower($fileInfo['extension'])) &&
|
||||
GeneralUtility::makeInstance(FileNameValidator::class)->isValid($this->fileName) &&
|
||||
GeneralUtility::validPathStr($this->fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create sys_file entry for given filename and return uid
|
||||
*
|
||||
* @param string $file absolute path and filename
|
||||
* @return int
|
||||
*/
|
||||
public function indexFile(string $file): int
|
||||
{
|
||||
$fileIdentifier = 0;
|
||||
if (file_exists($file)) {
|
||||
$resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
|
||||
$file = $resourceFactory->getFileObjectFromCombinedIdentifier($this->getCombinedIdentifier($file));
|
||||
$fileIdentifier = (int)$file->getProperty('uid');
|
||||
}
|
||||
return $fileIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* build combined identifier from absolute filename:
|
||||
* "/var/www/fileadmin/folder/test.pdf" => "1:folder/test.pdf"
|
||||
*
|
||||
* @param string $file relative path and filename
|
||||
* @return string
|
||||
*/
|
||||
protected function getCombinedIdentifier(string $file): string
|
||||
{
|
||||
// @Todo Make it a bit less ugly
|
||||
$file = PathUtility::getRelativePathTo($file);
|
||||
$identifier = $this->substituteFileadminFromPathAndName($file);
|
||||
return '1:' . $identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* "fileadmin/downloads/test.pdf" => "/downloads/test.pdf"
|
||||
*
|
||||
* @param string $pathAndName
|
||||
* @return string
|
||||
*/
|
||||
protected function substituteFileadminFromPathAndName(string $pathAndName): string
|
||||
{
|
||||
$substituteString = 'fileadmin/';
|
||||
if (substr($pathAndName, 0, strlen($substituteString)) === $substituteString) {
|
||||
$pathAndName = str_replace($substituteString, '', $pathAndName);
|
||||
}
|
||||
if (substr($pathAndName, 0, 1) !== '/') {
|
||||
$pathAndName = '/' . $pathAndName;
|
||||
}
|
||||
return $pathAndName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Service;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Finisher\AbstractFinisher;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class FinisherService
|
||||
*/
|
||||
class FinisherService
|
||||
{
|
||||
/**
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* Classname
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $class = '';
|
||||
|
||||
/**
|
||||
* Path that should be required
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $requirePath;
|
||||
|
||||
/**
|
||||
* Finisher Configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration = [];
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Controller actionName - usually "createAction" or "confirmationAction"
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
protected $actionMethodName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $finisherInterface = 'In2code\Femanager\Finisher\FinisherInterface';
|
||||
|
||||
/**
|
||||
* @var ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
public function injectObjectManager(ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClass()
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @return FinisherService
|
||||
*/
|
||||
public function setClass($class)
|
||||
{
|
||||
$this->class = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRequirePath()
|
||||
{
|
||||
return $this->requirePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set require path and do a require_once
|
||||
*
|
||||
* @param string|null $requirePath
|
||||
* @return FinisherService
|
||||
*/
|
||||
public function setRequirePath($requirePath)
|
||||
{
|
||||
$this->requirePath = $requirePath;
|
||||
if ($this->getRequirePath() && file_exists($this->getRequirePath())) {
|
||||
require_once($this->getRequirePath());
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getConfiguration()
|
||||
{
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $configuration
|
||||
* @return FinisherService
|
||||
*/
|
||||
public function setConfiguration($configuration)
|
||||
{
|
||||
$this->configuration = $configuration;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return FinisherService
|
||||
*/
|
||||
public function setUser($user)
|
||||
{
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSettings()
|
||||
{
|
||||
return $this->settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
* @return FinisherService
|
||||
*/
|
||||
public function setSettings($settings)
|
||||
{
|
||||
$this->settings = $settings;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getActionMethodName()
|
||||
{
|
||||
return $this->actionMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $actionMethodName
|
||||
* @return FinisherService
|
||||
*/
|
||||
public function setActionMethodName($actionMethodName)
|
||||
{
|
||||
$this->actionMethodName = $actionMethodName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start implementation
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
if (!class_exists($this->getClass())) {
|
||||
throw new \UnexpectedValueException(
|
||||
'Class ' . $this->getClass() . ' does not exists - check if file was loaded with autoloader',
|
||||
1516373888508
|
||||
);
|
||||
}
|
||||
if (is_subclass_of($this->getClass(), $this->finisherInterface)) {
|
||||
/** @var AbstractFinisher $finisher */
|
||||
$finisher = $this->objectManager->get(
|
||||
$this->getClass(),
|
||||
$this->getUser(),
|
||||
$this->getConfiguration(),
|
||||
$this->getSettings(),
|
||||
$this->getActionMethodName(),
|
||||
$this->contentObject
|
||||
);
|
||||
$finisher->initializeFinisher();
|
||||
$this->callFinisherMethods($finisher);
|
||||
} else {
|
||||
throw new \UnexpectedValueException(
|
||||
'Finisher does not implement ' . $this->finisherInterface,
|
||||
1516373899775
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call methods in finisher class
|
||||
*
|
||||
* @param AbstractFinisher $finisher
|
||||
*/
|
||||
protected function callFinisherMethods(AbstractFinisher $finisher)
|
||||
{
|
||||
foreach (get_class_methods($finisher) as $method) {
|
||||
if (!StringUtility::endsWith($method, 'Finisher') || strpos($method, 'initialize') === 0) {
|
||||
continue;
|
||||
}
|
||||
$this->callInitializeFinisherMethod($finisher, $method);
|
||||
$finisher->{$method}();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call initializeFinisherMethods like "initializeSaveFinisher()"
|
||||
*
|
||||
* @param AbstractFinisher $finisher
|
||||
* @param string $finisherMethod
|
||||
*/
|
||||
protected function callInitializeFinisherMethod(AbstractFinisher $finisher, $finisherMethod)
|
||||
{
|
||||
if (method_exists($finisher, 'initialize' . ucfirst($finisherMethod))) {
|
||||
$finisher->{'initialize' . ucfirst($finisherMethod)}();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param array $settings
|
||||
* @param ContentObjectRenderer $contentObject
|
||||
*/
|
||||
public function __construct(User $user, array $settings, ContentObjectRenderer $contentObject)
|
||||
{
|
||||
$this->setUser($user);
|
||||
$this->setSettings($settings);
|
||||
$this->contentObject = $contentObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Domain\Service;
|
||||
|
||||
use TYPO3\CMS\Core\Cache\CacheManager;
|
||||
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Crypto\Random;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
class RatelimiterService implements SingletonInterface
|
||||
{
|
||||
const CACHE_IDENTIFIER = 'femanager_ratelimiter';
|
||||
const DEFAULT_CONFIG = ['timeframe' => 60, 'limit' => 3];
|
||||
const LIMIT_IP = 'limit_ip_';
|
||||
const SESSION_KEY = 'tx_femanager_ratelimiter';
|
||||
|
||||
/** @var FrontendInterface */
|
||||
protected $cache;
|
||||
|
||||
/** @var int */
|
||||
protected $limit;
|
||||
|
||||
/** @var int */
|
||||
protected $timeframe;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->cache = GeneralUtility::makeInstance(CacheManager::class)->getCache(self::CACHE_IDENTIFIER);
|
||||
$setup = $this->getTSFE()->tmpl->setup;
|
||||
$config = $setup['plugin.']['tx_femanager.']['settings.']['ratelimiter.'] ?? self::DEFAULT_CONFIG;
|
||||
$this->timeframe = (int)$config['timeframe'];
|
||||
$this->limit = (int)$config['limit'];
|
||||
}
|
||||
|
||||
protected function getTSFE(): TypoScriptFrontendController
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
|
||||
public function isLimited(): bool
|
||||
{
|
||||
if ($this->limit > 0) {
|
||||
$userIp = GeneralUtility::getIndpEnv('REMOTE_ADDR');
|
||||
$userIpAccess = $this->getToken(self::LIMIT_IP, $userIp);
|
||||
|
||||
return count($userIpAccess) >= $this->limit;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function consumeSlot()
|
||||
{
|
||||
if ($this->limit > 0) {
|
||||
$userIp = GeneralUtility::getIndpEnv('REMOTE_ADDR');
|
||||
$this->consumeToken(self::LIMIT_IP, $userIp);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getCookie()
|
||||
{
|
||||
$this->touchCookie();
|
||||
|
||||
return $this->getTSFE()->fe_user->getSessionData(self::SESSION_KEY);
|
||||
}
|
||||
|
||||
public function touchCookie()
|
||||
{
|
||||
$feUser = $this->getTSFE()->fe_user;
|
||||
$identifier = $feUser->getSessionData(self::SESSION_KEY);
|
||||
|
||||
if (null === $identifier) {
|
||||
$unique = GeneralUtility::makeInstance(Random::class)->generateRandomHexString(16);
|
||||
$feUser->setAndSaveSessionData(self::SESSION_KEY, $unique);
|
||||
}
|
||||
}
|
||||
|
||||
protected function consumeToken(string $tokenName, string $value): array
|
||||
{
|
||||
$cacheID = $this->getCacheID($tokenName, $value);
|
||||
|
||||
$token = $this->retrieveToken($cacheID);
|
||||
$token[] = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('date', 'timestamp');
|
||||
$this->cache->set($cacheID, $token, [], $this->timeframe);
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
protected function getCacheID(string $tokenName, string $value): string
|
||||
{
|
||||
return $tokenName . hash('sha1', $value);
|
||||
}
|
||||
|
||||
protected function retrieveToken(string $cacheID): array
|
||||
{
|
||||
$token = [];
|
||||
if ($this->cache->has($cacheID)) {
|
||||
$token = $this->cache->get($cacheID);
|
||||
$token = $this->filterExpiredToken($token);
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
protected function filterExpiredToken(array $token): array
|
||||
{
|
||||
$slidingWindowStartTime = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('date', 'timestamp') - $this->timeframe;
|
||||
foreach ($token as $idx => $accessTime) {
|
||||
if ($accessTime < $slidingWindowStartTime) {
|
||||
unset($token[$idx]);
|
||||
}
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
protected function getToken(string $tokenName, string $value): array
|
||||
{
|
||||
$cacheID = $this->getCacheID($tokenName, $value);
|
||||
|
||||
return $this->retrieveToken($cacheID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Domain\Service;
|
||||
|
||||
use In2code\Femanager\Event\AfterMailSendEvent;
|
||||
use In2code\Femanager\Event\BeforeMailBodyRenderEvent;
|
||||
use In2code\Femanager\Event\BeforeMailSendEvent;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\ObjectUtility;
|
||||
use In2code\Femanager\Utility\TemplateUtility;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Mime\Part\DataPart;
|
||||
use TYPO3\CMS\Core\Mail\Mailer;
|
||||
use TYPO3\CMS\Core\Mail\MailMessage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class SendMailService
|
||||
*/
|
||||
class SendMailService
|
||||
{
|
||||
/**
|
||||
* Content Object
|
||||
*
|
||||
* @var object|null
|
||||
*/
|
||||
public ?object $contentObject = null;
|
||||
|
||||
/**
|
||||
* @var Mailer|null
|
||||
*/
|
||||
private ?Mailer $mailer = null;
|
||||
/**
|
||||
* @var EventDispatcherInterface|null
|
||||
*/
|
||||
private ?EventDispatcherInterface $dispatcher = null;
|
||||
|
||||
/**
|
||||
* SendMailService constructor.
|
||||
*/
|
||||
public function __construct(Mailer $mailer, EventDispatcherInterface $dispatcher)
|
||||
{
|
||||
$this->contentObject = ObjectUtility::getContentObject();
|
||||
$this->mailer = $mailer;
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $variables
|
||||
*/
|
||||
protected function contentObjectStart(array $variables): void
|
||||
{
|
||||
if (
|
||||
empty($variables['user'] ?? []) === false &&
|
||||
method_exists(($variables['user'] ?? null), '_getProperties') === true
|
||||
) {
|
||||
$this->contentObject->start($variables['user']->_getProperties());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and send Email
|
||||
*
|
||||
* @param string $template Template file in Templates/Email/
|
||||
* @param array $receiver Combination of Email => Name
|
||||
* @param array $sender Combination of Email => Name
|
||||
* @param string $subject Mail subject
|
||||
* @param array $variables Variables for assignMultiple
|
||||
* @param array $typoScript Add TypoScript to overwrite values
|
||||
* @return bool mail was sent?
|
||||
*/
|
||||
public function send(
|
||||
string $template,
|
||||
array $receiver,
|
||||
array $sender,
|
||||
string $subject,
|
||||
array $variables = [],
|
||||
array $typoScript = []
|
||||
): bool {
|
||||
if (false === $this->isMailEnabled($typoScript, $receiver)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->contentObjectStart($variables);
|
||||
$email = GeneralUtility::makeInstance(MailMessage::class);
|
||||
$variables = $this->embedImages($variables, $typoScript, $email);
|
||||
$this->prepareMailObject($template, $receiver, $sender, $subject, $variables, $email);
|
||||
$this->overwriteEmailReceiver($typoScript, $email);
|
||||
$this->overwriteEmailSender($typoScript, $email);
|
||||
$this->setSubject($typoScript, $email);
|
||||
$this->setCc($typoScript, $email);
|
||||
$this->setPriority($typoScript, $email);
|
||||
$this->setAttachments($typoScript, $email);
|
||||
|
||||
$this->dispatcher->dispatch(new BeforeMailSendEvent($email, $variables, $this));
|
||||
$email->send();
|
||||
$this->dispatcher->dispatch(new AfterMailSendEvent($email, $variables, $this));
|
||||
|
||||
return $email->isSent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Email Body
|
||||
*
|
||||
* @param string $template Template file in Templates/Email/
|
||||
* @param array $variables Variables for assignMultiple
|
||||
* @return string
|
||||
*/
|
||||
protected function getMailBody(string $template, array $variables): string
|
||||
{
|
||||
$standAloneView = TemplateUtility::getDefaultStandAloneView();
|
||||
$standAloneView->setTemplatePathAndFilename($this->getRelativeEmailPathAndFilename($template));
|
||||
$standAloneView->assignMultiple($variables);
|
||||
$this->dispatcher->dispatch(new BeforeMailBodyRenderEvent($standAloneView, $variables, $this));
|
||||
return $standAloneView->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $variables
|
||||
* @param array $typoScript
|
||||
* @param MailMessage $email
|
||||
* @return array
|
||||
*/
|
||||
protected function embedImages(array $variables, array $typoScript, MailMessage $email): array
|
||||
{
|
||||
$images = $this->contentObject->cObjGetSingle(
|
||||
$typoScript['embedImage'] ?? 'TEXT',
|
||||
$typoScript['embedImage.'] ?? []
|
||||
);
|
||||
|
||||
if (!$images) {
|
||||
return $variables;
|
||||
}
|
||||
|
||||
$images = GeneralUtility::trimExplode(',', $images, true);
|
||||
$imageVariables = [];
|
||||
|
||||
foreach ($images as $path) {
|
||||
$name = basename($path);
|
||||
$imagePart = DataPart::fromPath($path);
|
||||
$contentType = $imagePart->getMediaType() . '/' . $imagePart->getMediaSubtype();
|
||||
$email->embedFromPath($path, $name, $contentType);
|
||||
$imageVariables[] = 'cid:' . $name;
|
||||
}
|
||||
|
||||
return array_merge($variables, ['embedImages' => $imageVariables]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $template
|
||||
* @param array $receiver
|
||||
* @param array $sender
|
||||
* @param string $subject
|
||||
* @param array $variables
|
||||
* @param MailMessage $email
|
||||
*/
|
||||
protected function prepareMailObject(
|
||||
string $template,
|
||||
array $receiver,
|
||||
array $sender,
|
||||
string $subject,
|
||||
array $variables,
|
||||
MailMessage $email
|
||||
): void {
|
||||
$html = $this->getMailBody($template, $variables);
|
||||
$email->setTo($receiver)
|
||||
->setFrom($sender)
|
||||
->setSubject($subject)
|
||||
->html($html);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $typoScript
|
||||
* @param MailMessage $email
|
||||
*/
|
||||
protected function overwriteEmailReceiver(array $typoScript, MailMessage $email): void
|
||||
{
|
||||
$emailAddress = $this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('receiver./email', $typoScript),
|
||||
(array)ConfigurationUtility::getValue('receiver./email.', $typoScript)
|
||||
);
|
||||
$name = $this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('receiver./name', $typoScript),
|
||||
(array)ConfigurationUtility::getValue('receiver./name.', $typoScript)
|
||||
);
|
||||
if ($emailAddress && $name) {
|
||||
$email->setTo([$emailAddress => $name]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $typoScript
|
||||
* @param MailMessage $email
|
||||
*/
|
||||
protected function overwriteEmailSender(array $typoScript, MailMessage $email): void
|
||||
{
|
||||
$emailAddress = $this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('sender./email', $typoScript),
|
||||
(array)ConfigurationUtility::getValue('sender./email.', $typoScript)
|
||||
);
|
||||
$name = $this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('sender./name', $typoScript),
|
||||
(array)ConfigurationUtility::getValue('sender./name.', $typoScript)
|
||||
);
|
||||
|
||||
if ($emailAddress && $name) {
|
||||
$email->setFrom([$emailAddress => $name]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $typoScript
|
||||
* @param MailMessage $email
|
||||
*/
|
||||
protected function setSubject(array $typoScript, MailMessage $email): void
|
||||
{
|
||||
if ($this->contentObject->cObjGetSingle((string)$typoScript['subject'], (array)$typoScript['subject.'])) {
|
||||
$email->setSubject($this->contentObject->cObjGetSingle((string)$typoScript['subject'], (array)$typoScript['subject.']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $typoScript
|
||||
* @param MailMessage $email
|
||||
*/
|
||||
protected function setCc(array $typoScript, MailMessage $email): void
|
||||
{
|
||||
if ($this->contentObject->cObjGetSingle((string)$typoScript['cc'], (array)$typoScript['cc.'])) {
|
||||
$email->setCc($this->contentObject->cObjGetSingle((string)$typoScript['cc'], (array)$typoScript['cc.']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $typoScript
|
||||
* @param MailMessage $email
|
||||
*/
|
||||
protected function setPriority(array $typoScript, MailMessage $email): void
|
||||
{
|
||||
$priority = (int)$this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('priority', $typoScript),
|
||||
(array)ConfigurationUtility::getValue('priority.', $typoScript)
|
||||
);
|
||||
if ($priority) {
|
||||
$email->priority($priority);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $typoScript
|
||||
* @param MailMessage $email
|
||||
*/
|
||||
protected function setAttachments(array $typoScript, MailMessage $email): void
|
||||
{
|
||||
if ($this->contentObject->cObjGetSingle($typoScript['attachments'] ?? '', $typoScript['attachments.'] ?? [])) {
|
||||
$files = GeneralUtility::trimExplode(
|
||||
',',
|
||||
$this->contentObject->cObjGetSingle(
|
||||
$typoScript['attachments'] ?? '',
|
||||
$typoScript['attachments.'] ?? []
|
||||
),
|
||||
true
|
||||
);
|
||||
foreach ($files as $file) {
|
||||
$email->attachFromPath($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path and filename for mail template
|
||||
*
|
||||
* @param string $fileName
|
||||
* @return string
|
||||
*/
|
||||
protected function getRelativeEmailPathAndFilename(string $fileName): string
|
||||
{
|
||||
return TemplateUtility::getTemplatePath('Email/' . ucfirst($fileName) . '.html');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $typoScript
|
||||
* @param array $receiver
|
||||
* @return bool
|
||||
*/
|
||||
protected function isMailEnabled(array $typoScript, array $receiver): bool
|
||||
{
|
||||
$cObjectName = (string)ConfigurationUtility::getValue('_enable', $typoScript);
|
||||
$cObjectConf = (array)ConfigurationUtility::getValue('_enable.', $typoScript);
|
||||
|
||||
return $this->contentObject->cObjGetSingle($cObjectName, $cObjectConf) && count($receiver) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Domain\Service;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use TYPO3\CMS\Core\Log\LogLevel;
|
||||
use TYPO3\CMS\Core\Log\LogManager;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class SendParametersService
|
||||
*/
|
||||
class SendParametersService
|
||||
{
|
||||
/**
|
||||
* @var ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $properties = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($configuration)
|
||||
{
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function injectConfigurationManagerInterface(ConfigurationManagerInterface $configurationManager)
|
||||
{
|
||||
$this->configurationManager = $configurationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* SendPost - Send values via curl to target
|
||||
*
|
||||
* @param User $user User properties
|
||||
*/
|
||||
public function send(User $user)
|
||||
{
|
||||
$this->initialize($user);
|
||||
$this->contentObject->start($this->properties);
|
||||
if ($this->isTurnedOn()) {
|
||||
$curlObject = curl_init();
|
||||
curl_setopt($curlObject, CURLOPT_URL, $this->getUri());
|
||||
curl_setopt($curlObject, CURLOPT_POST, 1);
|
||||
curl_setopt($curlObject, CURLOPT_POSTFIELDS, $this->getData());
|
||||
curl_setopt($curlObject, CURLOPT_RETURNTRANSFER, true);
|
||||
if ($GLOBALS['FE']['debug'] === 1) {
|
||||
curl_setopt($curlObject, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($curlObject, CURLOPT_SSL_VERIFYPEER, false);
|
||||
}
|
||||
curl_exec($curlObject);
|
||||
curl_close($curlObject);
|
||||
$this->log();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URI for curl request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getUri()
|
||||
{
|
||||
return $this->configuration['targetUrl'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data array
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getData()
|
||||
{
|
||||
return $this->contentObject->cObjGetSingle((string)$this->configuration['data'], (array)$this->configuration['data.']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to devlog
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function log()
|
||||
{
|
||||
if (!empty($this->configuration['debug'])) {
|
||||
GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__)->log(LogLevel::INFO, 'femanager sendpost values', [
|
||||
'url' => $this->getUri(),
|
||||
'data' => $this->getData(),
|
||||
'properties' => $this->properties
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function isTurnedOn()
|
||||
{
|
||||
return $this->contentObject->cObjGetSingle((string)$this->configuration['_enable'], (array)$this->configuration['_enable.'])
|
||||
=== '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
protected function initialize(User $user)
|
||||
{
|
||||
$this->properties = $user->_getCleanProperties();
|
||||
$this->contentObject = $this->configurationManager->getContentObject();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Service;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class StoreInDatabaseService
|
||||
*/
|
||||
class StoreInDatabaseService
|
||||
{
|
||||
/**
|
||||
* Database Table to store
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = '';
|
||||
|
||||
/**
|
||||
* Array with fieldname=>value
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $properties = [];
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\CORE\Database\ConnectionPool
|
||||
*/
|
||||
protected $databaseConnection;
|
||||
|
||||
/**
|
||||
* Executes the storage
|
||||
*
|
||||
* @return int uid of inserted record
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$insertTable = $this->databaseConnection->getConnectionForTable($this->getTable());
|
||||
$insertTable->insert(
|
||||
$this->getTable(),
|
||||
$this->getProperties()
|
||||
);
|
||||
|
||||
return (int)$insertTable->lastInsertId($this->getTable());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set TableName
|
||||
*
|
||||
* @param string $table
|
||||
*/
|
||||
public function setTable($table)
|
||||
{
|
||||
$table = preg_replace('/[^a-zA-Z0-9_-]/', '', $table);
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TableName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read properties
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProperties()
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add property/value pair to array
|
||||
*
|
||||
* @param $propertyName
|
||||
* @param $value
|
||||
*/
|
||||
public function addProperty($propertyName, $value)
|
||||
{
|
||||
$propertyName = preg_replace('/[^a-zA-Z0-9_-]/', '', $propertyName);
|
||||
$this->properties[$propertyName] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove property/value pair form array by its key
|
||||
*
|
||||
* @param $propertyName
|
||||
*/
|
||||
public function removeProperty($propertyName)
|
||||
{
|
||||
unset($this->properties[$propertyName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->databaseConnection = GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Service;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
|
||||
/**
|
||||
* Class ValidationSettingsService
|
||||
*/
|
||||
class ValidationSettingsService
|
||||
{
|
||||
/**
|
||||
* Needed for validation settings. Should be "new", "edit" or "invitation"
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $controllerName = '';
|
||||
|
||||
/**
|
||||
* Needed for validation settings. Should be "validation" or "validationEdit"
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $validationName = '';
|
||||
|
||||
/**
|
||||
* Validation names with simple configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $simpleValidations = [
|
||||
'date',
|
||||
'email',
|
||||
'intOnly',
|
||||
'lettersOnly',
|
||||
'unicodeLettersOnly',
|
||||
'required',
|
||||
'uniqueInDb',
|
||||
'uniqueInPage'
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $controllerName
|
||||
* @param string $validationName
|
||||
*/
|
||||
public function __construct(string $controllerName, string $validationName)
|
||||
{
|
||||
$this->controllerName = $controllerName;
|
||||
$this->validationName = $validationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get validation string like
|
||||
* required, email, min(10), max(10), intOnly,
|
||||
* lettersOnly, unicodeLettersOnly, uniqueInPage, uniqueInDb, date,
|
||||
* mustInclude(number|letter|special), inList(1|2|3)
|
||||
*
|
||||
* @param string $fieldName Fieldname
|
||||
* @return string
|
||||
*/
|
||||
public function getValidationStringForField(string $fieldName): string
|
||||
{
|
||||
$string = '';
|
||||
$validationSettings = $this->getSettings()[$this->controllerName][$this->validationName][$fieldName] ?? [];
|
||||
|
||||
if (is_array($validationSettings)) {
|
||||
foreach ($validationSettings as $validation => $configuration) {
|
||||
if ($string !== '') {
|
||||
$string .= ',';
|
||||
}
|
||||
$string .= $this->getSingleValidationString($validation, $configuration);
|
||||
}
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidationEnabled(string $type = 'client'): bool
|
||||
{
|
||||
$validationSetting = $this->getSettings()[$this->controllerName]['validation']['_enable'][$type] ?? '0';
|
||||
return $validationSetting === '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $validation
|
||||
* @param string $configuration
|
||||
* @return string
|
||||
*/
|
||||
protected function getSingleValidationString($validation, $configuration)
|
||||
{
|
||||
$string = '';
|
||||
if ($this->isSimpleValidation($validation) && $configuration === '1') {
|
||||
$string = $validation;
|
||||
}
|
||||
if (!$this->isSimpleValidation($validation)) {
|
||||
$string = $validation;
|
||||
$string .= '(' . str_replace(',', '|', $configuration) . ')';
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if validation is simple or extended
|
||||
*
|
||||
* @param string $validation
|
||||
* @return bool
|
||||
*/
|
||||
protected function isSimpleValidation($validation): bool
|
||||
{
|
||||
if (in_array($validation, $this->simpleValidations)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getSettings(): array
|
||||
{
|
||||
$configurationManager = GeneralUtility::makeInstance(ConfigurationManagerInterface::class);
|
||||
return (array)$configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
|
||||
'femanager',
|
||||
'femanager_pi1'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,490 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Validator;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Repository\PluginRepository;
|
||||
use In2code\Femanager\Domain\Repository\UserRepository;
|
||||
use In2code\Femanager\Event\UniqueUserEvent;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use TYPO3\CMS\Core\EventDispatcher\EventDispatcher;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator as AbstractValidatorExtbase;
|
||||
|
||||
/**
|
||||
* Class GeneralValidator
|
||||
*/
|
||||
abstract class AbstractValidator extends AbstractValidatorExtbase
|
||||
{
|
||||
protected ?UserRepository $userRepository = null;
|
||||
|
||||
public ?ConfigurationManagerInterface $configurationManager = null;
|
||||
|
||||
protected ?EventDispatcherInterface $eventDispatcher = null;
|
||||
|
||||
/**
|
||||
* Former known as piVars
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $pluginVariables;
|
||||
|
||||
/**
|
||||
* Validationsettings
|
||||
*/
|
||||
public $validationSettings = [];
|
||||
|
||||
/**
|
||||
* Is Valid
|
||||
*/
|
||||
protected $isValid = true;
|
||||
|
||||
/**
|
||||
* @param UserRepository $userRepository
|
||||
*/
|
||||
public function injectUserRepository(UserRepository $userRepository)
|
||||
{
|
||||
$this->userRepository = $userRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function injectConfigurationManagerInterface(ConfigurationManagerInterface $configurationManager)
|
||||
{
|
||||
$this->configurationManager = $configurationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EventDispatcherInterface $eventDispatcher
|
||||
*/
|
||||
public function injectEventDispatcherInterface(EventDispatcherInterface $eventDispatcher)
|
||||
{
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
public function initializeObject(): void
|
||||
{
|
||||
if ($this->configurationManager === null) {
|
||||
$this->configurationManager = GeneralUtility::makeInstance(ConfigurationManagerInterface::class);
|
||||
}
|
||||
if ($this->eventDispatcher === null) {
|
||||
$this->eventDispatcher = GeneralUtility::makeInstance(EventDispatcher::class);
|
||||
}
|
||||
if ($this->userRepository === null) {
|
||||
$this->userRepository = GeneralUtility::makeInstance(UserRepository::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for required
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateRequired($value)
|
||||
{
|
||||
if (!is_object($value)) {
|
||||
if (is_numeric($value)) {
|
||||
return true;
|
||||
}
|
||||
return !empty($value);
|
||||
}
|
||||
if ((is_array($value) || $value instanceof \Countable) && count($value) > 0) {
|
||||
return true;
|
||||
}
|
||||
if ($value instanceof \DateTime) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for email
|
||||
*
|
||||
* @param string $value
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateEmail($value)
|
||||
{
|
||||
return GeneralUtility::validEmail($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for Minimum of characters
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $validationSetting
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateMin($value, $validationSetting)
|
||||
{
|
||||
if (mb_strlen($value) < $validationSetting) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for Maximum of characters
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $validationSetting
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateMax($value, $validationSetting)
|
||||
{
|
||||
if (mb_strlen($value) > $validationSetting) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for Numbers only
|
||||
*
|
||||
* @param string $value
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateInt($value)
|
||||
{
|
||||
return is_numeric($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for Letters (a-zA-Z), hyphen and underscore
|
||||
*
|
||||
* @param string $value
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateLetters($value)
|
||||
{
|
||||
if (preg_replace('/[^a-zA-Z_-]/', '', $value) === $value) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for all Unicode letters, hyphen and underscore
|
||||
*
|
||||
* @param string $value
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateUnicodeLetters($value)
|
||||
{
|
||||
return (bool)preg_match('/^[\pL_-]+$/u', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for Unique in sysfolder
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $field
|
||||
* @param User $user Existing User
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateUniquePage($value, $field, User $user = null)
|
||||
{
|
||||
$foundUser = $this->userRepository->checkUniquePage($field, $value, $user);
|
||||
return !is_object($foundUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for Unique in the db
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $field Fieldname like "username" or "email"
|
||||
* @param User $user Existing User
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateUniqueDb($value, $field, User $user = null)
|
||||
{
|
||||
$foundUser = $this->userRepository->checkUniqueDb($field, $value, $user);
|
||||
|
||||
$uniqueDb = !is_object($foundUser);
|
||||
|
||||
// return false, if is not unique
|
||||
return $this->eventDispatcher->dispatch(new UniqueUserEvent($value, $field, $user, $uniqueDb))->isUnique();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for "Must include some characters"
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $validationSettingList
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateMustInclude($value, $validationSettingList)
|
||||
{
|
||||
$isValid = true;
|
||||
$validationSettings = GeneralUtility::trimExplode(',', $validationSettingList, true);
|
||||
foreach ($validationSettings as $validationSetting) {
|
||||
switch ($validationSetting) {
|
||||
case 'number':
|
||||
if (!$this->stringContainsNumber($value)) {
|
||||
$isValid = false;
|
||||
}
|
||||
break;
|
||||
case 'letter':
|
||||
if (!$this->stringContainsLetter($value)) {
|
||||
$isValid = false;
|
||||
}
|
||||
break;
|
||||
case 'uppercase':
|
||||
if (!$this->stringContainsUppercase($value)) {
|
||||
$isValid = false;
|
||||
}
|
||||
break;
|
||||
case 'special':
|
||||
if (!$this->stringContainsSpecialCharacter($value)) {
|
||||
$isValid = false;
|
||||
}
|
||||
break;
|
||||
case 'space':
|
||||
if (!$this->stringContainsSpaceCharacter($value)) {
|
||||
$isValid = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
return $isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for "Must not include some characters"
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $validationSettingList
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateMustNotInclude($value, $validationSettingList)
|
||||
{
|
||||
$isValid = true;
|
||||
$validationSettings = GeneralUtility::trimExplode(',', $validationSettingList, true);
|
||||
foreach ($validationSettings as $validationSetting) {
|
||||
switch ($validationSetting) {
|
||||
case 'number':
|
||||
if ($this->stringContainsNumber($value)) {
|
||||
$isValid = false;
|
||||
}
|
||||
break;
|
||||
case 'letter':
|
||||
if ($this->stringContainsLetter($value)) {
|
||||
$isValid = false;
|
||||
}
|
||||
break;
|
||||
case 'uppercase':
|
||||
if ($this->stringContainsUppercase($value)) {
|
||||
$isValid = false;
|
||||
}
|
||||
break;
|
||||
case 'special':
|
||||
if ($this->stringContainsSpecialCharacter($value)) {
|
||||
$isValid = false;
|
||||
}
|
||||
break;
|
||||
case 'space':
|
||||
if ($this->stringContainsSpaceCharacter($value)) {
|
||||
$isValid = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
return $isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* String contains number?
|
||||
*
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function stringContainsNumber($value)
|
||||
{
|
||||
return strlen(preg_replace('/[^0-9]/', '', $value)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* String contains letter?
|
||||
*
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function stringContainsLetter($value)
|
||||
{
|
||||
return strlen(preg_replace('/[^a-zA-Z_-]/', '', $value)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* String contains uppercase letter?
|
||||
*
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function stringContainsUppercase($value)
|
||||
{
|
||||
return strlen(preg_replace('/[^A-Z]/', '', $value)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* String contains special character?
|
||||
*
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function stringContainsSpecialCharacter($value)
|
||||
{
|
||||
return strlen(preg_replace('/[^a-zA-Z0-9]/', '', $value)) !== strlen($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* String contains space character?
|
||||
*
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function stringContainsSpaceCharacter($value)
|
||||
{
|
||||
return strpos($value, ' ') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for checking if values are in a given list
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $validationSettingList
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateInList($value, $validationSettingList)
|
||||
{
|
||||
$valueList = GeneralUtility::trimExplode(',', $value, true);
|
||||
$validationSettings = GeneralUtility::trimExplode(',', $validationSettingList, true);
|
||||
$diff = array_diff($valueList, $validationSettings);
|
||||
|
||||
return empty($diff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for comparing two fields
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $value2
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateSameAs($value, $value2)
|
||||
{
|
||||
if ($value === $value2) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for checking if values is in date format
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $validationSetting
|
||||
* @return \bool
|
||||
*/
|
||||
protected function validateDate($value, $validationSetting)
|
||||
{
|
||||
$dateParts = [];
|
||||
switch ($validationSetting) {
|
||||
case 'd.m.Y':
|
||||
if (preg_match('/^([0-9]{2})\.([0-9]{2})\.([0-9]{4})$/', $value, $dateParts)) {
|
||||
if (checkdate((int)$dateParts[2], (int)$dateParts[1], (int)$dateParts[3])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm/d/Y':
|
||||
if (preg_match('/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/', $value, $dateParts)) {
|
||||
if (checkdate((int)$dateParts[1], (int)$dateParts[2], (int)$dateParts[3])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function init()
|
||||
{
|
||||
$this->initializeObject();
|
||||
$this->setPluginVariables();
|
||||
$this->setValidationSettings();
|
||||
}
|
||||
|
||||
protected function setPluginVariables()
|
||||
{
|
||||
$this->pluginVariables = GeneralUtility::_GP('tx_femanager_pi1');
|
||||
}
|
||||
|
||||
protected function setValidationSettings()
|
||||
{
|
||||
$config = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
|
||||
'Femanager',
|
||||
'Pi1'
|
||||
);
|
||||
$this->validationSettings = $config[$this->getControllerName()][$this->getValidationName()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getValidationName(): string
|
||||
{
|
||||
$validationName = 'validation';
|
||||
if ($this->getControllerName() === 'invitation' && $this->getActionName() === 'edit') {
|
||||
$validationName = 'validationEdit';
|
||||
}
|
||||
return $validationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getActionName(): string
|
||||
{
|
||||
return $this->pluginVariables['__referrer']['@action'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get controller name in lowercase
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getControllerName(): string
|
||||
{
|
||||
$controllerName = 'new';
|
||||
if ($this->pluginVariables['__referrer']['@controller'] === 'Edit') {
|
||||
$controllerName = 'edit';
|
||||
} elseif ($this->pluginVariables['__referrer']['@controller'] === 'Invitation') {
|
||||
$controllerName = 'invitation';
|
||||
}
|
||||
$this->checkAllowedControllerName($controllerName);
|
||||
return $controllerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controllerName
|
||||
*/
|
||||
protected function checkAllowedControllerName(string $controllerName)
|
||||
{
|
||||
$pluginRepository = GeneralUtility::makeInstance(PluginRepository::class);
|
||||
$pageIdentifier = FrontendUtility::getCurrentPid();
|
||||
if ($pluginRepository->isPluginWithViewOnGivenPage($controllerName, $pageIdentifier) === false) {
|
||||
throw new \LogicException('ControllerName is not allowed', 1541506524);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Validator;
|
||||
|
||||
use SJBR\SrFreecap\Domain\Repository\WordRepository;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class CaptchaValidator
|
||||
*/
|
||||
class CaptchaValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Validation of given Params
|
||||
*
|
||||
* @param $user
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($user)
|
||||
{
|
||||
$this->init();
|
||||
if (!$this->captchaEnabled() || $this->validCaptcha()) {
|
||||
return true;
|
||||
}
|
||||
$this->addError('validationErrorCaptcha', 0, ['fieldName' => 'captcha']);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if captcha is valid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validCaptcha()
|
||||
{
|
||||
$isValid = false;
|
||||
$wordRepository = GeneralUtility::makeInstance(WordRepository::class);
|
||||
$wordObject = $wordRepository->getWord();
|
||||
$wordHash = $wordObject->getWordHash();
|
||||
if (!empty($wordHash) && !empty($this->pluginVariables['captcha'])) {
|
||||
if ($wordObject->getHashFunction() == 'md5') {
|
||||
if (md5(strtolower(mb_convert_encoding((string)$this->pluginVariables['captcha'], 'ISO-8859-1'))) == $wordHash) {
|
||||
$wordRepository->cleanUpWord();
|
||||
$isValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if captcha is enabled (TypoScript, and sr_freecap loaded)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function captchaEnabled()
|
||||
{
|
||||
return ExtensionManagementUtility::isLoaded('sr_freecap')
|
||||
&& !empty($this->validationSettings['captcha']['captcha']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,482 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Domain\Validator;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Repository\PluginRepository;
|
||||
use In2code\Femanager\Domain\Service\ValidationSettingsService;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use SJBR\SrFreecap\Domain\Repository\WordRepository;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class ClientsideValidator
|
||||
*/
|
||||
class ClientsideValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Validation settings string
|
||||
* possible validations for each field are:
|
||||
* required, email, min(12), max(13), intOnly, lettersOnly,unicodeLettersOnly
|
||||
* uniqueInPage, uniqueInDb, date, mustInclude(number,letter,special),
|
||||
* inList(1,2,3)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $validationSettingsString;
|
||||
|
||||
/**
|
||||
* Field Value
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* Field Name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
/**
|
||||
* User
|
||||
*
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* Error message container
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $messages = [];
|
||||
|
||||
/**
|
||||
* Additional Values (for comparing a value with another)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $additionalValue;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $plugin = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $actionName = '';
|
||||
|
||||
/**
|
||||
* Validate Field
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateField()
|
||||
{
|
||||
if ($this->isValidationSettingsDifferentToGlobalSettings()) {
|
||||
$this->addMessage('validationErrorGeneral');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->getValidationSettings() as $validationSetting) {
|
||||
switch ($validationSetting) {
|
||||
case 'required':
|
||||
if (!$this->validateRequired($this->getValue())) {
|
||||
$this->addMessage('validationErrorRequired');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'email':
|
||||
if ($this->getValue() && !$this->validateEmail($this->getValue())) {
|
||||
$this->addMessage('validationErrorEmail');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case stristr($validationSetting, 'min('):
|
||||
if ($this->getValue() &&
|
||||
!$this->validateMin($this->getValue(), StringUtility::getValuesInBrackets($validationSetting))
|
||||
) {
|
||||
$this->addMessage('validationErrorMin');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case stristr($validationSetting, 'max('):
|
||||
if ($this->getValue() &&
|
||||
!$this->validateMax($this->getValue(), StringUtility::getValuesInBrackets($validationSetting))
|
||||
) {
|
||||
$this->addMessage('validationErrorMax');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'intOnly':
|
||||
if ($this->getValue() && !$this->validateInt($this->getValue())) {
|
||||
$this->addMessage('validationErrorInt');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'lettersOnly':
|
||||
if ($this->getValue() && !$this->validateLetters($this->getValue())) {
|
||||
$this->addMessage('validationErrorLetters');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'unicodeLettersOnly':
|
||||
if ($this->getValue() && !$this->validateUnicodeLetters($this->getValue())) {
|
||||
$this->addMessage('validationErrorLetters');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'uniqueInPage':
|
||||
if ($this->getValue() &&
|
||||
!$this->validateUniquePage($this->getValue(), $this->getFieldName(), $this->getUser())
|
||||
) {
|
||||
$this->addMessage('validationErrorUniquePage');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'uniqueInDb':
|
||||
if ($this->getValue() &&
|
||||
!$this->validateUniqueDb($this->getValue(), $this->getFieldName(), $this->getUser())
|
||||
) {
|
||||
$this->addMessage('validationErrorUniqueDb');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case stristr($validationSetting, 'mustInclude('):
|
||||
if ($this->getValue() &&
|
||||
!$this->validateMustInclude(
|
||||
$this->getValue(),
|
||||
StringUtility::getValuesInBrackets($validationSetting)
|
||||
)
|
||||
) {
|
||||
$this->addMessage('validationErrorMustInclude');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case stristr($validationSetting, 'mustNotInclude('):
|
||||
if ($this->getValue() &&
|
||||
!$this->validateMustNotInclude(
|
||||
$this->getValue(),
|
||||
StringUtility::getValuesInBrackets($validationSetting)
|
||||
)
|
||||
) {
|
||||
$this->addMessage('validationErrorMustNotInclude');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case stristr($validationSetting, 'inList('):
|
||||
if (!$this->validateInList(
|
||||
$this->getValue(),
|
||||
StringUtility::getValuesInBrackets($validationSetting)
|
||||
)) {
|
||||
$this->addMessage('validationErrorInList');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case stristr($validationSetting, 'sameAs('):
|
||||
if (!$this->validateSameAs($this->getValue(), $this->getAdditionalValue())) {
|
||||
$this->addMessage('validationErrorSameAs');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'date':
|
||||
if ($this->getValue() &&
|
||||
!$this->validateDate(
|
||||
$this->getValue(),
|
||||
LocalizationUtility::translate('tx_femanager_domain_model_user.dateFormat')
|
||||
)
|
||||
) {
|
||||
$this->addMessage('validationErrorDate');
|
||||
$this->isValid = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case stristr($validationSetting, 'captcha('):
|
||||
if (ExtensionManagementUtility::isLoaded('sr_freecap')) {
|
||||
$wordRepository = GeneralUtility::makeInstance(
|
||||
WordRepository::class
|
||||
);
|
||||
$wordObject = $wordRepository->getWord();
|
||||
$wordHash = $wordObject->getWordHash();
|
||||
$userVal = md5(strtolower(mb_convert_encoding($this->getValue(), 'ISO-8859-1')));
|
||||
if ($wordHash !== $userVal) {
|
||||
$this->addMessage('validationErrorCaptcha', 'captcha');
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// e.g. search for method validateCustom()
|
||||
$mainSetting = StringUtility::getValuesBeforeBrackets($validationSetting);
|
||||
if (method_exists($this, 'validate' . ucfirst($mainSetting))) {
|
||||
if (!$this->{'validate' . ucfirst($mainSetting)}(
|
||||
$this->getValue(),
|
||||
StringUtility::getValuesInBrackets($validationSetting)
|
||||
)) {
|
||||
$this->addMessage('validationError' . ucfirst($mainSetting));
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks the given validation string from user input against settings in TypoScript. If both strings
|
||||
* do not match, it could be possible that there is a manipulation. In this case, we stop validation and return a
|
||||
* global error message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isValidationSettingsDifferentToGlobalSettings(): bool
|
||||
{
|
||||
return $this->getValidationSettingsString() !== $this->getValidationSettingsFromTypoScript();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set validation
|
||||
*
|
||||
* @param string $validationSettingsString
|
||||
* @return ClientsideValidator
|
||||
*/
|
||||
public function setValidationSettingsString($validationSettingsString)
|
||||
{
|
||||
$this->validationSettingsString = $validationSettingsString;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValidationSettingsString()
|
||||
{
|
||||
return $this->validationSettingsString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValidationSettingsFromTypoScript(): string
|
||||
{
|
||||
$controllerName = $this->getControllerName();
|
||||
$validationService = GeneralUtility::makeInstance(
|
||||
ValidationSettingsService::class,
|
||||
$controllerName,
|
||||
$this->getValidationName()
|
||||
);
|
||||
|
||||
return $validationService->getValidationStringForField($this->fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getValidationSettings(): array
|
||||
{
|
||||
$validationSettings = GeneralUtility::trimExplode(',', $this->validationSettingsString, true);
|
||||
$validationSettings = str_replace('|', ',', $validationSettings);
|
||||
|
||||
return $validationSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return ClientsideValidator
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message to the errormessage array
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function addMessage($message)
|
||||
{
|
||||
$this->messages = array_merge($this->messages, [$message]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $messages
|
||||
* @return ClientsideValidator
|
||||
*/
|
||||
public function setMessages($messages)
|
||||
{
|
||||
$this->messages = $messages;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fieldName
|
||||
* @return ClientsideValidator
|
||||
*/
|
||||
public function setFieldName($fieldName)
|
||||
{
|
||||
$this->fieldName = $fieldName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFieldName()
|
||||
{
|
||||
return $this->fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return ClientsideValidator
|
||||
*/
|
||||
public function setUser(User $user = null)
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $additionalValue
|
||||
* @return ClientsideValidator
|
||||
*/
|
||||
public function setAdditionalValue($additionalValue)
|
||||
{
|
||||
$this->additionalValue = $additionalValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAdditionalValue()
|
||||
{
|
||||
return $this->additionalValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPlugin(): int
|
||||
{
|
||||
return $this->plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $plugin
|
||||
* @return ClientsideValidator
|
||||
*/
|
||||
public function setPlugin(int $plugin)
|
||||
{
|
||||
$this->plugin = $plugin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getActionName(): string
|
||||
{
|
||||
return $this->actionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $actionName
|
||||
* @return ClientsideValidator
|
||||
*/
|
||||
public function setActionName(string $actionName)
|
||||
{
|
||||
$this->actionName = $actionName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getValidationName(): string
|
||||
{
|
||||
$validationName = 'validation';
|
||||
if ($this->getControllerName() === 'invitation' && $this->getActionName() === 'edit') {
|
||||
$validationName = 'validationEdit';
|
||||
}
|
||||
|
||||
return $validationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getControllerName(): string
|
||||
{
|
||||
$pluginRepository = GeneralUtility::makeInstance(PluginRepository::class);
|
||||
$controllerName = $pluginRepository->getControllerNameByPluginSettings($this->getPlugin());
|
||||
|
||||
return $controllerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
protected function isValid($value)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Domain\Validator;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator as AbstractValidatorExtbase;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class PasswordValidator
|
||||
*/
|
||||
class PasswordValidator extends AbstractValidatorExtbase
|
||||
{
|
||||
public ?ConfigurationManagerInterface $configurationManager = null;
|
||||
|
||||
/**
|
||||
* Content Object
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $cObj;
|
||||
|
||||
/**
|
||||
* Plugin Variables
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $piVars = [];
|
||||
|
||||
/**
|
||||
* TypoScript Configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $configuration = [];
|
||||
|
||||
/**
|
||||
* Action Name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionName;
|
||||
|
||||
/**
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function injectConfigurationManagerInterface(ConfigurationManagerInterface $configurationManager)
|
||||
{
|
||||
$this->configurationManager = $configurationManager;
|
||||
}
|
||||
|
||||
public function initializeObject(): void
|
||||
{
|
||||
if ($this->configurationManager === null) {
|
||||
$this->configurationManager = GeneralUtility::makeInstance(ConfigurationManagerInterface::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation of given Params
|
||||
*
|
||||
* @param $user
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($user)
|
||||
{
|
||||
$this->initializeObject();
|
||||
$this->init();
|
||||
|
||||
// if password fields are not active or if keep function active
|
||||
if (!$this->passwordFieldsAdded() || $this->keepPasswordIfEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$password = $user->getPassword();
|
||||
$passwordRepeat = isset($this->piVars['password_repeat']) ? $this->piVars['password_repeat'] : '';
|
||||
|
||||
if ($password !== $passwordRepeat) {
|
||||
$this->addError('validationErrorPasswordRepeat', 0, ['field' => 'password']);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Passwords are empty and if keep configuration is active
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function keepPasswordIfEmpty()
|
||||
{
|
||||
if (isset($this->configuration['edit']['misc']['keepPasswordIfEmpty']) &&
|
||||
$this->configuration['edit']['misc']['keepPasswordIfEmpty'] === '1' &&
|
||||
isset($this->piVars['user']['password']) && $this->piVars['user']['password'] === '' &&
|
||||
isset($this->piVars['password_repeat']) && $this->piVars['password_repeat'] === ''
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if password fields are added with flexform
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function passwordFieldsAdded()
|
||||
{
|
||||
$flexFormValues = GeneralUtility::xml2array($this->cObj->data['pi_flexform']);
|
||||
if (is_array($flexFormValues)) {
|
||||
$fields =
|
||||
$flexFormValues['data'][$this->actionName]['lDEF']['settings.' . $this->actionName . '.fields']['vDEF'] ?? [];
|
||||
if (empty($fields) || GeneralUtility::inList($fields, 'password')) {
|
||||
// password fields are added to form
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// password fields are not added to form
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Validator Function
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
$this->configuration = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
|
||||
'Femanager',
|
||||
'Pi1'
|
||||
);
|
||||
$this->cObj = $this->configurationManager->getContentObject();
|
||||
$this->piVars = GeneralUtility::_GP('tx_femanager_pi1');
|
||||
$this->actionName = $this->piVars['__referrer']['@action'];
|
||||
}
|
||||
|
||||
public function setContentObjectRenderer(ContentObjectRenderer $cObj): void
|
||||
{
|
||||
$this->cObj = $cObj;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,403 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Domain\Validator;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
|
||||
/**
|
||||
* Class ServersideValidator
|
||||
*/
|
||||
class ServersideValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Validation of given Params
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($user): bool
|
||||
{
|
||||
$this->init();
|
||||
if ($this->validationSettings['_enable']['server'] === '1') {
|
||||
foreach ($this->validationSettings as $fieldName => $validations) {
|
||||
if ($this->shouldBeValidated($user, $fieldName, $validations)) {
|
||||
$value = $this->getValue($user, $fieldName);
|
||||
|
||||
foreach ($validations as $validation => $validationSetting) {
|
||||
switch ($validation) {
|
||||
case 'required':
|
||||
$this->checkRequiredValidation($validationSetting, $value, $fieldName);
|
||||
break;
|
||||
|
||||
case 'email':
|
||||
$this->checkEmailValidation($value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'min':
|
||||
$this->checkMinValidation($value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'max':
|
||||
$this->checkMaxValidation($value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'intOnly':
|
||||
$this->checkIntOnlyValidation($value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'lettersOnly':
|
||||
$this->checkLetterOnlyValidation($value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'unicodeLettersOnly':
|
||||
$this->checkUnicodeLetterOnlyValidation($value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'uniqueInPage':
|
||||
$this->checkUniqueInPageValidation($user, $value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'uniqueInDb':
|
||||
$this->checkUniqueInDbValidation($user, $value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'mustInclude':
|
||||
$this->checkMustIncludeValidation($value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'mustNotInclude':
|
||||
$this->checkMustNotIncludeValidation($value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'inList':
|
||||
$this->checkInListValidation($value, $validationSetting, $fieldName);
|
||||
break;
|
||||
|
||||
case 'sameAs':
|
||||
$this->checkSameAsValidation($user, $validationSetting, $value, $fieldName);
|
||||
break;
|
||||
|
||||
case 'date':
|
||||
// Nothing to do. ServersideValidator runs after converter
|
||||
// If dateTimeConverter exception $value is the old DateTime Object => True
|
||||
// If dateTimeConverter runs well we have an DateTime Object => True
|
||||
break;
|
||||
|
||||
default:
|
||||
// e.g. search for method validateCustom()
|
||||
$this->checkAnyValidation($validation, $value, $validationSetting, $fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $validationSetting
|
||||
* @param $value
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkRequiredValidation($validationSetting, $value, $fieldName)
|
||||
{
|
||||
if ($validationSetting === '1' && !$this->validateRequired($value)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorRequired', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkEmailValidation($value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (!empty($value) && $validationSetting === '1' && !$this->validateEmail($value)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorEmail', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkMinValidation($value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (!empty($value) && !$this->validateMin($value, $validationSetting)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorMin', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkMaxValidation($value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (!empty($value) && !$this->validateMax($value, $validationSetting)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorMax', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkIntOnlyValidation($value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (!empty($value) && $validationSetting === '1' && !$this->validateInt($value)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorInt', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkLetterOnlyValidation($value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (!empty($value) && $validationSetting === '1' && !$this->validateLetters($value)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorLetters', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkUnicodeLetterOnlyValidation($value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (!empty($value) && $validationSetting === '1' && !$this->validateUnicodeLetters($value)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorLetters', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkUniqueInPageValidation($user, $value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (
|
||||
!empty($value) &&
|
||||
$validationSetting === '1' &&
|
||||
!$this->validateUniquePage($value, $fieldName, $user)
|
||||
) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorUniquePage', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkUniqueInDbValidation($user, $value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (
|
||||
!empty($value) &&
|
||||
$validationSetting === '1' &&
|
||||
!$this->validateUniqueDb($value, $fieldName, $user)
|
||||
) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorUniqueDb', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkMustIncludeValidation($value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (!empty($value) && !$this->validateMustInclude($value, $validationSetting)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorMustInclude', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkMustNotIncludeValidation($value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (!empty($value) && !$this->validateMustNotInclude($value, $validationSetting)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorMustNotInclude', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkInListValidation($value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (!$this->validateInList($value, $validationSetting)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorInList', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user
|
||||
* @param $validationSetting
|
||||
* @param $value
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkSameAsValidation($user, $validationSetting, $value, $fieldName)
|
||||
{
|
||||
if (method_exists($user, 'get' . ucfirst($validationSetting))) {
|
||||
$valueToCompare = $user->{'get' . ucfirst($validationSetting)}();
|
||||
if (!$this->validateSameAs($value, $valueToCompare)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationErrorSameAs', 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $validation
|
||||
* @param $value
|
||||
* @param $validationSetting
|
||||
* @param $fieldName
|
||||
*/
|
||||
protected function checkAnyValidation($validation, $value, $validationSetting, $fieldName)
|
||||
{
|
||||
if (method_exists($this, 'validate' . ucfirst($validation))) {
|
||||
if (!$this->{'validate' . ucfirst($validation)}($value, $validationSetting)) {
|
||||
$this->addErrorForProperty($fieldName, 'validationError' . ucfirst($validation), 0, ['field' => $fieldName]);
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $fieldName
|
||||
* @return string
|
||||
*/
|
||||
protected function getValue($user, $fieldName)
|
||||
{
|
||||
$value = $this->getValueFromProperty($user, $fieldName);
|
||||
|
||||
if ($value instanceof ObjectStorage) {
|
||||
$values = [];
|
||||
|
||||
foreach ($value as $object) {
|
||||
if (method_exists($object, 'getUid')) {
|
||||
$values[] = $object->getUid();
|
||||
}
|
||||
if ($object instanceof FileReference) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return implode(',', $values);
|
||||
}
|
||||
|
||||
if (is_object($value)) {
|
||||
if (method_exists($value, 'getUid')) {
|
||||
return $value->getUid();
|
||||
}
|
||||
if (method_exists($value, 'getFirst')) {
|
||||
return $value->getFirst()->getUid();
|
||||
}
|
||||
if (method_exists($value, 'current')) {
|
||||
$current = $value->current();
|
||||
|
||||
if ($current instanceof FileReference) {
|
||||
return true;
|
||||
}
|
||||
if ($current !== null) {
|
||||
if (method_exists($current, 'getUid')) {
|
||||
return $current->getUid();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user
|
||||
* @param $fieldName
|
||||
* @param array $validationSettings
|
||||
* @return bool
|
||||
*/
|
||||
protected function shouldBeValidated($user, $fieldName, array $validationSettings): bool
|
||||
{
|
||||
return is_object($user)
|
||||
&& $this->propertyHasGetterMethod($user, $fieldName)
|
||||
&& $this->evaluateConditions($user, $fieldName, $validationSettings);
|
||||
}
|
||||
|
||||
protected function evaluateConditions(User $user, string $fieldName, array $validationSettings)
|
||||
{
|
||||
if (array_key_exists('if', $validationSettings) && class_exists($validationSettings['if'])) {
|
||||
$object = GeneralUtility::makeInstance($validationSettings['if']);
|
||||
if ($object instanceof ValidationConditionInterface) {
|
||||
return $object->shouldValidate($user, $fieldName, $validationSettings);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user
|
||||
* @param $fieldName
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getValueFromProperty($user, $fieldName)
|
||||
{
|
||||
$value = '';
|
||||
try {
|
||||
$value = ObjectAccess::getProperty($user, $fieldName);
|
||||
} catch (\Exception $exception) {
|
||||
unset($exception);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function propertyHasGetterMethod($user, $fieldName): bool
|
||||
{
|
||||
try {
|
||||
ObjectAccess::getProperty($user, $fieldName);
|
||||
$getterExists = true;
|
||||
} catch (\Exception $exception) {
|
||||
unset($exception);
|
||||
$getterExists = false;
|
||||
}
|
||||
return $getterExists === true;
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Domain\Validator;
|
||||
|
||||
use In2code\Femanager\DataProvider\CountryZonesDataProvider;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
|
||||
class ShouldValidateStateCondition implements ValidationConditionInterface
|
||||
{
|
||||
protected $isStaticInfoTablesLoaded;
|
||||
|
||||
protected $countryZonesDataProvider;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->isStaticInfoTablesLoaded = ExtensionManagementUtility::isLoaded('static_info_tables');
|
||||
if ($this->isStaticInfoTablesLoaded) {
|
||||
$this->countryZonesDataProvider = GeneralUtility::makeInstance(CountryZonesDataProvider::class);
|
||||
}
|
||||
}
|
||||
|
||||
public function shouldValidate(User $user, string $fieldName, array $validationSettings): bool
|
||||
{
|
||||
return $this->isStaticInfoTablesLoaded
|
||||
&& $this->countryHasZones(ObjectAccess::getProperty($user, 'country'));
|
||||
}
|
||||
|
||||
protected function countryHasZones($countryIso3)
|
||||
{
|
||||
return $this->countryZonesDataProvider->hasCountryZonesForCountryIso3($countryIso3);
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Domain\Validator;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
interface ValidationConditionInterface
|
||||
{
|
||||
public function shouldValidate(User $user, string $fieldName, array $validationSettings): bool;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
class AdminConfirmationUserEvent extends UserEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Service\SendMailService;
|
||||
use Symfony\Component\Mime\Email;
|
||||
|
||||
class AfterMailSendEvent
|
||||
{
|
||||
/**
|
||||
* @var Email
|
||||
*/
|
||||
private $email;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $variables;
|
||||
/**
|
||||
* @var SendMailService
|
||||
*/
|
||||
private $service;
|
||||
|
||||
public function __construct(Email $email, array $variables, SendMailService $service)
|
||||
{
|
||||
$this->email = $email;
|
||||
$this->variables = $variables;
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Email
|
||||
*/
|
||||
public function getEmail(): Email
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SendMailService
|
||||
*/
|
||||
public function getService(): SendMailService
|
||||
{
|
||||
return $this->service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getVariables(): array
|
||||
{
|
||||
return $this->variables;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
class AfterUserUpdateEvent extends UserEvent
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $hash;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $status;
|
||||
|
||||
public function __construct(User $user, string $hash, string $status)
|
||||
{
|
||||
parent::__construct($user);
|
||||
$this->hash = $hash;
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStatus(): string
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHash(): string
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Service\SendMailService;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
|
||||
class BeforeMailBodyRenderEvent
|
||||
{
|
||||
/**
|
||||
* @var StandaloneView
|
||||
*/
|
||||
private $standAloneView;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $variables;
|
||||
/**
|
||||
* @var SendMailService
|
||||
*/
|
||||
private $service;
|
||||
|
||||
public function __construct(StandaloneView $standAloneView, array $variables, SendMailService $service)
|
||||
{
|
||||
$this->standAloneView = $standAloneView;
|
||||
$this->variables = $variables;
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return StandaloneView
|
||||
*/
|
||||
public function getStandaloneView(): StandaloneView
|
||||
{
|
||||
return $this->standAloneView;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SendMailService
|
||||
*/
|
||||
public function getService(): SendMailService
|
||||
{
|
||||
return $this->service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getVariables(): array
|
||||
{
|
||||
return $this->variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StandaloneView $standAloneView
|
||||
*/
|
||||
public function setStandaloneView(StandaloneView $standAloneView): void
|
||||
{
|
||||
$this->standAloneView = $standAloneView;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Service\SendMailService;
|
||||
use Symfony\Component\Mime\Email;
|
||||
|
||||
class BeforeMailSendEvent
|
||||
{
|
||||
/**
|
||||
* @var Email
|
||||
*/
|
||||
private $email;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $variables;
|
||||
/**
|
||||
* @var SendMailService
|
||||
*/
|
||||
private $service;
|
||||
|
||||
public function __construct(Email $email, array $variables, SendMailService $service)
|
||||
{
|
||||
$this->email = $email;
|
||||
$this->variables = $variables;
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Email
|
||||
*/
|
||||
public function getEmail(): Email
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SendMailService
|
||||
*/
|
||||
public function getService(): SendMailService
|
||||
{
|
||||
return $this->service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getVariables(): array
|
||||
{
|
||||
return $this->variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Email $email
|
||||
*/
|
||||
public function setEmail(Email $email): void
|
||||
{
|
||||
$this->email = $email;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
class BeforeUpdateUserEvent extends UserEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
class BeforeUserConfirmEvent
|
||||
{
|
||||
/**
|
||||
* @var User|null
|
||||
*/
|
||||
private $user;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $hash;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $status;
|
||||
|
||||
public function __construct(
|
||||
?User $user,
|
||||
string $hash,
|
||||
string $status
|
||||
) {
|
||||
$this->user = $user;
|
||||
$this->hash = $hash;
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User|null
|
||||
*/
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHash(): string
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStatus(): string
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
class BeforeUserCreateEvent extends UserEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
class CreateConfirmationRequestEvent extends UserEvent
|
||||
{
|
||||
public const MODE_AUTOMATIC = 'automatic';
|
||||
|
||||
public const MODE_MANUAL = 'manual';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mode;
|
||||
|
||||
public function __construct(User $user, string $mode)
|
||||
{
|
||||
parent::__construct($user);
|
||||
$this->mode = $mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMode(): string
|
||||
{
|
||||
return $this->mode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
class DeleteUserEvent extends UserEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
class FinalCreateEvent extends UserEvent
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $action;
|
||||
|
||||
public function __construct(?User $user, string $action)
|
||||
{
|
||||
parent::__construct($user);
|
||||
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
public function getAction(): string
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
class FinalUpdateEvent extends UserEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
class ImpersonateEvent extends UserEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
class InviteUserConfirmedEvent extends UserEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
class InviteUserCreateEvent extends UserEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
class InviteUserEditEvent extends UserEvent
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $hash;
|
||||
|
||||
public function __construct(?User $user, string $hash)
|
||||
{
|
||||
parent::__construct($user);
|
||||
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHash(): string
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
class InviteUserUpdateEvent extends UserEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
class RefuseUserEvent extends UserEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
class UniqueUserEvent
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $emailOrUsername;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $fieldName;
|
||||
/**
|
||||
* @var User|null
|
||||
*/
|
||||
private $user;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $unique;
|
||||
|
||||
public function __construct(
|
||||
string $emailOrUsername,
|
||||
string $fieldName,
|
||||
?User $user,
|
||||
bool $unique
|
||||
) {
|
||||
$this->emailOrUsername = $emailOrUsername;
|
||||
$this->fieldName = $fieldName;
|
||||
$this->user = $user;
|
||||
$this->unique = $unique;
|
||||
}
|
||||
|
||||
public function setUnique(bool $unique): void
|
||||
{
|
||||
$this->unique = $unique;
|
||||
}
|
||||
|
||||
public function isUnique(): bool
|
||||
{
|
||||
return $this->unique;
|
||||
}
|
||||
|
||||
public function getEmailOrUsername(): string
|
||||
{
|
||||
return $this->emailOrUsername;
|
||||
}
|
||||
|
||||
public function getFieldName(): string
|
||||
{
|
||||
return $this->fieldName;
|
||||
}
|
||||
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
class UserEvent
|
||||
{
|
||||
protected $user;
|
||||
|
||||
public function __construct(?User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Event;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
class UserLogEvent extends UserEvent
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $state;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $additionalProperties;
|
||||
|
||||
public function __construct(?User $user, int $state, array $additionalProperties = [])
|
||||
{
|
||||
parent::__construct($user);
|
||||
|
||||
$this->state = $state;
|
||||
$this->additionalProperties = $additionalProperties;
|
||||
}
|
||||
|
||||
public function getAdditionalProperties(): array
|
||||
{
|
||||
return $this->additionalProperties;
|
||||
}
|
||||
|
||||
public function getState(): int
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Exception;
|
||||
|
||||
/**
|
||||
* Class FileNotFoundException
|
||||
*/
|
||||
class FileNotFoundException extends \Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Exception;
|
||||
|
||||
/**
|
||||
* NotPaginatableException
|
||||
*/
|
||||
class NotPaginatableException extends \Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Finisher;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class AbstractFinisher
|
||||
*/
|
||||
abstract class AbstractFinisher implements FinisherInterface
|
||||
{
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* Extension settings
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Finisher service configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration;
|
||||
|
||||
/**
|
||||
* Controller actionName - usually "createAction" or "confirmationAction"
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
protected $actionMethodName;
|
||||
|
||||
/**
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* @return User
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return AbstractFinisher
|
||||
*/
|
||||
public function setUser($user)
|
||||
{
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSettings()
|
||||
{
|
||||
return $this->settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
* @return AbstractFinisher
|
||||
*/
|
||||
public function setSettings($settings)
|
||||
{
|
||||
$this->settings = $settings;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getConfiguration()
|
||||
{
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $configuration
|
||||
* @return AbstractFinisher
|
||||
*/
|
||||
public function setConfiguration($configuration)
|
||||
{
|
||||
$this->configuration = $configuration;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getActionMethodName()
|
||||
{
|
||||
return $this->actionMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $actionMethodName
|
||||
* @return AbstractFinisher
|
||||
*/
|
||||
public function setActionMethodName($actionMethodName)
|
||||
{
|
||||
$this->actionMethodName = $actionMethodName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function initializeFinisher()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param array $configuration
|
||||
* @param array $settings
|
||||
* @param ContentObjectRenderer $contentObject
|
||||
* @param string $actionMethodName
|
||||
*/
|
||||
public function __construct(
|
||||
User $user,
|
||||
array $configuration,
|
||||
array $settings,
|
||||
$actionMethodName,
|
||||
ContentObjectRenderer $contentObject
|
||||
) {
|
||||
$this->setUser($user);
|
||||
$this->setConfiguration($configuration);
|
||||
$this->setSettings($settings);
|
||||
$this->setActionMethodName($actionMethodName);
|
||||
$this->contentObject = $contentObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Finisher;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
/**
|
||||
* Interface FinisherInterface
|
||||
*/
|
||||
interface FinisherInterface
|
||||
{
|
||||
/**
|
||||
* @return User
|
||||
*/
|
||||
public function getUser();
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return AbstractFinisher
|
||||
*/
|
||||
public function setUser($user);
|
||||
|
||||
/**
|
||||
* Get settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSettings();
|
||||
|
||||
/**
|
||||
* Set settings
|
||||
*
|
||||
* @param array $settings
|
||||
* @return AbstractFinisher
|
||||
*/
|
||||
public function setSettings($settings);
|
||||
|
||||
public function getActionMethodName();
|
||||
|
||||
/**
|
||||
* @param null $actionMethodName
|
||||
* @return AbstractFinisher
|
||||
*/
|
||||
public function setActionMethodName($actionMethodName);
|
||||
|
||||
public function initializeFinisher();
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Finisher;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Service\FinisherService;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class FinisherRunner
|
||||
*/
|
||||
class FinisherRunner
|
||||
{
|
||||
/**
|
||||
* @var ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* TypoScript settings
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* FinisherRunner constructor.
|
||||
* @param ObjectManagerInterface $objectManager
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function __construct(
|
||||
ObjectManagerInterface $objectManager,
|
||||
ConfigurationManagerInterface $configurationManager
|
||||
) {
|
||||
$this->objectManager = $objectManager;
|
||||
$this->configurationManager = $configurationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call finisher classes after submit
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $actionMethodName
|
||||
* @param array $settings
|
||||
* @param ContentObjectRenderer $contentObject
|
||||
*/
|
||||
public function callFinishers(
|
||||
User $user,
|
||||
$actionMethodName,
|
||||
$settings,
|
||||
ContentObjectRenderer $contentObject
|
||||
) {
|
||||
foreach ($this->getFinisherClasses($settings) as $finisherSettings) {
|
||||
/** @var FinisherService $finisherService */
|
||||
$finisherService = $this->objectManager->get(FinisherService::class, $user, $settings, $contentObject);
|
||||
$finisherService->setClass($finisherSettings['class']);
|
||||
$finisherService->setRequirePath($finisherSettings['require'] ?? '');
|
||||
$finisherService->setConfiguration($finisherSettings['config'] ?? []);
|
||||
$finisherService->setActionMethodName($actionMethodName);
|
||||
$finisherService->start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all finisher classes from typoscript and sort them
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
protected function getFinisherClasses($settings)
|
||||
{
|
||||
$finishers = (array)$settings['finishers'];
|
||||
ksort($finishers);
|
||||
return $finishers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Finisher;
|
||||
|
||||
use In2code\Femanager\Domain\Service\StoreInDatabaseService;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use TYPO3\CMS\Core\TypoScript\TypoScriptService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class SaveToAnyTableFinisher
|
||||
*/
|
||||
class SaveToAnyTableFinisher extends AbstractFinisher implements FinisherInterface
|
||||
{
|
||||
/**
|
||||
* Inject a complete new content object
|
||||
*
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* @var ObjectManager
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var TypoScriptService
|
||||
*/
|
||||
protected $typoScriptService;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration = [];
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $lastGeneratedUid = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $dataArray = [];
|
||||
|
||||
/**
|
||||
* @param ContentObjectRenderer $contentObject
|
||||
*/
|
||||
public function injectContentObjectRenderer(ContentObjectRenderer $contentObject)
|
||||
{
|
||||
$this->contentObject = $contentObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ObjectManager $objectManager
|
||||
*/
|
||||
public function injectObjectManager(ObjectManager $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TypoScriptService $typoScriptService
|
||||
*/
|
||||
public function injectTypoScriptService(TypoScriptService $typoScriptService)
|
||||
{
|
||||
$this->typoScriptService = $typoScriptService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite configuration with
|
||||
* plugin.tx_femanager.settings.new.storeInDatabase
|
||||
*/
|
||||
public function initializeFinisher()
|
||||
{
|
||||
if ($this->typoScriptService == null) {
|
||||
$this->typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
|
||||
}
|
||||
$configuration = $this->typoScriptService->convertPlainArrayToTypoScriptArray($this->settings);
|
||||
if (!empty($configuration['new.']['storeInDatabase.'])) {
|
||||
$this->configuration = $configuration['new.']['storeInDatabase.'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store to any table
|
||||
*/
|
||||
public function storeFinisher()
|
||||
{
|
||||
if (!empty($this->configuration)) {
|
||||
$this->addArrayToDataArray($this->user->_getProperties());
|
||||
foreach ((array)array_keys($this->configuration) as $table) {
|
||||
$this->storeForTable($table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store for a given table
|
||||
*
|
||||
* @param string $table
|
||||
*/
|
||||
protected function storeForTable($table)
|
||||
{
|
||||
if ($this->isTableEnabled($table)) {
|
||||
$this->contentObject->start($this->getDataArray());
|
||||
/** @var StoreInDatabaseService $storeInDatabase */
|
||||
$storeInDatabase = $this->objectManager->get(StoreInDatabaseService::class);
|
||||
$storeInDatabase->setTable($table);
|
||||
$this->setPropertiesForTable($table, $storeInDatabase);
|
||||
$this->addArrayToDataArray(['uid_' . $table => $storeInDatabase->execute()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store properties for a table
|
||||
*
|
||||
* @param string $table
|
||||
* @param StoreInDatabaseService $storeInDatabase
|
||||
*/
|
||||
protected function setPropertiesForTable($table, StoreInDatabaseService $storeInDatabase)
|
||||
{
|
||||
foreach ($this->configuration[$table] as $field => $value) {
|
||||
if (!$this->isSkippedKey($field)) {
|
||||
$value = $this->contentObject->cObjGetSingle(
|
||||
(string)$this->configuration[$table][$field],
|
||||
(array)$this->configuration[$table][$field . '.']
|
||||
);
|
||||
$storeInDatabase->addProperty($field, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this table is enabled in TypoScript
|
||||
*
|
||||
* @param string $table
|
||||
* @return bool
|
||||
*/
|
||||
protected function isTableEnabled($table)
|
||||
{
|
||||
return $this->contentObject->cObjGetSingle(
|
||||
(string)$this->configuration[$table]['_enable'],
|
||||
(array)$this->configuration[$table]['_enable.']
|
||||
) === '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this key skipped because it starts with _ or ends with .
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
protected function isSkippedKey($key)
|
||||
{
|
||||
return StringUtility::startsWith($key, '_') || StringUtility::endsWith($key, '.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add array to dataArray
|
||||
*
|
||||
* @param array $array
|
||||
*/
|
||||
protected function addArrayToDataArray(array $array)
|
||||
{
|
||||
$dataArray = $this->getDataArray();
|
||||
$dataArray = array_merge($dataArray, $array);
|
||||
$this->setDataArray($dataArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDataArray()
|
||||
{
|
||||
return $this->dataArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $dataArray
|
||||
* @return SaveToAnyTableFinisher
|
||||
*/
|
||||
public function setDataArray($dataArray)
|
||||
{
|
||||
$this->dataArray = $dataArray;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Finisher;
|
||||
|
||||
use TYPO3\CMS\Core\Http\RequestFactory;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class SendParametersFinisher
|
||||
*/
|
||||
class SendParametersFinisher extends AbstractFinisher implements FinisherInterface
|
||||
{
|
||||
/**
|
||||
* Inject a complete new content object
|
||||
*
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* @var ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* TypoScript configuration part sendPost
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration;
|
||||
|
||||
/**
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function injectConfigurationManagerInterface(ConfigurationManagerInterface $configurationManager)
|
||||
{
|
||||
$this->configurationManager = $configurationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContentObjectRenderer $contentObject
|
||||
*/
|
||||
public function injectContentObjectRenderer(ContentObjectRenderer $contentObject)
|
||||
{
|
||||
$this->contentObject = $contentObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
public function initializeFinisher()
|
||||
{
|
||||
$this->contentObject->start($this->user->_getProperties());
|
||||
$typoScript = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
|
||||
);
|
||||
$this->configuration = $typoScript['plugin.']['tx_femanager.']['settings.']['new.']['sendPost.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Send values via curl to a third party software
|
||||
*/
|
||||
public function sendFinisher()
|
||||
{
|
||||
if ($this->isEnabled()) {
|
||||
$curlSettings = $this->getCurlSettings();
|
||||
|
||||
/** @var RequestFactory $requestFactory */
|
||||
$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
|
||||
$params = $curlSettings['params'];
|
||||
$parsedParams = [];
|
||||
parse_str($params, $parsedParams);
|
||||
$requestFactory->request($curlSettings['url'], 'POST', ['form_params' => $parsedParams]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CURL settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getCurlSettings()
|
||||
{
|
||||
return [
|
||||
'url' => $this->getTargetUrl(),
|
||||
'params' => $this->getData()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getData()
|
||||
{
|
||||
return $this->contentObject->cObjGetSingle((string)$this->configuration['data'], (array)$this->configuration['data.']);
|
||||
}
|
||||
|
||||
protected function getTargetUrl()
|
||||
{
|
||||
$linkConfiguration = [
|
||||
'parameter' => $this->configuration['targetUrl'],
|
||||
'forceAbsoluteUrl' => '1',
|
||||
'returnLast' => 'url'
|
||||
];
|
||||
return $this->contentObject->typoLink('dummy', $linkConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if sendPost is activated
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isEnabled()
|
||||
{
|
||||
return $this->contentObject->cObjGetSingle($this->configuration['_enable'] ?? 'TEXT', $this->configuration['_enable.'] ?? '0')
|
||||
=== '1';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Persistence\Generic\Mapper;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Model\UserGroup;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap as DataMapExtbase;
|
||||
|
||||
/**
|
||||
* Disable tx_extbase_type='0' in where clause for femanager
|
||||
*/
|
||||
class DataMap extends DataMapExtbase
|
||||
{
|
||||
/**
|
||||
* Disable record type for femanager
|
||||
*
|
||||
* @param string $recordType The record type
|
||||
*/
|
||||
public function setRecordType($recordType)
|
||||
{
|
||||
parent::setRecordType($recordType);
|
||||
if ($this->getClassName() === User::class || $this->getClassName() === UserGroup::class) {
|
||||
$this->recordType = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\UserFunc;
|
||||
|
||||
use In2code\Femanager\DataProvider\CountryDataProvider;
|
||||
use In2code\Femanager\DataProvider\CountryZonesDataProvider;
|
||||
use In2code\Femanager\DataProvider\FallbackCountryDataProvider;
|
||||
use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
class StaticInfoTables
|
||||
{
|
||||
public function isStaticInfoTablesInstalled(): bool
|
||||
{
|
||||
return ExtensionManagementUtility::isLoaded('static_info_tables');
|
||||
}
|
||||
|
||||
public function getStatesOptions(array $data, TcaSelectItems $tcaSelectItems)
|
||||
{
|
||||
if (ExtensionManagementUtility::isLoaded('static_info_tables')) {
|
||||
$countryZonesDataProvider = GeneralUtility::makeInstance(CountryZonesDataProvider::class);
|
||||
$country = $data['row']['country'] ?? null;
|
||||
if (is_array($country)) {
|
||||
if (count($country) > 0) {
|
||||
$country = array_values($country)[0];
|
||||
} else {
|
||||
$country = null;
|
||||
}
|
||||
}
|
||||
if (empty($country)) {
|
||||
$data['items'] = [
|
||||
[
|
||||
'LLL:EXT:femanager/Resources/Private/Language/locallang_db.xlf:pleaseChooseCountry',
|
||||
''
|
||||
]
|
||||
];
|
||||
} else {
|
||||
$countryZones = $countryZonesDataProvider->getCountryZonesForCountryIso3($country);
|
||||
|
||||
if (empty($countryZones)) {
|
||||
$data['items'] = [
|
||||
[
|
||||
'LLL:EXT:femanager/Resources/Private/Language/locallang_db.xlf:noZonesForThisCountry',
|
||||
''
|
||||
]
|
||||
];
|
||||
} else {
|
||||
foreach ($countryZones as $countryZone) {
|
||||
$data['items'][] = [$countryZone->getLocalName(), $countryZone->getIsoCode()];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$data['items'][] = ['Error: static_info_tables is not installed', ''];
|
||||
}
|
||||
}
|
||||
|
||||
public function getCountryOptions(array $data, TcaSelectItems $tcaSelectItems)
|
||||
{
|
||||
if (ExtensionManagementUtility::isLoaded('static_info_tables')) {
|
||||
$countryDataProvider = GeneralUtility::makeInstance(CountryDataProvider::class);
|
||||
$countries = $countryDataProvider->getCountries();
|
||||
foreach ($countries as $country) {
|
||||
$data['items'][] = [$country->getShortNameEn(), $country->getIsoCodeA3()];
|
||||
}
|
||||
} else {
|
||||
$fallbackCountryDataProvider = GeneralUtility::makeInstance(FallbackCountryDataProvider::class);
|
||||
$countries = $fallbackCountryDataProvider->getCountries();
|
||||
foreach ($countries as $key => $name) {
|
||||
$data['items'][] = [$name, $key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\UserFunc;
|
||||
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class UserFieldsOptions
|
||||
*/
|
||||
class UserFieldsOptions
|
||||
{
|
||||
/**
|
||||
* @var LanguageService
|
||||
*/
|
||||
protected $languageService;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $localLangPrefix = 'LLL:EXT:femanager/Resources/Private/Language/locallang_db.xlf:';
|
||||
|
||||
/**
|
||||
* Add options to FlexForm Selection - Options can be defined in TSConfig
|
||||
*
|
||||
* @param array $params
|
||||
*/
|
||||
public function addOptions(&$params)
|
||||
{
|
||||
$this->initialize();
|
||||
$tSconfig = BackendUtility::getPagesTSconfig($this->getPid());
|
||||
$this->addCaptchaOption($params);
|
||||
$this->addStateOption($params);
|
||||
$tab = $params['config']['itemsProcFuncTab'] . '.';
|
||||
if (!empty($tSconfig['tx_femanager.']['flexForm.'][$tab]['addFieldOptions.'])) {
|
||||
$options = $tSconfig['tx_femanager.']['flexForm.'][$tab]['addFieldOptions.'];
|
||||
foreach ((array)$options as $value => $label) {
|
||||
$params['items'][] = [
|
||||
StringUtility::startsWith($label, 'LLL:') ? $this->languageService->sL($label) : $label,
|
||||
$value
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add captcha option
|
||||
*
|
||||
* @param array $params
|
||||
*/
|
||||
protected function addCaptchaOption(&$params)
|
||||
{
|
||||
if (ExtensionManagementUtility::isLoaded('sr_freecap')) {
|
||||
$params['items'][] = [
|
||||
$this->languageService->sL($this->localLangPrefix . 'tx_femanager_domain_model_user.captcha'),
|
||||
'captcha'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add captcha option
|
||||
*
|
||||
* @param array $params
|
||||
*/
|
||||
protected function addStateOption(&$params)
|
||||
{
|
||||
if (ExtensionManagementUtility::isLoaded('static_info_tables')) {
|
||||
$params['items'][] = [
|
||||
$this->languageService->sL($this->localLangPrefix . 'tx_femanager_domain_model_user.state'),
|
||||
'state'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read pid from current URL
|
||||
* URL example:
|
||||
* http://femanager.localhost.de/typo3/alt_doc.php?&returnUrl=
|
||||
* %2Ftypo3%2Fsysext%2Fcms%2Flayout%2Fdb_layout.php
|
||||
* %3Fid%3D17%23element-tt_content-14
|
||||
* &edit[tt_content][14]=edit
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getPid()
|
||||
{
|
||||
$pid = 0;
|
||||
$backUrl = str_replace('?', '&', GeneralUtility::_GP('returnUrl'));
|
||||
$urlParts = GeneralUtility::trimExplode('&', $backUrl, true);
|
||||
foreach ($urlParts as $part) {
|
||||
if (stristr($part, 'id=')) {
|
||||
$pid = str_replace('id=', '', $part);
|
||||
}
|
||||
}
|
||||
|
||||
return (int)$pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.Superglobals)
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
$this->languageService = $GLOBALS['LANG'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\UserFunc;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Utility\ObjectUtility;
|
||||
use TYPO3\CMS\Core\Database\QueryGenerator;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class UserOptions
|
||||
*/
|
||||
class UserOptions
|
||||
{
|
||||
/**
|
||||
* Just add users from start point to selection
|
||||
*
|
||||
* @param array $params
|
||||
*/
|
||||
public function addOptions(&$params)
|
||||
{
|
||||
if ($this->getPages($params) !== []) {
|
||||
$params['items'] = [
|
||||
$params['items'][0], // please choose
|
||||
$params['items'][1] // currently logged in user
|
||||
];
|
||||
|
||||
foreach ($this->getUsers($params) as $user) {
|
||||
$params['items'][] = [$user['username'], $user['uid']];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
protected function getUsers(array $params): array
|
||||
{
|
||||
$queryBuilder = ObjectUtility::getQueryBuilder(User::TABLE_NAME);
|
||||
$result = $queryBuilder
|
||||
->select('uid', 'username')
|
||||
->from(User::TABLE_NAME)
|
||||
->where('pid in (' . $this->getPageUidList($params) . ')')
|
||||
->setMaxResults(10000)
|
||||
->orderBy('username', 'ASC')
|
||||
->execute();
|
||||
return $result->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lists of page uids where the users are stored with recursive setting
|
||||
*
|
||||
* @param array $params
|
||||
* @return string
|
||||
*/
|
||||
protected function getPageUidList(array $params): string
|
||||
{
|
||||
$list = '';
|
||||
$queryGenerator = GeneralUtility::makeInstance(QueryGenerator::class);
|
||||
$depth = $params['flexParentDatabaseRow']['recursive'];
|
||||
foreach ($this->getPages($params) as $pageIdentifier) {
|
||||
$list .= $queryGenerator->getTreeList($pageIdentifier, $depth, 0, 1);
|
||||
$list .= ',';
|
||||
}
|
||||
return rtrim($list, ',');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
protected function getPages(array $params): array
|
||||
{
|
||||
$pages = [];
|
||||
if (!empty($params['flexParentDatabaseRow']['pages'][0]['uid'])) {
|
||||
foreach ($params['flexParentDatabaseRow']['pages'] as $page) {
|
||||
$pages[] = $page['uid'];
|
||||
}
|
||||
}
|
||||
return $pages;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use Exception;
|
||||
use In2code\Femanager\Domain\Repository\UserGroupRepository;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException;
|
||||
use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException;
|
||||
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
/**
|
||||
* Class AbstractUtility
|
||||
*/
|
||||
abstract class AbstractUtility
|
||||
{
|
||||
/**
|
||||
* Get table configuration array for a defined table
|
||||
*
|
||||
* @param string $table
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.Superglobals)
|
||||
*/
|
||||
protected static function getTcaFromTable($table = 'fe_users'): array
|
||||
{
|
||||
$tca = [];
|
||||
if (!empty($GLOBALS['TCA'][$table])) {
|
||||
$tca = $GLOBALS['TCA'][$table];
|
||||
}
|
||||
return $tca;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ConnectionPool
|
||||
* @SuppressWarnings(PHPMD.Superglobals)
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getConnectionPool(): ConnectionPool
|
||||
{
|
||||
return GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.Superglobals)
|
||||
*/
|
||||
protected static function getFilesArray(): array
|
||||
{
|
||||
return (array)$_FILES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UserGroupRepository
|
||||
*/
|
||||
protected static function getUserGroupRepository(): UserGroupRepository
|
||||
{
|
||||
return GeneralUtility::makeInstance(UserGroupRepository::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TypoScriptFrontendController|null
|
||||
* @SuppressWarnings(PHPMD.Superglobals)
|
||||
*/
|
||||
protected static function getTypoScriptFrontendController()
|
||||
{
|
||||
return $GLOBALS['TSFE'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TYPO3 encryption key
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
* @SuppressWarnings(PHPMD.Superglobals)
|
||||
*/
|
||||
protected static function getEncryptionKey(): string
|
||||
{
|
||||
if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
|
||||
throw new \UnexpectedValueException('No encryption key found in this TYPO3 installation', 1516373945265);
|
||||
}
|
||||
return $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extension configuration from LocalConfiguration.php
|
||||
*
|
||||
* @return array
|
||||
* @throws ExtensionConfigurationExtensionNotConfiguredException
|
||||
* @throws ExtensionConfigurationPathDoesNotExistException
|
||||
*/
|
||||
protected static function getExtensionConfiguration(): array
|
||||
{
|
||||
return (array)GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('femanager');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ContentObjectRenderer
|
||||
* @throws Exception
|
||||
*/
|
||||
protected static function getContentObject(): ContentObjectRenderer
|
||||
{
|
||||
return GeneralUtility::makeInstance(ContentObjectRenderer::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ConfigurationManagerInterface
|
||||
* @codeCoverageIgnore
|
||||
* @throws Exception
|
||||
*/
|
||||
protected static function getConfigurationManager(): ConfigurationManagerInterface
|
||||
{
|
||||
return GeneralUtility::makeInstance(ConfigurationManagerInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BackendUserAuthentication
|
||||
* @SuppressWarnings(PHPMD.Superglobals)
|
||||
*/
|
||||
protected static function getBackendUserAuthentication()
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
|
||||
/**
|
||||
* Class BackendUserUtility
|
||||
*/
|
||||
class BackendUserUtility extends AbstractUtility
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function isAdminAuthentication()
|
||||
{
|
||||
$userAuthentication = self::getBackendUserAuthentication();
|
||||
|
||||
if ($userAuthentication->user['admin'] === 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$tsConfigEnableLoginAs = (int)($userAuthentication->getTSConfig()['tx_femanager.']['UserBackend.']['enableLoginAs'] ?? 0);
|
||||
|
||||
return $tsConfigEnableLoginAs === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BackendUserAuthentication
|
||||
*/
|
||||
public static function getBackendUserAuthentication()
|
||||
{
|
||||
return parent::getBackendUserAuthentication();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Core\Http\ApplicationType;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\MathUtility;
|
||||
use TYPO3\CMS\Core\Utility\RootlineUtility;
|
||||
|
||||
/**
|
||||
* Class BackendUtility
|
||||
*/
|
||||
class BackendUtility
|
||||
{
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public static function getPageIdentifier(): int
|
||||
{
|
||||
return (int)GeneralUtility::_GET('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URI to edit a record in backend
|
||||
*
|
||||
* @param string $tableName like "fe_users"
|
||||
* @param int $identifier record identifier to edit
|
||||
* @param bool $addReturnUrl add current URI as returnUrl
|
||||
* @return string
|
||||
*/
|
||||
public static function getBackendEditUri(string $tableName, int $identifier, bool $addReturnUrl = true): string
|
||||
{
|
||||
$uriParameters = [
|
||||
'edit' => [
|
||||
$tableName => [
|
||||
$identifier => 'edit'
|
||||
]
|
||||
]
|
||||
];
|
||||
if ($addReturnUrl) {
|
||||
$uriParameters['returnUrl'] = GeneralUtility::getIndpEnv('REQUEST_URI');
|
||||
}
|
||||
return (string)GeneralUtility::makeInstance(UriBuilder::class)
|
||||
->buildUriFromRoute('record_edit', $uriParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URI to create a new record in backend
|
||||
*
|
||||
* @param string $tableName like "fe_users"
|
||||
* @param int $pageIdentifier page identifier to store the new record in
|
||||
* @param bool $addReturnUrl add current URI as returnUrl
|
||||
* @return string
|
||||
*/
|
||||
public static function getBackendNewUri(string $tableName, int $pageIdentifier, bool $addReturnUrl = true): string
|
||||
{
|
||||
$uriParameters = [
|
||||
'edit' => [
|
||||
$tableName => [
|
||||
$pageIdentifier => 'new'
|
||||
]
|
||||
]
|
||||
];
|
||||
if ($addReturnUrl) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$uriParameters['returnUrl'] = GeneralUtility::getIndpEnv('REQUEST_URI');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
return (string)GeneralUtility::makeInstance(UriBuilder::class)
|
||||
->buildUriFromRoute('record_edit', $uriParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string "plugin" or "module"
|
||||
*/
|
||||
public static function getPluginOrModuleString(): string
|
||||
{
|
||||
$string = 'plugin';
|
||||
if (($GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface
|
||||
&& ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend()
|
||||
) {
|
||||
$string = 'module';
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all GET/POST params without module name and token
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function getCurrentParameters(): array
|
||||
{
|
||||
$parameters = [];
|
||||
$ignoreKeys = [
|
||||
'M',
|
||||
'moduleToken'
|
||||
];
|
||||
foreach ((array)GeneralUtility::_GET() as $key => $value) {
|
||||
if (in_array($key, $ignoreKeys)) {
|
||||
continue;
|
||||
}
|
||||
$parameters[$key] = $value;
|
||||
}
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $pageUid [optional] the current pageuid
|
||||
* @return array
|
||||
*/
|
||||
public static function loadTS($pageUid = null)
|
||||
{
|
||||
$pageUid = ($pageUid && MathUtility::canBeInterpretedAsInteger($pageUid)) ? $pageUid : GeneralUtility::_GP('id');
|
||||
$TSObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\TypoScript\\TemplateService');
|
||||
$TSObj->tt_track = 0;
|
||||
$TSObj->runThroughTemplates(GeneralUtility::makeInstance(RootlineUtility::class, $pageUid, '')->get());
|
||||
$TSObj->generateConfig();
|
||||
|
||||
return $TSObj->setup;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||
use TYPO3\CMS\Core\Utility\Exception\MissingArrayPathException;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
|
||||
/**
|
||||
* Class ConfigurationUtility
|
||||
*/
|
||||
class ConfigurationUtility extends AbstractUtility
|
||||
{
|
||||
const DEFAULT_CONFIGURATION = [
|
||||
'_TypoScriptIncluded' => 0,
|
||||
'_enable' => '',
|
||||
'_enable.' => [],
|
||||
'dataProcessors' => [],
|
||||
'edit./forceValues./beforeAnyConfirmation.' => [],
|
||||
'edit./redirect' => 'TEXT',
|
||||
'edit./redirect.' => [],
|
||||
'edit./requestRedirect' => 'TEXT',
|
||||
'edit./requestRedirect.' => [],
|
||||
'edit/fillEmailWithUsername' => '0',
|
||||
'edit/notifyAdmin' => '',
|
||||
'edit/email/notifyAdmin/receiver/email/value' => '',
|
||||
'edit/misc/passwordSave' => '',
|
||||
'invitation/misc/passwordSave' => '',
|
||||
'invitation./email./invitationAdminNotify.' => [],
|
||||
'invitation./email./invitationAdminNotifyStep1.' => [],
|
||||
'invitation./email./invitationRefused.' => [],
|
||||
'invitation./forceValues./beforeAnyConfirmation.' => [],
|
||||
'invitation./redirect' => 'TEXT',
|
||||
'invitation./redirect.' => [],
|
||||
'invitation./redirectDelete' => 'TEXT',
|
||||
'invitation./redirectDelete.' => [],
|
||||
'invitation./redirectStep1' => 'TEXT',
|
||||
'invitation./redirectStep1.' => [],
|
||||
'invitation./redirectPasswordChanged' => 'TEXT',
|
||||
'invitation./redirectPasswordChanged.' => [],
|
||||
'invitation./requestRedirect' => 'TEXT',
|
||||
'invitation./requestRedirect.' => [],
|
||||
'invitation/fillEmailWithUsername' => '0',
|
||||
'invitation/notifyAdmin' => 0,
|
||||
'invitation/email/invitationAdminNotify/receiver/name/value' => 'femanager',
|
||||
'invitation/email/invitationRefused/receiver/name/value' => 'femanager',
|
||||
'invitation/notifyAdminStep1' => 0,
|
||||
'invitation/email/invitationAdminNotifyStep1/receiver/name/value' => 'femanager',
|
||||
'new./adminConfirmationRedirect' => '',
|
||||
'new./email./createAdminConfirmation.' => [],
|
||||
'new./email./createAdminNotify.' => [],
|
||||
'new./email./createAdminNotify./receiver./email./value' => '',
|
||||
'new./email./createAdminNotify./subject' => 'TEXT',
|
||||
'new./email./createAdminNotify./subject.' => [],
|
||||
'new./email./createUserConfirmation.' => [],
|
||||
'new./email./createUserConfirmation./sender./email./value' => '',
|
||||
'new./email./createUserConfirmation./sender./name./value' => '',
|
||||
'new./email./createUserConfirmation./subject' => 'TEXT',
|
||||
'new./email./createUserConfirmation./subject.' => [],
|
||||
'new./email./createUserConfirmation./confirmUserConfirmation' => '0',
|
||||
'new./email./createUserConfirmation./confirmUserConfirmationRefused' => '0',
|
||||
'new./email./createUserConfirmation./confirmAdminConfirmation' => '0',
|
||||
'new./email./createUserNotify.' => [],
|
||||
'new./email./createUserNotify./sender./email./value' => '9999',
|
||||
'new./email./createUserNotify./sender./name./value' => '9999',
|
||||
'new./email./createUserNotify./subject' => 'TEXT',
|
||||
'new./email./createUserNotify./subject.' => [],
|
||||
'new./email./createUserNotifyRefused.' => [],
|
||||
'new./fillEmailWithUsername' => 0,
|
||||
'new./forceValues./beforeAnyConfirmation.' => [],
|
||||
'new./forceValues./onAdminConfirmation.' => [],
|
||||
'new./forceValues./onUserConfirmation.' => [],
|
||||
'new./login' => '0',
|
||||
'new./misc./passwordSave' => 0,
|
||||
'new./notifyAdmin' => '',
|
||||
'new./redirect' => 'TEXT',
|
||||
'new./redirect.' => [],
|
||||
'new./requestRedirect' => 'TEXT',
|
||||
'new./requestRedirect.' => [],
|
||||
'new./userConfirmationRedirect' => 'TEXT',
|
||||
'new./userConfirmationRedirect.' => [],
|
||||
'new/misc/passwordSave' => 0,
|
||||
'persistence./storagePid' => '0',
|
||||
'receiver./email' => 'TEXT',
|
||||
'receiver./email.' => [],
|
||||
'receiver./name' => 'TEXT',
|
||||
'receiver./name.' => [],
|
||||
'sender./email' => 'TEXT',
|
||||
'sender./email.' => [],
|
||||
'sender./name' => 'TEXT',
|
||||
'sender./name.' => [],
|
||||
'priority' => 'TEXT',
|
||||
'priority.' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function isDisableModuleActive(): bool
|
||||
{
|
||||
$configuration = self::getExtensionConfiguration();
|
||||
|
||||
return $configuration['disableModule'] === '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function isConfirmationModuleActive(): bool
|
||||
{
|
||||
$configuration = self::getExtensionConfiguration();
|
||||
|
||||
return $configuration['enableConfirmationModule'] === '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function isDisableLogActive(): bool
|
||||
{
|
||||
$configuration = self::getExtensionConfiguration();
|
||||
|
||||
return $configuration['disableLog'] === '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get complete Typoscript or only a special value by a given path
|
||||
*
|
||||
* @param string $path "misc.uploadFolder" or empty for complete TypoScript array
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getConfiguration(string $path = '')
|
||||
{
|
||||
$configurationManager = GeneralUtility::makeInstance(ConfigurationManagerInterface::class);
|
||||
$typoscript = $configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
|
||||
'Femanager',
|
||||
'Pi1'
|
||||
);
|
||||
if (!empty($path)) {
|
||||
$typoscript = ArrayUtility::getValueByPath($typoscript, $path, '.');
|
||||
}
|
||||
|
||||
return $typoscript;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function isBackendModuleFilterUserConfirmation(): bool
|
||||
{
|
||||
$config = BackendUserUtility::getBackendUserAuthentication()->getTSConfig(
|
||||
)['tx_femanager.']['UserBackend.']['confirmation.']['filter.']['userConfirmation'] ?? false;
|
||||
|
||||
return (bool)$config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function IsResendUserConfirmationRequestActive(): bool
|
||||
{
|
||||
$config = BackendUserUtility::getBackendUserAuthentication()->getTSConfig(
|
||||
)['tx_femanager.']['UserBackend.']['confirmation.']['ResendUserConfirmationRequest'] ?? false;
|
||||
return (bool)$config;
|
||||
}
|
||||
|
||||
public static function IsCreateUserNotifyActive($config): bool
|
||||
{
|
||||
if (ConfigurationUtility::getValue(
|
||||
'new/email/createUserNotify/sender/email/value',
|
||||
$config
|
||||
) && ConfigurationUtility::getValue(
|
||||
'new./email./createUserNotify./sender./name./value',
|
||||
$config
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getDefaultConfiguration($key)
|
||||
{
|
||||
return self::DEFAULT_CONFIGURATION[$key] ?? null;
|
||||
}
|
||||
|
||||
public static function getValue($key, $config)
|
||||
{
|
||||
try {
|
||||
return ArrayUtility::getValueByPath($config, $key);
|
||||
} catch (MissingArrayPathException $ex) {
|
||||
return self::getDefaultConfiguration($key);
|
||||
}
|
||||
}
|
||||
|
||||
public static function notifyAdminAboutEdits($settings)
|
||||
{
|
||||
return self::getValue('edit/email/notifyAdmin/_enable/value', $settings)
|
||||
&& (
|
||||
self::getValue('edit/email/notifyAdmin/receiver/email/value', $settings)
|
||||
|| self::getValue('edit/notifyAdmin', $settings)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
|
||||
/**
|
||||
* Class FileUtility
|
||||
*/
|
||||
class FileUtility extends AbstractUtility
|
||||
{
|
||||
/**
|
||||
* @param string $path Absolute path
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function createFolderIfNotExists(string $path)
|
||||
{
|
||||
if (!is_dir($path) && !GeneralUtility::mkdir($path)) {
|
||||
throw new \UnexpectedValueException(
|
||||
'Folder ' . self::getRelativeFolderFromAbsolutePath($path) . ' does not exists and can not be created!',
|
||||
1516373962125
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get relative path from absolute path, but don't touch if it's already a relative path
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public static function getRelativeFolderFromAbsolutePath(string $path): string
|
||||
{
|
||||
if (PathUtility::isAbsolutePath($path)) {
|
||||
$path = PathUtility::getRelativePathTo($path);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Model\UserGroup;
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class FrontendUtility
|
||||
*/
|
||||
class FrontendUtility extends AbstractUtility
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $pluginNames = [
|
||||
'tx_femanager_pi1',
|
||||
'tx_femanager_pi2'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get current pid
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getCurrentPid(): int
|
||||
{
|
||||
return (int)self::getTypoScriptFrontendController()->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get frontend language uid
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getFrontendLanguageUid(): int
|
||||
{
|
||||
$languageUid = 0;
|
||||
$languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');
|
||||
$languageUid = $languageAspect->getId();
|
||||
return $languageUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getCharset(): string
|
||||
{
|
||||
return self::getTypoScriptFrontendController()->metaCharset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getUriToCurrentPage(): string
|
||||
{
|
||||
$contentObject = ObjectUtility::getContentObject();
|
||||
$configuration = [
|
||||
'parameter' => self::getCurrentPid()
|
||||
];
|
||||
return $contentObject->typoLink_URL($configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set object properties from forceValues in TypoScript
|
||||
*
|
||||
* @param User $user
|
||||
* @param array $settings
|
||||
* @return User $object
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function forceValues(User $user, array $settings)
|
||||
{
|
||||
foreach ((array)$settings as $field => $config) {
|
||||
$config = null;
|
||||
if (stristr($field, '.')) {
|
||||
continue;
|
||||
}
|
||||
// value to set
|
||||
$value = self::getContentObject()->cObjGetSingle($settings[$field], $settings[$field . '.']);
|
||||
self::forceValue($user, $field, $value);
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set single object property from forceValues in TypoScript
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $field
|
||||
* @param any $value
|
||||
*/
|
||||
public static function forceValue(User $user, string $field, $value): void
|
||||
{
|
||||
if ($field === 'usergroup') {
|
||||
// need objectstorage for usergroup field
|
||||
$user->removeAllUsergroups();
|
||||
$values = GeneralUtility::trimExplode(',', $value, true);
|
||||
$userGroupRepository = self::getUserGroupRepository();
|
||||
|
||||
foreach ($values as $usergroupUid) {
|
||||
/** @var UserGroup $usergroup */
|
||||
$usergroup = $userGroupRepository->findByUid($usergroupUid);
|
||||
$user->addUsergroup($usergroup);
|
||||
}
|
||||
} else {
|
||||
// set value
|
||||
$setterMethod = 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $field)));
|
||||
if (method_exists($user, $setterMethod)) {
|
||||
$user->{$setterMethod}($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getControllerName(): string
|
||||
{
|
||||
$controllerName = '';
|
||||
foreach (self::$pluginNames as $pluginName) {
|
||||
$variables = GeneralUtility::_GPmerged($pluginName);
|
||||
if (!empty($variables['controller'])) {
|
||||
$controllerName = $variables['controller'];
|
||||
}
|
||||
}
|
||||
return $controllerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getActionName(): string
|
||||
{
|
||||
$actionName = '';
|
||||
foreach (self::$pluginNames as $pluginName) {
|
||||
$variables = GeneralUtility::_GPmerged($pluginName);
|
||||
if (!empty($variables['action'])) {
|
||||
$actionName = $variables['action'];
|
||||
}
|
||||
}
|
||||
return $actionName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
|
||||
/**
|
||||
* Class HashUtility
|
||||
*/
|
||||
class HashUtility extends AbstractUtility
|
||||
{
|
||||
/**
|
||||
* Check if given hash is correct
|
||||
*
|
||||
* @param string $hash
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public static function validHash(string $hash, User $user, string $suffix = '')
|
||||
{
|
||||
return self::createHashForUser($user, $suffix) === $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create hash for a user
|
||||
*
|
||||
* @param User $user
|
||||
* @return string
|
||||
*/
|
||||
public static function createHashForUser(User $user, string $suffix = '')
|
||||
{
|
||||
return self::hashString($user->getUsername() . $suffix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Hash from String and TYPO3 Encryption Key (if available)
|
||||
*
|
||||
* @param string $string Any String to hash
|
||||
* @param int $length Hash Length
|
||||
* @return string $hash Hashed String
|
||||
*/
|
||||
protected static function hashString($string, $length = 16)
|
||||
{
|
||||
return substr(md5($string . self::getEncryptionKey()), 0, $length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility as ExtbaseLocalizationUtility;
|
||||
|
||||
/**
|
||||
* Class LocalizationUtility
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class LocalizationUtility
|
||||
{
|
||||
/**
|
||||
* Returns the localized label of the LOCAL_LANG key, but prefill extensionName
|
||||
*
|
||||
* @param string $key The key from the LOCAL_LANG array for which to return the value.
|
||||
* @param string $extensionName The name of the extension
|
||||
* @param array $arguments the arguments of the extension, being passed over to vsprintf
|
||||
* @return string|null
|
||||
*/
|
||||
public static function translate($key, $extensionName = 'femanager', $arguments = null)
|
||||
{
|
||||
return ExtbaseLocalizationUtility::translate($key, $extensionName, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get locallang translation with key prefix tx_femanager_domain_model_log.state.
|
||||
*
|
||||
* @param int $state
|
||||
* @return string|null
|
||||
*/
|
||||
public static function translateByState($state)
|
||||
{
|
||||
return self::translate('tx_femanager_domain_model_log.state.' . $state);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Repository\LogRepository;
|
||||
use In2code\Femanager\Event\UserLogEvent;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class LogUtility
|
||||
*/
|
||||
class LogUtility
|
||||
{
|
||||
/**
|
||||
* @var LogRepository
|
||||
*/
|
||||
private $logRepository;
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
private $eventDispatcher;
|
||||
|
||||
public function __construct(LogRepository $logRepository, EventDispatcherInterface $eventDispatcher)
|
||||
{
|
||||
$this->logRepository = $logRepository;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $state State to log
|
||||
* @param User $user Related User
|
||||
* @param array $additionalProperties for individual logging
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function log($state, User $user, array $additionalProperties = [])
|
||||
{
|
||||
if (!ConfigurationUtility::isDisableLogActive()) {
|
||||
$log = GeneralUtility::makeInstance(Log::class);
|
||||
$log->setTitle(LocalizationUtility::translateByState($state));
|
||||
$log->setState($state);
|
||||
$log->setUser($user);
|
||||
$this->logRepository->add($log);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(new UserLogEvent($user, $state, $additionalProperties));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
use TYPO3\CMS\Extbase\Reflection\Exception\PropertyNotAccessibleException;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class ObjectUtility
|
||||
*/
|
||||
class ObjectUtility extends AbstractUtility
|
||||
{
|
||||
/**
|
||||
* @param string $tableName
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
public static function getQueryBuilder(string $tableName): QueryBuilder
|
||||
{
|
||||
return GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ContentObjectRenderer
|
||||
*/
|
||||
public static function getContentObject(): ContentObjectRenderer
|
||||
{
|
||||
return GeneralUtility::makeInstance(ContentObjectRenderer::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if object was changed or not
|
||||
*
|
||||
* @param object $object
|
||||
* @return bool
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function isDirtyObject($object): bool
|
||||
{
|
||||
foreach (array_keys($object->_getProperties()) as $propertyName) {
|
||||
try {
|
||||
$property = ObjectAccess::getProperty($object, $propertyName);
|
||||
} catch (PropertyNotAccessibleException $e) {
|
||||
// if property can not be accessed
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* std::Property (string, int, etc..),
|
||||
* PHP-Objects (DateTime, RecursiveIterator, etc...),
|
||||
* TYPO3-Objects (user, page, etc...)
|
||||
*/
|
||||
if (!$property instanceof ObjectStorage) {
|
||||
if ($object->_isDirty($propertyName)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* ObjectStorage
|
||||
*/
|
||||
if ($property->_isDirty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implode subjobjects on a property (example for usergroups: "ug1, ug2, ug3")
|
||||
*
|
||||
* @param ObjectStorage $objectStorage
|
||||
* @param string $property
|
||||
* @param string $glue
|
||||
* @return string
|
||||
*/
|
||||
public static function implodeObjectStorageOnProperty(
|
||||
ObjectStorage $objectStorage,
|
||||
string $property = 'uid',
|
||||
string $glue = ', '
|
||||
): string {
|
||||
$values = [];
|
||||
if (!empty($objectStorage)) {
|
||||
foreach ($objectStorage as $object) {
|
||||
try {
|
||||
$values[] = ObjectAccess::getProperty($object, $property);
|
||||
} catch (\Exception $exception) {
|
||||
unset($exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
return implode($glue, $values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Class StringUtility
|
||||
*/
|
||||
class StringUtility extends AbstractUtility
|
||||
{
|
||||
/**
|
||||
* Only allowed a-z, A-Z, 0-9, -, .
|
||||
* Others will be replaced
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $replace
|
||||
* @return string
|
||||
*/
|
||||
public static function cleanString($filename, $replace = '_')
|
||||
{
|
||||
return preg_replace('/[^a-zA-Z0-9-\.]/', $replace, trim($filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read values between brackets
|
||||
*
|
||||
* test(1,2,3) => 1,2,3
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function getValuesInBrackets($value)
|
||||
{
|
||||
preg_match_all('/\(.*?\)/i', $value, $result);
|
||||
return str_replace(['(', ')'], '', $result[0][0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read values before brackets
|
||||
*
|
||||
* test(1,2,3) => test
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function getValuesBeforeBrackets($value)
|
||||
{
|
||||
$valueParts = GeneralUtility::trimExplode('(', $value, true);
|
||||
return $valueParts[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if string starts with another string
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string $needle
|
||||
* @return bool
|
||||
*/
|
||||
public static function startsWith($haystack, $needle)
|
||||
{
|
||||
return stristr($haystack, $needle) && strrpos($haystack, $needle, -strlen($haystack)) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if string ends with another string
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string $needle
|
||||
* @return string
|
||||
*/
|
||||
public static function endsWith($haystack, $needle)
|
||||
{
|
||||
return stristr($haystack, $needle) && strlen($haystack) - strlen($needle) === strpos($haystack, $needle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create array for swiftmailer
|
||||
* sender and receiver mail/name combination with fallback
|
||||
*
|
||||
* @param string $emailString String with separated emails (splitted by \n)
|
||||
* @param string $name Name for every email name combination
|
||||
* @return array $mailArray
|
||||
*/
|
||||
public static function makeEmailArray($emailString, $name = 'femanager')
|
||||
{
|
||||
$emails = GeneralUtility::trimExplode(PHP_EOL, $emailString, true);
|
||||
$mailArray = [];
|
||||
foreach ($emails as $email) {
|
||||
if (GeneralUtility::validEmail($email)) {
|
||||
$mailArray[$email] = $name;
|
||||
}
|
||||
}
|
||||
return $mailArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* createRandomFileName
|
||||
*
|
||||
* @param int $length
|
||||
* @param bool $addUpperCase
|
||||
* @param bool $addSpecialCharacters
|
||||
* @return string
|
||||
*/
|
||||
public static function getRandomString($length = 32, $addUpperCase = true, $addSpecialCharacters = true)
|
||||
{
|
||||
$characters = self::getNumbersString() . self::getCharactersString();
|
||||
if ($addUpperCase) {
|
||||
$characters .= self::getUpperCharactersString();
|
||||
}
|
||||
if ($addSpecialCharacters) {
|
||||
$characters .= '#+*&%$§()[]{}!.:-_,;';
|
||||
}
|
||||
$string = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$key = mt_rand(0, strlen($characters) - 1);
|
||||
$string .= $characters[$key];
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string "0123456789"
|
||||
*/
|
||||
public static function getNumbersString()
|
||||
{
|
||||
return implode('', range(0, 9));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string "abcdefghijklmnopqrstuvwxyz"
|
||||
*/
|
||||
public static function getCharactersString()
|
||||
{
|
||||
return implode('', range('a', 'z'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
*/
|
||||
public static function getUpperCharactersString()
|
||||
{
|
||||
return implode('', range('A', 'Z'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove double slashes from URI but don't touch the protocol (http:// e.g.)
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public static function removeDoubleSlashesFromUri($string)
|
||||
{
|
||||
return preg_replace('~([^:]|^)(/{2,})~', '$1/', $string);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
|
||||
/**
|
||||
* Class TemplateUtility
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class TemplateUtility extends AbstractUtility
|
||||
{
|
||||
/**
|
||||
* Get absolute path for templates with fallback
|
||||
* In case of multiple paths this will just return the first one.
|
||||
* See getTemplateFolders() for an array of paths.
|
||||
*
|
||||
* @param string $part "template", "partial", "layout"
|
||||
* @return string
|
||||
* @see getTemplateFolders()
|
||||
*/
|
||||
public static function getTemplateFolder($part = 'template')
|
||||
{
|
||||
$matches = self::getTemplateFolders($part);
|
||||
return !empty($matches) ? $matches[0] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get absolute paths for templates with fallback
|
||||
* Returns paths from *RootPaths and *RootPath and "hardcoded"
|
||||
* paths pointing to the EXT:femanager-resources.
|
||||
*
|
||||
* @param string $part "template", "partial", "layout"
|
||||
* @param bool $returnAllPaths Default: FALSE, If FALSE only paths
|
||||
* for the first configuration (Paths, Path, hardcoded)
|
||||
* will be returned. If TRUE all (possible) paths will be returned.
|
||||
* @return array
|
||||
*/
|
||||
public static function getTemplateFolders($part = 'template', $returnAllPaths = false)
|
||||
{
|
||||
$templatePaths = [];
|
||||
$configuration = self::getConfigurationManager()
|
||||
->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, 'femanager');
|
||||
if (!empty($configuration['view'][$part . 'RootPaths'] ?? '')) {
|
||||
$templatePaths = $configuration['view'][$part . 'RootPaths'] ?? '';
|
||||
$templatePaths = array_values($templatePaths);
|
||||
}
|
||||
if ($returnAllPaths || empty($templatePaths)) {
|
||||
$path = $configuration['view'][$part . 'RootPath'] ?? '';
|
||||
if (!empty($path)) {
|
||||
$templatePaths[] = $path;
|
||||
}
|
||||
}
|
||||
if ($returnAllPaths || empty($templatePaths)) {
|
||||
$templatePaths[] = 'EXT:femanager/Resources/Private/' . ucfirst($part) . 's/';
|
||||
}
|
||||
$templatePaths = array_unique($templatePaths);
|
||||
$absolutePaths = [];
|
||||
foreach ($templatePaths as $templatePath) {
|
||||
$absolutePaths[] = GeneralUtility::getFileAbsFileName($templatePath);
|
||||
}
|
||||
return $absolutePaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return path and filename for a file or path.
|
||||
* Only the first existing file/path will be returned.
|
||||
* respect *RootPaths and *RootPath
|
||||
*
|
||||
* @param string $pathAndFilename e.g. Email/Name.html
|
||||
* @param string $part "template", "partial", "layout"
|
||||
* @return string Filename/path
|
||||
*/
|
||||
public static function getTemplatePath($pathAndFilename, $part = 'template')
|
||||
{
|
||||
$matches = self::getTemplatePaths($pathAndFilename, $part);
|
||||
return !empty($matches) ? end($matches) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return path and filename for one or many files/paths.
|
||||
* Only existing files/paths will be returned.
|
||||
* respect *RootPaths and *RootPath
|
||||
*
|
||||
* @param string $pathAndFilename Path/filename (Email/Name.html) or path
|
||||
* @param string $part "template", "partial", "layout"
|
||||
* @return array All existing matches found
|
||||
*/
|
||||
public static function getTemplatePaths($pathAndFilename, $part = 'template')
|
||||
{
|
||||
$pathAndFilenames = [];
|
||||
$absolutePaths = self::getTemplateFolders($part, true);
|
||||
foreach ($absolutePaths as $absolutePath) {
|
||||
if (file_exists($absolutePath . $pathAndFilename)) {
|
||||
$pathAndFilenames[] = $absolutePath . $pathAndFilename;
|
||||
}
|
||||
}
|
||||
return $pathAndFilenames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get standaloneview with default properties
|
||||
*
|
||||
* @param string $controllerName
|
||||
* @param string $extensionName
|
||||
* @param string $pluginName
|
||||
* @param string $format
|
||||
* @return StandaloneView
|
||||
*/
|
||||
public static function getDefaultStandAloneView(
|
||||
$controllerName = 'New',
|
||||
$extensionName = 'Femanager',
|
||||
$pluginName = 'Pi1',
|
||||
$format = 'html'
|
||||
) {
|
||||
/** @var StandaloneView $standAloneView */
|
||||
$standAloneView = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$standAloneView->getRequest()->setControllerExtensionName($extensionName);
|
||||
$standAloneView->getRequest()->setPluginName($pluginName);
|
||||
$standAloneView->getRequest()->setControllerName($controllerName);
|
||||
$standAloneView->setFormat($format);
|
||||
$standAloneView->setLayoutRootPaths(TemplateUtility::getTemplateFolders('layout'));
|
||||
$standAloneView->setPartialRootPaths(TemplateUtility::getTemplateFolders('partial'));
|
||||
return $standAloneView;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,362 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Utility;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Model\UserGroup;
|
||||
use In2code\Femanager\Domain\Repository\UserRepository;
|
||||
use TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash;
|
||||
use TYPO3\CMS\Core\Crypto\PasswordHashing\BcryptPasswordHash;
|
||||
use TYPO3\CMS\Core\Crypto\PasswordHashing\BlowfishPasswordHash;
|
||||
use TYPO3\CMS\Core\Crypto\PasswordHashing\InvalidPasswordHashException;
|
||||
use TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash;
|
||||
use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory;
|
||||
use TYPO3\CMS\Core\Crypto\PasswordHashing\Pbkdf2PasswordHash;
|
||||
use TYPO3\CMS\Core\Crypto\PasswordHashing\PhpassPasswordHash;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
|
||||
/**
|
||||
* Class UserUtility
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class UserUtility extends AbstractUtility
|
||||
{
|
||||
/**
|
||||
* Return current logged in fe_user
|
||||
*
|
||||
* @return User|null
|
||||
*/
|
||||
public static function getCurrentUser()
|
||||
{
|
||||
if (self::getPropertyFromUser() !== null) {
|
||||
$userRepository = GeneralUtility::makeInstance(UserRepository::class);
|
||||
|
||||
return $userRepository->findByUid((int)self::getPropertyFromUser());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property from current logged in Frontend User
|
||||
*
|
||||
* @param string $propertyName
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getPropertyFromUser($propertyName = 'uid')
|
||||
{
|
||||
if (!empty(self::getTypoScriptFrontendController()->fe_user->user[$propertyName])) {
|
||||
return self::getTypoScriptFrontendController()->fe_user->user[$propertyName];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Usergroups from current logged in user
|
||||
*
|
||||
* array(
|
||||
* 1,
|
||||
* 5,
|
||||
* 7
|
||||
* )
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getCurrentUsergroupUids()
|
||||
{
|
||||
$currentLoggedInUser = self::getCurrentUser();
|
||||
$usergroupUids = [];
|
||||
if ($currentLoggedInUser !== null) {
|
||||
foreach ($currentLoggedInUser->getUsergroup() as $usergroup) {
|
||||
$usergroupUids[] = $usergroup->getUid();
|
||||
}
|
||||
}
|
||||
|
||||
return $usergroupUids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autogenerate username and password if it's empty
|
||||
*
|
||||
* @param User $user
|
||||
* @return User $user
|
||||
*/
|
||||
public static function fallbackUsernameAndPassword(User $user)
|
||||
{
|
||||
$settings = self::getConfigurationManager()->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
|
||||
'Femanager',
|
||||
'Pi1'
|
||||
);
|
||||
|
||||
if (isset($settings['new']['misc']['autogenerate'])) {
|
||||
$autogenerateSettings = $settings['new']['misc']['autogenerate'];
|
||||
|
||||
if (!$user->getUsername()) {
|
||||
$user->setUsername(
|
||||
StringUtility::getRandomString(
|
||||
$autogenerateSettings['username']['length'],
|
||||
$autogenerateSettings['username']['addUpperCase'],
|
||||
$autogenerateSettings['username']['addSpecialCharacters']
|
||||
)
|
||||
);
|
||||
if ($user->getEmail()) {
|
||||
$user->setUsername($user->getEmail());
|
||||
}
|
||||
}
|
||||
if (!$user->getPassword()) {
|
||||
$password = StringUtility::getRandomString(
|
||||
$autogenerateSettings['password']['length'],
|
||||
$autogenerateSettings['password']['addUpperCase'],
|
||||
$autogenerateSettings['password']['addSpecialCharacters']
|
||||
);
|
||||
$user->setPassword($password);
|
||||
$user->setPasswordAutoGenerated($password);
|
||||
}
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param array $settings
|
||||
* @return User
|
||||
*/
|
||||
public static function takeEmailAsUsername(User $user, array $settings)
|
||||
{
|
||||
if (ConfigurationUtility::getValue('new/fillEmailWithUsername', $settings) === '1') {
|
||||
$user->setEmail($user->getUsername());
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite usergroups from user by flexform settings
|
||||
*
|
||||
* @param User $user
|
||||
* @param array $settings
|
||||
* @param string $controllerName
|
||||
* @return User $object
|
||||
*/
|
||||
public static function overrideUserGroup(User $user, $settings, $controllerName = 'new')
|
||||
{
|
||||
if (!empty($settings[$controllerName]['overrideUserGroup'])) {
|
||||
$user->removeAllUsergroups();
|
||||
$usergroupUids = GeneralUtility::trimExplode(',', $settings[$controllerName]['overrideUserGroup'], true);
|
||||
foreach ($usergroupUids as $usergroupUid) {
|
||||
/** @var UserGroup $usergroup */
|
||||
$usergroup = self::getUserGroupRepository()->findByUid($usergroupUid);
|
||||
$user->addUsergroup($usergroup);
|
||||
}
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert password to Argon2i, Bcrypt, Pbkdf2, Phpass, Blowfish or Md5 hash
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $method
|
||||
* @throws InvalidPasswordHashException
|
||||
*/
|
||||
public static function convertPassword(User $user, $method)
|
||||
{
|
||||
if (array_key_exists('password', UserUtility::getDirtyPropertiesFromUser($user))) {
|
||||
self::hashPassword($user, $method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash a password from $user->getPassword()
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $method "Argon2i", "Bcrypt", "Pbkdf2", "Phpass", "Blowfish", "md5" or "none" ("sha1" for TYPO3 V8)
|
||||
* @throws InvalidPasswordHashException
|
||||
*/
|
||||
public static function hashPassword(User &$user, $method)
|
||||
{
|
||||
$hashInstance = false;
|
||||
$saltedHashPassword = $user->getPassword();
|
||||
/** @var PasswordHashFactory $passwordHashFactory */
|
||||
$passwordHashFactory = GeneralUtility::makeInstance(PasswordHashFactory::class);
|
||||
switch ($method) {
|
||||
case 'Argon2i':
|
||||
$hashInstance = GeneralUtility::makeInstance(Argon2iPasswordHash::class);
|
||||
break;
|
||||
|
||||
case 'Bcrypt':
|
||||
$hashInstance = GeneralUtility::makeInstance(BcryptPasswordHash::class);
|
||||
break;
|
||||
|
||||
case 'Pbkdf2':
|
||||
$hashInstance = GeneralUtility::makeInstance(Pbkdf2PasswordHash::class);
|
||||
break;
|
||||
|
||||
case 'Phpass':
|
||||
$hashInstance = GeneralUtility::makeInstance(PhpassPasswordHash::class);
|
||||
break;
|
||||
|
||||
case 'Blowfish':
|
||||
$hashInstance = GeneralUtility::makeInstance(BlowfishPasswordHash::class);
|
||||
break;
|
||||
|
||||
case 'md5':
|
||||
$hashInstance = GeneralUtility::makeInstance(Md5PasswordHash::class);
|
||||
break;
|
||||
case 'none':
|
||||
break;
|
||||
|
||||
default:
|
||||
$hashInstance = $passwordHashFactory->getDefaultHashInstance(TYPO3_MODE);
|
||||
}
|
||||
|
||||
if ($hashInstance === false) {
|
||||
$user->setPassword($saltedHashPassword);
|
||||
} else {
|
||||
$user->setPassword($hashInstance->getHashedPassword($saltedHashPassword));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get changed properties (compare two objects with same getter methods)
|
||||
*
|
||||
* @param User $changedObject
|
||||
* @return array
|
||||
* [firstName][old] = Alex
|
||||
* [firstName][new] = Alexander
|
||||
*/
|
||||
public static function getDirtyPropertiesFromUser(User $changedObject)
|
||||
{
|
||||
$dirtyProperties = [];
|
||||
$ignoreProperties = [
|
||||
'txFemanagerChangerequest',
|
||||
'ignoreDirty',
|
||||
'isOnline',
|
||||
'lastlogin'
|
||||
];
|
||||
|
||||
foreach ($changedObject->_getCleanProperties() as $propertyName => $oldPropertyValue) {
|
||||
if (method_exists($changedObject, 'get' . ucfirst($propertyName))
|
||||
&& !in_array($propertyName, $ignoreProperties)
|
||||
) {
|
||||
$newPropertyValue = $changedObject->{'get' . ucfirst($propertyName)}();
|
||||
if (!is_object($oldPropertyValue) || !is_object($newPropertyValue)) {
|
||||
if ($oldPropertyValue !== $newPropertyValue) {
|
||||
$dirtyProperties[$propertyName]['old'] = $oldPropertyValue;
|
||||
$dirtyProperties[$propertyName]['new'] = $newPropertyValue;
|
||||
}
|
||||
} else {
|
||||
if (get_class($oldPropertyValue) === 'DateTime') {
|
||||
/** @var $oldPropertyValue \DateTime */
|
||||
/** @var $newPropertyValue \DateTime */
|
||||
if ($oldPropertyValue->getTimestamp() !== $newPropertyValue->getTimestamp()) {
|
||||
$dirtyProperties[$propertyName]['old'] = $oldPropertyValue->getTimestamp();
|
||||
$dirtyProperties[$propertyName]['new'] = $newPropertyValue->getTimestamp();
|
||||
}
|
||||
} elseif (get_class($oldPropertyValue) === ObjectStorage::class) {
|
||||
$titlesOld = ObjectUtility::implodeObjectStorageOnProperty($oldPropertyValue);
|
||||
$titlesNew = ObjectUtility::implodeObjectStorageOnProperty($newPropertyValue);
|
||||
if ($titlesOld !== $titlesNew) {
|
||||
$dirtyProperties[$propertyName]['old'] = $titlesOld;
|
||||
$dirtyProperties[$propertyName]['new'] = $titlesNew;
|
||||
}
|
||||
} else {
|
||||
$uidOld = ObjectAccess::getProperty($oldPropertyValue, 'uid');
|
||||
$uidNew = ObjectAccess::getProperty($newPropertyValue, 'uid');
|
||||
if ($uidOld !== $uidNew) {
|
||||
$dirtyProperties[$propertyName]['old'] = $uidOld;
|
||||
$dirtyProperties[$propertyName]['new'] = $uidNew;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dirtyProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* overwrite user with old values and xml with new values
|
||||
*
|
||||
* @param User $user
|
||||
* @param array $dirtyProperties
|
||||
* @return User $user
|
||||
*/
|
||||
public static function rollbackUserWithChangeRequest($user, $dirtyProperties)
|
||||
{
|
||||
$existingProperties = $user->_getCleanProperties();
|
||||
|
||||
// reset old values
|
||||
$user->setUserGroup($existingProperties['usergroup']);
|
||||
foreach ($dirtyProperties as $propertyName => $propertyValue) {
|
||||
$propertyValue = null;
|
||||
$user->{'set' . ucfirst($propertyName)}($existingProperties[$propertyName]);
|
||||
}
|
||||
|
||||
// store changes as xml in field fe_users.tx_femanager_changerequest
|
||||
$user->setTxFemanagerChangerequest(GeneralUtility::array2xml($dirtyProperties, '', 0, 'changes'));
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove FE Session to a given user
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public static function removeFrontendSessionToUser(User $user)
|
||||
{
|
||||
self::getConnectionPool()->getConnectionForTable('fe_sessions')->delete(
|
||||
'fe_sessions',
|
||||
['ses_userid' => (int)$user->getUid()]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if FE Session exists
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkFrontendSessionToUser(User $user)
|
||||
{
|
||||
$queryBuilder = self::getConnectionPool()->getQueryBuilderForTable('fe_sessions');
|
||||
|
||||
$row = $queryBuilder->select('ses_id')
|
||||
->from('fe_sessions')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('ses_userid', (int)$user->getUid())
|
||||
)
|
||||
->execute()
|
||||
->fetch();
|
||||
|
||||
return !empty($row['ses_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Login FE-User
|
||||
*
|
||||
* @param User $user
|
||||
* @param string|null $storagePids
|
||||
*/
|
||||
public static function login(User $user, $storagePids = null)
|
||||
{
|
||||
// ensure a session cookie is set (in case there is no session yet)
|
||||
$GLOBALS['TSFE']->fe_user->setAndSaveSessionData('dummy', true);
|
||||
// create the session (destroys all existing session data in the session backend!)
|
||||
$GLOBALS['TSFE']->fe_user->createUserSession(['uid' => (int)$user->getUid()]);
|
||||
// re-fetch the session from the database so that the internal 'userSession' property of TSFE gets updated
|
||||
$GLOBALS['TSFE']->fe_user->fetchUserSession();
|
||||
// write the session data again to the session backend; preserves what was there before!!
|
||||
$GLOBALS['TSFE']->fe_user->setAndSaveSessionData('dummy', true);
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\ViewHelpers\Be;
|
||||
|
||||
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception as FluidViewHelperException;
|
||||
|
||||
/**
|
||||
* Class GetClassNameOnActionViewHelper
|
||||
*/
|
||||
class GetClassNameOnActionViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* Return className if actionName fits to current action
|
||||
*
|
||||
* @return string
|
||||
* @throws FluidViewHelperException
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
$actionName = $this->arguments['actionName'];
|
||||
$className = $this->arguments['className'];
|
||||
$fallbackClassName = $this->arguments['fallbackClassName'];
|
||||
|
||||
if ($this->getCurrentActionName() === $actionName) {
|
||||
return $className;
|
||||
}
|
||||
|
||||
return $fallbackClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current action name from the controller context
|
||||
*
|
||||
* @return string
|
||||
* @throws FluidViewHelperException
|
||||
*/
|
||||
protected function getCurrentActionName(): string
|
||||
{
|
||||
if (! $this->renderingContext instanceof RenderingContext) {
|
||||
throw new FluidViewHelperException(
|
||||
'Something went wrong; RenderingContext should be available in ViewHelper',
|
||||
1638341674
|
||||
);
|
||||
}
|
||||
return $this->renderingContext->getRequest()->getControllerActionName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all arguments for this viewhelper
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('actionName', 'string', 'action name to compare with current action', true);
|
||||
$this->registerArgument('className', 'string', 'classname that should be returned if action fits', false, ' btn-info');
|
||||
$this->registerArgument('fallbackClassName', 'string', 'fallback classname if action does not fit', false, '');
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\ViewHelpers\Be;
|
||||
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Class IsConfirmationModuleActivatedViewHelper
|
||||
*/
|
||||
class IsConfirmationModuleActivatedViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function render(): bool
|
||||
{
|
||||
return ConfigurationUtility::isConfirmationModuleActive();
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\ViewHelpers\Be;
|
||||
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Class IsConfirmationModuleActivatedViewHelper
|
||||
*/
|
||||
class IsResendUserConfirmationRequestActivatedViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function render(): bool
|
||||
{
|
||||
return ConfigurationUtility::IsResendUserConfirmationRequestActive();
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\ViewHelpers\Condition;
|
||||
|
||||
use In2code\Femanager\Utility\BackendUserUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Class IsBackendAdministratorAuthenticationViewHelper
|
||||
*/
|
||||
class IsBackendAdministratorAuthenticationViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* Check if a backenduser-administrator is logged in
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return BackendUserUtility::isAdminAuthentication();
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\ViewHelpers\Form;
|
||||
|
||||
use SJBR\StaticInfoTables\Domain\Repository\CountryRepository;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Class GetCountriesFromStaticInfoTablesViewHelper
|
||||
*/
|
||||
class GetCountriesFromStaticInfoTablesViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* @var CountryRepository
|
||||
*/
|
||||
protected $countryRepository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (ExtensionManagementUtility::isLoaded('static_info_tables')) {
|
||||
$this->countryRepository = GeneralUtility::makeInstance(CountryRepository::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an country array
|
||||
*
|
||||
* @param string $sorting
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
if (null === $this->countryRepository) {
|
||||
return ['ERROR: static_info_tables is not loaded'];
|
||||
}
|
||||
$key = $this->arguments['key'];
|
||||
$value = $this->arguments['value'];
|
||||
$sortbyField = $this->arguments['sortbyField'];
|
||||
$sorting = $this->arguments['sorting'];
|
||||
|
||||
$countries = $this->countryRepository->findAllOrderedBy($sortbyField, $sorting);
|
||||
$countriesArray = [];
|
||||
if ($this->arguments['preferredCountries']) {
|
||||
foreach ($this->countryRepository->findAllowedByIsoCodeA3($this->arguments['preferredCountries']) as $country) {
|
||||
$countriesArray[ObjectAccess::getProperty($country, $key)] = ObjectAccess::getProperty($country, $value);
|
||||
}
|
||||
$countriesArray['---'] = '---';
|
||||
}
|
||||
|
||||
if ($this->arguments['limitCountries']) {
|
||||
foreach ($this->countryRepository->findAllowedByIsoCodeA3($this->arguments['limitCountries']) as $country) {
|
||||
$countriesArray[ObjectAccess::getProperty($country, $key)] = ObjectAccess::getProperty($country, $value);
|
||||
}
|
||||
|
||||
return $countriesArray;
|
||||
}
|
||||
|
||||
foreach ($countries as $country) {
|
||||
/** @var $country \SJBR\StaticInfoTables\Domain\Model\Country */
|
||||
$countriesArray[ObjectAccess::getProperty($country, $key)] = ObjectAccess::getProperty($country, $value);
|
||||
}
|
||||
|
||||
return $countriesArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('key', 'string', 'country isoCode', false, 'isoCodeA3');
|
||||
$this->registerArgument('value', 'string', 'shortNameLocal', false, 'shortNameLocal');
|
||||
$this->registerArgument('sortbyField', 'string', 'shortNameLocal', false, 'shortNameLocal');
|
||||
$this->registerArgument('sorting', 'string', 'value to prepend', false, 'asc');
|
||||
$this->registerArgument('preferredCountries', 'string', 'comma separated list of countries (iso3 code) to show on top of select', false, '');
|
||||
$this->registerArgument('limitCountries', 'string', 'comma separated list of countries (iso3 code) to show only in select', false, '');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\ViewHelpers\Form;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Class GetCountriesViewHelper
|
||||
*/
|
||||
class GetCountriesViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $countries = [
|
||||
'AND' => 'Andorra',
|
||||
'ARE' => 'الإمارات العربيّة المتّحدة',
|
||||
'AFG' => 'افغانستان',
|
||||
'ATG' => 'Antigua and Barbuda',
|
||||
'AIA' => 'Anguilla',
|
||||
'ALB' => 'Shqipëria',
|
||||
'ARM' => 'Հայաստան',
|
||||
'ANT' => 'Nederlandse Antillen',
|
||||
'AGO' => 'Angola',
|
||||
'ATA' => 'Antarctica',
|
||||
'ARG' => 'Argentina',
|
||||
'ASM' => 'Amerika Samoa',
|
||||
'AUT' => 'Österreich',
|
||||
'AUS' => 'Australia',
|
||||
'ABW' => 'Aruba',
|
||||
'AZE' => 'Azərbaycan',
|
||||
'BIH' => 'BiH/БиХ',
|
||||
'BRB' => 'Barbados',
|
||||
'BGD' => 'বাংলাদেশ',
|
||||
'BEL' => 'Belgique',
|
||||
'BFA' => 'Burkina',
|
||||
'BGR' => 'България (Bulgaria)',
|
||||
'BHR' => 'البحري',
|
||||
'BDI' => 'Burundi',
|
||||
'BEN' => 'Bénin',
|
||||
'BMU' => 'Bermuda',
|
||||
'BRN' => 'دارالسلام',
|
||||
'BOL' => 'Bolivia',
|
||||
'BRA' => 'Brasil',
|
||||
'BHS' => 'The Bahamas',
|
||||
'BTN' => 'Druk-Yul',
|
||||
'BVT' => 'Bouvet Island',
|
||||
'BWA' => 'Botswana',
|
||||
'BLR' => 'Беларусь',
|
||||
'BLZ' => 'Belize',
|
||||
'CAN' => 'Canada',
|
||||
'CCK' => 'Cocos (Keeling) Islands',
|
||||
'COD' => 'Congo',
|
||||
'CAF' => 'Centrafrique',
|
||||
'COG' => 'Congo-Brazzaville',
|
||||
'CHE' => 'Schweiz',
|
||||
'CIV' => 'Côte d’Ivoire',
|
||||
'COK' => 'Cook Islands',
|
||||
'CHL' => 'Chile',
|
||||
'CMR' => 'Cameroun',
|
||||
'CHN' => '中华',
|
||||
'COL' => 'Colombia',
|
||||
'CRI' => 'Costa Rica',
|
||||
'CUB' => 'Cuba',
|
||||
'CPV' => 'Cabo Verde',
|
||||
'CXR' => 'Christmas Island',
|
||||
'CYP' => 'Κύπρος / Kıbrıs',
|
||||
'CZE' => 'Česko',
|
||||
'DEU' => 'Deutschland',
|
||||
'DJI' => 'Djibouti',
|
||||
'DNK' => 'Danmark',
|
||||
'DMA' => 'Dominica',
|
||||
'DOM' => 'Quisqueya',
|
||||
'DZA' => 'الجزائ',
|
||||
'ECU' => 'Ecuador',
|
||||
'EST' => 'Eesti',
|
||||
'EGY' => 'مصر',
|
||||
'ESH' => 'الصحراء الغربي',
|
||||
'ERI' => 'ኤርትራ',
|
||||
'ESP' => 'España',
|
||||
'ETH' => 'ኢትዮጵያ',
|
||||
'FIN' => 'Suomi',
|
||||
'FJI' => 'Fiji / Viti',
|
||||
'FLK' => 'Falkland Islands',
|
||||
'FSM' => 'Micronesia',
|
||||
'FRO' => 'Føroyar / Færøerne',
|
||||
'FRA' => 'France',
|
||||
'GAB' => 'Gabon',
|
||||
'GBR' => 'United Kingdom',
|
||||
'GRD' => 'Grenada',
|
||||
'GEO' => 'საქართველო',
|
||||
'GUF' => 'Guyane française',
|
||||
'GHA' => 'Ghana',
|
||||
'GIB' => 'Gibraltar',
|
||||
'GRL' => 'Grønland',
|
||||
'GMB' => 'Gambia',
|
||||
'GIN' => 'Guinée',
|
||||
'GLP' => 'Guadeloupe',
|
||||
'GNQ' => 'Guinea Ecuatorial',
|
||||
'GRC' => 'Ελλάδα',
|
||||
'SGS' => 'South Georgia and the South Sandwich Islands',
|
||||
'GTM' => 'Guatemala',
|
||||
'GUM' => 'Guåhån',
|
||||
'GNB' => 'Guiné-Bissau',
|
||||
'GUY' => 'Guyana',
|
||||
'HKG' => '香港',
|
||||
'HND' => 'Honduras',
|
||||
'HRV' => 'Hrvatska',
|
||||
'HTI' => 'Ayiti',
|
||||
'HUN' => 'Magyarország',
|
||||
'IDN' => 'Indonesia',
|
||||
'IRL' => 'Éire',
|
||||
'ISR' => 'ישראל',
|
||||
'IND' => 'India',
|
||||
'IOT' => 'British Indian Ocean Territory',
|
||||
'IRQ' => 'العراق / عيَراق',
|
||||
'IRN' => 'ايران',
|
||||
'ISL' => 'Ísland',
|
||||
'ITA' => 'Italia',
|
||||
'JAM' => 'Jamaica',
|
||||
'JOR' => 'أردنّ',
|
||||
'JPN' => '日本',
|
||||
'KEN' => 'Kenya',
|
||||
'KGZ' => 'Кыргызстан',
|
||||
'KHM' => 'Kâmpŭchea',
|
||||
'KIR' => 'Kiribati',
|
||||
'COM' => 'اتحاد القمر',
|
||||
'KNA' => 'Saint Kitts and Nevis',
|
||||
'PRK' => '북조선',
|
||||
'KOR' => '한국',
|
||||
'KWT' => 'الكويت',
|
||||
'CYM' => 'Cayman Islands',
|
||||
'KAZ' => 'Қазақстан /Казахстан',
|
||||
'LAO' => 'ເມືອງລາວ',
|
||||
'LBN' => 'لبنان',
|
||||
'LCA' => 'Saint Lucia',
|
||||
'LIE' => 'Liechtenstein',
|
||||
'LKA' => 'ශ්රී ලංකා / இலங்கை',
|
||||
'LBR' => 'Liberia',
|
||||
'LSO' => 'Lesotho',
|
||||
'LTU' => 'Lietuva',
|
||||
'LUX' => 'Luxemburg',
|
||||
'LVA' => 'Latvija',
|
||||
'LBY' => 'ليبيا',
|
||||
'MAR' => 'المغربية',
|
||||
'MCO' => 'Monaco',
|
||||
'MDA' => 'Moldova',
|
||||
'MDG' => 'Madagascar',
|
||||
'MHL' => 'Marshall Islands',
|
||||
'MKD' => 'Македонија',
|
||||
'MLI' => 'Mali',
|
||||
'MMR' => 'Myanmar',
|
||||
'MNG' => 'Монгол Улс',
|
||||
'MAC' => '澳門 / Macau',
|
||||
'MNP' => 'Northern Marianas',
|
||||
'MTQ' => 'Martinique',
|
||||
'MRT' => 'الموريتانية',
|
||||
'MSR' => 'Montserrat',
|
||||
'MLT' => 'Malta',
|
||||
'MUS' => 'Mauritius',
|
||||
'MDV' => 'ޖުމުހޫރިއްޔ',
|
||||
'MWI' => 'Malawi',
|
||||
'MEX' => 'México',
|
||||
'MYS' => 'مليسيا',
|
||||
'MOZ' => 'Moçambique',
|
||||
'NAM' => 'Namibia',
|
||||
'NCL' => 'Nouvelle-Calédonie',
|
||||
'NER' => 'Niger',
|
||||
'NFK' => 'Norfolk Island',
|
||||
'NGA' => 'Nigeria',
|
||||
'NIC' => 'Nicaragua',
|
||||
'NLD' => 'Nederland',
|
||||
'NOR' => 'Norge',
|
||||
'NPL' => 'नेपाल',
|
||||
'NRU' => 'Naoero',
|
||||
'NIU' => 'Niue',
|
||||
'NZL' => 'New Zealand / Aotearoa',
|
||||
'OMN' => 'عُمان',
|
||||
'PAN' => 'Panamá',
|
||||
'PER' => 'Perú',
|
||||
'PYF' => 'Polynésie française',
|
||||
'PNG' => 'Papua New Guinea / Papua Niugini',
|
||||
'PHL' => 'Philippines',
|
||||
'PAK' => 'پاکستان',
|
||||
'POL' => 'Polska',
|
||||
'SPM' => 'Saint-Pierre-et-Miquelon',
|
||||
'PCN' => 'Pitcairn Islands',
|
||||
'PRI' => 'Puerto Rico',
|
||||
'PRT' => 'Portugal',
|
||||
'PLW' => 'Belau / Palau',
|
||||
'PRY' => 'Paraguay',
|
||||
'QAT' => 'قطر',
|
||||
'REU' => 'Réunion',
|
||||
'ROU' => 'România',
|
||||
'RUS' => 'Россия',
|
||||
'RWA' => 'Rwanda',
|
||||
'SAU' => 'السعودية',
|
||||
'SLB' => 'Solomon Islands',
|
||||
'SYC' => 'Seychelles',
|
||||
'SDN' => 'Sénégal',
|
||||
'SWE' => 'Sverige',
|
||||
'SGP' => 'Singapore',
|
||||
'SHN' => 'Saint Helena, Ascension and Tristan da Cunha',
|
||||
'SVN' => 'Slovenija',
|
||||
'SJM' => 'Svalbard',
|
||||
'SVK' => 'Slovensko',
|
||||
'SLE' => 'Sierra Leone',
|
||||
'SMR' => 'San Marino',
|
||||
'SEN' => 'Sénégal',
|
||||
'SOM' => 'Soomaaliya',
|
||||
'SUR' => 'Suriname',
|
||||
'STP' => 'São Tomé e Príncipe',
|
||||
'SLV' => 'El Salvador',
|
||||
'SYR' => 'سوري',
|
||||
'SWZ' => 'weSwatini',
|
||||
'TCA' => 'Turks and Caicos Islands',
|
||||
'TCD' => 'Tchad',
|
||||
'ATF' => 'Terres australes fran‡aises',
|
||||
'TGO' => 'Togo',
|
||||
'THA' => 'ไทย',
|
||||
'TJK' => 'Тоҷикистон',
|
||||
'TKL' => 'Tokelau',
|
||||
'TKM' => 'Türkmenistan',
|
||||
'TUN' => 'التونسية',
|
||||
'TON' => 'Tonga',
|
||||
'TLS' => 'Timor Lorosa\'e',
|
||||
'TUR' => 'Türkiye',
|
||||
'TTO' => 'Trinidad and Tobago',
|
||||
'TUV' => 'Tuvalu',
|
||||
'TWN' => '中華',
|
||||
'TZA' => 'Tanzania',
|
||||
'UKR' => 'Україна',
|
||||
'UGA' => 'Uganda',
|
||||
'UMI' => 'United States Minor Outlying Islands',
|
||||
'USA' => 'United States',
|
||||
'URY' => 'Uruguay',
|
||||
'UZB' => 'O‘zbekiston',
|
||||
'VAT' => 'Vaticano',
|
||||
'VCT' => 'Saint Vincent and the Grenadines',
|
||||
'VEN' => 'Venezuela',
|
||||
'VGB' => 'British Virgin Islands',
|
||||
'VIR' => 'US Virgin Islands',
|
||||
'VNM' => 'Việt Nam',
|
||||
'VUT' => 'Vanuatu',
|
||||
'WLF' => 'Wallis and Futuna',
|
||||
'WSM' => 'Samoa',
|
||||
'YEM' => 'اليمنية',
|
||||
'MYT' => 'Mayotte',
|
||||
'ZAF' => 'Afrika-Borwa',
|
||||
'ZMB' => 'Zambia',
|
||||
'ZWE' => 'Zimbabwe',
|
||||
'PSE' => 'فلسطين',
|
||||
'CSG' => 'Србија и Црна Гора',
|
||||
'ALA' => 'Åland',
|
||||
'HMD' => 'Heard Island and McDonald Islands',
|
||||
'MNE' => 'Crna Gora',
|
||||
'SRB' => 'Srbija',
|
||||
'JEY' => 'Jersey',
|
||||
'GGY' => 'Guernsey',
|
||||
'IMN' => 'Mann / Mannin',
|
||||
'MAF' => 'Saint-Martin',
|
||||
'BLM' => 'Saint-Barthélemy',
|
||||
'BES' => 'Bonaire, Sint Eustatius en Saba',
|
||||
'CUW' => 'Curaçao',
|
||||
'SXM' => 'Sint Maarten',
|
||||
'SSD' => 'South Sudan'
|
||||
];
|
||||
|
||||
/**
|
||||
* Build an country array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
return $this->countries;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\ViewHelpers\Form;
|
||||
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext;
|
||||
use TYPO3\CMS\Fluid\ViewHelpers\Form\SelectViewHelper as OriginalSelectViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception as FluidViewHelperException;
|
||||
|
||||
/**
|
||||
* Class SelectViewHelper
|
||||
*/
|
||||
class SelectViewHelper extends OriginalSelectViewHelper
|
||||
{
|
||||
/**
|
||||
* Initialize
|
||||
* @throws FluidViewHelperException
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$this->tag->addAttribute('data-selected-value', $this->getSelectedValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('defaultOption', 'string', 'value to prepend', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$options = parent::getOptions();
|
||||
if (!empty($this->arguments['defaultOption'])) {
|
||||
$options = ['' => $this->arguments['defaultOption']] + $options;
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the selected value(s)
|
||||
*
|
||||
* @return mixed value string or an array of strings
|
||||
* @throws FluidViewHelperException
|
||||
*/
|
||||
protected function getSelectedValue()
|
||||
{
|
||||
$selectedValue = parent::getSelectedValue();
|
||||
|
||||
// set preselection from TypoScript
|
||||
if (empty($selectedValue)) {
|
||||
if (! $this->renderingContext instanceof RenderingContext) {
|
||||
throw new FluidViewHelperException(
|
||||
'Something went wrong; RenderingContext should be available in ViewHelper',
|
||||
1638341673
|
||||
);
|
||||
}
|
||||
$controllerName = strtolower($this->renderingContext->getRequest()->getControllerName());
|
||||
$contentObject = $this->configurationManager->getContentObject();
|
||||
$typoScript = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
|
||||
);
|
||||
|
||||
$prefillTypoScript =
|
||||
$typoScript['plugin.']['tx_femanager.']['settings.'][$controllerName . '.']['prefill.'] ?? [];
|
||||
|
||||
if (!empty($prefillTypoScript[$this->getFieldName()])) {
|
||||
$selectedValue = $contentObject->cObjGetSingle(
|
||||
$prefillTypoScript[$this->getFieldName()],
|
||||
$prefillTypoScript[$this->getFieldName() . '.']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $selectedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Field name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getFieldName()
|
||||
{
|
||||
preg_match_all('/\[.*?\]/i', $this->getNameWithoutPrefix(), $name);
|
||||
return str_replace(['[', ']'], '', $name[0][0]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\ViewHelpers\Form;
|
||||
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext;
|
||||
use TYPO3\CMS\Fluid\ViewHelpers\Form\TextfieldViewHelper as OriginalTextfieldViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception as FluidViewHelperException;
|
||||
|
||||
/**
|
||||
* Class TextfieldViewHelper
|
||||
*/
|
||||
class TextfieldViewHelper extends OriginalTextfieldViewHelper
|
||||
{
|
||||
/**
|
||||
* Get the value of this form element (changed to prefill from TypoScript)
|
||||
* Either returns arguments['value'], or the correct value for Object Access.
|
||||
*
|
||||
* @return mixed Value
|
||||
* @throws FluidViewHelperException
|
||||
*/
|
||||
protected function getValueAttribute()
|
||||
{
|
||||
$value = parent::getValueAttribute();
|
||||
|
||||
// prefill value from TypoScript
|
||||
if (empty($value) && $this->getValueFromTypoScript()) {
|
||||
$value = $this->getValueFromTypoScript();
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read value from TypoScript
|
||||
*
|
||||
* @return string Value from TypoScript
|
||||
* @throws FluidViewHelperException
|
||||
*/
|
||||
protected function getValueFromTypoScript(): string
|
||||
{
|
||||
if (! $this->renderingContext instanceof RenderingContext) {
|
||||
throw new FluidViewHelperException(
|
||||
'Something went wrong; RenderingContext should be available in ViewHelper',
|
||||
1638341334
|
||||
);
|
||||
}
|
||||
$controllerName = strtolower($this->renderingContext->getRequest()->getControllerName());
|
||||
$contentObject = $this->configurationManager->getContentObject();
|
||||
$typoScript = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
|
||||
);
|
||||
$prefillTypoScript = $typoScript['plugin.']['tx_femanager.']['settings.'][$controllerName . '.']['prefill.'] ?? 0;
|
||||
$value = $contentObject->cObjGetSingle(
|
||||
$prefillTypoScript[$this->arguments['property']] ?? '',
|
||||
$prefillTypoScript[$this->arguments['property'] . '.'] ?? ''
|
||||
);
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\ViewHelpers\Misc;
|
||||
|
||||
use In2code\Femanager\Utility\BackendUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Class BackendEditLinkViewHelper
|
||||
*/
|
||||
class BackendEditLinkViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* initialize arguments
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument('tableName', 'string', 'Records table name (like "fe_users")', true);
|
||||
$this->registerArgument('identifier', 'integer', 'Record identifier to edit', true);
|
||||
$this->registerArgument('addReturnUrl', 'bool', 'Add current URI as returnUrl', false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an URI for backend edit
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
): string {
|
||||
return BackendUtility::getBackendEditUri($arguments['tableName'], $arguments['identifier'], $arguments['addReturnUrl']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\ViewHelpers\Misc;
|
||||
|
||||
use In2code\Femanager\Utility\BackendUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Class BackendNewLinkViewHelper
|
||||
*/
|
||||
class BackendNewLinkViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* initialize arguments
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument('tableName', 'string', 'Records table name (like "fe_users")', true);
|
||||
$this->registerArgument('addReturnUrl', 'bool', 'Add current URI as returnUrl', false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an URI for new records in backend
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
): string {
|
||||
return BackendUtility::getBackendNewUri($arguments['tableName'], BackendUtility::getPageIdentifier(), $arguments['addReturnUrl']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\ViewHelpers\Misc;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception as FluidViewHelperException;
|
||||
|
||||
/**
|
||||
* Look if captcha is enabled
|
||||
*/
|
||||
class CaptchaEnabledViewHelper extends AbstractViewHelper
|
||||
{
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('settings', 'bool', 'array $settings TypoScript', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if captcha is enabled
|
||||
* @return bool
|
||||
* @throws FluidViewHelperException
|
||||
*/
|
||||
public function render(): bool
|
||||
{
|
||||
if (! $this->renderingContext instanceof RenderingContext) {
|
||||
throw new FluidViewHelperException(
|
||||
'Something went wrong; RenderingContext should be available in ViewHelper',
|
||||
1638341672
|
||||
);
|
||||
}
|
||||
$controllerName = strtolower($this->renderingContext->getRequest()->getControllerName());
|
||||
|
||||
return ExtensionManagementUtility::isLoaded('sr_freecap')
|
||||
&& $this->templateVariableContainer->getByPath('settings.' . $controllerName . '.validation.captcha.captcha');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\ViewHelpers\Misc;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Class ExplodeViewHelper
|
||||
*/
|
||||
class ExplodeViewHelper extends AbstractViewHelper
|
||||
{
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('string', 'string', 'Any list (e.g. "a,b,c,d")', false);
|
||||
$this->registerArgument('seperator', 'string', 'Separator sign (e.g. ",")', false, ',');
|
||||
$this->registerArgument('trim', 'bool', 'Should be trimmed?', false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* View helper to explode a list
|
||||
* @return array
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$string = $this->arguments['string'];
|
||||
$separator = $this->arguments['seperator'];
|
||||
$trim = $this->arguments['trim'];
|
||||
|
||||
return $trim ? GeneralUtility::trimExplode($separator, $string, true) : explode($separator, $string);
|
||||
}
|
||||
}
|
||||
Loaded 100 of 2984 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user