View source
<?php
namespace Drupal\Core\FileTransfer\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
class FileTransferAuthorizeForm extends FormBase {
protected $root;
public function __construct($root) {
$this->root = $root;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('app.root'));
}
public function getFormId() {
return 'authorize_filetransfer_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$available_backends = $this
->getRequest()
->getSession()
->get('authorize_filetransfer_info', []);
if (empty($available_backends)) {
$this
->messenger()
->addError($this
->t('Unable to continue, no available methods of file transfer'));
return [];
}
if (!$this
->getRequest()
->isSecure()) {
$form['information']['https_warning'] = [
'#prefix' => '<div class="messages messages--error">',
'#markup' => $this
->t('WARNING: You are not using an encrypted connection, so your password will be sent in plain text. <a href=":https-link">Learn more</a>.', [
':https-link' => 'https://www.drupal.org/https-information',
]),
'#suffix' => '</div>',
];
}
$authorize_filetransfer_default = $form_state
->getValue([
'connection_settings',
'authorize_filetransfer_default',
]);
if (!$authorize_filetransfer_default) {
$authorize_filetransfer_default = key($available_backends);
}
$form['information']['main_header'] = [
'#prefix' => '<h3>',
'#markup' => $this
->t('To continue, provide your server connection details'),
'#suffix' => '</h3>',
];
$form['connection_settings']['#tree'] = TRUE;
$form['connection_settings']['authorize_filetransfer_default'] = [
'#type' => 'select',
'#title' => $this
->t('Connection method'),
'#default_value' => $authorize_filetransfer_default,
'#weight' => -10,
];
$form['submit_connection'] = [
'#prefix' => "<br style='clear:both'/>",
'#name' => 'enter_connection_settings',
'#type' => 'submit',
'#value' => $this
->t('Enter connection settings'),
'#weight' => 100,
];
$form['submit_process'] = [
'#name' => 'process_updates',
'#type' => 'submit',
'#value' => $this
->t('Continue'),
'#weight' => 100,
];
foreach ($available_backends as $name => $backend) {
$form['connection_settings']['authorize_filetransfer_default']['#options'][$name] = $backend['title'];
$form['connection_settings'][$name] = [
'#type' => 'container',
'#attributes' => [
'class' => [
"filetransfer-{$name}",
'filetransfer',
],
],
'#states' => [
'visible' => [
'select[name="connection_settings[authorize_filetransfer_default]"]' => [
'value' => $name,
],
],
],
];
$form['connection_settings'][$name]['header'] = [
'#markup' => '<h4>' . $this
->t('@backend connection settings', [
'@backend' => $backend['title'],
]) . '</h4>',
];
$form['connection_settings'][$name] += $this
->addConnectionSettings($name);
if ($form_state
->getValue([
'connection_settings',
'authorize_filetransfer_default',
]) == $name) {
$form['submit_process']['#attributes'] = [];
unset($form['submit_connection']);
$form['connection_settings'][$name]['#attributes']['style'] = 'display:block';
$form['connection_settings']['authorize_filetransfer_default']['#disabled'] = TRUE;
$form['connection_settings']['change_connection_type'] = [
'#name' => 'change_connection_type',
'#type' => 'submit',
'#value' => $this
->t('Change connection type'),
'#weight' => -5,
'#attributes' => [
'class' => [
'filetransfer-change-connection-type',
],
],
];
}
}
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
if ($form_state
->getTriggeringElement()['#name'] != 'process_updates') {
return;
}
if ($form_connection_settings = $form_state
->getValue('connection_settings')) {
$backend = $form_connection_settings['authorize_filetransfer_default'];
$filetransfer = $this
->getFiletransfer($backend, $form_connection_settings[$backend]);
try {
if (!$filetransfer) {
throw new \Exception("The connection protocol '{$backend}' does not exist.");
}
$filetransfer
->connect();
} catch (\Exception $e) {
$form_state
->setErrorByName('connection_settings', $this
->t('Failed to connect to the server. The server reports the following message: <p class="error">@message</p> For more help installing or updating code on your server, see the <a href=":handbook_url">handbook</a>.', [
'@message' => $e
->getMessage(),
':handbook_url' => 'https://www.drupal.org/docs/8/extending-drupal-8/overview',
]));
}
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$form_connection_settings = $form_state
->getValue('connection_settings');
switch ($form_state
->getTriggeringElement()['#name']) {
case 'process_updates':
$filetransfer_backend = $form_connection_settings['authorize_filetransfer_default'];
try {
$filetransfer = $this
->getFiletransfer($filetransfer_backend, $form_connection_settings[$filetransfer_backend]);
$response = $this
->runOperation($filetransfer);
if ($response instanceof Response) {
$form_state
->setResponse($response);
}
} catch (\Exception $e) {
}
break;
case 'enter_connection_settings':
$form_state
->setRebuild();
break;
case 'change_connection_type':
$form_state
->setRebuild();
$form_state
->unsetValue([
'connection_settings',
'authorize_filetransfer_default',
]);
break;
}
}
protected function getFiletransfer($backend, $settings = []) {
$filetransfer = FALSE;
$info = $this
->getRequest()
->getSession()
->get('authorize_filetransfer_info', []);
if (!empty($info[$backend])) {
if (class_exists($info[$backend]['class'])) {
$filetransfer = $info[$backend]['class']::factory($this->root, $settings);
}
}
return $filetransfer;
}
protected function addConnectionSettings($backend) {
$defaults = [];
$form = [];
$filetransfer = $this
->getFiletransfer($backend);
if ($filetransfer) {
$form = $filetransfer
->getSettingsForm();
}
$this
->setConnectionSettingsDefaults($form, NULL, $defaults);
return $form;
}
protected function setConnectionSettingsDefaults(&$element, $key, array $defaults) {
if (!empty($key) && isset($defaults[$key]) && isset($element['#type']) && $element['#type'] != 'details') {
$element['#default_value'] = $defaults[$key];
}
foreach (Element::children($element) as $child_key) {
$this
->setConnectionSettingsDefaults($element[$child_key], $child_key, isset($defaults[$key]) && is_array($defaults[$key]) ? $defaults[$key] : $defaults);
}
}
protected function runOperation($filetransfer) {
$operation = $this
->getRequest()
->getSession()
->remove('authorize_operation');
require_once $operation['file'];
return call_user_func_array($operation['callback'], array_merge([
$filetransfer,
], $operation['arguments']));
}
}