diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index fd3b719..e7da6ec 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -508,7 +508,13 @@ function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) { $path = conf_path() . '/files/simpletest/' . substr($test_prefix, 10) . '/config_' . $type; } elseif (!empty($config_directories[$type])) { - $path = conf_path() . '/files/' . $config_directories[$type]; + // Allow a configuration directory path to be outside of webroot. + if (empty($config_directories[$type]['absolute'])) { + $path = conf_path() . '/files/' . $config_directories[$type]['path']; + } + else { + $path = $config_directories[$type]['path']; + } } else { throw new Exception(format_string('The configuration directory type %type does not exist.', array('%type' => $type))); diff --git a/core/includes/entity.inc b/core/includes/entity.inc index b651e32..24e150f 100644 --- a/core/includes/entity.inc +++ b/core/includes/entity.inc @@ -530,3 +530,48 @@ function entity_form_submit_build_entity($entity_type, $entity, $form, &$form_st field_attach_submit($entity_type, $entity, $form, $form_state); } } + +/** + * Returns an entity list controller for a given entity type. + * + * Since there might be different scenarios in which an entity is edited, + * multiple form controllers suitable to the different operations may be defined. + * If no controller is found for the default operation, the base class will be + * used. If a non-existing non-default operation is specified an exception will + * be thrown. + * + * @see hook_entity_info() + * + * @param string $entity_type + * The type of the entity. + * + * @return Drupal\Core\Entity\EntityListControllerInterface + * An entity list controller instance. + */ +function entity_list_controller($entity_type) { + $instances = &drupal_static(__FUNCTION__, array()); + + if (isset($instances[$entity_type])) { + return $instances[$entity_type]; + } + + $info = entity_get_info($entity_type); + + // Check whether there is a controller class for the specified operation. + if (!empty($info['list controller class'])) { + $class = $info['list controller class']; + } + // If no controller is specified default to the base implementation. + // @todo Provide a sane base implementation. + /* + elseif (empty($info['list controller class'])) { + $class = 'Drupal\Core\Entity\EntityListControllerBase'; + } + */ + else { + throw new \InvalidArgumentException("Missing list controller for '$entity_type'"); + } + + $instances[$entity_type] = new $class($entity_type); + return $instances[$entity_type]; +} diff --git a/core/includes/install.inc b/core/includes/install.inc index 330fc0e..efba3c1 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -266,8 +266,12 @@ function drupal_install_config_directories() { if (empty($config_directories)) { $settings['config_directories'] = array( 'value' => array( - CONFIG_ACTIVE_DIRECTORY => 'config/active_' . drupal_hash_base64(drupal_random_bytes(55)), - CONFIG_STAGING_DIRECTORY => 'config/staging_' . drupal_hash_base64(drupal_random_bytes(55)), + CONFIG_ACTIVE_DIRECTORY => array( + 'path' => 'config/active_' . drupal_hash_base64(drupal_random_bytes(55)), + ), + CONFIG_STAGING_DIRECTORY => array( + 'path' => 'config/staging_' . drupal_hash_base64(drupal_random_bytes(55)), + ), ), 'required' => TRUE, ); diff --git a/core/includes/mail.inc b/core/includes/mail.inc index 1be3c38..e9778d8 100644 --- a/core/includes/mail.inc +++ b/core/includes/mail.inc @@ -26,13 +26,13 @@ * * Finding out what language to send the e-mail with needs some consideration. * If you send e-mail to a user, her preferred language should be fine, so - * use user_preferred_language(). If you send email based on form values + * use user_preferred_langcode(). If you send email based on form values * filled on the page, there are two additional choices if you are not * sending the e-mail to a user on the site. You can either use the language - * used to generate the page ($language global variable) or the site default - * language. See language_default(). The former is good if sending e-mail to - * the person filling the form, the later is good if you send e-mail to an - * address previously set up (like contact addresses in a contact form). + * used to generate the page or the site default language. See + * language_default(). The former is good if sending e-mail to the person + * filling the form, the later is good if you send e-mail to an address + * previously set up (like contact addresses in a contact form). * * Taking care of always using the proper language is even more important * when sending e-mails in a row to multiple users. Hook_mail() abstracts @@ -47,13 +47,13 @@ * foreach ($accounts as $account) { * $params['account'] = $account; * // example_mail() will be called based on the first drupal_mail() parameter. - * drupal_mail('example', 'notice', $account->mail, user_preferred_language($account), $params); + * drupal_mail('example', 'notice', $account->mail, user_preferred_langcode($account), $params); * } * } * * function example_mail($key, &$message, $params) { * $data['user'] = $params['account']; - * $options['langcode'] = $message['language']; + * $options['langcode'] = $message['langcode']; * user_mail_tokens($variables, $data, $options); * switch($key) { * case 'notice': @@ -63,9 +63,8 @@ * $message['send'] = FALSE; * break; * } - * $langcode = $message['language']->langcode; - * $message['subject'] = t('Notification from !site', $variables, array('langcode' => $langcode)); - * $message['body'][] = t("Dear !username\n\nThere is new content available on the site.", $variables, array('langcode' => $langcode)); + * $message['subject'] = t('Notification from !site', $variables, $options); + * $message['body'][] = t("Dear !username\n\nThere is new content available on the site.", $variables, $options); * break; * } * } @@ -77,7 +76,7 @@ * @code * $params = array('current_conditions' => $data); * $to = 'user@example.com'; - * $message = drupal_mail('example', 'notice', $to, $language, $params, FALSE); + * $message = drupal_mail('example', 'notice', $to, $langcode, $params, FALSE); * // Only add to the spool if sending was not canceled. * if ($message['send']) { * example_spool_message($message); @@ -98,10 +97,10 @@ * - user@example.com, anotheruser@example.com * - User * - User , Another User - * @param $language - * Language object to use to compose the e-mail. + * @param $langcode + * Language code to use to compose the e-mail. * @param $params - * Optional parameters to build the e-mail. + * (optional) parameters to build the e-mail. * @param $from * Sets From to this value, if given. * @param $send @@ -117,7 +116,7 @@ * written to the watchdog. (Success means nothing more than the message being * accepted at php-level, which still doesn't guarantee it to be delivered.) */ -function drupal_mail($module, $key, $to, $language, $params = array(), $from = NULL, $send = TRUE) { +function drupal_mail($module, $key, $to, $langcode, $params = array(), $from = NULL, $send = TRUE) { $site_mail = config('system.site')->get('mail'); if (empty($site_mail)) { $site_mail = ini_get('sendmail_from'); @@ -131,7 +130,7 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N 'key' => $key, 'to' => $to, 'from' => isset($from) ? $from : $default_from, - 'language' => $language, + 'langcode' => $langcode, 'params' => $params, 'send' => TRUE, 'subject' => '', diff --git a/core/lib/Drupal/Core/Entity/EntityListControllerBase.php b/core/lib/Drupal/Core/Entity/EntityListControllerBase.php new file mode 100644 index 0000000..20b34ae --- /dev/null +++ b/core/lib/Drupal/Core/Entity/EntityListControllerBase.php @@ -0,0 +1,110 @@ +entityType = $entity_type; + $this->storage = entity_get_controller($this->entityType); + $this->entityInfo = entity_get_info($this->entityType); + } + + /** + * Implements Drupal\Core\Entity\EntityListControllerInterface::getStorageController(); + */ + public function getStorageController() { + return $this->storage; + } + + /** + * Implements Drupal\Core\Entity\EntityListControllerInterface::load(); + */ + public function load() { + return $this->storage->load(); + } + + public function getPath() { + return $this->entityInfo['list path']; + } + + /** + * Implements Drupal\Core\Entity\EntityListControllerInterface::buildHeader(); + */ + public function buildHeader() { + $row['label'] = t('Label'); + $row['id'] = t('Machine name'); + $row['operations'] = t('Operations'); + return $row; + } + + /** + * Implements Drupal\Core\Entity\EntityListControllerInterface::buildRow(); + */ + public function buildRow(EntityInterface $entity) { + $row['label'] = $entity->label(); + $row['id'] = $entity->id(); + $row['operations']['data'] = $this->buildOperations($entity); + return $row; + } + + /** + * Implements Drupal\Core\Entity\EntityListControllerInterface::buildOperations(); + */ + public function buildOperations(EntityInterface $entity) { + $operations = $this->getOperations($entity); + return $operations; + } + + /** + * Implements Drupal\Core\Entity\EntityListControllerInterface::render(); + */ + public function render() { + $build = array( + '#theme' => 'table', + '#header' => $this->buildHeader(), + '#rows' => array(), + '#empty' => t('There is no @label yet. Add one.', array( + '@label' => $this->entityInfo['label'], + '@add-url' => $this->getPath() . '/add', + )), + '#attributes' => array( + 'id' => 'config-entity-listing', + ), + ); + foreach ($this->load() as $entity) { + $build['#rows'][$entity->id()] = $this->buildRow($entity); + } + return $build; + } + +} diff --git a/core/lib/Drupal/Core/Entity/EntityListControllerInterface.php b/core/lib/Drupal/Core/Entity/EntityListControllerInterface.php new file mode 100644 index 0000000..d93d91c --- /dev/null +++ b/core/lib/Drupal/Core/Entity/EntityListControllerInterface.php @@ -0,0 +1,74 @@ +assertPattern($this->generateOutlinePattern($nodes), t('Node ' . $number . ' outline confirmed.')); + $this->assertPattern($this->generateOutlinePattern($nodes), format_string('Node @number outline confirmed.', array('@number' => $number))); } else { $this->pass(t('Node ' . $number . ' doesn\'t have outline.')); @@ -150,15 +150,15 @@ function checkBookNode(Node $node, $nodes, $previous = FALSE, $up = FALSE, $next // Check previous, up, and next links. if ($previous) { - $this->assertRaw(l(' ' . $previous->label(), 'node/' . $previous->nid, array('html' => TRUE, 'attributes' => array('rel' => array('prev'), 'title' => t('Go to previous page')))), t('Previous page link found.')); + $this->assertRaw(l(' ' . $previous->label(), 'node/' . $previous->nid, array('html' => TRUE, 'attributes' => array('rel' => array('prev'), 'title' => t('Go to previous page')))), 'Previous page link found.'); } if ($up) { - $this->assertRaw(l('up', 'node/' . $up->nid, array('html'=> TRUE, 'attributes' => array('title' => t('Go to parent page')))), t('Up page link found.')); + $this->assertRaw(l('up', 'node/' . $up->nid, array('html'=> TRUE, 'attributes' => array('title' => t('Go to parent page')))), 'Up page link found.'); } if ($next) { - $this->assertRaw(l($next->label() . ' ', 'node/' . $next->nid, array('html'=> TRUE, 'attributes' => array('rel' => array('next'), 'title' => t('Go to next page')))), t('Next page link found.')); + $this->assertRaw(l($next->label() . ' ', 'node/' . $next->nid, array('html'=> TRUE, 'attributes' => array('rel' => array('next'), 'title' => t('Go to next page')))), 'Next page link found.'); } // Compute the expected breadcrumb. @@ -176,12 +176,12 @@ function checkBookNode(Node $node, $nodes, $previous = FALSE, $up = FALSE, $next } // Compare expected and got breadcrumbs. - $this->assertIdentical($expected_breadcrumb, $got_breadcrumb, t('The breadcrumb is correctly displayed on the page.')); + $this->assertIdentical($expected_breadcrumb, $got_breadcrumb, 'The breadcrumb is correctly displayed on the page.'); // Check printer friendly version. $this->drupalGet('book/export/html/' . $node->nid); - $this->assertText($node->label(), t('Printer friendly title found.')); - $this->assertRaw(check_markup($node->body[LANGUAGE_NOT_SPECIFIED][0]['value'], $node->body[LANGUAGE_NOT_SPECIFIED][0]['format']), t('Printer friendly body found.')); + $this->assertText($node->label(), 'Printer friendly title found.'); + $this->assertRaw(check_markup($node->body[LANGUAGE_NOT_SPECIFIED][0]['value'], $node->body[LANGUAGE_NOT_SPECIFIED][0]['format']), 'Printer friendly body found.'); $number++; } @@ -229,7 +229,7 @@ function createBookNode($book_nid, $parent = NULL) { // Check to make sure the book node was created. $node = $this->drupalGetNodeByTitle($edit['title']); - $this->assertNotNull(($node === FALSE ? NULL : $node), t('Book node found in database.')); + $this->assertNotNull(($node === FALSE ? NULL : $node), 'Book node found in database.'); $number++; return $node; @@ -249,28 +249,28 @@ function testBookExport() { // Make sure each part of the book is there. foreach ($nodes as $node) { - $this->assertText($node->label(), t('Node title found in printer friendly version.')); - $this->assertRaw(check_markup($node->body[LANGUAGE_NOT_SPECIFIED][0]['value'], $node->body[LANGUAGE_NOT_SPECIFIED][0]['format']), t('Node body found in printer friendly version.')); + $this->assertText($node->label(), 'Node title found in printer friendly version.'); + $this->assertRaw(check_markup($node->body[LANGUAGE_NOT_SPECIFIED][0]['value'], $node->body[LANGUAGE_NOT_SPECIFIED][0]['format']), 'Node body found in printer friendly version.'); } // Make sure we can't export an unsupported format. $this->drupalGet('book/export/foobar/' . $this->book->nid); - $this->assertResponse('404', t('Unsupported export format returned "not found".')); + $this->assertResponse('404', 'Unsupported export format returned "not found".'); // Make sure we get a 404 on a not existing book node. $this->drupalGet('book/export/html/123'); - $this->assertResponse('404', t('Not existing book node returned "not found".')); + $this->assertResponse('404', 'Not existing book node returned "not found".'); // Make sure an anonymous user cannot view printer-friendly version. $this->drupalLogout(); // Load the book and verify there is no printer-friendly version link. $this->drupalGet('node/' . $this->book->nid); - $this->assertNoLink(t('Printer-friendly version'), t('Anonymous user is not shown link to printer-friendly version.')); + $this->assertNoLink(t('Printer-friendly version'), 'Anonymous user is not shown link to printer-friendly version.'); // Try getting the URL directly, and verify it fails. $this->drupalGet('book/export/html/' . $this->book->nid); - $this->assertResponse('403', t('Anonymous user properly forbidden.')); + $this->assertResponse('403', 'Anonymous user properly forbidden.'); } /** @@ -282,26 +282,26 @@ function testBookNavigationBlock() { // Set block title to confirm that the interface is available. $block_title = $this->randomName(16); $this->drupalPost('admin/structure/block/manage/book/navigation/configure', array('title' => $block_title), t('Save block')); - $this->assertText(t('The block configuration has been saved.'), t('Block configuration set.')); + $this->assertText(t('The block configuration has been saved.'), 'Block configuration set.'); // Set the block to a region to confirm block is available. $edit = array(); $edit['blocks[book_navigation][region]'] = 'footer'; $this->drupalPost('admin/structure/block', $edit, t('Save blocks')); - $this->assertText(t('The block settings have been updated.'), t('Block successfully move to footer region.')); + $this->assertText(t('The block settings have been updated.'), 'Block successfully move to footer region.'); // Give anonymous users the permission 'node test view'. $edit = array(); $edit[DRUPAL_ANONYMOUS_RID . '[node test view]'] = TRUE; $this->drupalPost('admin/people/permissions/' . DRUPAL_ANONYMOUS_RID, $edit, t('Save permissions')); - $this->assertText(t('The changes have been saved.'), t("Permission 'node test view' successfully assigned to anonymous users.")); + $this->assertText(t('The changes have been saved.'), "Permission 'node test view' successfully assigned to anonymous users."); // Test correct display of the block. $nodes = $this->createBook(); $this->drupalGet(''); - $this->assertText($block_title, t('Book navigation block is displayed.')); - $this->assertText($this->book->label(), t('Link to book root (@title) is displayed.', array('@title' => $nodes[0]->label()))); - $this->assertNoText($nodes[0]->label(), t('No links to individual book pages are displayed.')); + $this->assertText($block_title, 'Book navigation block is displayed.'); + $this->assertText($this->book->label(), format_string('Link to book root (@title) is displayed.', array('@title' => $nodes[0]->label()))); + $this->assertNoText($nodes[0]->label(), 'No links to individual book pages are displayed.'); } /** @@ -318,19 +318,19 @@ function testNavigationBlockOnAccessModuleEnabled() { // Set block display to 'Show block only on book pages'. $edit['book_block_mode'] = 'book pages'; $this->drupalPost('admin/structure/block/manage/book/navigation/configure', $edit, t('Save block')); - $this->assertText(t('The block configuration has been saved.'), t('Block configuration set.')); + $this->assertText(t('The block configuration has been saved.'), 'Block configuration set.'); // Set the block to a region to confirm block is available. $edit = array(); $edit['blocks[book_navigation][region]'] = 'footer'; $this->drupalPost('admin/structure/block', $edit, t('Save blocks')); - $this->assertText(t('The block settings have been updated.'), t('Block successfully move to footer region.')); + $this->assertText(t('The block settings have been updated.'), 'Block successfully move to footer region.'); // Give anonymous users the permission 'node test view'. $edit = array(); $edit[DRUPAL_ANONYMOUS_RID . '[node test view]'] = TRUE; $this->drupalPost('admin/people/permissions/' . DRUPAL_ANONYMOUS_RID, $edit, t('Save permissions')); - $this->assertText(t('The changes have been saved.'), t('Permission \'node test view\' successfully assigned to anonymous users.')); + $this->assertText(t('The changes have been saved.'), 'Permission \'node test view\' successfully assigned to anonymous users.'); // Create a book. $this->createBook(); @@ -338,12 +338,12 @@ function testNavigationBlockOnAccessModuleEnabled() { // Test correct display of the block to registered users. $this->drupalLogin($this->web_user); $this->drupalGet('node/' . $this->book->nid); - $this->assertText($block_title, t('Book navigation block is displayed to registered users.')); + $this->assertText($block_title, 'Book navigation block is displayed to registered users.'); $this->drupalLogout(); // Test correct display of the block to anonymous users. $this->drupalGet('node/' . $this->book->nid); - $this->assertText($block_title, t('Book navigation block is displayed to anonymous users.')); + $this->assertText($block_title, 'Book navigation block is displayed to anonymous users.'); } /** @@ -359,7 +359,7 @@ function testBookDelete() { $this->assertResponse('403', t('Deleting top-level book node properly forbidden.')); $this->drupalPost('node/' . $nodes[4]->nid . '/outline/remove', $edit, t('Remove')); $node4 = node_load($nodes[4]->nid, TRUE); - $this->assertTrue(empty($node4->book), t('Deleting child book node properly allowed.')); + $this->assertTrue(empty($node4->book), 'Deleting child book node properly allowed.'); // Delete all child book nodes and retest top-level node deletion. foreach ($nodes as $node) { @@ -368,7 +368,7 @@ function testBookDelete() { node_delete_multiple($nids); $this->drupalPost('node/' . $this->book->nid . '/outline/remove', $edit, t('Remove')); $node = node_load($this->book->nid, TRUE); - $this->assertTrue(empty($node->book), t('Deleting childless top-level book node properly allowed.')); + $this->assertTrue(empty($node->book), 'Deleting childless top-level book node properly allowed.'); } } diff --git a/core/modules/config/lib/Drupal/config/ConfigEntityListController.php b/core/modules/config/lib/Drupal/config/ConfigEntityListController.php new file mode 100644 index 0000000..1b56899 --- /dev/null +++ b/core/modules/config/lib/Drupal/config/ConfigEntityListController.php @@ -0,0 +1,49 @@ +uri(); + $operations['edit'] = array( + '#type' => 'link', + '#title' => t('edit'), + '#href' => $uri['path'] . '/edit', + '#options' => $uri['options'], + '#weight' => 10, + ); + $operations['delete'] = array( + '#type' => 'link', + '#title' => t('delete'), + '#href' => $uri['path'] . '/delete', + '#options' => $uri['options'], + '#weight' => 100, + ); + return $operations; + } + +} diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php new file mode 100644 index 0000000..46d52f6 --- /dev/null +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php @@ -0,0 +1,66 @@ + 'Configuration entity list', + 'description' => 'Tests listing of configuration entities.', + 'group' => 'Configuration', + ); + } + + /** + * Tests entity list controller functionality. + */ + function testList() { + $controller = entity_list_controller('config_test'); + + // Get a list of ConfigTest entities. + $list = $controller->load(); + $this->assertEqual(count($list), 1, '1 ConfigTest entity found.'); + $this->assertTrue(!empty($list['default']), '"Default" ConfigTest entity ID found.'); + $this->assertTrue($list['default'] instanceof ConfigTest, '"Default" ConfigTest entity is an instance of ConfigTest.'); + } + + /** + * Tests the listing UI. + */ + function testListUI() { + $page = $this->drupalGet('admin/structure/config_test'); + $this->assertText('Test configuration'); + + // Verify that the default ConfigTest configuration appears. + $this->assertText('default'); + $this->assertText('Default'); + + // Verify that operation links appear. + foreach (array('edit', 'delete') as $link) { + $this->drupalSetContent($page); + $this->assertLink($link); + $this->clickLink($link); + $this->assertResponse(200); + } + } + +} diff --git a/core/modules/config/tests/config_test/config_test.module b/core/modules/config/tests/config_test/config_test.module index 44d4087..a75eff8 100644 --- a/core/modules/config/tests/config_test/config_test.module +++ b/core/modules/config/tests/config_test/config_test.module @@ -82,6 +82,8 @@ function config_test_entity_info() { 'label' => 'Test configuration', 'controller class' => 'Drupal\config\ConfigStorageController', 'entity class' => 'Drupal\config_test\ConfigTest', + 'list controller class' => 'Drupal\config\ConfigEntityListController', + 'list path' => 'admin/structure/config_test', 'uri callback' => 'config_test_uri', 'config prefix' => 'config_test.dynamic', 'entity keys' => array( @@ -176,8 +178,10 @@ function config_test_delete($id) { * Page callback; Lists available ConfigTest objects. */ function config_test_list_page() { + $controller = entity_list_controller('config_test'); + return $controller->render(); + $entities = entity_load_multiple('config_test'); - uasort($entities, 'Drupal\config\ConfigEntityBase::sort'); $rows = array(); foreach ($entities as $config_test) { @@ -201,9 +205,6 @@ function config_test_list_page() { '#theme' => 'table', '#header' => array('Name', 'Operations'), '#rows' => $rows, - '#empty' => format_string('No test configuration defined. Add some', array( - '@add-url' => url('admin/structure/config_test/add'), - )), ); return $build; } diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module index 1ba70b9..985abbd 100644 --- a/core/modules/contact/contact.module +++ b/core/modules/contact/contact.module @@ -168,7 +168,7 @@ function contact_load($cid) { * Implements hook_mail(). */ function contact_mail($key, &$message, $params) { - $language = $message['language']; + $language = language_load($message['langcode']); $variables = array( '!site-name' => config('system.site')->get('name'), '!subject' => $params['subject'], diff --git a/core/modules/contact/contact.pages.inc b/core/modules/contact/contact.pages.inc index 08c1d12..e9a6c62 100644 --- a/core/modules/contact/contact.pages.inc +++ b/core/modules/contact/contact.pages.inc @@ -168,16 +168,16 @@ function contact_site_form_submit($form, &$form_state) { $from = $values['sender']->mail; // Send the e-mail to the recipients using the site default language. - drupal_mail('contact', 'page_mail', $to, language_default(), $values, $from); + drupal_mail('contact', 'page_mail', $to, language_default()->langcode, $values, $from); // If the user requests it, send a copy using the current language. if ($values['copy']) { - drupal_mail('contact', 'page_copy', $from, $language_interface, $values, $from); + drupal_mail('contact', 'page_copy', $from, $language_interface->langcode, $values, $from); } // Send an auto-reply if necessary using the current language. if ($values['category']['reply']) { - drupal_mail('contact', 'page_autoreply', $from, $language_interface, $values, $to); + drupal_mail('contact', 'page_autoreply', $from, $language_interface->langcode, $values, $to); } flood_register_event('contact', config('contact.settings')->get('flood.interval')); @@ -308,11 +308,11 @@ function contact_personal_form_submit($form, &$form_state) { $from = $values['sender']->mail; // Send the e-mail in the requested user language. - drupal_mail('contact', 'user_mail', $to, user_preferred_language($values['recipient']), $values, $from); + drupal_mail('contact', 'user_mail', $to, user_preferred_langcode($values['recipient']), $values, $from); // Send a copy if requested, using current page language. if ($values['copy']) { - drupal_mail('contact', 'user_copy', $from, $language_interface, $values, $from); + drupal_mail('contact', 'user_copy', $from, $language_interface->langcode, $values, $from); } flood_register_event('contact', config('contact.settings')->get('flood.interval')); diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index a407c74..73c4a83 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -33,6 +33,8 @@ * - label: The human readable name of the component. * - description: A short description of the component contents. * - weight: The default weight of the element. + * - visible: The default visibility of the element. Only for 'display' + * context. */ function hook_field_extra_fields() { $extra['node']['poll'] = array( diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc index 0d00dbd..65c6bcc 100644 --- a/core/modules/field/field.info.inc +++ b/core/modules/field/field.info.inc @@ -431,6 +431,7 @@ function _field_info_prepare_extra_fields($extra_fields, $entity_type, $bundle) $data = $extra_fields['display']; foreach ($extra_fields['display'] as $name => $field_data) { $settings = isset($bundle_settings['extra_fields']['display'][$name]) ? $bundle_settings['extra_fields']['display'][$name] : array(); + $field_data['visible'] = isset($field_data['visible']) ? $field_data['visible'] : TRUE; $view_modes = array_merge(array('default'), array_keys($entity_type_info['view modes'])); foreach ($view_modes as $view_mode) { if (isset($settings[$view_mode])) { @@ -439,7 +440,7 @@ function _field_info_prepare_extra_fields($extra_fields, $entity_type, $bundle) else { $field_data['display'][$view_mode] = array( 'weight' => $field_data['weight'], - 'visible' => TRUE, + 'visible' => $field_data['visible'], ); } } diff --git a/core/modules/image/image.module b/core/modules/image/image.module index ccdc879..775de2d 100644 --- a/core/modules/image/image.module +++ b/core/modules/image/image.module @@ -1205,6 +1205,9 @@ function theme_image_style($variables) { $variables['width'] = $dimensions['width']; $variables['height'] = $dimensions['height']; + // Add in the image style name as an HTML class. + $variables['attributes']['class'][] = 'image-style-' . drupal_html_class($variables['style_name']); + // Determine the URL for the styled image. $variables['uri'] = image_style_url($variables['style_name'], $variables['uri']); return theme('image', $variables); diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php index d2554cf..76110cf 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php @@ -69,7 +69,7 @@ function testImageDimensions() { image_effect_save('test', $effect); $img_tag = theme_image_style($variables); - $this->assertEqual($img_tag, ''); + $this->assertEqual($img_tag, ''); $this->assertFalse(file_exists($generated_uri), t('Generated file does not exist.')); $this->drupalGet($url); $this->assertResponse(200, t('Image was generated at the URL.')); @@ -90,7 +90,7 @@ function testImageDimensions() { image_effect_save('test', $effect); $img_tag = theme_image_style($variables); - $this->assertEqual($img_tag, ''); + $this->assertEqual($img_tag, ''); $this->assertFalse(file_exists($generated_uri), t('Generated file does not exist.')); $this->drupalGet($url); $this->assertResponse(200, t('Image was generated at the URL.')); @@ -112,7 +112,7 @@ function testImageDimensions() { image_effect_save('test', $effect); $img_tag = theme_image_style($variables); - $this->assertEqual($img_tag, ''); + $this->assertEqual($img_tag, ''); $this->assertFalse(file_exists($generated_uri), t('Generated file does not exist.')); $this->drupalGet($url); $this->assertResponse(200, t('Image was generated at the URL.')); @@ -134,7 +134,7 @@ function testImageDimensions() { image_effect_save('test', $effect); $img_tag = theme_image_style($variables); - $this->assertEqual($img_tag, ''); + $this->assertEqual($img_tag, ''); $this->assertFalse(file_exists($generated_uri), t('Generated file does not exist.')); $this->drupalGet($url); $this->assertResponse(200, t('Image was generated at the URL.')); @@ -152,7 +152,7 @@ function testImageDimensions() { image_effect_save('test', $effect); $img_tag = theme_image_style($variables); - $this->assertEqual($img_tag, ''); + $this->assertEqual($img_tag, ''); $this->assertFalse(file_exists($generated_uri), t('Generated file does not exist.')); $this->drupalGet($url); $this->assertResponse(200, t('Image was generated at the URL.')); @@ -173,7 +173,7 @@ function testImageDimensions() { image_effect_save('test', $effect); $img_tag = theme_image_style($variables); - $this->assertEqual($img_tag, ''); + $this->assertEqual($img_tag, ''); $this->assertFalse(file_exists($generated_uri), t('Generated file does not exist.')); $this->drupalGet($url); $this->assertResponse(200, t('Image was generated at the URL.')); @@ -193,7 +193,7 @@ function testImageDimensions() { image_effect_save('test', $effect); $img_tag = theme_image_style($variables); - $this->assertEqual($img_tag, ''); + $this->assertEqual($img_tag, ''); $this->assertFalse(file_exists($generated_uri), t('Generated file does not exist.')); $this->drupalGet($url); $this->assertResponse(200, t('Image was generated at the URL.')); @@ -214,7 +214,7 @@ function testImageDimensions() { $effect = image_effect_save('test', $effect); $img_tag = theme_image_style($variables); - $this->assertEqual($img_tag, ''); + $this->assertEqual($img_tag, ''); $this->assertFalse(file_exists($generated_uri), t('Generated file does not exist.')); $this->drupalGet($url); $this->assertResponse(200, t('Image was generated at the URL.')); @@ -232,6 +232,6 @@ function testImageDimensions() { image_effect_save('test', $effect); $img_tag = theme_image_style($variables); - $this->assertEqual($img_tag, ''); + $this->assertEqual($img_tag, ''); } } diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php index 601c3c2..9e00434 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php @@ -104,10 +104,11 @@ function _testImageFieldFormatters($scheme) { // Ensure the derivative image is generated so we do not have to deal with // image style callback paths. $this->drupalGet(image_style_url('thumbnail', $image_uri)); - $image_info['uri'] = image_style_path('thumbnail', $image_uri); + $image_info['uri'] = $image_uri; $image_info['width'] = 100; $image_info['height'] = 50; - $default_output = theme('image', $image_info); + $image_info['style_name'] = 'thumbnail'; + $default_output = theme('image_style', $image_info); $this->drupalGet('node/' . $nid); $this->assertRaw($default_output, t('Image style thumbnail formatter displaying correctly on full node view.')); @@ -158,11 +159,12 @@ function testImageFieldSettings() { // style. $node = node_load($nid, TRUE); $image_info = array( - 'uri' => image_style_url('medium', file_load($node->{$field_name}[LANGUAGE_NOT_SPECIFIED][0]['fid'])->uri), + 'uri' => file_load($node->{$field_name}[LANGUAGE_NOT_SPECIFIED][0]['fid'])->uri, 'width' => 220, 'height' => 110, + 'style_name' => 'medium', ); - $default_output = theme('image', $image_info); + $default_output = theme('image_style', $image_info); $this->assertRaw($default_output, t("Preview image is displayed using 'medium' style.")); // Add alt/title fields to the image and verify that they are displayed. diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageThemeFunctionTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageThemeFunctionTest.php index 0e026f2..45de98e 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageThemeFunctionTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageThemeFunctionTest.php @@ -56,7 +56,7 @@ function testImageFormatterTheme() { ), ); $rendered_element = render($element); - $expected_result = ''; + $expected_result = ''; $this->assertEqual($expected_result, $rendered_element, 'theme_image_formatter() correctly renders without title, alt, or path options.'); // Link the image to a fragment on the page, and not a full URL. @@ -67,7 +67,7 @@ function testImageFormatterTheme() { 'fragment' => $fragment, ); $rendered_element = render($element); - $expected_result = ''; + $expected_result = ''; $this->assertEqual($expected_result, $rendered_element, 'theme_image_formatter() correctly renders a link fragment.'); } @@ -81,17 +81,17 @@ function testImageStyleTheme() { $original_uri = file_unmanaged_copy($file->uri, 'public://', FILE_EXISTS_RENAME); // Create a style. - image_style_save(array('name' => 'test')); - $url = image_style_url('test', $original_uri); + image_style_save(array('name' => 'image_test')); + $url = image_style_url('image_test', $original_uri); $path = $this->randomName(); $element = array( '#theme' => 'image_style', - '#style_name' => 'test', + '#style_name' => 'image_test', '#uri' => $original_uri, ); $rendered_element = render($element); - $expected_result = ''; + $expected_result = ''; $this->assertEqual($expected_result, $rendered_element, 'theme_image_style() renders an image correctly.'); } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php index 3ba3fe6..e191eca 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php @@ -78,6 +78,13 @@ function testNodeTypeInitialLanguageDefaults() { $language_field = $this->xpath('//*[@id="language"]'); $this->assert(!empty($language_field), 'Language field is visible on manage fields tab.'); + // Tests if the language field can be rearranged on the manage display tab. + $this->drupalGet('admin/structure/types/manage/article/display'); + $language_display = $this->xpath('//*[@id="language"]'); + $this->assert(!empty($language_display), 'Language field is visible on manage display tab.'); + // Tests if the language field is hidden by default. + $this->assertOptionSelected('edit-fields-language-type', 'hidden', 'Language is hidden by default on manage display tab.'); + // Changes the inital language settings. $edit = array( 'node_type_language_default' => 'en', @@ -86,4 +93,42 @@ function testNodeTypeInitialLanguageDefaults() { $this->drupalGet('node/add/article'); $this->assertOptionSelected('edit-langcode', 'en', 'The inital language is the defined language.'); } + + /** + * Tests Language field visibility features. + */ + function testLanguageFieldVisibility() { + $langcode = LANGUAGE_NOT_SPECIFIED; + + // Creates a node to test Language field visibility feature. + $edit = array( + 'title' => $this->randomName(8), + "body[$langcode][0][value]" => $this->randomName(16), + ); + $this->drupalPost('node/add/article', $edit, t('Save')); + $node = $this->drupalGetNodeByTitle($edit['title']); + $this->assertTrue($node, 'Node found in database.'); + + // Loads node page and check if Language field is hidden by default. + $this->drupalGet('node/' . $node->nid); + $language_field = $this->xpath('//div[@id=:id]/div', array( + ':id' => 'field-language-display', + )); + $this->assertTrue(empty($language_field), 'Language field value is not shown by default on node page.'); + + // Changes Language field visibility to true and check if it is saved. + $edit = array( + 'fields[language][type]' => 'visible', + ); + $this->drupalPost('admin/structure/types/manage/article/display', $edit, t('Save')); + $this->drupalGet('admin/structure/types/manage/article/display'); + $this->assertOptionSelected('edit-fields-language-type', 'visible', 'Language field has been set to visible.'); + + // Loads node page and check if Language field is shown. + $this->drupalGet('node/' . $node->nid); + $language_field = $this->xpath('//div[@id=:id]/div', array( + ':id' => 'field-language-display', + )); + $this->assertFalse(empty($language_field), 'Language field value is shown on node page.'); + } } diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 2d87534..bfba2fd 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -678,13 +678,21 @@ function node_field_extra_fields() { // Add also the 'language' select if Language module is enabled and the // bundle has multilingual support. - // Visibility of the ordering of the language selector is the same as on the node/add form, - // i.e. node_type_language_hidden_TYPE variable - if ($module_language_enabled && !variable_get('node_type_language_hidden_' . $bundle->type, TRUE)) { - $extra['node'][$bundle->type]['form']['language'] = array( + // Visibility of the ordering of the language selector is the same as on the + // node/add form, i.e. node_type_language_hidden_TYPE variable. + if ($module_language_enabled) { + if (!variable_get('node_type_language_hidden_' . $bundle->type, TRUE)) { + $extra['node'][$bundle->type]['form']['language'] = array( + 'label' => t('Language'), + 'description' => $description, + 'weight' => 0, + ); + } + $extra['node'][$bundle->type]['display']['language'] = array( 'label' => t('Language'), 'description' => $description, 'weight' => 0, + 'visible' => FALSE, ); } } @@ -1167,6 +1175,18 @@ function node_view(Node $node, $view_mode = 'full', $langcode = NULL) { // Populate $node->content with a render() array. node_build_content($node, $view_mode, $langcode); + // Add language text element on node view if language module is enabled. + if (module_exists('language')) { + $node->content['language'] = array( + '#type' => 'item', + '#title' => t('Language'), + '#markup' => language_name($langcode), + '#weight' => 0, + '#prefix' => '
', + '#suffix' => '
' + ); + } + $build = $node->content; // We don't need duplicate rendering info in node->content. unset($node->content); diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module index eafb0b0..4a9136e 100644 --- a/core/modules/openid/openid.module +++ b/core/modules/openid/openid.module @@ -481,7 +481,7 @@ function openid_discovery($claimed_id) { } /** - * Implementation of hook_openid_discovery_method_info(). + * Implements hook_openid_discovery_method_info(). * * Define standard discovery methods. */ @@ -619,7 +619,7 @@ function _openid_xrds_discovery($claimed_id) { } /** - * Implementation of hook_openid_normalization_method_info(). + * Implements hook_openid_normalization_method_info(). * * Define standard normalization methods. */ @@ -1067,7 +1067,7 @@ function openid_verify_assertion_return_url($service, $response) { /** * Remove expired nonces from the database. * - * Implementation of hook_cron(). + * Implements hook_cron(). */ function openid_cron() { db_delete('openid_nonce') diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php index 6f17f57..095981e 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php @@ -727,7 +727,7 @@ protected function prepareEnvironment() { // @see config_get_config_directory() $GLOBALS['config_directories'] = array(); foreach (array(CONFIG_ACTIVE_DIRECTORY, CONFIG_STAGING_DIRECTORY) as $type) { - $GLOBALS['config_directories'][$type] = 'simpletest/' . substr($this->databasePrefix, 10) . '/config_' . $type; + $GLOBALS['config_directories'][$type]['path'] = 'simpletest/' . substr($this->databasePrefix, 10) . '/config_' . $type; } // Reset and create a new service container. @@ -735,11 +735,11 @@ protected function prepareEnvironment() { $this->configDirectories = array(); include_once DRUPAL_ROOT . '/core/includes/install.inc'; - foreach ($GLOBALS['config_directories'] as $type => $path) { + foreach ($GLOBALS['config_directories'] as $type => $directory) { if (!install_ensure_config_directory($type)) { return FALSE; } - $this->configDirectories[$type] = $this->originalFileDirectory . '/' . $path; + $this->configDirectories[$type] = $this->originalFileDirectory . '/' . $directory['path']; } // Unset globals. diff --git a/core/modules/system/lib/Drupal/system/Tests/Mail/MailTest.php b/core/modules/system/lib/Drupal/system/Tests/Mail/MailTest.php index d75b593..4eaa4c8 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Mail/MailTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Mail/MailTest.php @@ -52,7 +52,7 @@ public function testPluggableFramework() { $language_interface = language(LANGUAGE_TYPE_INTERFACE); // Use MailTestCase for sending a message. - $message = drupal_mail('simpletest', 'mail_test', 'testing@example.com', $language_interface); + $message = drupal_mail('simpletest', 'mail_test', 'testing@example.com', $language_interface->langcode); // Assert whether the message was sent through the send function. $this->assertEqual(self::$sent_message['to'], 'testing@example.com', t('Pluggable mail system is extendable.')); @@ -64,13 +64,13 @@ public function testPluggableFramework() { * @see simpletest_mail_alter() */ public function testCancelMessage() { - global $language; + $language_interface = language(LANGUAGE_TYPE_INTERFACE); // Reset the class variable holding a copy of the last sent message. self::$sent_message = NULL; // Send a test message that simpletest_mail_alter should cancel. - $message = drupal_mail('simpletest', 'cancel_test', 'cancel@example.com', $language); + $message = drupal_mail('simpletest', 'cancel_test', 'cancel@example.com', $language_interface->langcode); // Assert that the message was not actually sent. $this->assertNull(self::$sent_message, 'Message was canceled.'); diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php index c7343ba..efdadb4 100644 --- a/core/modules/system/system.api.php +++ b/core/modules/system/system.api.php @@ -1945,7 +1945,7 @@ function hook_watchdog(array $log_entry) { '@message' => strip_tags($log_entry['message']), )); - drupal_mail('emaillog', 'entry', $to, $language_interface, $params); + drupal_mail('emaillog', 'entry', $to, $language_interface->langcode, $params); } /** diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 80ba5ad..e5dc768 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -3661,14 +3661,14 @@ function system_send_email_action($entity, $context) { // language. $recipient_account = user_load_by_mail($recipient); if ($recipient_account) { - $language = user_preferred_language($recipient_account); + $langcode = user_preferred_langcode($recipient_account); } else { - $language = language_default(); + $langcode = language_default()->langcode; } $params = array('context' => $context); - if (drupal_mail('system', 'action_send_email', $recipient, $language, $params)) { + if (drupal_mail('system', 'action_send_email', $recipient, $langcode, $params)) { watchdog('action', 'Sent email to %recipient', array('%recipient' => $recipient)); } else { diff --git a/core/modules/update/update.fetch.inc b/core/modules/update/update.fetch.inc index 76eeb54..a4d1bd7 100644 --- a/core/modules/update/update.fetch.inc +++ b/core/modules/update/update.fetch.inc @@ -366,15 +366,15 @@ function _update_cron_notify() { if (!empty($params)) { $notify_list = $update_config->get('notification.emails'); if (!empty($notify_list)) { - $default_language = language_default(); + $default_langcode = language_default()->langcode; foreach ($notify_list as $target) { if ($target_user = user_load_by_mail($target)) { - $target_language = user_preferred_language($target_user); + $target_langcode = user_preferred_langcode($target_user); } else { - $target_language = $default_language; + $target_langcode = $default_langcode; } - $message = drupal_mail('update', 'status_notify', $target, $target_language, $params); + $message = drupal_mail('update', 'status_notify', $target, $target_langcode, $params); // Track when the last mail was successfully sent to avoid sending // too many e-mails. if ($message['result']) { diff --git a/core/modules/update/update.module b/core/modules/update/update.module index bee906f..f9445bc 100644 --- a/core/modules/update/update.module +++ b/core/modules/update/update.module @@ -510,11 +510,10 @@ function _update_get_cached_available_releases() { * @see _update_message_text() */ function update_mail($key, &$message, $params) { - $language = $message['language']; - $langcode = $language->langcode; + $langcode = $message['langcode']; $message['subject'] .= t('New release(s) available for !site_name', array('!site_name' => config('system.site')->get('name')), array('langcode' => $langcode)); foreach ($params as $msg_type => $msg_reason) { - $message['body'][] = _update_message_text($msg_type, $msg_reason, FALSE, $language); + $message['body'][] = _update_message_text($msg_type, $msg_reason, FALSE, $langcode); } $message['body'][] = t('See the available updates page for more information:', array(), array('langcode' => $langcode)) . "\n" . url('admin/reports/updates', array('absolute' => TRUE, 'language' => $language)); if (update_manager_access()) { @@ -544,14 +543,13 @@ function update_mail($key, &$message, $params) { * @param $report_link * (optional) Boolean that controls if a link to the updates report should be * added. Defaults to FALSE. - * @param $language - * (optional) A language object to use. Defaults to NULL. + * @param $langcode + * (optional) A language code to use. Defaults to NULL. * * @return * The properly translated error message for the given key. */ -function _update_message_text($msg_type, $msg_reason, $report_link = FALSE, $language = NULL) { - $langcode = isset($language) ? $language->langcode : NULL; +function _update_message_text($msg_type, $msg_reason, $report_link = FALSE, $langcode = NULL) { $text = ''; switch ($msg_reason) { case UPDATE_NOT_SECURE: @@ -602,7 +600,12 @@ function _update_message_text($msg_type, $msg_reason, $report_link = FALSE, $lan } break; } - + if (!empty($langcode)) { + $language = language_load(langcode); + } + else { + $language = NULL; + } if ($report_link) { if (update_manager_access()) { $text .= ' ' . t('See the available updates page for more information and to install your missing updates.', array('@available_updates' => url('admin/reports/updates/update', array('language' => $language))), array('langcode' => $langcode)); diff --git a/core/modules/user/lib/Drupal/user/AccountFormController.php b/core/modules/user/lib/Drupal/user/AccountFormController.php index 44acf72..a5545f4 100644 --- a/core/modules/user/lib/Drupal/user/AccountFormController.php +++ b/core/modules/user/lib/Drupal/user/AccountFormController.php @@ -204,9 +204,9 @@ public function form(array $form, array &$form_state, EntityInterface $account) $form['#validate'][] = 'user_validate_picture'; - $user_preferred_language = $register ? $language_interface : user_preferred_language($account); + $user_preferred_langcode = $register ? $language_interface->langcode : user_preferred_langcode($account); - $user_preferred_admin_language = $register ? $language_interface : user_preferred_language($account, 'admin'); + $user_preferred_admin_langcode = $register ? $language_interface->langcode : user_preferred_langcode($account, 'admin'); // Is default the interface language? include_once DRUPAL_ROOT . '/core/includes/language.inc'; @@ -223,7 +223,7 @@ public function form(array $form, array &$form_state, EntityInterface $account) '#type' => 'language_select', '#title' => t('Site language'), '#languages' => LANGUAGE_CONFIGURABLE, - '#default_value' => $user_preferred_language->langcode, + '#default_value' => $user_preferred_langcode, '#description' => $interface_language_is_default ? t("This account's preferred language for e-mails and site presentation.") : t("This account's preferred language for e-mails."), ); @@ -231,7 +231,7 @@ public function form(array $form, array &$form_state, EntityInterface $account) '#type' => 'language_select', '#title' => t('Administration pages language'), '#languages' => LANGUAGE_CONFIGURABLE, - '#default_value' => $user_preferred_admin_language->langcode, + '#default_value' => $user_preferred_admin_langcode, '#access' => user_access('access administration pages', $account), ); diff --git a/core/modules/user/user.module b/core/modules/user/user.module index e2a73fc..3b69966 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1812,13 +1812,8 @@ function user_external_login_register($name, $module) { */ function user_pass_reset_url($account, $options = array()) { $timestamp = REQUEST_TIME; - $url_options = array('absolute' => TRUE); - if (isset($options['langcode'])) { - $url_options['language'] = language_load($options['langcode']); - } - else { - $url_options['language'] = user_preferred_language($account); - } + $langcode = isset($options['langcode']) ? $options['langcode'] : user_preferred_langcode($account); + $url_options = array('absolute' => TRUE, 'language' => language_load($langcode)); return url("user/reset/$account->uid/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), $url_options); } @@ -1845,13 +1840,8 @@ function user_pass_reset_url($account, $options = array()) { */ function user_cancel_url($account, $options = array()) { $timestamp = REQUEST_TIME; - $url_options = array('absolute' => TRUE); - if (isset($options['langcode'])) { - $url_options['language'] = language_load($options['langcode']); - } - else { - $url_options['language'] = user_preferred_language($account); - } + $langcode = isset($options['langcode']) ? $options['langcode'] : user_preferred_langcode($account); + $url_options = array('absolute' => TRUE, 'language' => language_load($langcode)); return url("user/$account->uid/cancel/confirm/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), $url_options); } @@ -2105,10 +2095,10 @@ function user_build_content($account, $view_mode = 'full', $langcode = NULL) { * Implements hook_mail(). */ function user_mail($key, &$message, $params) { - $language = $message['language']; + $langcode = $message['langcode']; $variables = array('user' => $params['account']); - $message['subject'] .= _user_mail_text($key . '.subject', $language, $variables); - $message['body'][] = _user_mail_text($key . '.body', $language, $variables); + $message['subject'] .= _user_mail_text($key . '.subject', $langcode, $variables); + $message['body'][] = _user_mail_text($key . '.body', $langcode, $variables); } /** @@ -2116,16 +2106,15 @@ function user_mail($key, &$message, $params) { * * @param string $key * The config key that provides the mail text. - * @param object $language - * A language object. + * @param string $langcode + * (optional) A language code to use to generate the e-mail text. * @param array $variables - * An array of token keys and values. + * (optional) An array of token keys and values. * * @return * A string value containing the text for the user.mail config key. */ -function _user_mail_text($key, $language = NULL, $variables = array()) { - $langcode = isset($language) ? $language->langcode : NULL; +function _user_mail_text($key, $langcode = NULL, $variables = array()) { // We do not sanitize the token replacement, since the output of this // replacement is intended for an e-mail message, not a web browser. return token_replace(config('user.mail')->get($key), $variables, array('langcode' => $langcode, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE)); @@ -2795,10 +2784,10 @@ function theme_user_signature($variables) { * Default to 'preferred_langcode' property. * If set 'preferred_$type_langcode' is used. * @param $default - * Optional default language object to return if the account + * Optional default language code to return if the account * has no valid language. */ -function user_preferred_language($account, $type = NULL, $default = NULL) { +function user_preferred_langcode($account, $type = NULL, $default = NULL) { $language_list = language_list(); if (isset($type)) { $preferred_langcode = $account->{'preferred_' . $type . '_langcode'}; @@ -2807,10 +2796,10 @@ function user_preferred_language($account, $type = NULL, $default = NULL) { $preferred_langcode = $account->preferred_langcode; } if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) { - return $language_list[$preferred_langcode]; + return $language_list[$preferred_langcode]->langcode; } else { - return $default ? $default : language_default(); + return $default ? $default : language_default()->langcode; } } @@ -2837,20 +2826,21 @@ function user_preferred_language($account, $type = NULL, $default = NULL) { * @param $account * The user object of the account being notified. Must contain at * least the fields 'uid', 'name', and 'mail'. - * @param $language - * Optional language to use for the notification, overriding account language. + * @param $langcode + * Optional language code to use for the notification, overriding account + * language. * * @return * The return value from drupal_mail_system()->mail(), if ends up being * called. */ -function _user_mail_notify($op, $account, $language = NULL) { +function _user_mail_notify($op, $account, $langcode = NULL) { // By default, we always notify except for canceled and blocked. $notify = config('user.settings')->get('notify.' . $op); if ($notify || ($op != 'status_canceled' && $op != 'status_blocked')) { $params['account'] = $account; - $language = $language ? $language : user_preferred_language($account); - $mail = drupal_mail('user', $op, $account->mail, $language, $params); + $langcode = $langcode ? $langcode : user_preferred_langcode($account); + $mail = drupal_mail('user', $op, $account->mail, $langcode, $params); if ($op == 'register_pending_approval') { // If a user registered requiring admin approval, notify the admin, too. // We use the site default language for this. @@ -2858,7 +2848,7 @@ function _user_mail_notify($op, $account, $language = NULL) { if (empty($site_mail)) { $site_mail = ini_get('sendmail_from'); } - drupal_mail('user', 'register_pending_approval_admin', $site_mail, language_default(), $params); + drupal_mail('user', 'register_pending_approval_admin', $site_mail, language_default()->langcode, $params); } } return empty($mail) ? NULL : $mail['result']; diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc index d26ca6d..9dd2cc9 100644 --- a/core/modules/user/user.pages.inc +++ b/core/modules/user/user.pages.inc @@ -81,7 +81,7 @@ function user_pass_submit($form, &$form_state) { $account = $form_state['values']['account']; // Mail one time login URL and instructions using current language. - $mail = _user_mail_notify('password_reset', $account, $language_interface); + $mail = _user_mail_notify('password_reset', $account, $language_interface->langcode); if (!empty($mail)) { watchdog('user', 'Password reset instructions mailed to %name at %email.', array('%name' => $account->name, '%email' => $account->mail)); drupal_set_message(t('Further instructions have been sent to your e-mail address.')); diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index 7010b6a..8e95dba 100755 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -259,8 +259,14 @@ * Example: * @code * $config_directories = array( - * CONFIG_ACTIVE_DIRECTORY => '/some/directory/outside/webroot', - * CONFIG_STAGING_DIRECTORY => '/another/directory/outside/webroot', + * CONFIG_ACTIVE_DIRECTORY => array( + * 'path' => '/some/directory/outside/webroot', + * 'absolute' => TRUE, + * ), + * CONFIG_STAGING_DIRECTORY => array( + * 'path' => '/another/directory/outside/webroot', + * 'absolute' => TRUE, + * ), * ); * @endcode */