/** * Provides a method to update date fields that use a time increment value. * * @param int $time_increment * The new time increment value. */ function hook_studyroom_time_increment_update($time_increment) { foreach (studyroom_reservation_types() as $bundle) { $instance = field_info_instance('studyroom_reservation', 'field_reservation_datetime', $bundle->type); $instance['widget']['settings']['increment'] = $time_increment; field_update_instance($instance); } }
/** * @Given that the widget for the :field_name field of the :bundle :entity_type is changed to :widget_type_machine_name * * Behat is not very good at filling in form fields that are taxonomy * term trees, or checkboxes. The reason for this is that Behat is * overly energetic about regularly deleting and recreating all of the * test content, sometimes even in the middle of a scenario. The result * of this is that the term ids all change between the time the checkbox * is "clicked", and the time the form is submitted, leading to a validation * error. With this step definition, we can change taxonomy checkbox * fields into autocomplete forms, which Behat fills in with a String value * rather than a term id -- which works consistently. * * Example: * "Given that the widget for the offices field of the regnum entityform is changed to taxonomy_autocomplete" * "And the cache has been cleared" * * http://dropbucket.org/node/1265 */ function change_form_widget($entity_type, $bundle, $field_name, $widget_type_machine_name) { // Retrieve the stored instance settings to merge with the incoming values. $instance = field_read_instance($entity_type, $field_name, $bundle); // Set the right module information. $widget_type = field_info_widget_types($widget_type_machine_name); $widget_module = $widget_type['module']; $instance['widget']['type'] = $widget_type_machine_name; $instance['widget']['module'] = $widget_module; // Update field instance field_update_instance($instance); }
/** * @todo. */ public function dateForm($field_name, $field_type, $widget_type, $todate = TRUE) { // Tests that date field functions properly. $edit = array(); $edit['title'] = $this->randomName(8); if ($widget_type == 'date_select') { $edit[$field_name . '[und][0][value][year]'] = '2010'; $edit[$field_name . '[und][0][value][month]'] = '10'; $edit[$field_name . '[und][0][value][day]'] = '7'; $edit[$field_name . '[und][0][value][hour]'] = '10'; $edit[$field_name . '[und][0][value][minute]'] = '30'; if ($todate) { $edit[$field_name . '[und][0][show_todate]'] = '1'; $edit[$field_name . '[und][0][value2][year]'] = '2010'; $edit[$field_name . '[und][0][value2][month]'] = '10'; $edit[$field_name . '[und][0][value2][day]'] = '7'; $edit[$field_name . '[und][0][value2][hour]'] = '11'; $edit[$field_name . '[und][0][value2][minute]'] = '30'; } } elseif ($widget_type == 'date_popup') { $edit[$field_name . '[und][0][value][date]'] = '10/07/2010'; $edit[$field_name . '[und][0][value][time]'] = '10:30'; if ($todate) { $edit[$field_name . '[und][0][show_todate]'] = '1'; $edit[$field_name . '[und][0][value2][date]'] = '10/07/2010'; $edit[$field_name . '[und][0][value2][time]'] = '11:30'; } } // Test that the date is displayed correctly using both the 'short' and // 'long' date types. // // For the short type, save an explicit format and assert that is the one // which is displayed. variable_set('date_format_short', 'l, m/d/Y - H:i:s'); $instance = field_info_instance('node', $field_name, 'story'); $instance['display']['default']['settings']['format_type'] = 'short'; field_update_instance($instance); $this->drupalPost('node/add/story', $edit, t('Save')); $this->assertText($edit['title'], "Node has been created"); $should_be = $todate ? 'Thursday, 10/07/2010 - 10:30 to 11:30' : 'Thursday, 10/07/2010 - 10:30'; $this->assertText($should_be, "Found the correct date for a {$field_type} field using the {$widget_type} widget displayed using the short date format."); // For the long format, do not save anything, and assert that the displayed // date uses the expected default value of this format provided by Drupal // core ('l, F j, Y - H:i'). $instance = field_info_instance('node', $field_name, 'story'); $instance['display']['default']['settings']['format_type'] = 'long'; field_update_instance($instance); $this->drupalPost('node/add/story', $edit, t('Save')); $this->assertText($edit['title'], "Node has been created"); $should_be = $todate ? 'Thursday, October 7, 2010 - 10:30 to 11:30' : 'Thursday, October 7, 2010 - 10:30'; $this->assertText($should_be, "Found the correct date for a {$field_type} field using the {$widget_type} widget displayed using the long date format."); }
public function synchronize(NodeInterface $node, Context $context, $dirtyAllowed = false) { /* @var $node ViewNode */ $entityType = $node->getEntityType(); $bundle = $node->getBundle(); $name = $node->getName(); // First populate the variable that will be used during the // hook_entity_info_alter() call to populate the view modes $viewModes = variable_get(USYNC_VAR_VIEW_MODE, []); $viewModes[$entityType][$name] = $name; variable_set(USYNC_VAR_VIEW_MODE, $viewModes); // First grab a list of everything that can be displayed in view // modes with both extra fields and real fields $instances = field_info_instances($entityType, $bundle); $bundleSettings = field_bundle_settings($entityType, $bundle); $extra = $this->getExtraFieldsDisplay($entityType, $bundle); $weight = 0; $displayExtra = []; $displayField = []; // Then deal with fields and such foreach ($node->getValue() as $propertyName => $formatter) { if (isset($instances[$propertyName])) { $display = array(); // We are working with a field if (!is_array($formatter)) { if (true === $formatter || 'default' === $formatter) { $formatter = array(); } else { if (false === $formatter || null === $formatter || 'delete' === $formatter) { continue; } else { if (!is_string($formatter)) { $context->logWarning(sprintf("%s: %s invalid value for formatter", $node->getPath(), $propertyName)); $formatter = array(); } else { $display['type'] = $formatter; } } } } else { $display = $formatter; } // Merge default and save $displayField[$propertyName] = drupal_array_merge_deep($this->getFieldDefault($node, $entityType, $bundle, $propertyName, $context), $display, array('weight' => $weight++)); } else { if (isset($extra[$propertyName])) { // We are working with and extra field if (!is_array($formatter)) { if (true === $formatter || 'default' === $formatter) { $formatter = array(); } else { if (false === $formatter || null === $formatter || 'delete' === $formatter) { continue; } else { $context->logWarning(sprintf("%s: %s extra fields can only be delete or default", $node->getPath(), $propertyName)); } } } // Merge default and save $displayExtra[$propertyName] = ['visible' => true, 'weight' => $weight++]; } else { $context->logError(sprintf("%s: %s property is nor a field nor an extra field", $node->getPath(), $propertyName)); } } } // Iterate over the fields and update each instance: we don't // need to do it with the $displayExtra property since it is // already the correctly formatted variable foreach ($displayField as $fieldName => $display) { $instances[$fieldName]['display'][$name] = $display; } // Remove non configured fields and extra fields from display foreach ($instances as $fieldName => $instance) { if (!isset($displayField[$fieldName])) { $instance['display'][$name] = array('type' => 'hidden'); } if ($dirtyAllowed) { $data = $instance; unset($data['id'], $data['field_id'], $data['field_name'], $data['entity_type'], $data['bundle'], $data['deleted']); db_update('field_config_instance')->condition('id', $instance['id'])->fields(['data' => serialize($data)])->execute(); } else { field_update_instance($instance); } } foreach (array_keys($extra) as $propertyName) { if (isset($displayExtra[$propertyName])) { $bundleSettings['extra_fields']['display'][$propertyName][$name] = $displayExtra[$propertyName]; } else { $bundleSettings['extra_fields']['display'][$propertyName][$name] = ['visible' => false, 'weight' => $weight++]; } } $bundleSettings['view_modes'][$name] = ['label' => $name, 'custom_settings' => true]; if ($dirtyAllowed) { // Hopefully nothing about display is really cached into the // internal field cache class, except the raw display array // into each instance, but nothing will use that except this // specific view mode implementation, we are going to delay // a few cache clear calls at the very end of the processing. // From field_bundle_settings(). variable_set('field_bundle_settings_' . $entityType . '__' . $bundle, $bundleSettings); } else { field_bundle_settings($entityType, $bundle, $bundleSettings); } if ($dirtyAllowed) { // From field_update_instance() cache_clear_all('*', 'cache_field', true); // From field_info_cache_clear() drupal_static_reset('field_view_mode_settings'); // We need to clear cache in order for later view modes to // load the right instance and prevent them for overriding // what we actually did here entity_info_cache_clear(); _field_info_field_cache()->flush(); } }
/** * Save field instance to database. * * @see \field_update_instance(). * @see \field_create_instance(). */ public function save() { if (isset($this->id)) { \field_update_instance($this->export()); } else { foreach (\field_create_instance($this->export()) as $k => $v) { $this->{$k} = $v; } } return $this; }
/** * Tests the 'link_separate' formatter. * * This test is mostly the same as testLinkFormatter(), but they cannot be * merged, since they involve different configuration and output. */ function testLinkSeparateFormatter() { // Create a field with settings to validate. $this->field = array( 'field_name' => drupal_strtolower($this->randomName()), 'type' => 'link', 'cardinality' => 2, ); field_create_field($this->field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', 'settings' => array( 'title' => DRUPAL_OPTIONAL, ), 'widget' => array( 'type' => 'link_default', ), 'display' => array( 'full' => array( 'type' => 'link_separate', 'label' => 'hidden', ), ), ); field_create_instance($this->instance); $langcode = LANGUAGE_NOT_SPECIFIED; // Create an entity with two link field values: // - The first field item uses a URL only. // - The second field item uses a URL and title. // For consistency in assertion code below, the URL is assigned to the title // variable for the first field. $this->drupalGet('test-entity/add/test_bundle'); $url1 = 'http://www.example.com/content/articles/archive?author=John&year=2012#com'; $url2 = 'http://www.example.org/content/articles/archive?author=John&year=2012#org'; // Intentionally contains an ampersand that needs sanitization on output. $title2 = 'A very long & strange example title that could break the nice layout of the site'; $edit = array( "{$this->field['field_name']}[$langcode][0][url]" => $url1, "{$this->field['field_name']}[$langcode][1][url]" => $url2, "{$this->field['field_name']}[$langcode][1][title]" => $title2, ); $this->drupalPost(NULL, $edit, t('Save')); preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match); $id = $match[1]; $this->assertRaw(t('test_entity @id has been created.', array('@id' => $id))); // Verify that the link is output according to the formatter settings. $options = array( 'trim_length' => array(NULL, 6), 'rel' => array(NULL, 'nofollow'), 'target' => array(NULL, '_blank'), ); foreach ($options as $setting => $values) { foreach ($values as $new_value) { // Update the field formatter settings. $this->instance['display']['full']['settings'] = array($setting => $new_value); field_update_instance($this->instance); $this->renderTestEntity($id); switch ($setting) { case 'trim_length': $url = $url1; $url_title = isset($new_value) ? truncate_utf8($url, $new_value, FALSE, TRUE) : $url; $expected = '<div class="link-item">'; $expected .= '<div class="link-url"><a href="' . check_plain($url) . '">' . check_plain($url_title) . '</a></div>'; $expected .= '</div>'; $this->assertRaw($expected); $url = $url2; $url_title = isset($new_value) ? truncate_utf8($url, $new_value, FALSE, TRUE) : $url; $title = isset($new_value) ? truncate_utf8($title2, $new_value, FALSE, TRUE) : $title2; $expected = '<div class="link-item">'; $expected .= '<div class="link-title">' . check_plain($title) . '</div>'; $expected .= '<div class="link-url"><a href="' . check_plain($url) . '">' . check_plain($url_title) . '</a></div>'; $expected .= '</div>'; $this->assertRaw($expected); break; case 'rel': $rel = isset($new_value) ? ' rel="' . $new_value . '"' : ''; $this->assertRaw('<div class="link-url"><a href="' . check_plain($url1) . '"' . $rel . '>' . check_plain($url1) . '</a></div>'); $this->assertRaw('<div class="link-url"><a href="' . check_plain($url2) . '"' . $rel . '>' . check_plain($url2) . '</a></div>'); break; case 'target': $target = isset($new_value) ? ' target="' . $new_value . '"' : ''; $this->assertRaw('<div class="link-url"><a href="' . check_plain($url1) . '"' . $target . '>' . check_plain($url1) . '</a></div>'); $this->assertRaw('<div class="link-url"><a href="' . check_plain($url2) . '"' . $target . '>' . check_plain($url2) . '</a></div>'); break; } } } }
/** * Implements Drupal\configuration\Config\Configuration::saveToActiveStore(). */ public function saveToActiveStore(ConfigIteratorSettings &$settings) { field_info_cache_clear(); // Load all the existing fields and instance up-front so that we don't // have to rebuild the cache all the time. $existing_fields = field_info_fields(); $existing_instances = field_info_instances(); $field = $this->getData(); // Create or update field. $field_config = $field['field_config']; if (isset($existing_fields[$field_config['field_name']])) { $existing_field = $existing_fields[$field_config['field_name']]; if ($field_config + $existing_field != $existing_field) { field_update_field($field_config); } } else { field_create_field($field_config); $existing_fields[$field_config['field_name']] = $field_config; } // Create or update field instance. $field_instance = $field['field_instance']; if (isset($existing_instances[$field_instance['entity_type']][$field_instance['bundle']][$field_instance['field_name']])) { $existing_instance = $existing_instances[$field_instance['entity_type']][$field_instance['bundle']][$field_instance['field_name']]; if ($field_instance + $existing_instance != $existing_instance) { field_update_instance($field_instance); } } else { field_create_instance($field_instance); $existing_instances[$field_instance['entity_type']][$field_instance['bundle']][$field_instance['field_name']] = $field_instance; } variable_set('menu_rebuild_needed', TRUE); $settings->addInfo('imported', $this->getUniqueId()); }
/** * Set the display of field_event_registration to be Registration Link. */ public static function EventRegistrationLink() { $instance = field_info_instance('node', 'field_event_registration', 'event'); $instance['display']['default']['type'] = 'registration_link'; $instance['display']['default']['settings']['label'] = 'Sign up for this event'; field_update_instance($instance); }
public function synchronize(NodeInterface $node, Context $context, $dirtyAllowed = false) { /* @var $node FieldInstanceNode */ $entityType = $node->getEntityType(); $bundle = $node->getBundle(); $fieldName = $node->getFieldName(); $existing = field_info_instance($entityType, $fieldName, $bundle); $field = field_info_field($fieldName); $default = array('entity_type' => $entityType, 'bundle' => $bundle, 'field_name' => $fieldName); $object = $node->getValue(); if (!is_array($object)) { $object = array(); } if (empty($object['label'])) { // Field data 'label' key is not part of the Drupal signature // but this module will inject it anyway and should be persisted // along the field 'data' key in database if (empty($field['label'])) { if ($label = $this->findFieldLabel($fieldName)) { $default['label'] = $label; } } else { $default['label'] = $field['label']; } } // This is a forced default from this module: never display new // fields without being explicitely told to $instance = $default + $object + array('display' => array('default' => array('type' => 'hidden'))); // Dynamically determine weight using position relative to parent node // @todo Find a quicker way if ($node->hasParent()) { $instance['weight'] = $node->getParent()->getChildPosition($node); } // Propagate defaults set at the field level if (!empty($field['instance'])) { foreach ($field['instance'] as $key => $value) { if (!isset($instance[$key])) { $instance[$key] = $value; } } } // Even thought this is not mandatory few modules such as the 'image' // module will attempt to access this attribute, without carying about // the field_update_instance() method documentation if (!isset($instance['settings'])) { $instance['settings'] = array(); } // Deal with widget if (!isset($instance['widget'])) { if (isset($field['widget'])) { $instance['widget'] = $field['widget']; } } if ($existing) { $this->alter(self::HOOK_UPDATE, $node, $instance); field_update_instance($instance); } else { $this->alter(self::HOOK_INSERT, $node, $instance); field_create_instance($instance); } }