View source  
  <?php
namespace Drupal\content_kanban\Component;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\content_kanban\Form\KanbanFilterForm;
use Drupal\content_kanban\KanbanService;
use Drupal\Core\Entity\ContentEntityType;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\workflows\Entity\Workflow;
class Kanban {
  
  protected $request;
  
  protected $currentUser;
  
  protected $kanbanService;
  
  protected $workflow;
  
  protected $workflowID;
  
  protected $typeSettings = [];
  
  protected $entityTypes = [];
  
  protected $states = [];
  
  public function __construct(AccountInterface $current_user, KanbanService $kanban_service, Workflow $workflow) {
    if (!self::isValidContentModerationWorkflow($workflow)) {
      throw new \Exception('The given workflow is no valid Content Moderation Workflow');
    }
    
    $this->request = \Drupal::request();
    
    $this->currentUser = $current_user;
    
    $this->kanbanService = $kanban_service;
    
    $this->workflow = $workflow;
    
    $this->workflowID = $workflow
      ->get('id');
    
    $this->typeSettings = $workflow
      ->get('type_settings');
    
    $this->entityTypes = $this->typeSettings['entity_types'];
    
    $this->states = $this
      ->sortStates($this->typeSettings['states']);
  }
  
  protected function sortStates(array $states) {
    
    $sorted_states = $states;
    
    foreach ($sorted_states as $state_id => &$state) {
      $state['state_id'] = $state_id;
    }
    
    usort($sorted_states, function ($a, $b) {
      if ($a['weight'] == $b['weight']) {
        return 0;
      }
      elseif ($a['weight'] < $b['weight']) {
        return -1;
      }
      else {
        return 1;
      }
    });
    
    $return = [];
    foreach ($sorted_states as $sorted_state) {
      $return[$sorted_state['state_id']] = $sorted_state;
    }
    return $return;
  }
  
  public static function isValidContentModerationWorkflow(Workflow $workflow) {
    if ($workflow
      ->get('type') == 'content_moderation') {
      $type_settings = $workflow
        ->get('type_settings');
      if (!empty($type_settings['entity_types'])) {
        if (array_key_exists('states', $type_settings)) {
          if (!empty($type_settings['states'])) {
            return TRUE;
          }
        }
      }
    }
    return FALSE;
  }
  
  public function build() {
    $columns = [];
    
    $entityTypeConfigs = $this->kanbanService
      ->getEntityTypeConfigs($this->entityTypes);
    
    $filter_uid = KanbanFilterForm::getUserIdFilter();
    
    if (!$this->currentUser
      ->hasPermission('manage any content with content kanban')) {
      $filter_uid = $this->currentUser
        ->id();
    }
    
    $filter_content_type = KanbanFilterForm::getContentTypeFilter();
    
    $filter_state = KanbanFilterForm::getStateFilter();
    foreach ($this->states as $state_id => $state) {
      
      if ($filter_state && $filter_state != $state_id) {
        
        $emptyColumn = new KanbanColumn($this->workflowID, $state_id, $state, [], $entityTypeConfigs);
        $columns[] = $emptyColumn
          ->build();
        continue;
      }
      
      $filters = [
        'moderation_state' => $state_id,
      ];
      
      if ($filter_uid) {
        $filters['uid'] = $filter_uid;
      }
      if ($filter_content_type) {
        $filters['content_type'] = $filter_content_type;
      }
      else {
        $filters['content_type'] = FALSE;
      }
      
      $multipleEntities = [];
      if ($entityIds = $this->kanbanService
        ->getEntityIdsFromContentModerationEntities($this->workflowID, $filters, $this->entityTypes)) {
        $multipleEntities = $this->kanbanService
          ->getEntitiesByEntityIds($entityIds, $filters);
      }
      $columnEntities = [];
      foreach ($multipleEntities as $entities) {
        $columnEntities = array_merge($columnEntities, $entities);
      }
      
      $kanban_column = new KanbanColumn($this->workflowID, $state_id, $state, $columnEntities, $entityTypeConfigs);
      
      $columns[] = $kanban_column
        ->build();
    }
    
    $permissions = [
      'create_entity' => $this
        ->getCreateEntityPermissions($entityTypeConfigs),
    ];
    
    $build = [
      '#theme' => 'content_kanban',
      '#kanban_id' => $this->workflowID,
      '#kanban_label' => $this->workflow
        ->label(),
      '#filter_form' => $this
        ->buildFilterForm(),
      '#permissions' => $permissions,
      '#headers' => $this
        ->buildHeaders(),
      '#columns' => $columns,
      '#attached' => [
        'library' => [
          'content_kanban/kanban',
        ],
      ],
    ];
    return $build;
  }
  
  protected function buildHeaders() {
    $headers = [];
    foreach ($this->states as $state) {
      $headers[] = $state['label'];
    }
    return $headers;
  }
  
  protected function getCreateEntityPermissions(array $entity_type_configs) {
    $permissions = [];
    foreach ($entity_type_configs as $entity_type_id => $entity_type_config) {
      
      if ($this->currentUser
        ->hasPermission("create {$entity_type_id} content")) {
        $permissions[$entity_type_id] = t("Add @type", [
          '@type' => $entity_type_config
            ->getLabel(),
        ]);
      }
    }
    return $permissions;
  }
  
  protected function buildFilterForm() {
    
    if (!$this->currentUser
      ->hasPermission('manage any content with content kanban')) {
      return [];
    }
    
    $form_params = [
      'workflow_id' => $this->workflowID,
      'states' => $this->states,
    ];
    $filter_form = \Drupal::formBuilder()
      ->getForm('Drupal\\content_kanban\\Form\\KanbanFilterForm', $form_params);
    
    unset($filter_form['form_build_id']);
    unset($filter_form['form_id']);
    return $filter_form;
  }
}