You are here

DashboardForm.php in Draggable dashboard 8.2

File

src/Form/DashboardForm.php
View source
<?php

namespace Drupal\draggable_dashboard\Form;

use Drupal\Component\Serialization\Json;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class DashboardForm.
 *
 * @package Drupal\draggable_dashboard\Form
 */
class DashboardForm extends EntityForm {

  /**
   * Block manager.
   *
   * @var \Drupal\Core\Block\BlockManagerInterface
   */
  protected $blockPluginManager;

  /**
   * Context repository.
   *
   * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface
   */
  protected $contextRepository;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    $instance = parent::create($container);
    $instance->blockPluginManager = $container
      ->get('plugin.manager.block');
    $instance->contextRepository = $container
      ->get('context.repository');
    return $instance;
  }

  /**
   * Sort blocks by weight.
   *
   * @param array $a
   * @param array $b
   *
   * @return int
   */
  protected function sortBlocks($a, $b) {
    return $a['weight'] > $b['weight'] ? +1 : -1;
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    $form = parent::form($form, $form_state);

    /** @var \Drupal\draggable_dashboard\Entity\DashboardEntityInterface $dashboard */
    $dashboard = $this->entity;
    $form['title'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Label'),
      '#maxlength' => 255,
      '#default_value' => $dashboard
        ->label(),
      '#description' => $this
        ->t('Label for the dashboard.'),
      '#required' => TRUE,
    ];
    $form['id'] = [
      '#type' => 'machine_name',
      '#maxlength' => 64,
      '#default_value' => $dashboard
        ->id(),
      '#machine_name' => [
        'exists' => [
          '\\Drupal\\draggable_dashboard\\Entity\\DashboardEntity',
          'load',
        ],
        'source' => [
          'title',
        ],
      ],
      '#disabled' => !$dashboard
        ->isNew(),
    ];
    $form['description'] = [
      '#title' => $this
        ->t('Description'),
      '#type' => 'textarea',
      '#default_value' => $dashboard
        ->get('description'),
      '#description' => '',
    ];
    if ($dashboard
      ->isNew()) {
      $form['columns'] = [
        '#type' => 'select',
        '#title' => $this
          ->t('Dashboard columns'),
        '#options' => [
          1 => $this
            ->t('1 Column'),
          2 => $this
            ->t('2 Columns'),
          3 => $this
            ->t('3 Columns'),
          4 => $this
            ->t('4 Columns'),
        ],
        '#default_value' => $dashboard
          ->get('columns'),
      ];
    }
    if (!$dashboard
      ->isNew()) {
      $form['#attached']['library'][] = 'core/drupal.tableheader';
      $form['#attached']['library'][] = 'draggable_dashboard/main';
      $form['dashboard_blocks_table'] = [
        '#type' => 'table',
        '#header' => [
          $this
            ->t('Block'),
          $this
            ->t('Region'),
          $this
            ->t('Weight'),
          [
            'data' => $this
              ->t('Operations'),
            'class' => [
              'text-align-right',
            ],
          ],
        ],
        '#empty' => $this
          ->t('No columns defined.'),
        '#attributes' => [
          'id' => 'dashboardblocks',
        ],
      ];

      // Prepare available regions list.
      $regionOptions = [];
      for ($i = 1; $i <= $dashboard
        ->get('columns'); $i++) {
        $regionOptions[$i] = $i . ' ' . $this
          ->t('Column');
      }
      $entities = $dashboard
        ->get('blocks');

      // Weights range from -delta to +delta, so delta should be at least half
      // of the amount of blocks present. This makes sure all blocks in the same
      // region get an unique weight.
      $weight_delta = round(count($entities) / 2);
      for ($i = 1; $i <= $dashboard
        ->get('columns'); $i++) {
        $region = $i;
        $title = $this
          ->t('Column #@id', [
          '@id' => $i,
        ]);
        $form['dashboard_blocks_table']['#tabledrag'][] = [
          'action' => 'match',
          'relationship' => 'sibling',
          'group' => 'block-region-select',
          'subgroup' => 'block-region-' . $region,
          'hidden' => FALSE,
        ];
        $form['dashboard_blocks_table']['#tabledrag'][] = [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'block-weight',
          'subgroup' => 'block-weight-' . $region,
        ];
        $form['dashboard_blocks_table']['region-' . $region] = [
          '#attributes' => [
            'class' => [
              'region-title',
              'region-title-' . $region,
            ],
            'no_striping' => TRUE,
          ],
        ];
        $form['dashboard_blocks_table']['region-' . $region]['title'] = [
          '#theme_wrappers' => [
            'container' => [
              '#attributes' => [
                'class' => 'region-title__action',
              ],
            ],
          ],
          '#prefix' => $title,
          '#type' => 'link',
          '#title' => $this
            ->t('Place block <span class="visually-hidden">in the %region region</span>', [
            '%region' => $title,
          ]),
          '#url' => Url::fromRoute('draggable_dashboard.block_library', [
            'dashboard_entity' => $dashboard
              ->id(),
            'region' => $region,
          ]),
          '#wrapper_attributes' => [
            'colspan' => 4,
          ],
          '#attributes' => [
            'class' => [
              'use-ajax',
              'button',
              'button--small',
              'place-blocks',
            ],
            'data-dialog-type' => 'modal',
            'data-dialog-options' => Json::encode([
              'width' => 700,
            ]),
          ],
        ];

        // Collect all blocks from one particular column.
        $relations = [];
        if (!empty($entities)) {
          foreach ($entities as $key => $entity) {
            if ($entity['column'] == $i) {
              $relations[$key] = $entity;
            }
          }
          uasort($relations, [
            $this,
            'sortBlocks',
          ]);
        }
        $form['dashboard_blocks_table']['region-' . $region . '-message'] = [
          '#attributes' => [
            'class' => [
              'region-message',
              'region-' . $region . '-message',
              empty($relations) ? 'region-empty' : 'region-populated',
            ],
          ],
        ];
        $form['dashboard_blocks_table']['region-' . $region . '-message']['message'] = [
          '#markup' => '<em>' . t('No blocks in this region') . '</em>',
          '#wrapper_attributes' => [
            'colspan' => 4,
          ],
        ];
        if (!empty($relations)) {
          foreach ($relations as $key => $relation) {

            /** @var \Drupal\Core\Block\BlockPluginInterface $block_instance */
            $block_instance = $this->blockPluginManager
              ->createInstance($relation['settings']['id'], $relation['settings']);
            $form['dashboard_blocks_table'][$key] = [
              '#attributes' => [
                'class' => [
                  'draggable',
                ],
              ],
            ];
            $form['dashboard_blocks_table'][$key]['info'] = [
              '#plain_text' => $block_instance
                ->label(),
              '#wrapper_attributes' => [
                'class' => [
                  'block',
                ],
              ],
            ];
            $form['dashboard_blocks_table'][$key]['column'] = [
              '#type' => 'select',
              '#default_value' => $relation['column'],
              '#required' => TRUE,
              '#title' => $this
                ->t('Region for @block block', [
                '@block' => $block_instance
                  ->label(),
              ]),
              '#title_display' => 'invisible',
              '#options' => $regionOptions,
              '#attributes' => [
                'class' => [
                  'block-region-select',
                  'block-region-' . $region,
                ],
              ],
            ];
            $form['dashboard_blocks_table'][$key]['weight'] = [
              '#type' => 'weight',
              '#default_value' => $relation['weight'],
              '#delta' => $weight_delta,
              '#title' => t('Weight for @block block', [
                '@block' => $block_instance
                  ->label(),
              ]),
              '#title_display' => 'invisible',
              '#attributes' => [
                'class' => [
                  'block-weight',
                  'block-weight-' . $region,
                ],
              ],
            ];
            $links = [];
            $links['edit'] = [
              'title' => $this
                ->t('Configure'),
              'url' => Url::fromRoute('draggable_dashboard.block_configure', [
                'block_id' => $key,
                'dashboard_entity' => $dashboard
                  ->id(),
              ]),
            ];
            $links['delete'] = [
              'title' => $this
                ->t('Delete'),
              'url' => Url::fromRoute('draggable_dashboard.block_delete', [
                'dashboard_entity' => $dashboard
                  ->id(),
                'block_id' => $key,
              ]),
            ];
            $form['dashboard_blocks_table'][$key]['operations'] = [
              'data' => [
                '#type' => 'operations',
                '#links' => $links,
              ],
              '#wrapper_attributes' => [
                'class' => [
                  'text-align-right',
                ],
              ],
            ];
          }
        }
      }
      $form['actions']['back'] = [
        '#type' => 'link',
        '#title' => $this
          ->t('Back To Dashboards'),
        '#url' => new Url('entity.dashboard_entity.collection'),
        '#attributes' => [
          'class' => [
            'button',
          ],
        ],
      ];
    }
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $blocks = $form_state
      ->getValue('dashboard_blocks_table', []);
    if (!empty($blocks)) {
      $existing_blocks = $this->entity
        ->get('blocks');
      if (!empty($existing_blocks)) {
        foreach ($existing_blocks as $block_id => $block) {
          if (!empty($blocks[$block_id])) {
            $existing_blocks[$block_id] = array_merge($existing_blocks[$block_id], $blocks[$block_id]);
          }
        }
        $blocks = $existing_blocks;
      }
      $form_state
        ->setValue('blocks', $blocks);
    }
    parent::submitForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    $status = $this->entity
      ->save();
    switch ($status) {
      case SAVED_NEW:
        $this
          ->messenger()
          ->addStatus($this
          ->t('Created the %label remote website.', [
          '%label' => $this->entity
            ->label(),
        ]));
        $form_state
          ->setRedirectUrl($this->entity
          ->toUrl('edit-form'));
        break;
      default:
        $this
          ->messenger()
          ->addStatus($this
          ->t('Saved the %label remote website.', [
          '%label' => $this->entity
            ->label(),
        ]));
        $form_state
          ->setRedirectUrl($this->entity
          ->toUrl('collection'));
        break;
    }

    // Clear block plugin definitions to reflect changes in the list due to
    // changes to dashboard.
    $this->blockPluginManager
      ->clearCachedDefinitions();
  }

}

Classes

Namesort descending Description
DashboardForm Class DashboardForm.