achievements-2.x-dev/src/Form/AchievementEntityForm.php

src/Form/AchievementEntityForm.php
<?php

namespace Drupal\achievements\Form;

use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StreamWrapper\PublicStream;

/**
 * Class AchievementEntityForm.
 */
class AchievementEntityForm extends EntityForm {

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

    /** @var \Drupal\achievements\Entity\AchievementEntity $achievement_entity */
    $achievement_entity = $this->entity;
    $form['label'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Label'),
      '#maxlength' => 255,
      '#default_value' => $achievement_entity->label(),
      '#description' => $this->t("Label for the Achievement entity."),
      '#required' => TRUE,
    ];

    $form['id'] = [
      '#type' => 'machine_name',
      '#default_value' => $achievement_entity->id(),
      '#machine_name' => [
        'exists' => '\Drupal\achievements\Entity\AchievementEntity::load',
      ],
      '#disabled' => !$achievement_entity->isNew(),
    ];

    $form['description'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Description'),
      '#required' => TRUE,
      '#default_value' => $achievement_entity->getDescription(),
      '#description' => $this->t('The description of the achievement.'),
    ];

    $form['storage'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Storage'),
      '#size' => 60,
      '#maxlength' => 128,
      '#required' => FALSE,
      '#default_value' => $achievement_entity->getStorage(),
      '#description' => $this->t('The storage of the achievement.'),
    ];

    $form['secret'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Secret'),
      '#description' => $this->t('The achievement is only visible once a user has unlocked it.'),
      '#default_value' => $achievement_entity->isSecret(),
    ];

    $form['invisible'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Invisible'),
      '#description' => $this->t('The achievement does <em>not</em> display. Ever.'),
      '#default_value' => $achievement_entity->isInvisible(),
    ];

    $form['points'] = [
      '#type' => 'number',
      '#title' => $this->t('Points'),
      '#description' => $this->t('The point value of the achievement.'),
      '#default_value' => $achievement_entity->getPoints(),
    ];

    $form['image'] = [
      '#type' => 'details',
      '#title' => $this->t('Images'),
      '#open' => TRUE,
    ];
    $form['image']['use_default_image'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Use the default images supplied by the module'),
      '#default_value' => $achievement_entity->useDefaultImage(),
      '#tree' => FALSE,
    ];
    $form['image']['settings'] = [
      '#type' => 'container',
      '#states' => [
        // Hide the image settings when using the default image.
        'invisible' => [
          'input[name="use_default_image"]' => ['checked' => TRUE],
        ],
      ],
    ];
    $form['image']['settings']['unlocked_image_path'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Path to custom image for unlocked achievements'),
      '#default_value' => $achievement_entity->getImagePath('unlocked', FALSE),
    ];
    $form['image']['settings']['unlocked_image_upload'] = [
      '#type' => 'managed_file',
      '#title' => $this->t('Upload custom image for unlocked achievement'),
      '#description' => $this->t("If you don't have direct file access to the server, use this field to upload your image."),
      '#required' => FALSE,
      '#upload_location' => 'public://achievements/',
      '#upload_validators' => [
        'FileExtension' => [
          'extensions' => 'png gif jpg jpeg svg webp',
        ],
      ],
    ];
    $form['image']['settings']['locked_image_path'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Path to custom image for locked achievement'),
      '#default_value' => $achievement_entity->getImagePath('locked', FALSE),
    ];
    $form['image']['settings']['locked_image_upload'] = [
      '#type' => 'managed_file',
      '#title' => $this->t('Upload custom image for locked achievement'),
      '#description' => $this->t("If you don't have direct file access to the server, use this field to upload your image."),
      '#required' => FALSE,
      '#upload_location' => 'public://achievements/',
      '#upload_validators' => [
        'FileExtension' => [
          'extensions' => 'png gif jpg jpeg svg webp',
        ],
      ],
    ];
    $default = '.svg';
    // Inject human-friendly values and form element descriptions for image.
    foreach (['locked_image', 'unlocked_image'] as $type) {
      if (isset($form[$type]['settings'][$type . '_path'])) {
        $element = &$form[$type]['settings'][$type . '_path'];

        // If path is a public:// URI, display the path relative to the files
        // directory; stream wrappers are not end-user friendly.
        $original_path = $element['#default_value'];
        $friendly_path = NULL;
        if (\Drupal::service('stream_wrapper_manager')->getScheme($original_path) == 'public') {
          $friendly_path = \Drupal::service('stream_wrapper_manager')->getTarget($original_path);
          $element['#default_value'] = $friendly_path;
        }

        // Prepare local file path for description.
        if ($original_path && isset($friendly_path)) {
          $local_file = strtr($original_path, ['public:/' => PublicStream::basePath()]);
        }
        else {
          $local_file = $this->moduleHandler->getModule('achievements')->getPath() . '/' . $default;
        }

        $element['#description'] = $this->t('Examples: <code>@implicit-public-file</code> (for a file in the public filesystem), <code>@explicit-file</code>, or <code>@local-file</code>.', [
          '@implicit-public-file' => isset($friendly_path) ? $friendly_path : $default,
          '@explicit-file' => \Drupal::service('stream_wrapper_manager')->getScheme($original_path) !== FALSE ? $original_path : 'public://' . $default,
          '@local-file' => $local_file,
        ]);
      }
    }

    return $form;
  }

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

    foreach (['locked', 'unlocked'] as $type) {
      // When intending to use the default image, unset the image_path.
      if ($form_state->getValue('use_default_image')) {
        $form_state->unsetValue($type . '_image_path');
      }

      // If the user provided a path for an image file, make sure a file
      // exists at that path.
      if ($form_state->getValue($type . '_image_path')) {
        $path = $this->validatePath($form_state->getValue($type . '_image_path'));
        if (!$path) {
          $form_state->setErrorByName($type . '_image_path', $this->t("The custom image path for $type is invalid."));
        }
      }
    }
  }

  /**
   * Helper function for the system_theme_settings form.
   *
   * Attempts to validate normal system paths, paths relative to the public files
   * directory, or stream wrapper URIs. If the given path is any of the above,
   * returns a valid path or URI that the theme system can display.
   *
   * @param string $path
   *   A path relative to the Drupal root or to the public files directory, or
   *   a stream wrapper URI.
   *
   * @return mixed
   *   A valid path that can be displayed through the theme system, or FALSE if
   *   the path could not be validated.
   */
  protected function validatePath($path) {
    // Absolute local file paths are invalid.
    if (\Drupal::service('file_system')->realpath($path) == $path) {
      return FALSE;
    }
    // A path relative to the Drupal root or a fully qualified URI is valid.
    if (is_file($path)) {
      return $path;
    }
    // Prepend 'public://' for relative file paths within public filesystem.
    if (\Drupal::service('stream_wrapper_manager')->getScheme($path) === FALSE) {
      $path = 'public://' . $path;
    }
    if (is_file($path)) {
      return $path;
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state->getValues();

    foreach (['locked', 'unlocked'] as $type) {
      // If the user uploaded a new image via managed_file, get the file URI.
      if (!empty($values[$type . '_image_upload'])) {
        $fid = is_array($values[$type . '_image_upload']) ? reset($values[$type . '_image_upload']) : $values[$type . '_image_upload'];
        if ($fid) {
          /** @var \Drupal\file\FileInterface $file */
          $file = \Drupal\file\Entity\File::load($fid);
          if ($file) {
            // Make the file permanent.
            $file->setPermanent();
            $file->save();
            $values['use_default_image'] = 0;
            // Store as stream wrapper URI (public://...) - the entity/rendering will handle conversion
            $values[$type . '_image_path'] = $file->getFileUri();
          }
        }
      }
      unset($values[$type . '_image_upload']);

      // If the user entered a path relative to the system files directory for
      // an image, store a public:// URI so the theme system can handle it.
      if (!empty($values[$type . '_image_path'])) {
        $values[$type . '_image_path'] = $this->validatePath($values[$type . '_image_path']);
      }
    }

    $form_state->setValues($values);

    parent::submitForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    $achievement_entity = $this->entity;
    $status = $achievement_entity->save();

    switch ($status) {
      case SAVED_NEW:
        \Drupal::messenger()->addMessage($this->t('Created the %label Achievement entity.', [
          '%label' => $achievement_entity->label(),
        ]));
        break;

      default:
        \Drupal::messenger()->addMessage($this->t('Saved the %label Achievement entity.', [
          '%label' => $achievement_entity->label(),
        ]));
    }
    $form_state->setRedirectUrl($achievement_entity->toUrl('collection'));
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc