Same filename and directory in other branches
  1. 8.x-1.x entity_redirect.module 1 comment

Manages post edit/create redirection for entities.

File

./entity_redirect.module

View source
<?php


/**
 * @file
 * Manages post edit/create redirection for entities.
 */
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Render\Element\PathElement;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Url;

/**
 * Implements hook_help().
 */
function entity_redirect_help($route_name, RouteMatchInterface $route_match) {
    switch ($route_name) {
        case 'help.page.entity_redirect':
            $output = '';
            $output .= '<h3>' . t('About') . '</h3>';
            $output .= '<p>' . t('The Entity Redirect module adds a configurable redirect after saving a node or other entity.The redirect is configurable per bundle. Also, given sufficient permissions (and presuming it is enabled for that specific content/bundle), individual users can configure their own redirects (on their profile edit page).') . '</p>';
            $output .= '<h3>' . t('Configuration') . '</h3>';
            $output .= '<p>' . t('Configuration can be accessed for each supported entity bundle on the edit page for that entity type. For example for the Node type Article that would be at /admin/structure/types/manage/article. The configuration will be in the publishing options section if available.');
            $output .= '<h3>' . t('Uses') . '</h3>';
            $output .= '<dl>';
            $output .= '<dt>' . t('Default') . '</dt>';
            $output .= '<dd>' . t('This will not impact the entity but will just go to the default.') . '</dd>';
            $output .= '<dt>' . t('Add Form') . '</dt>';
            $output .= '<dd>' . t('Redirect to a new add form for the content type/entity.') . '</dd>';
            $output .= '<dt>' . t('Return to Edit Form') . '</dt>';
            $output .= '<dd>' . t('Redirect back to the edit form of the entity.') . '</dd>';
            $output .= '<dt>' . t('Local Url') . '</dt>';
            $output .= '<dd>' . t('provide a local url in the form of /about to go to any page on the site.') . '</dd>';
            $output .= '<dt>' . t('Created entity') . '</dt>';
            $output .= '<dd>' . t('Redirect to the view of the entity') . '</dd>';
            $output .= '<dt>' . t('Go to Layout Builder Page') . '</dt>';
            $output .= '<dd>' . t('If Layout Builder module is enabled, redirect to the layout builder page of the entity.') . '</dd>';
            $output .= '<dt>' . t('External Url') . '</dt>';
            $output .= '<dd>' . t('Same as local url but to an external location. Note: this is only available to users with the permission set external entity redirects.') . '</dd>';
            $output .= '<dt>' . t('Return to the previous page') . '</dt>';
            $output .= '<dd>' . t('Redirects to the page where the form was submited from.') . '</dd>';
            $output .= '</dl>';
            return $output;
        default:
    }
}

/**
 * Implements hook_form_alter().
 */
function entity_redirect_form_alter(&$form, FormStateInterface $form_state, $form_id) {
    
    /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */
    $form_object = $form_state->getFormObject();
    if (!is_a($form_object, '\\Drupal\\Core\\Entity\\EntityFormInterface')) {
        return;
    }
    $entity = $form_object->getEntity();
    if (is_a($entity, '\\Drupal\\Core\\Config\\Entity\\ConfigEntityBundleBase')) {
        if (is_a($form_object, '\\Drupal\\Core\\Entity\\EntityDeleteForm')) {
            return;
        }
        
        /** @var \Drupal\Core\Config\Entity\ConfigEntityBundleBase $entity */
        $settings = $entity->getThirdPartySettings('entity_redirect');
        $user = \Drupal::currentUser();
        $form['workflow']['entity_redirect'] = [
            '#type' => 'fieldset',
            '#title' => t('Redirect after Entity Operations'),
            '#tree' => TRUE,
        ];
        $actions = [
            'add' => t('Add'),
            'edit' => t('Edit'),
            'delete' => t('Delete'),
            'anonymous' => t('Override for Anonymous Users'),
        ];
        $destination = [
            'default' => t('- Default -'),
            'add_form' => t('Add Form'),
            'edit_form' => t('Return to Edit Form'),
            'url' => t('Local Url'),
            'created' => t('Created %entity_label', [
                '%entity_label' => $entity->label(),
            ]),
            'previous_page' => t('Return to the previous page'),
        ];
        $no_destionation_delete = [
            'edit_form' => t('Return to Edit Form'),
            'created' => t('Created %entity_label', [
                '%entity_label' => $entity->label(),
            ]),
        ];
        if (\Drupal::moduleHandler()->moduleExists('layout_builder')) {
            $destination['layout_builder'] = t('Go to Layout Builder Page');
        }
        foreach ($actions as $action => $title) {
            $options = $settings['redirect'][$action] ?? [];
            $form['workflow']['entity_redirect'][$action] = [
                '#type' => 'details',
                '#open' => FALSE,
                '#title' => $title,
                'active' => [
                    '#type' => 'checkbox',
                    '#title' => t('Enable'),
                    '#default_value' => $options['active'] ?? FALSE,
                ],
                'destination' => [
                    '#type' => 'select',
                    '#title' => t('Redirect Destination'),
                    '#options' => $action == 'delete' ? array_diff($destination, $no_destionation_delete) : $destination,
                    '#default_value' => $options['destination'] ?? 'default',
                    '#states' => [
                        'visible' => [
                            "[name='entity_redirect[{$action}][active]']" => [
                                'checked' => TRUE,
                            ],
                        ],
                    ],
                ],
                'url' => [
                    '#type' => 'path',
                    '#title' => t('Local Destination Url'),
                    '#description' => t('Path to redirect the user to after submission of forms for this entity. For example, type "/about" to redirect to that page. Use a relative path with a slash in front.'),
                    '#default_value' => $options['url'] ?? '',
                    '#convert_path' => PathElement::CONVERT_NONE,
                    '#states' => [
                        'visible' => [
                            "[name='entity_redirect[{$action}][destination]']" => [
                                'value' => 'url',
                            ],
                            "[name='entity_redirect[{$action}][active]']" => [
                                'checked' => TRUE,
                            ],
                        ],
                    ],
                ],
                'external' => [
                    '#type' => 'url',
                    '#title' => t('External Destination Url'),
                    '#description' => t('Enter a fully qualified url such as https://example.com/page.'),
                    '#default_value' => $options['external'] ?? '',
                    '#access' => $user->hasPermission('set external entity redirects'),
                    '#states' => [
                        'visible' => [
                            "[name='entity_redirect[{$action}][destination]']" => [
                                'value' => 'external',
                            ],
                            "[name='entity_redirect[{$action}][active]']" => [
                                'checked' => TRUE,
                            ],
                        ],
                    ],
                ],
            ];
            if ($user->hasPermission('set external entity redirects')) {
                $form['workflow']['entity_redirect'][$action]['destination']['#options']['external'] = t('External URL');
            }
        }
        $form['#entity_builders'][] = 'entity_redirect_bundle_builder';
    }
    elseif (is_a($entity, '\\Drupal\\Core\\Entity\\ContentEntityBase')) {
        
        /** @var \Drupal\Core\Entity\ContentEntityBase $entity */
        if (!($bundle_type = $entity->getEntityType()
            ->getBundleEntityType())) {
            return;
        }
        
        /** @var \Drupal\Core\Config\Entity\ConfigEntityBundleBase $bundle */
        $bundle = \Drupal::entityTypeManager()->getStorage($bundle_type)
            ->load($entity->bundle());
        if (!$bundle->getThirdPartySetting('entity_redirect', 'redirect')) {
            return;
        }
        // Create a hidden field to store the HTTP_REFERER variable.
        $form['http_referer'] = [
            '#type' => 'hidden',
            '#default_value' => $_SERVER['HTTP_REFERER'] ?? "",
        ];
        $form['actions']['submit']['#submit'][] = $entity->isNew() ? 'entity_redirect_new' : 'entity_redirect_submit';
    }
}

/**
 * Entity form builder for bundle forms to save values to 3rd party settings.
 */
function entity_redirect_bundle_builder($entity_type, ConfigEntityInterface $type, &$form, FormStateInterface $form_state) {
    $type->setThirdPartySetting('entity_redirect', 'redirect', $form_state->getValue('entity_redirect'));
}

/**
 * Submit function to handle the redirection per entity create/edit action.
 */
function entity_redirect_new($form, FormStateInterface $form_state) {
    $form_state->set('entity_redirect_new', TRUE);
    entity_redirect_submit($form, $form_state);
}

/**
 * Submit function to handle the redirection per entity create/edit action.
 */
function entity_redirect_submit($form, FormStateInterface $form_state) {
    
    /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */
    $form_object = $form_state->getFormObject();
    if (!is_a($form_object, '\\Drupal\\Core\\Entity\\EntityFormInterface')) {
        return;
    }
    $entity = $form_object->getEntity();
    if (is_a($entity, '\\Drupal\\Core\\Entity\\ContentEntityBase')) {
        
        /** @var \Drupal\Core\Entity\ContentEntityBase $entity */
        $entity_type = $entity->getEntityType();
        if (!($bundle_type = $entity_type->getBundleEntityType())) {
            return;
        }
        
        /** @var \Drupal\Core\Config\Entity\ConfigEntityBundleBase $bundle */
        $bundle = \Drupal::entityTypeManager()->getStorage($bundle_type)
            ->load($entity->bundle());
        if (!($options = $bundle->getThirdPartySetting('entity_redirect', 'redirect'))) {
            return;
        }
        $user = \Drupal::currentUser();
        if ($user->isAnonymous() && !empty($options['anonymous']['active'])) {
            $settings = $options['anonymous'];
        }
        elseif (is_a($form_object, 'Drupal\\Core\\Entity\\ContentEntityDeleteForm')) {
            if (empty($options['delete']['active'])) {
                return;
            }
            $settings = $options['delete'];
        }
        elseif ($form_state->has('entity_redirect_new')) {
            if (empty($options['add']['active'])) {
                return;
            }
            $entity->save();
            $settings = $options['add'];
        }
        else {
            if (empty($options['edit']['active'])) {
                return;
            }
            $settings = $options['edit'];
        }
        if ($settings['destination'] != 'default') {
            // Remove the default destination parameter.
            \Drupal::request()->query
                ->remove('destination');
        }
        switch ($settings['destination']) {
            case 'add_form':
                $route_provider = \Drupal::service('router.route_provider');
                $routes = array_keys($route_provider->getRoutesByNames([
                    "{$entity_type->id()}.add",
                    "entity.{$entity_type->id()}.add_form",
                ]));
                $form_state->setRedirect($routes[0], [
                    $bundle_type => $bundle->id(),
                ]);
                break;
            case 'edit_form':
                $route_provider = \Drupal::service('router.route_provider');
                $routes = array_keys($route_provider->getRoutesByNames([
                    "{$entity_type->id()}.edit",
                    "entity.{$entity_type->id()}.edit_form",
                ]));
                $form_state->setRedirect($routes[0], [
                    $entity_type->id() => $entity->id(),
                ]);
                break;
            case 'created':
                $form_state->setRedirect("entity.{$entity_type->id()}.canonical", [
                    $entity_type->id() => $entity->id(),
                ]);
                break;
            case 'url':
                if (empty($settings['url'])) {
                    return;
                }
                $form_state->setRedirectUrl(Url::fromUri('internal:' . $settings['url']));
                break;
            case 'previous_page':
                $http_referer = $form_state->getValue('http_referer');
                $pos = strpos($http_referer, \Drupal::request()->getHost());
                $referer_path = substr($http_referer, $pos + strlen(\Drupal::request()->getHost()));
                $form_state->setRedirectUrl(Url::fromUri('internal:' . $referer_path));
                break;
            case 'layout_builder':
                $form_state->setRedirectUrl(Url::fromUri('internal:' . $entity->toUrl()
                    ->toString() . '/layout'));
                break;
            case 'external':
                if (empty($settings['external'])) {
                    return;
                }
                $response = new TrustedRedirectResponse($settings['external']);
                $form_state->setResponse($response);
        }
    }
}

Functions

Title Deprecated Summary
entity_redirect_bundle_builder Entity form builder for bundle forms to save values to 3rd party settings.
entity_redirect_form_alter Implements hook_form_alter().
entity_redirect_help Implements hook_help().
entity_redirect_new Submit function to handle the redirection per entity create/edit action.
entity_redirect_submit Submit function to handle the redirection per entity create/edit action.