class ForwardForm in Forward 8
Same name in this branch
- 8 src/Form/ForwardForm.php \Drupal\forward\Form\ForwardForm
- 8 src/Plugin/DsField/ForwardForm.php \Drupal\forward\Plugin\DsField\ForwardForm
Same name and namespace in other branches
- 8.3 src/Form/ForwardForm.php \Drupal\forward\Form\ForwardForm
- 8.2 src/Form/ForwardForm.php \Drupal\forward\Form\ForwardForm
- 4.x src/Form/ForwardForm.php \Drupal\forward\Form\ForwardForm
- 4.0.x src/Form/ForwardForm.php \Drupal\forward\Form\ForwardForm
Forward a page to a friend
Hierarchy
- class \Drupal\Core\Form\FormBase implements ContainerInjectionInterface, FormInterface uses DependencySerializationTrait, LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\forward\Form\ForwardForm implements BaseFormIdInterface
Expanded class hierarchy of ForwardForm
1 file declares its use of ForwardForm
File
- src/
Form/ ForwardForm.php, line 30
Namespace
Drupal\forward\FormView source
class ForwardForm extends FormBase implements BaseFormIdInterface {
/**
* The entity being forwarded.
*
* @var Drupal\Core\Entity\EntityInterface
*/
protected $entity;
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The token service.
*
* @var \Drupal\Core\Utility\Token
*/
protected $tokenService;
/**
* The flood interface.
*
* @var \Drupal\Core\Flood\FloodInterface
*/
protected $floodInterface;
/**
* The account switcher service.
*
* @var \Drupal\Core\Session\AccountSwitcherInterface
*/
protected $accountSwitcher;
/**
* The render service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* The event dispatcher service.
*
* @var \Symfony\Component\EventDispatcher;
*/
protected $eventDispatcher;
/**
* The mail service.
*
* @var \Drupal\Core\Mail\MailManager
*/
protected $mailer;
/**
* The link generation service.
*
* @var \Drupal\Core\Utility\LinkGenerator
*/
protected $linkGenerator;
/**
* The settings for this form.
*
* @var array
*/
protected $settings;
/**
* Constructs a Forward Form.
*
* @param Drupal\Core\Entity\EntityInterface $entity
* The entity being forwarded.
*/
public function __construct(EntityInterface $entity) {
$this->entity = $entity;
}
/**
* Inject services.
*
* @param \Drupal\Core\Extension\ModuleHandlerInterface
* The module handler service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface
* The entity type manager.
* @param \Symfony\Component\HttpFoundation\RequestStack
* The request stack.
* @param \Drupal\Core\Database\Connection
* The database connection.
* @param \Drupal\Core\Utility\Token
* The token service.
* @param \Drupal\Core\Flood\FloodInterface
* The flood interface.
* @param \Drupal\Core\Session\AccountSwitcherInterface
* The account switcher service.
* @param \Drupal\Core\Render\RendererInterface
* The render service.
* @param \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
* The event dispatcher service.
* @param \Drupal\Core\Mail\MailManager
* The mail service.
* @param \Drupal\Core\Utility\LinkGenerator
* The link generation service.
*/
public function injectServices(ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, RequestStack $request_stack, Connection $database, Token $token_service, FloodInterface $flood_interface, AccountSwitcherInterface $account_switcher, RendererInterface $renderer, ContainerAwareEventDispatcher $event_dispatcher, MailManager $mailer, LinkGenerator $link_generator) {
$this->moduleHandler = $module_handler;
$this->entityTypeManager = $entity_type_manager;
$this->requestStack = $request_stack;
$this->database = $database;
$this->tokenService = $token_service;
$this->floodInterface = $flood_interface;
$this->accountSwitcher = $account_switcher;
$this->renderer = $renderer;
$this->eventDispatcher = $event_dispatcher;
$this->mailer = $mailer;
$this->linkGenerator = $link_generator;
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'forward_form_' . $this->entity
->getEntityTypeId() . '_' . $this->entity
->id();
}
/**
* {@inheritdoc}
*/
public function getBaseFormId() {
return 'forward_form';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'forward.form',
];
}
/**
* Clean a string
*/
private function cleanString($string) {
// Strip embedded URLs
$string = preg_replace('|https?://www\\.[a-z\\.0-9]+|i', '', $string);
$string = preg_replace('|www\\.[a-z\\.0-9]+|i', '', $string);
return $string;
}
/**
* Get a token
*/
private function getToken(FormStateInterface $form_state = NULL) {
$token = array();
if ($form_state && $form_state
->getValue('name')) {
// Harden the name field against abuse. @see https://www.drupal.org/node/2793891
$token = [
'forward' => [
'sender_name' => $this
->cleanString($form_state
->getValue('name')),
],
];
}
elseif ($this
->currentUser()
->isAuthenticated()) {
$token = [
'forward' => [
'sender_name' => $this
->currentUser()
->getDisplayName(),
],
];
}
if ($form_state && $form_state
->getValue('email')) {
$token['forward']['sender_email'] = $form_state
->getValue('email');
}
elseif ($this
->currentUser()
->isAuthenticated()) {
$token['forward']['sender_email'] = $this
->currentUser()
->getEmail();
}
if ($form_state) {
$token['forward']['entity'] = $form_state
->get('#entity');
}
// Allow other modules to add more tokens
if ($extra_tokens = $this->moduleHandler
->invokeAll('forward_token', array(
$form_state,
))) {
$token += $extra_tokens;
}
return $token;
}
/**
* Get the event name used for Flood control
*/
private function getFloodControlEventName() {
return 'forward.send';
}
/**
* Determine if a given display is valid for an entity
*/
private function isValidDisplay(EntityInterface $entity, $view_mode) {
// Assume the display is valid
$valid = TRUE;
// Build display name
if ($entity
->getEntityType()
->hasKey('bundle')) {
// Bundled entity types, e.g. node
$display_name = $entity
->getEntityTypeId() . '.' . $entity
->bundle() . '.' . $view_mode;
}
else {
// Entity types without bundles, e.g. user
$display_name = $entity
->getEntityTypeId() . '.' . $view_mode;
}
// Attempt load
$display = $this->entityTypeManager
->getStorage('entity_view_display')
->load($display_name);
if ($display) {
// If the display loads, it exists in configuration, and status can be checked
$valid = FALSE;
if ($display
->status()) {
$valid = TRUE;
}
}
return $valid;
}
/**
* Logging
*/
private function logEvent(EntityInterface $entity) {
$entity_type = $entity
->getEntityTypeId();
$bundle = $entity
->bundle();
$entity_id = $entity
->id();
$uid = $this
->currentUser()
->id();
$path = substr($entity
->toUrl()
->toString(), 1);
$ip_address = $this->requestStack
->getCurrentRequest()
->getClientIp();
$timestamp = REQUEST_TIME;
// Insert into log
$this->database
->insert('forward_log')
->fields(array(
'type' => $entity_type,
'id' => $entity_id,
'path' => $path,
'action' => 'SENT',
'timestamp' => $timestamp,
'uid' => $uid,
'hostname' => $ip_address,
))
->execute();
// Update statistics
$this->database
->merge('forward_statistics')
->key(array(
'type' => $entity_type,
'bundle' => $bundle,
'id' => $entity_id,
))
->fields(array(
'forward_count' => 1,
'last_forward_timestamp' => $timestamp,
))
->expression('forward_count', 'forward_count + 1')
->execute();
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, array $settings = NULL) {
if (!$settings) {
$settings = $this
->config('forward.settings')
->get();
}
$this->settings = $settings;
$form_state
->set('#entity', $this->entity);
$token = $this
->getToken($form_state);
$langcode = $this->entity
->language()
->getId();
// Build the form
if ($settings['forward_interface_type'] == 'link') {
// Set the page title dynamically
$form['#title'] = $this->tokenService
->replace($settings['forward_link_title'], $token, array(
'langcode' => $langcode,
));
}
else {
// Inline form
$form['message'] = array(
'#type' => 'details',
'#title' => $this->tokenService
->replace($settings['forward_link_title'], $token, array(
'langcode' => $langcode,
)),
'#description' => '',
'#open' => FALSE,
'#weight' => $settings['forward_interface_weight'],
);
}
$form['message']['instructions'] = array(
'#markup' => $this->tokenService
->replace($settings['forward_form_instructions'], $token, array(
'langcode' => $langcode,
)),
);
$form['message']['email'] = array(
'#type' => 'email',
'#title' => $this
->t('Your email address'),
'#maxlength' => 254,
'#required' => TRUE,
);
$form['message']['name'] = array(
'#type' => 'textfield',
'#title' => $this
->t('Your name'),
'#maxlength' => 128,
'#required' => TRUE,
);
$form['message']['recipient'] = array(
'#type' => 'email',
'#title' => $this
->t('Send to'),
'#maxlength' => 254,
'#description' => $this
->t('Enter the email address of the recipient.'),
'#required' => TRUE,
);
if ($settings['forward_form_display_page']) {
$form['message']['page'] = array(
'#type' => 'item',
'#title' => $this
->t('You are going to email the following:'),
'#markup' => $this->linkGenerator
->generate($this->entity
->label(), $this->entity
->toUrl()),
);
}
if ($settings['forward_form_display_subject']) {
$form['message']['subject'] = array(
'#type' => 'item',
'#title' => $this
->t('The message subject will be:'),
'#markup' => $this->tokenService
->replace($settings['forward_email_subject'], $token, array(
'langcode' => $langcode,
)),
);
}
if ($settings['forward_form_display_body']) {
$form['message']['body'] = array(
'#type' => 'item',
'#title' => $this
->t('The introductory message text will be:'),
'#markup' => $this->tokenService
->replace($settings['forward_email_message'], $token, array(
'langcode' => $langcode,
)),
);
}
if ($settings['forward_personal_message']) {
$form['message']['message'] = array(
'#type' => 'textarea',
'#title' => $this
->t('Your personal message'),
'#default_value' => '',
'#cols' => 50,
'#rows' => 5,
'#description' => $settings['forward_personal_message_filter'] ? $this
->t('These HTML tags are allowed in this field: @tags.', array(
'@tags' => $settings['forward_personal_message_tags'],
)) : t('HTML is not allowed in this field.'),
'#required' => $settings['forward_personal_message'] == 2,
);
}
// Submit button
if ($settings['forward_interface_type'] == 'form') {
// When using a collapsible form, move submit button into fieldset
$form['message']['actions'] = array(
'#type' => 'actions',
);
$form['message']['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $this
->t('Send Message'),
'#weight' => 100,
);
}
else {
// When using a separate form page, use actions directly
$form['actions'] = array(
'#type' => 'actions',
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $this
->t('Send Message'),
);
}
// Default name and email address to logged in user
if ($this
->currentUser()
->isAuthenticated()) {
if ($this
->currentUser()
->hasPermission('override email address')) {
$form['message']['email']['#default_value'] = $this
->currentUser()
->getEmail();
}
else {
// User not allowed to change sender email address
$form['message']['email']['#type'] = 'hidden';
$form['message']['email']['#value'] = $this
->currentUser()
->getEmail();
}
$form['message']['name']['#default_value'] = $this
->currentUser()
->getDisplayName();
}
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
if (!$this
->currentUser()
->hasPermission('override flood control')) {
$event = $this
->getFloodControlEventName();
if (!$this->floodInterface
->isAllowed($event, $this->settings['forward_flood_control_limit'])) {
$message = new FormattableMarkup($this->settings['forward_flood_control_error'], [
'@number' => $this->settings['forward_flood_control_limit'],
]);
$form_state
->setErrorByName('', $message);
}
}
parent::validateForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// Get form values
$entity = $form_state
->get('#entity');
$recipient = $form_state
->getValue('recipient');
// Use the entity language to drive translation
$langcode = $entity
->language()
->getId();
// Switch to anonymous user session if logged in, unless bypassing access control
$switched = FALSE;
if ($this
->currentUser()
->isAuthenticated() && empty($this->settings['forward_bypass_access_control'])) {
$this->accountSwitcher
->switchTo(new AnonymousUserSession());
$switched = TRUE;
}
try {
// Build the message subject line
$token = $this
->getToken($form_state);
$params['subject'] = $this->tokenService
->replace($this->settings['forward_email_subject'], $token, array(
'langcode' => $langcode,
));
// Build the entity content
$view_mode = '';
$elements = array();
if ($entity
->access('view')) {
$view_builder = $this->entityTypeManager
->getViewBuilder($entity
->getEntityTypeId());
$view_mode = 'forward';
if ($this
->isValidDisplay($entity, $view_mode)) {
$elements = $view_builder
->view($entity, $view_mode, $langcode);
}
if (empty($elements)) {
$view_mode = 'teaser';
if ($this
->isValidDisplay($entity, $view_mode)) {
$elements = $view_builder
->view($entity, $view_mode, $langcode);
}
}
if (empty($elements)) {
$view_mode = 'full';
$elements = $view_builder
->view($entity, $view_mode, $langcode);
}
}
$elements['#forward_build'] = TRUE;
// prevent recursion
$content = $this->renderer
->render($elements);
// Build the header line
$header = [
'#markup' => $this->tokenService
->replace($this->settings['forward_email_message'], $token, array(
'langcode' => $langcode,
)),
];
// Build the personal message if present
$message = '';
if ($this->settings['forward_personal_message']) {
if ($this->settings['forward_personal_message_filter']) {
// HTML allowed in personal message, so filter out anything but the allowed tags
$raw_values = $form_state
->getUserInput();
$allowed_tags = explode(',', $this->settings['forward_personal_message_tags']);
$message = !empty($raw_values['message']) ? Xss::filter($raw_values['message'], $allowed_tags) : '';
$message = [
'#markup' => nl2br($message),
];
}
else {
// HTML not allowed in personal message, so use the sanitized version converted to plain text
$message = [
'#plain_text' => nl2br($form_state
->getValue('message')),
];
}
}
// Build the email body
$render_array = array(
'#theme' => 'forward',
'#email' => $form_state
->getValue('email'),
'#header' => $header,
'#message' => $message,
'#settings' => $this->settings,
'#entity' => $entity,
'#content' => $content,
'#view_mode' => $view_mode,
);
// Allow modules to alter the render array for the message
$this->moduleHandler
->alter('forward_mail_pre_render', $render_array, $form_state);
// Render the message
$params['body'] = $this->renderer
->render($render_array);
// Apply filters such as Pathologic for link correction
if ($this->settings['forward_filter_format']) {
// This filter was setup by the Forward administrator for this purpose only, whose permission to run the filter was checked at that time
// Therefore, no need to check filter access again here
$params['body'] = check_markup($params['body'], $this->settings['forward_filter_format'], $langcode);
}
// Allow modules to alter the final message body
$this->moduleHandler
->alter('forward_mail_post_render', $params['body'], $form_state);
} catch (Exception $e) {
if ($switched) {
$this->accountSwitcher
->switchBack();
$switched = FALSE;
}
$this
->logger('forward')
->error($e
->getMessage());
}
// Switch back to logged in user if necessary
if ($switched) {
$this->accountSwitcher
->switchBack();
}
// Build the from email address and Reply-To
$from = $this->settings['forward_email_from_address'];
if (empty($from)) {
$from = $this
->config('system.site')
->get('mail');
}
if (empty($from)) {
$site_mail = ini_get('sendmail_from');
}
$params['headers']['Reply-To'] = trim(Unicode::mimeHeaderEncode($form_state
->getValue('name')) . ' <' . $form_state
->getValue('email') . '>');
// Prepare for Event dispatch
$account = $this->entityTypeManager
->getStorage('user')
->load($this
->currentUser()
->id());
// Event dispatch - before forwarding
$event = new EntityPreforwardEvent($account, $entity, [
'account' => $account,
'entity' => $entity,
]);
$this->eventDispatcher
->dispatch(EntityPreforwardEvent::EVENT_NAME, $event);
// Send the email to the recipient
$key = 'send_entity';
$this->mailer
->mail('forward', $key, $recipient, $langcode, $params, $from);
// Log this for tracking purposes
$this
->logEvent($entity);
// Register event for flood control
$event = $this
->getFloodControlEventName();
$this->floodInterface
->register($event);
// Event dispatch - after forwarding
$event = new EntityForwardEvent($account, $entity, [
'account' => $account,
'entity' => $entity,
]);
$this->eventDispatcher
->dispatch(EntityForwardEvent::EVENT_NAME, $event);
// Allow modules to post process the forward
$this->moduleHandler
->invokeAll('forward_entity', array(
$account,
$entity,
$form_state,
));
// Display a confirmation message
$message = $this->tokenService
->replace($this->settings['forward_form_confirmation'], $token, array(
'langcode' => $langcode,
));
if ($message) {
drupal_set_message($message);
}
// Redirect back to entity page unless a redirect is already set
if ($this->settings['forward_interface_type'] == 'link') {
if (!$form_state
->getRedirect()) {
$form_state
->setRedirectUrl($entity
->toUrl());
}
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
FormBase:: |
protected | property | The config factory. | 1 |
FormBase:: |
protected | property | The route match. | |
FormBase:: |
protected | function | Retrieves a configuration object. | |
FormBase:: |
protected | function | Gets the config factory for this form. | 1 |
FormBase:: |
private | function | Returns the service container. | |
FormBase:: |
public static | function |
Instantiates a new instance of this class. Overrides ContainerInjectionInterface:: |
87 |
FormBase:: |
protected | function | Gets the current user. | |
FormBase:: |
protected | function | Gets the request object. | |
FormBase:: |
protected | function | Gets the route match. | |
FormBase:: |
protected | function | Gets the logger for a specific channel. | |
FormBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
FormBase:: |
public | function | Resets the configuration factory. | |
FormBase:: |
public | function | Sets the config factory for this form. | |
FormBase:: |
public | function | Sets the request stack object to use. | |
ForwardForm:: |
protected | property | The account switcher service. | |
ForwardForm:: |
protected | property | The database connection. | |
ForwardForm:: |
protected | property | The entity being forwarded. | |
ForwardForm:: |
protected | property | The entity type manager. | |
ForwardForm:: |
protected | property | The event dispatcher service. | |
ForwardForm:: |
protected | property | The flood interface. | |
ForwardForm:: |
protected | property |
The link generation service. Overrides LinkGeneratorTrait:: |
|
ForwardForm:: |
protected | property | The mail service. | |
ForwardForm:: |
protected | property | The module handler service. | |
ForwardForm:: |
protected | property | The render service. | |
ForwardForm:: |
protected | property |
The request stack. Overrides FormBase:: |
|
ForwardForm:: |
protected | property | The settings for this form. | |
ForwardForm:: |
protected | property | The token service. | |
ForwardForm:: |
public | function |
Form constructor. Overrides FormInterface:: |
|
ForwardForm:: |
private | function | Clean a string | |
ForwardForm:: |
public | function |
Returns a string identifying the base form. Overrides BaseFormIdInterface:: |
|
ForwardForm:: |
protected | function | ||
ForwardForm:: |
private | function | Get the event name used for Flood control | |
ForwardForm:: |
public | function |
Returns a unique string identifying the form. Overrides FormInterface:: |
|
ForwardForm:: |
private | function | Get a token | |
ForwardForm:: |
public | function | Inject services. | |
ForwardForm:: |
private | function | Determine if a given display is valid for an entity | |
ForwardForm:: |
private | function | Logging | |
ForwardForm:: |
public | function |
Form submission handler. Overrides FormInterface:: |
|
ForwardForm:: |
public | function |
Form validation handler. Overrides FormBase:: |
|
ForwardForm:: |
public | function | Constructs a Forward Form. | |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |