Skip to content

Commit deabc8b

Browse files
author
roadiz-ci
committed
Merge branch develop of github.com:roadiz/core-bundle-dev-app into develop
1 parent d9b1fa4 commit deabc8b

12 files changed

Lines changed: 254 additions & 114 deletions

File tree

config/routing/nodes.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ nodesBulkStatusPage:
1111
path: /bulk-status
1212
defaults:
1313
_controller: RZ\Roadiz\RozierBundle\Controller\Node\NodeTreeController::bulkStatusAction
14+
nodesBulkUndeletePage:
15+
path: /bulk-undelete
16+
defaults:
17+
_controller: RZ\Roadiz\RozierBundle\Controller\Node\NodeTreeController::bulkUndeleteAction

src/Controller/Node/NodeBulkActionTrait.php

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,4 +426,102 @@ private function buildBulkStatusForm(
426426

427427
return $builder->getForm();
428428
}
429+
430+
/**
431+
* @throws RuntimeError
432+
*/
433+
public function bulkUndeleteAction(Request $request): Response
434+
{
435+
if (empty($request->get('undeleteForm')['nodesIds'])) {
436+
throw new ResourceNotFoundException();
437+
}
438+
439+
$nodesIds = trim((string) $request->get('undeleteForm')['nodesIds']);
440+
$nodesIds = \json_decode($nodesIds, true, flags: JSON_THROW_ON_ERROR);
441+
array_filter($nodesIds);
442+
443+
/** @var Node[] $nodes */
444+
$nodes = $this->allStatusesNodeRepository->findBy([
445+
'id' => $nodesIds,
446+
]);
447+
448+
if (0 === count($nodes)) {
449+
throw new ResourceNotFoundException();
450+
}
451+
452+
$items = [];
453+
foreach ($nodes as $node) {
454+
$this->denyAccessUnlessGranted(NodeVoter::DELETE, $node);
455+
$items[] = $this->explorerItemFactory->createForEntity($node)->toArray();
456+
}
457+
458+
$form = $this->buildBulkUndeleteForm(
459+
$nodesIds
460+
);
461+
$form->handleRequest($request);
462+
if ($request->get('confirm') && $form->isSubmitted() && $form->isValid()) {
463+
$msg = $this->bulkUndeleteNodes($form->getData());
464+
$this->logTrail->publishConfirmMessage($request, $msg);
465+
466+
return $this->redirectToRoute('nodesHomePage');
467+
}
468+
469+
return $this->render('@RoadizRozier/admin/confirm_action.html.twig', [
470+
'title' => new UnicodeString($this->translator->trans('undelete.nodes')),
471+
'headPath' => '@RoadizRozier/nodes/head.html.twig',
472+
'cancelPath' => $this->generateUrl('nodesHomePage'),
473+
'alertMessage' => 'are_you_sure.undelete.these.nodes',
474+
'action_label' => 'undelete.nodes.all',
475+
'action_icon' => 'rz-icon-ri--device-recover-line',
476+
'form' => $form->createView(),
477+
'items' => $items,
478+
]);
479+
}
480+
481+
private function buildBulkUndeleteForm(
482+
array $nodesIds = [],
483+
): FormInterface {
484+
/** @var FormBuilder $builder */
485+
$builder = $this->formFactory
486+
->createNamedBuilder('undeleteForm')
487+
->add('nodesIds', HiddenType::class, [
488+
'data' => json_encode($nodesIds, flags: JSON_THROW_ON_ERROR),
489+
'attr' => ['class' => 'bulk-form-value'],
490+
'constraints' => [
491+
new NotNull(),
492+
new NotBlank(),
493+
],
494+
]);
495+
496+
$builder->setAction('?confirm=1');
497+
498+
return $builder->getForm();
499+
}
500+
501+
private function bulkUndeleteNodes(array $data): string
502+
{
503+
if (!empty($data['nodesIds'])) {
504+
$nodesIds = trim((string) $data['nodesIds']);
505+
$nodesIds = \json_decode($nodesIds, true, flags: JSON_THROW_ON_ERROR);
506+
array_filter($nodesIds);
507+
508+
$nodes = $this->allStatusesNodeRepository
509+
->findBy([
510+
'id' => $nodesIds,
511+
]);
512+
513+
/** @var Node $node */
514+
foreach ($nodes as $node) {
515+
/** @var NodeHandler $handler */
516+
$handler = $this->handlerFactory->getHandler($node);
517+
$handler->softUnremoveWithChildren();
518+
}
519+
520+
$this->managerRegistry->getManager()->flush();
521+
522+
return $this->translator->trans('nodes.bulk.undeleted');
523+
}
524+
525+
return $this->translator->trans('wrong.request');
526+
}
429527
}

src/Controller/Node/NodeController.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,14 @@ public function indexAction(Request $request, ?string $filter = null): Response
229229
$assignation['deleteNodesForm'] = $deleteNodesForm->createView();
230230
}
231231

232+
/*
233+
* Handle bulk undelete form
234+
*/
235+
if ($this->isGranted('ROLE_ACCESS_NODES_DELETE')) {
236+
$undeleteNodesForm = $this->buildBulkUndeleteForm();
237+
$assignation['undeleteNodesForm'] = $undeleteNodesForm->createView();
238+
}
239+
232240
$assignation['filters'] = $listManager->getAssignation();
233241
$assignation['translation'] = $translation;
234242
$assignation['availableTranslations'] = $this->translationRepository->findAll();

templates/admin/webhooks/actionsMenu.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
} only %}
66
{% block items %}
77
{% if item.id and is_granted('ROLE_ACCESS_WEBHOOKS') %}
8+
{{ _self.deleteItem(href: path('webhooksDeletePage', { id: item.id })) }}
89
{{ _self.item(
910
label: 'webhook.trigger',
1011
href: path('webhooksTriggerPage', { id: item.id }),
1112
icon: 'rz-icon-ri--space-ship-line'
1213
) }}
13-
{{ _self.deleteItem(href: path('webhooksDeletePage', { id: item.id })) }}
1414
{% endif %}
1515
{% endblock %}
1616
{% endembed %}

templates/custom-forms/actionsMenu.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
{% block items %}
77
{% if (is_granted('ROLE_ACCESS_CUSTOMFORMS_DELETE')) %}
88
{% if item.id %}
9+
{{ _self.deleteItem(href: path('customFormsDeletePage', { id: item.id })) }}
910
{{ _self.item(
1011
label: 'customForm.duplicate',
1112
class: 'rz-button--tertiary',
1213
href: path('customFormsDuplicatePage', { id: item.id}) ,
1314
icon: 'rz-icon-ri--file-copy-line'
1415
) }}
15-
{{ _self.deleteItem(href: path('customFormsDeletePage', { id: item.id })) }}
1616
{% endif %}
1717
{% endif %}
1818
{% endblock %}

templates/documents/actionsMenu.html.twig

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@
1010
max_versions_showed: max_versions_showed,
1111
} only %}
1212
{% block items %}
13+
{% if (is_granted('ROLE_ACCESS_DOCUMENTS_DELETE') and not readOnly) %}
14+
{% if document.id %}
15+
{{ _self.item(
16+
label: 'delete.document',
17+
class: 'rz-button--primary rz-button--danger',
18+
href: path('documentsDeletePage', { documentId: document.id}),
19+
icon: 'rz-icon-ri--delete-bin-7-line'
20+
) }}
21+
{% endif %}
22+
{% endif %}
23+
1324
{% if versions and versions|length > 1 %}
1425
<rz-popover popover-placement="left-start" popover-offset="18px">
1526
<button popovertarget="version-menu"
@@ -59,16 +70,5 @@
5970
icon: 'rz-icon-ri--download-line'
6071
) }}
6172
{% endif %}
62-
63-
{% if (is_granted('ROLE_ACCESS_DOCUMENTS_DELETE') and not readOnly) %}
64-
{% if document.id %}
65-
{{ _self.item(
66-
label: 'delete.document',
67-
class: 'rz-button--primary rz-button--danger',
68-
href: path('documentsDeletePage', { documentId: document.id}),
69-
icon: 'rz-icon-ri--delete-bin-7-line'
70-
) }}
71-
{% endif %}
72-
{% endif %}
7373
{% endblock %}
7474
{% endembed %}

templates/folders/actionsMenu.html.twig

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,18 @@
55
} only %}
66
{% block items %}
77
{% if folder.getId %}
8-
{{ _self.item(
9-
label: 'download',
10-
class: 'rz-button--tertiary',
11-
href: path('foldersDownloadPage', { folderId: folder.getId }),
12-
icon: 'rz-icon-ri--download-line'
13-
) }}
14-
158
{% if not folder.locked %}
169
{{ _self.deleteItem(
1710
label: 'delete.folder',
1811
href: path('foldersDeletePage', { folderId: folder.getId }),
1912
) }}
2013
{% endif %}
14+
{{ _self.item(
15+
label: 'download',
16+
class: 'rz-button--tertiary',
17+
href: path('foldersDownloadPage', { folderId: folder.getId }),
18+
icon: 'rz-icon-ri--download-line'
19+
) }}
2120
{% endif %}
2221
{% endblock %}
2322
{% endembed %}

templates/nodes/actionsMenu.html.twig

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,47 @@
1212
} only %}
1313
{% block items %}
1414
{% if node %}
15+
{% if not readOnly and is_granted('DELETE', node) %}
16+
{% set canDelete = workflow_can(node, 'delete') %}
17+
18+
{% if workflow_can(node, 'undelete') %}
19+
{{ _self.item(
20+
class: 'rz-button--primary rz-button--danger',
21+
href: path('nodesUndeletePage', { nodeId: node.getId}),
22+
icon: 'rz-icon-ri--device-recover-line',
23+
attr: {
24+
title: 'undelete'|trans,
25+
'popover-placement': 'left',
26+
}
27+
) }}
28+
{% endif %}
29+
30+
{% if canDelete and node.nodeSources|length > 1 and source %}
31+
{{ _self.item(
32+
class: 'rz-button--primary rz-button--danger',
33+
href: path('nodesDeleteSourcePage', { nodeSourceId: source.id }),
34+
icon: 'rz-icon-ri--flag-off-line',
35+
attr: {
36+
title: 'delete.translation'|trans,
37+
'popover-placement': 'left',
38+
}
39+
) }}
40+
{% endif %}
41+
42+
{% if canDelete and (node.nodeSources|length == 1 or source.translation.defaultTranslation) %}
43+
{{ _self.deleteItem(
44+
href: path('nodesDeletePage', {
45+
nodeId: node.getId,
46+
referer: node.parent ? getBreadcrumbsItem(node.parent).url : null
47+
}),
48+
attr: {
49+
title: 'delete.node'|trans,
50+
'popover-placement': 'left',
51+
},
52+
) }}
53+
{% endif %}
54+
{% endif %}
55+
1556
{% import '@RoadizRozier/macros/rz_button.html.twig' as rz_button %}
1657
{% set canPublish = workflow_can(node, 'publish') %}
1758
{% if not node.isDeleted %}
@@ -219,46 +260,6 @@
219260
</rz-popover>
220261
{% endif %}
221262

222-
{% if not readOnly and is_granted('DELETE', node) %}
223-
{% set canDelete = workflow_can(node, 'delete') %}
224-
225-
{% if workflow_can(node, 'undelete') %}
226-
{{ _self.item(
227-
class: 'rz-button--primary rz-button--danger',
228-
href: path('nodesUndeletePage', { nodeId: node.getId}),
229-
icon: 'rz-icon-ri--device-recover-line',
230-
attr: {
231-
title: 'undelete'|trans,
232-
'popover-placement': 'left',
233-
}
234-
) }}
235-
{% endif %}
236-
237-
{% if canDelete and node.nodeSources|length > 1 and source %}
238-
{{ _self.item(
239-
class: 'rz-button--primary rz-button--danger',
240-
href: path('nodesDeleteSourcePage', { nodeSourceId: source.id }),
241-
icon: 'rz-icon-ri--flag-off-line',
242-
attr: {
243-
title: 'delete.translation'|trans,
244-
'popover-placement': 'left',
245-
}
246-
) }}
247-
{% endif %}
248-
249-
{% if canDelete and (node.nodeSources|length == 1 or source.translation.defaultTranslation) %}
250-
{{ _self.deleteItem(
251-
href: path('nodesDeletePage', {
252-
nodeId: node.getId,
253-
referer: node.parent ? getBreadcrumbsItem(node.parent).url : null
254-
}),
255-
attr: {
256-
title: 'delete.node'|trans,
257-
'popover-placement': 'left',
258-
},
259-
) }}
260-
{% endif %}
261-
{% endif %}
262263
{% endif %}
263264
{% endblock %}
264265
{% endembed %}

templates/nodes/bulkActions.html.twig

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,60 @@
55
{% set status_panel_id = "nodes-bulk-status-form-cont" %}
66

77
{% block other_actions %}
8-
{{
9-
rz_button.root({
10-
attributes: {
11-
type: 'button',
12-
title: "link.tags"|trans,
13-
'data-tab-controls': tags_panel_id,
14-
'data-tab-panel-active-class': 'rz-bulk-actions__group--visible',
15-
'data-tab-active-class': 'rz-button--selected',
16-
},
17-
emphasis: 'primary',
18-
icon: 'rz-icon-ri--price-tag-3-line',
19-
})
20-
}}
21-
{{
22-
rz_button.root({
23-
attributes: {
24-
type: 'button',
25-
title: "nodes.status"|trans,
26-
"data-tab-controls": status_panel_id,
27-
'data-tab-panel-active-class': 'rz-bulk-actions__group--visible',
28-
'data-tab-active-class': 'rz-button--selected',
29-
},
30-
emphasis: 'primary',
31-
icon: 'rz-icon-ri--flag-line',
32-
})
33-
}}
8+
{% if (routeName !== 'nodesHomeDeletedPage') %}
9+
{{
10+
rz_button.root({
11+
attributes: {
12+
type: 'button',
13+
title: "link.tags"|trans,
14+
'data-tab-controls': tags_panel_id,
15+
'data-tab-panel-active-class': 'rz-bulk-actions__group--visible',
16+
'data-tab-active-class': 'rz-button--selected',
17+
},
18+
emphasis: 'primary',
19+
icon: 'rz-icon-ri--price-tag-3-line',
20+
})
21+
}}
22+
{{
23+
rz_button.root({
24+
attributes: {
25+
type: 'button',
26+
title: "nodes.status"|trans,
27+
"data-tab-controls": status_panel_id,
28+
'data-tab-panel-active-class': 'rz-bulk-actions__group--visible',
29+
'data-tab-active-class': 'rz-button--selected',
30+
},
31+
emphasis: 'primary',
32+
icon: 'rz-icon-ri--flag-line',
33+
})
34+
}}
35+
{% endif %}
3436
{% endblock %}
3537

38+
{% block delete_form %}
39+
{% if (routeName == 'nodesHomeDeletedPage') %}
40+
<form
41+
class="rz-bulk-actions__form-button"
42+
action="{{ undelete_form_action }}"
43+
method="POST"
44+
>
45+
{% form_theme undelete_form_data '@RoadizRozier/forms.html.twig' %}
46+
{{ form_widget(undelete_form_data) }}
47+
{{ rz_button.root({
48+
attributes: {
49+
type: 'submit',
50+
title: title
51+
},
52+
color: 'danger',
53+
emphasis: 'primary',
54+
icon: 'rz-icon-ri--device-recover-line',
55+
}) }}
56+
</form>
57+
{% else %}
58+
{{ parent() }}
59+
{% endif %}
60+
{% endblock %}
61+
3662
{% block panels %}
3763
{% if tagNodesForm %}
3864
<tag-autocomplete

0 commit comments

Comments
 (0)