0

I am wanting to make it so that users can upload images to a block configuration form for a pre-existing (views-generated) block (views_exposed_form) and have the images available in the block's template file. Here's my block class:

<?php

namespace Drupal\exposed_filter_images\Plugin\Block;

use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\Block\ViewsExposedFilterBlock;

/**
 * Provides a 'Views Exposed Filter' block.
 *
 * @Block(
 *   id = "exposed_filter_images_block",
 *   admin_label = @Translation("Exposed Filter Images Block"),
 *   deriver = "Drupal\exposed_filter_images\Plugin\Derivative\ExposedFilterImagesBlock"
 * )
 */
class ExposedFilterImagesBlock extends ViewsExposedFilterBlock {

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

    $form['image_1'] = [
      '#type' => 'managed_file',
      '#upload_location' => 'public://images/steps/',
      '#title' => t('Image 1'),
      '#description' => t("Image on the left"),
      '#default_value' => $this->configuration['image_1'],
      '#upload_validators' => [
        'file_validate_extensions' => ['gif png jpg jpeg'],
        'file_validate_size' => [25600000],
      ],
      '#states' => [
        'visible' => [
          ':input[name="image_type"]' => ['value' => t('Upload New Image(s)')],
        ]
      ]
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    $this->configuration['image_1'] = $form_state->getValue('image_1');
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $output = parent::build();

    $output['#theme'] = 'views_exposed_form';
    $output['#files'][0] = $this->configuration['image_1'];

    return $output;
  }
} 

Here's my exposed_filter_images.module file:

<?php

/**
 * Implements hook_theme().
 */
function exposed_filter_images_theme($existing, $type, $theme, $path) {
  return [
      'views_exposed_form' => [
          'variables' => ['files' => []],
      ],
  ];
}

/**
 * Implements hook_block_alter().
 */
function exposed_filter_images_block_alter(&$plugins) {
  if (isset($plugins['views_exposed_filter_block:elder_index-page_1'])) {
    $plugins['views_exposed_filter_block:elder_index-page_1']['class'] = \Drupal\exposed_filter_images\Plugin\Block\ExposedFilterImagesBlock::class;
  }
}

And then in the views-exposed-form.html.twig file, I can have a number returned with this simple debug: {{ files.0|json_encode }} (without the |json_encode filter, nothing shows up), but I'm not really understanding what this number is is or what I can do with it.

So I'm looking for what I would need to do in the class or in the twig file in order to have an image or at least the URL to the image appear on the front-end.

Thanks in advance!

1 Answer 1

1

Since my rep isn't high enough to comment... yet, I have to add my comment as an answer.

My initial thought is that the file would be saved as an entity. After reading up a bit on some d.o comments, there is/was a bug where managed_files are temporary by default. Somewhere in the mix you'll need to add something similar to

   $image = $form_state->getValue('image');
   $file = \Drupal\file\Entity\File::load( $image[0] );
   $file->setPermanent();
   $file->save();

to make the file permanent. (credit to This question)

Most likely you will need to save the file itself as an entity in the blockSubmit function.

    $file = \Drupal\file\Entity\File::load($image_id[0]);
    // Change status to permanent.
    if(gettype($file) == 'object'){
      $file->setPermanent();    
      // Save.
      $file->save();
      $user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());
      $file->setOwner($user);
    } ... and so on.

After that, you should be able to pass the filename or file entity to your theme layer and load it in your preferred method.

Examples modified from This d.o post

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.