You are here

public function Acquiadam::getForm in Media: Acquia DAM 8

File

src/Plugin/EntityBrowser/Widget/Acquiadam.php, line 167

Class

Acquiadam
Uses a view to provide entity listing in a browser's widget.

Namespace

Drupal\media_acquiadam\Plugin\EntityBrowser\Widget

Code

public function getForm(array &$original_form, FormStateInterface $form_state, array $additional_widget_parameters) {
  $config = $this->config
    ->get('media_acquiadam.settings');
  $media_type_storage = $this->entityTypeManager
    ->getStorage('media_type');

  /** @var \Drupal\media\MediaTypeInterface $media_type */
  if (!$this->configuration['media_type'] || !($media_type = $media_type_storage
    ->load($this->configuration['media_type']))) {
    return [
      '#markup' => $this
        ->t('The media type is not configured correctly.'),
    ];
  }
  elseif ($media_type
    ->getSource()
    ->getPluginId() != 'acquiadam_asset') {
    return [
      '#markup' => $this
        ->t('The configured media type is not using the acquiadam_asset plugin.'),
    ];
  }
  elseif ($this
    ->uuid() != $form_state
    ->getStorage()['entity_browser_current_widget']) {

    // Return an empty array.
    return [];
  }
  $auth = $this->acquiadam
    ->getAuthState();
  if (empty($auth['valid_token'])) {
    try {
      $auth = $this->acquiadam
        ->checkAuth();
      if (!empty($auth['valid_token'])) {
        $this->userData
          ->set('media_acquiadam', $this->user
          ->id(), 'acquiadam_access_token', $auth['access_token']);
        $this->userData
          ->set('media_acquiadam', $this->user
          ->id(), 'acquiadam_access_token_expiration', $auth['access_token_expiry']);
        $this->userData
          ->set('media_acquiadam', $this->user
          ->id(), 'acquiadam_refresh_token', $auth['refresh_token']);
      }
    } catch (InvalidCredentialsException $x) {
      $message = '';
      if ($config
        ->get('samesite_cookie_disable') || $this->requestStack
        ->getCurrentRequest()
        ->getScheme() == "http") {
        $message = $this
          ->t("You are not authenticated. %authenticate first, then re-open this modal to browse Acquia DAM assets..", [
          '%authenticate' => Link::createFromRoute('authenticate', 'media_acquiadam.auth_start', [], [
            'attributes' => [
              'target' => '_blank',
            ],
          ])
            ->toString(),
        ]);
      }
      else {
        $message = $this
          ->t('You are not authenticated. Please %authenticate to browse Acquia DAM assets.', [
          '%authenticate' => Link::createFromRoute('authenticate', 'media_acquiadam.auth_start', [
            'auth_finish_redirect' => $this->requestStack
              ->getCurrentRequest()
              ->getRequestUri(),
          ])
            ->toString(),
        ]);
      }
      $form['message'] = [
        '#theme' => 'asset_browser_message',
        '#message' => $message,
        '#attached' => [
          'library' => [
            'media_acquiadam/asset_browser',
          ],
        ],
      ];
      return $form;
    }
  }

  // Start by inheriting parent form.
  $form = parent::getForm($original_form, $form_state, $additional_widget_parameters);

  // Attach the modal library.
  $form['#attached']['library'][] = 'core/drupal.dialog.ajax';

  // This form is submitted and rebuilt when a folder is clicked.
  // The triggering element identifies which folder button was clicked.
  $trigger_elem = $form_state
    ->getTriggeringElement();

  // Initialize current_folder.
  $current_folder = new Folder();

  // Default current folder id to zero which represents the root folder.
  $current_folder->id = 0;

  // Default current folder parent id to zero which represents root folder.
  $current_folder->parent = 0;

  // Default current folder name to 'Home' which represents the root folder.
  $current_folder->name = 'Home';

  // Default current page to first page.
  $page = 0;

  // Number of assets to show per page.
  $num_per_page = $config
    ->get('num_images_per_page') ?? AcquiadamConfig::NUM_IMAGES_PER_PAGE;

  // Initial breadcrumb array representing the root folder only.
  $breadcrumbs = [
    '0' => 'Home',
  ];

  // If the form state contains the widget AND the reset button hadn't been
  // clicked then pull values for the current form state.
  if (isset($form_state
    ->getCompleteForm()['widget']) && isset($trigger_elem) && $trigger_elem['#name'] != 'filter_sort_reset') {

    // Assign $widget for convenience.
    $widget = $form_state
      ->getCompleteForm()['widget'];
    if (isset($widget['pager-container']) && is_numeric($widget['pager-container']['#page'])) {

      // Set the page number to the value stored in the form state.
      $page = intval($widget['pager-container']['#page']);
    }
    if (isset($widget['asset-container']) && is_numeric($widget['asset-container']['#acquiadam_folder_id'])) {

      // Set current folder id to the value stored in the form state.
      $current_folder->id = $widget['asset-container']['#acquiadam_folder_id'];
    }
    if (isset($widget['breadcrumb-container']) && is_array($widget['breadcrumb-container']['#breadcrumbs'])) {

      // Set the breadcrumbs to the value stored in the form state.
      $breadcrumbs = $widget['breadcrumb-container']['#breadcrumbs'];
    }
    if ($form_state
      ->getValue('assets')) {
      $current_selections = $form_state
        ->getValue('current_selections', []) + array_filter($form_state
        ->getValue('assets', []));
      $form['current_selections'] = [
        '#type' => 'value',
        '#value' => $current_selections,
      ];
    }
  }

  // If the form has been submitted.
  if (isset($trigger_elem)) {

    // If a folder button has been clicked.
    if ($trigger_elem['#name'] == 'acquiadam_folder') {

      // Set the current folder id to the id of the folder that was clicked.
      $current_folder->id = intval($trigger_elem['#acquiadam_folder_id']);

      // Reset page to zero if we have navigated to a new folder.
      $page = 0;
    }

    // If a pager button has been clicked.
    if ($trigger_elem['#name'] == 'acquiadam_pager') {

      // Set the current folder id to the id of the folder that was clicked.
      $page = intval($trigger_elem['#acquiadam_page']);
    }

    // If the filter/sort submit button has been clicked.
    if ($trigger_elem['#name'] == 'filter_sort_submit') {

      // Reset page to zero.
      $page = 0;
    }

    // If the reset submit button has been clicked.
    if ($trigger_elem['#name'] == 'filter_sort_reset') {

      // Fetch the user input.
      $user_input = $form_state
        ->getUserInput();

      // Fetch clean values keys (system related, not user input).
      $clean_val_key = $form_state
        ->getCleanValueKeys();

      // Loop through user inputs.
      foreach ($user_input as $key => $item) {

        // Unset only the User Input values.
        if (!in_array($key, $clean_val_key)) {
          unset($user_input[$key]);
        }
      }

      // Reset the user input.
      $form_state
        ->setUserInput($user_input);

      // Set values to user input.
      $form_state
        ->setValues($user_input);

      // Rebuild the form state values.
      $form_state
        ->setRebuild();

      // Get back to first page.
      $page = 0;
    }
  }

  // Offset used for pager.
  $offset = $num_per_page * $page;

  // Parameters for searching, sorting, and filtering.
  $params = [
    'limit' => $num_per_page,
    'offset' => $offset,
    'sortby' => $form_state
      ->getValue('sortby'),
    'sortdir' => $form_state
      ->getValue('sortdir'),
    'types' => $form_state
      ->getValue('types'),
    'query' => $form_state
      ->getValue('query'),
    'folderid' => $current_folder->id,
  ];

  // If the current folder is not zero then fetch information about
  // the sub folder being rendered.
  if ($current_folder->id) {

    // Fetch the folder object.
    $current_folder = $this->acquiadam
      ->getFolder($current_folder->id);

    // Store the list of folders for rendering later.
    $folders = $current_folder->folders;

    // Fetch a list of assets for the folder.
    $folder_assets = $this->acquiadam
      ->getFolderAssets($current_folder->id, $params);

    // We need to override this because getFolder only counts active assets.
    $current_folder->numassets = $folder_assets->total_count;

    // If there is a filter applied for the file type.
    if (!empty($params['types'])) {

      // Override number of assets on current folder to make number of search
      // results so pager works correctly.
      $current_folder->numassets = $folder_assets->facets->types->{$params['types']};
    }

    // Set items to array of assets in the current folder.
    $items = $folder_assets->items;
  }
  else {

    // The root folder is fetched differently because it can only
    // contain subfolders (not assets)
    $folders = $this->acquiadam
      ->getTopLevelFolders();
  }

  // If searching by keyword.
  if (!empty($params['query'])) {

    // Fetch search results.
    $search_results = $this->acquiadam
      ->searchAssets($params);

    // Override number of assets on current folder to make number of
    // search results so pager works correctly.
    $current_folder->numassets = $search_results['total_count'];

    // Set items to array of assets in the search result.
    $items = isset($search_results['assets']) ? $search_results['assets'] : [];
  }

  // Add the filter and sort options to the form.
  $form += $this
    ->getFilterSort();

  // Add the breadcrumb to the form.
  $form += $this
    ->getBreadcrumb($current_folder, $breadcrumbs);

  // Add container for assets (and folder buttons)
  $form['asset-container'] = [
    '#type' => 'container',
    // Store the current folder id in the form so it can be retrieved
    // from the form state.
    '#acquiadam_folder_id' => $current_folder->id,
    '#attributes' => [
      'class' => [
        'acquiadam-asset-browser',
      ],
    ],
  ];

  // Get module path to create URL for background images.
  $modulePath = $this->moduleHandler
    ->getModule('media_acquiadam')
    ->getPath();

  // If no search terms, display folders.
  if (empty($params['query'])) {

    // Add folder buttons to form.
    foreach ($folders as $folder) {
      $form['asset-container']['folders'][$folder->name] = [
        '#type' => 'container',
        '#attributes' => [
          'class' => [
            'acquiadam-browser-folder-link',
          ],
          'style' => 'background-image:url("/' . $modulePath . '/img/folder.png")',
        ],
      ];

      // Use folder thumbnail to generate inline style, if present.
      $backgroundImageStyle = '';
      if (isset($folder->thumbnailurls) && !empty($folder->thumbnailurls[0]->url)) {
        $backgroundImageStyle .= 'background-image:url("' . $folder->thumbnailurls[0]->url . '")';
      }
      $form['asset-container']['folders'][$folder->name][$folder->id] = [
        '#type' => 'button',
        '#value' => $folder->name,
        '#name' => 'acquiadam_folder',
        '#acquiadam_folder_id' => $folder->id,
        '#acquiadam_parent_folder_id' => $current_folder->parent,
        '#attributes' => [
          'class' => [
            'acquiadam-folder-link-button',
          ],
          'style' => $backgroundImageStyle,
        ],
      ];
      $form['asset-container']['folders'][$folder->name]['title'] = [
        '#type' => 'html_tag',
        '#tag' => 'p',
        '#value' => $folder->name,
      ];
    }
  }

  // Assets are rendered as #options for a checkboxes element.
  // Start with an empty array.
  $assets = [];
  $assets_status = [];

  // Add to the assets array.
  if (isset($items)) {
    foreach ($items as $folder_item) {
      $assets_status[$folder_item->id]['#disabled'] = $folder_item->status !== 'active';
      $assets[$folder_item->id] = $this
        ->layoutMediaEntity($folder_item);
    }
  }

  // Add assets to form.
  // IMPORTANT: Do not add #title or #description properties.
  // This will wrap elements in a fieldset and will cause styling problems.
  // See: \core\lib\Drupal\Core\Render\Element\CompositeFormElementTrait.php.
  $form['asset-container']['assets'] = [
    '#type' => 'checkboxes',
    '#theme_wrappers' => [
      'checkboxes__acquiadam_assets',
    ],
    '#title_display' => 'invisible',
    '#options' => $assets,
    '#attached' => [
      'library' => [
        'media_acquiadam/asset_browser',
      ],
    ],
  ] + $assets_status;

  // If the number of assets in the current folder is greater than
  // the number of assets to show per page.
  if ($current_folder->numassets > $num_per_page) {

    // Add the pager to the form.
    $form['actions'] += $this
      ->getPager($current_folder, $page, $num_per_page);
  }
  return $form;
}