From 7d09a94c7ed6c43bdad48cf38256dcc9697cf844 Mon Sep 17 00:00:00 2001 From: Florent Torregrosa Date: Sat, 27 May 2017 14:40:57 +0200 Subject: [PATCH 1/5] Update entityreference to 7.x-1.4 --- .../entityreference/entityreference.info | 6 +- .../entityreference/entityreference.install | 25 ++ .../entityreference/entityreference.module | 247 +++++++++++++++--- .../entityreference_behavior_example.info | 6 +- ...yReferenceBehavior_TaxonomyIndex.class.php | 12 +- ...ference_SelectionHandler_Generic.class.php | 6 +- ...Reference_SelectionHandler_Views.class.php | 74 +++++- .../plugins/selection/abstract.inc | 5 +- .../tests/entityreference.admin.test | 2 +- .../tests/entityreference.handlers.test | 15 ++ .../tests/entityreference.taxonomy.test | 48 ++++ .../entityreference_feeds_test.info | 6 +- .../views/entityreference_plugin_display.inc | 5 +- .../views/entityreference_plugin_style.inc | 2 +- 14 files changed, 394 insertions(+), 65 deletions(-) diff --git a/www7/sites/all/modules/contrib/entityreference/entityreference.info b/www7/sites/all/modules/contrib/entityreference/entityreference.info index cb0301bdc..2695e4650 100644 --- a/www7/sites/all/modules/contrib/entityreference/entityreference.info +++ b/www7/sites/all/modules/contrib/entityreference/entityreference.info @@ -29,9 +29,9 @@ files[] = tests/entityreference.admin.test files[] = tests/entityreference.feeds.test files[] = tests/entityreference.entity_translation.test -; Information added by Drupal.org packaging script on 2016-09-19 -version = "7.x-1.2" +; Information added by Drupal.org packaging script on 2017-05-23 +version = "7.x-1.4" core = "7.x" project = "entityreference" -datestamp = "1474306740" +datestamp = "1495557187" diff --git a/www7/sites/all/modules/contrib/entityreference/entityreference.install b/www7/sites/all/modules/contrib/entityreference/entityreference.install index cc7bce591..ce6101852 100644 --- a/www7/sites/all/modules/contrib/entityreference/entityreference.install +++ b/www7/sites/all/modules/contrib/entityreference/entityreference.install @@ -163,3 +163,28 @@ function entityreference_update_7002() { )); } } + +/** + * Implements hook_update_N(). + * + * Remove duplicate rows in the taxonomy_index table. + */ +function entityreference_update_7100() { + if (db_table_exists('taxonomy_index')) { + if (db_table_exists('taxonomy_index_tmp')) { + db_drop_table('taxonomy_index_tmp'); + } + + $tx_schema = drupal_get_schema('taxonomy_index'); + db_create_table('taxonomy_index_tmp', $tx_schema); + $select = db_select('taxonomy_index', 'tx'); + $select->fields('tx', array('nid', 'tid')); + $select->groupBy('tx.nid'); + $select->groupBy('tx.tid'); + $select->addExpression('MAX(sticky)', 'sticky'); + $select->addExpression('MAX(created)', 'created'); + db_insert('taxonomy_index_tmp')->from($select)->execute(); + db_drop_table('taxonomy_index'); + db_rename_table('taxonomy_index_tmp', 'taxonomy_index'); + } +} diff --git a/www7/sites/all/modules/contrib/entityreference/entityreference.module b/www7/sites/all/modules/contrib/entityreference/entityreference.module index 14d932a5f..42af2a302 100644 --- a/www7/sites/all/modules/contrib/entityreference/entityreference.module +++ b/www7/sites/all/modules/contrib/entityreference/entityreference.module @@ -1,5 +1,10 @@ array( + 'variables' => array('label' => NULL, 'item' => NULL, 'settings' => NULL, 'uri' => NULL), + ), + 'entityreference_entity_id' => array( + 'variables' => array('item' => NULL, 'settings' => NULL), + ), + ); +} + /** * Implements hook_menu(). */ @@ -163,7 +182,7 @@ function entityreference_get_behavior_handlers($field, $instance = NULL) { /** * Get the behavior handler for a given entityreference field and instance. * - * @param $handler + * @param $behavior * The behavior handler name. */ function _entityreference_get_behavior_handler($behavior) { @@ -400,6 +419,9 @@ function entityreference_field_settings_form($field, $instance, $has_data) { return $form; } +/** + * Callback for custom element processing. + */ function _entityreference_field_settings_process($form, $form_state) { $field = isset($form_state['entityreference']['field']) ? $form_state['entityreference']['field'] : $form['#field']; $instance = isset($form_state['entityreference']['instance']) ? $form_state['entityreference']['instance'] : $form['#instance']; @@ -481,11 +503,17 @@ function _entityreference_field_settings_process($form, $form_state) { return $form; } +/** + * Custom callback for ajax processing. + */ function _entityreference_field_settings_ajax_process($form, $form_state) { _entityreference_field_settings_ajax_process_element($form, $form); return $form; } +/** + * Helper function for custom ajax processing. + */ function _entityreference_field_settings_ajax_process_element(&$element, $main_form) { if (isset($element['#ajax']) && $element['#ajax'] === TRUE) { $element['#ajax'] = array( @@ -500,6 +528,9 @@ function _entityreference_field_settings_ajax_process_element(&$element, $main_f } } +/** + * Custom callback for element processing. + */ function _entityreference_form_process_merge_parent($element) { $parents = $element['#parents']; array_pop($parents); @@ -507,11 +538,17 @@ function _entityreference_form_process_merge_parent($element) { return $element; } +/** + * Helper function to remove blank elements. + */ function _entityreference_element_validate_filter(&$element, &$form_state) { $element['#value'] = array_filter($element['#value']); form_set_value($element, $element['#value'], $form_state); } +/** + * Implements hook_validate(). + */ function _entityreference_field_settings_validate($form, &$form_state) { // Store the new values in the form state. $field = $form['#field']; @@ -547,6 +584,9 @@ function entityreference_field_instance_settings_form($field, $instance) { return $form; } +/** + * Implements hook_field_settings_form(). + */ function _entityreference_field_instance_settings_form($form, $form_state) { $field = isset($form_state['entityreference']['field']) ? $form_state['entityreference']['field'] : $form['#field']; $instance = isset($form_state['entityreference']['instance']) ? $form_state['entityreference']['instance'] : $form['#instance']; @@ -564,6 +604,9 @@ function _entityreference_field_instance_settings_form($form, $form_state) { return $form; } +/** + * Implements hook_validate(). + */ function _entityreference_field_instance_settings_validate($form, &$form_state) { // Store the new values in the form state. $instance = $form['#instance']; @@ -795,7 +838,7 @@ function entityreference_query_entityreference_alter(QueryAlterableInterface $qu function entityreference_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { // Ensure that the entity target type exists before displaying the widget. $entity_info = entity_get_info($field['settings']['target_type']); - if (empty($entity_info)){ + if (empty($entity_info)) { return; } $entity_type = $instance['entity_type']; @@ -820,7 +863,9 @@ function entityreference_field_widget_form(&$form, &$form_state, $field, $instan // Build an array of entities ID. foreach ($items as $item) { - $entity_ids[] = $item['target_id']; + if (isset($item['target_id'])) { + $entity_ids[] = $item['target_id']; + } } // Load those entities and loop through them to extract their labels. @@ -881,6 +926,9 @@ function entityreference_field_widget_form(&$form, &$form_state, $field, $instan } } +/** + * Implements hook_validate(). + */ function _entityreference_autocomplete_validate($element, &$form_state, $form) { // If a value was entered into the autocomplete... $value = ''; @@ -905,6 +953,9 @@ function _entityreference_autocomplete_validate($element, &$form_state, $form) { form_set_value($element, $value, $form_state); } +/** + * Implements hook_validate(). + */ function _entityreference_autocomplete_tags_validate($element, &$form_state, $form) { $value = array(); // If a value was entered into the autocomplete... @@ -951,7 +1002,8 @@ function entityreference_field_widget_error($element, $error) { * The entity type. * @param $bundle_name * The bundle name. - * @return + * + * @return bool * True if user can access this menu item. */ function entityreference_autocomplete_access_callback($type, $field_name, $entity_type, $bundle_name) { @@ -983,10 +1035,11 @@ function entityreference_autocomplete_access_callback($type, $field_name, $entit */ function entityreference_autocomplete_callback($type, $field_name, $entity_type, $bundle_name, $entity_id = '', $string = '') { // If the request has a '/' in the search text, then the menu system will have - // split it into multiple arguments and $string will only be a partial. We want - // to make sure we recover the intended $string. + // split it into multiple arguments and $string will only be a partial. + // We want to make sure we recover the intended $string. $args = func_get_args(); - // Shift off the $type, $field_name, $entity_type, $bundle_name, and $entity_id args. + // Shift off the $type, $field_name, $entity_type, + // $bundle_name, and $entity_id args. array_shift($args); array_shift($args); array_shift($args); @@ -1022,6 +1075,7 @@ function entityreference_autocomplete_callback($type, $field_name, $entity_type, */ function entityreference_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id = '', $string = '') { $matches = array(); + $prefix = ''; $entity = NULL; if ($entity_id !== 'NULL') { @@ -1036,7 +1090,8 @@ function entityreference_autocomplete_callback_get_matches($type, $field, $insta $handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity); if ($type == 'tags') { - // The user enters a comma-separated list of tags. We only autocomplete the last tag. + // The user enters a comma-separated list of tags. + // We only autocomplete the last tag. $tags_typed = drupal_explode_tags($string); $tag_last = drupal_strtolower(array_pop($tags_typed)); if (!empty($tag_last)) { @@ -1045,7 +1100,6 @@ function entityreference_autocomplete_callback_get_matches($type, $field, $insta } else { // The user enters a single tag. - $prefix = ''; $tag_last = $string; } @@ -1057,7 +1111,7 @@ function entityreference_autocomplete_callback_get_matches($type, $field, $insta foreach ($entity_labels as $values) { foreach ($values as $entity_id => $label) { $key = "$label ($entity_id)"; - // Strip things like starting/trailing white spaces, line breaks and tags. + // Strip starting/trailing white spaces, line breaks and tags. $key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(decode_entities(strip_tags($key))))); // Names containing commas or quotes must be wrapped in quotes. if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) { @@ -1071,6 +1125,32 @@ function entityreference_autocomplete_callback_get_matches($type, $field, $insta drupal_json_output($matches); } + /** + * Introspects field and instance settings, and determines the correct settings + * for the functioning of the formatter. + * + * Settings: + * - entity_type - The entity_type being loaded. + * - column - The name of the ref. field column that stores the entity id. + */ +function entityreference_field_type_settings($field) { + $settings = array( + 'entity_type' => NULL, + 'column' => NULL, + ); + + if ($field['type'] == 'entityreference') { + $settings['entity_type'] = $field['settings']['target_type']; + $settings['column'] = 'target_id'; + } + elseif ($field['type'] == 'taxonomy_term_reference') { + $settings['entity_type'] = 'taxonomy_term'; + $settings['column'] = 'tid'; + } + + return $settings; +} + /** * Implements hook_field_formatter_info(). */ @@ -1082,6 +1162,7 @@ function entityreference_field_formatter_info() { 'field types' => array('entityreference'), 'settings' => array( 'link' => FALSE, + 'bypass_access' => FALSE, ), ), 'entityreference_entity_id' => array( @@ -1092,7 +1173,7 @@ function entityreference_field_formatter_info() { 'entityreference_entity_view' => array( 'label' => t('Rendered entity'), 'description' => t('Display the referenced entities rendered by entity_view().'), - 'field types' => array('entityreference'), + 'field types' => array('entityreference', 'taxonomy_term_reference'), 'settings' => array( 'view_mode' => 'default', 'links' => TRUE, @@ -1108,9 +1189,17 @@ function entityreference_field_formatter_info() { function entityreference_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) { $display = $instance['display'][$view_mode]; $settings = $display['settings']; + $field_type_settings = entityreference_field_type_settings($field); $element = array(); if ($display['type'] == 'entityreference_label') { + $element['bypass_access'] = array( + '#title' => t('Show entity labels regardless of user access'), + '#description' => t("All entities in the field will be shown, without checking them for access. If the 'Link' setting is also enabled, an entity which the user does not have access to view will show without a link."), + '#type' => 'checkbox', + '#default_value' => $settings['bypass_access'], + ); + $element['link'] = array( '#title' => t('Link label to the referenced entity'), '#type' => 'checkbox', @@ -1119,7 +1208,7 @@ function entityreference_field_formatter_settings_form($field, $instance, $view_ } if ($display['type'] == 'entityreference_entity_view') { - $entity_info = entity_get_info($field['settings']['target_type']); + $entity_info = entity_get_info($field_type_settings['entity_type']); $options = array('default' => t('Default')); if (!empty($entity_info['view modes'])) { foreach ($entity_info['view modes'] as $view_mode => $view_mode_settings) { @@ -1157,15 +1246,17 @@ function entityreference_field_formatter_settings_form($field, $instance, $view_ function entityreference_field_formatter_settings_summary($field, $instance, $view_mode) { $display = $instance['display'][$view_mode]; $settings = $display['settings']; + $field_type_settings = entityreference_field_type_settings($field); $summary = array(); if ($display['type'] == 'entityreference_label') { $summary[] = $settings['link'] ? t('Link to the referenced entity') : t('No link'); + $summary[] = $settings['bypass_access'] ? t('Show labels regardless of access') : t('Respect entity access for label visibility'); } if ($display['type'] == 'entityreference_entity_view') { - $entity_info = entity_get_info($field['settings']['target_type']); + $entity_info = entity_get_info($field_type_settings['entity_type']); $view_mode_label = $settings['view_mode'] == 'default' ? t('Default') : $settings['view_mode']; if (isset($entity_info['view modes'][$settings['view_mode']]['label'])) { $view_mode_label = $entity_info['view modes'][$settings['view_mode']]['label']; @@ -1182,19 +1273,22 @@ function entityreference_field_formatter_settings_summary($field, $instance, $vi * Implements hook_field_formatter_prepare_view(). */ function entityreference_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) { + $field_type_settings = entityreference_field_type_settings($field); + $target_type = $field_type_settings['entity_type']; + $column = $field_type_settings['column']; $target_ids = array(); // Collect every possible entity attached to any of the entities. foreach ($entities as $id => $entity) { foreach ($items[$id] as $delta => $item) { - if (isset($item['target_id'])) { - $target_ids[] = $item['target_id']; + if (isset($item[$column])) { + $target_ids[] = $item[$column]; } } } if ($target_ids) { - $target_entities = entity_load($field['settings']['target_type'], $target_ids); + $target_entities = entity_load($target_type, $target_ids); } else { $target_entities = array(); @@ -1206,12 +1300,12 @@ function entityreference_field_formatter_prepare_view($entity_type, $entities, $ foreach ($items[$id] as $delta => $item) { // Check whether the referenced entity could be loaded. - if (isset($item['target_id']) && isset($target_entities[$item['target_id']])) { + if (isset($target_entities[$item[$column]]) && isset($target_entities[$item[$column]])) { // Replace the instance value with the term data. - $items[$id][$delta]['entity'] = $target_entities[$item['target_id']]; + $items[$id][$delta]['entity'] = $target_entities[$item[$column]]; // Check whether the user has access to the referenced entity. - $has_view_access = (entity_access('view', $field['settings']['target_type'], $target_entities[$item['target_id']]) !== FALSE); - $has_update_access = (entity_access('update', $field['settings']['target_type'], $target_entities[$item['target_id']]) !== FALSE); + $has_view_access = (entity_access('view', $target_type, $target_entities[$item[$column]]) !== FALSE); + $has_update_access = (entity_access('update', $target_type, $target_entities[$item[$column]]) !== FALSE); $items[$id][$delta]['access'] = ($has_view_access || $has_update_access); } // Otherwise, unset the instance value, since the entity does not exist. @@ -1234,34 +1328,63 @@ function entityreference_field_formatter_prepare_view($entity_type, $entities, $ function entityreference_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $result = array(); $settings = $display['settings']; - - // Rebuild the items list to contain only those with access. - foreach ($items as $key => $item) { - if (empty($item['access'])) { - unset($items[$key]); - } - } + $field_type_settings = entityreference_field_type_settings($field); + $target_type = $field_type_settings['entity_type']; + $column = $field_type_settings['column']; switch ($display['type']) { case 'entityreference_label': $handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity); foreach ($items as $delta => $item) { - $label = $handler->getLabel($item['entity']); - // If the link is to be displayed and the entity has a uri, display a link. - // Note the assignment ($url = ) here is intended to be an assignment. - if ($display['settings']['link'] && ($uri = entity_uri($field['settings']['target_type'], $item['entity']))) { - $result[$delta] = array('#markup' => l($label, $uri['path'], $uri['options'])); + // Skip an item that is not accessible, unless we're allowing output of + // entity labels without considering access. + if (empty($item['access']) && !$display['settings']['bypass_access']) { + continue; } - else { - $result[$delta] = array('#markup' => check_plain($label)); + + // Calling EntityReferenceHandler::getLabel() would make a repeated, + // wasteful call to entity_access(). + $label = entity_label($field['settings']['target_type'], $item['entity']); + + // Check if the settings and access allow a link to be displayed. + $display_link = $display['settings']['link'] && $item['access']; + + $uri = NULL; + + // If the link is allowed and the entity has a uri, display a link. + if ($display_link) { + $uri = entity_uri($target_type, $item['entity']); } + + $result[$delta] = array( + '#theme' => 'entityreference_label', + '#label' => $label, + '#item' => $item, + '#uri' => $uri, + '#settings' => array( + 'display' => $display['settings'], + 'field' => $field['settings'], + ), + ); } break; case 'entityreference_entity_id': foreach ($items as $delta => $item) { - $result[$delta] = array('#markup' => check_plain($item['target_id'])); + // Skip an item that is not accessible. + if (empty($item['access'])) { + continue; + } + + $result[$delta] = array( + '#theme' => 'entityreference_entity_id', + '#item' => $item, + '#settings' => array( + 'display' => $display['settings'], + 'field' => $field['settings'], + ), + ); } break; @@ -1272,19 +1395,24 @@ function entityreference_field_formatter_view($entity_type, $entity, $field, $in } foreach ($items as $delta => $item) { + // Skip an item that is not accessible. + if (empty($item['access'])) { + continue; + } + // Protect ourselves from recursive rendering. static $depth = 0; $depth++; if ($depth > 20) { - throw new EntityReferenceRecursiveRenderingException(t('Recursive rendering detected when rendering entity @entity_type(@entity_id). Aborting rendering.', array('@entity_type' => $entity_type, '@entity_id' => $item['target_id']))); + throw new EntityReferenceRecursiveRenderingException(t('Recursive rendering detected when rendering entity @entity_type(@entity_id). Aborting rendering.', array('@entity_type' => $target_type, '@entity_id' => $item[$column]))); } $target_entity = clone $item['entity']; unset($target_entity->content); - $result[$delta] = entity_view($field['settings']['target_type'], array($item['target_id'] => $target_entity), $settings['view_mode'], $target_langcode, FALSE); + $result[$delta] = entity_view($target_type, array($item[$column] => $target_entity), $settings['view_mode'], $target_langcode, FALSE); - if (empty($settings['links']) && isset($result[$delta][$field['settings']['target_type']][$item['target_id']]['links'])) { - $result[$delta][$field['settings']['target_type']][$item['target_id']]['links']['#access'] = FALSE; + if (empty($settings['links']) && isset($result[$delta][$target_type][$column]['links'])) { + $result[$delta][$target_type][$item[$column]]['links']['#access'] = FALSE; } $depth = 0; } @@ -1308,3 +1436,44 @@ function entityreference_views_api() { 'path' => drupal_get_path('module', 'entityreference') . '/views', ); } + +/** + * Theme label. + * + * @ingroup themeable. + */ +function theme_entityreference_label($vars) { + $label = $vars['label']; + $settings = $vars['settings']; + $item = $vars['item']; + $uri = $vars['uri']; + + $output = ''; + + // If the link is to be displayed and the entity has a uri, display a link. + // Note the assignment ($url = ) here is intended to be an assignment. + if ($settings['display']['link'] && isset($uri['path'])) { + $output .= l($label, $uri['path'], $uri['options']); + } + else { + $output .= check_plain($label); + } + + return $output; +} + +/** + * Theme entity_id + * + * @ingroup themeable. + */ +function theme_entityreference_entity_id($vars) { + $settings = $vars['settings']; + $item = $vars['item']; + + $output = ''; + + $output = check_plain($item['target_id']); + + return $output; +} diff --git a/www7/sites/all/modules/contrib/entityreference/examples/entityreference_behavior_example/entityreference_behavior_example.info b/www7/sites/all/modules/contrib/entityreference/examples/entityreference_behavior_example/entityreference_behavior_example.info index 33fe2036e..6f21bac57 100644 --- a/www7/sites/all/modules/contrib/entityreference/examples/entityreference_behavior_example/entityreference_behavior_example.info +++ b/www7/sites/all/modules/contrib/entityreference/examples/entityreference_behavior_example/entityreference_behavior_example.info @@ -4,9 +4,9 @@ core = 7.x package = Fields dependencies[] = entityreference -; Information added by Drupal.org packaging script on 2016-09-19 -version = "7.x-1.2" +; Information added by Drupal.org packaging script on 2017-05-23 +version = "7.x-1.4" core = "7.x" project = "entityreference" -datestamp = "1474306740" +datestamp = "1495557187" diff --git a/www7/sites/all/modules/contrib/entityreference/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php b/www7/sites/all/modules/contrib/entityreference/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php index 43ac693f2..075b54d79 100644 --- a/www7/sites/all/modules/contrib/entityreference/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php +++ b/www7/sites/all/modules/contrib/entityreference/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php @@ -144,18 +144,20 @@ protected function buildNodeIndex($node) { // already inserted in taxonomy_build_node_index(). $tid_all = array_diff($tid_all, $original_tid_all); - // Insert index entries for all the node's terms. + // Insert index entries for all the node's terms, preventing duplicates. if (!empty($tid_all)) { - $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created')); foreach ($tid_all as $tid) { - $query->values(array( + $row = array( 'nid' => $node->nid, 'tid' => $tid, 'sticky' => $sticky, 'created' => $node->created, - )); + ); + $query = db_merge('taxonomy_index') + ->key($row) + ->fields($row); + $query->execute(); } - $query->execute(); } } } diff --git a/www7/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php b/www7/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php index 902c55ced..e0dff00bb 100644 --- a/www7/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php +++ b/www7/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php @@ -208,7 +208,11 @@ public function validateReferencableEntities(array $ids) { * Implements EntityReferenceHandler::validateAutocompleteInput(). */ public function validateAutocompleteInput($input, &$element, &$form_state, $form) { - $entities = $this->getReferencableEntities($input, '=', 6); + $bundled_entities = $this->getReferencableEntities($input, '=', 6); + $entities = array(); + foreach($bundled_entities as $entities_list) { + $entities += $entities_list; + } if (empty($entities)) { // Error if there are no entities available for a required field. form_error($element, t('There are no entities matching "%value"', array('%value' => $input))); diff --git a/www7/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Views.class.php b/www7/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Views.class.php index 859e1e133..cbed33b17 100644 --- a/www7/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Views.class.php +++ b/www7/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Views.class.php @@ -9,12 +9,13 @@ class EntityReference_SelectionHandler_Views implements EntityReference_Selectio * Implements EntityReferenceHandler::getInstance(). */ public static function getInstance($field, $instance = NULL, $entity_type = NULL, $entity = NULL) { - return new EntityReference_SelectionHandler_Views($field, $instance); + return new EntityReference_SelectionHandler_Views($field, $instance, $entity); } - protected function __construct($field, $instance) { + protected function __construct($field, $instance, $entity) { $this->field = $field; $this->instance = $instance; + $this->entity = $entity; } /** @@ -52,13 +53,32 @@ public static function settingsForm($field, $instance) { ); $default = !empty($view_settings['args']) ? implode(', ', $view_settings['args']) : ''; + $description = t('Provide a comma separated list of arguments to pass to the view.') . '
' . t('This field supports tokens.'); + + if (!module_exists('token')) { + $description .= '
' . t('Install the token module to get more tokens and display available once.', array('@url' => 'http://drupal.org/project/token')); + } + $form['view']['args'] = array( '#type' => 'textfield', '#title' => t('View arguments'), '#default_value' => $default, '#required' => FALSE, - '#description' => t('Provide a comma separated list of arguments to pass to the view.'), + '#description' => $description, + '#maxlength' => '512', ); + if (module_exists('token')) { + // Get the token type for the entity type our field is in (a type 'taxonomy_term' has a 'term' type token). + $info = entity_get_info($instance['entity_type']); + + $form['view']['tokens'] = array( + '#theme' => 'token_tree', + '#token_types' => array($info['token type']), + '#global_types' => TRUE, + '#click_insert' => TRUE, + '#dialog' => TRUE, + ); + } } else { $form['view']['no_view_help'] = array( @@ -84,6 +104,7 @@ protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $ return FALSE; } $this->view->set_display($display_name); + $this->view->pre_execute(); // Make sure the query is not cached. $this->view->is_cacheable = FALSE; @@ -104,7 +125,7 @@ protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $ */ public function getReferencableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) { $display_name = $this->field['settings']['handler_settings']['view']['display_name']; - $args = $this->field['settings']['handler_settings']['view']['args']; + $args = $this->handleArgs($this->field['settings']['handler_settings']['view']['args']); $result = array(); if ($this->initializeView($match, $match_operator, $limit)) { // Get the results. @@ -133,7 +154,7 @@ function countReferencableEntities($match = NULL, $match_operator = 'CONTAINS') function validateReferencableEntities(array $ids) { $display_name = $this->field['settings']['handler_settings']['view']['display_name']; - $args = $this->field['settings']['handler_settings']['view']['args']; + $args = $this->handleArgs($this->field['settings']['handler_settings']['view']['args']); $result = array(); if ($this->initializeView(NULL, 'CONTAINS', 0, $ids)) { // Get the results. @@ -166,6 +187,49 @@ public function entityFieldQueryAlter(SelectQueryInterface $query) { } + /** + * Handles arguments for views. + * + * Replaces tokens using token_replace(). + * + * @param array $args + * Usually $this->field['settings']['handler_settings']['view']['args']. + * + * @return array + * The arguments to be send to the View. + */ + protected function handleArgs($args) { + if (!module_exists('token')) { + return $args; + } + + // Parameters for token_replace(). + $data = array(); + $options = array('clear' => TRUE); + + if ($entity = $this->entity) { + // D7 HACK: For new entities, entity and revision id are not set. This leads to + // * token replacement emitting PHP warnings + // * views choking on empty arguments + // We workaround this by filling in '0' for these IDs + // and use a clone to leave no traces of our unholy doings. + $info = entity_get_info($this->instance['entity_type']); + if (!isset($entity->{$info['entity keys']['id']})) { + $entity = clone $entity; + $entity->{$info['entity keys']['id']} = '0'; + if (!empty($info['entity keys']['revision'])) { + $entity->{$info['entity keys']['revision']} = '0'; + } + } + + $data[$info['token type']] = $entity; + } + // Replace tokens for each argument. + foreach ($args as $key => $arg) { + $args[$key] = token_replace($arg, $data, $options); + } + return $args; + } } function entityreference_view_settings_validate($element, &$form_state, $form) { diff --git a/www7/sites/all/modules/contrib/entityreference/plugins/selection/abstract.inc b/www7/sites/all/modules/contrib/entityreference/plugins/selection/abstract.inc index 1d2ea0d30..a4805b1f5 100644 --- a/www7/sites/all/modules/contrib/entityreference/plugins/selection/abstract.inc +++ b/www7/sites/all/modules/contrib/entityreference/plugins/selection/abstract.inc @@ -21,8 +21,9 @@ interface EntityReference_SelectionHandler { * Return a list of referencable entities. * * @return - * An array of referencable entities, which keys are entity ids and - * values (safe HTML) labels to be displayed to the user. + * A nested array of entities, the first level is keyed by the + * entity bundle, which contains an array of entity labels (safe HTML), + * keyed by the entity ID. */ public function getReferencableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0); diff --git a/www7/sites/all/modules/contrib/entityreference/tests/entityreference.admin.test b/www7/sites/all/modules/contrib/entityreference/tests/entityreference.admin.test index 6c886975e..ec78e7bca 100644 --- a/www7/sites/all/modules/contrib/entityreference/tests/entityreference.admin.test +++ b/www7/sites/all/modules/contrib/entityreference/tests/entityreference.admin.test @@ -68,7 +68,7 @@ class EntityReferenceAdminTestCase extends DrupalWebTestCase { 'fields[_add_new_field][type]' => 'entityreference', 'fields[_add_new_field][widget_type]' => 'entityreference_autocomplete', ), t('Save')); - return; + // Node should be selected by default. $this->assertFieldByName('field[settings][target_type]', 'node'); // The base handler should be selected by default. diff --git a/www7/sites/all/modules/contrib/entityreference/tests/entityreference.handlers.test b/www7/sites/all/modules/contrib/entityreference/tests/entityreference.handlers.test index b88e10693..22569324c 100644 --- a/www7/sites/all/modules/contrib/entityreference/tests/entityreference.handlers.test +++ b/www7/sites/all/modules/contrib/entityreference/tests/entityreference.handlers.test @@ -194,6 +194,21 @@ class EntityReferenceHandlersTestCase extends DrupalWebTestCase { ), ); $this->assertReferencable($field, $referencable_tests, 'Node handler (admin)'); + + // Verify autocomplete input validation. + $handler = entityreference_get_selection_handler($field); + $element = array( + '#parents' => array('element_name'), + ); + $form_state = array(); + $form = array(); + $value = $handler->validateAutocompleteInput($nodes['published1']->title, $element, $form_state, $form); + $this->assertEqual($value, $nodes['published1']->nid); + + $invalid_input = $this->randomName(); + $value = $handler->validateAutocompleteInput($invalid_input, $element, $form_state, $form); + $this->assertNull($value); + $this->assertEqual(form_get_error($element), t('There are no entities matching "%value"', array('%value' => $invalid_input))); } /** diff --git a/www7/sites/all/modules/contrib/entityreference/tests/entityreference.taxonomy.test b/www7/sites/all/modules/contrib/entityreference/tests/entityreference.taxonomy.test index 6e4afb780..94b3f5682 100644 --- a/www7/sites/all/modules/contrib/entityreference/tests/entityreference.taxonomy.test +++ b/www7/sites/all/modules/contrib/entityreference/tests/entityreference.taxonomy.test @@ -112,4 +112,52 @@ class EntityReferenceTaxonomyTestCase extends DrupalWebTestCase { $this->assertFalse(taxonomy_select_nodes(1)); } + /** + * Add a second ER field from node/article to taxonomy. + * + * This should not cause {taxonomy_index} to receive duplicate entries. + */ + protected function setupForIndexDuplicates() { + // Create an entity reference field. + $field = array( + 'entity_types' => array('node'), + 'settings' => array( + 'handler' => 'base', + 'target_type' => 'taxonomy_term', + 'handler_settings' => array( + 'target_bundles' => array(), + ), + ), + 'field_name' => 'field_entityreference_term2', + 'type' => 'entityreference', + ); + $field = field_create_field($field); + $instance = array( + 'field_name' => 'field_entityreference_term2', + 'bundle' => 'article', + 'entity_type' => 'node', + ); + + // Enable the taxonomy-index behavior. + $instance['settings']['behaviors']['taxonomy-index']['status'] = TRUE; + field_create_instance($instance); + } + + /** + * Make sure the index only contains one entry for a given node->term + * reference, even when multiple ER fields link from the node bundle to terms. + */ + public function testIndexDuplicates() { + // Extra setup for this test: add another ER field on this content type. + $this->setupForIndexDuplicates(); + + // Assert node insert with reference to term in first field. + $tid = 1; + $settings = array(); + $settings['type'] = 'article'; + $settings['field_entityreference_term'][LANGUAGE_NONE][0]['target_id'] = $tid; + $node = $this->drupalCreateNode($settings); + + $this->assertEqual(taxonomy_select_nodes($tid), array($node->nid)); + } } diff --git a/www7/sites/all/modules/contrib/entityreference/tests/modules/entityreference_feeds_test/entityreference_feeds_test.info b/www7/sites/all/modules/contrib/entityreference/tests/modules/entityreference_feeds_test/entityreference_feeds_test.info index 6a7a2ec60..dace68b70 100644 --- a/www7/sites/all/modules/contrib/entityreference/tests/modules/entityreference_feeds_test/entityreference_feeds_test.info +++ b/www7/sites/all/modules/contrib/entityreference/tests/modules/entityreference_feeds_test/entityreference_feeds_test.info @@ -8,9 +8,9 @@ dependencies[] = feeds dependencies[] = feeds_ui dependencies[] = entityreference -; Information added by Drupal.org packaging script on 2016-09-19 -version = "7.x-1.2" +; Information added by Drupal.org packaging script on 2017-05-23 +version = "7.x-1.4" core = "7.x" project = "entityreference" -datestamp = "1474306740" +datestamp = "1495557187" diff --git a/www7/sites/all/modules/contrib/entityreference/views/entityreference_plugin_display.inc b/www7/sites/all/modules/contrib/entityreference/views/entityreference_plugin_display.inc index f13e88a86..cca365090 100644 --- a/www7/sites/all/modules/contrib/entityreference/views/entityreference_plugin_display.inc +++ b/www7/sites/all/modules/contrib/entityreference/views/entityreference_plugin_display.inc @@ -81,8 +81,9 @@ class entityreference_plugin_display extends views_plugin_display { $field = $this->view->query->fields[$this->view->field[$field_alias]->field_alias]; } else { - $this->view->query->add_field($this->view->field[$field_alias]->options['table'], $this->view->field[$field_alias]->real_field, $this->view->field[$field_alias]->options['field'], array()); - $field = $this->view->query->fields[$this->view->field[$field_alias]->options['field']]; + $field_table = $this->view->query->ensure_table($this->view->field[$field_alias]->table, $this->view->field[$field_alias]->relationship); + $this->view->query->add_field($field_table, $this->view->field[$field_alias]->real_field, $this->view->field[$field_alias]->field, array()); + $field = $this->view->query->fields[$this->view->field[$field_alias]->field]; } // Add an OR condition for the field $conditions->condition($field['table'] . '.' . $field['field'], $value, 'LIKE'); diff --git a/www7/sites/all/modules/contrib/entityreference/views/entityreference_plugin_style.inc b/www7/sites/all/modules/contrib/entityreference/views/entityreference_plugin_style.inc index fadaa9ee2..b72a23578 100644 --- a/www7/sites/all/modules/contrib/entityreference/views/entityreference_plugin_style.inc +++ b/www7/sites/all/modules/contrib/entityreference/views/entityreference_plugin_style.inc @@ -26,7 +26,7 @@ class entityreference_plugin_style extends views_plugin_style { '#title' => t('Search fields'), '#options' => $options, '#required' => TRUE, - '#default_value' => $this->options['search_fields'], + '#default_value' => isset($this->options['search_fields']) ? $this->options['search_fields'] : array(), '#description' => t('Select the field(s) that will be searched when using the autocomplete widget.'), '#weight' => -3, ); From 927e2c414ca8a527ab471615f2d0c16a299b9c7c Mon Sep 17 00:00:00 2001 From: Florent Torregrosa Date: Sat, 24 Jun 2017 14:26:12 +0200 Subject: [PATCH 2/5] Update core to 7.56 --- www7/.htaccess | 11 ++- www7/includes/bootstrap.inc | 9 +- www7/includes/common.inc | 2 +- www7/includes/database/pgsql/database.inc | 12 +-- www7/includes/database/pgsql/install.inc | 2 +- www7/includes/database/pgsql/select.inc | 4 +- www7/includes/database/query.inc | 6 +- www7/includes/database/schema.inc | 5 +- www7/includes/database/sqlite/query.inc | 13 ++- www7/includes/database/sqlite/schema.inc | 2 +- www7/includes/errors.inc | 6 +- www7/includes/file.inc | 29 ++++++- www7/misc/drupal.js | 85 +++++++++++++++---- www7/modules/aggregator/aggregator.info | 6 +- www7/modules/aggregator/aggregator.module | 8 ++ www7/modules/aggregator/aggregator.test | 38 ++++++++- .../aggregator/tests/aggregator_test.info | 6 +- www7/modules/block/block.info | 6 +- www7/modules/block/block.module | 19 ++--- www7/modules/block/tests/block_test.info | 6 +- .../block_test_theme/block_test_theme.info | 6 +- www7/modules/blog/blog.info | 6 +- www7/modules/book/book.info | 6 +- www7/modules/color/color.info | 6 +- www7/modules/comment/comment.info | 6 +- www7/modules/contact/contact.info | 6 +- www7/modules/contact/contact.module | 9 +- www7/modules/contact/contact.test | 22 +++++ www7/modules/contextual/contextual.info | 6 +- www7/modules/dashboard/dashboard.info | 6 +- www7/modules/dblog/dblog.info | 6 +- www7/modules/field/field.info | 6 +- .../field_sql_storage/field_sql_storage.info | 6 +- www7/modules/field/modules/list/list.info | 6 +- .../field/modules/list/tests/list_test.info | 6 +- www7/modules/field/modules/number/number.info | 6 +- .../field/modules/options/options.info | 6 +- www7/modules/field/modules/text/text.info | 6 +- www7/modules/field/tests/field_test.info | 6 +- www7/modules/field/theme/field.tpl.php | 8 +- www7/modules/field_ui/field_ui.info | 6 +- www7/modules/file/file.info | 6 +- www7/modules/file/file.module | 7 +- www7/modules/file/tests/file.test | 74 ++++++++++++++++ www7/modules/file/tests/file_module_test.info | 6 +- www7/modules/filter/filter.info | 6 +- www7/modules/forum/forum.info | 6 +- www7/modules/help/help.info | 6 +- www7/modules/image/image.info | 6 +- .../image/tests/image_module_test.info | 6 +- www7/modules/locale/locale.info | 6 +- www7/modules/locale/locale.test | 6 +- www7/modules/locale/tests/locale_test.info | 6 +- www7/modules/menu/menu.info | 6 +- www7/modules/node/node.info | 6 +- www7/modules/node/tests/node_access_test.info | 6 +- www7/modules/node/tests/node_test.info | 6 +- .../node/tests/node_test_exception.info | 6 +- www7/modules/openid/openid.info | 6 +- www7/modules/openid/tests/openid_test.info | 6 +- www7/modules/overlay/overlay.info | 6 +- www7/modules/path/path.info | 6 +- www7/modules/php/php.info | 6 +- www7/modules/poll/poll.info | 6 +- www7/modules/profile/profile.info | 6 +- www7/modules/rdf/rdf.info | 6 +- www7/modules/rdf/tests/rdf_test.info | 6 +- www7/modules/search/search.info | 6 +- .../search/tests/search_embedded_form.info | 6 +- .../search/tests/search_extra_type.info | 6 +- .../search/tests/search_node_tags.info | 6 +- www7/modules/shortcut/shortcut.info | 6 +- .../simpletest/drupal_web_test_case.php | 32 ++++++- www7/modules/simpletest/simpletest.info | 6 +- .../simpletest/tests/actions_loop_test.info | 6 +- .../simpletest/tests/ajax_forms_test.info | 6 +- www7/modules/simpletest/tests/ajax_test.info | 6 +- www7/modules/simpletest/tests/batch_test.info | 6 +- .../modules/simpletest/tests/boot_test_1.info | 6 +- .../modules/simpletest/tests/boot_test_2.info | 6 +- www7/modules/simpletest/tests/common.test | 2 +- .../modules/simpletest/tests/common_test.info | 6 +- .../tests/common_test_cron_helper.info | 6 +- .../simpletest/tests/database_test.info | 6 +- .../drupal_autoload_test.info | 6 +- ...drupal_system_listing_compatible_test.info | 6 +- ...upal_system_listing_incompatible_test.info | 6 +- .../simpletest/tests/entity_cache_test.info | 6 +- .../tests/entity_cache_test_dependency.info | 6 +- .../tests/entity_crud_hook_test.info | 6 +- .../tests/entity_query_access_test.info | 6 +- www7/modules/simpletest/tests/error_test.info | 6 +- www7/modules/simpletest/tests/file_test.info | 6 +- .../modules/simpletest/tests/filter_test.info | 6 +- www7/modules/simpletest/tests/form_test.info | 6 +- www7/modules/simpletest/tests/image_test.info | 6 +- www7/modules/simpletest/tests/menu_test.info | 6 +- .../modules/simpletest/tests/module_test.info | 6 +- www7/modules/simpletest/tests/path_test.info | 6 +- .../tests/psr_0_test/psr_0_test.info | 6 +- .../tests/psr_4_test/psr_4_test.info | 6 +- .../simpletest/tests/requirements1_test.info | 6 +- .../simpletest/tests/requirements2_test.info | 6 +- .../simpletest/tests/session_test.info | 6 +- .../tests/system_dependencies_test.info | 6 +- ...atible_core_version_dependencies_test.info | 6 +- ...system_incompatible_core_version_test.info | 6 +- ...ible_module_version_dependencies_test.info | 6 +- ...stem_incompatible_module_version_test.info | 6 +- .../tests/system_project_namespace_test.info | 6 +- .../modules/simpletest/tests/system_test.info | 6 +- .../simpletest/tests/taxonomy_test.info | 6 +- www7/modules/simpletest/tests/theme_test.info | 6 +- .../themes/test_basetheme/test_basetheme.info | 6 +- .../themes/test_subtheme/test_subtheme.info | 6 +- .../tests/themes/test_theme/test_theme.info | 6 +- .../test_theme_nyan_cat.info | 6 +- .../simpletest/tests/update_script_test.info | 6 +- .../simpletest/tests/update_test_1.info | 6 +- .../simpletest/tests/update_test_2.info | 6 +- .../simpletest/tests/update_test_3.info | 6 +- .../simpletest/tests/url_alter_test.info | 6 +- .../modules/simpletest/tests/xmlrpc_test.info | 6 +- www7/modules/statistics/statistics.info | 6 +- www7/modules/statistics/statistics.module | 2 +- www7/modules/syslog/syslog.info | 6 +- www7/modules/system/system.info | 6 +- www7/modules/system/system.install | 2 +- .../modules/system/tests/cron_queue_test.info | 6 +- .../system/tests/system_cron_test.info | 6 +- www7/modules/taxonomy/taxonomy.info | 6 +- www7/modules/toolbar/toolbar.info | 6 +- www7/modules/tracker/tracker.info | 6 +- .../translation/tests/translation_test.info | 6 +- www7/modules/translation/translation.info | 6 +- www7/modules/trigger/tests/trigger_test.info | 6 +- www7/modules/trigger/trigger.info | 6 +- .../modules/update/tests/aaa_update_test.info | 6 +- .../modules/update/tests/bbb_update_test.info | 6 +- .../modules/update/tests/ccc_update_test.info | 6 +- .../update_test_admintheme.info | 6 +- .../update_test_basetheme.info | 6 +- .../update_test_subtheme.info | 6 +- www7/modules/update/tests/update_test.info | 6 +- www7/modules/update/update.info | 6 +- www7/modules/user/tests/user_form_test.info | 6 +- www7/modules/user/user.info | 6 +- www7/modules/user/user.module | 9 +- www7/modules/user/user.test | 76 +++++++++++++++-- www7/profiles/minimal/minimal.info | 6 +- www7/profiles/standard/standard.info | 6 +- ...drupal_system_listing_compatible_test.info | 6 +- ...upal_system_listing_incompatible_test.info | 6 +- www7/profiles/testing/testing.info | 6 +- www7/themes/bartik/bartik.info | 6 +- www7/themes/garland/garland.info | 6 +- www7/themes/seven/seven.info | 6 +- www7/themes/stark/stark.info | 6 +- 158 files changed, 802 insertions(+), 478 deletions(-) diff --git a/www7/.htaccess b/www7/.htaccess index 440cabc6d..37fce10d3 100644 --- a/www7/.htaccess +++ b/www7/.htaccess @@ -3,8 +3,13 @@ # # Protect files and directories from prying eyes. - - Order allow,deny + + + Require all denied + + + Order allow,deny + # Don't show directory listings for URLs which map to a directory. @@ -80,7 +85,7 @@ DirectoryIndex index.php index.html index.htm # If you do not have mod_rewrite installed, you should remove these # directories from your webroot or otherwise protect them from being # downloaded. - RewriteRule "(^|/)\." - [F] + RewriteRule "/\.|^\.(?!well-known/)" - [F] # If your site can be accessed both with and without the 'www.' prefix, you # can use one of the following settings to redirect users to your preferred diff --git a/www7/includes/bootstrap.inc b/www7/includes/bootstrap.inc index 99a5ac84d..c06055edb 100644 --- a/www7/includes/bootstrap.inc +++ b/www7/includes/bootstrap.inc @@ -8,7 +8,7 @@ /** * The current system version. */ -define('VERSION', '7.54'); +define('VERSION', '7.56'); /** * Core API compatibility. @@ -254,8 +254,13 @@ define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' * http://tools.ietf.org/html/rfc7231#section-7.1.1.1 * * Example: Sun, 06 Nov 1994 08:49:37 GMT + * + * This constant was introduced in PHP 7.0.19 and PHP 7.1.5 but needs to be + * defined by Drupal for earlier PHP versions. */ -define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T'); +if (!defined('DATE_RFC7231')) { + define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T'); +} /** * Provides a caching wrapper to be used in place of large array structures. diff --git a/www7/includes/common.inc b/www7/includes/common.inc index da8996a1b..a32930a51 100644 --- a/www7/includes/common.inc +++ b/www7/includes/common.inc @@ -487,7 +487,7 @@ function drupal_http_build_query(array $query, $parent = '') { $params = array(); foreach ($query as $key => $value) { - $key = ($parent ? $parent . '[' . rawurlencode($key) . ']' : rawurlencode($key)); + $key = $parent ? $parent . rawurlencode('[' . $key . ']') : rawurlencode($key); // Recurse into children. if (is_array($value)) { diff --git a/www7/includes/database/pgsql/database.inc b/www7/includes/database/pgsql/database.inc index 41579659b..fb3d0ab51 100644 --- a/www7/includes/database/pgsql/database.inc +++ b/www7/includes/database/pgsql/database.inc @@ -11,7 +11,7 @@ */ /** - * The name by which to obtain a lock for retrive the next insert id. + * The name by which to obtain a lock for retrieving the next insert id. */ define('POSTGRESQL_NEXTID_LOCK', 1000); @@ -55,7 +55,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection { $connection_options['pdo'] += array( // Prepared statements are most effective for performance when queries // are recycled (used several times). However, if they are not re-used, - // prepared statements become ineffecient. Since most of Drupal's + // prepared statements become inefficient. Since most of Drupal's // prepared queries are not re-used, it should be faster to emulate // the preparation than to actually ready statements for re-use. If in // doubt, reset to FALSE and measure performance. @@ -175,14 +175,14 @@ class DatabaseConnection_pgsql extends DatabaseConnection { } /** - * Retrive a the next id in a sequence. + * Retrieve the next id in a sequence. * * PostgreSQL has built in sequences. We'll use these instead of inserting * and updating a sequences table. */ public function nextId($existing = 0) { - // Retrive the name of the sequence. This information cannot be cached + // Retrieve the name of the sequence. This information cannot be cached // because the prefix may change, for example, like it does in simpletests. $sequence_name = $this->makeSequenceName('sequences', 'value'); @@ -194,7 +194,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection { } // PostgreSQL advisory locks are simply locks to be used by an - // application such as Drupal. This will prevent other Drupal proccesses + // application such as Drupal. This will prevent other Drupal processes // from altering the sequence while we are. $this->query("SELECT pg_advisory_lock(" . POSTGRESQL_NEXTID_LOCK . ")"); @@ -209,7 +209,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection { // Reset the sequence to a higher value than the existing id. $this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1)); - // Retrive the next id. We know this will be as high as we want it. + // Retrieve the next id. We know this will be as high as we want it. $id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField(); $this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")"); diff --git a/www7/includes/database/pgsql/install.inc b/www7/includes/database/pgsql/install.inc index c77f4ea78..122031ee5 100644 --- a/www7/includes/database/pgsql/install.inc +++ b/www7/includes/database/pgsql/install.inc @@ -165,7 +165,7 @@ class DatabaseTasks_pgsql extends DatabaseTasks { LANGUAGE \'sql\'' ); - // Using || to concatenate in Drupal is not recommeneded because there are + // Using || to concatenate in Drupal is not recommended because there are // database drivers for Drupal that do not support the syntax, however // they do support CONCAT(item1, item2) which we can replicate in // PostgreSQL. PostgreSQL requires the function to be defined for each diff --git a/www7/includes/database/pgsql/select.inc b/www7/includes/database/pgsql/select.inc index f6a83db7f..5b8736d68 100644 --- a/www7/includes/database/pgsql/select.inc +++ b/www7/includes/database/pgsql/select.inc @@ -80,7 +80,7 @@ class SelectQuery_pgsql extends SelectQuery { } // If a table loads all fields, it can not be added again. It would - // result in an ambigious alias error because that field would be loaded + // result in an ambiguous alias error because that field would be loaded // twice: Once through table_alias.* and once directly. If the field // actually belongs to a different table, it must be added manually. foreach ($this->tables as $table) { @@ -90,7 +90,7 @@ class SelectQuery_pgsql extends SelectQuery { } // If $field contains an characters which are not allowed in a field name - // it is considered an expression, these can't be handeld automatically + // it is considered an expression, these can't be handled automatically // either. if ($this->connection->escapeField($field) != $field) { return $return; diff --git a/www7/includes/database/query.inc b/www7/includes/database/query.inc index c9c5a8328..048c8a265 100644 --- a/www7/includes/database/query.inc +++ b/www7/includes/database/query.inc @@ -845,8 +845,8 @@ class DeleteQuery extends Query implements QueryConditionInterface { /** * Executes the DELETE query. * - * @return - * The return value is dependent on the database connection. + * @return int + * The number of rows affected by the delete query. */ public function execute() { $values = array(); @@ -1242,7 +1242,7 @@ class UpdateQuery extends Query implements QueryConditionInterface { * MergeQuery::updateFields() and MergeQuery::insertFields() needs to be called * instead. MergeQuery::fields() can also be called which calls both of these * methods as the common case is to use the same column-value pairs for both - * INSERT and UPDATE. However, this is not mandatory. Another convinient + * INSERT and UPDATE. However, this is not mandatory. Another convenient * wrapper is MergeQuery::key() which adds the same column-value pairs to the * condition and the INSERT query part. * diff --git a/www7/includes/database/schema.inc b/www7/includes/database/schema.inc index d8344c626..31862db39 100644 --- a/www7/includes/database/schema.inc +++ b/www7/includes/database/schema.inc @@ -164,6 +164,9 @@ require_once dirname(__FILE__) . '/query.inc'; * @see drupal_install_schema() */ +/** + * Base class for database schema definitions. + */ abstract class DatabaseSchema implements QueryPlaceholderInterface { protected $connection; @@ -291,7 +294,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface { protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) { $info = $this->connection->getConnectionOptions(); - // Retrive the table name and schema + // Retrieve the table name and schema $table_info = $this->getPrefixInfo($table_name, $add_prefix); $condition = new DatabaseCondition('AND'); diff --git a/www7/includes/database/sqlite/query.inc b/www7/includes/database/sqlite/query.inc index 1c6289bd7..c9c028bb0 100644 --- a/www7/includes/database/sqlite/query.inc +++ b/www7/includes/database/sqlite/query.inc @@ -99,16 +99,15 @@ class UpdateQuery_sqlite extends UpdateQuery { /** * SQLite specific implementation of DeleteQuery. - * - * When the WHERE is omitted from a DELETE statement and the table being deleted - * has no triggers, SQLite uses an optimization to erase the entire table content - * without having to visit each row of the table individually. - * - * Prior to SQLite 3.6.5, SQLite does not return the actual number of rows deleted - * by that optimized "truncate" optimization. */ class DeleteQuery_sqlite extends DeleteQuery { public function execute() { + // When the WHERE is omitted from a DELETE statement and the table being + // deleted has no triggers, SQLite uses an optimization to erase the entire + // table content without having to visit each row of the table individually. + // Prior to SQLite 3.6.5, SQLite does not return the actual number of rows + // deleted by that optimized "truncate" optimization. But we want to return + // the number of rows affected, so we calculate it directly. if (!count($this->condition)) { $total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField(); parent::execute(); diff --git a/www7/includes/database/sqlite/schema.inc b/www7/includes/database/sqlite/schema.inc index df19d2fa5..281d8fc6b 100644 --- a/www7/includes/database/sqlite/schema.inc +++ b/www7/includes/database/sqlite/schema.inc @@ -244,7 +244,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema { // database. So the syntax '...RENAME TO database.table' would fail. // So we must determine the full table name here rather than surrounding // the table with curly braces incase the db_prefix contains a reference - // to a database outside of our existsing database. + // to a database outside of our existing database. $info = $this->getPrefixInfo($new_name); $this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']); diff --git a/www7/includes/errors.inc b/www7/includes/errors.inc index 7393148e9..3548d1fd8 100644 --- a/www7/includes/errors.inc +++ b/www7/includes/errors.inc @@ -66,7 +66,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c _drupal_log_error(array( '%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error', // The standard PHP error handler considers that the error messages - // are HTML. We mimick this behavior here. + // are HTML. We mimic this behavior here. '!message' => filter_xss_admin($message), '%function' => $caller['function'], '%file' => $caller['file'], @@ -114,7 +114,7 @@ function _drupal_decode_exception($exception) { return array( '%type' => get_class($exception), // The standard PHP exception handler considers that the exception message - // is plain-text. We mimick this behavior here. + // is plain-text. We mimic this behavior here. '!message' => check_plain($message), '%function' => $caller['function'], '%file' => $caller['file'], @@ -233,7 +233,7 @@ function _drupal_log_error($error, $fatal = FALSE) { } else { // Display the message if the current error reporting level allows this type - // of message to be displayed, and unconditionnaly in update.php. + // of message to be displayed, and unconditionally in update.php. if (error_displayable($error)) { $class = 'error'; diff --git a/www7/includes/file.inc b/www7/includes/file.inc index de9d17d69..fa7f5eb54 100644 --- a/www7/includes/file.inc +++ b/www7/includes/file.inc @@ -535,7 +535,18 @@ SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006 EOF; if ($private) { - $lines = "Deny from all\n\n" . $lines; + $lines = << + Require all denied + + +# Deny all requests from Apache 2.0-2.2. + + Deny from all + +EOF + . "\n\n" . $lines; } return $lines; @@ -889,7 +900,6 @@ function file_valid_uri($uri) { */ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) { $original_source = $source; - $original_destination = $destination; // Assert that the source file actually exists. if (!file_exists($source)) { @@ -1604,6 +1614,20 @@ function file_save_upload($form_field_name, $validators = array(), $destination // If we made it this far it's safe to record this file in the database. if ($file = file_save($file)) { + // Track non-public files in the session if they were uploaded by an + // anonymous user. This allows modules such as the File module to only + // grant view access to the specific anonymous user who uploaded the file. + // See file_file_download(). + // The 'file_public_schema' variable is used to allow other publicly + // accessible file schemes to be treated the same as the public:// scheme + // provided by Drupal core and to avoid adding unnecessary data to the + // session (and the resulting bypass of the page cache) in those cases. For + // security reasons, only schemes that are completely publicly accessible, + // with no download restrictions, should be added to this variable. See + // file_managed_file_value(). + if (!$user->uid && !in_array($destination_scheme, variable_get('file_public_schema', array('public')))) { + $_SESSION['anonymous_allowed_file_ids'][$file->fid] = $file->fid; + } // Add file to the cache. $upload_cache[$form_field_name] = $file; return $file; @@ -2553,7 +2577,6 @@ function file_directory_temp() { * An associative array of headers, as expected by file_transfer(). */ function file_get_content_headers($file) { - $name = mime_header_encode($file->filename); $type = mime_header_encode($file->filemime); return array( diff --git a/www7/misc/drupal.js b/www7/misc/drupal.js index 03eef50ed..d86ea1fae 100644 --- a/www7/misc/drupal.js +++ b/www7/misc/drupal.js @@ -168,23 +168,76 @@ Drupal.checkPlain = function (str) { Drupal.formatString = function(str, args) { // Transform arguments before inserting them. for (var key in args) { - switch (key.charAt(0)) { - // Escaped only. - case '@': - args[key] = Drupal.checkPlain(args[key]); - break; - // Pass-through. - case '!': - break; - // Escaped and placeholder. - case '%': - default: - args[key] = Drupal.theme('placeholder', args[key]); - break; + if (args.hasOwnProperty(key)) { + switch (key.charAt(0)) { + // Escaped only. + case '@': + args[key] = Drupal.checkPlain(args[key]); + break; + // Pass-through. + case '!': + break; + // Escaped and placeholder. + default: + args[key] = Drupal.theme('placeholder', args[key]); + break; + } } - str = str.replace(key, args[key]); } - return str; + + return Drupal.stringReplace(str, args, null); +}; + +/** + * Replace substring. + * + * The longest keys will be tried first. Once a substring has been replaced, + * its new value will not be searched again. + * + * @param {String} str + * A string with placeholders. + * @param {Object} args + * Key-value pairs. + * @param {Array|null} keys + * Array of keys from the "args". Internal use only. + * + * @return {String} + * Returns the replaced string. + */ +Drupal.stringReplace = function (str, args, keys) { + if (str.length === 0) { + return str; + } + + // If the array of keys is not passed then collect the keys from the args. + if (!$.isArray(keys)) { + keys = []; + for (var k in args) { + if (args.hasOwnProperty(k)) { + keys.push(k); + } + } + + // Order the keys by the character length. The shortest one is the first. + keys.sort(function (a, b) { return a.length - b.length; }); + } + + if (keys.length === 0) { + return str; + } + + // Take next longest one from the end. + var key = keys.pop(); + var fragments = str.split(key); + + if (keys.length) { + for (var i = 0; i < fragments.length; i++) { + // Process each fragment with a copy of remaining keys. + fragments[i] = Drupal.stringReplace(fragments[i], args, keys.slice(0)); + } + } + + return fragments.join(args[key]); }; /** @@ -251,7 +304,7 @@ Drupal.t = function (str, args, options) { * A translated string. */ Drupal.formatPlural = function (count, singular, plural, args, options) { - var args = args || {}; + args = args || {}; args['@count'] = count; // Determine the index of the plural form. var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1); diff --git a/www7/modules/aggregator/aggregator.info b/www7/modules/aggregator/aggregator.info index 67ebdc00a..09caa0081 100644 --- a/www7/modules/aggregator/aggregator.info +++ b/www7/modules/aggregator/aggregator.info @@ -7,8 +7,8 @@ files[] = aggregator.test configure = admin/config/services/aggregator/settings stylesheets[all][] = aggregator.css -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/aggregator/aggregator.module b/www7/modules/aggregator/aggregator.module index 70f8c5cd8..02c9ec46a 100644 --- a/www7/modules/aggregator/aggregator.module +++ b/www7/modules/aggregator/aggregator.module @@ -455,6 +455,14 @@ function aggregator_save_category($edit) { db_delete('aggregator_category') ->condition('cid', $edit['cid']) ->execute(); + // Remove category from feeds. + db_delete('aggregator_category_feed') + ->condition('cid', $edit['cid']) + ->execute(); + // Remove category from feed items. + db_delete('aggregator_category_item') + ->condition('cid', $edit['cid']) + ->execute(); // Make sure there is no active block for this category. if (module_exists('block')) { db_delete('block') diff --git a/www7/modules/aggregator/aggregator.test b/www7/modules/aggregator/aggregator.test index d84ee7852..afa791d63 100644 --- a/www7/modules/aggregator/aggregator.test +++ b/www7/modules/aggregator/aggregator.test @@ -418,7 +418,7 @@ class CategorizeFeedTestCase extends AggregatorTestCase { } /** - * Creates a feed and makes sure you can add more than one category to it. + * Creates a feed and makes sure you can add/delete categories to it. */ function testCategorizeFeed() { @@ -448,7 +448,31 @@ class CategorizeFeedTestCase extends AggregatorTestCase { // Assert the feed has two categories. $this->getFeedCategories($db_feed); $this->assertEqual(count($db_feed->categories), 2, 'Feed has 2 categories'); + + // Use aggregator_save_feed() to delete a category. + $category = reset($categories); + aggregator_save_category(array('cid' => $category->cid)); + + // Assert that category is deleted. + $db_category = db_query("SELECT COUNT(*) FROM {aggregator_category} WHERE cid = :cid", array(':cid' => $category->cid))->fetchField(); + $this->assertFalse($db_category, format_string('The category %title has been deleted.', array('%title' => $category->title))); + + // Assert that category has been removed from feed. + $categorized_feeds = db_query("SELECT COUNT(*) FROM {aggregator_category_feed} WHERE cid = :cid", array(':cid' => $category->cid))->fetchField(); + $this->assertFalse($categorized_feeds, format_string('The category %title has been removed from feed %feed_title.', array('%title' => $category->title, '%feed_title' => $feed['title']))); + + // Assert that no broken links (associated with the deleted category) + // appear on one of the other category pages. + $this->createSampleNodes(); + $this->drupalGet('admin/config/services/aggregator'); + $this->clickLink('update items'); + $categories = $this->getCategories(); + $category = reset($categories); + $this->drupalGet('aggregator/categories/' . $category->cid); + global $base_path; + $this->assertNoRaw(','); } + } /** @@ -685,9 +709,21 @@ class CategorizeFeedItemTestCase extends AggregatorTestCase { } } + // Delete category from feed items when category is deleted. + $cid = reset($feed->categories); + $categories = $this->getCategories(); + $category_title = $categories[$cid]->title; + + // Delete category. + aggregator_save_category(array('cid' => $cid)); + + // Assert category has been removed from feed items. + $categorized_count = db_query("SELECT COUNT(*) FROM {aggregator_category_item} WHERE cid = :cid", array(':cid' => $cid))->fetchField(); + $this->assertFalse($categorized_count, format_string('The category %title has been removed from feed items.', array('%title' => $category_title))); // Delete feed. $this->deleteFeed($feed); } + } /** diff --git a/www7/modules/aggregator/tests/aggregator_test.info b/www7/modules/aggregator/tests/aggregator_test.info index 49838960d..575be5664 100644 --- a/www7/modules/aggregator/tests/aggregator_test.info +++ b/www7/modules/aggregator/tests/aggregator_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/block/block.info b/www7/modules/block/block.info index 9e47f1ff4..a0ff83f0f 100644 --- a/www7/modules/block/block.info +++ b/www7/modules/block/block.info @@ -6,8 +6,8 @@ core = 7.x files[] = block.test configure = admin/structure/block -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/block/block.module b/www7/modules/block/block.module index 73e116211..d68ea9e7a 100644 --- a/www7/modules/block/block.module +++ b/www7/modules/block/block.module @@ -432,23 +432,20 @@ function _block_rehash($theme = NULL) { drupal_alter('block_info', $current_blocks, $theme, $code_blocks); foreach ($current_blocks as $module => $module_blocks) { foreach ($module_blocks as $delta => $block) { - if (!isset($block['pages'])) { - // {block}.pages is type 'text', so it cannot have a - // default value, and not null, so we need to provide - // value if the module did not. - $block['pages'] = ''; - } - // Make sure weight is set. - if (!isset($block['weight'])) { - $block['weight'] = 0; - } + // Make sure certain attributes are set. + $block += array( + 'pages' => '', + 'weight' => 0, + 'status' => 0, + ); + // Check for active blocks in regions that are not available. if (!empty($block['region']) && $block['region'] != BLOCK_REGION_NONE && !isset($regions[$block['region']]) && $block['status'] == 1) { drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $block['info'], '%region' => $block['region'])), 'warning'); // Disabled modules are moved into the BLOCK_REGION_NONE later so no // need to move the block to another region. $block['status'] = 0; } - // Set region to none if not enabled and make sure status is set. + // Set region to none if not enabled. if (empty($block['status'])) { $block['status'] = 0; $block['region'] = BLOCK_REGION_NONE; diff --git a/www7/modules/block/tests/block_test.info b/www7/modules/block/tests/block_test.info index ef1f71386..beff5962c 100644 --- a/www7/modules/block/tests/block_test.info +++ b/www7/modules/block/tests/block_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/block/tests/themes/block_test_theme/block_test_theme.info b/www7/modules/block/tests/themes/block_test_theme/block_test_theme.info index be82747e7..6e7b9c964 100644 --- a/www7/modules/block/tests/themes/block_test_theme/block_test_theme.info +++ b/www7/modules/block/tests/themes/block_test_theme/block_test_theme.info @@ -13,8 +13,8 @@ regions[footer] = Footer regions[highlighted] = Highlighted regions[help] = Help -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/blog/blog.info b/www7/modules/blog/blog.info index 0302f22f7..d241eca29 100644 --- a/www7/modules/blog/blog.info +++ b/www7/modules/blog/blog.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = blog.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/book/book.info b/www7/modules/book/book.info index 396bd6692..164043dfd 100644 --- a/www7/modules/book/book.info +++ b/www7/modules/book/book.info @@ -7,8 +7,8 @@ files[] = book.test configure = admin/content/book/settings stylesheets[all][] = book.css -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/color/color.info b/www7/modules/color/color.info index 2b5881065..086f8cf1b 100644 --- a/www7/modules/color/color.info +++ b/www7/modules/color/color.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = color.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/comment/comment.info b/www7/modules/comment/comment.info index 69885dbb5..3dbf6e607 100644 --- a/www7/modules/comment/comment.info +++ b/www7/modules/comment/comment.info @@ -9,8 +9,8 @@ files[] = comment.test configure = admin/content/comment stylesheets[all][] = comment.css -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/contact/contact.info b/www7/modules/contact/contact.info index 464c22467..466e94177 100644 --- a/www7/modules/contact/contact.info +++ b/www7/modules/contact/contact.info @@ -6,8 +6,8 @@ core = 7.x files[] = contact.test configure = admin/structure/contact -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/contact/contact.module b/www7/modules/contact/contact.module index 9a48f2312..9c6671a91 100644 --- a/www7/modules/contact/contact.module +++ b/www7/modules/contact/contact.module @@ -234,7 +234,14 @@ function contact_form_user_profile_form_alter(&$form, &$form_state) { * Implements hook_user_presave(). */ function contact_user_presave(&$edit, $account, $category) { - $edit['data']['contact'] = isset($edit['contact']) ? $edit['contact'] : variable_get('contact_default_status', 1); + if (isset($edit['contact'])) { + // Set new value. + $edit['data']['contact'] = $edit['contact']; + } + elseif (!isset($account->data['contact'])) { + // Use default if none has been set. + $edit['data']['contact'] = variable_get('contact_default_status', 1); + } } /** diff --git a/www7/modules/contact/contact.test b/www7/modules/contact/contact.test index 6693b5749..6a1674a0d 100644 --- a/www7/modules/contact/contact.test +++ b/www7/modules/contact/contact.test @@ -346,6 +346,28 @@ class ContactPersonalTestCase extends DrupalWebTestCase { $this->drupalGet('user/' . $this->contact_user->uid . '/contact'); $this->assertResponse(200); + // Test that users can disable their contact form. + $this->drupalLogin($this->contact_user); + $edit = array('contact' => FALSE); + $this->drupalPost('user/' . $this->contact_user->uid . '/edit', $edit, 'Save'); + $this->drupalLogout(); + $this->drupalGet('user/' . $this->contact_user->uid . '/contact'); + $this->assertResponse(403); + + // Test that user's contact status stays disabled when saving. + $contact_user_temp = user_load($this->contact_user->uid, TRUE); + user_save($contact_user_temp); + $this->drupalGet('user/' . $this->contact_user->uid . '/contact'); + $this->assertResponse(403); + + // Test that users can enable their contact form. + $this->drupalLogin($this->contact_user); + $edit = array('contact' => TRUE); + $this->drupalPost('user/' . $this->contact_user->uid . '/edit', $edit, 'Save'); + $this->drupalLogout(); + $this->drupalGet('user/' . $this->contact_user->uid . '/contact'); + $this->assertResponse(200); + // Revoke the personal contact permission for the anonymous user. user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access user contact forms')); $this->drupalGet('user/' . $this->contact_user->uid . '/contact'); diff --git a/www7/modules/contextual/contextual.info b/www7/modules/contextual/contextual.info index b57e9f67e..fd73edd57 100644 --- a/www7/modules/contextual/contextual.info +++ b/www7/modules/contextual/contextual.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = contextual.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/dashboard/dashboard.info b/www7/modules/dashboard/dashboard.info index d17a97400..bc9c98a94 100644 --- a/www7/modules/dashboard/dashboard.info +++ b/www7/modules/dashboard/dashboard.info @@ -7,8 +7,8 @@ files[] = dashboard.test dependencies[] = block configure = admin/dashboard/customize -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/dblog/dblog.info b/www7/modules/dblog/dblog.info index 89b66c115..dc39510e7 100644 --- a/www7/modules/dblog/dblog.info +++ b/www7/modules/dblog/dblog.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = dblog.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/field/field.info b/www7/modules/field/field.info index d19c29d17..241c29713 100644 --- a/www7/modules/field/field.info +++ b/www7/modules/field/field.info @@ -11,8 +11,8 @@ dependencies[] = field_sql_storage required = TRUE stylesheets[all][] = theme/field.css -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/field/modules/field_sql_storage/field_sql_storage.info b/www7/modules/field/modules/field_sql_storage/field_sql_storage.info index a35372a8b..48881e267 100644 --- a/www7/modules/field/modules/field_sql_storage/field_sql_storage.info +++ b/www7/modules/field/modules/field_sql_storage/field_sql_storage.info @@ -7,8 +7,8 @@ dependencies[] = field files[] = field_sql_storage.test required = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/field/modules/list/list.info b/www7/modules/field/modules/list/list.info index 0cd4939ca..e7427bcc4 100644 --- a/www7/modules/field/modules/list/list.info +++ b/www7/modules/field/modules/list/list.info @@ -7,8 +7,8 @@ dependencies[] = field dependencies[] = options files[] = tests/list.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/field/modules/list/tests/list_test.info b/www7/modules/field/modules/list/tests/list_test.info index 4bd2dae2b..ce3ca4c9f 100644 --- a/www7/modules/field/modules/list/tests/list_test.info +++ b/www7/modules/field/modules/list/tests/list_test.info @@ -5,8 +5,8 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/field/modules/number/number.info b/www7/modules/field/modules/number/number.info index d3c995e57..39a336414 100644 --- a/www7/modules/field/modules/number/number.info +++ b/www7/modules/field/modules/number/number.info @@ -6,8 +6,8 @@ core = 7.x dependencies[] = field files[] = number.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/field/modules/options/options.info b/www7/modules/field/modules/options/options.info index d395377aa..bb212833a 100644 --- a/www7/modules/field/modules/options/options.info +++ b/www7/modules/field/modules/options/options.info @@ -6,8 +6,8 @@ core = 7.x dependencies[] = field files[] = options.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/field/modules/text/text.info b/www7/modules/field/modules/text/text.info index 678bdab33..86dcdc77f 100644 --- a/www7/modules/field/modules/text/text.info +++ b/www7/modules/field/modules/text/text.info @@ -7,8 +7,8 @@ dependencies[] = field files[] = text.test required = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/field/tests/field_test.info b/www7/modules/field/tests/field_test.info index 07eed538d..54ea80f39 100644 --- a/www7/modules/field/tests/field_test.info +++ b/www7/modules/field/tests/field_test.info @@ -6,8 +6,8 @@ files[] = field_test.entity.inc version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/www7/modules/field/theme/field.tpl.php b/www7/modules/field/theme/field.tpl.php index f0f9d583f..460fd2e26 100644 --- a/www7/modules/field/theme/field.tpl.php +++ b/www7/modules/field/theme/field.tpl.php @@ -4,8 +4,10 @@ * @file field.tpl.php * Default template implementation to display the value of a field. * - * This file is not used and is here as a starting point for customization only. - * @see theme_field() + * This file is not used by Drupal core, which uses theme functions instead for + * performance reasons. The markup is the same, though, so if you want to use + * template files rather than functions to extend field theming, copy this to + * your custom theme. See theme_field() for a discussion of performance. * * Available variables: * - $items: An array of field values. Use render() to output them. @@ -45,7 +47,7 @@ */ ?>