/** * {@inheritdoc} * * Validates the date type to adjust 12 hour time and prevent invalid dates. * If the date is valid, the date is set in the form. */ public static function valueCallback(&$element, $input, FormStateInterface $form_state) { $parts = $element['#date_part_order']; $increment = $element['#date_increment']; $date = NULL; if ($input !== FALSE) { $return = $input; if (isset($input['ampm'])) { if ($input['ampm'] == 'pm' && $input['hour'] < 12) { $input['hour'] += 12; } elseif ($input['ampm'] == 'am' && $input['hour'] == 12) { $input['hour'] -= 12; } unset($input['ampm']); } $timezone = !empty($element['#date_timezone']) ? $element['#date_timezone'] : NULL; $date = DrupalDateTime::createFromArray($input, $timezone); if ($date instanceof DrupalDateTime && !$date->hasErrors()) { static::incrementRound($date, $increment); } } else { $return = array_fill_keys($parts, ''); if (!empty($element['#default_value'])) { $date = $element['#default_value']; if ($date instanceof DrupalDateTime && !$date->hasErrors()) { static::incrementRound($date, $increment); foreach ($parts as $part) { switch ($part) { case 'day': $format = 'j'; break; case 'month': $format = 'n'; break; case 'year': $format = 'Y'; break; case 'hour': $format = in_array('ampm', $element['#date_part_order']) ? 'g' : 'G'; break; case 'minute': $format = 'i'; break; case 'second': $format = 's'; break; case 'ampm': $format = 'a'; break; default: $format = ''; } $return[$part] = $date->format($format); } } } } $return['object'] = $date; return $return; }
/** * Alter the default value for a date argument. * * @param object $argument * The argument object. * @param string $value * The default value created by the argument handler. */ function hook_date_default_argument_alter(&$argument, &$value) { $style_options = $style_options = $argument->view->display_handler->get_option('style_options'); if (!empty($style_options['track_date'])) { $default_date = new DrupalDateTime(); $value = $default_date->format($argument->arg_format); } }
/** * {@inheritdoc} */ public function setDateTime(DrupalDateTime $dateTime, $notify = TRUE) { $this->value = $dateTime->getTimestamp(); // Notify the parent of any changes. if ($notify && isset($this->parent)) { $this->parent->onChange($this->name); } }
/** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { $form = parent::settingsForm($form, $form_state); $time = new DrupalDateTime(); $format_types = $this->dateFormatStorage->loadMultiple(); $options = []; foreach ($format_types as $type => $type_info) { $format = $this->dateFormatter->format($time->format('U'), $type); $options[$type] = $type_info->label() . ' (' . $format . ')'; } $form['format_type'] = array('#type' => 'select', '#title' => t('Date format'), '#description' => t("Choose a format for displaying the date. Be sure to set a format appropriate for the field, i.e. omitting time for a field that only has a date."), '#options' => $options, '#default_value' => $this->getSetting('format_type')); return $form; }
/** * Test that DrupalDateTime can detect the right timezone to use. * Test with a variety of less commonly used timezone names to * help ensure that the system timezone will be different than the * stated timezones. */ public function testDateTimezone() { global $user; $date_string = '2007-01-31 21:00:00'; // Make sure no site timezone has been set. \Drupal::config('system.date')->set('timezone.user.configurable', 0)->set('timezone.default', NULL)->save(); // Detect the system timezone. $system_timezone = date_default_timezone_get(); // Create a date object with an unspecified timezone, which should // end up using the system timezone. $date = new DrupalDateTime($date_string); $timezone = $date->getTimezone()->getName(); $this->assertTrue($timezone == $system_timezone, 'DrupalDateTime uses the system timezone when there is no site timezone.'); // Create a date object with a specified timezone. $date = new DrupalDateTime($date_string, 'America/Yellowknife'); $timezone = $date->getTimezone()->getName(); $this->assertTrue($timezone == 'America/Yellowknife', 'DrupalDateTime uses the specified timezone if provided.'); // Set a site timezone. \Drupal::config('system.date')->set('timezone.default', 'Europe/Warsaw')->save(); // Create a date object with an unspecified timezone, which should // end up using the site timezone. $date = new DrupalDateTime($date_string); $timezone = $date->getTimezone()->getName(); $this->assertTrue($timezone == 'Europe/Warsaw', 'DrupalDateTime uses the site timezone if provided.'); // Create user. \Drupal::config('system.date')->set('timezone.user.configurable', 1)->save(); $test_user = $this->drupalCreateUser(array()); $this->drupalLogin($test_user); // Set up the user with a different timezone than the site. $edit = array('mail' => $test_user->getEmail(), 'timezone' => 'Asia/Manila'); $this->drupalPostForm('user/' . $test_user->id() . '/edit', $edit, t('Save')); // Disable session saving as we are about to modify the global $user. \Drupal::service('session_manager')->disable(); // Save the original user and then replace it with the test user. $real_user = $user; $user = user_load($test_user->id(), TRUE); // Simulate a Drupal bootstrap with the logged-in user. date_default_timezone_set(drupal_get_user_timezone()); // Create a date object with an unspecified timezone, which should // end up using the user timezone. $date = new DrupalDateTime($date_string); $timezone = $date->getTimezone()->getName(); $this->assertTrue($timezone == 'Asia/Manila', 'DrupalDateTime uses the user timezone, if configurable timezones are used and it is set.'); // Restore the original user, and enable session saving. $user = $real_user; // Restore default time zone. date_default_timezone_set(drupal_get_user_timezone()); \Drupal::service('session_manager')->enable(); }
/** * Test taxonomy functionality with nodes prior to 1970. */ function testTaxonomyLegacyNode() { // Posts an article with a taxonomy term and a date prior to 1970. $date = new DrupalDateTime('1969-01-01 00:00:00'); $edit = array(); $edit['title[0][value]'] = $this->randomMachineName(); $edit['created[0][value][date]'] = $date->format('Y-m-d'); $edit['created[0][value][time]'] = $date->format('H:i:s'); $edit['body[0][value]'] = $this->randomMachineName(); $edit['field_tags[target_id]'] = $this->randomMachineName(); $this->drupalPostForm('node/add/article', $edit, t('Save and publish')); // Checks that the node has been saved. $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertEqual($node->getCreatedTime(), $date->getTimestamp(), 'Legacy node was saved with the right date.'); }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $default_role_choices = user_role_names(TRUE); unset($default_role_choices[DRUPAL_AUTHENTICATED_RID]); $roles_config = $this->config('uc_role.settings'); if (!count($default_role_choices)) { $form['no_roles'] = array('#markup' => $this->t('You need to <a href=":url">create new roles</a> before any can be added as product features.', [':url' => Url::fromRoute('user.role_add', [], ['query' => ['destination' => 'admin/store/config/products']])->toString()]), '#prefix' => '<p>', '#suffix' => '</p>'); return $form; } $form['default_role'] = array('#type' => 'select', '#title' => $this->t('Default role'), '#default_value' => $roles_config->get('default_role'), '#description' => $this->t('The default role Ubercart grants on specified products.'), '#options' => _uc_role_get_choices()); $form['default_role_choices'] = array('#type' => 'checkboxes', '#title' => $this->t('Product roles'), '#default_value' => $roles_config->get('default_role_choices'), '#multiple' => TRUE, '#description' => $this->t('These are roles that Ubercart can grant to customers who purchase specified products. If you leave all roles unchecked, they will all be eligible for adding to a product.'), '#options' => $default_role_choices); $form['role_lifetime'] = array('#type' => 'fieldset', '#title' => $this->t('Default role expiration')); $form['role_lifetime']['default_end_expiration'] = array('#type' => 'select', '#title' => $this->t('Expiration type'), '#options' => array('rel' => $this->t('Relative to purchase date'), 'abs' => $this->t('Fixed date')), '#default_value' => $roles_config->get('default_end_expiration')); $form['role_lifetime']['default_length'] = array('#type' => 'textfield', '#default_value' => $roles_config->get('default_granularity') == 'never' ? NULL : $roles_config->get('default_length'), '#size' => 4, '#maxlength' => 4, '#prefix' => '<div class="expiration">', '#suffix' => '</div>', '#states' => array('visible' => array('select[name="default_end_expiration"]' => array('value' => 'rel')), 'invisible' => array('select[name="default_granularity"]' => array('value' => 'never')))); $form['role_lifetime']['default_granularity'] = array('#type' => 'select', '#default_value' => $roles_config->get('default_granularity'), '#options' => array('never' => $this->t('never'), 'day' => $this->t('day(s)'), 'week' => $this->t('week(s)'), 'month' => $this->t('month(s)'), 'year' => $this->t('year(s)')), '#description' => $this->t('From the time the role was purchased.'), '#prefix' => '<div class="expiration">', '#suffix' => '</div>', '#states' => array('visible' => array('select[name="default_end_expiration"]' => array('value' => 'rel')))); $form['role_lifetime']['absolute'] = array('#type' => 'container', '#states' => array('visible' => array('select[name="default_end_expiration"]' => array('value' => 'abs')))); $date = (int) $roles_config->get('default_end_time'); $date = !empty($date) ? DrupalDateTime::createFromTimestamp($date) : DrupalDateTime::createFromTimestamp(REQUEST_TIME); $form['role_lifetime']['absolute']['default_end_time'] = array('#type' => 'datetime', '#description' => $this->t('Expire the role at the beginning of this day.'), '#date_date_element' => 'date', '#date_time_element' => 'none', '#default_value' => $date); $form['role_lifetime']['default_by_quantity'] = array('#type' => 'checkbox', '#title' => $this->t('Multiply by quantity'), '#description' => $this->t('Check if the role duration should be multiplied by the quantity purchased.'), '#default_value' => $roles_config->get('default_by_quantity')); $form['reminder']['reminder_length'] = array('#type' => 'textfield', '#title' => $this->t('Time before reminder'), '#default_value' => $roles_config->get('reminder_granularity') == 'never' ? NULL : $roles_config->get('reminder_length'), '#size' => 4, '#maxlength' => 4, '#prefix' => '<div class="expiration">', '#suffix' => '</div>', '#states' => array('disabled' => array('select[name="reminder_granularity"]' => array('value' => 'never')))); $form['reminder']['reminder_granularity'] = array('#type' => 'select', '#default_value' => $roles_config->get('reminder_granularity'), '#options' => array('never' => $this->t('never'), 'day' => $this->t('day(s)'), 'week' => $this->t('week(s)'), 'month' => $this->t('month(s)'), 'year' => $this->t('year(s)')), '#description' => $this->t('The amount of time before a role expiration takes place that a customer is notified of its expiration.'), '#prefix' => '<div class="expiration">', '#suffix' => '</div>'); $form['default_show_expiration'] = array('#type' => 'checkbox', '#title' => $this->t('Show expirations on user page'), '#default_value' => $roles_config->get('default_show_expiration'), '#description' => $this->t('If users have any role expirations they will be displayed on their account page.')); return parent::buildForm($form, $form_state); }
/** * {@inheritdoc} */ public function massageFormValues(array $values, array $form, FormStateInterface $form_state) { foreach ($values as &$item) { // @todo The structure is different whether access is denied or not, to // be fixed in https://www.drupal.org/node/2326533. if (isset($item['value']) && $item['value'] instanceof DrupalDateTime) { $date = $item['value']; } elseif (isset($item['value']['object']) && $item['value']['object'] instanceof DrupalDateTime) { $date = $item['value']['object']; } else { $date = new DrupalDateTime(); } $item['value'] = $date->getTimestamp(); } return $values; }
/** * {@inheritdoc} */ public static function valueCallback(&$element, $input, FormStateInterface $form_state) { if ($input !== FALSE) { $date_input = $element['#date_date_element'] != 'none' && !empty($input['date']) ? $input['date'] : ''; $time_input = $element['#date_time_element'] != 'none' && !empty($input['time']) ? $input['time'] : ''; $date_format = $element['#date_date_element'] != 'none' ? static::getHtml5DateFormat($element) : ''; $time_format = $element['#date_time_element'] != 'none' ? static::getHtml5TimeFormat($element) : ''; $timezone = !empty($element['#date_timezone']) ? $element['#date_timezone'] : NULL; // Seconds will be omitted in a post in case there's no entry. if (!empty($time_input) && strlen($time_input) == 5) { $time_input .= ':00'; } try { $date_time_format = trim($date_format . ' ' . $time_format); $date_time_input = trim($date_input . ' ' . $time_input); $date = DrupalDateTime::createFromFormat($date_time_format, $date_time_input, $timezone); } catch (\Exception $e) { $date = NULL; } $input = array('date' => $date_input, 'time' => $time_input, 'object' => $date); } else { $date = $element['#default_value']; if ($date instanceof DrupalDateTime && !$date->hasErrors()) { $input = array('date' => $date->format($element['#date_date_format']), 'time' => $date->format($element['#date_time_format']), 'object' => $date); } else { $input = array('date' => '', 'time' => '', 'object' => NULL); } } return $input; }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, OrderInterface $uc_order = NULL) { $balance = uc_payment_balance($uc_order); $form['balance'] = array('#prefix' => '<strong>' . $this->t('Order balance:') . '</strong> ', '#markup' => uc_currency_format($balance)); $form['order_id'] = array('#type' => 'hidden', '#value' => $uc_order->id()); $form['amount'] = array('#type' => 'uc_price', '#title' => $this->t('Check amount'), '#default_value' => $balance); $form['comment'] = array('#type' => 'textfield', '#title' => $this->t('Comment'), '#description' => $this->t('Any notes about the check, like type or check number.'), '#size' => 64, '#maxlength' => 256); $form['clear_date'] = array('#type' => 'datetime', '#title' => $this->t('Expected clear date'), '#date_date_element' => 'date', '#date_time_element' => 'none', '#default_value' => DrupalDateTime::createFromTimestamp(REQUEST_TIME)); $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Receive check')); return $form; }
/** * Test that DrupalDateTime can detect the right timezone to use. * Test with a variety of less commonly used timezone names to * help ensure that the system timezone will be different than the * stated timezones. */ public function testDateTimezone() { $date_string = '2007-01-31 21:00:00'; // Make sure no site timezone has been set. $this->config('system.date')->set('timezone.user.configurable', 0)->set('timezone.default', NULL)->save(); // Detect the system timezone. $system_timezone = date_default_timezone_get(); // Create a date object with an unspecified timezone, which should // end up using the system timezone. $date = new DrupalDateTime($date_string); $timezone = $date->getTimezone()->getName(); $this->assertTrue($timezone == $system_timezone, 'DrupalDateTime uses the system timezone when there is no site timezone.'); // Create a date object with a specified timezone. $date = new DrupalDateTime($date_string, 'America/Yellowknife'); $timezone = $date->getTimezone()->getName(); $this->assertTrue($timezone == 'America/Yellowknife', 'DrupalDateTime uses the specified timezone if provided.'); // Set a site timezone. $this->config('system.date')->set('timezone.default', 'Europe/Warsaw')->save(); // Create a date object with an unspecified timezone, which should // end up using the site timezone. $date = new DrupalDateTime($date_string); $timezone = $date->getTimezone()->getName(); $this->assertTrue($timezone == 'Europe/Warsaw', 'DrupalDateTime uses the site timezone if provided.'); // Create user. $this->config('system.date')->set('timezone.user.configurable', 1)->save(); $test_user = $this->drupalCreateUser(array()); $this->drupalLogin($test_user); // Set up the user with a different timezone than the site. $edit = array('mail' => $test_user->getEmail(), 'timezone' => 'Asia/Manila'); $this->drupalPostForm('user/' . $test_user->id() . '/edit', $edit, t('Save')); // Reload the user and reset the timezone in AccountProxy::setAccount(). \Drupal::entityManager()->getStorage('user')->resetCache(); $this->container->get('current_user')->setAccount(User::load($test_user->id())); // Create a date object with an unspecified timezone, which should // end up using the user timezone. $date = new DrupalDateTime($date_string); $timezone = $date->getTimezone()->getName(); $this->assertTrue($timezone == 'Asia/Manila', 'DrupalDateTime uses the user timezone, if configurable timezones are used and it is set.'); }
/** * Specifies the start and end year to use as a date range. * * Handles a string like -3:+3 or 2001:2010 to describe a dynamic range of * minimum and maximum years to use in a date selector. * * Centers the range around the current year, if any, but expands it far enough * so it will pick up the year value in the field in case the value in the field * is outside the initial range. * * @param string $string * A min and max year string like '-3:+1' or '2000:2010' or '2000:+3'. * @param object $date * (optional) A date object to test as a default value. Defaults to NULL. * * @return array * A numerically indexed array, containing the minimum and maximum year * described by this pattern. */ protected static function datetimeRangeYears($string, $date = NULL) { $datetime = new DrupalDateTime(); $this_year = $datetime->format('Y'); list($min_year, $max_year) = explode(':', $string); // Valid patterns would be -5:+5, 0:+1, 2008:2010. $plus_pattern = '@[\\+|\\-][0-9]{1,4}@'; $year_pattern = '@^[0-9]{4}@'; if (!preg_match($year_pattern, $min_year, $matches)) { if (preg_match($plus_pattern, $min_year, $matches)) { $min_year = $this_year + $matches[0]; } else { $min_year = $this_year; } } if (!preg_match($year_pattern, $max_year, $matches)) { if (preg_match($plus_pattern, $max_year, $matches)) { $max_year = $this_year + $matches[0]; } else { $max_year = $this_year; } } // We expect the $min year to be less than the $max year. Some custom values // for -99:+99 might not obey that. if ($min_year > $max_year) { $temp = $max_year; $max_year = $min_year; $min_year = $temp; } // If there is a current value, stretch the range to include it. $value_year = $date instanceof DrupalDateTime ? $date->format('Y') : ''; if (!empty($value_year)) { $min_year = min($value_year, $min_year); $max_year = max($value_year, $max_year); } return array($min_year, $max_year); }
/** * {@inheritdoc} */ protected function prepareValue($delta, array &$values) { $date = FALSE; $value = trim($values['value']); if (is_numeric($value) || is_string($value) && ($value = strtotime($value))) { $date = DrupalDateTime::createFromTimestamp($value, DATETIME_STORAGE_TIMEZONE); } elseif ($value instanceof \DateTime) { $date = DrupalDateTime::createFromDateTime($value); } if ($date && !$date->hasErrors()) { $values['value'] = $date->format($this->storageFormat); } else { $values['value'] = ''; } }
/** * {@inheritdoc} */ protected function prepareValue($delta, array &$values) { $value = trim($values['value']); // This is a year value. if (ctype_digit($value) && strlen($value) === 4) { $value = 'January ' . $value; } if (is_numeric($value) || ($value = strtotime($value))) { $date = DrupalDateTime::createFromTimestamp($value, DATETIME_STORAGE_TIMEZONE); } if (isset($date) && !$date->hasErrors()) { $values['value'] = $date->format($this->storageFormat); } else { $values['value'] = ''; } }
/** * {@inheritdoc} */ public function getValue($langcode = NULL) { if ($this->date !== NULL) { return $this->date; } $item = $this->getParent(); $value = $item->{$this->definition->getSetting('date source')}; $storage_format = $item->getFieldDefinition()->getSetting('datetime_type') == 'date' ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT; try { $date = DrupalDateTime::createFromFormat($storage_format, $value, DATETIME_STORAGE_TIMEZONE); if ($date instanceof DrupalDateTime && !$date->hasErrors()) { $this->date = $date; } } catch (\Exception $e) { // @todo Handle this. } return $this->date; }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $args = NULL) { if (!isset($args['start_date'])) { $args['start_date'] = REQUEST_TIME; } if (!isset($args['end_date'])) { $args['end_date'] = REQUEST_TIME; } if (!isset($args['statuses'])) { $args['statuses'] = uc_report_order_statuses(); } $form['params'] = array('#type' => 'fieldset', '#title' => $this->t('Customize tax report parameters'), '#description' => $this->t('Adjust these values and update the report to build your sales tax report. Once submitted, the report may be bookmarked for easy reference in the future.')); $form['params']['start_date'] = array('#type' => 'datetime', '#title' => $this->t('Start date'), '#date_date_element' => 'date', '#date_time_element' => 'none', '#default_value' => DrupalDateTime::createFromTimestamp($args['start_date'])); $form['params']['end_date'] = array('#type' => 'datetime', '#title' => $this->t('End date'), '#date_date_element' => 'date', '#date_time_element' => 'none', '#default_value' => DrupalDateTime::createFromTimestamp($args['end_date'])); $form['params']['statuses'] = array('#type' => 'select', '#title' => $this->t('Order statuses'), '#description' => $this->t('Only orders with selected statuses will be included in the report.') . '<br />' . $this->t('Hold Ctrl + click to select multiple statuses.'), '#options' => OrderStatus::getOptionsList(), '#default_value' => $args['statuses'], '#multiple' => TRUE, '#size' => 5); $form['params']['actions'] = array('#type' => 'actions'); $form['params']['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Update report')); return $form; }
/** * Formats a date/time as a time interval. * * @param \Drupal\Core\Datetime\DrupalDateTime|object $date * A date/time object. * * @return string * The formatted date/time string using the past or future format setting. */ protected function formatDate(DrupalDateTime $date) { $granularity = $this->getSetting('granularity'); $timestamp = $date->getTimestamp(); $options = ['granularity' => $granularity]; if ($this->request->server->get('REQUEST_TIME') > $timestamp) { return SafeMarkup::format($this->getSetting('past_format'), ['@interval' => $this->dateFormatter->formatTimeDiffSince($timestamp, $options)]); } else { return SafeMarkup::format($this->getSetting('future_format'), ['@interval' => $this->dateFormatter->formatTimeDiffUntil($timestamp, $options)]); } }
/** * {@inheritdoc} */ public function getCreatedTime() { return DrupalDateTime::createFromTimestamp($this->get('created')->value); }
/** * Sets the proper time zone on a DrupalDateTime object for the current user. * * A DrupalDateTime object loaded from the database will have the UTC time * zone applied to it. This method will apply the time zone for the current * user, based on system and user settings. * * @see drupal_get_user_timezone() * * @param \Drupal\Core\Datetime\DrupalDateTime $date * A DrupalDateTime object. */ protected function setTimeZone(DrupalDateTime $date) { $date->setTimeZone(timezone_open(drupal_get_user_timezone())); }
/** * Formats a date/time as a time interval. * * @param \Drupal\Core\Datetime\DrupalDateTime|object $date * A date/time object. * * @return array * The formatted date/time string using the past or future format setting. */ protected function formatDate(DrupalDateTime $date) { $granularity = $this->getSetting('granularity'); $timestamp = $date->getTimestamp(); $options = ['granularity' => $granularity, 'return_as_object' => TRUE]; if ($this->request->server->get('REQUEST_TIME') > $timestamp) { $result = $this->dateFormatter->formatTimeDiffSince($timestamp, $options); $build = ['#markup' => SafeMarkup::format($this->getSetting('past_format'), ['@interval' => $result->getString()])]; } else { $result = $this->dateFormatter->formatTimeDiffUntil($timestamp, $options); $build = ['#markup' => SafeMarkup::format($this->getSetting('future_format'), ['@interval' => $result->getString()])]; } CacheableMetadata::createFromObject($result)->applyTo($build); return $build; }
/** * Sets the proper time zone on a DrupalDateTime object for the current user. * * A DrupalDateTime object loaded from the database will have the UTC time * zone applied to it. This method will apply the time zone for the current * user, based on system and user settings. * * @see drupal_get_user_timezone() * * @param \Drupal\Core\Datetime\DrupalDateTime $date * A DrupalDateTime object. */ protected function setTimeZone(DrupalDateTime $date) { if ($this->getFieldSetting('datetime_type') === DateTimeItem::DATETIME_TYPE_DATE) { // A date without time has no timezone conversion. $timezone = DATETIME_STORAGE_TIMEZONE; } else { $timezone = drupal_get_user_timezone(); } $date->setTimeZone(timezone_open($timezone)); }
/** * Creates a forum topic. * * @return string * The title of the newly generated topic. */ protected function createForumTopics($count = 5) { $topics = array(); $date = new DrupalDateTime(); $date->modify('-24 hours'); for ($index = 0; $index < $count; $index++) { // Generate a random subject/body. $title = $this->randomMachineName(20); $body = $this->randomMachineName(200); // Forum posts are ordered by timestamp, so force a unique timestamp by // changing the date. $date->modify('+1 minute'); $edit = array('title[0][value]' => $title, 'body[0][value]' => $body, 'created[0][value][date]' => $date->format('Y-m-d'), 'created[0][value][time]' => $date->format('H:i:s')); // Create the forum topic, preselecting the forum ID via a URL parameter. $this->drupalPostForm('node/add/forum', $edit, t('Save and publish'), array('query' => array('forum_id' => 1))); $topics[] = $title; } return $topics; }
/** * Overrides Drupal\Core\Entity\EntityForm::form(). */ public function form(array $form, FormStateInterface $form_state) { /** @var \Drupal\comment\CommentInterface $comment */ $comment = $this->entity; $entity = $this->entityManager->getStorage($comment->getCommentedEntityTypeId())->load($comment->getCommentedEntityId()); $field_name = $comment->getFieldName(); $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()]; // Use #comment-form as unique jump target, regardless of entity type. $form['#id'] = drupal_html_id('comment_form'); $form['#theme'] = array('comment_form__' . $entity->getEntityTypeId() . '__' . $entity->bundle() . '__' . $field_name, 'comment_form'); $anonymous_contact = $field_definition->getSetting('anonymous'); $is_admin = $comment->id() && $this->currentUser->hasPermission('administer comments'); if (!$this->currentUser->isAuthenticated() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT) { $form['#attached']['library'][] = 'core/drupal.form'; $form['#attributes']['data-user-info-from-browser'] = TRUE; } // If not replying to a comment, use our dedicated page callback for new // Comments on entities. if (!$comment->id() && !$comment->hasParentComment()) { $form['#action'] = $this->url('comment.reply', array('entity_type' => $entity->getEntityTypeId(), 'entity' => $entity->id(), 'field_name' => $field_name)); } $comment_preview = $form_state->get('comment_preview'); if (isset($comment_preview)) { $form += $comment_preview; } $form['author'] = array(); // Display author information in a details element for comment moderators. if ($is_admin) { $form['author'] += array('#type' => 'details', '#title' => $this->t('Administration')); } // Prepare default values for form elements. if ($is_admin) { $author = $comment->getAuthorName(); $status = $comment->getStatus(); if (empty($comment_preview)) { $form['#title'] = $this->t('Edit comment %title', array('%title' => $comment->getSubject())); } } else { if ($this->currentUser->isAuthenticated()) { $author = $this->currentUser->getUsername(); } else { $author = $comment->getAuthorName() ? $comment->getAuthorName() : ''; } $status = $this->currentUser->hasPermission('skip comment approval') ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED; } $date = ''; if ($comment->id()) { $date = !empty($comment->date) ? $comment->date : DrupalDateTime::createFromTimestamp($comment->getCreatedTime()); } // Add the author name field depending on the current user. $form['author']['name'] = array('#type' => 'textfield', '#title' => $this->t('Your name'), '#default_value' => $author, '#required' => $this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT, '#maxlength' => 60, '#size' => 30); if ($is_admin) { $form['author']['name']['#title'] = $this->t('Authored by'); $form['author']['name']['#description'] = $this->t('Leave blank for %anonymous.', array('%anonymous' => $this->config('user.settings')->get('anonymous'))); $form['author']['name']['#autocomplete_route_name'] = 'user.autocomplete'; } elseif ($this->currentUser->isAuthenticated()) { $form['author']['name']['#type'] = 'item'; $form['author']['name']['#value'] = $form['author']['name']['#default_value']; $form['author']['name']['#theme'] = 'username'; $form['author']['name']['#account'] = $this->currentUser; } elseif ($this->currentUser->isAnonymous()) { $form['author']['name']['#attributes']['data-drupal-default-value'] = $this->config('user.settings')->get('anonymous'); } $language_configuration = \Drupal::moduleHandler()->invoke('language', 'get_default_configuration', array('comment', $comment->getTypeId())); $form['langcode'] = array('#title' => t('Language'), '#type' => 'language_select', '#default_value' => $comment->getUntranslated()->language()->getId(), '#languages' => Language::STATE_ALL, '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show']); // Add author email and homepage fields depending on the current user. $form['author']['mail'] = array('#type' => 'email', '#title' => $this->t('Email'), '#default_value' => $comment->getAuthorEmail(), '#required' => $this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT, '#maxlength' => 64, '#size' => 30, '#description' => $this->t('The content of this field is kept private and will not be shown publicly.'), '#access' => $is_admin || $this->currentUser->isAnonymous() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT); $form['author']['homepage'] = array('#type' => 'url', '#title' => $this->t('Homepage'), '#default_value' => $comment->getHomepage(), '#maxlength' => 255, '#size' => 30, '#access' => $is_admin || $this->currentUser->isAnonymous() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT); // Add administrative comment publishing options. $form['author']['date'] = array('#type' => 'datetime', '#title' => $this->t('Authored on'), '#default_value' => $date, '#size' => 20, '#access' => $is_admin); $form['author']['status'] = array('#type' => 'radios', '#title' => $this->t('Status'), '#default_value' => $status, '#options' => array(CommentInterface::PUBLISHED => $this->t('Published'), CommentInterface::NOT_PUBLISHED => $this->t('Not published')), '#access' => $is_admin); // Used for conditional validation of author fields. $form['is_anonymous'] = array('#type' => 'value', '#value' => $comment->id() ? !$comment->getOwnerId() : $this->currentUser->isAnonymous()); return parent::form($form, $form_state, $comment); }
/** * Formats a date, using a date type or a custom date format string. * * @param int $timestamp * A UNIX timestamp to format. * @param string $type * (optional) The format to use, one of: * - One of the built-in formats: 'short', 'medium', * 'long', 'html_datetime', 'html_date', 'html_time', * 'html_yearless_date', 'html_week', 'html_month', 'html_year'. * - The name of a date type defined by a date format config entity. * - The machine name of an administrator-defined date format. * - 'custom', to use $format. * Defaults to 'medium'. * @param string $format * (optional) If $type is 'custom', a PHP date format string suitable for * input to date(). Use a backslash to escape ordinary text, so it does not * get interpreted as date format characters. * @param string|null $timezone * (optional) Time zone identifier, as described at * http://php.net/manual/timezones.php Defaults to the time zone used to * display the page. * @param string|null $langcode * (optional) Language code to translate to. NULL (default) means to use * the user interface language for the page. * * @return string * A translated date string in the requested format. Since the format may * contain user input, this value should be escaped when output. */ public function format($timestamp, $type = 'medium', $format = '', $timezone = NULL, $langcode = NULL) { if (!isset($timezone)) { $timezone = date_default_timezone_get(); } // Store DateTimeZone objects in an array rather than repeatedly // constructing identical objects over the life of a request. if (!isset($this->timezones[$timezone])) { $this->timezones[$timezone] = timezone_open($timezone); } if (empty($langcode)) { $langcode = $this->languageManager->getCurrentLanguage()->getId(); } // Create a DrupalDateTime object from the timestamp and timezone. $create_settings = array('langcode' => $langcode, 'country' => $this->country()); $date = DrupalDateTime::createFromTimestamp($timestamp, $this->timezones[$timezone], $create_settings); // If we have a non-custom date format use the provided date format pattern. if ($date_format = $this->dateFormat($type, $langcode)) { $format = $date_format->getPattern(); } // Fall back to medium if a format was not found. if (empty($format)) { $format = $this->dateFormat('fallback', $langcode)->getPattern(); } // Call $date->format(). $settings = array('langcode' => $langcode); return $date->format($format, $settings); }
/** * Tests the basics around constructing and working with typed data objects. */ public function testGetAndSet() { // Boolean type. $typed_data = $this->createTypedData(array('type' => 'boolean'), TRUE); $this->assertTrue($typed_data instanceof BooleanInterface, 'Typed data object is an instance of BooleanInterface.'); $this->assertTrue($typed_data->getValue() === TRUE, 'Boolean value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(FALSE); $this->assertTrue($typed_data->getValue() === FALSE, 'Boolean value was changed.'); $this->assertEqual($typed_data->validate()->count(), 0); $this->assertTrue(is_string($typed_data->getString()), 'Boolean value was converted to string'); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'Boolean wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // String type. $value = $this->randomString(); $typed_data = $this->createTypedData(array('type' => 'string'), $value); $this->assertTrue($typed_data instanceof StringInterface, 'Typed data object is an instance of StringInterface.'); $this->assertTrue($typed_data->getValue() === $value, 'String value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); $new_value = $this->randomString(); $typed_data->setValue($new_value); $this->assertTrue($typed_data->getValue() === $new_value, 'String value was changed.'); $this->assertEqual($typed_data->validate()->count(), 0); // Funky test. $this->assertTrue(is_string($typed_data->getString()), 'String value was converted to string'); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'String wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(array('no string')); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Integer type. $value = rand(); $typed_data = $this->createTypedData(array('type' => 'integer'), $value); $this->assertTrue($typed_data instanceof IntegerInterface, 'Typed data object is an instance of IntegerInterface.'); $this->assertTrue($typed_data->getValue() === $value, 'Integer value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); $new_value = rand(); $typed_data->setValue($new_value); $this->assertTrue($typed_data->getValue() === $new_value, 'Integer value was changed.'); $this->assertTrue(is_string($typed_data->getString()), 'Integer value was converted to string'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'Integer wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Float type. $value = 123.45; $typed_data = $this->createTypedData(array('type' => 'float'), $value); $this->assertTrue($typed_data instanceof FloatInterface, 'Typed data object is an instance of FloatInterface.'); $this->assertTrue($typed_data->getValue() === $value, 'Float value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); $new_value = 678.9; $typed_data->setValue($new_value); $this->assertTrue($typed_data->getValue() === $new_value, 'Float value was changed.'); $this->assertTrue(is_string($typed_data->getString()), 'Float value was converted to string'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'Float wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Date Time type. $value = '2014-01-01T20:00:00+00:00'; $typed_data = $this->createTypedData(array('type' => 'datetime_iso8601'), $value); $this->assertTrue($typed_data instanceof DateTimeInterface, 'Typed data object is an instance of DateTimeInterface.'); $this->assertTrue($typed_data->getValue() == $value, 'Date value was fetched.'); $this->assertEqual($typed_data->getValue(), $typed_data->getDateTime()->format('c'), 'Value representation of a date is ISO 8601'); $this->assertEqual($typed_data->validate()->count(), 0); $new_value = '2014-01-02T20:00:00+00:00'; $typed_data->setValue($new_value); $this->assertTrue($typed_data->getDateTime()->format('c') === $new_value, 'Date value was changed and set by an ISO8601 date.'); $this->assertEqual($typed_data->validate()->count(), 0); $this->assertTrue($typed_data->getDateTime()->format('Y-m-d') == '2014-01-02', 'Date value was changed and set by date string.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getDateTime(), 'Date wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Check implementation of DateTimeInterface. $typed_data = $this->createTypedData(array('type' => 'datetime_iso8601'), '2014-01-01T20:00:00+00:00'); $this->assertTrue($typed_data->getDateTime() instanceof DrupalDateTime); $typed_data->setDateTime(new DrupalDateTime('2014-01-02T20:00:00+00:00')); $this->assertEqual($typed_data->getValue(), '2014-01-02T20:00:00+00:00'); $typed_data->setValue(NULL); $this->assertNull($typed_data->getDateTime()); // Timestamp type. $value = REQUEST_TIME; $typed_data = $this->createTypedData(array('type' => 'timestamp'), $value); $this->assertTrue($typed_data instanceof DateTimeInterface, 'Typed data object is an instance of DateTimeInterface.'); $this->assertTrue($typed_data->getValue() == $value, 'Timestamp value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); $new_value = REQUEST_TIME + 1; $typed_data->setValue($new_value); $this->assertTrue($typed_data->getValue() === $new_value, 'Timestamp value was changed and set.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getDateTime(), 'Timestamp wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Check implementation of DateTimeInterface. $typed_data = $this->createTypedData(array('type' => 'timestamp'), REQUEST_TIME); $this->assertTrue($typed_data->getDateTime() instanceof DrupalDateTime); $typed_data->setDateTime(DrupalDateTime::createFromTimestamp(REQUEST_TIME + 1)); $this->assertEqual($typed_data->getValue(), REQUEST_TIME + 1); $typed_data->setValue(NULL); $this->assertNull($typed_data->getDateTime()); // DurationIso8601 type. $value = 'PT20S'; $typed_data = $this->createTypedData(array('type' => 'duration_iso8601'), $value); $this->assertTrue($typed_data instanceof DurationInterface, 'Typed data object is an instance of DurationInterface.'); $this->assertIdentical($typed_data->getValue(), $value, 'DurationIso8601 value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('P40D'); $this->assertEqual($typed_data->getDuration()->d, 40, 'DurationIso8601 value was changed and set by duration string.'); $this->assertTrue(is_string($typed_data->getString()), 'DurationIso8601 value was converted to string'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'DurationIso8601 wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Check implementation of DurationInterface. $typed_data = $this->createTypedData(array('type' => 'duration_iso8601'), 'PT20S'); $this->assertTrue($typed_data->getDuration() instanceof \DateInterval); $typed_data->setDuration(new \DateInterval('P40D')); // @todo: Should we make this "nicer"? $this->assertEqual($typed_data->getValue(), 'P0Y0M40DT0H0M0S'); $typed_data->setValue(NULL); $this->assertNull($typed_data->getDuration()); // Time span type. $value = 20; $typed_data = $this->createTypedData(array('type' => 'timespan'), $value); $this->assertTrue($typed_data instanceof DurationInterface, 'Typed data object is an instance of DurationInterface.'); $this->assertIdentical($typed_data->getValue(), $value, 'Time span value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(60 * 60 * 4); $this->assertEqual($typed_data->getDuration()->s, 14400, 'Time span was changed'); $this->assertTrue(is_string($typed_data->getString()), 'Time span value was converted to string'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'Time span wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Check implementation of DurationInterface. $typed_data = $this->createTypedData(array('type' => 'timespan'), 20); $this->assertTrue($typed_data->getDuration() instanceof \DateInterval); $typed_data->setDuration(new \DateInterval('PT4H')); $this->assertEqual($typed_data->getValue(), 60 * 60 * 4); $typed_data->setValue(NULL); $this->assertNull($typed_data->getDuration()); // URI type. $uri = 'http://example.com/foo/'; $typed_data = $this->createTypedData(array('type' => 'uri'), $uri); $this->assertTrue($typed_data instanceof UriInterface, 'Typed data object is an instance of UriInterface.'); $this->assertTrue($typed_data->getValue() === $uri, 'URI value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue($uri . 'bar.txt'); $this->assertTrue($typed_data->getValue() === $uri . 'bar.txt', 'URI value was changed.'); $this->assertTrue(is_string($typed_data->getString()), 'URI value was converted to string'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'URI wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); $typed_data->setValue('public://field/image/Photo on 4-28-14 at 12.01 PM.jpg'); $this->assertEqual($typed_data->validate()->count(), 0, 'Filename with spaces is valid.'); // Generate some files that will be used to test the binary data type. $files = array(); for ($i = 0; $i < 3; $i++) { $path = "public://example_{$i}.png"; file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', $path); $image = File::create(['uri' => $path]); $image->save(); $files[] = $image; } // Email type. $value = $this->randomString(); $typed_data = $this->createTypedData(array('type' => 'email'), $value); $this->assertTrue($typed_data instanceof StringInterface, 'Typed data object is an instance of StringInterface.'); $this->assertIdentical($typed_data->getValue(), $value, 'Email value was fetched.'); $new_value = '*****@*****.**'; $typed_data->setValue($new_value); $this->assertIdentical($typed_data->getValue(), $new_value, 'Email value was changed.'); $this->assertTrue(is_string($typed_data->getString()), 'Email value was converted to string'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'Email wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('invalidATexample.com'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Binary type. $typed_data = $this->createTypedData(array('type' => 'binary'), $files[0]->getFileUri()); $this->assertTrue($typed_data instanceof BinaryInterface, 'Typed data object is an instance of BinaryInterface.'); $this->assertTrue(is_resource($typed_data->getValue()), 'Binary value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); // Try setting by URI. $typed_data->setValue($files[1]->getFileUri()); $this->assertEqual(fgets($typed_data->getValue()), fgets(fopen($files[1]->getFileUri(), 'r')), 'Binary value was changed.'); $this->assertTrue(is_string($typed_data->getString()), 'Binary value was converted to string'); $this->assertEqual($typed_data->validate()->count(), 0); // Try setting by resource. $typed_data->setValue(fopen($files[2]->getFileUri(), 'r')); $this->assertEqual(fgets($typed_data->getValue()), fgets(fopen($files[2]->getFileUri(), 'r')), 'Binary value was changed.'); $this->assertTrue(is_string($typed_data->getString()), 'Binary value was converted to string'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'Binary wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Any type. $value = array('foo'); $typed_data = $this->createTypedData(array('type' => 'any'), $value); $this->assertIdentical($typed_data->getValue(), $value, 'Any value was fetched.'); $new_value = '*****@*****.**'; $typed_data->setValue($new_value); $this->assertIdentical($typed_data->getValue(), $new_value, 'Any value was changed.'); $this->assertTrue(is_string($typed_data->getString()), 'Any value was converted to string'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'Any wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); // We cannot test invalid values as everything is valid for the any type, // but make sure an array or object value passes validation also. $typed_data->setValue(array('entry')); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue((object) array('entry')); $this->assertEqual($typed_data->validate()->count(), 0); }
/** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { /** @var \Drupal\comment\CommentInterface $comment */ $comment = $this->entity; $entity = $this->entityManager->getStorage($comment->getCommentedEntityTypeId())->load($comment->getCommentedEntityId()); $field_name = $comment->getFieldName(); $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()]; $config = $this->config('user.settings'); // In several places within this function, we vary $form on: // - The current user's permissions. // - Whether the current user is authenticated or anonymous. // - The 'user.settings' configuration. // - The comment field's definition. $form['#cache']['contexts'][] = 'user.permissions'; $form['#cache']['contexts'][] = 'user.roles:authenticated'; $this->renderer->addCacheableDependency($form, $config); $this->renderer->addCacheableDependency($form, $field_definition->getConfig($entity->bundle())); // Use #comment-form as unique jump target, regardless of entity type. $form['#id'] = Html::getUniqueId('comment_form'); $form['#theme'] = array('comment_form__' . $entity->getEntityTypeId() . '__' . $entity->bundle() . '__' . $field_name, 'comment_form'); $anonymous_contact = $field_definition->getSetting('anonymous'); $is_admin = $comment->id() && $this->currentUser->hasPermission('administer comments'); if (!$this->currentUser->isAuthenticated() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT) { $form['#attached']['library'][] = 'core/drupal.form'; $form['#attributes']['data-user-info-from-browser'] = TRUE; } // If not replying to a comment, use our dedicated page callback for new // Comments on entities. if (!$comment->id() && !$comment->hasParentComment()) { $form['#action'] = $this->url('comment.reply', array('entity_type' => $entity->getEntityTypeId(), 'entity' => $entity->id(), 'field_name' => $field_name)); } $comment_preview = $form_state->get('comment_preview'); if (isset($comment_preview)) { $form += $comment_preview; } $form['author'] = array(); // Display author information in a details element for comment moderators. if ($is_admin) { $form['author'] += array('#type' => 'details', '#title' => $this->t('Administration')); } // Prepare default values for form elements. $author = ''; if ($is_admin) { if (!$comment->getOwnerId()) { $author = $comment->getAuthorName(); } $status = $comment->getStatus(); if (empty($comment_preview)) { $form['#title'] = $this->t('Edit comment %title', array('%title' => $comment->getSubject())); } } else { $status = $this->currentUser->hasPermission('skip comment approval') ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED; } $date = ''; if ($comment->id()) { $date = !empty($comment->date) ? $comment->date : DrupalDateTime::createFromTimestamp($comment->getCreatedTime()); } // The uid field is only displayed when a user with the permission // 'administer comments' is editing an existing comment from an // authenticated user. $owner = $comment->getOwner(); $form['author']['uid'] = ['#type' => 'entity_autocomplete', '#target_type' => 'user', '#default_value' => $owner->isAnonymous() ? NULL : $owner, '#selection_settings' => ['include_anonymous' => FALSE], '#title' => $this->t('Authored by'), '#description' => $this->t('Leave blank for %anonymous.', ['%anonymous' => $config->get('anonymous')]), '#access' => $is_admin]; // The name field is displayed when an anonymous user is adding a comment or // when a user with the permission 'administer comments' is editing an // existing comment from an anonymous user. $form['author']['name'] = array('#type' => 'textfield', '#title' => $is_admin ? $this->t('Name for @anonymous', ['@anonymous' => $config->get('anonymous')]) : $this->t('Your name'), '#default_value' => $author, '#required' => $this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT, '#maxlength' => 60, '#access' => $this->currentUser->isAnonymous() || $is_admin, '#size' => 30, '#attributes' => ['data-drupal-default-value' => $config->get('anonymous')]); if ($is_admin) { // When editing a comment only display the name textfield if the uid field // is empty. $form['author']['name']['#states'] = ['visible' => [':input[name="uid"]' => array('empty' => TRUE)]]; } // Add author email and homepage fields depending on the current user. $form['author']['mail'] = array('#type' => 'email', '#title' => $this->t('Email'), '#default_value' => $comment->getAuthorEmail(), '#required' => $this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT, '#maxlength' => 64, '#size' => 30, '#description' => $this->t('The content of this field is kept private and will not be shown publicly.'), '#access' => $comment->getOwner()->isAnonymous() && $is_admin || $this->currentUser->isAnonymous() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT); $form['author']['homepage'] = array('#type' => 'url', '#title' => $this->t('Homepage'), '#default_value' => $comment->getHomepage(), '#maxlength' => 255, '#size' => 30, '#access' => $is_admin || $this->currentUser->isAnonymous() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT); // Add administrative comment publishing options. $form['author']['date'] = array('#type' => 'datetime', '#title' => $this->t('Authored on'), '#default_value' => $date, '#size' => 20, '#access' => $is_admin); $form['author']['status'] = array('#type' => 'radios', '#title' => $this->t('Status'), '#default_value' => $status, '#options' => array(CommentInterface::PUBLISHED => $this->t('Published'), CommentInterface::NOT_PUBLISHED => $this->t('Not published')), '#access' => $is_admin); return parent::form($form, $form_state, $comment); }
/** * Tests comment edit, preview, and save. */ function testCommentEditPreviewSave() { $web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'skip comment approval', 'edit own comments')); $this->drupalLogin($this->adminUser); $this->setCommentPreview(DRUPAL_OPTIONAL); $this->setCommentForm(TRUE); $this->setCommentSubject(TRUE); $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Comment paging changed.'); $edit = array(); $date = new DrupalDateTime('2008-03-02 17:23'); $edit['subject[0][value]'] = $this->randomMachineName(8); $edit['comment_body[0][value]'] = $this->randomMachineName(16); $edit['uid'] = $web_user->getUsername() . ' (' . $web_user->id() . ')'; $edit['date[date]'] = $date->format('Y-m-d'); $edit['date[time]'] = $date->format('H:i:s'); $raw_date = $date->getTimestamp(); $expected_text_date = format_date($raw_date); $expected_form_date = $date->format('Y-m-d'); $expected_form_time = $date->format('H:i:s'); $comment = $this->postComment($this->node, $edit['subject[0][value]'], $edit['comment_body[0][value]'], TRUE); $this->drupalPostForm('comment/' . $comment->id() . '/edit', $edit, t('Preview')); // Check that the preview is displaying the subject, comment, author and date correctly. $this->assertTitle(t('Preview comment | Drupal'), 'Page title is "Preview comment".'); $this->assertText($edit['subject[0][value]'], 'Subject displayed.'); $this->assertText($edit['comment_body[0][value]'], 'Comment displayed.'); $this->assertText($web_user->getUsername(), 'Author displayed.'); $this->assertText($expected_text_date, 'Date displayed.'); // Check that the subject, comment, author and date fields are displayed with the correct values. $this->assertFieldByName('subject[0][value]', $edit['subject[0][value]'], 'Subject field displayed.'); $this->assertFieldByName('comment_body[0][value]', $edit['comment_body[0][value]'], 'Comment field displayed.'); $this->assertFieldByName('uid', $edit['uid'], 'Author field displayed.'); $this->assertFieldByName('date[date]', $edit['date[date]'], 'Date field displayed.'); $this->assertFieldByName('date[time]', $edit['date[time]'], 'Time field displayed.'); // Check that saving a comment produces a success message. $this->drupalPostForm('comment/' . $comment->id() . '/edit', $edit, t('Save')); $this->assertText(t('Your comment has been posted.'), 'Comment posted.'); // Check that the comment fields are correct after loading the saved comment. $this->drupalGet('comment/' . $comment->id() . '/edit'); $this->assertFieldByName('subject[0][value]', $edit['subject[0][value]'], 'Subject field displayed.'); $this->assertFieldByName('comment_body[0][value]', $edit['comment_body[0][value]'], 'Comment field displayed.'); $this->assertFieldByName('uid', $edit['uid'], 'Author field displayed.'); $this->assertFieldByName('date[date]', $expected_form_date, 'Date field displayed.'); $this->assertFieldByName('date[time]', $expected_form_time, 'Time field displayed.'); // Submit the form using the displayed values. $displayed = array(); $displayed['subject[0][value]'] = (string) current($this->xpath("//input[@id='edit-subject-0-value']/@value")); $displayed['comment_body[0][value]'] = (string) current($this->xpath("//textarea[@id='edit-comment-body-0-value']")); $displayed['uid'] = (string) current($this->xpath("//input[@id='edit-uid']/@value")); $displayed['date[date]'] = (string) current($this->xpath("//input[@id='edit-date-date']/@value")); $displayed['date[time]'] = (string) current($this->xpath("//input[@id='edit-date-time']/@value")); $this->drupalPostForm('comment/' . $comment->id() . '/edit', $displayed, t('Save')); // Check that the saved comment is still correct. $comment_storage = \Drupal::entityManager()->getStorage('comment'); $comment_storage->resetCache(array($comment->id())); /** @var \Drupal\comment\CommentInterface $comment_loaded */ $comment_loaded = Comment::load($comment->id()); $this->assertEqual($comment_loaded->getSubject(), $edit['subject[0][value]'], 'Subject loaded.'); $this->assertEqual($comment_loaded->comment_body->value, $edit['comment_body[0][value]'], 'Comment body loaded.'); $this->assertEqual($comment_loaded->getOwner()->id(), $web_user->id(), 'Name loaded.'); $this->assertEqual($comment_loaded->getCreatedTime(), $raw_date, 'Date loaded.'); $this->drupalLogout(); // Check that the date and time of the comment are correct when edited by // non-admin users. $user_edit = array(); $expected_created_time = $comment_loaded->getCreatedTime(); $this->drupalLogin($web_user); // Web user cannot change the comment author. unset($edit['uid']); $this->drupalPostForm('comment/' . $comment->id() . '/edit', $user_edit, t('Save')); $comment_storage->resetCache(array($comment->id())); $comment_loaded = Comment::load($comment->id()); $this->assertEqual($comment_loaded->getCreatedTime(), $expected_created_time, 'Expected date and time for comment edited.'); $this->drupalLogout(); }
/** * Test default value functionality. */ function testDefaultValue() { // Create a test content type. $this->drupalCreateContentType(array('type' => 'date_content')); // Create a field storage with settings to validate. $field_name = Unicode::strtolower($this->randomMachineName()); $field_storage = entity_create('field_storage_config', array('field_name' => $field_name, 'entity_type' => 'node', 'type' => 'datetime', 'settings' => array('datetime_type' => 'date'))); $field_storage->save(); $field = entity_create('field_config', array('field_storage' => $field_storage, 'bundle' => 'date_content')); $field->save(); // Set now as default_value. $field_edit = array('default_value_input[default_date_type]' => 'now'); $this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings')); // Check that default value is selected in default value form. $this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name); $this->assertOptionSelected('edit-default-value-input-default-date-type', 'now', 'The default value is selected in instance settings page'); $this->assertFieldByName('default_value_input[default_date]', '', 'The relative default value is empty in instance settings page'); // Check if default_date has been stored successfully. $config_entity = $this->config('field.field.node.date_content.' . $field_name)->get(); $this->assertEqual($config_entity['default_value'][0], array('default_date_type' => 'now', 'default_date' => 'now'), 'Default value has been stored successfully'); // Clear field cache in order to avoid stale cache values. \Drupal::entityManager()->clearCachedFieldDefinitions(); // Create a new node to check that datetime field default value is today. $new_node = entity_create('node', array('type' => 'date_content')); $expected_date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE); $this->assertEqual($new_node->get($field_name)->offsetGet(0)->value, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT)); // Set an invalid relative default_value to test validation. $field_edit = array('default_value_input[default_date_type]' => 'relative', 'default_value_input[default_date]' => 'invalid date'); $this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings')); $this->assertText('The relative date value entered is invalid.'); // Set a relative default_value. $field_edit = array('default_value_input[default_date_type]' => 'relative', 'default_value_input[default_date]' => '+90 days'); $this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings')); // Check that default value is selected in default value form. $this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name); $this->assertOptionSelected('edit-default-value-input-default-date-type', 'relative', 'The default value is selected in instance settings page'); $this->assertFieldByName('default_value_input[default_date]', '+90 days', 'The relative default value is displayed in instance settings page'); // Check if default_date has been stored successfully. $config_entity = $this->config('field.field.node.date_content.' . $field_name)->get(); $this->assertEqual($config_entity['default_value'][0], array('default_date_type' => 'relative', 'default_date' => '+90 days'), 'Default value has been stored successfully'); // Clear field cache in order to avoid stale cache values. \Drupal::entityManager()->clearCachedFieldDefinitions(); // Create a new node to check that datetime field default value is +90 days. $new_node = entity_create('node', array('type' => 'date_content')); $expected_date = new DrupalDateTime('+90 days', DATETIME_STORAGE_TIMEZONE); $this->assertEqual($new_node->get($field_name)->offsetGet(0)->value, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT)); // Remove default value. $field_edit = array('default_value_input[default_date_type]' => ''); $this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings')); // Check that default value is selected in default value form. $this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name); $this->assertOptionSelected('edit-default-value-input-default-date-type', '', 'The default value is selected in instance settings page'); $this->assertFieldByName('default_value_input[default_date]', '', 'The relative default value is empty in instance settings page'); // Check if default_date has been stored successfully. $config_entity = $this->config('field.field.node.date_content.' . $field_name)->get(); $this->assertTrue(empty($config_entity['default_value']), 'Empty default value has been stored successfully'); // Clear field cache in order to avoid stale cache values. \Drupal::entityManager()->clearCachedFieldDefinitions(); // Create a new node to check that datetime field default value is not set. $new_node = entity_create('node', array('type' => 'date_content')); $this->assertNull($new_node->get($field_name)->value, 'Default value is not set'); }
/** * {@inheritdoc} */ public static function processDefaultValue($default_value, FieldableEntityInterface $entity, FieldDefinitionInterface $definition) { $default_value = parent::processDefaultValue($default_value, $entity, $definition); if (isset($default_value[0]['default_date_type'])) { // A default value should be in the format and timezone used for date // storage. $date = new DrupalDateTime($default_value[0]['default_date'], DATETIME_STORAGE_TIMEZONE); $storage_format = $definition->getSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT; $value = $date->format($storage_format); // We only provide a default value for the first item, as do all fields. // Otherwise, there is no way to clear out unwanted values on multiple value // fields. $default_value = array(array('value' => $value, 'date' => $date)); } return $default_value; }
/** * {@inheritdoc} */ public static function processDefaultValue($default_value, FieldableEntityInterface $entity, FieldDefinitionInterface $definition) { // Explicitly call the base class so that we can get the default value // types. $default_value = FieldItemList::processDefaultValue($default_value, $entity, $definition); // Allow either the start or end date to have a default, but not require // defaults for both. if (!empty($default_value[0]['default_date_type']) || !empty($default_value[0]['default_end_date_type'])) { // A default value should be in the format and timezone used for date // storage. All-day ranges are stored the same as date+time ranges. We // only provide a default value for the first item, as do all fields. // Otherwise, there is no way to clear out unwanted values on multiple // value fields. $storage_format = $definition->getSetting('datetime_type') == DateRangeItem::DATETIME_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT; $default_values = [[]]; if (!empty($default_value[0]['default_date_type'])) { $start_date = new DrupalDateTime($default_value[0]['default_date'], DATETIME_STORAGE_TIMEZONE); $start_value = $start_date->format($storage_format); $default_values[0]['value'] = $start_value; $default_values[0]['start_date'] = $start_date; } if (!empty($default_value[0]['default_end_date_type'])) { $end_date = new DrupalDateTime($default_value[0]['default_end_date'], DATETIME_STORAGE_TIMEZONE); $end_value = $end_date->format($storage_format); $default_values[0]['end_value'] = $end_value; $default_values[0]['end_date'] = $end_date; } $default_value = $default_values; } return $default_value; }