Skip to content

Commit

Permalink
Fix for deep copy in tree view
Browse files Browse the repository at this point in the history
  • Loading branch information
zonky2 committed Dec 5, 2024
1 parent d510811 commit 0845216
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 69 deletions.
21 changes: 14 additions & 7 deletions src/BaseConfigRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,27 @@ public function getEnvironment()
private function addParentFilter(ModelIdInterface $idParent, ConfigInterface $config): ConfigInterface
{
$environment = $this->getEnvironment();
$definition = $environment->getDataDefinition();
assert($environment instanceof EnvironmentInterface);

$definition = $environment->getDataDefinition();
if (null === $definition) {
throw new DcGeneralRuntimeException('Data definition not set.');
}
$basicDefinition = $definition->getBasicDefinition();
$providerName = $basicDefinition->getDataProvider();
$providerName = (string) $basicDefinition->getDataProvider();
$parentProviderName = $idParent->getDataProviderName();
$parentProvider = $environment->getDataProvider($parentProviderName);

if ($basicDefinition->getParentDataProvider() !== $parentProviderName) {
throw new DcGeneralRuntimeException(
'Unexpected parent provider ' . $parentProviderName .
' (expected ' . ((string) $basicDefinition->getParentDataProvider()) . ')'
);
// Could be a tree parent then.
if ($basicDefinition->getDataProvider() !== $parentProviderName) {
throw new DcGeneralRuntimeException(
'Unexpected parent provider ' . $parentProviderName .
' (expected ' . ((string) $basicDefinition->getParentDataProvider()) . ')'
);
}
$parentProviderName = $providerName;
$parentProvider = $environment->getDataProvider($parentProviderName);
}

if ($parentProvider) {
Expand All @@ -115,7 +122,7 @@ private function addParentFilter(ModelIdInterface $idParent, ConfigInterface $co

$condition = $definition->getModelRelationshipDefinition()->getChildCondition(
$parentProviderName,
(string) $providerName
$providerName
);

if ($condition) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,12 +285,11 @@ protected function parseDataProvider(ContainerInterface $container)
}

// First check if we are using the "new" notation used in DcGeneral 0.9.
if (!\is_array($this->getFromDca('dca_config/data_provider'))) {
$dataProvidersDca = $this->getFromDca('dca_config/data_provider');
if (!\is_array($dataProvidersDca)) {
return;
}

$dataProvidersDca = $this->getFromDca('dca_config/data_provider');

foreach ($dataProvidersDca as $dataProviderDcaName => $dataProviderDca) {
$providerInformation = $this->parseSingleDataProvider(
$container,
Expand Down Expand Up @@ -326,6 +325,7 @@ protected function parseDataProvider(ContainerInterface $container)
break;

default:
$baseInitializationData['name'] = $providerInformation->getName();
}

$providerInformation->setInitializationData(
Expand Down
6 changes: 6 additions & 0 deletions src/Contao/Dca/Populator/ParentDefinitionPopulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ public function populateController(EnvironmentInterface $environment)
return;
}

if ($parentDataProvider === $definition->getName()) {
$environment->setParentDataDefinition($definition);

return;
}

if (null === $dispatcher = $environment->getEventDispatcher()) {
throw new LogicException('No event dispatcher given');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* This file is part of contao-community-alliance/dc-general.
*
* (c) 2013-2023 Contao Community Alliance.
* (c) 2013-2024 Contao Community Alliance.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
Expand All @@ -15,7 +15,7 @@
* @author Sven Baumann <[email protected]>
* @author David Molineus <[email protected]>
* @author Ingolf Steinhardt <[email protected]>
* @copyright 2013-2023 Contao Community Alliance.
* @copyright 2013-2024 Contao Community Alliance.
* @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later
* @filesource
*/
Expand Down Expand Up @@ -144,7 +144,7 @@ protected function process(EnvironmentInterface $environment)
return null;
}

ViewHelpers::redirectHome($environment);
ViewHelpers::redirectCleanHome($environment, ['source', 'after', 'into']);

return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ private function handleCopyAllAction(EnvironmentInterface $environment, Action $
foreach ($this->getModelIds($environment, $action, $this->getSubmitAction($environment)) as $modelId) {
$inputProvider->setParameter('source', $modelId->getSerialized());

$this->callAction($environment, 'copy');
$this->callAction($environment, 'deepcopy');

$inputProvider->unsetParameter('source');
}
Expand Down
5 changes: 3 additions & 2 deletions src/Contao/View/Contao2BackendView/ButtonRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,9 @@ private function calculateParameters(CommandInterface $command, string $serializ
}
if (($command instanceof CutCommandInterface) || ($command instanceof CopyCommandInterface)) {
// Cut & copy need some special information.
$parameters = [];
$parameters['act'] = $command->getName();
if (!\array_key_exists('act', $parameters)) {
$parameters['act'] = $command->getName();
}

$inputProvider = $this->environment->getInputProvider();
assert($inputProvider instanceof InputProviderInterface);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ private function checkPermission(ActionEvent $event)
*
* @return void
*/
private function clearClipboard(ActionEvent $event, $redirect = true)
private function clearClipboard(ActionEvent $event, bool $redirect = true): void
{
$environment = $event->getEnvironment();

Expand Down
2 changes: 1 addition & 1 deletion src/Contao/View/Contao2BackendView/TreeView.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ private function handleNodeStateChanges()
$this->toggleModel($providerName, $modelId);
}

ViewHelpers::redirectHome($environment);
ViewHelpers::redirectCleanHome($environment, ['ptg', 'provider']);
}
}

Expand Down
71 changes: 48 additions & 23 deletions src/Contao/View/Contao2BackendView/ViewHelpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,56 @@ public static function redirectHome(EnvironmentInterface $environment): never
$request = self::getRequest();
$routeName = $request->attributes->get('_route');
if ($routeName !== 'contao_backend') {
self::determineNewStyleRedirect($routeName, $request, $environment);
self::determineNewStyleRedirect($routeName, $request, $environment, []);
}
self::determineLegacyRedirect($environment, $input);
}

/** @param list<string> $cleanNames */
public static function redirectCleanHome(EnvironmentInterface $environment, array $cleanNames): never
{
$input = $environment->getInputProvider();
assert($input instanceof InputProviderInterface);

$request = self::getRequest();
$routeName = $request->attributes->get('_route');
if ($routeName !== 'contao_backend') {
self::determineNewStyleRedirect($routeName, $request, $environment, $cleanNames);
}
self::determineLegacyRedirect($environment, $input);
}

/** @param list<string> $cleanNames */
private static function determineNewStyleRedirect(
string $routeName,
Request $request,
EnvironmentInterface $environment,
array $cleanNames
): never {
$routeGenerator = System::getContainer()->get('router');
assert($routeGenerator instanceof UrlGeneratorInterface);
$parameters = $request->query->all();
foreach ($cleanNames as $key) {
unset($parameters[$key]);
}
if ($routeName === $request->attributes->get('_route')) {
foreach ($request->attributes->get('_route_params') ?? [] as $key => $value) {
if ('_' === $key[0] || \in_array($key, $cleanNames, true)) {
continue;
}
$parameters[$key] = $value;
}
}
unset($parameters['act']);
$routeBase = $routeGenerator->generate($routeName, $parameters);

self::dispatchRedirect($environment, new RedirectEvent($routeBase));
}

private static function determineLegacyRedirect(
EnvironmentInterface $environment,
InputProviderInterface $input,
): never {
if ($input->hasParameter('table')) {
if ($input->hasParameter('pid')) {
$event = new RedirectEvent(
Expand All @@ -288,28 +335,6 @@ public static function redirectHome(EnvironmentInterface $environment): never
self::dispatchRedirect($environment, $event);
}

private static function determineNewStyleRedirect(
string $routeName,
Request $request,
EnvironmentInterface $environment
): never {
$routeGenerator = System::getContainer()->get('router');
assert($routeGenerator instanceof UrlGeneratorInterface);
$parameters = $request->query->all();
if ($routeName === $request->attributes->get('_route')) {
foreach ($request->attributes->get('_route_params') ?? [] as $key => $value) {
if ('_' === $key[0]) {
continue;
}
$parameters[$key] = $value;
}
}
unset($parameters['act']);
$routeBase = $routeGenerator->generate($routeName, $parameters);

self::dispatchRedirect($environment, new RedirectEvent($routeBase));
}

private static function getRequest(): Request
{
$requestStack = System::getContainer()->get('request_stack');
Expand Down
16 changes: 8 additions & 8 deletions src/Controller/DefaultController.php
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ private function doActions(
// Now apply sorting and persist all models.
$models = $this->sortAndPersistModels($actions, $after, $into, $parentModelId, $items);

// At least, go ahead with the deep copy.
// At last, go ahead with the deep copy.
$this->doDeepCopy($deepCopyList);

return $models;
Expand Down Expand Up @@ -1112,28 +1112,28 @@ protected function doDeepCopy(array $deepCopyList)
$groupAndSortingCollection = $listingConfig->getGroupAndSortingDefinition();
$groupAndSorting = $groupAndSortingCollection->getDefault();

// ***** fetch the children
// ***** fetch the children.
$filter = $childCondition->getFilter($origin);

// apply parent-child condition
$config = $destinationDataProvider->getEmptyConfig();
$config->setFilter($filter);

// apply sorting
// Apply sorting.
$sorting = [];
foreach ($groupAndSorting as $information) {
/** @var GroupAndSortingInformationInterface $information */
$sorting[$information->getProperty()] = $information->getSortingMode();
}
$config->setSorting($sorting);

// receive children
// Receive children.
$children = $destinationDataProvider->fetchAll($config);

// ***** do the deep copy
// ***** do the deep copy.
$actions = [];

// build the copy actions
// Build the copy actions.
foreach ($children as $childModel) {
if (!($childModel instanceof ModelInterface)) {
continue;
Expand All @@ -1147,8 +1147,8 @@ protected function doDeepCopy(array $deepCopyList)
];
}

// do the deep copy
$childrenModels = $destinationController->doActions($actions, null, null, $parentId);
// Do the deep copy.
$childrenModels = $destinationController->doActions($actions, null, $parentId, null);

// ensure parent-child condition
foreach ($childrenModels as $childrenModel) {
Expand Down
42 changes: 22 additions & 20 deletions src/Controller/ModelCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* This file is part of contao-community-alliance/dc-general.
*
* (c) 2013-2023 Contao Community Alliance.
* (c) 2013-2024 Contao Community Alliance.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
Expand All @@ -16,7 +16,7 @@
* @author Ingolf Steinhardt <[email protected]>
* @author David Molineus <[email protected]>
* @author Stefan Heimes <[email protected]>
* @copyright 2013-2023 Contao Community Alliance.
* @copyright 2013-2024 Contao Community Alliance.
* @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later
* @filesource
*/
Expand Down Expand Up @@ -160,6 +160,8 @@ public function __construct(EnvironmentInterface $environment)
*
* @return ModelInterface|null
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*
* @throws \InvalidArgumentException When the model id is invalid.
*/
public function getModel($modelId, $providerName = null)
Expand All @@ -185,34 +187,34 @@ public function getModel($modelId, $providerName = null)
assert($dataProvider instanceof DataProviderInterface);

$config = $dataProvider->getEmptyConfig();
$config->setId($modelId->getId());

if ($definition->getName() === $modelId->getDataProviderName()) {
$propertyDefinition = $definition->getPropertiesDefinition();
} elseif ($parentDefinition && $parentDefinition->getName() === $modelId->getDataProviderName()) {
$propertyDefinition = $parentDefinition->getPropertiesDefinition();
} else {
throw new \InvalidArgumentException('Invalid provider name ' . $modelId->getDataProviderName());
$propertyDefinition = null;
}
if (null !== $propertyDefinition) {
$properties = [];
// Filter real properties from the property definition.
foreach ($propertyDefinition->getPropertyNames() as $propertyName) {
if ($dataProvider->fieldExists($propertyName)) {
$properties[] = $propertyName;
continue;
}

$properties = [];

// Filter real properties from the property definition.
foreach ($propertyDefinition->getPropertyNames() as $propertyName) {
if ($dataProvider->fieldExists($propertyName)) {
$properties[] = $propertyName;

continue;
// @codingStandardsIgnoreStart
@\trigger_error(
'Only real property is allowed in the property definition.' .
'This will no longer be supported in the future.',
E_USER_DEPRECATED
);
// @codingStandardsIgnoreEnd
}

// @codingStandardsIgnoreStart
@\trigger_error(
'Only real property is allowed in the property definition.' .
'This will no longer be supported in the future.',
E_USER_DEPRECATED
);
// @codingStandardsIgnoreEnd
$config->setFields($properties);
}
$config->setId($modelId->getId())->setFields($properties);

return $dataProvider->fetch($config);
}
Expand Down

0 comments on commit 0845216

Please sign in to comment.