Skip to content

Commit

Permalink
Merge pull request #34 from IchHabRecht/prevent-code-duplication
Browse files Browse the repository at this point in the history
  • Loading branch information
IchHabRecht authored Dec 17, 2017
2 parents f4a80ff + 41fc30d commit feae7c5
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 106 deletions.
75 changes: 21 additions & 54 deletions Classes/Form/FormDataProvider/TcaColPosItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,24 @@

use IchHabRecht\ContentDefender\BackendLayout\BackendLayoutConfiguration;
use IchHabRecht\ContentDefender\Form\Exception\AccessDeniedColPosException;
use IchHabRecht\ContentDefender\Repository\ContentRepository;
use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class TcaColPosItems implements FormDataProviderInterface
{
/**
* @var array
* @var ContentRepository
*/
protected static $colPosCount = [];
protected $contentRepository;

/**
* @param ContentRepository $contentRepository
*/
public function __construct(ContentRepository $contentRepository = null)
{
$this->contentRepository = $contentRepository ?? GeneralUtility::makeInstance(ContentRepository::class);
}

/**
* @param array $result
Expand All @@ -32,39 +39,44 @@ public function addData(array $result)
$pageId = !empty($result['effectivePid']) ? (int)$result['effectivePid'] : (int)$result['databaseRow']['pid'];
$backendLayoutConfiguration = BackendLayoutConfiguration::createFromPageId($pageId);

$record = $result['databaseRow'];
$record['pid'] = $pageId;

foreach ($result['processedTca']['columns']['colPos']['config']['items'] as $key => $item) {
$colPos = (int)$item[1];
$columnConfiguration = $backendLayoutConfiguration->getConfigurationByColPos($colPos);
if (empty($columnConfiguration)) {
continue;
}

$record['colPos'] = $colPos;

$allowedConfiguration = $columnConfiguration['allowed.'] ?? [];
foreach ($allowedConfiguration as $field => $value) {
if (!isset($result['databaseRow'][$field])) {
if (!isset($record[$field])) {
continue;
}

$allowedValues = GeneralUtility::trimExplode(',', $value);
if ($this->fieldContainsDisallowedValues($result['databaseRow'][$field], $allowedValues)) {
if ($this->fieldContainsDisallowedValues($record[$field], $allowedValues)) {
unset($result['processedTca']['columns']['colPos']['config']['items'][$key]);
}
}

$disallowedConfiguration = $columnConfiguration['disallowed.'] ?? [];
foreach ($disallowedConfiguration as $field => $value) {
if (!isset($result['databaseRow'][$field])) {
if (!isset($record[$field])) {
continue;
}

$disallowedValues = GeneralUtility::trimExplode(',', $value);
if ($this->fieldContainsDisallowedValues($result['databaseRow'][$field], $disallowedValues, false)) {
if ($this->fieldContainsDisallowedValues($record[$field], $disallowedValues, false)) {
unset($result['processedTca']['columns']['colPos']['config']['items'][$key]);
}
}

if (!empty($columnConfiguration['maxitems'])
&& $columnConfiguration['maxitems'] <= $this->getCurrentColPosCount($pageId, $colPos, $result['databaseRow'])
&& $columnConfiguration['maxitems'] <= $this->contentRepository->countColPosByRecord($record)
) {
if ($colPos === (int)$result['databaseRow']['colPos'][0]) {
throw new AccessDeniedColPosException(
Expand Down Expand Up @@ -97,49 +109,4 @@ protected function fieldContainsDisallowedValues($fieldValue, array $values, $al

return false;
}

/**
* @param int $pageId
* @param int $colPos
* @param array $record
* @return int
*/
protected function getCurrentColPosCount($pageId, $colPos, array $record)
{
$languageField = $GLOBALS['TCA']['tt_content']['ctrl']['languageField'];
$language = $record[$languageField][0];

$identifier = $pageId . '/' . $language . '/' . $colPos;

if (isset(self::$colPosCount[$identifier])) {
return self::$colPosCount[$identifier];
}

$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
$queryBuilder->getRestrictions()->removeByType(HiddenRestriction::class);
$count = $queryBuilder->count('*')
->from('tt_content')
->where(
$queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
'colPos',
$queryBuilder->createNamedParameter($colPos, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
$languageField,
$queryBuilder->createNamedParameter($language, \PDO::PARAM_INT)
),
$queryBuilder->expr()->neq(
'uid',
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
)
)
->execute()
->fetchColumn();

return self::$colPosCount[$identifier] = $count;
}
}
63 changes: 12 additions & 51 deletions Classes/Hooks/AbstractDataHandlerHook.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
<?php
namespace IchHabRecht\ContentDefender\Hooks;

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use IchHabRecht\ContentDefender\Repository\ContentRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;

abstract class AbstractDataHandlerHook
{
/**
* @var array
* @var ContentRepository
*/
protected static $colPosCount = [];
protected $contentRepository;

/**
* @param ContentRepository $contentRepository
*/
public function __construct(ContentRepository $contentRepository = null)
{
$this->contentRepository = $contentRepository ?? GeneralUtility::makeInstance(ContentRepository::class);
}

/**
* @param array $columnConfiguration
Expand Down Expand Up @@ -67,52 +74,6 @@ protected function isRecordAllowedByItemsCount(array $columnConfiguration, array
return true;
}

$identifier = $this->getIdentifierForRecord($record);

if (!isset(self::$colPosCount[$identifier])) {
$languageField = $GLOBALS['TCA']['tt_content']['ctrl']['languageField'];
list($pageId, $colPos, $language) = explode('/', $identifier);
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
$queryBuilder->getRestrictions()->removeByType(HiddenRestriction::class);
$count = $queryBuilder->count('*')
->from('tt_content')
->where(
$queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
'colPos',
$queryBuilder->createNamedParameter($colPos, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
$languageField,
$queryBuilder->createNamedParameter($language, \PDO::PARAM_INT)
),
$queryBuilder->expr()->neq(
'uid',
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
)
)
->execute()
->fetchColumn();
self::$colPosCount[$identifier] = $count;
}

return (int)$columnConfiguration['maxitems'] >= ++self::$colPosCount[$identifier];
}

/**
* @param array $record
* @return string
*/
protected function getIdentifierForRecord(array $record)
{
$pageId = $record['pid'];
$colPos = $record['colPos'];
$languageField = $GLOBALS['TCA']['tt_content']['ctrl']['languageField'];
$language = $record[$languageField];

return $pageId . '/' . $colPos . '/' . $language;
return (int)$columnConfiguration['maxitems'] >= $this->contentRepository->increaseColPosCountByRecord($record);
}
}
2 changes: 1 addition & 1 deletion Classes/Hooks/CmdmapDataHandlerHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public function processCmdmap_beforeStart(DataHandler $dataHandler)
// As for copy command the wrong record uid is used (the one of the record which should
// be copied), we need to decrease the self::$colPosCount count again
if ('paste' === $command) {
self::$colPosCount[$this->getIdentifierForRecord($currentRecord)]--;
$this->contentRepository->decreaseColPosCountByRecord($currentRecord);
}
}
}
Expand Down
93 changes: 93 additions & 0 deletions Classes/Repository/ContentRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php
declare(strict_types=1);
namespace IchHabRecht\ContentDefender\Repository;

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class ContentRepository
{
/**
* @var int[]
*/
protected static $colPosCount = [];

/**
* @param array $record
* @return int
*/
public function countColPosByRecord(array $record): int
{
$identifier = $this->getIdentifier($record);

if (!isset(self::$colPosCount[$identifier])) {
$this->initialize($record);
}

return self::$colPosCount[$identifier];
}

public function increaseColPosCountByRecord(array $record, int $inc = 1): int
{
$identifier = $this->getIdentifier($record);

if (!isset(self::$colPosCount[$identifier])) {
$this->initialize($record);
}

return self::$colPosCount[$identifier] += $inc;
}

public function decreaseColPosCountByRecord(array $record, int $dec = 1): int
{
$identifier = $this->getIdentifier($record);

if (!isset(self::$colPosCount[$identifier])) {
$this->initialize($record);
}

return self::$colPosCount[$identifier] -= $dec;
}

protected function initialize(array $record)
{
$languageField = $GLOBALS['TCA']['tt_content']['ctrl']['languageField'];
$language = (int)$record[$languageField][0];

$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
$queryBuilder->getRestrictions()->removeByType(HiddenRestriction::class);
$count = $queryBuilder->count('*')
->from('tt_content')
->where(
$queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter($record['pid'], \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
'colPos',
$queryBuilder->createNamedParameter($record['colPos'], \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
$languageField,
$queryBuilder->createNamedParameter($language, \PDO::PARAM_INT)
),
$queryBuilder->expr()->neq(
'uid',
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
)
)
->execute()
->fetchColumn();

self::$colPosCount[$this->getIdentifier($record)] = (int)$count;
}

protected function getIdentifier(array $record): string
{
$languageField = $GLOBALS['TCA']['tt_content']['ctrl']['languageField'];
$language = (int)$record[$languageField][0];

return $record['pid'] . '/' . $language . '/' . $record['colPos'];
}
}

0 comments on commit feae7c5

Please sign in to comment.