View source
<?php
namespace Drupal\layouter\Form;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
class LayouterForm extends FormBase {
protected $steps = 2;
protected $templates;
public function __construct() {
$this->templates = \Drupal::moduleHandler()
->invokeAll('layouter_templates_info');
}
public function getFormId() {
return 'layouter_multistep_form';
}
public function buildForm(array $form, FormStateInterface $form_state, $textarea_id = NULL) {
$step = $form_state
->get('step');
if (!$step) {
$step = 1;
$form_state
->set('step', $step);
}
$form['#prefix'] = '<div id="layouter-form-wrapper" class="layouter-form">';
$form['#sufix'] = '</div>';
$form['errors'] = [];
$button_label = '';
if ($step == 1) {
$options = [];
foreach ($this->templates as $id => $params) {
$options[$id] = $params['title']
->render();
}
$form['data']['type'] = [
'#title' => $this
->t('Choose the layout'),
'#type' => 'radios',
'#options' => $options,
'#required' => TRUE,
'#after_build' => [
'::processLayoutTypeRadios',
],
];
$button_label = $this
->t('Next');
}
if ($step == 2) {
$this
->buildLayouterFields($form, $form_state);
$button_label = $this
->t('Submit');
}
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $button_label,
'#name' => 'submit_button',
'#attributes' => [
'class' => [
'use-ajax-submit',
],
],
'#ajax' => [
'callback' => '::ajaxResponse',
],
];
$form['actions']['cancel'] = [
'#type' => 'submit',
'#value' => $this
->t('Cancel'),
'#name' => 'cancel_button',
'#submit' => [
'::cancelForm',
],
'#limit_validation_errors' => [],
'#attributes' => [
'class' => [
'use-ajax-submit',
],
],
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$step = $form_state
->get('step');
if ($step < $this->steps) {
$form_state
->setRebuild();
if ($step == 1) {
$form_state
->set('type', $form_state
->getValue('type'));
}
}
$step++;
$form_state
->set('step', $step);
}
public function ajaxResponse(array &$form, FormStateInterface $form_state) {
if ($form_state
->hasAnyErrors()) {
$form['errors']['#prefix'] = '<div class="messages messages--error">';
$form['errors']['#suffix'] = '</div>';
$form['errors']['#markup'] = '';
$mess = $this
->messenger()
->messagesByType('error');
foreach ($mess as $errors) {
foreach ($errors as $error) {
$form['errors']['#markup'] .= $error . '<br />';
}
}
$form_state
->clearErrors();
}
$step = $form_state
->get('step');
$response = new AjaxResponse();
if ($step == $this->steps + 1 && $form_state
->isExecuted()) {
$textarea_id = $form_state
->getBuildInfo()['args'][0];
$content = $this
->buildResponseHtml($form_state);
$command = new CloseModalDialogCommand();
$response
->addCommand($command);
$command = new InvokeCommand(NULL, 'layouterAddContent', [
$textarea_id,
$content,
]);
$response
->addCommand($command);
}
else {
$command = new ReplaceCommand('#layouter-form-wrapper', $form);
$response
->addCommand($command);
}
return $response;
}
public function cancelForm(array &$form, FormStateInterface $form_state) {
if ($form_state
->hasFileElement()) {
foreach ($form_state
->get('fields') as $name => $params) {
if ($params['type'] == 'image') {
$input = $form_state
->getUserInput();
if (!empty($input[$name]['fids'])) {
File::load($input[$name]['fids'])
->delete();
}
}
}
}
$response = new AjaxResponse();
$response
->addCommand(new CloseModalDialogCommand());
$form_state
->setResponse($response);
}
public function processLayoutTypeRadios(array $element) {
foreach ($this->templates as $id => $params) {
if (!empty($element[$id])) {
$element[$id]['#prefix'] = '<div class="layouter-radio-wrapper ' . $id . '" title="' . $params['title'] . '">';
$element[$id]['#suffix'] = '</div>';
}
}
return $element;
}
private function textContentHandler($name, array $params) {
$result[$name] = [
'#type' => 'textarea',
'#title' => $params['title'],
'#description' => $params['description'],
'#rows' => 10,
'#required' => 1,
];
return $result;
}
private function imageContentHandler($name, array $params) {
$fieldset_name = 'image_' . $name;
$result['#type'] = 'fieldset';
$result['#title'] = $params['title'];
$allowed_extensions = [
'png gif jpeg jpg',
];
$max_upload_size_mb = (int) ini_get('upload_max_filesize');
$max_upload_size = [
$max_upload_size_mb * 1024 * 1024,
];
$image_field_description = $this
->t('Files must be less than @size.', [
'@size' => format_size($max_upload_size[0]),
]);
$image_field_description .= '<br />' . $this
->t('Allowed file types: @extensions.', [
'@extensions' => $allowed_extensions[0],
]);
if (!empty($params['description'])) {
$image_field_description .= '<br />' . $params['description'];
}
$location_scheme = \Drupal::config('layouter.settings')
->get('uri_scheme');
$result[$name] = [
'#type' => 'managed_file',
'#title' => $this
->t('Image'),
'#field_name' => 'layouter_image',
'#description' => $image_field_description,
'#required' => 1,
'#upload_location' => $location_scheme . '://layouter_images',
'#upload_validators' => [
'file_validate_extensions' => $allowed_extensions,
'file_validate_size' => [
$max_upload_size,
],
],
];
$result[$name . '_alt'] = [
'#type' => 'textfield',
'#title' => $this
->t('Alternative text'),
];
if (\Drupal::currentUser()
->hasPermission('administer image styles')) {
$url = Url::fromRoute('entity.image_style.collection')
->getInternalPath();
$description = $this
->t('You can also') . ' <a href="/' . $url . '" target="_blank">' . $this
->t('add your own image style') . '</a> ' . $this
->t('if you need to.');
$admin_image_style_description = $description;
}
else {
$admin_image_style_description = '';
}
$image_styles = \Drupal::config('layouter.settings')
->get('image_styles');
$image_styles_options['none'] = 'none';
foreach ($image_styles as $k => $v) {
if ($v != '0') {
$image_styles_options[$k] = $v;
}
}
$result[$name . '_style'] = [
'#type' => 'select',
'#title' => $this
->t('Image style'),
'#required' => TRUE,
'#options' => $image_styles_options,
'#description' => $admin_image_style_description,
];
$fieldset[$fieldset_name] = $result;
return $fieldset;
}
private function buildResponseHtml(FormStateInterface $form_state) {
$content = [
'#theme' => $this->templates[$form_state
->get('type')]['theme'],
];
$fields = $form_state
->get('fields');
foreach ($fields as $field_name => $fiels_params) {
switch ($fiels_params['type']) {
case 'image':
$image_fid = $form_state
->getValue($field_name)[0];
$image = File::load($image_fid);
$image
->setPermanent();
$image
->save();
$image_style = $form_state
->getValue($field_name . '_style');
if ($image_style == 'none') {
$image_content = [
'#theme' => 'image',
];
}
else {
$image_content = [
'#theme' => 'image_style',
'#style_name' => $image_style,
];
}
$image_content['#uri'] = $image
->getFileUri();
$image_content['#alt'] = $form_state
->getValue($field_name . '_alt');
$content['#' . $field_name] = render($image_content);
break;
case 'text':
$content['#' . $field_name] = $form_state
->getValue($field_name);
break;
}
}
return render($content);
}
private function buildLayouterFields(array &$form, FormStateInterface $form_state) {
$type = $form_state
->get('type');
$fields = $this->templates[$type]['fields'];
if (!is_null($fields)) {
$form_state
->set('fields', $fields);
$form['data'] = [];
foreach ($fields as $name => $params) {
$params['description'] = isset($params['description']) ? $params['description'] : '';
if ($params['type'] == 'image') {
$params['title'] = isset($params['title']) ? $params['title'] : $this
->t('Image settings');
$form['data'] += $this
->imageContentHandler($name, $params);
}
if ($params['type'] == 'text') {
$params['title'] = isset($params['title']) ? $params['title'] : $this
->t('Text');
$form['data'] += $this
->textContentHandler($name, $params);
}
}
}
}
}