DateFormatFormBase.php 6.48 KB
Newer Older
1 2 3 4 5 6 7 8 9
<?php

/**
 * @file
 * Contains \Drupal\system\Form\DateFormatFormBase.
 */

namespace Drupal\system\Form;

10 11
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
12
use Drupal\Core\Config\Entity\ConfigStorageControllerInterface;
13
use Drupal\Core\Datetime\Date;
14
use Drupal\Core\Language\Language;
15
use Symfony\Component\DependencyInjection\ContainerInterface;
16
use Drupal\Core\Datetime\DrupalDateTime;
17
use Drupal\Core\Entity\EntityFormController;
18 19

/**
20
 * Provides a base form controller for date formats.
21
 */
22
abstract class DateFormatFormBase extends EntityFormController {
23 24 25 26 27 28 29 30

  /**
   * The date pattern type.
   *
   * @var string
   */
  protected $patternType;

31 32 33 34 35 36 37
  /**
   * The date service.
   *
   * @var \Drupal\Core\Datetime\Date
   */
  protected $dateService;

38 39 40
  /**
   * The date format storage controller.
   *
41
   * @var \Drupal\Core\Config\Entity\ConfigStorageControllerInterface
42 43 44
   */
  protected $dateFormatStorage;

45 46
  /**
   * Constructs a new date format form.
47 48 49
   *
   * @param \Drupal\Core\Datetime\Date $date_service
   *   The date service.
50
   * @param \Drupal\Core\Config\Entity\ConfigStorageControllerInterface $date_format_storage
51
   *   The date format storage controller.
52
   */
53
  public function __construct(Date $date_service, ConfigStorageControllerInterface $date_format_storage) {
54 55
    $date = new DrupalDateTime();
    $this->patternType = $date->canUseIntl() ? DrupalDateTime::INTL : DrupalDateTime::PHP;
56 57

    $this->dateService = $date_service;
58
    $this->dateFormatStorage = $date_format_storage;
59 60 61 62 63
  }

  /**
   * {@inheritdoc}
   */
64
  public static function create(ContainerInterface $container) {
65
    return new static(
66 67
      $container->get('date'),
      $container->get('entity.manager')->getStorageController('date_format')
68 69
    );
  }
70

71 72 73 74 75 76 77 78 79 80 81 82 83 84
  /**
   * Checks for an existing date format.
   *
   * @param string|int $entity_id
   *   The entity ID.
   * @param array $element
   *   The form element.
   * @param array $form_state
   *   The form state.
   *
   * @return bool
   *   TRUE if this format already exists, FALSE otherwise.
   */
  public function exists($entity_id, array $element,  array $form_state) {
85 86
    return (bool) $this->dateFormatStorage
      ->getQuery()
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
      ->condition('id', $element['#field_prefix'] . $entity_id)
      ->execute();
  }

  /**
   * Returns the date for a given format string.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param array $form_state
   *   An associative array containing the current state of the form.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   An AJAX Response to update the date-time value of the date format.
   */
  public static function dateTimeLookup(array $form, array $form_state) {
    $format = '';
    if (!empty($form_state['values']['date_format_pattern'])) {
      $format = t('Displayed as %date_format', array('%date_format' => \Drupal::service('date')->format(REQUEST_TIME, 'custom', $form_state['values']['date_format_pattern'])));
106
    }
107 108 109 110 111 112
    // Return a command instead of a string, since the Ajax framework
    // automatically prepends an additional empty DIV element for a string, which
    // breaks the layout.
    $response = new AjaxResponse();
    $response->addCommand(new ReplaceCommand('#edit-date-format-suffix', '<small id="edit-date-format-suffix">' . $format . '</small>'));
    return $response;
113 114 115 116 117
  }

  /**
   * {@inheritdoc}
   */
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
  public function form(array $form, array &$form_state) {
    $form['label'] = array(
      '#type' => 'textfield',
      '#title' => 'Name',
      '#maxlength' => 100,
      '#description' => t('Name of the date format'),
      '#default_value' => $this->entity->label(),
    );

    $form['id'] = array(
      '#type' => 'machine_name',
      '#description' => t('A unique machine-readable name. Can only contain lowercase letters, numbers, and underscores.'),
      '#disabled' => !$this->entity->isNew(),
      '#default_value' => $this->entity->id(),
      '#machine_name' => array(
        'exists' => array($this, 'exists'),
134 135
        'replace_pattern' =>'([^a-z0-9_]+)|(^custom$)',
        'error' => 'The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores. Additionally, it can not be the reserved word "custom".',
136 137 138 139 140
      ),
    );

    if (class_exists('intlDateFormatter')) {
      $description = t('A user-defined date format. See the <a href="@url">PHP manual</a> for available options.', array('@url' => 'http://userguide.icu-project.org/formatparse/datetime'));
141 142
    }
    else {
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
      $description = t('A user-defined date format. See the <a href="@url">PHP manual</a> for available options.', array('@url' => 'http://php.net/manual/function.date.php'));
    }
    $form['date_format_pattern'] = array(
      '#type' => 'textfield',
      '#title' => t('Format string'),
      '#maxlength' => 100,
      '#description' => $description,
      '#default_value' => '',
      '#field_suffix' => ' <small id="edit-date-format-suffix"></small>',
      '#ajax' => array(
        'callback' => array($this, 'dateTimeLookup'),
        'event' => 'keyup',
        'progress' => array('type' => 'throbber', 'message' => NULL),
      ),
      '#required' => TRUE,
    );

160 161 162 163 164 165
    $form['langcode'] = array(
      '#type' => 'language_select',
      '#title' => t('Language'),
      '#languages' => Language::STATE_ALL,
      '#default_value' => $this->entity->langcode,
    );
166

167 168 169 170 171 172 173 174 175 176 177 178
    return parent::form($form, $form_state);
  }

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

    // The machine name field should already check to see if the requested
    // machine name is available. Regardless of machine_name or human readable
    // name, check to see if the provided pattern exists.
179 180
    $pattern = trim($form_state['values']['date_format_pattern']);
    foreach ($this->dateFormatStorage->loadMultiple() as $format) {
181
      if ($format->getPattern() == $pattern && ($this->entity->isNew() || $format->id() != $this->entity->id())) {
182
        $this->setFormError('date_format_pattern', $form_state, $this->t('This format already exists. Enter a unique format string.'));
183 184
        continue;
      }
185 186 187 188 189 190 191
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submit(array $form, array &$form_state) {
192
    $form_state['redirect_route']['route_name'] = 'system.date_format_list';
193 194 195 196
    $form_state['values']['pattern'][$this->patternType] = trim($form_state['values']['date_format_pattern']);

    parent::submit($form, $form_state);
    $this->entity->save();
197 198 199
  }

}