src/Configuration/ActionConfigPass.php
private function resolveActionInheritance(array $backendConfig)
    {
        foreach ($backendConfig['entities'] as $entityName => $entityConfig) {
            foreach ($this->views as $view) {
                $defaultActions = $this->getDefaultActions($view);
                $backendActions = $backendConfig[$view]['actions'];
                $entityActions = $entityConfig[$view]['actions'];

                // filter actions removed in the global view configuration
                foreach ($backendActions as $backendAction) {
                    if ('-' === $backendAction['name'][0]) {
                        $actionName = \mb_substr($backendAction['name'], 1);

                        unset($backendActions[$actionName], $backendActions['-'.$actionName]);

                        // unless the entity explicitly adds this globally removed action, remove it from the
                        // default actions config to avoid adding it to the entity later when merging everything
                        if (!isset($entityActions[$actionName])) {
                            unset($defaultActions[$actionName]);
                        }
                    }
                }

                // filter actions removed in the local entity configuration
                foreach ($entityActions as $entityAction) {
                    if ('-' === $entityAction['name'][0]) {
                        $actionName = \mb_substr($entityAction['name'], 1);

                        unset($entityActions[$actionName], $entityActions['-'.$actionName], $defaultActions[$actionName], $backendActions[$actionName]);
                    }
                }

                $actionsConfig = \array_merge($defaultActions, $backendActions, $entityActions);

                // reorder the actions to match the order set by the user in the
                // entity or in the global backend options
                if (!empty($entityActions)) {
                    $actionsConfig = $this->reorderArrayItems($actionsConfig, \array_keys($entityActions));
                } elseif (!empty($backendActions)) {
                    $actionsConfig = $this->reorderArrayItems($actionsConfig, \array_keys($backendActions));
                }

                $backendConfig['entities'][$entityName][$view]['actions'] = $actionsConfig;
            }
        }

        return $backendConfig;
    }
private function resolveActionInheritance(array $backendConfig)
    {
        foreach ($backendConfig['entities'] as $entityName => $entityConfig) {
            foreach ($this->views as $view) {
                $defaultActions = $this->getDefaultActions($view);
                $backendActions = $backendConfig[$view]['actions'];
                $entityActions = $entityConfig[$view]['actions'];

                // filter actions removed in the global view configuration
                foreach ($backendActions as $backendAction) {
                    if ('-' === $backendAction['name'][0]) {
                        $actionName = \mb_substr($backendAction['name'], 1);

                        unset($backendActions[$actionName], $backendActions['-'.$actionName]);

                        // unless the entity explicitly adds this globally removed action, remove it from the
                        // default actions config to avoid adding it to the entity later when merging everything
                        if (!isset($entityActions[$actionName])) {
                            unset($defaultActions[$actionName]);
                        }
                    }
                }

                // filter actions removed in the local entity configuration
                foreach ($entityActions as $entityAction) {
                    if ('-' === $entityAction['name'][0]) {
                        $actionName = \mb_substr($entityAction['name'], 1);

                        unset($entityActions[$actionName], $entityActions['-'.$actionName], $defaultActions[$actionName], $backendActions[$actionName]);
                    }
                }

                $actionsConfig = \array_merge($defaultActions, $backendActions, $entityActions);

                // reorder the actions to match the order set by the user in the
                // entity or in the global backend options
                if (!empty($entityActions)) {
                    $actionsConfig = $this->reorderArrayItems($actionsConfig, \array_keys($entityActions));
                } elseif (!empty($backendActions)) {
                    $actionsConfig = $this->reorderArrayItems($actionsConfig, \array_keys($backendActions));
                }

                $backendConfig['entities'][$entityName][$view]['actions'] = $actionsConfig;
            }
        }

        return $backendConfig;
    }
Actions can be added/removed globally in the edit/list/new/show views of
the backend and locally in each of the configured entities. Local config always
wins over the global config (e.g. if backend removes 'delete' action in the
'list' view but some action explicitly adds 'delete' in its 'list' view,
then that entity shows the 'delete' action and the others don't).