You are here

public function AdminSettingsForm::buildForm in SMS Framework 8

Form constructor.

Parameters

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

Return value

array The form structure.

Overrides ConfigFormBase::buildForm

File

modules/sms_user/src/Form/AdminSettingsForm.php, line 60

Class

AdminSettingsForm
Provides a general settings form for SMS User.

Namespace

Drupal\sms_user\Form

Code

public function buildForm(array $form, FormStateInterface $form_state, $op = NULL, $domain = NULL) {
  $form['#attached']['library'][] = 'sms_user/admin';
  $config = $this
    ->config('sms_user.settings');

  // Active hours.
  $form['active_hours'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Active hours'),
    '#open' => TRUE,
    '#tree' => TRUE,
  ];
  $form['active_hours']['status'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Enable active hours'),
    '#description' => $this
      ->t('Active hours will suspend transmission of automated SMS messages until the users local time is between any of these hours. The site default timezone is used if a user has not selected a timezone. Active hours are not applied to SMS messages created as a result of direct user action. Messages which are already queued are not retroactively updated.'),
    '#default_value' => $config
      ->get('active_hours.status'),
  ];
  $form['active_hours']['days_container'] = [
    '#type' => 'container',
    '#states' => [
      'visible' => [
        ':input[name="active_hours[status]"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ];
  $form['active_hours']['days_container']['days'] = [
    '#type' => 'table',
    '#header' => [
      'day' => $this
        ->t('Day'),
      'start' => $this
        ->t('Start time'),
      'end' => $this
        ->t('End time'),
    ],
    '#parents' => [
      'active_hours',
      'days',
    ],
  ];

  // Convert configuration into days.
  $day_defaults = [];
  foreach ($config
    ->get('active_hours.ranges') as $range) {
    $start = new DrupalDateTime($range['start']);
    $end = new DrupalDateTime($range['end']);
    $start_day = strtolower($start
      ->format('l'));
    $day_defaults[$start_day]['start'] = $start
      ->format('G');
    if (new DrupalDateTime($start_day . ' +1 day') == $end) {
      $day_defaults[$start_day]['end'] = 24;
    }
    else {
      $day_defaults[$start_day]['end'] = $end
        ->format('G');
    }
  }

  // Prepare options for select fields.
  $hours = [];
  for ($i = 0; $i < 24; $i++) {
    $hours[$i] = DrupalDateTime::datePad($i) . ':00';
  }
  $hours[0] = $this
    ->t('- Start of day -');
  $end_hours = $hours;
  unset($end_hours[0]);
  $end_hours[24] = $this
    ->t('- End of day -');
  $timestamp = strtotime('next Sunday');
  for ($i = 0; $i < 7; $i++) {
    $row = [
      '#tree' => TRUE,
    ];
    $day = strftime('%A', $timestamp);
    $day_lower = strtolower($day);
    $row['day']['#plain_text'] = $day;

    // @todo convert to 'datetime' after
    // https://www.drupal.org/node/2703941 is fixed.
    $row['start'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Start time for @day', [
        '@day' => $day,
      ]),
      '#title_display' => 'invisible',
      '#default_value' => isset($day_defaults[$day_lower]['start']) ? $day_defaults[$day_lower]['start'] : -1,
      '#options' => $hours,
      '#empty_option' => $this
        ->t('- Suspend messages for this day -'),
      '#empty_value' => -1,
    ];
    $row['end'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Start time for @day', [
        '@day' => $day,
      ]),
      '#title_display' => 'invisible',
      '#default_value' => isset($day_defaults[$day_lower]['end']) ? $day_defaults[$day_lower]['end'] : 24,
      '#options' => $end_hours,
      '#states' => [
        'invisible' => [
          ':input[name="active_hours[days][' . $day_lower . '][start]"]' => [
            'value' => '-1',
          ],
        ],
      ],
    ];
    $timestamp = strtotime('+1 day', $timestamp);
    $form['active_hours']['days_container']['days'][$day_lower] = $row;
  }

  // Account registration.
  $form['account_registration'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Account creation'),
    '#description' => $this
      ->t('New accounts can be created and associated with a phone number.'),
    '#open' => TRUE,
    '#tree' => TRUE,
  ];
  if ($config
    ->get('account_registration.unrecognized_sender.status')) {
    $radio_value = 'all';
  }
  elseif ($config
    ->get('account_registration.incoming_pattern.status')) {
    $radio_value = 'incoming_pattern';
  }
  else {
    $radio_value = 'none';
  }
  $user_phone_settings_exist = $this->phoneNumberVerificationProvider
    ->getPhoneNumberSettings('user', 'user') instanceof PhoneNumberSettingsInterface;
  if (!$user_phone_settings_exist) {
    drupal_set_message($this
      ->t('There are no phone number settings configured for the user entity type. Some features cannot operate without these settings. <a href=":add">Add phone number settings</a>.', [
      ':add' => Url::fromRoute('entity.phone_number_settings.add')
        ->toString(),
    ]), 'warning');
  }

  // The parent 'radios' form element for our account registration behaviour.
  $form['account_registration']['behaviour'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Account registration via SMS'),
    '#options' => [
      'none' => $this
        ->t('Disabled'),
      'all' => $this
        ->t('All unrecognised phone numbers'),
      'incoming_pattern' => $this
        ->t('Incoming message based on pattern'),
    ],
    '#required' => TRUE,
    '#default_value' => $radio_value,
  ];

  // Modify the radio button for the 'Disabled' option.
  $form['account_registration']['behaviour']['none'] = [
    '#description' => $this
      ->t('Disable account creation via SMS.'),
    '#return_value' => 'none',
  ];

  // Modify the radio button for the 'All unrecognised phone numbers' option.
  $form['account_registration']['behaviour']['all'] = [
    '#description' => $this
      ->t('Automatically create a Drupal account for all phone numbers not associated with an existing account.'),
    '#return_value' => 'all',
    '#disabled' => !$user_phone_settings_exist,
  ];

  // Dynamically show form elements if the 'all' radio button is selected.
  // This container holds a checkbox which, if checked, will be accompanied
  // by a textarea.
  $form['account_registration']['behaviour']['all_options'] = [
    '#type' => 'container',
    '#attributes' => [
      'class' => [
        'sms_user-radio-indent',
      ],
    ],
    '#parents' => [
      'account_registration',
      'all_options',
    ],
    '#tree' => TRUE,
    '#states' => [
      // Show only when the 'all' radio button is selected.
      'visible' => [
        ':input[name="account_registration[behaviour]"]' => [
          'value' => 'all',
        ],
      ],
    ],
  ];
  $form['account_registration']['behaviour']['all_options']['reply_status'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Enable reply message'),
    '#default_value' => $config
      ->get('account_registration.unrecognized_sender.reply.status'),
  ];

  // Show the accompanying textarea only if the 'reply_status' checkbox
  // is selected.
  $form['account_registration']['behaviour']['all_options']['reply'] = [
    '#type' => 'container',
    '#states' => [
      'visible' => [
        ':input[name="account_registration[behaviour][all_options][reply_status]"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ];
  $form['account_registration']['behaviour']['all_options']['reply']['message'] = [
    '#type' => 'textarea',
    '#title' => $this
      ->t('Reply message'),
    '#description' => $this
      ->t('Send a message after a new account is created. In addition to the tokens listed below, [user:password] is also available.'),
    '#default_value' => $config
      ->get('account_registration.unrecognized_sender.reply.message'),
    '#states' => [
      'visible' => [
        ':input[name="account_registration[behaviour][all_options][reply_status]"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ];
  $form['account_registration']['behaviour']['all_options']['reply']['tokens'] = $this
    ->buildTokenElement();

  // Modify radio button for the 'Incoming message based on pattern' option.
  $form['account_registration']['behaviour']['incoming_pattern'] = [
    '#description' => $this
      ->t('Automatically create a Drupal account if message is received in a specified format.'),
    '#return_value' => 'incoming_pattern',
    '#disabled' => !$user_phone_settings_exist,
  ];

  // Dynamically show form elements if the 'incoming_pattern' radio button is
  // selected. This container holds a textarea and two checkboxs. The second
  // checkbox, if checked, will be accompanied by two message textareas.
  $form['account_registration']['behaviour']['incoming_pattern_options'] = [
    '#type' => 'container',
    '#attributes' => [
      'class' => [
        'sms_user-radio-indent',
      ],
    ],
    '#parents' => [
      'account_registration',
      'incoming_pattern_options',
    ],
    '#tree' => TRUE,
    '#states' => [
      // Show only when the 'incoming_pattern' radio button is selected.
      'visible' => [
        ':input[name="account_registration[behaviour]"]' => [
          'value' => 'incoming_pattern',
        ],
      ],
    ],
  ];
  $form['account_registration']['behaviour']['incoming_pattern_options']['incoming_message'] = [
    '#type' => 'textarea',
    '#title' => $this
      ->t('Incoming message'),
    '#description' => $this
      ->t('You should use at least one placeholder: [email], [password], or [username]. If password is omitted: a random password will be generated. If username is omitted: a random username will be generated. If email address is omitted: no email address will be associated with the account.'),
    '#default_value' => $config
      ->get('account_registration.incoming_pattern.incoming_messages.0'),
  ];
  $form['account_registration']['behaviour']['incoming_pattern_options']['send_activation_email'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Send activation email'),
    '#description' => $this
      ->t('Send activation email if an [email] placeholder is present, and [password] placeholder is omitted.'),
    '#default_value' => $config
      ->get('account_registration.incoming_pattern.send_activation_email'),
  ];
  $form['account_registration']['behaviour']['incoming_pattern_options']['reply_status'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Enable reply message'),
    '#default_value' => $config
      ->get('account_registration.incoming_pattern.reply.status'),
  ];

  // Show the two accompanying textareas only if the 'reply_status' checkbox
  // is selected.
  $form['account_registration']['behaviour']['incoming_pattern_options']['reply'] = [
    '#type' => 'container',
    '#attributes' => [
      'class' => [
        'sms_user-radio-indent',
      ],
    ],
    '#states' => [
      'visible' => [
        ':input[name="account_registration[behaviour][incoming_pattern_options][reply_status]"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ];
  $form['account_registration']['behaviour']['incoming_pattern_options']['reply']['message_success'] = [
    '#type' => 'textarea',
    '#title' => $this
      ->t('Reply message (success)'),
    '#description' => $this
      ->t('Send a message after a new account is successfully created. In addition to the tokens listed below, [user:password] is also available.'),
    '#default_value' => $config
      ->get('account_registration.incoming_pattern.reply.message'),
  ];
  $form['account_registration']['behaviour']['incoming_pattern_options']['reply']['message_failure'] = [
    '#type' => 'textarea',
    '#title' => $this
      ->t('Reply message (failure)'),
    '#description' => $this
      ->t('Send a message if a new account could not be created. Such reasons include: username already taken, email already used. In addition to the tokens listed below, [error] is also available.'),
    '#default_value' => $config
      ->get('account_registration.incoming_pattern.reply.message_failure'),
  ];
  $form['account_registration']['behaviour']['incoming_pattern_options']['reply']['tokens'] = $this
    ->buildTokenElement();
  return parent::buildForm($form, $form_state);
}