first commit
This commit is contained in:
commit
e81864e683
2984 files changed
+267797
No files matched your search
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user