View source
<?php
namespace Drupal\redirect\Plugin\Field\FieldWidget;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Url;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
class RedirectSourceWidget extends WidgetBase {
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$default_url_value = $items[$delta]->path;
if ($items[$delta]->query) {
$default_url_value .= '?' . http_build_query($items[$delta]->query);
}
$element['path'] = [
'#type' => 'textfield',
'#title' => $this
->t('Path'),
'#placeholder' => $this
->getSetting('placeholder_url'),
'#default_value' => $default_url_value,
'#maxlength' => 2048,
'#required' => $element['#required'],
'#field_prefix' => Url::fromRoute('<front>', [], [
'absolute' => TRUE,
])
->toString(),
'#attributes' => [
'data-disable-refocus' => 'true',
],
];
if ($items
->getEntity()
->isNew()) {
$element['status_box'] = [
'#prefix' => '<div id="redirect-link-status">',
'#suffix' => '</div>',
];
$source_path = $form_state
->getValue([
'redirect_source',
0,
'path',
]);
if ($source_path) {
$source_path = trim($source_path);
try {
\Drupal::service('router')
->match('/' . $form_state
->getValue([
'redirect_source',
0,
'path',
]));
$element['status_box'][]['#markup'] = '<div class="messages messages--warning">' . $this
->t('The source path %path is likely a valid path. It is preferred to <a href="@url-alias">create URL aliases</a> for existing paths rather than redirects.', [
'%path' => $source_path,
'@url-alias' => Url::fromRoute('entity.path_alias.add_form')
->toString(),
]) . '</div>';
} catch (ResourceNotFoundException $e) {
} catch (AccessDeniedHttpException $e) {
}
$parsed_url = UrlHelper::parse($source_path);
$path = isset($parsed_url['path']) ? $parsed_url['path'] : NULL;
if (!empty($path)) {
$repository = \Drupal::service('redirect.repository');
$redirects = $repository
->findBySourcePath($path);
if (!empty($redirects)) {
$redirect = array_shift($redirects);
$element['status_box'][]['#markup'] = '<div class="messages messages--warning">' . $this
->t('The base source path %source is already being redirected. Do you want to <a href="@edit-page">edit the existing redirect</a>?', [
'%source' => $source_path,
'@edit-page' => $redirect
->toUrl('edit-form')
->toString(),
]) . '</div>';
}
}
}
$element['path']['#ajax'] = [
'callback' => 'redirect_source_link_get_status_messages',
'wrapper' => 'redirect-link-status',
];
}
return $element;
}
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
$values = parent::massageFormValues($values, $form, $form_state);
foreach ($values as &$value) {
if (!empty($value['path'])) {
if (strpos($value['path'], '?') !== FALSE) {
$url = UrlHelper::parse($value['path']);
$value['path'] = $url['path'];
$value['query'] = $url['query'];
}
}
}
return $values;
}
}