View source  
  <?php
namespace Drupal\acquia_contenthub\Form;
use Drupal\acquia_contenthub\EntityManager;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\image\Entity\ImageStyle;
class NodeTypePreviewImageForm {
  use StringTranslationTrait;
  const PREVIEW_IMAGE_DEFAULT_KEY = 'acquia_contenthub_preview_image';
  const PREVIEW_IMAGE_ADD_DEFAULT_KEY = 'acquia_contenthub_preview_image_add';
  
  private $entityFieldManager;
  
  private $entityTypeManager;
  
  private $contenthubEntityConfig;
  
  private $processedFieldHashes = [];
  
  private $imageFields = [];
  
  public function __construct(EntityManager $entity_manager, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager) {
    
    $this->contenthubEntityConfig = $entity_manager
      ->getContentHubEntityTypeConfigurationEntity('node');
    $this->entityTypeManager = $entity_type_manager;
    $this->entityFieldManager = $entity_field_manager;
  }
  
  public function getForm($node_type) {
    $form = [
      '#title' => $this
        ->t('Acquia Content Hub'),
      '#type' => 'details',
      '#tree' => TRUE,
      '#group' => 'additional_settings',
    ];
    
    $this
      ->collectImageFields('node', $node_type);
    if (empty($this->imageFields)) {
      $form['no_image_field'] = [
        '#type' => 'markup',
        '#markup' => '<div>' . $this
          ->t('This content type has no image field yet.') . '</div>',
      ];
      return $form;
    }
    
    $image_styles = image_style_options(FALSE);
    
    if (!isset($image_styles[self::PREVIEW_IMAGE_DEFAULT_KEY])) {
      $image_styles = [
        self::PREVIEW_IMAGE_ADD_DEFAULT_KEY => $this
          ->t('Acquia Content Hub Preview Image (150×150)'),
      ] + $image_styles;
    }
    
    $preview_image_field = $this->contenthubEntityConfig
      ->getPreviewImageField($node_type);
    $preview_image_style = $this->contenthubEntityConfig
      ->getPreviewImageStyle($node_type);
    
    $form['field'] = [
      '#type' => 'select',
      '#title' => $this
        ->t("Select content type's preview image."),
      '#options' => $this->imageFields,
      '#default_value' => isset($preview_image_field) ? $preview_image_field : '',
      '#empty_option' => $this
        ->t('None'),
      '#empty_value' => '',
    ];
    $form['style'] = [
      '#type' => 'select',
      '#title' => $this
        ->t("Select the preview image's style."),
      '#options' => $image_styles,
      '#default_value' => isset($preview_image_style) ? $preview_image_style : '',
      '#empty_option' => $this
        ->t('None'),
      '#empty_value' => '',
      '#states' => [
        'visible' => [
          ':input[name="acquia_contenthub[field]"]' => [
            '!value' => '',
          ],
        ],
      ],
    ];
    return $form;
  }
  
  private function collectImageFields($target_type, $type, $key_prefix = '', $label_prefix = '') {
    $field_definitions = $this->entityFieldManager
      ->getFieldDefinitions($target_type, $type);
    foreach ($field_definitions as $field_key => $field_definition) {
      $field_type = $field_definition
        ->getType();
      $field_target_type = $field_definition
        ->getSetting('target_type');
      $field_label = $field_definition
        ->getLabel();
      $full_label = $label_prefix . $field_label;
      $full_key = $key_prefix . $field_key;
      
      if ($field_type === 'image') {
        $this->imageFields[$full_key] = $full_label . ' (' . $full_key . ')';
        continue;
      }
      
      $field_hash = spl_object_hash($field_definition);
      if (isset($this->processedFieldHashes[$field_hash])) {
        continue;
      }
      
      if ($field_type === 'entity_reference' && $this->entityTypeManager
        ->getDefinition($field_target_type)
        ->entityClassImplements('\\Drupal\\Core\\Entity\\FieldableEntityInterface')) {
        
        $this->processedFieldHashes[$field_hash] = TRUE;
        
        $this
          ->collectImageFields($field_target_type, $field_type, $full_key . '->', $full_label . '->');
        continue;
      }
    }
  }
  
  public function saveSettings($node_type, ?array $settings) {
    if (NULL === $settings || !isset($settings['field'], $settings['style'])) {
      return;
    }
    if ($settings['style'] === self::PREVIEW_IMAGE_ADD_DEFAULT_KEY) {
      $this
        ->createDefaultImageStyle();
      $settings['style'] = self::PREVIEW_IMAGE_DEFAULT_KEY;
    }
    
    $this->contenthubEntityConfig
      ->setPreviewImageField($node_type, $settings['field']);
    $this->contenthubEntityConfig
      ->setPreviewImageStyle($node_type, $settings['style']);
    $this->contenthubEntityConfig
      ->save();
  }
  
  public function createDefaultImageStyle() {
    $image_style = ImageStyle::create([
      'name' => self::PREVIEW_IMAGE_DEFAULT_KEY,
      'label' => $this
        ->t('Acquia Content Hub Preview Image (150×150)'),
    ]);
    $image_style
      ->addImageEffect([
      'id' => 'image_scale_and_crop',
      'weight' => 1,
      'data' => [
        'width' => 150,
        'height' => 150,
      ],
    ]);
    $image_style
      ->save();
  }
}